@tencent-ai/agent-sdk 0.3.147 → 0.3.150
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 +158 -0
- package/cli/dist/codebuddy-headless.js +178 -178
- package/cli/package.json +1 -1
- package/cli/product.cloudhosted.json +7 -3
- package/cli/product.internal.json +5 -2
- package/cli/product.ioa.json +5 -2
- package/cli/product.json +11 -3
- package/cli/product.selfhosted.json +5 -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
package/cli/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tencent-ai/codebuddy-code",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.97.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",
|
|
@@ -110,6 +110,9 @@
|
|
|
110
110
|
"tools": [
|
|
111
111
|
"Read"
|
|
112
112
|
],
|
|
113
|
+
"commands": [
|
|
114
|
+
"_compact"
|
|
115
|
+
],
|
|
113
116
|
"tags": [
|
|
114
117
|
"cli",
|
|
115
118
|
"compact"
|
|
@@ -407,8 +410,9 @@
|
|
|
407
410
|
"DeferToolLoading": true,
|
|
408
411
|
"ImageGen": true,
|
|
409
412
|
"ScheduledTasks": true,
|
|
410
|
-
"SkillManage": false
|
|
413
|
+
"SkillManage": false,
|
|
414
|
+
"SelectImage": true
|
|
411
415
|
},
|
|
412
|
-
"commit": "
|
|
413
|
-
"date": "2026-05-
|
|
416
|
+
"commit": "128246570576896f27eea5952184b086b997c167",
|
|
417
|
+
"date": "2026-05-13T06:44:47.289Z"
|
|
414
418
|
}
|
|
@@ -118,6 +118,9 @@
|
|
|
118
118
|
"tools": [
|
|
119
119
|
"Read"
|
|
120
120
|
],
|
|
121
|
+
"commands": [
|
|
122
|
+
"_compact"
|
|
123
|
+
],
|
|
121
124
|
"tags": [
|
|
122
125
|
"cli",
|
|
123
126
|
"compact"
|
|
@@ -594,6 +597,6 @@
|
|
|
594
597
|
}
|
|
595
598
|
}
|
|
596
599
|
},
|
|
597
|
-
"commit": "
|
|
598
|
-
"date": "2026-05-
|
|
600
|
+
"commit": "128246570576896f27eea5952184b086b997c167",
|
|
601
|
+
"date": "2026-05-13T06:44:47.289Z"
|
|
599
602
|
}
|
package/cli/product.ioa.json
CHANGED
|
@@ -141,6 +141,9 @@
|
|
|
141
141
|
"tools": [
|
|
142
142
|
"Read"
|
|
143
143
|
],
|
|
144
|
+
"commands": [
|
|
145
|
+
"_compact"
|
|
146
|
+
],
|
|
144
147
|
"tags": [
|
|
145
148
|
"cli",
|
|
146
149
|
"compact"
|
|
@@ -945,6 +948,6 @@
|
|
|
945
948
|
}
|
|
946
949
|
}
|
|
947
950
|
},
|
|
948
|
-
"commit": "
|
|
949
|
-
"date": "2026-05-
|
|
951
|
+
"commit": "128246570576896f27eea5952184b086b997c167",
|
|
952
|
+
"date": "2026-05-13T06:44:47.278Z"
|
|
950
953
|
}
|
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",
|
|
@@ -945,6 +945,9 @@
|
|
|
945
945
|
"tools": [
|
|
946
946
|
"Read"
|
|
947
947
|
],
|
|
948
|
+
"commands": [
|
|
949
|
+
"_compact"
|
|
950
|
+
],
|
|
948
951
|
"tags": [
|
|
949
952
|
"cli",
|
|
950
953
|
"compact"
|
|
@@ -1128,6 +1131,11 @@
|
|
|
1128
1131
|
"compact-agent"
|
|
1129
1132
|
]
|
|
1130
1133
|
},
|
|
1134
|
+
{
|
|
1135
|
+
"name": "_compact",
|
|
1136
|
+
"description": "Clear conversation history but keep a summary in context. Optional: /compact [instructions for summarization]",
|
|
1137
|
+
"prompt": "compact-prompt"
|
|
1138
|
+
},
|
|
1131
1139
|
{
|
|
1132
1140
|
"name": "upgrade",
|
|
1133
1141
|
"description": "Open upgrade page in browser"
|
|
@@ -1519,6 +1527,6 @@
|
|
|
1519
1527
|
"description": "Send a reply to a WeCom (企业微信) user. For text: pass text (markdown supported)."
|
|
1520
1528
|
}
|
|
1521
1529
|
],
|
|
1522
|
-
"commit": "
|
|
1523
|
-
"date": "2026-05-
|
|
1530
|
+
"commit": "128246570576896f27eea5952184b086b997c167",
|
|
1531
|
+
"date": "2026-05-13T06:44:47.294Z"
|
|
1524
1532
|
}
|
|
@@ -104,6 +104,9 @@
|
|
|
104
104
|
"tools": [
|
|
105
105
|
"Read"
|
|
106
106
|
],
|
|
107
|
+
"commands": [
|
|
108
|
+
"_compact"
|
|
109
|
+
],
|
|
107
110
|
"tags": [
|
|
108
111
|
"cli",
|
|
109
112
|
"compact"
|
|
@@ -296,6 +299,6 @@
|
|
|
296
299
|
"DeferToolLoading": true,
|
|
297
300
|
"ScheduledTasks": true
|
|
298
301
|
},
|
|
299
|
-
"commit": "
|
|
300
|
-
"date": "2026-05-
|
|
302
|
+
"commit": "128246570576896f27eea5952184b086b997c167",
|
|
303
|
+
"date": "2026-05-13T06:44:47.285Z"
|
|
301
304
|
}
|
|
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
|
*/
|