shennian 0.4.71 → 0.4.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/publish-build-manifest.json +36 -31
- package/dist/src/agents/claude.js +4 -4
- package/dist/src/agents/model-registry/discovery.js +3 -3
- package/dist/src/agents/model-registry/parsers.js +4 -4
- package/dist/src/agents/model-registry/service.d.ts +6 -2
- package/dist/src/agents/model-registry/service.js +1 -1
- package/dist/src/agents/model-registry/types.d.ts +9 -1
- package/dist/src/agents/model-registry/types.js +1 -1
- package/dist/src/commands/agent-readiness.js +2 -2
- package/dist/src/commands/manager.js +1 -1
- package/dist/src/commands/worker.d.ts +11 -0
- package/dist/src/commands/worker.js +2 -0
- package/dist/src/daemon-ipc/agent-readiness.js +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/manager/prompt.d.ts +1 -1
- package/dist/src/manager/prompt.js +6 -6
- package/dist/src/manager/registry.d.ts +48 -2
- package/dist/src/manager/registry.js +1 -1
- package/dist/src/manager/runtime.d.ts +2 -2
- package/dist/src/manager/runtime.js +6 -6
- package/dist/src/manager/worker-ipc.d.ts +7 -0
- package/dist/src/manager/worker-ipc.js +1 -1
- package/dist/src/session/handlers/agent-workspace-validation.js +1 -1
- package/dist/src/session/queue.js +1 -1
- package/node_modules/@shennian/wire/dist/session.d.ts +6 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"jsMinified": true,
|
|
4
4
|
"minifier": "esbuild",
|
|
5
|
-
"fileCount":
|
|
5
|
+
"fileCount": 220,
|
|
6
6
|
"files": [
|
|
7
7
|
{
|
|
8
8
|
"file": "bin/shennian.js",
|
|
@@ -106,8 +106,8 @@
|
|
|
106
106
|
},
|
|
107
107
|
{
|
|
108
108
|
"file": "src/agents/claude.js",
|
|
109
|
-
"beforeBytes":
|
|
110
|
-
"afterBytes":
|
|
109
|
+
"beforeBytes": 18953,
|
|
110
|
+
"afterBytes": 8992
|
|
111
111
|
},
|
|
112
112
|
{
|
|
113
113
|
"file": "src/agents/codex-managed-permissions.js",
|
|
@@ -201,8 +201,8 @@
|
|
|
201
201
|
},
|
|
202
202
|
{
|
|
203
203
|
"file": "src/agents/model-registry/discovery.js",
|
|
204
|
-
"beforeBytes":
|
|
205
|
-
"afterBytes":
|
|
204
|
+
"beforeBytes": 11711,
|
|
205
|
+
"afterBytes": 5499
|
|
206
206
|
},
|
|
207
207
|
{
|
|
208
208
|
"file": "src/agents/model-registry/opencode-api.js",
|
|
@@ -211,8 +211,8 @@
|
|
|
211
211
|
},
|
|
212
212
|
{
|
|
213
213
|
"file": "src/agents/model-registry/parsers.js",
|
|
214
|
-
"beforeBytes":
|
|
215
|
-
"afterBytes":
|
|
214
|
+
"beforeBytes": 23995,
|
|
215
|
+
"afterBytes": 12356
|
|
216
216
|
},
|
|
217
217
|
{
|
|
218
218
|
"file": "src/agents/model-registry/runner.js",
|
|
@@ -221,13 +221,13 @@
|
|
|
221
221
|
},
|
|
222
222
|
{
|
|
223
223
|
"file": "src/agents/model-registry/service.js",
|
|
224
|
-
"beforeBytes":
|
|
225
|
-
"afterBytes":
|
|
224
|
+
"beforeBytes": 7401,
|
|
225
|
+
"afterBytes": 2929
|
|
226
226
|
},
|
|
227
227
|
{
|
|
228
228
|
"file": "src/agents/model-registry/types.js",
|
|
229
|
-
"beforeBytes":
|
|
230
|
-
"afterBytes":
|
|
229
|
+
"beforeBytes": 906,
|
|
230
|
+
"afterBytes": 495
|
|
231
231
|
},
|
|
232
232
|
{
|
|
233
233
|
"file": "src/agents/model-registry.js",
|
|
@@ -306,8 +306,8 @@
|
|
|
306
306
|
},
|
|
307
307
|
{
|
|
308
308
|
"file": "src/commands/agent-readiness.js",
|
|
309
|
-
"beforeBytes":
|
|
310
|
-
"afterBytes":
|
|
309
|
+
"beforeBytes": 3718,
|
|
310
|
+
"afterBytes": 3018
|
|
311
311
|
},
|
|
312
312
|
{
|
|
313
313
|
"file": "src/commands/agent.js",
|
|
@@ -361,8 +361,8 @@
|
|
|
361
361
|
},
|
|
362
362
|
{
|
|
363
363
|
"file": "src/commands/manager.js",
|
|
364
|
-
"beforeBytes":
|
|
365
|
-
"afterBytes":
|
|
364
|
+
"beforeBytes": 9692,
|
|
365
|
+
"afterBytes": 6336
|
|
366
366
|
},
|
|
367
367
|
{
|
|
368
368
|
"file": "src/commands/pair-authorization.js",
|
|
@@ -409,6 +409,11 @@
|
|
|
409
409
|
"beforeBytes": 13446,
|
|
410
410
|
"afterBytes": 6795
|
|
411
411
|
},
|
|
412
|
+
{
|
|
413
|
+
"file": "src/commands/worker.js",
|
|
414
|
+
"beforeBytes": 6654,
|
|
415
|
+
"afterBytes": 4212
|
|
416
|
+
},
|
|
412
417
|
{
|
|
413
418
|
"file": "src/config/index.js",
|
|
414
419
|
"beforeBytes": 2801,
|
|
@@ -416,8 +421,8 @@
|
|
|
416
421
|
},
|
|
417
422
|
{
|
|
418
423
|
"file": "src/daemon-ipc/agent-readiness.js",
|
|
419
|
-
"beforeBytes":
|
|
420
|
-
"afterBytes":
|
|
424
|
+
"beforeBytes": 4154,
|
|
425
|
+
"afterBytes": 2206
|
|
421
426
|
},
|
|
422
427
|
{
|
|
423
428
|
"file": "src/daemon-ipc/client.js",
|
|
@@ -486,8 +491,8 @@
|
|
|
486
491
|
},
|
|
487
492
|
{
|
|
488
493
|
"file": "src/index.js",
|
|
489
|
-
"beforeBytes":
|
|
490
|
-
"afterBytes":
|
|
494
|
+
"beforeBytes": 41017,
|
|
495
|
+
"afterBytes": 20498
|
|
491
496
|
},
|
|
492
497
|
{
|
|
493
498
|
"file": "src/log-redaction.js",
|
|
@@ -501,13 +506,13 @@
|
|
|
501
506
|
},
|
|
502
507
|
{
|
|
503
508
|
"file": "src/manager/prompt.js",
|
|
504
|
-
"beforeBytes":
|
|
505
|
-
"afterBytes":
|
|
509
|
+
"beforeBytes": 5067,
|
|
510
|
+
"afterBytes": 8427
|
|
506
511
|
},
|
|
507
512
|
{
|
|
508
513
|
"file": "src/manager/registry.js",
|
|
509
|
-
"beforeBytes":
|
|
510
|
-
"afterBytes":
|
|
514
|
+
"beforeBytes": 16879,
|
|
515
|
+
"afterBytes": 8079
|
|
511
516
|
},
|
|
512
517
|
{
|
|
513
518
|
"file": "src/manager/retired-external-channel-compat.js",
|
|
@@ -516,13 +521,13 @@
|
|
|
516
521
|
},
|
|
517
522
|
{
|
|
518
523
|
"file": "src/manager/runtime.js",
|
|
519
|
-
"beforeBytes":
|
|
520
|
-
"afterBytes":
|
|
524
|
+
"beforeBytes": 34449,
|
|
525
|
+
"afterBytes": 16700
|
|
521
526
|
},
|
|
522
527
|
{
|
|
523
528
|
"file": "src/manager/worker-ipc.js",
|
|
524
|
-
"beforeBytes":
|
|
525
|
-
"afterBytes":
|
|
529
|
+
"beforeBytes": 19731,
|
|
530
|
+
"afterBytes": 11321
|
|
526
531
|
},
|
|
527
532
|
{
|
|
528
533
|
"file": "src/manager/worker-markdown.js",
|
|
@@ -836,8 +841,8 @@
|
|
|
836
841
|
},
|
|
837
842
|
{
|
|
838
843
|
"file": "src/session/handlers/agent-workspace-validation.js",
|
|
839
|
-
"beforeBytes":
|
|
840
|
-
"afterBytes":
|
|
844
|
+
"beforeBytes": 9750,
|
|
845
|
+
"afterBytes": 5155
|
|
841
846
|
},
|
|
842
847
|
{
|
|
843
848
|
"file": "src/session/handlers/agents.js",
|
|
@@ -996,8 +1001,8 @@
|
|
|
996
1001
|
},
|
|
997
1002
|
{
|
|
998
1003
|
"file": "src/session/queue.js",
|
|
999
|
-
"beforeBytes":
|
|
1000
|
-
"afterBytes":
|
|
1004
|
+
"beforeBytes": 49538,
|
|
1005
|
+
"afterBytes": 21745
|
|
1001
1006
|
},
|
|
1002
1007
|
{
|
|
1003
1008
|
"file": "src/session/queued-chat-dispatch.js",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import p from"node:fs";import o from"node:path";import{createInterface as y}from"node:readline";import{randomUUID as f}from"node:crypto";import{AgentAdapter as S,registerAgent as E}from"./adapter.js";import{resolveBuiltinCommand as m,spawnAgentCommand as x,spawnResolvedCommandSync as v}from"./command-spec.js";import{buildAgentProcessEnv as P,buildManagedAgentProcessEnv as I,buildManagedNativeFullProcessEnv as C}from"../agent-env.js";import{buildPlatformInstructions as g}from"./platform-instructions.js";import{resolveManagedAgentAdapterEnforcement as k,isManagedAgentNativeFull as
|
|
2
|
-
${t.stderr??""}`,a=/(?:^|\s)--effort(?:\s|,|<)/.test(s);return
|
|
1
|
+
import p from"node:fs";import o from"node:path";import{createInterface as y}from"node:readline";import{randomUUID as f}from"node:crypto";import{AgentAdapter as S,registerAgent as E}from"./adapter.js";import{resolveBuiltinCommand as m,spawnAgentCommand as x,spawnResolvedCommandSync as v}from"./command-spec.js";import{buildAgentProcessEnv as P,buildManagedAgentProcessEnv as I,buildManagedNativeFullProcessEnv as C}from"../agent-env.js";import{buildPlatformInstructions as g}from"./platform-instructions.js";import{resolveManagedAgentAdapterEnforcement as k,isManagedAgentNativeFull as h}from"../security/managed-agent-policy.js";import{registerManagedAgentRuntimeSecurity as w}from"../security/managed-agent-runtime.js";import{resolveManagedRoomIpcPaths as A}from"../daemon-ipc/paths.js";import{CLAUDE_MANAGED_RUNTIME_SECURITY as _,compileClaudeManagedPermissions as T}from"./claude-managed-permissions.js";w("claude",_);function R(n){return n?.trim()||"default"}const M=new Set(["low","medium","high","xhigh","max"]),c=new Map;function O(n){const e=n?.trim();if(e){if(M.has(e))return e;throw new Error(`Unsupported Claude reasoning effort "${e}". Supported values: low, medium, high, xhigh, max.`)}}function X(){c.clear()}function N(n){const e=n.trim();return e?!e.includes("claude.ai connectors are disabled because"):!1}function D(){const n=m("claude");if(!n)return!1;const e=`${n.kind}:${n.path}:${n.command}:${n.args.join("\0")}`;if(c.has(e))return c.get(e)??!1;try{const t=v(n,["--help"],{encoding:"utf-8",stdio:["ignore","pipe","pipe"],timeout:3e3,env:process.env}),s=`${t.stdout??""}
|
|
2
|
+
${t.stderr??""}`,a=/(?:^|\s)--effort(?:\s|,|<)/.test(s);return c.set(e,a),a}catch{return c.set(e,!1),!1}}class F extends S{options;type="claude";get recoveryCapabilities(){return{inspectTerminal:!1,reattachRun:!1,resumeRun:!1,resumeSession:!0}}process=null;agentSessionId=null;sessionId=null;workDir=null;seq=0;runId="";hasEmittedText=!1;terminalState="open";pendingSuccess=null;persistNativeSession=!0;managedAgentPolicy=null;constructor(e={}){super(),this.options=e}externalChannel=null;shennianSessionId=null;extraEnv={};configure(e){this.shennianSessionId=e.sessionId??null,this.externalChannel=e.externalChannel??null,this.extraEnv=e.env??{},"managedAgentPolicy"in e&&(this.managedAgentPolicy=e.managedAgentPolicy??null),this.managedAgentPolicy&&(this.workDir=this.managedAgentPolicy.adapterPolicy.workDir)}async start(e,t,s,a){this.sessionId=e,this.workDir=this.managedAgentPolicy?.adapterPolicy.workDir??t,this.seq=0,this.persistNativeSession=a?.persistNativeSession!==!1,s&&(this.agentSessionId=s)}async send(e,t,s,a,l,r){if(r?.source==="room_activation"&&!this.managedAgentPolicy)throw new Error("managed_agent_policy_missing");await this.killProcess(),this.runId=f(),this.resetRunState();const i=["-p",e,"--output-format","stream-json","--verbose",...this.buildManagedPermissionConfig()?.args??[]];this.persistNativeSession||i.push("--no-session-persistence");const u=this.options.systemPrompt??g(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0,l);u&&i.push("--append-system-prompt",u),this.options.hidden&&i.push("--name","Shennian Manager Substrate"),(!this.managedAgentPolicy||h(this.managedAgentPolicy))&&process.getuid?.()!==0&&i.push("--dangerously-skip-permissions"),i.push("--model",R(t));const d=O(s);d&&D()&&i.push("--effort",d),this.agentSessionId&&i.push("--resume",this.agentSessionId),this.spawnAndParse(i)}async resume(e){await this.killProcess(),this.agentSessionId=e,this.runId=f(),this.resetRunState();const t=["--resume",e,"--output-format","stream-json","--verbose",...this.buildManagedPermissionConfig()?.args??[]],s=this.options.systemPrompt??g(this.workDir??process.cwd(),this.externalChannel,this.shennianSessionId??void 0);s&&t.push("--append-system-prompt",s),this.options.hidden&&t.push("--name","Shennian Manager Substrate"),(!this.managedAgentPolicy||h(this.managedAgentPolicy))&&process.getuid?.()!==0&&t.push("--dangerously-skip-permissions"),this.spawnAndParse(t)}async stop(){await this.killProcess()}spawnAndParse(e){const t=m("claude");if(!t){this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?'));return}const s=x(t,e,{cwd:this.workDir??void 0,stdio:["ignore","pipe","pipe"],env:this.buildProcessEnv()});this.process=s,y({input:s.stdout}).on("line",r=>{if(r.trim())try{const i=JSON.parse(r);this.handleStreamEvent(i)}catch{}});let l="";s.stderr?.on("data",r=>{const i=r.toString();if(l+=i,this.terminalState==="open")for(const u of i.split(`
|
|
3
3
|
`)){const d=u.trim();N(d)&&this.emitEvent({state:"delta",text:d+`
|
|
4
|
-
`})}}),s.on("close",r=>{this.process===s&&(this.process=null,this.handleProcessClose(r,l))}),s.on("error",r=>{this.process===s&&(this.process=null,r.code==="ENOENT"?this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?')):this.emit("error",r))})}buildManagedPermissionConfig(){const e=this.managedAgentPolicy;if(!e||
|
|
4
|
+
`})}}),s.on("close",r=>{this.process===s&&(this.process=null,this.handleProcessClose(r,l))}),s.on("error",r=>{this.process===s&&(this.process=null,r.code==="ENOENT"?this.emit("error",new Error('Command "claude" not found. Is Claude Code CLI installed?')):this.emit("error",r))})}buildManagedPermissionConfig(){const e=this.managedAgentPolicy;if(!e||h(e))return null;const t=L();return T(k(e),e.adapterPolicy.workDir,{internalReadPaths:t.readPaths,internalUnixSockets:t.unixSockets,shellSubprocessPolicy:e.environmentPolicy.shellSubprocess})}buildProcessEnv(){return this.managedAgentPolicy?h(this.managedAgentPolicy)?C({NO_COLOR:"1",...this.extraEnv}):I({agentType:"claude",providerEnv:this.extraEnv,sessionEnv:this.extraEnv,runtimeEnv:{NO_COLOR:"1"}}):P(this.extraEnv)}handleStreamEvent(e){if(e.type==="system"&&e.subtype==="init"&&e.session_id){this.agentSessionId=e.session_id,this.emitEvent({state:"start",agentSessionId:this.agentSessionId});return}if(!(e.type==="system"&&e.subtype==="api_retry"&&e.error==="authentication_failed")){if(e.type==="assistant"){if(e.message?.content){for(const t of e.message.content)if(t.type==="text"&&t.text){const s=this.hasEmittedText?`
|
|
5
5
|
|
|
6
6
|
`:"";this.emitEvent({state:"delta",text:s+t.text}),this.hasEmittedText=!0}else t.type==="thinking"&&t.thinking?this.emitEvent({state:"delta",text:t.thinking,thinking:!0}):t.type==="tool_use"&&this.emitEvent({state:"tool-call",name:t.name,args:t.input});return}if(e.subtype==="text"&&e.text){const t=this.hasEmittedText?`
|
|
7
7
|
|
|
8
|
-
`:"";this.emitEvent({state:"delta",text:t+e.text}),this.hasEmittedText=!0}else e.subtype==="thinking"&&e.thinking?this.emitEvent({state:"delta",text:e.thinking,thinking:!0}):e.subtype==="tool_use"&&this.emitEvent({state:"tool-call",name:e.name,args:e.input});return}if(e.type==="result")if(e.subtype==="tool_result"){const t=typeof e.content=="string"?e.content:JSON.stringify(e.content);this.emitEvent({state:"tool-result",name:e.name,result:t})}else if(e.subtype==="success"){e.session_id&&(this.agentSessionId=e.session_id);const t=typeof e.result=="string"?e.result:"";!this.hasEmittedText&&t.trim()&&(this.emitEvent({state:"delta",text:t}),this.hasEmittedText=!0);const s=e.usage??e.message?.usage;this.pendingSuccess={agentSessionId:this.agentSessionId??void 0,usage:s?{inputTokens:s.input_tokens,outputTokens:s.output_tokens}:void 0}}else e.subtype==="error"&&this.emitErrorIfOpen({state:"error",message:e.error??e.result??"unknown error"})}handleProcessClose(e,t){if(e!==0&&e!==null){const s=t.trim()||`claude exited with code ${e}`;this.emitErrorIfOpen({state:"error",message:s});return}if(!this.hasEmittedText){this.emitErrorIfOpen({state:"error",message:"Claude completed without response text"});return}this.emitFinalIfOpen({state:"final",agentSessionId:this.pendingSuccess?.agentSessionId??this.agentSessionId??void 0,usage:this.pendingSuccess?.usage})}emitFinalIfOpen(e){this.terminalState==="open"&&(this.terminalState="final",this.emitEvent(e))}emitErrorIfOpen(e){this.terminalState==="open"&&(this.terminalState="error",this.emitEvent(e))}resetRunState(){this.seq=0,this.hasEmittedText=!1,this.terminalState="open",this.pendingSuccess=null}emitEvent(e){const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}async killProcess(){const e=this.process;e&&(this.process=null,e.kill("SIGTERM"),await new Promise(t=>{e.on("close",t),setTimeout(()=>{e.kill("SIGKILL"),t()},3e3)}))}}function L(){const n=A(),e=[n.secretFile],t=n.transport==="unix_socket"?[n.endpoint]:[];n.transport==="unix_socket"&&e.push(n.endpoint);const s=m("pi");return s?.path&&e.push(...U(s.path)),{readPaths:[...new Set(e)].sort(),unixSockets:[...new Set(t)].sort()}}function U(n){const e=o.normalize(n.trim());if(!e||!o.isAbsolute(e))return[];const t=[e];try{const s=p.realpathSync(e);t.push(s,o.dirname(s),o.dirname(o.dirname(s)));let a=o.dirname(s);for(let l=0;l<8;l+=1){const r=o.join(a,"package.json");try{if(JSON.parse(p.readFileSync(r,"utf8")).name==="shennian"){t.push(a);break}}catch{}const i=o.dirname(a);if(i===a)break;a=i}}catch{}return[...new Set(t)].sort()}E("claude",()=>new F);export{F as ClaudeAdapter,R as normalizeClaudeModelId,
|
|
8
|
+
`:"";this.emitEvent({state:"delta",text:t+e.text}),this.hasEmittedText=!0}else e.subtype==="thinking"&&e.thinking?this.emitEvent({state:"delta",text:e.thinking,thinking:!0}):e.subtype==="tool_use"&&this.emitEvent({state:"tool-call",name:e.name,args:e.input});return}if(e.type==="result")if(e.subtype==="tool_result"){const t=typeof e.content=="string"?e.content:JSON.stringify(e.content);this.emitEvent({state:"tool-result",name:e.name,result:t})}else if(e.subtype==="success"){e.session_id&&(this.agentSessionId=e.session_id);const t=typeof e.result=="string"?e.result:"";!this.hasEmittedText&&t.trim()&&(this.emitEvent({state:"delta",text:t}),this.hasEmittedText=!0);const s=e.usage??e.message?.usage;this.pendingSuccess={agentSessionId:this.agentSessionId??void 0,usage:s?{inputTokens:s.input_tokens,outputTokens:s.output_tokens}:void 0}}else e.subtype==="error"&&this.emitErrorIfOpen({state:"error",message:e.error??e.result??"unknown error"})}}handleProcessClose(e,t){if(e!==0&&e!==null){const s=t.trim()||`claude exited with code ${e}`;this.emitErrorIfOpen({state:"error",message:s});return}if(!this.hasEmittedText){this.emitErrorIfOpen({state:"error",message:"Claude completed without response text"});return}this.emitFinalIfOpen({state:"final",agentSessionId:this.pendingSuccess?.agentSessionId??this.agentSessionId??void 0,usage:this.pendingSuccess?.usage})}emitFinalIfOpen(e){this.terminalState==="open"&&(this.terminalState="final",this.emitEvent(e))}emitErrorIfOpen(e){this.terminalState==="open"&&(this.terminalState="error",this.emitEvent(e))}resetRunState(){this.seq=0,this.hasEmittedText=!1,this.terminalState="open",this.pendingSuccess=null}emitEvent(e){const t={...e,runId:this.runId,seq:this.seq++};this.emit("agentEvent",t)}async killProcess(){const e=this.process;e&&(this.process=null,e.kill("SIGTERM"),await new Promise(t=>{e.on("close",t),setTimeout(()=>{e.kill("SIGKILL"),t()},3e3)}))}}function L(){const n=A(),e=[n.secretFile],t=n.transport==="unix_socket"?[n.endpoint]:[];n.transport==="unix_socket"&&e.push(n.endpoint);const s=m("pi");return s?.path&&e.push(...U(s.path)),{readPaths:[...new Set(e)].sort(),unixSockets:[...new Set(t)].sort()}}function U(n){const e=o.normalize(n.trim());if(!e||!o.isAbsolute(e))return[];const t=[e];try{const s=p.realpathSync(e);t.push(s,o.dirname(s),o.dirname(o.dirname(s)));let a=o.dirname(s);for(let l=0;l<8;l+=1){const r=o.join(a,"package.json");try{if(JSON.parse(p.readFileSync(r,"utf8")).name==="shennian"){t.push(a);break}}catch{}const i=o.dirname(a);if(i===a)break;a=i}}catch{}return[...new Set(t)].sort()}E("claude",()=>new F);export{F as ClaudeAdapter,R as normalizeClaudeModelId,O as normalizeClaudeReasoningEffort,X as resetClaudeCapabilityCacheForTests,L as resolveClaudeManagedInternalAccess,U as resolveClaudeShennianCliReadPaths,N as shouldForwardClaudeStderrLine,D as supportsClaudeReasoningEffort};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createInterface as
|
|
2
|
-
`,p=>{p&&(clearTimeout(c),e.delete(t),a(p))})}):Promise.reject(new Error("codex app-server stdin unavailable"))}async function
|
|
3
|
-
${n.stderr}`)?s:s.filter(i=>i.id!=="fable")}async function
|
|
1
|
+
import{createInterface as k}from"node:readline";import{resolveBuiltinCommand as l,spawnResolvedCommand as w}from"../command-spec.js";import{fallbackClaudeAliasModels as E,discoverClaudeAliasModelsFromEnv as x,fallbackCodexModels as M,fallbackWorkBuddyModels as R,fallbackGeminiModels as O,parseCodexAppServerModels as A,parseCursorModels as D,parseOpenCodeModels as I}from"./parsers.js";import{runResolvedCommand as m}from"./runner.js";import{DISCOVERY_WORKDIR as b,ModelDiscoveryFallbackError as C}from"./types.js";import{buildAgentProcessEnv as _,readLatestUserEnv as S}from"../../agent-env.js";import{CODEX_APP_SERVER_CLIENT_INFO as T}from"../codex-utils.js";import{PiRpcClient as P}from"../pi-rpc-client.js";import{loadConfig as $}from"../../config/index.js";import{discoverOpenCodeModelsViaApi as L}from"./opencode-api.js";function q(r){const e=r instanceof Error?r.message:"";return/timed out/i.test(e)?"app_server_timeout":/\berror\b|invalid|unsupported|unknown (?:method|field)/i.test(e)?"app_server_rpc_error":"app_server_unavailable"}function v(r,e,t,s,n,i){return r.stdin?new Promise((o,a)=>{const c=setTimeout(()=>{e.delete(t),a(new Error(`codex app-server request timed out: ${s}`))},i);e.set(t,{resolve:o,reject:a,timer:c}),r.stdin.write(`${JSON.stringify({id:t,method:s,params:n})}
|
|
2
|
+
`,p=>{p&&(clearTimeout(c),e.delete(t),a(p))})}):Promise.reject(new Error("codex app-server stdin unavailable"))}async function j(r){const e=w(r,["app-server","--listen","stdio://"],{cwd:b,stdio:["pipe","pipe","pipe"],env:_({NO_COLOR:"1"})}),t=new Map;let s=1;k({input:e.stdout}).on("line",i=>{if(!i.trim())return;let o;try{o=JSON.parse(i)}catch{return}if(o.id==null)return;const a=t.get(o.id);a&&(clearTimeout(a.timer),t.delete(o.id),o.error?a.reject(new Error(o.error.message||`codex app-server error ${o.error.code??""}`.trim())):a.resolve(o.result))});try{await v(e,t,s++,"initialize",{clientInfo:T,capabilities:{experimentalApi:!0}},1e4);const[i,o]=await Promise.all([v(e,t,s++,"model/list",{},15e3),v(e,t,s++,"config/read",{},15e3).catch(()=>null)]),a=typeof o=="object"&&o!==null&&"config"in o?o.config:void 0;return A({...typeof i=="object"&&i!==null?i:{},config:a})}finally{for(const[i,o]of t)clearTimeout(o.timer),o.reject(new Error("codex app-server stopped")),t.delete(i);e.kill("SIGTERM"),setTimeout(()=>e.kill("SIGKILL"),1e3).unref()}}async function F(){const r=l("cursor");if(!r)return[];const e=await m(r,["--list-models"]);return D(e.stdout)}async function G(){const r=l("opencode");if(!r)return[];const e=await L().catch(()=>[]);if(e.length>0)return e;const t=await m(r,["models"]);return I(t.stdout)}async function N(){const r={id:"shennian-dashscope/deepseek-v4-flash-0731",name:"DeepSeek V4 Flash",provider:"shennian-dashscope",isDefault:!0,supportedReasoningEfforts:["low","high","max"].map(n=>({id:n,name:n})),defaultReasoningEffort:"high"},e=l("pi-coding-agent");if(!e)return[];if($().machineToken?.trim())return[r];const t=w(e,["--mode","rpc","--no-session","--offline","--no-extensions","--no-skills","--no-prompt-templates","--no-context-files","--no-tools"],{cwd:b,stdio:["pipe","pipe","pipe"],env:_({NO_COLOR:"1"})}),s=new P(t,{requestTimeoutMs:1e4});try{const[n,i]=await Promise.all([s.request("get_available_models"),s.request("get_state")]),o=n.data&&typeof n.data=="object"?n.data:{},a=i.data&&typeof i.data=="object"?i.data:{},c=typeof a.model?.id=="string"&&typeof a.model.provider=="string"?`${a.model.provider}/${a.model.id}`:null;return Array.isArray(o.models)?o.models.flatMap(f=>{if(!f||typeof f!="object")return[];const d=f;if(typeof d.id!="string"||typeof d.provider!="string")return[];const h=`${d.provider}/${d.id}`,g=d.reasoning===!0?["off","minimal","low","medium","high","xhigh","max"].map(y=>({id:y,name:y})):void 0;return[{id:h,name:typeof d.name=="string"&&d.name.trim()?d.name:d.id,provider:d.provider,isDefault:h===c,...g?{supportedReasoningEfforts:g,defaultReasoningEffort:"medium"}:{}}]}):[]}catch{return[]}finally{s.close(),t.kill("SIGTERM"),setTimeout(()=>t.kill("SIGKILL"),1e3).unref()}}async function V(){const r=l("claude");if(!r)return[];const e=S(),t=x(e);if(t.length>0)return t;const s=E(e),n=await m(r,["--help"],3e3).catch(()=>null);return!n||/\bfable\b/i.test(`${n.stdout}
|
|
3
|
+
${n.stderr}`)?s:s.filter(i=>i.id!=="fable")}async function B(){const r=l("codex");if(!r)return[];let e;try{e=await j(r)}catch(t){throw new C("codex",q(t),M())}if(e.length===0)throw new C("codex","empty_model_list",M());return e}async function K(){return l("gemini")?O():[]}const u=[{id:"qwen3.6-plus",name:"Qwen 3.6 Plus",provider:"dashscope",isDefault:!0}],U=[{id:"codex",name:"Codex",provider:"shennian",isDefault:!0},{id:"claude",name:"Claude Code",provider:"shennian"}];async function W(r){if(!r.serverUrl||!r.authToken)return u;try{const e=await fetch(`${r.serverUrl.replace(/\/$/,"")}/api/models`,{headers:{Authorization:`Bearer ${r.authToken}`}});if(!e.ok)return u;const t=await e.json(),s=(t.models??[]).map(n=>({id:n.id,name:n.name?.trim()||n.id,provider:n.provider,isDefault:n.id===t.default}));return s.length>0?s:u}catch{return u}}async function z(r,e){switch(r){case"claude":return V();case"codex":return B();case"workbuddy":return l("workbuddy")?R():[];case"gemini":return K();case"cursor":return F();case"openclaw":return[];case"opencode":return G();case"pi":return W(e);case"pi-coding-agent":return N();case"manager":return U}}async function ne(r,e){return r.type.startsWith("custom:")?r.models??[]:z(r.type,e)}export{ne as discoverModelsForAgent};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function b(e){return e.replace(/\u001b\[[0-9;?]*[a-zA-Z]/g,"").replace(/\u001b\][^\u0007]*\u0007/g,"").replace(/[\u0000-\u0008\u000b-\u001f\u007f]/g,"")}function m(e){const t=new Set,n=[];for(const o of e)!o.id||t.has(o.id)||(t.add(o.id),n.push(o));return n}function y(e){return e&&e[0].toUpperCase()+e.slice(1)}function
|
|
2
|
-
`)){const i=o.trim().match(/^(\S+)\s+-\s+(.+?)(?:\s+\(([^)]+)\))?$/);if(!i)continue;const[,s,r,d]=i,l=d?.split(",").map(u=>u.trim().toLowerCase())??[];t.push({id:s,name:r.trim()||w(s),description:d?.trim(),isDefault:l.includes("default")||l.includes("current")})}return m(t)}function
|
|
3
|
-
`).map(n=>n.trim()).filter(Boolean).filter(n=>!n.includes(" ")).map(n=>({id:n,name:n,provider:n.includes("/")?n.split("/")[0]:void 0}));return m(t)}function
|
|
4
|
-
`)){const i=o.match(/\b(gpt-[a-z0-9][a-z0-9.-]*)\b/i);if(!i)continue;const s=i[1].trim(),r=o.replace(s,"").replace(/^[^\w]+/,"").trim()||void 0;n.push({id:s,name:
|
|
1
|
+
function b(e){return e.replace(/\u001b\[[0-9;?]*[a-zA-Z]/g,"").replace(/\u001b\][^\u0007]*\u0007/g,"").replace(/[\u0000-\u0008\u000b-\u001f\u007f]/g,"")}function m(e){const t=new Set,n=[];for(const o of e)!o.id||t.has(o.id)||(t.add(o.id),n.push(o));return n}function y(e){return e&&e[0].toUpperCase()+e.slice(1)}function M(e){return e.split("-").map(t=>t==="gpt"?"GPT":t==="codex"?"Codex":/^\d/.test(t)?t:y(t)).join("-")}function A(e){switch(e){case"low":return"Low";case"medium":return"Medium";case"high":return"High";case"xhigh":return"Extra High";default:return y(e)}}const E=[{id:"low",name:"Low"},{id:"medium",name:"Medium"},{id:"high",name:"High"},{id:"xhigh",name:"Extra High"},{id:"max",name:"Max"},{id:"ultra",name:"Ultra"}],C=[{id:"gpt-6-astra",name:"GPT-6 Astra",description:"Most capable Codex model for complex, demanding work.",provider:"openai",supportedReasoningEfforts:E,defaultReasoningEffort:"medium"},{id:"gpt-5.6-sol",name:"GPT-5.6 Sol",description:"Reliable agentic workhorse for everyday tasks.",provider:"openai",supportedReasoningEfforts:E,defaultReasoningEffort:"low"},{id:"gpt-5.6-terra",name:"GPT-5.6 Terra",description:"Balanced agentic coding model for everyday work.",provider:"openai",supportedReasoningEfforts:E,defaultReasoningEffort:"medium"},{id:"gpt-5.6-luna",name:"GPT-5.6 Luna",description:"Fast and affordable agentic coding model.",provider:"openai",supportedReasoningEfforts:E.filter(e=>e.id!=="ultra"),defaultReasoningEffort:"medium"},{id:"gpt-5.5",name:"GPT-5.5",description:"Proven previous-generation model for coding and general work.",provider:"openai",supportedReasoningEfforts:E.filter(e=>e.id!=="max"&&e.id!=="ultra"),defaultReasoningEffort:"medium"}];function O(e){const t={...e};return e.supportedReasoningEfforts&&(t.supportedReasoningEfforts=e.supportedReasoningEfforts.map(n=>({...n}))),e.additionalSpeedTiers&&(t.additionalSpeedTiers=[...e.additionalSpeedTiers]),t}function L(e,t){const n=t??e.find(i=>i.isDefault)?.id,o=m([...e.map(O),...C.map(i=>O(i))]);return n?o.map(i=>({...i,isDefault:i.id===n})):o}function G(){return C.map((e,t)=>({...O(e),...t===0?{isDefault:!0}:{}}))}function H(){return[{id:"auto",name:"Auto",provider:"workbuddy",isDefault:!0,supportedReasoningEfforts:["minimal","low","medium","high","xhigh","max"].map(e=>({id:e,name:A(e)})),defaultReasoningEffort:"medium"}]}function w(e){return e.split("-").map(t=>/^\d/.test(t)?t:y(t)).join(" ")}function _(e,t,n=!1){const o=t.toLowerCase().replace(/\s+/g,"-");return`gemini-${e}-${o}${n?"-preview":""}`}function I(e){const t=[],n=b(e);for(const o of n.split(`
|
|
2
|
+
`)){const i=o.trim().match(/^(\S+)\s+-\s+(.+?)(?:\s+\(([^)]+)\))?$/);if(!i)continue;const[,s,r,d]=i,l=d?.split(",").map(u=>u.trim().toLowerCase())??[];t.push({id:s,name:r.trim()||w(s),description:d?.trim(),isDefault:l.includes("default")||l.includes("current")})}return m(t)}function U(e){try{const n=(JSON.parse(e).models??[]).filter(o=>o.available).map(o=>({id:o.key,name:o.name?.trim()||o.key,provider:o.key.split("/")[0],description:o.tags?.join(", "),isDefault:o.tags?.includes("default")??!1}));return m(n)}catch{return[]}}function B(e){const t=b(e).split(`
|
|
3
|
+
`).map(n=>n.trim()).filter(Boolean).filter(n=>!n.includes(" ")).map(n=>({id:n,name:n,provider:n.includes("/")?n.split("/")[0]:void 0}));return m(t)}function V(e,t){if(!e||typeof e!="object")return[];const n=e;if(!Array.isArray(n.all)||!Array.isArray(n.connected))return[];const o=new Set(n.connected.filter(u=>typeof u=="string")),i=t&&typeof t=="object"?t:{},s=typeof i.model=="string"?i.model:"",r=i.provider&&typeof i.provider=="object"?i.provider:{},d=new Set;for(const[u,a]of Object.entries(r)){if(!a||typeof a!="object")continue;const f=a.models;if(!(!f||typeof f!="object"))for(const p of Object.keys(f))d.add(`${u}/${p}`)}const l=[];for(const u of n.all){if(!u||typeof u!="object")continue;const a=u;if(!(typeof a.id!="string"||!o.has(a.id))&&!(!a.models||typeof a.models!="object"))for(const[f,p]of Object.entries(a.models)){if(!p||typeof p!="object")continue;const c=p;if(c.status==="deprecated"||c.status==="unavailable"||c.capabilities?.input?.text===!1||c.capabilities?.output?.text===!1||c.capabilities?.toolcall===!1)continue;const g=typeof c.id=="string"&&c.id?c.id:f,h=`${a.id}/${g}`;l.push({id:h,name:typeof c.name=="string"&&c.name.trim()?c.name:h,provider:a.id,...h===s?{isDefault:!0}:{}})}}return m(l).sort((u,a)=>{const f=p=>p.id===s?0:d.has(p.id)?1:p.provider&&Object.hasOwn(r,p.provider)?2:3;return f(u)-f(a)||u.id.localeCompare(a.id)})}function z(e){const t=b(e).replace(/\s+/g," "),n=[[/\d+\.Default\(recommended\).*?(?:Sonnet|currently\s*Sonnet)\s*([\d.]+)/i,"default","Default (recommended)"],[/\d+\.Best.*?Opus\s*([\d.]+)/i,"best","Best","Most capable available model"],[/\d+\.Fable.*?Fable\s*([\d.]+)/i,"fable","Fable","Most capable for the hardest, longest-running tasks"],[/\d+\.Opus\(1Mcontext\).*?Opus\s*([\d.]+)/i,"opus[1m]","Opus (1M context)"],[/\d+\.OpusPlan.*?Opus\s*([\d.]+)/i,"opusplan","Opus Plan","Opus for planning \xB7 Sonnet for execution"],[/\d+\.Opus(?!\(1Mcontext\)).*?Opus\s*([\d.]+)/i,"opus","Opus"],[/\d+\.Sonnet\(1Mcontext\).*?Sonnet\s*([\d.]+)/i,"sonnet[1m]","Sonnet (1M context)"],[/\d+\.Sonnet(?!\(1Mcontext\)).*?Sonnet\s*([\d.]+)/i,"sonnet","Sonnet"],[/\d+\.Haiku.*?Haiku\s*([\d.]+)/i,"haiku","Haiku"]],o=[];for(const[d,l,u,a]of n){const f=t.match(d);f&&o.push(v({id:l,name:u,description:a?`${a} \xB7 v${f[1]}`:`v${f[1]}`,provider:"anthropic",isDefault:l==="default"}))}if(o.length>0)return m(o);const i=[],s=t.match(/currently\s*(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)/i),r={sonnet:"sonnet",opus:"opus",haiku:"haiku"};for(const d of t.matchAll(/\b(Sonnet|Opus|Haiku)\s*([34](?:\.\d)?)\b/gi)){const l=(d[1]??"").toLowerCase(),u=r[l];if(!u)continue;const a=d[2]??"",f=s&&s[1]?.toLowerCase()===l&&s[2]===a;i.push(v({id:u,name:`${y(l)} ${a}`,provider:"anthropic",isDefault:!!f}))}return m(i)}function T(e,t){const n=Math.max(e.length,t.length);for(let o=0;o<n;o++){const i=e[o]??-1,s=t[o]??-1;if(i!==s)return i-s}return 0}function $(e,t){const n=e.match(new RegExp(`^claude-${t}-([0-9]+(?:-[0-9]+)*)$`,"i"));if(!n?.[1])return null;const o=n[1].split("-").map(i=>Number.parseInt(i,10)).filter(i=>Number.isFinite(i));return o.length===0||o.length>2?null:o}function F(e){if(e?.length)return`v${e.join(".")}`}const S={default:"Default (recommended)",sonnet:"Sonnet",opus:"Opus",haiku:"Haiku"},D={default:"ANTHROPIC_MODEL",sonnet:"ANTHROPIC_DEFAULT_SONNET_MODEL",opus:"ANTHROPIC_DEFAULT_OPUS_MODEL",haiku:"ANTHROPIC_DEFAULT_HAIKU_MODEL"},P=[{id:"max",name:"Max"}],j=[{id:"low",name:"Low"},{id:"medium",name:"Medium"},{id:"high",name:"High"},{id:"xhigh",name:"Extra High"},{id:"max",name:"Max"}];function v(e){return{...e,supportedReasoningEfforts:j,defaultReasoningEffort:"medium"}}function x(e,t){return e[t]?.trim()||null}function R(e,t){const n=x(t,"ANTHROPIC_BASE_URL")?.toLowerCase()??"";return n.includes("deepseek.com")||e.toLowerCase().startsWith("deepseek-")?"deepseek":n?"custom":"anthropic"}function k(e){const t=new Set;for(const o of Object.values(D)){const i=x(e,o);i&&t.add(i)}const n=Array.from(t).map((o,i)=>{const s=R(o,e),r={id:o,name:o,provider:s,isDefault:i===0};return s==="deepseek"?{...r,supportedReasoningEfforts:P,defaultReasoningEffort:x(e,"CLAUDE_CODE_EFFORT_LEVEL")??"max"}:v(r)});return m(n)}function K(e=process.env){return k(e)}function N(e,t=process.env){return e.map(n=>{if(!["default","sonnet","opus","haiku"].includes(n.id))return n;const o=n.id,i=x(t,D[o]);if(!i)return n;const r=`Claude Code alias: ${S[o]}`;return{...n,name:i,description:n.description?`${r} \xB7 ${n.description}`:r,provider:R(i,t)}})}function q(e){const t=b(e),n=new Map;for(const i of["sonnet","opus","haiku"])for(const s of t.matchAll(new RegExp(`\\bclaude-${i}-[0-9.-]+\\b`,"gi"))){const r=s[0].trim().toLowerCase().replace(/\./g,"-").replace(/-+$/g,""),d=$(r,i);if(!d)continue;const l=n.get(i);(!l||T(l,d)<0)&&n.set(i,d)}const o=[];for(const i of["default","sonnet","opus","haiku"]){if(!new RegExp(`\\b${i}\\b`,"i").test(t))continue;const s=(i==="default"?n.get("sonnet"):n.get(i))??null;o.push(v({id:i,name:S[i],description:F(s),provider:"anthropic",isDefault:i==="default"}))}return m(o)}function W(e=process.env){const t=k(e);return t.length>0?t:N([{id:"default",name:"Default (recommended)",description:"Recommended model for your account",provider:"anthropic",isDefault:!0},{id:"sonnet",name:"Sonnet",description:"Latest Sonnet \xB7 everyday coding",provider:"anthropic"},{id:"fable",name:"Fable",description:"Most capable for the hardest, longest-running tasks",provider:"anthropic"},{id:"opus",name:"Opus",description:"Latest Opus \xB7 complex reasoning",provider:"anthropic"},{id:"haiku",name:"Haiku",description:"Fast and efficient \xB7 simple tasks",provider:"anthropic"},{id:"best",name:"Best",description:"Most capable available model",provider:"anthropic"},{id:"opus[1m]",name:"Opus (1M context)",description:"Latest Opus \xB7 long sessions",provider:"anthropic"},{id:"sonnet[1m]",name:"Sonnet (1M context)",description:"Latest Sonnet \xB7 long sessions",provider:"anthropic"},{id:"opusplan",name:"Opus Plan",description:"Opus for planning \xB7 Sonnet for execution",provider:"anthropic"}],e).map(n=>n.id==="haiku"?n:v(n))}function X(e){const t=b(e),n=[];for(const o of t.split(`
|
|
4
|
+
`)){const i=o.match(/\b(gpt-[a-z0-9][a-z0-9.-]*)\b/i);if(!i)continue;const s=i[1].trim(),r=o.replace(s,"").replace(/^[^\w]+/,"").trim()||void 0;n.push({id:s,name:M(s),description:r,provider:"openai",isDefault:/\bcurrent\b/i.test(o)||/\bselected\b/i.test(o)})}return m(n)}function J(e){const t=typeof e=="object"&&e!==null?e:{},n=typeof t.config?.model=="string"?t.config.model:void 0,o=typeof t.config?.model_reasoning_effort=="string"?t.config.model_reasoning_effort:void 0,i=[];for(const s of t.data??[]){if(typeof s!="object"||s===null)continue;const r=s,d=typeof r.id=="string"?r.id:typeof r.model=="string"?r.model:"";if(!d)continue;const l=typeof r.displayName=="string"?r.displayName:typeof r.name=="string"?r.name:void 0,u=typeof r.description=="string"?r.description:void 0,a=typeof r.defaultReasoningEffort=="string"?r.defaultReasoningEffort:void 0,f=Array.isArray(r.supportedReasoningEfforts)?r.supportedReasoningEfforts.map(c=>{if(typeof c!="object"||c===null)return null;const g=c,h=typeof g.reasoningEffort=="string"?g.reasoningEffort:typeof g.id=="string"?g.id:"";return h?{id:h,name:A(h),description:typeof g.description=="string"?g.description:void 0}:null}).filter(c=>c!=null):void 0,p=Array.isArray(r.additionalSpeedTiers)?r.additionalSpeedTiers.filter(c=>typeof c=="string"):void 0;i.push({id:d,name:l||M(d),description:u,provider:"openai",isDefault:n?n===d:r.isDefault===!0,supportedReasoningEfforts:f,defaultReasoningEffort:a,additionalSpeedTiers:p})}return n&&!i.some(s=>s.id===n)&&i.unshift({id:n,name:M(n),provider:"openai",isDefault:!0,defaultReasoningEffort:o}),L(m(i),n)}function Z(e){const t=b(e),n=[];for(const o of t.matchAll(/\b(?:auto-)?gemini-[a-z0-9.-]+\b/gi)){const i=o[0].trim();n.push({id:i,name:i,provider:"google",isDefault:/\bcurrent\b/i.test(t)&&t.includes(i)})}for(const o of t.matchAll(/\bGemini\s*(\d(?:\.\d)?)\s*(Pro|Flash(?:[- ]Lite)?)\s*(Preview)?\b/gi)){const i=o[1]??"",s=(o[2]??"").replace(/\s+/g,"-"),r=!!o[3],d=_(i,s,r);n.push({id:d,name:`Gemini ${i} ${s.replace(/-/g," ")}`.trim(),provider:"google",isDefault:/\bcurrent\b/i.test(t)&&t.includes(o[0]??"")})}for(const o of t.matchAll(/\bAuto\s*Gemini\s*(\d(?:\.\d)?)\b/gi)){const i=o[1]??"",s=`auto-gemini-${i}`;n.push({id:s,name:`Auto Gemini ${i}`,provider:"google",isDefault:/\bcurrent\b/i.test(t)&&t.includes(o[0]??"")})}return m(n)}function Q(){return[{id:"gemini-2.5-pro",name:"Gemini 2.5 Pro",provider:"google",isDefault:!0},{id:"gemini-2.5-flash",name:"Gemini 2.5 Flash",provider:"google"},{id:"auto-gemini-2.5",name:"Auto Gemini 2.5",provider:"google"}]}export{N as applyClaudeModelEnvOverrides,K as discoverClaudeAliasModelsFromEnv,W as fallbackClaudeAliasModels,G as fallbackCodexModels,Q as fallbackGeminiModels,H as fallbackWorkBuddyModels,R as inferClaudeOverrideProvider,q as parseClaudeBinaryModels,z as parseClaudeModels,J as parseCodexAppServerModels,X as parseCodexModels,I as parseCursorModels,Z as parseGeminiModels,U as parseOpenClawModels,B as parseOpenCodeModels,V as parseOpenCodeProviderModels,x as readEnvValue,b as stripAnsi};
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { AgentInfo } from '@shennian/wire';
|
|
2
2
|
import type { DetectedAgent } from '../detect.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type DiscoveryContext } from './types.js';
|
|
4
|
+
type ResolveAgentInfoOptions = {
|
|
5
|
+
forceRefresh?: boolean;
|
|
6
|
+
};
|
|
4
7
|
export declare function getCachedAgentInfos(detectedAgents: DetectedAgent[]): AgentInfo[];
|
|
5
8
|
export declare function refreshAgentInfos(detectedAgents: DetectedAgent[], context: DiscoveryContext): Promise<AgentInfo[]>;
|
|
6
|
-
export declare function resolveAgentInfos(detectedAgents: DetectedAgent[], context: DiscoveryContext): Promise<AgentInfo[]>;
|
|
9
|
+
export declare function resolveAgentInfos(detectedAgents: DetectedAgent[], context: DiscoveryContext, options?: ResolveAgentInfoOptions): Promise<AgentInfo[]>;
|
|
10
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getAgentConfigSummary as
|
|
1
|
+
import{getAgentConfigSummary as y}from"../config-status.js";import{isCacheFresh as A,readCache as v,writeCache as S}from"./cache.js";import{discoverModelsForAgent as M}from"./discovery.js";import{ModelDiscoveryFallbackError as R}from"./types.js";import{getAgentRuntimeSummary as g}from"../runtime-compatibility.js";import{resolveManagedAgentRuntimeProtection as b}from"../../security/managed-agent-runtime.js";const x={claude:"claude-alias-v2",codex:"codex-app-server-v2",opencode:"opencode-connected-v1"};function F(o,s,e){console.warn(`[model-discovery] agent=${o} source=fallback reason=${s} usedCache=${e}`)}function E(o){const s=new Set,e=[];for(const i of o)!i.id||s.has(i.id)||(s.add(i.id),e.push(i));return e}function C(o){const s=o.type!=="manager"&&o.type!=="pi"&&o.type!=="openclaw",e=s,i=e&&!o.type.startsWith("acp:"),r=e?b({agentType:o.type,runtimeVersion:o.version,platform:o.runtimePlatform,isWsl:o.runtimeIsWsl,executableFingerprint:o.executableFingerprint,requireExecutableFingerprint:!0}):null,p=i&&(r?.level==="hard"||r?.level==="partial"),t=e,n=p||t,a=s;return{supportsStandardSession:s,supportsManagedAgent:p,supportsManagedNativeFull:t,supportsRoomTools:n,supportsWorker:a,supportsManagerMode:n&&a,supportsExternalWorkerTarget:a,...r?{managedAgentProtection:r}:{}}}function q(o){const s=v();return o.map(e=>{const i=y(e.type),r=g(e);return{type:e.type,models:s.agents[e.type]?.models??e.models??[],...e.integration?{integration:e.integration}:{},...e.display?{display:e.display}:{},...e.acpCapabilities?{acpCapabilities:e.acpCapabilities}:{},...e.authState?{authState:e.authState}:{},...e.acpAuthMethods?{acpAuthMethods:e.acpAuthMethods}:{},...e.catalogRevision?{catalogRevision:e.catalogRevision}:{},...C(e),...i?{config:i}:{},...r?{runtime:r}:{}}})}async function P(o,s){return I(o,s,{forceRefresh:!0})}async function I(o,s,e={}){const i=v();let r=!1;const p=[];for(const t of o){const n=i.agents[t.type],a=x[t.type],u=n&&(!a||n.sourceRevision===a)?n:void 0;let c;if(!e.forceRefresh&&A(n,t.version,a))c=n.models;else{let d=null;try{d=E(await M(t,s)),c=d.length>0?d:u?.models??t.models??[]}catch(l){if(l instanceof R){const m=!!u?.models.length;c=m?u.models:l.fallbackModels,F(t.type,l.failureCode,m)}else c=u?.models??t.models??[]}if(d&&d.length>0){const l={version:t.version,...a?{sourceRevision:a}:{},refreshedAt:Date.now(),models:c};JSON.stringify(n)!==JSON.stringify(l)&&(i.agents[t.type]=l,r=!0)}}const f=y(t.type),h=g(t);p.push({type:t.type,models:c,...t.integration?{integration:t.integration}:{},...t.display?{display:t.display}:{},...t.acpCapabilities?{acpCapabilities:t.acpCapabilities}:{},...t.authState?{authState:t.authState}:{},...t.acpAuthMethods?{acpAuthMethods:t.acpAuthMethods}:{},...t.catalogRevision?{catalogRevision:t.catalogRevision}:{},...C(t),...f?{config:f}:{},...h?{runtime:h}:{}})}return r&&S(i),p}export{q as getCachedAgentInfos,P as refreshAgentInfos,I as resolveAgentInfos};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ModelInfo } from '@shennian/wire';
|
|
1
|
+
import type { BuiltinAgentType, ModelInfo } from '@shennian/wire';
|
|
2
2
|
export declare const CACHE_VERSION = 1;
|
|
3
3
|
export declare const CACHE_TTL_MS: number;
|
|
4
4
|
export declare const MODEL_CACHE_PATH: string;
|
|
@@ -17,6 +17,14 @@ export type DiscoveryContext = {
|
|
|
17
17
|
serverUrl?: string;
|
|
18
18
|
authToken?: string;
|
|
19
19
|
};
|
|
20
|
+
export type ModelDiscoveryFailureCode = 'app_server_unavailable' | 'app_server_timeout' | 'app_server_rpc_error' | 'empty_model_list';
|
|
21
|
+
/** An emergency list that is safe to display but must never become authoritative cache data. */
|
|
22
|
+
export declare class ModelDiscoveryFallbackError extends Error {
|
|
23
|
+
readonly agentType: BuiltinAgentType;
|
|
24
|
+
readonly failureCode: ModelDiscoveryFailureCode;
|
|
25
|
+
readonly fallbackModels: ModelInfo[];
|
|
26
|
+
constructor(agentType: BuiltinAgentType, failureCode: ModelDiscoveryFailureCode, fallbackModels: ModelInfo[]);
|
|
27
|
+
}
|
|
20
28
|
export type PtyOptions = {
|
|
21
29
|
startupArgs?: string[];
|
|
22
30
|
readyPatterns: RegExp[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import s from"node:os";import{resolveShennianPath as t}from"../../config/index.js";const i=1,n=1440*60*1e3,d=t("model-cache.json"),p=s.tmpdir();class E extends Error{agentType;failureCode;fallbackModels;constructor(o,r,e){super(`Model discovery fell back for ${o}: ${r}`),this.agentType=o,this.failureCode=r,this.fallbackModels=e,this.name="ModelDiscoveryFallbackError"}}export{n as CACHE_TTL_MS,i as CACHE_VERSION,p as DISCOVERY_WORKDIR,d as MODEL_CACHE_PATH,E as ModelDiscoveryFallbackError};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{callDaemonIpc as a}from"../daemon-ipc/client.js";import{DaemonIpcError as r}from"../daemon-ipc/protocol.js";const s={method_not_found:"Update the existing Shennian installation: Desktop through Desktop updates, standalone CLI through its own update flow. Do not install a second Client.",daemon_unavailable:"Check shennian status --json on the target computer. Do not resume an intentional pause without the user requesting it.",daemon_paused:"Shennian is paused. Ask the user to resume it before checking.",ipc_timeout:"The result is unknown. Check the target machine and wait for the current check to finish; do not repeatedly send tests.",agent_check_in_progress:"Wait for the running check to finish before trying again.",agent_validation_runtime_unavailable:"Refresh discovery. If the tool is still missing, guide the user through its official installation on this computer.",agent_validation_runtime_auth_required:"Guide the user through the provider\u2019s own sign-in on this computer, then retry the selected AI and model.",agent_validation_model_unavailable:"Choose a model returned by discovery and check the provider account\u2019s model access.",agent_validation_quota_exceeded:"Check the provider account\u2019s credits, subscription or rate limit before another test.",agent_validation_network_failed:"Check the target computer\u2019s connection to the provider, then retry when it is available."};async function c(
|
|
2
|
-
`),o.ok||(process.exitCode=1)};
|
|
1
|
+
import{callDaemonIpc as a}from"../daemon-ipc/client.js";import{DaemonIpcError as r}from"../daemon-ipc/protocol.js";const s={method_not_found:"Update the existing Shennian installation: Desktop through Desktop updates, standalone CLI through its own update flow. Do not install a second Client.",daemon_unavailable:"Check shennian status --json on the target computer. Do not resume an intentional pause without the user requesting it.",daemon_paused:"Shennian is paused. Ask the user to resume it before checking.",ipc_timeout:"The result is unknown. Check the target machine and wait for the current check to finish; do not repeatedly send tests.",agent_check_in_progress:"Wait for the running check to finish before trying again.",agent_validation_runtime_unavailable:"Refresh discovery. If the tool is still missing, guide the user through its official installation on this computer.",agent_validation_runtime_auth_required:"Guide the user through the provider\u2019s own sign-in on this computer, then retry the selected AI and model.",agent_validation_model_unavailable:"Choose a model returned by discovery and check the provider account\u2019s model access.",agent_validation_quota_exceeded:"Check the provider account\u2019s credits, subscription or rate limit before another test.",agent_validation_network_failed:"Check the target computer\u2019s connection to the provider, then retry when it is available."};async function c(n,i,t=a){try{const e=await t({method:n,params:i,timeoutMs:9e4});if(n==="agent.check"&&(!e||typeof e!="object"||Array.isArray(e)||e.ready!==!0))throw new r("agent_check_invalid_response","The daemon did not confirm a successful hello reply.");return{ok:!0,command:n,result:e}}catch(e){const o=e instanceof r?e.code:"agent_check_failed";return{ok:!1,command:n,error:o,nextAction:s[o]??"Return to the AI preparation guide on this machine. Check the selected directory, account, model and network; do not reinstall by default."}}}function l(n){const i=async(t,e)=>{const o=await c(t,e);process.stdout.write(`${JSON.stringify(o)}
|
|
2
|
+
`),o.ok||(process.exitCode=1)};n.command("discover").description("Refresh AI discovery and sign-in summaries on the running local daemon; no model requests").option("--agent <type>","Return only one discovered Agent type").option("--compact","Return capability summary without the full model list").option("--json","Print JSON (default)").action(t=>i("agent.discover",{...t.agent?{agentType:t.agent}:{},compact:t.compact===!0})),n.command("check <agentType>").description("Send one hello test using the selected AI and model; uses provider quota, creates no managed Agent or room").requiredOption("--workdir <path>","Absolute project directory on this machine").option("--model <id>","Model returned by discovery; otherwise use the provider default").option("--json","Print JSON (default)").action((t,e)=>i("agent.check",{agentType:t,workDir:e.workdir,modelId:e.model??null}))}export{c as executeAgentReadinessCommand,l as registerAgentReadinessCommands};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import g from"node:fs";import p from"node:path";import{callDaemonIpc as f}from"../daemon-ipc/client.js";import{DaemonIpcError as w}from"../daemon-ipc/protocol.js";import{MANAGED_ROOM_IPC_ROOT_ENV as k,resolveManagedRoomIpcPaths as I}from"../daemon-ipc/paths.js";import{MANAGED_ROOM_CONTEXT_ENV as h}from"../room/managed-context.js";async function y(){const o=process.env.SHENNIAN_MANAGER_IPC_URL,r=process.env.SHENNIAN_MANAGER_IPC_TOKEN,n=process.env.SHENNIAN_MANAGER_SESSION_ID;if(o&&r&&n)return{url:o,token:r,managerSessionId:n};throw new Error("manager_context_required: this command is only available inside a Shennian managed Manager session")}async function t(o,r){const n=process.env[h]?.trim();if(n){const s=M[o];if(!s)throw new Error(`Manager IPC path is unavailable in managed Room context: ${o}`);const i=process.env[k]?.trim();if(!i||!N(i))throw new w("managed_room_context_unavailable","Managed Room IPC context is unavailable.");return await f({method:"managed-room.execute",params:{context:n,action:s,...r},paths:I(i),timeoutMs:s==="manager.sessions.start"||s==="manager.sessions.send"?18e4:15e3})}const d=await y(),m=await fetch(`${d.url}${o}`,{method:"POST",headers:{authorization:`Bearer ${d.token}`,"content-type":"application/json","x-shennian-manager-session-id":d.managerSessionId},body:JSON.stringify({...r,managerSessionId:d.managerSessionId})}),e=await m.json().catch(()=>({ok:!1,error:m.statusText}));if(!m.ok||!e.ok)throw new Error(e.error||`Manager IPC failed: ${m.status}`);return e}const M={"/sessions/list":"manager.sessions.list","/sessions/start":"manager.sessions.start","/sessions/send":"manager.sessions.send","/sessions/queue":"manager.sessions.queue","/sessions/queue/edit":"manager.sessions.queue.edit","/sessions/queue/delete":"manager.sessions.queue.delete","/sessions/stop":"manager.sessions.stop","/sessions/read":"manager.sessions.read","/memory/path":"manager.memory.path"};function N(o){return p.isAbsolute(o)}function c(o){console.log(JSON.stringify(o,null,2))}function l(o){console.log(typeof o.markdown=="string"?o.markdown:"ok")}function u(o){return o.messageFile?g.readFileSync(o.messageFile,"utf-8"):o.message??""}function E(o){const r=o.command("manager",{hidden:!0}).description("Manager Session local tools"),n=r.command("sessions").description("Manage same-project worker sessions");n.command("list").description("List same-project sessions visible to this Manager").option("--json","Print JSON").action(async e=>{const s=await t("/sessions/list",{});if(e.json)c(s);else{const i=s.sessions??[];for(const a of i)console.log(`${a.sessionId} ${a.agentType} ${a.role??""} ${a.status} ${a.title??a.summary??""}`)}}),n.command("start").description("Start a worker session in the same project").requiredOption("--agent <agent>","Worker agent type, e.g. codex, claude, cursor, opencode, pi, or custom:<name>").option("--workdir <path>","Worker workdir; defaults to the Manager-bound directory").option("--title <title>","Short worker title").option("--model <model>","Worker model id").option("--message <text>","Worker prompt").option("--message-file <path>","Read worker prompt from file").option("--json","Print JSON").action(async e=>{const s=await t("/sessions/start",{agentType:e.agent,workDir:e.workdir,title:e.title,modelId:e.model,message:u(e)});e.json?c(s):l(s)}),n.command("send").description("Queue a message for a managed worker; runs immediately if idle").requiredOption("--session-id <id>","Worker session id").option("--message <text>","Message text").option("--message-file <path>","Read message from file").option("--direct","Deprecated compatibility flag; delivery still uses the durable queue").action(async e=>{const s=await t("/sessions/send",{sessionId:e.sessionId,message:u(e),enqueue:!e.direct});l(s)});const d=n.command("queue").description("Inspect and edit pending worker messages");d.command("list").description("List pending messages for a managed worker").requiredOption("--session-id <id>","Worker session id").option("--json","Print JSON").action(async e=>{const s=await t("/sessions/queue",{sessionId:e.sessionId});if(e.json)c(s);else{const i=s.queue?.pending??[];for(const a of i)console.log(`${a.id} ${a.text.replace(/\s+/g," ").slice(0,120)}`)}}),d.command("edit").description("Edit a pending worker message").requiredOption("--session-id <id>","Worker session id").requiredOption("--message-id <id>","Queued message id").option("--message <text>","Replacement message text").option("--message-file <path>","Read replacement message from file").action(async e=>{await t("/sessions/queue/edit",{sessionId:e.sessionId,queueMessageId:e.messageId,message:u(e)}),console.log("ok")}),d.command("delete").description("Delete a pending worker message").requiredOption("--session-id <id>","Worker session id").requiredOption("--message-id <id>","Queued message id").action(async e=>{await t("/sessions/queue/delete",{sessionId:e.sessionId,queueMessageId:e.messageId}),console.log("ok")});const m=async e=>{const s=await t("/sessions/stop",{sessionId:e.sessionId});l(s)};n.command("stop").aliases(["terminate","kill"]).description("Stop or terminate a running managed worker").requiredOption("--session-id <id>","Worker session id").action(m),n.command("read").description("Read a managed worker transcript").requiredOption("--session-id <id>","Worker session id").option("--limit <n>","Message limit","200").option("--json","Print JSON").action(async e=>{const s=await t("/sessions/read",{sessionId:e.sessionId,limit:Number(e.limit)});e.json?c(s):c(s.messages??[])}),n.command("wait").description("Wait up to a bounded timeout for the next worker progress or terminal event").requiredOption("--session-id <id>","Worker session id").option("--timeout <seconds>","Maximum wait in seconds (1-600)","600").option("--json","Print JSON").action(async e=>{const s=Math.max(1,Math.min(Number(e.timeout)||600,600)),i=await t("/sessions/wait",{sessionId:e.sessionId,timeoutMs:s*1e3});e.json?c(i):i.timedOut?console.log(`\u7B49\u5F85\u8D85\u65F6\uFF1BAgent \u5F53\u524D\u72B6\u6001\uFF1A${String(i.status||"unknown")}`):l(i)}),r.command("memory").description("Manager project memory helpers").command("path").description("Print project memory directory path").action(async()=>{const e=await t("/memory/path",{});console.log(e.path)})}export{E as registerManagerCommand};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
type WorkerCommandResponse = {
|
|
3
|
+
ok: boolean;
|
|
4
|
+
error?: string;
|
|
5
|
+
message?: string;
|
|
6
|
+
nextAction?: string;
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
};
|
|
9
|
+
export declare function executeWorkerCommand(operation: 'start' | 'read' | 'send' | 'wait' | 'stop', body: Record<string, unknown>): Promise<WorkerCommandResponse>;
|
|
10
|
+
export declare function registerWorkerCommand(program: Command): void;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import c from"node:fs";import{resolveShennianPath as d}from"../config/index.js";function u(){const r=d("runtime","manager-ipc.json");let t;try{t=c.statSync(r)}catch{throw new Error("daemon_unavailable")}if(process.platform!=="win32"){const o=typeof process.getuid=="function"?process.getuid():t.uid;if(t.uid!==o||(t.mode&63)!==0)throw new Error("worker_runtime_permissions_invalid")}const e=JSON.parse(c.readFileSync(r,"utf-8")),n=typeof e.url=="string"?e.url:"",a=typeof e.token=="string"?e.token:"";if(!/^http:\/\/127\.0\.0\.1:\d+$/.test(n)||!a)throw new Error("daemon_unavailable");return{url:n,token:a}}function f(r){return r==="daemon_unavailable"?"Check shennian status --json and start the existing paired daemon if it was not intentionally paused.":r==="worker_runtime_permissions_invalid"?"Repair or update the existing Shennian installation; do not bypass the local runtime file permissions.":"Check the local Shennian daemon and retry the same command once."}async function i(r,t){try{const e=u(),n=r==="wait"?Math.max(2e3,Math.min(Number(t.timeoutMs||6e5)+5e3,605e3)):r==="start"||r==="send"?18e4:15e3,a=await fetch(`${e.url}/workers/${r}`,{method:"POST",headers:{authorization:`Bearer ${e.token}`,"content-type":"application/json"},body:JSON.stringify(t),signal:AbortSignal.timeout(n)}),o=await a.json().catch(()=>({ok:!1,error:"worker_invalid_response",message:a.statusText}));return a.ok&&o.ok?o:{ok:!1,error:o.error||"worker_command_failed",...o.message?{message:o.message}:{},nextAction:o.nextAction||"Check the selected Agent, working directory, account, and Worker reference."}}catch(e){const n=e instanceof Error&&e.message==="daemon_unavailable"||e instanceof Error&&e.message==="worker_runtime_permissions_invalid"?e.message:e instanceof Error&&e.name==="TimeoutError"?"ipc_timeout":"worker_command_failed";return{ok:!1,error:n,message:e instanceof Error?e.message:String(e),nextAction:f(n)}}}function m(r){return r.messageFile?c.readFileSync(r.messageFile,"utf8"):r.message??""}function s(r){process.stdout.write(`${JSON.stringify(r)}
|
|
2
|
+
`),r.ok||(process.exitCode=1)}function k(r){const t=r.command("worker").description("Start and control an external temporary Worker by opaque reference");t.command("start").description("Start a new Worker; returns the only reference that can control it").requiredOption("--agent <agent>","Agent type returned by shennian agent discover").option("--workdir <path>","Working directory; defaults to the current directory").option("--title <title>","Short Worker title").option("--model <model>","Model id returned by discovery").option("--message <text>","Worker task").option("--message-file <path>","Read the Worker task from a file").option("--json","Print JSON (default)").action(async e=>s(await i("start",{agentType:e.agent,workDir:e.workdir??process.cwd(),title:e.title,modelId:e.model,message:m(e)}))),t.command("read").description("Read a Worker transcript using the reference returned by worker start").requiredOption("--ref <worker-ref>","Opaque Worker reference").option("--limit <n>","Message limit","200").option("--json","Print JSON (default)").action(async e=>s(await i("read",{workerRef:e.ref,limit:Number(e.limit)}))),t.command("send").description("Queue another message for a Worker").requiredOption("--ref <worker-ref>","Opaque Worker reference").option("--message <text>","Message text").option("--message-file <path>","Read the message from a file").option("--json","Print JSON (default)").action(async e=>s(await i("send",{workerRef:e.ref,message:m(e)}))),t.command("wait").description("Wait once for Worker progress or a terminal event").requiredOption("--ref <worker-ref>","Opaque Worker reference").option("--timeout <seconds>","Maximum wait in seconds (1-600)","600").option("--json","Print JSON (default)").action(async e=>{const n=Math.max(1,Math.min(Number(e.timeout)||600,600));s(await i("wait",{workerRef:e.ref,timeoutMs:n*1e3}))}),t.command("stop").description("Stop a Worker using its opaque reference").requiredOption("--ref <worker-ref>","Opaque Worker reference").option("--json","Print JSON (default)").action(async e=>s(await i("stop",{workerRef:e.ref})))}export{i as executeWorkerCommand,k as registerWorkerCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isAvailableAgentType as
|
|
1
|
+
import{isAvailableAgentType as a}from"@shennian/wire";import{DaemonIpcError as n}from"./protocol.js";function c(i){let s=!1;const l=()=>{const e=i.getStatus();if(e.remoteAccessDisabled)throw new n("daemon_paused","Shennian is paused; resume it only when requested.");if(!e.running)throw new n("daemon_unavailable","Shennian is not running.")};return{"agent.discover":async e=>{l();const r=e&&typeof e=="object"&&!Array.isArray(e)&&typeof e.agentType=="string"?e.agentType:null,u=!!(e&&typeof e=="object"&&!Array.isArray(e)&&e.compact===!0),d=(await i.discover()).filter(t=>!r||t.type===r);return{modelTested:!1,compact:u,agents:d.map(t=>({type:t.type,name:t.display?.name??t.type,authState:t.authState??"unknown",...t.runtime?.cliVersion?{version:t.runtime.cliVersion}:{},...t.runtime?.compatibility?{compatibility:t.runtime.compatibility}:{},...t.runtimePlatform?{runtimePlatform:t.runtimePlatform}:{},...t.runtimeIsWsl!==void 0?{runtimeIsWsl:t.runtimeIsWsl}:{},supportsStandardSession:t.supportsStandardSession===!0,supportsManagedAgent:t.supportsManagedAgent===!0,supportsManagedNativeFull:t.supportsManagedNativeFull===!0,supportsRoomTools:t.supportsRoomTools===!0,supportsWorker:t.supportsWorker===!0,supportsManagerMode:t.supportsManagerMode===!0,supportsExternalWorkerTarget:t.supportsExternalWorkerTarget===!0,...u?{modelCount:t.models.length,defaultModelId:t.models.find(o=>o.isDefault)?.id??null}:{models:t.models.map(o=>({id:o.id,name:o.name,isDefault:o.isDefault===!0}))}}))}},"agent.check":async e=>{if(l(),!e||typeof e!="object"||Array.isArray(e)||typeof e.agentType!="string"||!a(e.agentType)||typeof e.workDir!="string"||!e.workDir.trim()||e.modelId!=null&&typeof e.modelId!="string")throw new n("agent_validation_invalid_configuration","Select an AI and its absolute working directory.");if(s)throw new n("agent_check_in_progress","An AI reply check is already running.");s=!0;try{const r=await i.validate({runtimeAdapter:e.agentType,workDir:e.workDir,modelId:e.modelId??null,sessionMode:"standard"});if(!r.ok)throw new n(r.errorCode,r.errorCode);return{ready:!0,agentType:e.agentType,modelId:e.modelId??null,scope:"hello_reply"}}finally{s=!1}}}}export{c as createAgentReadinessHandlers};
|