@trim21/personal-pi-extensions 0.1.500 → 0.1.501
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/package.json +1 -1
- package/src/aft/bridge.ts +5 -0
- package/src/aft/tools.ts +48 -14
package/package.json
CHANGED
package/src/aft/bridge.ts
CHANGED
|
@@ -150,6 +150,9 @@ export async function createAftPool(
|
|
|
150
150
|
* 调用 AFT 工具命令并返回 Rust 格式化好的文本。
|
|
151
151
|
* 只读感知工具统一走 toolCall(server 侧 tool_call 分派)。`softCodes` 里的
|
|
152
152
|
* 错误码(如 symbol_not_found)是合法否定答案,不抛错、按文本返回。
|
|
153
|
+
*
|
|
154
|
+
* `signal`:宿主取消信号,透传给 bridge 的 abortSignal——standalone transport
|
|
155
|
+
* 会在 abort 时向 Rust 发 cancel_request(subc route 忽略,靠 route 关闭取消)。
|
|
153
156
|
*/
|
|
154
157
|
export async function callAftTool(
|
|
155
158
|
bridge: AftProjectTransport,
|
|
@@ -158,12 +161,14 @@ export async function callAftTool(
|
|
|
158
161
|
extCtx: ExtensionContext,
|
|
159
162
|
options?: BridgeRequestOptions & { preview?: boolean },
|
|
160
163
|
softCodes?: ReadonlySet<string>,
|
|
164
|
+
signal?: AbortSignal,
|
|
161
165
|
): Promise<{ text: string; response: Record<string, unknown> }> {
|
|
162
166
|
const timeoutMs = timeoutForCommand(command);
|
|
163
167
|
const sessionId = resolveSessionId(extCtx);
|
|
164
168
|
const sendOptions = {
|
|
165
169
|
...(timeoutMs !== undefined && { timeoutMs }),
|
|
166
170
|
...options,
|
|
171
|
+
...(signal !== undefined && !options?.abortSignal && { abortSignal: signal }),
|
|
167
172
|
};
|
|
168
173
|
const response = await bridge.toolCall(
|
|
169
174
|
sessionId,
|
package/src/aft/tools.ts
CHANGED
|
@@ -126,7 +126,7 @@ export function registerOutlineTool(pi: ExtensionAPI, ctx: AftToolContext): void
|
|
|
126
126
|
promptSnippet: "Output structural outline of a file/directory",
|
|
127
127
|
promptGuidelines: [OUTLINE_PROMPT],
|
|
128
128
|
parameters: OutlineParams,
|
|
129
|
-
async execute(_id, params,
|
|
129
|
+
async execute(_id, params, signal, _onUpdate, extCtx) {
|
|
130
130
|
const target = coerceTargetParam(params.target);
|
|
131
131
|
if (typeof target !== "string" || target.length === 0) {
|
|
132
132
|
throw new Error("'target' must be a single path (array targets are not supported)");
|
|
@@ -145,7 +145,15 @@ export function registerOutlineTool(pi: ExtensionAPI, ctx: AftToolContext): void
|
|
|
145
145
|
|
|
146
146
|
const subtitle = buildOutlineSubtitle(extCtx.cwd, target);
|
|
147
147
|
|
|
148
|
-
const { text, response } = await callAftTool(
|
|
148
|
+
const { text, response } = await callAftTool(
|
|
149
|
+
bridgeFor(ctx),
|
|
150
|
+
"outline",
|
|
151
|
+
rawArgs,
|
|
152
|
+
extCtx,
|
|
153
|
+
undefined,
|
|
154
|
+
undefined,
|
|
155
|
+
signal,
|
|
156
|
+
);
|
|
149
157
|
const truncated = response.truncated === true;
|
|
150
158
|
return {
|
|
151
159
|
content: [{ type: "text", text }],
|
|
@@ -201,7 +209,7 @@ export function registerZoomTool(pi: ExtensionAPI, ctx: AftToolContext): void {
|
|
|
201
209
|
promptSnippet: "Inspect the full source of a named symbol",
|
|
202
210
|
promptGuidelines: [ZOOM_PROMPT],
|
|
203
211
|
parameters: ZoomParams,
|
|
204
|
-
async execute(_id, params,
|
|
212
|
+
async execute(_id, params, signal, _onUpdate, extCtx) {
|
|
205
213
|
const rawArgs = compactArgs({
|
|
206
214
|
filePath: resolvePathArg(extCtx.cwd, params.path),
|
|
207
215
|
symbols: params.symbols,
|
|
@@ -216,7 +224,15 @@ export function registerZoomTool(pi: ExtensionAPI, ctx: AftToolContext): void {
|
|
|
216
224
|
|
|
217
225
|
const subtitle = buildZoomSubtitle(extCtx.cwd, params);
|
|
218
226
|
|
|
219
|
-
const { text, response } = await callAftTool(
|
|
227
|
+
const { text, response } = await callAftTool(
|
|
228
|
+
bridgeFor(ctx),
|
|
229
|
+
"zoom",
|
|
230
|
+
rawArgs,
|
|
231
|
+
extCtx,
|
|
232
|
+
undefined,
|
|
233
|
+
undefined,
|
|
234
|
+
signal,
|
|
235
|
+
);
|
|
220
236
|
const truncated = response.truncated === true;
|
|
221
237
|
return {
|
|
222
238
|
content: [{ type: "text", text }],
|
|
@@ -305,12 +321,16 @@ export async function callCallgraphWithBuildRetry(
|
|
|
305
321
|
bridge: AftProjectTransport,
|
|
306
322
|
rawArgs: Record<string, unknown>,
|
|
307
323
|
extCtx: ExtensionContext,
|
|
324
|
+
signal?: AbortSignal,
|
|
308
325
|
timing?: { budgetMs: number; intervalMs: number },
|
|
309
326
|
): Promise<{ text: string; response: Record<string, unknown> }> {
|
|
310
327
|
const budgetMs = timing?.budgetMs ?? CALLGRAPH_BUILD_RETRY_BUDGET_MS;
|
|
311
328
|
const intervalMs = timing?.intervalMs ?? CALLGRAPH_BUILD_RETRY_INTERVAL_MS;
|
|
312
329
|
const deadline = Date.now() + budgetMs;
|
|
313
330
|
for (;;) {
|
|
331
|
+
if (signal?.aborted) {
|
|
332
|
+
throw new Error("callgraph request aborted");
|
|
333
|
+
}
|
|
314
334
|
const { text, response } = await callAftTool(
|
|
315
335
|
bridge,
|
|
316
336
|
"callgraph",
|
|
@@ -318,6 +338,7 @@ export async function callCallgraphWithBuildRetry(
|
|
|
318
338
|
extCtx,
|
|
319
339
|
undefined,
|
|
320
340
|
CALLGRAPH_SOFT_CODES,
|
|
341
|
+
signal,
|
|
321
342
|
);
|
|
322
343
|
const code = typeof response.code === "string" ? response.code : "";
|
|
323
344
|
if (code !== "callgraph_building" || Date.now() >= deadline) {
|
|
@@ -341,7 +362,7 @@ export function registerCallgraphTool(pi: ExtensionAPI, ctx: AftToolContext): vo
|
|
|
341
362
|
promptSnippet: "Call graph and data-flow navigation",
|
|
342
363
|
promptGuidelines: [CALLGRAPH_PROMPT],
|
|
343
364
|
parameters: CallgraphParams,
|
|
344
|
-
async execute(_id, params,
|
|
365
|
+
async execute(_id, params, signal, _onUpdate, extCtx) {
|
|
345
366
|
const rawArgs = compactArgs({
|
|
346
367
|
op: params.op,
|
|
347
368
|
filePath: resolvePathArg(extCtx.cwd, params.path),
|
|
@@ -354,7 +375,12 @@ export function registerCallgraphTool(pi: ExtensionAPI, ctx: AftToolContext): vo
|
|
|
354
375
|
includeUnresolved: params.includeUnresolved,
|
|
355
376
|
});
|
|
356
377
|
|
|
357
|
-
const { text, response } = await callCallgraphWithBuildRetry(
|
|
378
|
+
const { text, response } = await callCallgraphWithBuildRetry(
|
|
379
|
+
bridgeFor(ctx),
|
|
380
|
+
rawArgs,
|
|
381
|
+
extCtx,
|
|
382
|
+
signal,
|
|
383
|
+
);
|
|
358
384
|
const out =
|
|
359
385
|
text ||
|
|
360
386
|
formatCallgraphSections(params.op, response, PLAIN_CALLGRAPH_THEME, {
|
|
@@ -483,7 +509,7 @@ export function registerSearchTool(pi: ExtensionAPI, ctx: AftToolContext): void
|
|
|
483
509
|
promptSnippet: "Search code by meaning or exact text",
|
|
484
510
|
promptGuidelines: [SEARCH_PROMPT],
|
|
485
511
|
parameters: SearchParams,
|
|
486
|
-
async execute(_id, params,
|
|
512
|
+
async execute(_id, params, signal, onUpdate, extCtx) {
|
|
487
513
|
if (typeof params.query !== "string" || params.query.trim().length === 0) {
|
|
488
514
|
throw new Error("'query' must be a non-empty string");
|
|
489
515
|
}
|
|
@@ -506,13 +532,21 @@ export function registerSearchTool(pi: ExtensionAPI, ctx: AftToolContext): void
|
|
|
506
532
|
let response: Record<string, unknown>;
|
|
507
533
|
let text: string;
|
|
508
534
|
try {
|
|
509
|
-
({ text, response } = await callAftTool(
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
535
|
+
({ text, response } = await callAftTool(
|
|
536
|
+
bridge,
|
|
537
|
+
"search",
|
|
538
|
+
rawArgs,
|
|
539
|
+
extCtx,
|
|
540
|
+
{
|
|
541
|
+
// 默认 search 传输超时仅 60s,会早于索引等待(600s)触发;覆盖为等待
|
|
542
|
+
// 上限 + 常规执行预算。超时只说明响应被挤掉而非 bridge 挂死,保留
|
|
543
|
+
// 常驻的语义索引/LSP 状态。
|
|
544
|
+
transportTimeoutMs: SEMANTIC_INDEX_WAIT_TIMEOUT_MS + 60_000,
|
|
545
|
+
keepBridgeOnTimeout: true,
|
|
546
|
+
},
|
|
547
|
+
undefined,
|
|
548
|
+
signal,
|
|
549
|
+
));
|
|
516
550
|
} finally {
|
|
517
551
|
stopProgress?.();
|
|
518
552
|
}
|