@bacnh85/pi-serena 0.3.1 → 0.4.0
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/README.md +2 -1
- package/index.ts +13 -14
- package/package.json +1 -1
- package/worker.ts +17 -1
package/README.md
CHANGED
|
@@ -46,7 +46,6 @@ After install or update, restart Pi or run `/reload` in an existing Pi session.
|
|
|
46
46
|
- `serena_replace_content`
|
|
47
47
|
- `serena_restart_language_server`
|
|
48
48
|
- `serena_get_current_config`
|
|
49
|
-
- `serena_check_onboarding_performed`
|
|
50
49
|
- `serena_onboarding`
|
|
51
50
|
- `serena_list_memories`
|
|
52
51
|
- `serena_read_memory`
|
|
@@ -55,6 +54,8 @@ After install or update, restart Pi or run `/reload` in an existing Pi session.
|
|
|
55
54
|
|
|
56
55
|
All tool outputs are truncated to 50KB / 2000 lines to match Pi-friendly output limits. Most tools accept optional `timeout_ms`.
|
|
57
56
|
|
|
57
|
+
When a worker request exceeds the configured timeout, the Python bridge process is automatically killed and a fresh worker is started for the next call. This prevents cascading timeouts from blocking future requests.
|
|
58
|
+
|
|
58
59
|
### Pattern search
|
|
59
60
|
|
|
60
61
|
Use the Pi-facing `pattern` field with `serena_search_for_pattern`:
|
package/index.ts
CHANGED
|
@@ -150,6 +150,9 @@ export function normalizeSearchPatternParams(params: Record<string, unknown>): R
|
|
|
150
150
|
normalized.substring_pattern = normalized.pattern;
|
|
151
151
|
}
|
|
152
152
|
delete normalized.pattern;
|
|
153
|
+
// The Python SearchForPatternTool.apply() does not accept a multiline parameter.
|
|
154
|
+
// Strip it here to avoid TypeError when the parameter description says "when supported by Serena".
|
|
155
|
+
delete normalized.multiline;
|
|
153
156
|
return normalized;
|
|
154
157
|
}
|
|
155
158
|
|
|
@@ -206,8 +209,16 @@ function truncateText(text: string): string {
|
|
|
206
209
|
}
|
|
207
210
|
|
|
208
211
|
function resultText(response: SerenaWorkerResponse): string {
|
|
209
|
-
|
|
210
|
-
|
|
212
|
+
if (!response.ok) {
|
|
213
|
+
return `Error: ${response.error ?? "Unknown Serena error"}`;
|
|
214
|
+
}
|
|
215
|
+
// For search results, show a friendly empty-state instead of raw "{}".
|
|
216
|
+
if (response.tool === "search_for_pattern") {
|
|
217
|
+
if (response.result == null || (typeof response.result === "object" && Object.keys(response.result as object).length === 0)) {
|
|
218
|
+
return "No results found.";
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return typeof response.result === "string" ? response.result : JSON.stringify(response, null, 2);
|
|
211
222
|
}
|
|
212
223
|
|
|
213
224
|
export default function serenaToolsExtension(pi: ExtensionAPI) {
|
|
@@ -423,18 +434,6 @@ export default function serenaToolsExtension(pi: ExtensionAPI) {
|
|
|
423
434
|
},
|
|
424
435
|
});
|
|
425
436
|
|
|
426
|
-
pi.registerTool({
|
|
427
|
-
name: "serena_check_onboarding_performed",
|
|
428
|
-
label: "Serena Check Onboarding",
|
|
429
|
-
description: "Check whether Serena onboarding memories exist for this project.",
|
|
430
|
-
promptSnippet: "Check whether project onboarding was already performed",
|
|
431
|
-
promptGuidelines: ["Use serena_check_onboarding_performed before relying on Serena project memories."],
|
|
432
|
-
parameters: emptyToolSchema,
|
|
433
|
-
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
434
|
-
return callSerena(ctx, "check_onboarding_performed", params);
|
|
435
|
-
},
|
|
436
|
-
});
|
|
437
|
-
|
|
438
437
|
pi.registerTool({
|
|
439
438
|
name: "serena_onboarding",
|
|
440
439
|
label: "Serena Onboarding",
|
package/package.json
CHANGED
package/worker.ts
CHANGED
|
@@ -272,7 +272,13 @@ export class SerenaWorkerClient {
|
|
|
272
272
|
return new Promise((resolve, reject) => {
|
|
273
273
|
const timer = setTimeout(() => {
|
|
274
274
|
this.pending.delete(id);
|
|
275
|
-
|
|
275
|
+
// Kill and reset worker so subsequent requests don't pile up.
|
|
276
|
+
// The next request() call triggers ensureStarted() which spawns a fresh worker.
|
|
277
|
+
this.killAndReset();
|
|
278
|
+
reject(new Error(
|
|
279
|
+
`Serena worker request timed out: ${payload.action ?? "unknown"}. ` +
|
|
280
|
+
`Worker has been restarted; retry if needed.`
|
|
281
|
+
));
|
|
276
282
|
}, timeoutMs);
|
|
277
283
|
this.pending.set(id, { resolve, reject, timer });
|
|
278
284
|
this.process!.stdin.write(`${JSON.stringify(request)}\n`);
|
|
@@ -353,6 +359,16 @@ export class SerenaWorkerClient {
|
|
|
353
359
|
}
|
|
354
360
|
}
|
|
355
361
|
|
|
362
|
+
private killAndReset(): void {
|
|
363
|
+
if (this.process) {
|
|
364
|
+
this.process.kill();
|
|
365
|
+
this.process = undefined;
|
|
366
|
+
this.onStatus?.(undefined);
|
|
367
|
+
}
|
|
368
|
+
this.failAll(new Error("Serena worker killed due to timeout, restarted"));
|
|
369
|
+
this.buffer = "";
|
|
370
|
+
}
|
|
371
|
+
|
|
356
372
|
private failAll(error: Error): void {
|
|
357
373
|
for (const [id, pending] of this.pending) {
|
|
358
374
|
clearTimeout(pending.timer);
|