@tencent-ai/agent-sdk 0.3.147 → 0.3.148
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/cli/CHANGELOG.md +17 -0
- package/cli/dist/codebuddy-headless.js +249 -177
- package/cli/dist/web-ui/assets/{index-bVNRRvKC.js → index-Dk5Zj7Qd.js} +126 -126
- package/cli/dist/web-ui/index.html +1 -1
- package/cli/dist/web-ui/sw.js +1 -1
- package/cli/package.json +1 -1
- package/cli/product.cloudhosted.json +4 -3
- package/cli/product.internal.json +2 -2
- package/cli/product.ioa.json +2 -2
- package/cli/product.json +3 -3
- package/cli/product.selfhosted.json +2 -2
- package/cli/vendor/sandbox/sandbox-cli +0 -0
- package/lib/_internal/query-controller.d.ts +41 -0
- package/lib/_internal/query-controller.d.ts.map +1 -0
- package/lib/_internal/query-controller.js +168 -0
- package/lib/_internal/query-controller.js.map +1 -0
- package/lib/query.d.ts +1 -7
- package/lib/query.d.ts.map +1 -1
- package/lib/query.js +19 -146
- package/lib/query.js.map +1 -1
- package/lib/session.d.ts +1 -7
- package/lib/session.d.ts.map +1 -1
- package/lib/session.js +10 -144
- package/lib/session.js.map +1 -1
- package/lib/types.d.ts +1 -1
- package/lib/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
20
20
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
21
21
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
22
|
-
<script type="module" crossorigin src="/assets/index-
|
|
22
|
+
<script type="module" crossorigin src="/assets/index-Dk5Zj7Qd.js"></script>
|
|
23
23
|
<link rel="modulepreload" crossorigin href="/assets/markdown-Ce2Umeb2.js">
|
|
24
24
|
<link rel="modulepreload" crossorigin href="/assets/vendor-DpYitQz5.js">
|
|
25
25
|
<link rel="stylesheet" crossorigin href="/assets/index-CY6b2fbj.css">
|
package/cli/dist/web-ui/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
if(!self.define){let s,e={};const o=(o,n)=>(o=new URL(o+".js",n).href,e[o]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=o,s.onload=e,document.head.appendChild(s)}else s=o,importScripts(o),e()}).then(()=>{let s=e[o];if(!s)throw new Error(`Module ${o} didn’t register its module`);return s}));self.define=(n,i)=>{const l=s||("document"in self?document.currentScript.src:"")||location.href;if(e[l])return;let t={};const r=s=>o(s,l),u={module:{uri:l},exports:t,require:r};e[l]=Promise.all(n.map(s=>u[s]||r(s))).then(s=>(i(...s),t))}}define(["./workbox-e082a648"],function(s){"use strict";self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"logo.svg",revision:"6165db837a6039880af9705aa09be574"},{url:"index.html",revision:"
|
|
1
|
+
if(!self.define){let s,e={};const o=(o,n)=>(o=new URL(o+".js",n).href,e[o]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=o,s.onload=e,document.head.appendChild(s)}else s=o,importScripts(o),e()}).then(()=>{let s=e[o];if(!s)throw new Error(`Module ${o} didn’t register its module`);return s}));self.define=(n,i)=>{const l=s||("document"in self?document.currentScript.src:"")||location.href;if(e[l])return;let t={};const r=s=>o(s,l),u={module:{uri:l},exports:t,require:r};e[l]=Promise.all(n.map(s=>u[s]||r(s))).then(s=>(i(...s),t))}}define(["./workbox-e082a648"],function(s){"use strict";self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"logo.svg",revision:"6165db837a6039880af9705aa09be574"},{url:"index.html",revision:"ef7597fba07ed77264db22fbd1411551"},{url:"assets/workbox-window.prod.es5-BIl4cyR9.js",revision:null},{url:"assets/vendor-DpYitQz5.js",revision:null},{url:"assets/octicons-CaZ_fok2.woff2",revision:null},{url:"assets/mfixx-CpAhKOZz.woff2",revision:null},{url:"assets/markdown-Ce2Umeb2.js",revision:null},{url:"assets/logo-iZVLr450.svg",revision:null},{url:"assets/index-Dk5Zj7Qd.js",revision:null},{url:"assets/index-DixJ0kqk.js",revision:null},{url:"assets/index-CY6b2fbj.css",revision:null},{url:"assets/fontawesome-B-jkhYfk.woff2",revision:null},{url:"assets/file-icons-C0jOugUK.woff2",revision:null},{url:"assets/devopicons-QN4QXivI.woff2",revision:null},{url:"logo.svg",revision:"6165db837a6039880af9705aa09be574"},{url:"manifest.webmanifest",revision:"ed76a251c8eb35918791b0d0a060a0c2"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("/index.html"),{denylist:[/^\/api/,/^\/gateway/,/^\/docs\//]})),s.registerRoute(/^https:\/\/fonts\.googleapis\.com/,new s.StaleWhileRevalidate({cacheName:"google-fonts-stylesheets",plugins:[]}),"GET"),s.registerRoute(/^https:\/\/fonts\.gstatic\.com/,new s.CacheFirst({cacheName:"google-fonts-webfonts",plugins:[new s.ExpirationPlugin({maxEntries:20,maxAgeSeconds:31536e3})]}),"GET")});
|
package/cli/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tencent-ai/codebuddy-code",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.96.0",
|
|
4
4
|
"description": "Use CodeBuddy, Tencent's AI assistant, right from your terminal. CodeBuddy can understand your codebase, edit files, run terminal commands, and handle entire workflows for you.",
|
|
5
5
|
"main": "lib/node/index.js",
|
|
6
6
|
"typings": "lib/node/index.d.ts",
|
|
@@ -407,8 +407,9 @@
|
|
|
407
407
|
"DeferToolLoading": true,
|
|
408
408
|
"ImageGen": true,
|
|
409
409
|
"ScheduledTasks": true,
|
|
410
|
-
"SkillManage": false
|
|
410
|
+
"SkillManage": false,
|
|
411
|
+
"SelectImage": true
|
|
411
412
|
},
|
|
412
|
-
"commit": "
|
|
413
|
-
"date": "2026-05-
|
|
413
|
+
"commit": "43f0a5d80e1f77fb31f8cba0ec819db0436e73ed",
|
|
414
|
+
"date": "2026-05-11T11:14:06.748Z"
|
|
414
415
|
}
|
package/cli/product.ioa.json
CHANGED
package/cli/product.json
CHANGED
|
@@ -505,7 +505,7 @@
|
|
|
505
505
|
},
|
|
506
506
|
{
|
|
507
507
|
"name": "terminal-title-generator-instructions",
|
|
508
|
-
"template": "You are a topic analyzer. Your ONLY purpose is to identify conversation topics.\n\nYour job:\n1. Read the user message\n2. Determine if it starts a NEW conversation topic (compared to previous context if any)\n3. If yes, extract a 2-3 word title for the topic\n\nCRITICAL CONSTRAINTS:\n- You are NOT a code generator, writer, or task executor\n- You MUST respond ONLY with JSON in this exact format:\n {\"isNewTopic\": boolean, \"title\": string or null}\n- NEVER generate, implement, code, or produce any content\n- NEVER provide explanations, reasoning, or extra text\n- NEVER engage with the user's actual request beyond identifying the topic\n\nExamples:\nUser: \"Can you build an HTML5 game?\" → {\"isNewTopic\": true, \"title\": \"Game Development\"}\nUser: \"Add more features\" → {\"isNewTopic\": false, \"title\": null}\n\nReturn only the JSON object. Nothing else.\n"
|
|
508
|
+
"template": "You are a topic analyzer. Your ONLY purpose is to identify conversation topics.\n\nYour job:\n1. Read the user message\n2. Determine if it starts a NEW conversation topic (compared to previous context if any)\n3. If yes, extract a 2-3 word title for the topic\n\nCRITICAL CONSTRAINTS:\n- You are NOT a code generator, writer, or task executor\n- You MUST respond ONLY with JSON in this exact format:\n {\"isNewTopic\": boolean, \"title\": string or null}\n- NEVER generate, implement, code, or produce any content\n- NEVER provide explanations, reasoning, or extra text\n- NEVER engage with the user's actual request beyond identifying the topic\n\nExamples:\nUser: \"Can you build an HTML5 game?\" → {\"isNewTopic\": true, \"title\": \"Game Development\"}\nUser: \"Add more features\" → {\"isNewTopic\": false, \"title\": null}\n\nReturn only the JSON object. Nothing else.\n{%- if language -%}\n\nIMPORTANT: The `title` field MUST be written in {{language}}. Do not use English for the title value even though these instructions are in English. The JSON structure itself (field names, boolean values) stays unchanged.\n{%- endif -%}\n"
|
|
509
509
|
},
|
|
510
510
|
{
|
|
511
511
|
"name": "memory-selector-instructions",
|
|
@@ -1519,6 +1519,6 @@
|
|
|
1519
1519
|
"description": "Send a reply to a WeCom (企业微信) user. For text: pass text (markdown supported)."
|
|
1520
1520
|
}
|
|
1521
1521
|
],
|
|
1522
|
-
"commit": "
|
|
1523
|
-
"date": "2026-05-
|
|
1522
|
+
"commit": "43f0a5d80e1f77fb31f8cba0ec819db0436e73ed",
|
|
1523
|
+
"date": "2026-05-11T11:14:06.748Z"
|
|
1524
1524
|
}
|
|
@@ -296,6 +296,6 @@
|
|
|
296
296
|
"DeferToolLoading": true,
|
|
297
297
|
"ScheduledTasks": true
|
|
298
298
|
},
|
|
299
|
-
"commit": "
|
|
300
|
-
"date": "2026-05-
|
|
299
|
+
"commit": "43f0a5d80e1f77fb31f8cba0ec819db0436e73ed",
|
|
300
|
+
"date": "2026-05-11T11:14:06.734Z"
|
|
301
301
|
}
|
|
Binary file
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Owns control protocol bookkeeping (initialize + hook/permission/mcp routing)
|
|
3
|
+
* shared by ``query()`` and ``createSession()``.
|
|
4
|
+
*/
|
|
5
|
+
import type { Transport } from '../transport';
|
|
6
|
+
import type { AgentDefinition, CanUseTool, ControlInitializeRequest, ControlInitializeResponse, ControlRequest, HookCallbackMatcher, HookEvent } from '../types';
|
|
7
|
+
export interface InitializePayloadOptions {
|
|
8
|
+
/** SDK-defined agent definitions (sent via initialize control_request) */
|
|
9
|
+
agents?: Record<string, AgentDefinition>;
|
|
10
|
+
/** Override the default system prompt (string), or append (object) */
|
|
11
|
+
systemPrompt?: string | {
|
|
12
|
+
append: string;
|
|
13
|
+
};
|
|
14
|
+
/** Predefined environment for selfhosted authentication */
|
|
15
|
+
environment?: ControlInitializeRequest['environment'];
|
|
16
|
+
/** Custom endpoint URL for selfhosted environment */
|
|
17
|
+
endpoint?: ControlInitializeRequest['endpoint'];
|
|
18
|
+
/** Whether a prompt is going to follow this initialize (controls history replay) */
|
|
19
|
+
hasPrompt: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare class QueryController {
|
|
22
|
+
private readonly transport;
|
|
23
|
+
private readonly canUseToolGetter;
|
|
24
|
+
private readonly abortSignalGetter;
|
|
25
|
+
private hookCallbacks;
|
|
26
|
+
private registeredHooks?;
|
|
27
|
+
constructor(transport: Transport, hooks: Partial<Record<HookEvent, HookCallbackMatcher[]>> | undefined, canUseToolGetter: () => CanUseTool | undefined, abortSignalGetter: () => AbortSignal);
|
|
28
|
+
initialize(opts: InitializePayloadOptions): Promise<ControlInitializeResponse>;
|
|
29
|
+
handleControlRequest(request: ControlRequest): Promise<void>;
|
|
30
|
+
private handlePermissionRequest;
|
|
31
|
+
private handleHookCallback;
|
|
32
|
+
/**
|
|
33
|
+
* Replace the registered hook callbacks. The hook event structure (events,
|
|
34
|
+
* matchers) was sent to CLI during initialize() — this just rewires the
|
|
35
|
+
* callback functions for existing hook IDs.
|
|
36
|
+
*/
|
|
37
|
+
setHooks(hooks: Partial<Record<HookEvent, HookCallbackMatcher[]>> | undefined): void;
|
|
38
|
+
private registerHooks;
|
|
39
|
+
private buildHooksConfig;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=query-controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-controller.d.ts","sourceRoot":"","sources":["../../src/_internal/query-controller.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EACR,eAAe,EACf,UAAU,EAEV,wBAAwB,EACxB,yBAAyB,EAEzB,cAAc,EACd,mBAAmB,EACnB,SAAS,EAKZ,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,wBAAwB;IACrC,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACzC,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,2DAA2D;IAC3D,WAAW,CAAC,EAAE,wBAAwB,CAAC,aAAa,CAAC,CAAC;IACtD,qDAAqD;IACrD,QAAQ,CAAC,EAAE,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAChD,oFAAoF;IACpF,SAAS,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,eAAe;IAQpB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAG1B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAIjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAdtC,OAAO,CAAC,aAAa,CAGP;IACd,OAAO,CAAC,eAAe,CAAC,CAAoD;gBAGvD,SAAS,EAAE,SAAS,EACrC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAAC,GAAG,SAAS,EAEnD,gBAAgB,EAAE,MAAM,UAAU,GAAG,SAAS,EAI9C,iBAAiB,EAAE,MAAM,WAAW;IAOnD,UAAU,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,yBAAyB,CAAC;IA8B9E,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;YAUpD,uBAAuB;YA4DvB,kBAAkB;IAsBhC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,mBAAmB,EAAE,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI;IAMpF,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,gBAAgB;CAoB3B"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Owns control protocol bookkeeping (initialize + hook/permission/mcp routing)
|
|
4
|
+
* shared by ``query()`` and ``createSession()``.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.QueryController = void 0;
|
|
8
|
+
class QueryController {
|
|
9
|
+
constructor(transport, hooks,
|
|
10
|
+
// Lazy: Session may swap canUseTool at runtime via setCanUseTool().
|
|
11
|
+
canUseToolGetter,
|
|
12
|
+
// Lazy: Session replaces its AbortController after an interrupt+continue cycle
|
|
13
|
+
// (see SessionImpl.send) — a captured reference would dispatch hook / canUseTool
|
|
14
|
+
// callbacks with a stale, already-aborted signal.
|
|
15
|
+
abortSignalGetter) {
|
|
16
|
+
this.transport = transport;
|
|
17
|
+
this.canUseToolGetter = canUseToolGetter;
|
|
18
|
+
this.abortSignalGetter = abortSignalGetter;
|
|
19
|
+
this.hookCallbacks = new Map();
|
|
20
|
+
this.registerHooks(hooks);
|
|
21
|
+
}
|
|
22
|
+
// ============= Initialize =============
|
|
23
|
+
async initialize(opts) {
|
|
24
|
+
const systemPrompt = typeof opts.systemPrompt === 'string'
|
|
25
|
+
? opts.systemPrompt
|
|
26
|
+
: undefined;
|
|
27
|
+
const appendSystemPrompt = typeof opts.systemPrompt === 'object'
|
|
28
|
+
? opts.systemPrompt.append
|
|
29
|
+
: undefined;
|
|
30
|
+
const sdkMcpServerNames = this.transport.sdkMcpServerNames;
|
|
31
|
+
const initRequest = {
|
|
32
|
+
subtype: 'initialize',
|
|
33
|
+
hooks: this.buildHooksConfig(),
|
|
34
|
+
systemPrompt,
|
|
35
|
+
appendSystemPrompt,
|
|
36
|
+
agents: opts.agents,
|
|
37
|
+
sdkMcpServers: sdkMcpServerNames.length > 0 ? sdkMcpServerNames : undefined,
|
|
38
|
+
environment: opts.environment,
|
|
39
|
+
endpoint: opts.endpoint,
|
|
40
|
+
capabilities: {
|
|
41
|
+
askUserQuestion: true,
|
|
42
|
+
},
|
|
43
|
+
hasPrompt: opts.hasPrompt,
|
|
44
|
+
};
|
|
45
|
+
return this.transport.sendControlRequest(initRequest);
|
|
46
|
+
}
|
|
47
|
+
// ============= Control request routing =============
|
|
48
|
+
async handleControlRequest(request) {
|
|
49
|
+
const { subtype } = request.request;
|
|
50
|
+
if (subtype === 'hook_callback') {
|
|
51
|
+
await this.handleHookCallback(request);
|
|
52
|
+
}
|
|
53
|
+
else if (subtype === 'can_use_tool') {
|
|
54
|
+
await this.handlePermissionRequest(request);
|
|
55
|
+
}
|
|
56
|
+
// mcp_message is handled at the transport level
|
|
57
|
+
}
|
|
58
|
+
async handlePermissionRequest(request) {
|
|
59
|
+
const permRequest = request.request;
|
|
60
|
+
const { tool_name, input, tool_use_id, agent_id, permission_suggestions, blocked_path, decision_reason, } = permRequest;
|
|
61
|
+
const canUseTool = this.canUseToolGetter();
|
|
62
|
+
if (!canUseTool) {
|
|
63
|
+
this.transport.sendControlResponse(request.request_id, {
|
|
64
|
+
allowed: false,
|
|
65
|
+
reason: 'No permission handler provided',
|
|
66
|
+
tool_use_id,
|
|
67
|
+
});
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const result = await canUseTool(tool_name, input, {
|
|
72
|
+
signal: this.abortSignalGetter(),
|
|
73
|
+
suggestions: permission_suggestions,
|
|
74
|
+
blockedPath: blocked_path,
|
|
75
|
+
decisionReason: decision_reason,
|
|
76
|
+
toolUseID: tool_use_id,
|
|
77
|
+
agentID: agent_id,
|
|
78
|
+
});
|
|
79
|
+
if (result.behavior === 'allow') {
|
|
80
|
+
this.transport.sendControlResponse(request.request_id, {
|
|
81
|
+
allowed: true,
|
|
82
|
+
updatedInput: result.updatedInput,
|
|
83
|
+
tool_use_id,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.transport.sendControlResponse(request.request_id, {
|
|
88
|
+
allowed: false,
|
|
89
|
+
reason: result.message,
|
|
90
|
+
interrupt: result.interrupt,
|
|
91
|
+
tool_use_id,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
this.transport.sendControlResponse(request.request_id, {
|
|
97
|
+
allowed: false,
|
|
98
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
99
|
+
tool_use_id,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async handleHookCallback(request) {
|
|
104
|
+
const { callback_id, input, tool_use_id } = request.request;
|
|
105
|
+
const callback = this.hookCallbacks.get(callback_id);
|
|
106
|
+
let response = { continue: true };
|
|
107
|
+
if (callback) {
|
|
108
|
+
try {
|
|
109
|
+
response = await callback(input, tool_use_id, { signal: this.abortSignalGetter() });
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
response = {
|
|
113
|
+
continue: false,
|
|
114
|
+
stopReason: error instanceof Error ? error.message : String(error),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
this.transport.sendControlResponse(request.request_id, response);
|
|
119
|
+
}
|
|
120
|
+
// ============= Hooks =============
|
|
121
|
+
/**
|
|
122
|
+
* Replace the registered hook callbacks. The hook event structure (events,
|
|
123
|
+
* matchers) was sent to CLI during initialize() — this just rewires the
|
|
124
|
+
* callback functions for existing hook IDs.
|
|
125
|
+
*/
|
|
126
|
+
setHooks(hooks) {
|
|
127
|
+
this.hookCallbacks.clear();
|
|
128
|
+
this.registeredHooks = undefined;
|
|
129
|
+
this.registerHooks(hooks);
|
|
130
|
+
}
|
|
131
|
+
registerHooks(hooks) {
|
|
132
|
+
if (!hooks) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.registeredHooks = hooks;
|
|
136
|
+
for (const [event, matchers] of Object.entries(hooks)) {
|
|
137
|
+
if (!matchers) {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
matchers.forEach((matcher, matcherIndex) => {
|
|
141
|
+
matcher.hooks.forEach((hook, hookIndex) => {
|
|
142
|
+
const callbackId = `hook_${event}_${matcherIndex}_${hookIndex}`;
|
|
143
|
+
this.hookCallbacks.set(callbackId, hook);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
buildHooksConfig() {
|
|
149
|
+
if (!this.registeredHooks) {
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
const config = {};
|
|
153
|
+
for (const [event, matchers] of Object.entries(this.registeredHooks)) {
|
|
154
|
+
if (!matchers) {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const hookEvent = event;
|
|
158
|
+
config[hookEvent] = matchers.map((matcher, matcherIndex) => ({
|
|
159
|
+
matcher: matcher.matcher,
|
|
160
|
+
hookCallbackIds: matcher.hooks.map((_, hookIndex) => `hook_${event}_${matcherIndex}_${hookIndex}`),
|
|
161
|
+
timeout: matcher.timeout,
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
return Object.keys(config).length > 0 ? config : undefined;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
exports.QueryController = QueryController;
|
|
168
|
+
//# sourceMappingURL=query-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-controller.js","sourceRoot":"","sources":["../../src/_internal/query-controller.ts"],"names":[],"mappings":"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"}
|
package/lib/query.d.ts
CHANGED
|
@@ -20,9 +20,9 @@ export declare class Query implements AsyncGenerator<Message, void> {
|
|
|
20
20
|
private prompt;
|
|
21
21
|
private options?;
|
|
22
22
|
private transport;
|
|
23
|
+
private controller;
|
|
23
24
|
private initialized;
|
|
24
25
|
private abortController;
|
|
25
|
-
private hookCallbacks;
|
|
26
26
|
private iterator;
|
|
27
27
|
private connectPromise;
|
|
28
28
|
private lockedSessionId;
|
|
@@ -89,12 +89,6 @@ export declare class Query implements AsyncGenerator<Message, void> {
|
|
|
89
89
|
private createIterator;
|
|
90
90
|
private initialize;
|
|
91
91
|
private sendPrompt;
|
|
92
|
-
private handleControlRequest;
|
|
93
|
-
private handlePermissionRequest;
|
|
94
|
-
private handleHookCallback;
|
|
95
|
-
private registeredHooks?;
|
|
96
|
-
private registerHooks;
|
|
97
|
-
private buildHooksConfig;
|
|
98
92
|
/**
|
|
99
93
|
* Cleanup all resources.
|
|
100
94
|
*/
|
package/lib/query.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EACR,WAAW,EACX,eAAe,EACf,OAAO,EACP,SAAS,EACT,OAAO,EACP,cAAc,EACd,YAAY,EACZ,WAAW,EACd,MAAM,SAAS,CAAC;AAGjB;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,KAAK,CAER;AAED;;GAEG;AACH,qBAAa,KAAM,YAAW,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC;IAqBnD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,OAAO,CAAC;IArBpB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAA8C;IAC9D,OAAO,CAAC,cAAc,CAA8B;IAGpD,OAAO,CAAC,eAAe,CAAuB;IAG9C,OAAO,CAAC,UAAU,CAAuB;IAGzC,OAAO,CAAC,sBAAsB,CAAiB;IAC/C,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,sBAAsB,CAAiB;IAC/C,OAAO,CAAC,aAAa,CAAqB;gBAG9B,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,GAAG,SAAS,EACvD,OAAO,CAAC,EAAE,OAAO,YAAA;IA2G7B,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC;IAOjD,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAI9C,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAKhD,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAO7D;;;;;;;;;;;;;;;;OAgBG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B;;;OAGG;IACH,OAAO,CAAC,YAAY;IAId,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAchC;;;;OAIG;IACG,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAa5D;;OAEG;IACH,iBAAiB,IAAI,cAAc;IAInC;;;;OAIG;IACG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa7C;;OAEG;IACH,QAAQ,IAAI,MAAM,GAAG,SAAS;IAIxB,oBAAoB,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAUrE,iBAAiB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAO5C,eAAe,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAOvC,eAAe,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAO7C,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAOnC,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAQrD,cAAc;YAmEf,UAAU;YAkCV,UAAU;IA0BxB;;OAEG;IACH,OAAO,CAAC,OAAO;CAUlB"}
|
package/lib/query.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.Query = void 0;
|
|
7
7
|
exports.query = query;
|
|
8
|
+
const query_controller_1 = require("./_internal/query-controller");
|
|
8
9
|
const connect_1 = require("./connect");
|
|
9
10
|
const errors_1 = require("./errors");
|
|
10
11
|
const transport_1 = require("./transport");
|
|
@@ -31,7 +32,6 @@ class Query {
|
|
|
31
32
|
this.prompt = prompt;
|
|
32
33
|
this.options = options;
|
|
33
34
|
this.initialized = false;
|
|
34
|
-
this.hookCallbacks = new Map();
|
|
35
35
|
this.iterator = null;
|
|
36
36
|
this.connectPromise = null;
|
|
37
37
|
// Session lock tracking
|
|
@@ -97,11 +97,16 @@ class Query {
|
|
|
97
97
|
requestTimeoutMs: options === null || options === void 0 ? void 0 : options.requestTimeoutMs,
|
|
98
98
|
};
|
|
99
99
|
this.transport = (0, transport_1.createTransport)(transportOptions);
|
|
100
|
+
this.abortController = (_a = options === null || options === void 0 ? void 0 : options.abortController) !== null && _a !== void 0 ? _a : new AbortController();
|
|
101
|
+
// QueryController owns initialize + hook registry + control-request routing.
|
|
102
|
+
// The canUseTool getter is lazy because options shouldn't be re-read on every
|
|
103
|
+
// call (they don't change for query()), but it matches Session's pattern.
|
|
104
|
+
this.controller = new query_controller_1.QueryController(this.transport, options === null || options === void 0 ? void 0 : options.hooks, () => options === null || options === void 0 ? void 0 : options.canUseTool, () => this.abortController.signal);
|
|
100
105
|
// Register control request handler on transport so control requests
|
|
101
106
|
// are dispatched directly in handleLine(), bypassing the message queue.
|
|
102
107
|
this.transport.onControlRequest(request => {
|
|
103
108
|
// eslint-disable-next-line no-void
|
|
104
|
-
void this.handleControlRequest(request).catch(() => {
|
|
109
|
+
void this.controller.handleControlRequest(request).catch(() => {
|
|
105
110
|
// Individual control request errors shouldn't affect the query
|
|
106
111
|
});
|
|
107
112
|
});
|
|
@@ -110,8 +115,6 @@ class Query {
|
|
|
110
115
|
this.connectPromise = this.transport.connect().catch(() => {
|
|
111
116
|
// Ignore connection errors - they'll be reported when iteration starts
|
|
112
117
|
});
|
|
113
|
-
this.abortController = (_a = options === null || options === void 0 ? void 0 : options.abortController) !== null && _a !== void 0 ? _a : new AbortController();
|
|
114
|
-
this.registerHooks(options === null || options === void 0 ? void 0 : options.hooks);
|
|
115
118
|
// Track initial values (passed to CLI via command line args)
|
|
116
119
|
this._initialPermissionMode = (_b = options === null || options === void 0 ? void 0 : options.permissionMode) !== null && _b !== void 0 ? _b : 'default';
|
|
117
120
|
this._initialModel = options === null || options === void 0 ? void 0 : options.model;
|
|
@@ -327,7 +330,7 @@ class Query {
|
|
|
327
330
|
}
|
|
328
331
|
}
|
|
329
332
|
async initialize() {
|
|
330
|
-
var _a, _b, _c, _d, _e, _f
|
|
333
|
+
var _a, _b, _c, _d, _e, _f;
|
|
331
334
|
if (this.initialized) {
|
|
332
335
|
return;
|
|
333
336
|
}
|
|
@@ -339,39 +342,19 @@ class Query {
|
|
|
339
342
|
}
|
|
340
343
|
this.lockedSessionId = this.options.resume;
|
|
341
344
|
}
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
:
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
const sdkMcpServerNames = this.transport.sdkMcpServerNames;
|
|
350
|
-
const initRequest = {
|
|
351
|
-
subtype: 'initialize',
|
|
352
|
-
hooks: this.buildHooksConfig(),
|
|
353
|
-
systemPrompt,
|
|
354
|
-
appendSystemPrompt,
|
|
355
|
-
agents: (_e = this.options) === null || _e === void 0 ? void 0 : _e.agents,
|
|
356
|
-
// Include SDK MCP server names from transport
|
|
357
|
-
sdkMcpServers: sdkMcpServerNames.length > 0 ? sdkMcpServerNames : undefined,
|
|
358
|
-
// Pass environment/endpoint for selfhosted environment resolution
|
|
359
|
-
environment: (_f = this.options) === null || _f === void 0 ? void 0 : _f.environment,
|
|
360
|
-
endpoint: (_g = this.options) === null || _g === void 0 ? void 0 : _g.endpoint,
|
|
361
|
-
// Declare SDK capabilities for tool enablement
|
|
362
|
-
capabilities: {
|
|
363
|
-
// SDK supports handling AskUserQuestion via canUseTool callback
|
|
364
|
-
askUserQuestion: true,
|
|
365
|
-
},
|
|
366
|
-
// Tell CLI whether prompt will follow (for resume history decision)
|
|
367
|
-
// hasPrompt=true means CLI should NOT replay history
|
|
345
|
+
const response = await this.controller.initialize({
|
|
346
|
+
agents: (_c = this.options) === null || _c === void 0 ? void 0 : _c.agents,
|
|
347
|
+
systemPrompt: (_d = this.options) === null || _d === void 0 ? void 0 : _d.systemPrompt,
|
|
348
|
+
environment: (_e = this.options) === null || _e === void 0 ? void 0 : _e.environment,
|
|
349
|
+
endpoint: (_f = this.options) === null || _f === void 0 ? void 0 : _f.endpoint,
|
|
350
|
+
// Tell CLI whether prompt will follow (controls resume history replay).
|
|
351
|
+
// hasPrompt=true means CLI should NOT replay history.
|
|
368
352
|
hasPrompt: this.prompt !== undefined && this.prompt !== '',
|
|
369
|
-
};
|
|
370
|
-
const response = await this.transport.sendControlRequest(initRequest);
|
|
353
|
+
});
|
|
371
354
|
this.initialized = true;
|
|
372
|
-
//
|
|
373
|
-
//
|
|
374
|
-
// start
|
|
355
|
+
// When ``options.model`` was unset, sync the CLI-reported model into both
|
|
356
|
+
// current *and* initial — otherwise the pending-change check at iteration
|
|
357
|
+
// start would treat the CLI's reported value as a user-initiated change.
|
|
375
358
|
if (!this._currentModel && response.currentModelId) {
|
|
376
359
|
this._currentModel = response.currentModelId;
|
|
377
360
|
this._initialModel = response.currentModelId;
|
|
@@ -403,116 +386,6 @@ class Query {
|
|
|
403
386
|
}
|
|
404
387
|
}
|
|
405
388
|
}
|
|
406
|
-
async handleControlRequest(request) {
|
|
407
|
-
const { subtype } = request.request;
|
|
408
|
-
if (subtype === 'hook_callback') {
|
|
409
|
-
await this.handleHookCallback(request);
|
|
410
|
-
}
|
|
411
|
-
else if (subtype === 'can_use_tool') {
|
|
412
|
-
await this.handlePermissionRequest(request);
|
|
413
|
-
}
|
|
414
|
-
// Note: mcp_message is handled at the transport level
|
|
415
|
-
}
|
|
416
|
-
async handlePermissionRequest(request) {
|
|
417
|
-
var _a;
|
|
418
|
-
const permRequest = request.request;
|
|
419
|
-
const { tool_name, input, tool_use_id, agent_id, permission_suggestions, blocked_path, decision_reason, } = permRequest;
|
|
420
|
-
const canUseTool = (_a = this.options) === null || _a === void 0 ? void 0 : _a.canUseTool;
|
|
421
|
-
// If no canUseTool callback provided, deny by default
|
|
422
|
-
if (!canUseTool) {
|
|
423
|
-
this.transport.sendControlResponse(request.request_id, {
|
|
424
|
-
allowed: false,
|
|
425
|
-
reason: 'No permission handler provided',
|
|
426
|
-
tool_use_id,
|
|
427
|
-
});
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
try {
|
|
431
|
-
const result = await canUseTool(tool_name, input, {
|
|
432
|
-
signal: this.abortController.signal,
|
|
433
|
-
suggestions: permission_suggestions,
|
|
434
|
-
blockedPath: blocked_path,
|
|
435
|
-
decisionReason: decision_reason,
|
|
436
|
-
toolUseID: tool_use_id,
|
|
437
|
-
agentID: agent_id,
|
|
438
|
-
});
|
|
439
|
-
if (result.behavior === 'allow') {
|
|
440
|
-
this.transport.sendControlResponse(request.request_id, {
|
|
441
|
-
allowed: true,
|
|
442
|
-
updatedInput: result.updatedInput,
|
|
443
|
-
tool_use_id,
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
else {
|
|
447
|
-
this.transport.sendControlResponse(request.request_id, {
|
|
448
|
-
allowed: false,
|
|
449
|
-
reason: result.message,
|
|
450
|
-
interrupt: result.interrupt,
|
|
451
|
-
tool_use_id,
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
catch (error) {
|
|
456
|
-
this.transport.sendControlResponse(request.request_id, {
|
|
457
|
-
allowed: false,
|
|
458
|
-
reason: error instanceof Error ? error.message : String(error),
|
|
459
|
-
tool_use_id,
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
async handleHookCallback(request) {
|
|
464
|
-
const { callback_id, input, tool_use_id } = request.request;
|
|
465
|
-
const callback = this.hookCallbacks.get(callback_id);
|
|
466
|
-
let response = { continue: true };
|
|
467
|
-
if (callback) {
|
|
468
|
-
try {
|
|
469
|
-
response = await callback(input, tool_use_id, { signal: this.abortController.signal });
|
|
470
|
-
}
|
|
471
|
-
catch (error) {
|
|
472
|
-
response = {
|
|
473
|
-
continue: false,
|
|
474
|
-
stopReason: error instanceof Error ? error.message : String(error),
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
this.transport.sendControlResponse(request.request_id, response);
|
|
479
|
-
}
|
|
480
|
-
registerHooks(hooks) {
|
|
481
|
-
if (!hooks) {
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
this.registeredHooks = hooks;
|
|
485
|
-
// Build callback ID mapping for each hook - must match buildHooksConfig
|
|
486
|
-
for (const [event, matchers] of Object.entries(hooks)) {
|
|
487
|
-
if (!matchers) {
|
|
488
|
-
continue;
|
|
489
|
-
}
|
|
490
|
-
matchers.forEach((matcher, matcherIndex) => {
|
|
491
|
-
matcher.hooks.forEach((hook, hookIndex) => {
|
|
492
|
-
const callbackId = `hook_${event}_${matcherIndex}_${hookIndex}`;
|
|
493
|
-
this.hookCallbacks.set(callbackId, hook);
|
|
494
|
-
});
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
buildHooksConfig() {
|
|
499
|
-
if (!this.registeredHooks) {
|
|
500
|
-
return undefined;
|
|
501
|
-
}
|
|
502
|
-
const config = {};
|
|
503
|
-
for (const [event, matchers] of Object.entries(this.registeredHooks)) {
|
|
504
|
-
if (!matchers) {
|
|
505
|
-
continue;
|
|
506
|
-
}
|
|
507
|
-
const hookEvent = event;
|
|
508
|
-
config[hookEvent] = matchers.map((matcher, matcherIndex) => ({
|
|
509
|
-
matcher: matcher.matcher,
|
|
510
|
-
hookCallbackIds: matcher.hooks.map((_, hookIndex) => `hook_${event}_${matcherIndex}_${hookIndex}`),
|
|
511
|
-
timeout: matcher.timeout,
|
|
512
|
-
}));
|
|
513
|
-
}
|
|
514
|
-
return Object.keys(config).length > 0 ? config : undefined;
|
|
515
|
-
}
|
|
516
389
|
/**
|
|
517
390
|
* Cleanup all resources.
|
|
518
391
|
*/
|