@agimon-ai/po-codemode 0.0.1-alpha.27 → 0.0.1-alpha.29
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/{codemodeTools-DiqyGxSU.cjs → codemodeTools-46IqsFCu.cjs} +229 -173
- package/dist/codemodeTools-46IqsFCu.cjs.map +1 -0
- package/dist/{codemodeTools-De6GNjzR.mjs → codemodeTools-CnOko99s.mjs} +230 -174
- package/dist/codemodeTools-CnOko99s.mjs.map +1 -0
- package/dist/extensions/server.cjs +2 -1
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.mjs +3 -2
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +9 -9
- package/src/prompts/how-to-codemode/SKILL.md +1 -0
- package/dist/codemodeTools-De6GNjzR.mjs.map +0 -1
- package/dist/codemodeTools-DiqyGxSU.cjs.map +0 -1
|
@@ -262,7 +262,7 @@ function recordedCall(call, budget) {
|
|
|
262
262
|
} }
|
|
263
263
|
};
|
|
264
264
|
}
|
|
265
|
-
function toResult(result, output, saved, calls) {
|
|
265
|
+
function toResult(result, output, saved, calls, approvals = []) {
|
|
266
266
|
const content = [];
|
|
267
267
|
if (output.lines.length > 0) content.push({
|
|
268
268
|
type: "text",
|
|
@@ -285,6 +285,10 @@ function toResult(result, output, saved, calls) {
|
|
|
285
285
|
text: `${name}: ${message}${hint}`
|
|
286
286
|
});
|
|
287
287
|
}
|
|
288
|
+
if (approvals.length > 0) content.push({
|
|
289
|
+
type: "text",
|
|
290
|
+
text: `Waiting for the person's approval: ${approvals.map((entry) => `${entry.name} (approval ${entry.approvalId})`).join(", ")}. Each runs once approved, and its outcome arrives as a message. Keep working meanwhile.`
|
|
291
|
+
});
|
|
288
292
|
if (content.length === 0) content.push({
|
|
289
293
|
type: "text",
|
|
290
294
|
text: "(no return value)"
|
|
@@ -298,9 +302,13 @@ function toResult(result, output, saved, calls) {
|
|
|
298
302
|
data: image.data,
|
|
299
303
|
mimeType: image.mimeType
|
|
300
304
|
});
|
|
305
|
+
const details = {
|
|
306
|
+
...calls.length > 0 ? { calls } : {},
|
|
307
|
+
...approvals.length > 0 ? { approvals } : {}
|
|
308
|
+
};
|
|
301
309
|
return {
|
|
302
310
|
content,
|
|
303
|
-
...
|
|
311
|
+
...Object.keys(details).length > 0 ? { details } : {},
|
|
304
312
|
...result.ok ? {} : { isError: true }
|
|
305
313
|
};
|
|
306
314
|
}
|
|
@@ -405,7 +413,6 @@ function createCodemodeTools({ registry, isolate, scripts, npm, signal: lifecycl
|
|
|
405
413
|
if (closing || ownerSignal.aborted) return text("Code mode session is disposing.", true);
|
|
406
414
|
if (running >= MAX_CONCURRENT_RUNS) return text(`This session already has ${MAX_CONCURRENT_RUNS} exec runs active. Wait for one to finish.`, true);
|
|
407
415
|
running += 1;
|
|
408
|
-
const expiresAt = Date.now() + deadlineMs;
|
|
409
416
|
const controller = new AbortController();
|
|
410
417
|
const runSignal = AbortSignal.any([
|
|
411
418
|
ownerSignal,
|
|
@@ -426,6 +433,7 @@ function createCodemodeTools({ registry, isolate, scripts, npm, signal: lifecycl
|
|
|
426
433
|
...presence === void 0 ? {} : { interaction: presence }
|
|
427
434
|
}) ? "unattended" : "interactive";
|
|
428
435
|
const run = {
|
|
436
|
+
source: parameters.code,
|
|
429
437
|
sessionId: execution.sessionId,
|
|
430
438
|
...execution.caller === void 0 ? {} : { caller: execution.caller },
|
|
431
439
|
toolCallId,
|
|
@@ -441,6 +449,7 @@ function createCodemodeTools({ registry, isolate, scripts, npm, signal: lifecycl
|
|
|
441
449
|
warning: "The exec run has ended."
|
|
442
450
|
} : output.emitImage(image)
|
|
443
451
|
};
|
|
452
|
+
const approvals = [];
|
|
444
453
|
const gateFor = (namespace) => (name, policy, call) => async (...args) => {
|
|
445
454
|
const gate = await (0, _agimon_ai_po_core_approval.gateApproval)({
|
|
446
455
|
policy,
|
|
@@ -449,15 +458,22 @@ function createCodemodeTools({ registry, isolate, scripts, npm, signal: lifecycl
|
|
|
449
458
|
name
|
|
450
459
|
},
|
|
451
460
|
input: args[0],
|
|
461
|
+
arguments: args[0],
|
|
452
462
|
sessionId: run.sessionId,
|
|
453
463
|
toolCallId,
|
|
454
464
|
...run.caller === void 0 ? {} : { caller: run.caller },
|
|
455
465
|
background,
|
|
456
466
|
interaction,
|
|
457
467
|
service: approval?.(),
|
|
458
|
-
signal: runSignal
|
|
459
|
-
expiresAt
|
|
468
|
+
signal: runSignal
|
|
460
469
|
});
|
|
470
|
+
if (!gate.ok && gate.pending === true) {
|
|
471
|
+
approvals.push({
|
|
472
|
+
approvalId: gate.approvalId,
|
|
473
|
+
name
|
|
474
|
+
});
|
|
475
|
+
throw new _agimon_ai_po_core_approval.ApprovalPendingError(gate.approvalId, gate.reason);
|
|
476
|
+
}
|
|
461
477
|
if (!gate.ok) throw new Error(gate.reason);
|
|
462
478
|
if (!registry.list().includes(namespace)) throw new Error(`'${name}' is no longer active. Nothing ran.`);
|
|
463
479
|
if (runSignal.aborted) throw new Error(`'${name}' was cancelled. Nothing ran.`);
|
|
@@ -567,186 +583,226 @@ function createCodemodeTools({ registry, isolate, scripts, npm, signal: lifecycl
|
|
|
567
583
|
});
|
|
568
584
|
running -= 1;
|
|
569
585
|
}
|
|
570
|
-
return toResult(result, output, saved, calls);
|
|
586
|
+
return toResult(result, output, saved, calls, approvals);
|
|
571
587
|
};
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
return text(`Unknown namespace "${parameters.namespace}". Registered: ${names}.`, true);
|
|
590
|
-
}
|
|
591
|
-
return text(truncate(found.declarations, MAX_DECLARATION_CHARS));
|
|
592
|
-
}
|
|
593
|
-
if (parameters.query !== void 0) {
|
|
594
|
-
const needle = parameters.query.toLowerCase();
|
|
595
|
-
const hits = [];
|
|
596
|
-
for (const namespace of namespaces) {
|
|
597
|
-
const lines = namespace.declarations.split("\n");
|
|
598
|
-
lines.forEach((line, index) => {
|
|
599
|
-
if (!line.toLowerCase().includes(needle) || hits.length >= MAX_QUERY_LINES) return;
|
|
600
|
-
const doc = lines[index - 1]?.trim().startsWith("/**") ? `${lines[index - 1]?.trim()} ` : "";
|
|
601
|
-
hits.push(`${namespace.name}: ${doc}${line.trim()}`);
|
|
602
|
-
});
|
|
603
|
-
}
|
|
604
|
-
for (const script of listed) {
|
|
605
|
-
if (hits.length >= MAX_QUERY_LINES) break;
|
|
606
|
-
if (`${script.specifier} ${script.description}`.toLowerCase().includes(needle)) hits.push(`script ${script.specifier}: ${script.description}`);
|
|
607
|
-
}
|
|
608
|
-
return text(hits.length > 0 ? hits.join("\n") : `No members or scripts match "${parameters.query}".`);
|
|
588
|
+
const discover = {
|
|
589
|
+
name: "discover",
|
|
590
|
+
label: "Discover",
|
|
591
|
+
description: "List the code-mode namespaces and reusable scripts you can use from `exec`, show one namespace in full, or search members and scripts. Not required before exec: its description already names the namespaces.",
|
|
592
|
+
parameters: DiscoverToolSchema,
|
|
593
|
+
promptSnippet: "List code-mode namespaces and their TypeScript declarations",
|
|
594
|
+
executionMode: "parallel",
|
|
595
|
+
async execute(_toolCallId, parameters, _signal, _onUpdate, execution) {
|
|
596
|
+
const service = isolate();
|
|
597
|
+
if (!service) return text("Code mode is not available on this host.", true);
|
|
598
|
+
const namespaces = visible(service);
|
|
599
|
+
const listed = scripts && service.liveObjects ? await scripts.list(activeDomains(execution)) : [];
|
|
600
|
+
if (parameters.namespace !== void 0) {
|
|
601
|
+
const found = namespaces.find((namespace) => namespace.name === parameters.namespace);
|
|
602
|
+
if (!found) {
|
|
603
|
+
const names = namespaces.map((namespace) => namespace.name).join(", ") || "none";
|
|
604
|
+
return text(`Unknown namespace "${parameters.namespace}". Registered: ${names}.`, true);
|
|
609
605
|
}
|
|
610
|
-
|
|
611
|
-
|
|
606
|
+
return text(truncate(found.declarations, MAX_DECLARATION_CHARS));
|
|
607
|
+
}
|
|
608
|
+
if (parameters.query !== void 0) {
|
|
609
|
+
const needle = parameters.query.toLowerCase();
|
|
610
|
+
const hits = [];
|
|
612
611
|
for (const namespace of namespaces) {
|
|
613
|
-
const
|
|
614
|
-
|
|
612
|
+
const lines = namespace.declarations.split("\n");
|
|
613
|
+
lines.forEach((line, index) => {
|
|
614
|
+
if (!line.toLowerCase().includes(needle) || hits.length >= MAX_QUERY_LINES) return;
|
|
615
|
+
const doc = lines[index - 1]?.trim().startsWith("/**") ? `${lines[index - 1]?.trim()} ` : "";
|
|
616
|
+
hits.push(`${namespace.name}: ${doc}${line.trim()}`);
|
|
617
|
+
});
|
|
615
618
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
sections.push(`Scripts. ${SCRIPTS_HELP}`);
|
|
620
|
-
for (const script of listed.slice(0, MAX_LISTED_SCRIPTS)) sections.push(`- ${script.specifier}${script.description ? `: ${script.description}` : ""}`);
|
|
621
|
-
if (listed.length > MAX_LISTED_SCRIPTS) sections.push(`...and ${listed.length - MAX_LISTED_SCRIPTS} more; use discover({ query }) to search.`);
|
|
619
|
+
for (const script of listed) {
|
|
620
|
+
if (hits.length >= MAX_QUERY_LINES) break;
|
|
621
|
+
if (`${script.specifier} ${script.description}`.toLowerCase().includes(needle)) hits.push(`script ${script.specifier}: ${script.description}`);
|
|
622
622
|
}
|
|
623
|
-
|
|
624
|
-
return text(sections.join("\n"));
|
|
623
|
+
return text(hits.length > 0 ? hits.join("\n") : `No members or scripts match "${parameters.query}".`);
|
|
625
624
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
const service = isolate();
|
|
632
|
-
return [
|
|
633
|
-
"Run a TypeScript script inside the Po server with live objects from the namespaces below in scope.",
|
|
634
|
-
"It runs with full server trust, like bash. Keep each call to one logical step.",
|
|
635
|
-
(service ? visible(service) : []).map((namespace) => `- ${namespace.name}: ${namespace.summary}`).join("\n") || "(no namespaces registered yet; call discover to check)",
|
|
636
|
-
GLOBALS_HELP,
|
|
637
|
-
...scripts && service?.liveObjects ? [`${SCRIPTS_HELP} discover lists saved and domain scripts.`, ...domainScriptsHelp()] : [],
|
|
638
|
-
"Use discover({ namespace }) for full signatures when needed."
|
|
639
|
-
].join("\n");
|
|
640
|
-
},
|
|
641
|
-
parameters: ExecToolSchema,
|
|
642
|
-
promptSnippet: "Run a TypeScript script against live Po objects (browser and other namespaces)",
|
|
643
|
-
executionMode: "serial",
|
|
644
|
-
async execute(toolCallId, parameters, signal, _onUpdate, execution) {
|
|
645
|
-
return executeCode(parameters, signal, execution, Math.min(MAX_TIMEOUT_MS, Math.max(MIN_TIMEOUT_MS, parameters.timeoutMs ?? DEFAULT_TIMEOUT_MS)), toolCallId);
|
|
625
|
+
const sections = [];
|
|
626
|
+
if (namespaces.length === 0) sections.push("No namespaces are registered in this session.");
|
|
627
|
+
for (const namespace of namespaces) {
|
|
628
|
+
const members = memberNames(namespace).map((member) => gatedLabel(namespace, member));
|
|
629
|
+
sections.push(`- ${namespace.name}: ${namespace.summary}\n members: ${members.join(", ")}`);
|
|
646
630
|
}
|
|
631
|
+
sections.push(GLOBALS_HELP);
|
|
632
|
+
if (!service.liveObjects) sections.push("This host runs plain JavaScript with JSON-only functions.");
|
|
633
|
+
if (listed.length > 0) {
|
|
634
|
+
sections.push(`Scripts. ${SCRIPTS_HELP}`);
|
|
635
|
+
for (const script of listed.slice(0, MAX_LISTED_SCRIPTS)) sections.push(`- ${script.specifier}${script.description ? `: ${script.description}` : ""}`);
|
|
636
|
+
if (listed.length > MAX_LISTED_SCRIPTS) sections.push(`...and ${listed.length - MAX_LISTED_SCRIPTS} more; use discover({ query }) to search.`);
|
|
637
|
+
}
|
|
638
|
+
if (namespaces.length > 0) sections.push("Call discover({ namespace }) for full types.");
|
|
639
|
+
return text(sections.join("\n"));
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
const exec = {
|
|
643
|
+
name: "exec",
|
|
644
|
+
label: "Exec",
|
|
645
|
+
get description() {
|
|
646
|
+
const service = isolate();
|
|
647
|
+
return [
|
|
648
|
+
"Run a TypeScript script inside the Po server with live objects from the namespaces below in scope.",
|
|
649
|
+
"It runs with full server trust, like bash. Keep each call to one logical step.",
|
|
650
|
+
(service ? visible(service) : []).map((namespace) => `- ${namespace.name}: ${namespace.summary}`).join("\n") || "(no namespaces registered yet; call discover to check)",
|
|
651
|
+
GLOBALS_HELP,
|
|
652
|
+
...scripts && service?.liveObjects ? [`${SCRIPTS_HELP} discover lists saved and domain scripts.`, ...domainScriptsHelp()] : [],
|
|
653
|
+
"Use discover({ namespace }) for full signatures when needed."
|
|
654
|
+
].join("\n");
|
|
647
655
|
},
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
parameters
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
656
|
+
parameters: ExecToolSchema,
|
|
657
|
+
promptSnippet: "Run a TypeScript script against live Po objects (browser and other namespaces)",
|
|
658
|
+
executionMode: "serial",
|
|
659
|
+
async execute(toolCallId, parameters, signal, _onUpdate, execution) {
|
|
660
|
+
return executeCode(parameters, signal, execution, Math.min(MAX_TIMEOUT_MS, Math.max(MIN_TIMEOUT_MS, parameters.timeoutMs ?? DEFAULT_TIMEOUT_MS)), toolCallId);
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
const execBackground = {
|
|
664
|
+
name: "exec_background",
|
|
665
|
+
label: "Background Exec",
|
|
666
|
+
description: "Run a long-lived Node code-mode script. Returns its ID immediately; one completion message arrives after execution and cleanup. End the turn rather than polling. Full server trust, like exec.",
|
|
667
|
+
parameters: ExecBackgroundToolSchema,
|
|
668
|
+
mainAgentOnly: true,
|
|
669
|
+
executionMode: "serial",
|
|
670
|
+
async execute(toolCallId, parameters, signal, _onUpdate, execution) {
|
|
671
|
+
if (signal?.aborted) return text("Background exec launch was aborted.", true);
|
|
672
|
+
if (closing || ownerSignal.aborted) return text("Code mode session is disposing.", true);
|
|
673
|
+
if (!isolate()?.liveObjects) return text("Background exec requires a Node host with live objects.", true);
|
|
674
|
+
if (!execution.session?.admitMessage) return text("This session cannot admit background exec completion messages.", true);
|
|
675
|
+
if (running >= MAX_CONCURRENT_RUNS) return text(`This session already has ${MAX_CONCURRENT_RUNS} exec runs active. Wait for one to finish.`, true);
|
|
676
|
+
const deadlineMs = Math.min(BACKGROUND_MAX_TIMEOUT_MS, Math.max(MIN_TIMEOUT_MS, parameters.timeoutMs ?? BACKGROUND_DEFAULT_TIMEOUT_MS));
|
|
677
|
+
const id = crypto.randomUUID();
|
|
678
|
+
const controller = new AbortController();
|
|
679
|
+
const job = {
|
|
680
|
+
id,
|
|
681
|
+
sessionId: execution.sessionId,
|
|
682
|
+
controller,
|
|
683
|
+
status: "running",
|
|
684
|
+
done: Promise.resolve()
|
|
685
|
+
};
|
|
686
|
+
jobs.set(id, job);
|
|
687
|
+
onBackgroundChange?.();
|
|
688
|
+
job.done = (async () => {
|
|
689
|
+
let timedOut = false;
|
|
690
|
+
const timer = setTimeout(() => {
|
|
691
|
+
timedOut = true;
|
|
692
|
+
controller.abort();
|
|
693
|
+
}, deadlineMs);
|
|
694
|
+
try {
|
|
695
|
+
const result = await executeCode(parameters, controller.signal, execution, deadlineMs, toolCallId, true);
|
|
696
|
+
clearTimeout(timer);
|
|
697
|
+
job.status = "reporting";
|
|
698
|
+
onBackgroundChange?.();
|
|
699
|
+
const status = timedOut ? "timed-out" : controller.signal.aborted ? "stopped" : result.isError ? "failed" : "completed";
|
|
700
|
+
const message = {
|
|
701
|
+
type: "po-codemode-finished",
|
|
702
|
+
text: `Background exec ${id} ${status}.\n${result.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("\n")}`,
|
|
703
|
+
display: true,
|
|
704
|
+
details: {
|
|
705
|
+
id,
|
|
706
|
+
status,
|
|
707
|
+
result
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
let warned = false;
|
|
711
|
+
while (!ownerSignal.aborted) {
|
|
712
|
+
let stopAdmission;
|
|
713
|
+
try {
|
|
714
|
+
const stopped = new Promise((resolve) => {
|
|
715
|
+
stopAdmission = resolve;
|
|
716
|
+
ownerSignal.addEventListener("abort", stopAdmission, { once: true });
|
|
717
|
+
if (ownerSignal.aborted) resolve();
|
|
718
|
+
});
|
|
719
|
+
await Promise.race([execution.session.admitMessage(message, "steer", `po-codemode-finished:${execution.sessionId}:${id}`), stopped]);
|
|
720
|
+
break;
|
|
721
|
+
} catch (error) {
|
|
722
|
+
if (ownerSignal.aborted) break;
|
|
723
|
+
if (!warned) {
|
|
724
|
+
warned = true;
|
|
725
|
+
await Promise.resolve().then(() => execution.client.notify({
|
|
726
|
+
body: `Background exec completion admission failed; retrying: ${String(error)}`,
|
|
727
|
+
level: "warning"
|
|
728
|
+
})).catch(() => void 0);
|
|
718
729
|
}
|
|
730
|
+
await sleep(250, ownerSignal).catch(() => void 0);
|
|
731
|
+
} finally {
|
|
732
|
+
if (stopAdmission) ownerSignal.removeEventListener("abort", stopAdmission);
|
|
719
733
|
}
|
|
720
|
-
} finally {
|
|
721
|
-
clearTimeout(timer);
|
|
722
|
-
jobs.delete(id);
|
|
723
|
-
onBackgroundChange?.();
|
|
724
734
|
}
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
735
|
+
} finally {
|
|
736
|
+
clearTimeout(timer);
|
|
737
|
+
jobs.delete(id);
|
|
738
|
+
onBackgroundChange?.();
|
|
739
|
+
}
|
|
740
|
+
})();
|
|
741
|
+
return {
|
|
742
|
+
...text(JSON.stringify({ id })),
|
|
743
|
+
details: { id }
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
};
|
|
747
|
+
const execCancel = {
|
|
748
|
+
name: "exec_cancel",
|
|
749
|
+
label: "Cancel Exec",
|
|
750
|
+
description: "Cancel a background exec in this session. Its terminal message follows child cleanup.",
|
|
751
|
+
parameters: ExecCancelToolSchema,
|
|
752
|
+
mainAgentOnly: true,
|
|
753
|
+
executionMode: "serial",
|
|
754
|
+
async execute(_toolCallId, parameters, _signal, _onUpdate, execution) {
|
|
755
|
+
const job = jobs.get(parameters.id);
|
|
756
|
+
if (job && job.sessionId !== execution.sessionId) return text("Background exec belongs to another session.", true);
|
|
757
|
+
if (job?.status === "running") job.controller.abort(parameters.reason ? new Error(parameters.reason) : void 0);
|
|
758
|
+
return text(JSON.stringify({
|
|
759
|
+
id: parameters.id,
|
|
760
|
+
status: job?.status === "running" ? "stopping" : "finished"
|
|
761
|
+
}));
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
const runApproved = async (call, signal, sessionId) => {
|
|
765
|
+
const name = call.operation.name;
|
|
766
|
+
const [namespaceName, ...path] = name.split(".");
|
|
767
|
+
const namespace = registry.list().find((entry) => entry.name === namespaceName);
|
|
768
|
+
if (namespace === void 0 || path.length === 0) throw new Error(`'${name}' is no longer active. Nothing ran.`);
|
|
769
|
+
if (namespace.approval?.[path.join(".")] === void 0) throw new Error(`'${name}' no longer asks for approval, so it was not replayed. Nothing ran.`);
|
|
770
|
+
signal.throwIfAborted();
|
|
771
|
+
const cleanups = [];
|
|
772
|
+
const bound = namespace.bind({
|
|
773
|
+
source: "",
|
|
774
|
+
sessionId,
|
|
775
|
+
caller: "main",
|
|
776
|
+
toolCallId: `approval:${call.approvalId}`,
|
|
777
|
+
interaction: "interactive",
|
|
778
|
+
signal,
|
|
779
|
+
onDispose: (cleanup) => void cleanups.push(cleanup),
|
|
780
|
+
record: () => void 0,
|
|
781
|
+
emitImage: () => ({
|
|
782
|
+
emitted: false,
|
|
783
|
+
warning: "An approved call cannot show images."
|
|
784
|
+
})
|
|
785
|
+
});
|
|
786
|
+
try {
|
|
787
|
+
let receiver = bound;
|
|
788
|
+
let member = bound;
|
|
789
|
+
for (const key of path) {
|
|
790
|
+
receiver = member;
|
|
791
|
+
member = typeof member === "object" && member !== null ? Reflect.get(member, key, member) : void 0;
|
|
747
792
|
}
|
|
748
|
-
|
|
793
|
+
if (typeof member !== "function") throw new Error(`'${name}' is no longer active. Nothing ran.`);
|
|
794
|
+
return await Reflect.apply(member, receiver, [call.input]);
|
|
795
|
+
} finally {
|
|
796
|
+
for (const cleanup of cleanups.reverse()) await cleanup();
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
return {
|
|
800
|
+
discover,
|
|
801
|
+
exec,
|
|
802
|
+
execBackground,
|
|
803
|
+
execCancel,
|
|
749
804
|
backgroundWork,
|
|
805
|
+
runApproved,
|
|
750
806
|
async dispose() {
|
|
751
807
|
closing = true;
|
|
752
808
|
unsubscribe();
|
|
@@ -769,4 +825,4 @@ Object.defineProperty(exports, "createCodemodeTools", {
|
|
|
769
825
|
}
|
|
770
826
|
});
|
|
771
827
|
|
|
772
|
-
//# sourceMappingURL=codemodeTools-
|
|
828
|
+
//# sourceMappingURL=codemodeTools-46IqsFCu.cjs.map
|