fix(agents): allow WorkBuddy configuration without detected app
This commit is contained in:
1 parent
0bb6eab4cb
commit
b0f69877f8
6 files changed
+50
-7
No files matched your search
@@ -1257,7 +1257,8 @@ pub(crate) fn validate_agent_can_enable(
|
||||
));
|
||||
}
|
||||
let detection = inspect_agent_config(client, home, port, api_key);
|
||||
if !detection.installed {
|
||||
let workbuddy_config_available = client == AgentClient::WorkBuddy && detection.config_exists;
|
||||
if !detection.installed && !workbuddy_config_available {
|
||||
return Err(format!("{} is not installed", client.name()));
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -1003,7 +1003,12 @@ pub(crate) fn inspect_agent_config(
|
||||
if !client.supported_platform() {
|
||||
warnings.push("当前平台不支持 Claude Desktop 3P 配置".to_string());
|
||||
} else if !installed && config_exists {
|
||||
warnings.push("只检测到配置文件,未检测到客户端".to_string());
|
||||
warnings.push(if client == AgentClient::WorkBuddy {
|
||||
"只检测到 WorkBuddy 配置文件,仍可编辑配置并接入 CPA;启动功能不可用"
|
||||
.to_string()
|
||||
} else {
|
||||
"只检测到配置文件,未检测到客户端".to_string()
|
||||
});
|
||||
}
|
||||
if let Some(message) = error.as_ref() {
|
||||
warnings.push(message.clone());
|
||||
|
||||
@@ -181,6 +181,31 @@ fn workbuddy_status_checks_endpoint_key_visibility_and_tool_support() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workbuddy_config_file_allows_cpa_connection_without_detected_application() {
|
||||
let home = Home::new();
|
||||
home.save(&json!({}));
|
||||
|
||||
let status = inspect_agent_config(AgentClient::WorkBuddy, &home.0, 8317, "test-key");
|
||||
assert!(!status.installed);
|
||||
assert!(status.config_exists);
|
||||
assert!(status.config_valid);
|
||||
assert!(status.launch_targets.is_empty());
|
||||
assert!(validate_agent_can_enable(
|
||||
AgentClient::WorkBuddy,
|
||||
&home.0,
|
||||
8317,
|
||||
"test-key"
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
home.apply("gpt-one").unwrap();
|
||||
let connected = inspect_agent_config(AgentClient::WorkBuddy, &home.0, 8317, "test-key");
|
||||
assert!(!connected.installed);
|
||||
assert!(connected.configured);
|
||||
assert_eq!(connected.current_model.as_deref(), Some("gpt-one"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn workbuddy_visibility_restores_original_references_and_keeps_user_edits() {
|
||||
for external_edit in [false, true] {
|
||||
|
||||
@@ -102,6 +102,7 @@ type AgentConfigStatus = {
|
||||
cliVersion: string | null;
|
||||
appVersion: string | null;
|
||||
pluginVersion: string | null;
|
||||
configExists: boolean;
|
||||
configValid: boolean;
|
||||
configured: boolean;
|
||||
connectionState: 'configured' | 'not-configured' | 'needs-update' | 'invalid';
|
||||
@@ -1196,9 +1197,12 @@ export function AgentsPage({ embedded = false, onConfigurationApplied }: AgentsP
|
||||
&& claudeModelMappingsDraft.autoCompactPct >= 1
|
||||
&& claudeModelMappingsDraft.autoCompactPct <= 100
|
||||
);
|
||||
const canEnable = Boolean(
|
||||
const canConfigureActiveClient = Boolean(
|
||||
activeStatus?.supportedPlatform
|
||||
&& activeStatus.installed
|
||||
&& (activeStatus.installed || (selected === 'workbuddy' && activeStatus.configExists)),
|
||||
);
|
||||
const canEnable = Boolean(
|
||||
canConfigureActiveClient
|
||||
&& !modelLoading
|
||||
&& (isClaudeModelMappingClient
|
||||
? claudeMappingsReady && claudeCodeRuntimeSettingsReady
|
||||
@@ -2091,7 +2095,7 @@ export function AgentsPage({ embedded = false, onConfigurationApplied }: AgentsP
|
||||
value={isClaudeModelMappingClient ? claudeModelMappingsDraft.sonnet : selectedModel}
|
||||
loading={modelLoading}
|
||||
error={modelError}
|
||||
disabled={busy || !activeStatus?.installed || !activeStatus.supportedPlatform}
|
||||
disabled={busy || !canConfigureActiveClient}
|
||||
onChange={selectEmbeddedModel}
|
||||
onRefresh={refreshModels}
|
||||
/>
|
||||
@@ -2187,7 +2191,7 @@ export function AgentsPage({ embedded = false, onConfigurationApplied }: AgentsP
|
||||
value={selectedModel}
|
||||
loading={modelLoading}
|
||||
error={modelError}
|
||||
disabled={busy || !activeStatus?.installed || !activeStatus.supportedPlatform}
|
||||
disabled={busy || !canConfigureActiveClient}
|
||||
onChange={selectModel}
|
||||
onRefresh={refreshModels}
|
||||
/>
|
||||
|
||||
@@ -141,6 +141,14 @@ const path = require('node:path');
|
||||
await open(mode + 'not-installed');
|
||||
assert.ok(await button('启动 App').isDisabled());
|
||||
assert.ok(await button('重启 App').isDisabled());
|
||||
await open(mode + 'client=workbuddy&config-only&fresh');
|
||||
assert.ok(await page.locator('.agent-model-trigger').isEnabled());
|
||||
assert.ok(await button('一键接入').isEnabled());
|
||||
assert.ok(await button('启动 App').isDisabled());
|
||||
assert.ok(await button('重启 App').isDisabled());
|
||||
await button('一键接入').click();
|
||||
await page.waitForFunction(() => window.fixtureCalls.some(call => call.cmd === 'update_agent_config'));
|
||||
assert.deepEqual((await calls('update_agent_config'))[0].args.client, 'workbuddy');
|
||||
await open(mode + 'client=kimi-code');
|
||||
assert.equal(await button('重启 App').count(), 0);
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -35,7 +35,7 @@ mockIPC(async (cmd,args:any) => {
|
||||
calls.push({cmd,args});
|
||||
if(cmd==='plugin:event|listen') return 1;
|
||||
if(cmd==='plugin:event|unlisten'||cmd==='set_app_locale') return null;
|
||||
if(cmd==='get_agent_config_statuses'||cmd==='refresh_agent_config_statuses') return ids.map(id=>({id,name:id,supportedPlatform:true,installed:!params.has('not-installed'),pluginInstalled:!params.has('no-plugin'),launchTargets:params.has('not-installed')?[]:['claude-desktop','zcode','workbuddy'].includes(id)?[{id:'app',label:id,detail:'test desktop'}]:['codex','opencode'].includes(id)&&!params.has('cli-only')?[...(params.has('app-only')?[]:[{id:'cli',label:'CLI',detail:'test CLI'}]),{id:'app',label:'APP',detail:'test desktop'}]:[{id:'cli',label:'CLI',detail:'test CLI'}],version:'1.0',cliVersion:'1.0',appVersion:null,pluginVersion:'1.0',configValid:params.get('state')!=='invalid',connectionState:params.get('state') || (currentModel?'configured':'not-configured'),configured:!!currentModel,configurationSynchronized:!!currentModel,currentModel,oauthConfiguration:id==='codex'&¤tOauth,codexNativeOauth:id==='codex'&&nativeOauth,modificationEnabled:!!currentModel,modificationState:currentModel?'applied':'unconfigured',backupAvailable:false,appliedModel:currentModel,claudeCodeModelMappings:id==='claude-code'?currentMappings[id]??null:null,claudeDesktopModelMappings:id==='claude-desktop'?currentMappings[id]??null:null,warnings:[],error:null})).map(status=>status.id==='codex'&&(nativeOauth||codexClosed)?{...status,configured:false,connectionState:'not-configured',configurationSynchronized:false,currentModel:null,appliedModel:null,modificationEnabled:false,modificationState:'unconfigured',oauthConfiguration:false}:status);
|
||||
if(cmd==='get_agent_config_statuses'||cmd==='refresh_agent_config_statuses') return ids.map(id=>({id,name:id,supportedPlatform:true,installed:!params.has('not-installed')&&!(params.has('config-only')&&id==='workbuddy'),pluginInstalled:!params.has('no-plugin'),launchTargets:params.has('not-installed')||(params.has('config-only')&&id==='workbuddy')?[]:['claude-desktop','zcode','workbuddy'].includes(id)?[{id:'app',label:id,detail:'test desktop'}]:['codex','opencode'].includes(id)&&!params.has('cli-only')?[...(params.has('app-only')?[]:[{id:'cli',label:'CLI',detail:'test CLI'}]),{id:'app',label:'APP',detail:'test desktop'}]:[{id:'cli',label:'CLI',detail:'test CLI'}],version:'1.0',cliVersion:'1.0',appVersion:null,pluginVersion:'1.0',configExists:!params.has('not-installed')||(params.has('config-only')&&id==='workbuddy'),configValid:params.get('state')!=='invalid',connectionState:params.get('state') || (currentModel?'configured':'not-configured'),configured:!!currentModel,configurationSynchronized:!!currentModel,currentModel,oauthConfiguration:id==='codex'&¤tOauth,codexNativeOauth:id==='codex'&&nativeOauth,modificationEnabled:!!currentModel,modificationState:currentModel?'applied':'unconfigured',backupAvailable:false,appliedModel:currentModel,claudeCodeModelMappings:id==='claude-code'?currentMappings[id]??null:null,claudeDesktopModelMappings:id==='claude-desktop'?currentMappings[id]??null:null,warnings:[],error:null})).map(status=>status.id==='codex'&&(nativeOauth||codexClosed)?{...status,configured:false,connectionState:'not-configured',configurationSynchronized:false,currentModel:null,appliedModel:null,modificationEnabled:false,modificationState:'unconfigured',oauthConfiguration:false}:status);
|
||||
if(cmd==='close_codex_config_modification') {
|
||||
closeCount++;
|
||||
if(params.has('fail-close')&&closeCount===1)throw new Error('模拟关闭失败,已回滚');
|
||||
|
||||
Reference in new issue
Block a user