@ashx-j/lunr 0.2.22 → 0.2.23
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/CHANGELOG.md +3 -1
- package/README.md +5 -3
- package/dist/builtin-extensions/lunr-browser.d.ts +7 -1
- package/dist/builtin-extensions/lunr-browser.d.ts.map +1 -1
- package/dist/builtin-extensions/lunr-browser.js +116 -3
- package/dist/builtin-extensions/lunr-browser.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js +9 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-wait.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +41 -3
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +4 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +3 -2
- package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -1
- package/dist/core/agent-session.d.ts +19 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +230 -103
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/settings-manager.d.ts +4 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +9 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/subagent-wait-interruption.d.ts +11 -0
- package/dist/core/subagent-wait-interruption.d.ts.map +1 -0
- package/dist/core/subagent-wait-interruption.js +19 -0
- package/dist/core/subagent-wait-interruption.js.map +1 -0
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +3 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +3 -3
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +3 -3
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +10 -2
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +29 -5
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/copyable-text.d.ts +2 -6
- package/dist/modes/interactive/components/copyable-text.d.ts.map +1 -1
- package/dist/modes/interactive/components/copyable-text.js +26 -35
- package/dist/modes/interactive/components/copyable-text.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +13 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-tail.d.ts +9 -2
- package/dist/modes/interactive/components/thinking-tail.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-tail.js +43 -1
- package/dist/modes/interactive/components/thinking-tail.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +4 -3
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +34 -45
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +6 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +118 -39
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +1 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +23 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/node-runtime/{agent-session-services-NQ6GKOIK.js → agent-session-services-GZVSOGYR.js} +7 -7
- package/dist/node-runtime/{builtin-extensions-GVC6IFDU.js → builtin-extensions-QVCXNQT4.js} +3 -3
- package/dist/node-runtime/{chunk-6B2POMK7.js → chunk-6VYZ5UFP.js} +1 -1
- package/dist/node-runtime/{chunk-VJPTNWAP.js → chunk-DD5YWFSJ.js} +1 -1
- package/dist/node-runtime/{chunk-TDL7UWJ7.js → chunk-DQMGU675.js} +173 -57
- package/dist/node-runtime/{chunk-V2A7CEXK.js → chunk-EKVFP6YF.js} +2 -2
- package/dist/node-runtime/{chunk-5BNJ4JUH.js → chunk-GJ2RDBRL.js} +1 -1
- package/dist/node-runtime/{chunk-GNN7H3B7.js → chunk-GS42T6MX.js} +1 -1
- package/dist/node-runtime/{chunk-PC2Z5TKZ.js → chunk-HMBGROQK.js} +3 -3
- package/dist/node-runtime/{chunk-GJSAD4AB.js → chunk-HPUP7E4T.js} +10 -10
- package/dist/node-runtime/{chunk-IVXYUAJE.js → chunk-IF24A3FH.js} +1 -1
- package/dist/node-runtime/{chunk-BFNXONG3.js → chunk-LFZDVKSP.js} +2 -2
- package/dist/node-runtime/{chunk-EQ63ANHL.js → chunk-LLUIPGDR.js} +210 -125
- package/dist/node-runtime/{chunk-ORH324EP.js → chunk-PCEW76PM.js} +3 -3
- package/dist/node-runtime/{chunk-WADV2VDS.js → chunk-QAZOULTU.js} +7 -0
- package/dist/node-runtime/{chunk-6427XAWG.js → chunk-QH6YL7VK.js} +3 -3
- package/dist/node-runtime/{chunk-7QWNYZDI.js → chunk-RDDAZOMU.js} +16 -0
- package/dist/node-runtime/{chunk-QDGKKKUM.js → chunk-RIR5EDDJ.js} +1 -1
- package/dist/node-runtime/{chunk-H3XF4UVQ.js → chunk-RWTKOC3B.js} +1 -1
- package/dist/node-runtime/{chunk-IQIEU7SB.js → chunk-TVJUOJZJ.js} +2 -2
- package/dist/node-runtime/{chunk-UAFLNHSH.js → chunk-W64JC4E7.js} +8 -8
- package/dist/node-runtime/{chunk-LMBNLFXQ.js → chunk-X3URCYCU.js} +4 -4
- package/dist/node-runtime/{chunk-VSSXXL36.js → chunk-YDO2F2IA.js} +2 -2
- package/dist/node-runtime/{chunk-IWOWXRWU.js → chunk-YHQ3NBB3.js} +15 -15
- package/dist/node-runtime/cli-runtime.js +1 -1
- package/dist/node-runtime/{command-3JHHXOPX.js → command-PDVTBRWA.js} +3 -3
- package/dist/node-runtime/{commands-2JVNFGMQ.js → commands-XDCFGIGW.js} +5 -5
- package/dist/node-runtime/{export-html-KBFVV63J.js → export-html-KSOIMVPI.js} +1 -1
- package/dist/node-runtime/{extension-input-K24TVKVW.js → extension-input-E7BJZ35H.js} +4 -4
- package/dist/node-runtime/{extension-selector-SPNF7EDR.js → extension-selector-WU42XDTU.js} +4 -4
- package/dist/node-runtime/{gateway-VFO6SFKK.js → gateway-AYWM5DIO.js} +7 -7
- package/dist/node-runtime/index.js +17 -17
- package/dist/node-runtime/{install-cli-C3CF7O7N.js → install-cli-3BO4MMQ6.js} +1 -1
- package/dist/node-runtime/{interactive-mode-LOM6AIF6.js → interactive-mode-4MFRKAHG.js} +13 -13
- package/dist/node-runtime/{interactive-view-IDSCPPK7.js → interactive-view-TUZHCQM3.js} +5 -5
- package/dist/node-runtime/{lunr-browser-YNW7FTYX.js → lunr-browser-RYFIIVJN.js} +91 -4
- package/dist/node-runtime/{lunr-cron-BKHGNBKT.js → lunr-cron-YWXEPZMQ.js} +4 -4
- package/dist/node-runtime/main.js +14 -14
- package/dist/node-runtime/{mobile-commands-HMP25WBC.js → mobile-commands-LVHDAUDP.js} +4 -4
- package/dist/node-runtime/{package-manager-cli-VCK4E2RC.js → package-manager-cli-6GT3Z3CK.js} +9 -9
- package/dist/node-runtime/{pi-subagents-FEUDLJOE.js → pi-subagents-CDWK2AKY.js} +44 -10
- package/dist/node-runtime/rpc-entry.js +14 -14
- package/dist/node-runtime/{rpc-mode-P5ODXPEG.js → rpc-mode-O3XV4SID.js} +2 -2
- package/dist/node-runtime/{session-selector-LHRMJOKT.js → session-selector-GIM4DHQ2.js} +4 -4
- package/dist/node-runtime/{settings-manager-UUZ6NUXI.js → settings-manager-6VEMXRDL.js} +1 -1
- package/dist/node-runtime/{setup-NRXVZBLJ.js → setup-5SR2J35A.js} +1 -1
- package/dist/node-runtime/{subagent-executor-MLUMBWCP.js → subagent-executor-M5VWB3D3.js} +8 -4
- package/dist/node-runtime/{theme-U7IGOA7O.js → theme-UOO5RVFN.js} +1 -1
- package/dist/node-runtime/{update-cli-4TP25CNW.js → update-cli-UVKJWRRJ.js} +1 -1
- package/docs/features.md +2 -0
- package/docs/settings.md +1 -0
- package/docs/usage.md +2 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
|
@@ -34,6 +34,7 @@ import { expandPromptTemplate } from "./prompt-templates.js";
|
|
|
34
34
|
import { rollbackSnapshotBeforeWrite } from "./rollback.js";
|
|
35
35
|
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
|
|
36
36
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
37
|
+
import { registerSubagentWaitInterruptionOwner, } from "./subagent-wait-interruption.js";
|
|
37
38
|
import { buildSystemPrompt } from "./system-prompt.js";
|
|
38
39
|
import { measureStartup } from "./timings.js";
|
|
39
40
|
import { TODO_TOOL_NAMES } from "./todo-settings.js";
|
|
@@ -90,6 +91,11 @@ export class AgentSession {
|
|
|
90
91
|
_isAgentRunActive = false;
|
|
91
92
|
_idleWaitPromise;
|
|
92
93
|
_resolveIdleWait;
|
|
94
|
+
_activePromptRun;
|
|
95
|
+
_waitPromptHandoff;
|
|
96
|
+
_waitPromptAcceptance = Promise.resolve();
|
|
97
|
+
_waitPromptGeneration = 0;
|
|
98
|
+
_unregisterSubagentWaitInterruptionOwners = [];
|
|
93
99
|
/** Tracks pending steering messages for UI display. Removed when delivered. */
|
|
94
100
|
_steeringMessages = [];
|
|
95
101
|
/** Tracks pending follow-up messages for UI display. Removed when delivered. */
|
|
@@ -161,6 +167,10 @@ export class AgentSession {
|
|
|
161
167
|
this._excludedToolNames = config.excludedToolNames ? new Set(config.excludedToolNames) : undefined;
|
|
162
168
|
this._baseToolsOverride = config.baseToolsOverride;
|
|
163
169
|
this._sessionStartEvent = config.sessionStartEvent ?? { type: "session_start", reason: "startup" };
|
|
170
|
+
const waitInterruptionOwner = { register: () => this._registerSubagentWaitInterruption() };
|
|
171
|
+
for (const identity of new Set([this.sessionId, this.sessionFile].filter((value) => !!value))) {
|
|
172
|
+
this._unregisterSubagentWaitInterruptionOwners.push(registerSubagentWaitInterruptionOwner(identity, waitInterruptionOwner));
|
|
173
|
+
}
|
|
164
174
|
// Always subscribe to agent events for internal handling
|
|
165
175
|
// (session persistence, extensions, auto-compaction, retry logic)
|
|
166
176
|
this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
|
|
@@ -644,6 +654,8 @@ export class AgentSession {
|
|
|
644
654
|
transferring = false;
|
|
645
655
|
setTransferring(value) {
|
|
646
656
|
this.transferring = value;
|
|
657
|
+
if (value)
|
|
658
|
+
this._invalidateWaitPromptHandoffs("Session transfer interrupted the pending prompt.");
|
|
647
659
|
}
|
|
648
660
|
assertCanStartWork() {
|
|
649
661
|
this.sessionManager.assertWritable();
|
|
@@ -651,6 +663,9 @@ export class AgentSession {
|
|
|
651
663
|
throw new Error("Session transfer is in progress. Wait or reclaim the session.");
|
|
652
664
|
}
|
|
653
665
|
dispose() {
|
|
666
|
+
this._invalidateWaitPromptHandoffs("Session closed before the pending prompt could run.");
|
|
667
|
+
for (const unregister of this._unregisterSubagentWaitInterruptionOwners.splice(0))
|
|
668
|
+
unregister();
|
|
654
669
|
try {
|
|
655
670
|
this.abortRetry();
|
|
656
671
|
this.abortCompaction();
|
|
@@ -690,6 +705,10 @@ export class AgentSession {
|
|
|
690
705
|
get isIdle() {
|
|
691
706
|
return !this._isAgentRunActive;
|
|
692
707
|
}
|
|
708
|
+
/** Whether normal Enter is still being reserved for an interrupted wait handoff. */
|
|
709
|
+
get isWaitPromptHandoffActive() {
|
|
710
|
+
return this._waitPromptHandoff?.accepting === true;
|
|
711
|
+
}
|
|
693
712
|
/** Current effective system prompt (includes any per-turn extension modifications) */
|
|
694
713
|
get systemPrompt() {
|
|
695
714
|
return this.agent.state.systemPrompt;
|
|
@@ -885,24 +904,67 @@ export class AgentSession {
|
|
|
885
904
|
// =========================================================================
|
|
886
905
|
// Prompting
|
|
887
906
|
// =========================================================================
|
|
907
|
+
_registerSubagentWaitInterruption() {
|
|
908
|
+
const run = this._activePromptRun;
|
|
909
|
+
const ownerSignal = this.agent.signal;
|
|
910
|
+
const wait = run && ownerSignal ? { controller: new AbortController(), interrupted: false, ownerSignal } : undefined;
|
|
911
|
+
if (run && wait) {
|
|
912
|
+
run.waits.add(wait);
|
|
913
|
+
if (run.gracefulStopRequested) {
|
|
914
|
+
wait.interrupted = true;
|
|
915
|
+
wait.controller.abort();
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
const signal = wait?.controller.signal ?? new AbortController().signal;
|
|
919
|
+
return {
|
|
920
|
+
signal,
|
|
921
|
+
wasInterrupted: () => wait?.interrupted === true,
|
|
922
|
+
unregister: () => {
|
|
923
|
+
if (wait)
|
|
924
|
+
run?.waits.delete(wait);
|
|
925
|
+
},
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
_interruptSubagentWaits(run, ownerSignal) {
|
|
929
|
+
for (const wait of run.waits) {
|
|
930
|
+
if (wait.ownerSignal !== ownerSignal)
|
|
931
|
+
continue;
|
|
932
|
+
wait.interrupted = true;
|
|
933
|
+
wait.controller.abort();
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
_invalidateWaitPromptHandoffs(message) {
|
|
937
|
+
this._waitPromptGeneration++;
|
|
938
|
+
const handoff = this._waitPromptHandoff;
|
|
939
|
+
this._waitPromptHandoff = undefined;
|
|
940
|
+
if (!handoff)
|
|
941
|
+
return;
|
|
942
|
+
const error = new Error(message);
|
|
943
|
+
for (const reservation of handoff.reservations.splice(0))
|
|
944
|
+
reservation.reject(error);
|
|
945
|
+
}
|
|
888
946
|
async _runAgentPrompt(messages) {
|
|
947
|
+
const run = { waits: new Set(), gracefulStopRequested: false };
|
|
948
|
+
this._activePromptRun = run;
|
|
889
949
|
this._isAgentRunActive = true;
|
|
890
950
|
try {
|
|
891
951
|
await this.agent.prompt(messages);
|
|
892
|
-
while (await this._handlePostAgentRun()) {
|
|
952
|
+
while (await this._handlePostAgentRun(run)) {
|
|
893
953
|
await this.agent.continue();
|
|
894
954
|
}
|
|
895
955
|
}
|
|
896
956
|
finally {
|
|
957
|
+
if (this._activePromptRun === run)
|
|
958
|
+
this._activePromptRun = undefined;
|
|
897
959
|
this._systemPromptOverride = undefined;
|
|
898
960
|
this._flushPendingBashMessages();
|
|
899
961
|
await this._emitAgentSettled();
|
|
900
962
|
}
|
|
901
963
|
}
|
|
902
|
-
async _handlePostAgentRun() {
|
|
964
|
+
async _handlePostAgentRun(run) {
|
|
903
965
|
const msg = this._lastAssistantMessage;
|
|
904
966
|
this._lastAssistantMessage = undefined;
|
|
905
|
-
if (!msg) {
|
|
967
|
+
if (!msg || run.gracefulStopRequested) {
|
|
906
968
|
return false;
|
|
907
969
|
}
|
|
908
970
|
// lunr: quota-dead or auth-invalid keys rotate immediately — same-key backoff
|
|
@@ -944,130 +1006,193 @@ export class AgentSession {
|
|
|
944
1006
|
*/
|
|
945
1007
|
async prompt(text, options) {
|
|
946
1008
|
this.assertCanStartWork();
|
|
947
|
-
const expandPromptTemplates = options?.expandPromptTemplates ?? true;
|
|
948
1009
|
const preflightResult = options?.preflightResult;
|
|
1010
|
+
let prepared;
|
|
949
1011
|
let messages;
|
|
950
1012
|
try {
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
if (handled) {
|
|
956
|
-
// Extension command executed, no prompt to send
|
|
957
|
-
preflightResult?.(true);
|
|
958
|
-
return;
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
// Emit input event for extension interception (before skill/template expansion)
|
|
962
|
-
let currentText = text;
|
|
963
|
-
let currentImages = options?.images;
|
|
964
|
-
if (this._extensionRunner.hasHandlers("input")) {
|
|
965
|
-
const inputResult = await this._extensionRunner.emitInput(currentText, currentImages, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
|
|
966
|
-
if (inputResult.action === "handled") {
|
|
967
|
-
preflightResult?.(true);
|
|
968
|
-
return;
|
|
969
|
-
}
|
|
970
|
-
if (inputResult.action === "transform") {
|
|
971
|
-
currentText = inputResult.text;
|
|
972
|
-
currentImages = inputResult.images ?? currentImages;
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
// Expand skill commands (/skill:name args) and prompt templates (/template args)
|
|
976
|
-
let expandedText = currentText;
|
|
977
|
-
if (expandPromptTemplates) {
|
|
978
|
-
expandedText = this._expandSkillCommand(expandedText);
|
|
979
|
-
expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
|
|
1013
|
+
prepared = await this._preparePromptInput(text, options, this.isStreaming ? options?.streamingBehavior : undefined);
|
|
1014
|
+
if (!prepared) {
|
|
1015
|
+
preflightResult?.(true);
|
|
1016
|
+
return;
|
|
980
1017
|
}
|
|
981
|
-
// If streaming, queue via steer() or followUp() based on option
|
|
982
1018
|
if (this.isStreaming) {
|
|
983
1019
|
if (!options?.streamingBehavior) {
|
|
984
1020
|
throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");
|
|
985
1021
|
}
|
|
986
1022
|
if (options.streamingBehavior === "followUp") {
|
|
987
|
-
await this._queueFollowUp(
|
|
1023
|
+
await this._queueFollowUp(prepared.text, prepared.images);
|
|
988
1024
|
}
|
|
989
1025
|
else {
|
|
990
|
-
await this._queueSteer(
|
|
1026
|
+
await this._queueSteer(prepared.text, prepared.images);
|
|
991
1027
|
}
|
|
992
1028
|
preflightResult?.(true);
|
|
993
1029
|
return;
|
|
994
1030
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
if (
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1031
|
+
messages = await this._createPromptMessages(prepared);
|
|
1032
|
+
}
|
|
1033
|
+
catch (error) {
|
|
1034
|
+
preflightResult?.(false);
|
|
1035
|
+
throw error;
|
|
1036
|
+
}
|
|
1037
|
+
preflightResult?.(true);
|
|
1038
|
+
await this._runAgentPrompt(messages);
|
|
1039
|
+
}
|
|
1040
|
+
async _preparePromptInput(text, options, streamingBehavior) {
|
|
1041
|
+
const expandPromptTemplates = options?.expandPromptTemplates ?? true;
|
|
1042
|
+
if (expandPromptTemplates && text.startsWith("/") && (await this._tryExecuteExtensionCommand(text))) {
|
|
1043
|
+
return undefined;
|
|
1044
|
+
}
|
|
1045
|
+
let currentText = text;
|
|
1046
|
+
let currentImages = options?.images;
|
|
1047
|
+
if (this._extensionRunner.hasHandlers("input")) {
|
|
1048
|
+
const inputResult = await this._extensionRunner.emitInput(currentText, currentImages, options?.source ?? "interactive", streamingBehavior);
|
|
1049
|
+
if (inputResult.action === "handled")
|
|
1050
|
+
return undefined;
|
|
1051
|
+
if (inputResult.action === "transform") {
|
|
1052
|
+
currentText = inputResult.text;
|
|
1053
|
+
currentImages = inputResult.images ?? currentImages;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
if (expandPromptTemplates) {
|
|
1057
|
+
currentText = this._expandSkillCommand(currentText);
|
|
1058
|
+
currentText = expandPromptTemplate(currentText, [...this.promptTemplates]);
|
|
1059
|
+
}
|
|
1060
|
+
return { text: currentText, images: currentImages };
|
|
1061
|
+
}
|
|
1062
|
+
async _createPromptMessages(input) {
|
|
1063
|
+
this._flushPendingBashMessages();
|
|
1064
|
+
if (!this.model)
|
|
1065
|
+
throw new Error(formatNoModelSelectedMessage());
|
|
1066
|
+
const hasConfiguredAuth = this._modelRuntime.hasConfiguredAuth(this.model.provider) ||
|
|
1067
|
+
(await this._modelRuntime.checkAuth(this.model.provider)) !== undefined;
|
|
1068
|
+
if (!hasConfiguredAuth) {
|
|
1069
|
+
if (this._modelRuntime.isUsingOAuth(this.model.provider)) {
|
|
1070
|
+
throw new Error(`Authentication failed for "${this.model.provider}". ` +
|
|
1071
|
+
`Credentials may have expired or network is unavailable. ` +
|
|
1072
|
+
`Run '/login ${this.model.provider}' to re-authenticate.`);
|
|
1073
|
+
}
|
|
1074
|
+
throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
|
|
1075
|
+
}
|
|
1076
|
+
const lastAssistant = this._findLastAssistantMessage();
|
|
1077
|
+
if (lastAssistant)
|
|
1078
|
+
await this._checkCompaction(lastAssistant, false);
|
|
1079
|
+
const userContent = [{ type: "text", text: input.text }];
|
|
1080
|
+
if (input.images)
|
|
1081
|
+
userContent.push(...input.images);
|
|
1082
|
+
const messages = [
|
|
1083
|
+
{
|
|
1026
1084
|
role: "user",
|
|
1027
1085
|
content: userContent,
|
|
1028
1086
|
timestamp: Date.now(),
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
content: msg.content ?? [],
|
|
1045
|
-
display: msg.display,
|
|
1046
|
-
details: msg.details,
|
|
1047
|
-
timestamp: Date.now(),
|
|
1048
|
-
});
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
// Apply extension-modified system prompt, or reset to base
|
|
1052
|
-
if (result?.systemPrompt !== undefined) {
|
|
1053
|
-
this._systemPromptOverride = result.systemPrompt;
|
|
1054
|
-
this.agent.state.systemPrompt = this._withSystemPromptAppend(result.systemPrompt);
|
|
1055
|
-
}
|
|
1056
|
-
else {
|
|
1057
|
-
// Ensure we're using the base prompt (in case previous turn had modifications)
|
|
1058
|
-
this._systemPromptOverride = undefined;
|
|
1059
|
-
this.agent.state.systemPrompt = this._withSystemPromptAppend(this._baseSystemPrompt);
|
|
1087
|
+
},
|
|
1088
|
+
...this._pendingNextTurnMessages,
|
|
1089
|
+
];
|
|
1090
|
+
this._pendingNextTurnMessages = [];
|
|
1091
|
+
const result = await this._extensionRunner.emitBeforeAgentStart(input.text, input.images, this._baseSystemPrompt, this._baseSystemPromptOptions);
|
|
1092
|
+
if (result?.messages) {
|
|
1093
|
+
for (const msg of result.messages) {
|
|
1094
|
+
messages.push({
|
|
1095
|
+
role: "custom",
|
|
1096
|
+
customType: msg.customType,
|
|
1097
|
+
content: msg.content ?? [],
|
|
1098
|
+
display: msg.display,
|
|
1099
|
+
details: msg.details,
|
|
1100
|
+
timestamp: Date.now(),
|
|
1101
|
+
});
|
|
1060
1102
|
}
|
|
1061
1103
|
}
|
|
1104
|
+
if (result?.systemPrompt !== undefined) {
|
|
1105
|
+
this._systemPromptOverride = result.systemPrompt;
|
|
1106
|
+
this.agent.state.systemPrompt = this._withSystemPromptAppend(result.systemPrompt);
|
|
1107
|
+
}
|
|
1108
|
+
else {
|
|
1109
|
+
this._systemPromptOverride = undefined;
|
|
1110
|
+
this.agent.state.systemPrompt = this._withSystemPromptAppend(this._baseSystemPrompt);
|
|
1111
|
+
}
|
|
1112
|
+
return messages;
|
|
1113
|
+
}
|
|
1114
|
+
async interruptSubagentWaitWithPrompt(text, options) {
|
|
1115
|
+
const acceptance = this._waitPromptAcceptance.then(() => this._reserveWaitPrompt(text, options));
|
|
1116
|
+
this._waitPromptAcceptance = acceptance.then(() => { }, () => { });
|
|
1117
|
+
return acceptance;
|
|
1118
|
+
}
|
|
1119
|
+
async _reserveWaitPrompt(text, options) {
|
|
1120
|
+
this.assertCanStartWork();
|
|
1121
|
+
const activeRun = this._activePromptRun;
|
|
1122
|
+
const existing = this._waitPromptHandoff;
|
|
1123
|
+
const activeWait = activeRun?.waits.values().next().value;
|
|
1124
|
+
const run = existing?.accepting ? existing.run : activeWait ? activeRun : undefined;
|
|
1125
|
+
const ownerSignal = existing?.accepting ? existing.ownerSignal : activeWait?.ownerSignal;
|
|
1126
|
+
if (!run || !ownerSignal)
|
|
1127
|
+
return undefined;
|
|
1128
|
+
const handoff = existing?.run === run && existing.accepting
|
|
1129
|
+
? existing
|
|
1130
|
+
: {
|
|
1131
|
+
run,
|
|
1132
|
+
ownerSignal,
|
|
1133
|
+
generation: this._waitPromptGeneration,
|
|
1134
|
+
reservations: [],
|
|
1135
|
+
draining: false,
|
|
1136
|
+
accepting: true,
|
|
1137
|
+
};
|
|
1138
|
+
this._waitPromptHandoff = handoff;
|
|
1139
|
+
let prepared;
|
|
1140
|
+
try {
|
|
1141
|
+
prepared = await this._preparePromptInput(text, options, undefined);
|
|
1142
|
+
}
|
|
1062
1143
|
catch (error) {
|
|
1063
|
-
|
|
1144
|
+
if (handoff.reservations.length === 0 && this._waitPromptHandoff === handoff) {
|
|
1145
|
+
this._waitPromptHandoff = undefined;
|
|
1146
|
+
}
|
|
1064
1147
|
throw error;
|
|
1065
1148
|
}
|
|
1066
|
-
if (!
|
|
1067
|
-
|
|
1149
|
+
if (!prepared) {
|
|
1150
|
+
if (handoff.reservations.length === 0 && this._waitPromptHandoff === handoff) {
|
|
1151
|
+
this._waitPromptHandoff = undefined;
|
|
1152
|
+
}
|
|
1153
|
+
return { completion: Promise.resolve() };
|
|
1068
1154
|
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1155
|
+
let resolveCompletion = () => { };
|
|
1156
|
+
let rejectCompletion = (_error) => { };
|
|
1157
|
+
const completion = new Promise((resolve, reject) => {
|
|
1158
|
+
resolveCompletion = resolve;
|
|
1159
|
+
rejectCompletion = reject;
|
|
1160
|
+
});
|
|
1161
|
+
handoff.reservations.push({ input: prepared, resolve: resolveCompletion, reject: rejectCompletion });
|
|
1162
|
+
if (!run.gracefulStopRequested && this.agent.requestGracefulStop(handoff.ownerSignal)) {
|
|
1163
|
+
run.gracefulStopRequested = true;
|
|
1164
|
+
}
|
|
1165
|
+
this._interruptSubagentWaits(run, handoff.ownerSignal);
|
|
1166
|
+
if (!handoff.draining) {
|
|
1167
|
+
handoff.draining = true;
|
|
1168
|
+
void this._drainWaitPromptHandoff(handoff);
|
|
1169
|
+
}
|
|
1170
|
+
return { completion };
|
|
1171
|
+
}
|
|
1172
|
+
async _drainWaitPromptHandoff(handoff) {
|
|
1173
|
+
await this.waitForIdle();
|
|
1174
|
+
while (this._waitPromptHandoff === handoff &&
|
|
1175
|
+
handoff.generation === this._waitPromptGeneration &&
|
|
1176
|
+
handoff.reservations.length > 0) {
|
|
1177
|
+
const reservation = handoff.reservations[0];
|
|
1178
|
+
try {
|
|
1179
|
+
this.assertCanStartWork();
|
|
1180
|
+
const messages = await this._createPromptMessages(reservation.input);
|
|
1181
|
+
handoff.accepting = false;
|
|
1182
|
+
await this._runAgentPrompt(messages);
|
|
1183
|
+
reservation.resolve();
|
|
1184
|
+
}
|
|
1185
|
+
catch (error) {
|
|
1186
|
+
reservation.reject(error);
|
|
1187
|
+
}
|
|
1188
|
+
finally {
|
|
1189
|
+
if (handoff.reservations[0] === reservation)
|
|
1190
|
+
handoff.reservations.shift();
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
handoff.accepting = false;
|
|
1194
|
+
if (this._waitPromptHandoff === handoff)
|
|
1195
|
+
this._waitPromptHandoff = undefined;
|
|
1071
1196
|
}
|
|
1072
1197
|
/**
|
|
1073
1198
|
* Try to execute an extension command. Returns true if command was found and executed.
|
|
@@ -1320,6 +1445,7 @@ export class AgentSession {
|
|
|
1320
1445
|
* Abort current operation and wait for agent to become idle.
|
|
1321
1446
|
*/
|
|
1322
1447
|
async abort() {
|
|
1448
|
+
this._invalidateWaitPromptHandoffs("The active run was aborted before the pending prompt could run.");
|
|
1323
1449
|
this.abortRetry();
|
|
1324
1450
|
this.agent.abort();
|
|
1325
1451
|
await this.waitForIdle();
|
|
@@ -2339,6 +2465,7 @@ export class AgentSession {
|
|
|
2339
2465
|
});
|
|
2340
2466
|
}
|
|
2341
2467
|
async reload(options) {
|
|
2468
|
+
this._invalidateWaitPromptHandoffs("Extensions reloaded before the pending prompt could run.");
|
|
2342
2469
|
const previousFlagValues = this._extensionRunner.getFlagValues();
|
|
2343
2470
|
await emitSessionShutdownEvent(this._extensionRunner, { type: "session_shutdown", reason: "reload" });
|
|
2344
2471
|
await this.settingsManager.reload();
|