@caupulican/pi-adaptative 0.91.2 → 0.91.4

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/bundled-resources/skills/worker-profile-writer/SKILL.md +19 -9
  3. package/dist/core/agent-session.d.ts +1 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +20 -33
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/goals/goal-session-controller.d.ts +18 -1
  8. package/dist/core/goals/goal-session-controller.d.ts.map +1 -1
  9. package/dist/core/goals/goal-session-controller.js +46 -5
  10. package/dist/core/goals/goal-session-controller.js.map +1 -1
  11. package/dist/core/goals/natural-language-goal.d.ts +6 -5
  12. package/dist/core/goals/natural-language-goal.d.ts.map +1 -1
  13. package/dist/core/goals/natural-language-goal.js +109 -2
  14. package/dist/core/goals/natural-language-goal.js.map +1 -1
  15. package/dist/core/tools/bash.d.ts.map +1 -1
  16. package/dist/core/tools/bash.js +88 -1
  17. package/dist/core/tools/bash.js.map +1 -1
  18. package/dist/core/tools/delegate.d.ts.map +1 -1
  19. package/dist/core/tools/delegate.js +12 -2
  20. package/dist/core/tools/delegate.js.map +1 -1
  21. package/dist/core/tools/profile-writer.d.ts +1 -0
  22. package/dist/core/tools/profile-writer.d.ts.map +1 -1
  23. package/dist/core/tools/profile-writer.js +5 -1
  24. package/dist/core/tools/profile-writer.js.map +1 -1
  25. package/dist/core/tools/read.d.ts.map +1 -1
  26. package/dist/core/tools/read.js +13 -1
  27. package/dist/core/tools/read.js.map +1 -1
  28. package/dist/core/tools/session-transcript-read.d.ts +4 -0
  29. package/dist/core/tools/session-transcript-read.d.ts.map +1 -0
  30. package/dist/core/tools/session-transcript-read.js +98 -0
  31. package/dist/core/tools/session-transcript-read.js.map +1 -0
  32. package/docs/sessions.md +12 -4
  33. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  34. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  35. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  36. package/examples/extensions/sandbox/package-lock.json +2 -2
  37. package/examples/extensions/sandbox/package.json +1 -1
  38. package/examples/extensions/with-deps/package-lock.json +2 -2
  39. package/examples/extensions/with-deps/package.json +1 -1
  40. package/npm-shrinkwrap.json +12 -12
  41. package/package.json +5 -5
@@ -1,4 +1,5 @@
1
1
  import type { SessionManager } from "@caupulican/pi-agent-core/session";
2
+ import type { AgentMessage } from "@caupulican/pi-agent-core/types";
2
3
  import type { AssistantMessage } from "@caupulican/pi-ai";
3
4
  import type { GoalContinuationLoopOptions, GoalContinuationLoopResult, GoalContinuationOnceOptions, GoalContinuationOnceResult, PromptOptions } from "../agent-session-contracts.ts";
4
5
  import type { LaneRecord } from "../autonomy/lane-tracker.ts";
@@ -43,6 +44,8 @@ export declare class GoalSessionController {
43
44
  private readonly loop;
44
45
  private executionLease;
45
46
  private startAuthority;
47
+ private readonly queuedOwnerChatGoals;
48
+ private queuedOwnerChatExecutionLease;
46
49
  constructor(deps: GoalSessionControllerDeps);
47
50
  saveState(state: GoalState, expected?: GoalStateRevision): string;
48
51
  clearState(state: GoalState, now: string): string;
@@ -52,7 +55,21 @@ export declare class GoalSessionController {
52
55
  * goal tool. This is intentionally narrower than task detection: ordinary work never starts a
53
56
  * goal, and an unfinished goal is never replaced implicitly.
54
57
  */
55
- admitExplicitChatGoal(text: string, now?: string): ChatGoalAdmission;
58
+ admitOwnerChatGoal(text: string, messages: readonly {
59
+ role: string;
60
+ content?: unknown;
61
+ }[]): ChatGoalAdmission;
62
+ startOwnerChatGoal(text: string, messages: readonly {
63
+ role: string;
64
+ content?: unknown;
65
+ }[]): string | undefined;
66
+ queueOwnerChatGoal(message: AgentMessage, text: string, authority: ExplicitGoalStartAuthority): void;
67
+ activateQueuedOwnerChatGoal(message: AgentMessage, messages: readonly {
68
+ role: string;
69
+ content?: unknown;
70
+ }[]): void;
71
+ endQueuedOwnerChatGoalExecution(): void;
72
+ admitExplicitChatGoal(text: string, now?: string, priorUserText?: string): ChatGoalAdmission;
56
73
  /** Attribute turn/wall-clock telemetry after usage has already been charged per response. */
57
74
  recordContinuationPass(pass: {
58
75
  turns: number;
@@ -1 +1 @@
1
- {"version":3,"file":"goal-session-controller.d.ts","sourceRoot":"","sources":["../../../src/core/goals/goal-session-controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"goal-session-controller.d.ts","sourceRoot":"","sources":["../../../src/core/goals/goal-session-controller.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EACX,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,aAAa,EACb,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAGnF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAE9E,OAAO,EAAE,KAAK,iBAAiB,EAA4C,MAAM,qBAAqB,CAAC;AACvG,OAAO,EAEN,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAChC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAkB,KAAK,SAAS,EAAiD,MAAM,iBAAiB,CAAC;AAEhH,OAAO,EACN,KAAK,0BAA0B,EAG/B,MAAM,4BAA4B,CAAC;AAOpC,MAAM,WAAW,yBAAyB;IACzC,iBAAiB,IAAI,cAAc,CAAC;IACpC,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAAC;IACvC,cAAc,IAAI,SAAS,UAAU,EAAE,CAAC;IACxC,sBAAsB,IAAI,qBAAqB,GAAG,SAAS,CAAC;IAC5D,sBAAsB,IAAI,SAAS,qBAAqB,EAAE,CAAC;IAC3D,oBAAoB,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IAC7C,gCAAgC,IAAI,IAAI,CAAC;IACzC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,MAAM,iBAAiB,GAC1B;IAAE,MAAM,EAAE,cAAc,CAAA;CAAE,GAC1B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,wBAAwB,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAe1D,QAAA,MAAM,wBAAwB,EAAE,OAAO,MAAqC,CAAC;AAE7E,0EAA0E;AAC1E,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,CAAC,wBAAwB,CAAC,EAAE,IAAI,CAAC;CAC1C;AAqBD;;;GAGG;AACH,qBAAa,qBAAqB;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAoD;IACzF,OAAO,CAAC,6BAA6B,CAAiC;IAEtE,YAAY,IAAI,EAAE,yBAAyB,EAS1C;IAED,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAmBhE;IAED,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAUhD;IAED,QAAQ,IAAI,SAAS,GAAG,SAAS,CAEhC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,GAAG,iBAAiB,CAE5G;IAED,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,GAAG,MAAM,GAAG,SAAS,CAS7G;IAED,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,0BAA0B,GAAG,IAAI,CAEnG;IAED,2BAA2B,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,GAAG,IAAI,CAajH;IAED,+BAA+B,IAAI,IAAI,CAMtC;IAED,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAyB3F;IAED,6FAA6F;IAC7F,sBAAsB,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAYzE;IAED,gGAAgG;IAChG,cAAc,CACb,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,GAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,sBAAsB,CAAC,EAAE,MAAM,CAAA;KAAO,GACvE,kBAAkB,GAAG,SAAS,CAmBhC;IAED,YAAY,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,GAAG,IAAI,CAKxD;IAED,iHAAiH;IACjH,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAmBpD;IAED,OAAO,CAAC,oBAAoB;IA4B5B,0BAA0B,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAaxD;IAED,iBAAiB,CAAC,SAAS,EAAE,0BAA0B,GAAG,SAAS,GAAG,IAAI,CAEzE;IAED,sBAAsB,CAAC,KAAK,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,GAAG,SAAS,CAU1E;IAED;;;;;;;;;OASG;IACH,mCAAmC,IAAI,OAAO,CAI7C;IAED,4FAA4F;IAC5F,oBAAoB,IAAI,MAAM,GAAG,SAAS,CA2CzC;IAED,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,0BAA0B;IAsBlC,mBAAmB,IAAI,IAAI,CAK1B;IAED,kBAAkB,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAKxE;IAED,8BAA8B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKxD;IAED,kBAAkB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,mBAAmB,CAQ7E;IAED,YAAY,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAEtF;IAED,YAAY,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAEtF;IAED,kBAAkB,IAAI,IAAI,CAEzB;IAED,OAAO,CAAC,yBAAyB;IASjC,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,cAAc;CAOtB"}
@@ -7,7 +7,7 @@ import { getGoalStateRevision, stopGoalFromSystem } from "./goal-lifecycle.js";
7
7
  import { buildGoalRuntimeSnapshot, } from "./goal-runtime-snapshot.js";
8
8
  import { applyGoalEvent, isGoalExecutionActive, isGoalUnfinishedStatus } from "./goal-state.js";
9
9
  import { applyGoalAction } from "./goal-tool-core.js";
10
- import { parseExplicitChatGoal } from "./natural-language-goal.js";
10
+ import { parseExplicitChatGoal, priorUserPromptText, } from "./natural-language-goal.js";
11
11
  import { appendGoalClearedSnapshot, appendGoalStateSnapshot, getLatestGoalStateSnapshot, } from "./session-goal-state.js";
12
12
  /**
13
13
  * Smallest remaining goal budget worth handing to the provider as one more request's OUTPUT cap.
@@ -28,6 +28,7 @@ const goalExecutionLeaseMarker = Symbol("goalExecutionLease");
28
28
  */
29
29
  export class GoalSessionController {
30
30
  constructor(deps) {
31
+ this.queuedOwnerChatGoals = new WeakMap();
31
32
  this.deps = deps;
32
33
  this.loop = new GoalLoopController({
33
34
  getGoalRuntimeSnapshot: (settings) => this.getRuntimeSnapshot(settings),
@@ -71,8 +72,48 @@ export class GoalSessionController {
71
72
  * goal tool. This is intentionally narrower than task detection: ordinary work never starts a
72
73
  * goal, and an unfinished goal is never replaced implicitly.
73
74
  */
74
- admitExplicitChatGoal(text, now = new Date().toISOString()) {
75
- const parsed = parseExplicitChatGoal(text);
75
+ admitOwnerChatGoal(text, messages) {
76
+ return this.admitExplicitChatGoal(text, undefined, priorUserPromptText(messages, text));
77
+ }
78
+ startOwnerChatGoal(text, messages) {
79
+ const admission = this.admitOwnerChatGoal(text, messages);
80
+ if (admission.status === "started")
81
+ return admission.state.goalId;
82
+ if (admission.status === "unfinished_goal_exists") {
83
+ this.deps.emitWarning(`Explicit chat goal was not started because unfinished goal '${admission.state.goalId}' is ${admission.state.status}. Complete, clear, or explicitly replace it first.`);
84
+ }
85
+ return undefined;
86
+ }
87
+ queueOwnerChatGoal(message, text, authority) {
88
+ this.queuedOwnerChatGoals.set(message, { text, authority });
89
+ }
90
+ activateQueuedOwnerChatGoal(message, messages) {
91
+ const queued = this.queuedOwnerChatGoals.get(message);
92
+ if (!queued)
93
+ return;
94
+ this.queuedOwnerChatGoals.delete(message);
95
+ const goalId = this.startOwnerChatGoal(queued.text, messages);
96
+ if (!goalId)
97
+ return;
98
+ this.setStartAuthority(queued.authority);
99
+ const lease = this.beginExecution(goalId);
100
+ if (!lease) {
101
+ this.setStartAuthority(undefined);
102
+ return;
103
+ }
104
+ this.queuedOwnerChatExecutionLease = lease;
105
+ }
106
+ endQueuedOwnerChatGoalExecution() {
107
+ const lease = this.queuedOwnerChatExecutionLease;
108
+ if (!lease)
109
+ return;
110
+ this.queuedOwnerChatExecutionLease = undefined;
111
+ this.setStartAuthority(undefined);
112
+ this.endExecution(lease);
113
+ }
114
+ admitExplicitChatGoal(text, now, priorUserText) {
115
+ const admittedAt = now ?? new Date().toISOString();
116
+ const parsed = parseExplicitChatGoal(text, priorUserText);
76
117
  if (!parsed)
77
118
  return { status: "not_explicit" };
78
119
  const current = this.getState();
@@ -80,7 +121,7 @@ export class GoalSessionController {
80
121
  return { status: "unfinished_goal_exists", state: current };
81
122
  }
82
123
  const digest = createHash("sha256")
83
- .update(`${now}\0${current?.goalId ?? "none"}\0${parsed.objective}`)
124
+ .update(`${admittedAt}\0${current?.goalId ?? "none"}\0${parsed.objective}`)
84
125
  .digest("hex")
85
126
  .slice(0, 20);
86
127
  const result = applyGoalAction(current, {
@@ -88,7 +129,7 @@ export class GoalSessionController {
88
129
  goalId: `chat-${digest}`,
89
130
  userGoal: parsed.objective,
90
131
  tokenBudget: parsed.tokenBudget,
91
- }, now);
132
+ }, admittedAt);
92
133
  if (!result.ok)
93
134
  throw new Error(result.error);
94
135
  this.saveState(result.state, current ? getGoalStateRevision(current) : undefined);
@@ -1 +1 @@
1
- {"version":3,"file":"goal-session-controller.js","sourceRoot":"","sources":["../../../src/core/goals/goal-session-controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { classifyFailure } from \"@caupulican/pi-agent-core/reliability\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/session\";\nimport type { AssistantMessage } from \"@caupulican/pi-ai\";\nimport type {\n\tGoalContinuationLoopOptions,\n\tGoalContinuationLoopResult,\n\tGoalContinuationOnceOptions,\n\tGoalContinuationOnceResult,\n\tPromptOptions,\n} from \"../agent-session-contracts.ts\";\nimport type { LaneRecord } from \"../autonomy/lane-tracker.ts\";\nimport type { BackgroundToolTaskRef } from \"../background-tool-task-controller.ts\";\nimport { GoalLoopController } from \"../goal-loop-controller.ts\";\nimport { budgetedTokens } from \"../orchestration/capability-gateway.ts\";\nimport type { TaskRuntimeProjection } from \"../orchestration/task-runtime.ts\";\nimport { GoalBudgetExhaustedError } from \"./goal-execution-errors.ts\";\nimport { type GoalStateRevision, getGoalStateRevision, stopGoalFromSystem } from \"./goal-lifecycle.ts\";\nimport {\n\tbuildGoalRuntimeSnapshot,\n\ttype GoalRuntimeSnapshot,\n\ttype GoalRuntimeSnapshotSettings,\n} from \"./goal-runtime-snapshot.ts\";\nimport { applyGoalEvent, type GoalState, isGoalExecutionActive, isGoalUnfinishedStatus } from \"./goal-state.ts\";\nimport { applyGoalAction } from \"./goal-tool-core.ts\";\nimport { type ExplicitGoalStartAuthority, parseExplicitChatGoal } from \"./natural-language-goal.ts\";\nimport {\n\tappendGoalClearedSnapshot,\n\tappendGoalStateSnapshot,\n\tgetLatestGoalStateSnapshot,\n} from \"./session-goal-state.ts\";\n\nexport interface GoalSessionControllerDeps {\n\tgetSessionManager(): SessionManager;\n\tgetModelProvider(): string | undefined;\n\tgetLaneRecords(): readonly LaneRecord[];\n\tgetTaskRuntimeSnapshot(): TaskRuntimeProjection | undefined;\n\tgetBackgroundToolTasks(): readonly BackgroundToolTaskRef[];\n\tsynchronizeGoalState(state: GoalState): void;\n\tscheduleGoalAutoContinueFromIdle(): void;\n\tprompt(text: string, options?: PromptOptions): Promise<void>;\n\temitWarning(message: string): void;\n}\n\nexport type ChatGoalAdmission =\n\t| { status: \"not_explicit\" }\n\t| { status: \"started\"; state: GoalState }\n\t| { status: \"unfinished_goal_exists\"; state: GoalState };\n\n/**\n * Smallest remaining goal budget worth handing to the provider as one more request's OUTPUT cap.\n * `admitProviderRequest` returns the goal's remaining TOTAL budget (input+output, cache-weighted) as\n * that cap — correct only because it also narrows further downstream against the model's real output\n * limit. When remaining drops below this floor (e.g. 200k budget, 199.4k used → 600 remaining), handing\n * 600 to the provider as maxTokens produces a request that pays the FULL input cost of the turn only to\n * get cut off mid-generation (`stopReason: \"length\"`) — a doomed, wasted turn. Below the floor, stop\n * the goal cleanly BEFORE sending instead of gambling on a truncated one. Above it, the remaining-total\n * value is a generous (imprecise but safe) protective ceiling — a modest final-turn overrun is\n * acceptable; a truncated turn is not.\n */\nconst MIN_VIABLE_GOAL_TURN_OUTPUT_TOKENS = 1_000;\n\nconst goalExecutionLeaseMarker: unique symbol = Symbol(\"goalExecutionLease\");\n\n/** Identity-bound attribution for one goal-owned foreground execution. */\nexport interface GoalExecutionLease {\n\treadonly goalId?: string;\n\treadonly [goalExecutionLeaseMarker]: true;\n}\n\ninterface MutableGoalExecutionLease extends GoalExecutionLease {\n\tgoalId?: string;\n\tadoptNewGoal: boolean;\n\tadoptionBaselineGoalId?: string;\n\tprovisionalTokenBudget?: number;\n\tpendingTokens: number;\n\tpendingSpendUsd: number;\n\t/** Set once this lease has admitted a provider request while its goal was still active. Lets a\n\t * later admission on the SAME still-held lease recognize \"the goal ended mid-turn\" (drain the\n\t * in-flight turn's wrap-up response) instead of \"a new turn is starting against a dead goal\"\n\t * (which stays denied). */\n\tadmittedWhileActive: boolean;\n}\n\n/**\n * Owns durable goal state, exact continuation accounting, and the raw continuation loop. The\n * AgentSession facade supplies process collaborators but no longer implements goal lifecycle rules.\n */\nexport class GoalSessionController {\n\tprivate readonly deps: GoalSessionControllerDeps;\n\tprivate readonly loop: GoalLoopController;\n\tprivate executionLease: MutableGoalExecutionLease | undefined;\n\tprivate startAuthority: ExplicitGoalStartAuthority | undefined;\n\n\tconstructor(deps: GoalSessionControllerDeps) {\n\t\tthis.deps = deps;\n\t\tthis.loop = new GoalLoopController({\n\t\t\tgetGoalRuntimeSnapshot: (settings) => this.getRuntimeSnapshot(settings),\n\t\t\tprompt: (text, options) => this.deps.prompt(text, options),\n\t\t\trecordGoalContinuationPass: (pass) => this.recordContinuationPass(pass),\n\t\t\trecordGoalContinuationFailure: (error) => this.recordContinuationFailure(error),\n\t\t\tmarkGoalBudgetLimited: (reason) => this.markBudgetLimited(reason),\n\t\t});\n\t}\n\n\tsaveState(state: GoalState, expected?: GoalStateRevision): string {\n\t\tconst current = this.getState();\n\t\tif (\n\t\t\texpected &&\n\t\t\t(!current || current.goalId !== expected.goalId || (current.revision ?? 0) !== expected.revision)\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Goal state changed concurrently; expected ${expected.goalId}@${expected.revision}, found ${current ? `${current.goalId}@${current.revision ?? 0}` : \"none\"}. Retry against the latest state.`,\n\t\t\t);\n\t\t}\n\t\tconst entryId = appendGoalStateSnapshot(this.deps.getSessionManager(), state, current);\n\t\ttry {\n\t\t\tthis.deps.synchronizeGoalState(state);\n\t\t} catch (error) {\n\t\t\tthis.deps.emitWarning(\n\t\t\t\t`Goal state persisted but durable worker reconciliation failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t\treturn entryId;\n\t}\n\n\tclearState(state: GoalState, now: string): string {\n\t\tconst current = this.getState();\n\t\tconst expected = getGoalStateRevision(state);\n\t\tif (!current || current.goalId !== expected.goalId || (current.revision ?? 0) !== expected.revision) {\n\t\t\tthrow new Error(\"Goal state changed concurrently; retry clear against the latest state.\");\n\t\t}\n\t\tif (state.status !== \"completed\" && state.status !== \"cancelled\") {\n\t\t\tthis.deps.synchronizeGoalState(applyGoalEvent(state, { type: \"cancel_goal\", now }));\n\t\t}\n\t\treturn appendGoalClearedSnapshot(this.deps.getSessionManager(), state, now);\n\t}\n\n\tgetState(): GoalState | undefined {\n\t\treturn getLatestGoalStateSnapshot(this.deps.getSessionManager());\n\t}\n\n\t/**\n\t * Promote high-confidence natural-language persistence into the same durable state written by the\n\t * goal tool. This is intentionally narrower than task detection: ordinary work never starts a\n\t * goal, and an unfinished goal is never replaced implicitly.\n\t */\n\tadmitExplicitChatGoal(text: string, now = new Date().toISOString()): ChatGoalAdmission {\n\t\tconst parsed = parseExplicitChatGoal(text);\n\t\tif (!parsed) return { status: \"not_explicit\" };\n\t\tconst current = this.getState();\n\t\tif (current && isGoalUnfinishedStatus(current.status)) {\n\t\t\treturn { status: \"unfinished_goal_exists\", state: current };\n\t\t}\n\t\tconst digest = createHash(\"sha256\")\n\t\t\t.update(`${now}\\0${current?.goalId ?? \"none\"}\\0${parsed.objective}`)\n\t\t\t.digest(\"hex\")\n\t\t\t.slice(0, 20);\n\t\tconst result = applyGoalAction(\n\t\t\tcurrent,\n\t\t\t{\n\t\t\t\taction: \"start\",\n\t\t\t\tgoalId: `chat-${digest}`,\n\t\t\t\tuserGoal: parsed.objective,\n\t\t\t\ttokenBudget: parsed.tokenBudget,\n\t\t\t},\n\t\t\tnow,\n\t\t);\n\t\tif (!result.ok) throw new Error(result.error);\n\t\tthis.saveState(result.state, current ? getGoalStateRevision(current) : undefined);\n\t\treturn { status: \"started\", state: result.state };\n\t}\n\n\t/** Attribute turn/wall-clock telemetry after usage has already been charged per response. */\n\trecordContinuationPass(pass: { turns: number; wallClockMs: number }): void {\n\t\tconst state = this.getState();\n\t\tif (!state) return;\n\t\tconst updated = applyGoalEvent(state, {\n\t\t\ttype: \"record_continuation_budget\",\n\t\t\tturns: pass.turns,\n\t\t\twallClockMs: pass.wallClockMs,\n\t\t\ttokens: 0,\n\t\t\tspendUsd: 0,\n\t\t\tnow: new Date().toISOString(),\n\t\t});\n\t\tthis.saveState(updated, getGoalStateRevision(state));\n\t}\n\n\t/** Begin one foreground execution whose provider usage belongs to the specified active goal. */\n\tbeginExecution(\n\t\tgoalId: string | undefined,\n\t\toptions: { adoptNewGoal?: boolean; provisionalTokenBudget?: number } = {},\n\t): GoalExecutionLease | undefined {\n\t\tif (!goalId && !options.adoptNewGoal) return undefined;\n\t\tif (this.executionLease) throw new Error(\"Goal execution attribution is already active\");\n\t\tconst state = this.getState();\n\t\tif (goalId && (!state || state.goalId !== goalId || !isGoalExecutionActive(state.status))) return undefined;\n\t\tconst lease: MutableGoalExecutionLease = {\n\t\t\t...(goalId ? { goalId } : {}),\n\t\t\t[goalExecutionLeaseMarker]: true,\n\t\t\tadoptNewGoal: options.adoptNewGoal === true,\n\t\t\t...(options.adoptNewGoal && state ? { adoptionBaselineGoalId: state.goalId } : {}),\n\t\t\t...(options.provisionalTokenBudget !== undefined\n\t\t\t\t? { provisionalTokenBudget: options.provisionalTokenBudget }\n\t\t\t\t: {}),\n\t\t\tpendingTokens: 0,\n\t\t\tpendingSpendUsd: 0,\n\t\t\tadmittedWhileActive: false,\n\t\t};\n\t\tthis.executionLease = lease;\n\t\treturn lease;\n\t}\n\n\tendExecution(lease: GoalExecutionLease | undefined): void {\n\t\tif (!lease) return;\n\t\tif (this.executionLease !== lease) throw new Error(\"Cannot end goal execution attribution owned by another run\");\n\t\tthis.flushPendingExecutionUsage(this.executionLease);\n\t\tthis.executionLease = undefined;\n\t}\n\n\t/** Charge one observed assistant response exactly once, including routed responses buffered from persistence. */\n\trecordExecutionUsage(message: AssistantMessage): void {\n\t\tconst lease = this.executionLease;\n\t\tif (!lease) return;\n\t\tconst tokens = budgetedTokens({\n\t\t\tinputTokens: Math.max(0, message.usage.input),\n\t\t\toutputTokens: Math.max(0, message.usage.output),\n\t\t\tcacheReadTokens: Math.max(0, message.usage.cacheRead),\n\t\t\tcacheWriteTokens: Math.max(0, message.usage.cacheWrite),\n\t\t\ttotalTokens: Math.max(0, message.usage.totalTokens),\n\t\t});\n\t\tconst spendUsd = Math.max(0, message.usage.cost.total);\n\t\tif (tokens === 0 && spendUsd === 0) return;\n\t\tconst state = this.resolveExecutionState(lease);\n\t\tif (!state) {\n\t\t\tlease.pendingTokens += tokens;\n\t\t\tlease.pendingSpendUsd += spendUsd;\n\t\t\treturn;\n\t\t}\n\t\tthis.chargeExecutionUsage(lease, state, tokens, spendUsd);\n\t}\n\n\tprivate chargeExecutionUsage(\n\t\tlease: MutableGoalExecutionLease,\n\t\tstate: GoalState,\n\t\ttokens: number,\n\t\tspendUsd: number,\n\t): void {\n\t\tconst updated = applyGoalEvent(state, {\n\t\t\ttype: \"record_continuation_budget\",\n\t\t\tturns: 0,\n\t\t\twallClockMs: 0,\n\t\t\ttokens,\n\t\t\tspendUsd,\n\t\t\tnow: new Date().toISOString(),\n\t\t});\n\t\tthis.saveState(updated, getGoalStateRevision(state));\n\t\tlease.pendingTokens = 0;\n\t\tlease.pendingSpendUsd = 0;\n\t\tif (\n\t\t\tisGoalExecutionActive(updated.status) &&\n\t\t\tupdated.tokenBudget !== undefined &&\n\t\t\t(updated.tokensUsed ?? 0) >= updated.tokenBudget\n\t\t) {\n\t\t\tthis.markBudgetLimited(\n\t\t\t\t`token budget exhausted (${updated.tokensUsed ?? 0}/${updated.tokenBudget}) during goal execution`,\n\t\t\t);\n\t\t}\n\t}\n\n\tmarkProtocolFailureBlocked(errorMessage: string): boolean {\n\t\tconst lease = this.executionLease;\n\t\tif (!lease) return false;\n\t\tconst state = this.resolveExecutionState(lease);\n\t\tif (!state || !isGoalExecutionActive(state.status)) return false;\n\t\tconst stopped = stopGoalFromSystem(\n\t\t\tstate,\n\t\t\t{ status: \"blocked\", reason: errorMessage.slice(0, 500) },\n\t\t\tnew Date().toISOString(),\n\t\t);\n\t\tif (!stopped.ok) return false;\n\t\tthis.saveState(stopped.state, getGoalStateRevision(state));\n\t\treturn true;\n\t}\n\n\tsetStartAuthority(authority: ExplicitGoalStartAuthority | undefined): void {\n\t\tthis.startAuthority = authority;\n\t}\n\n\tauthorizeStartFromTool(input: { tokenBudget?: number }): string | undefined {\n\t\tconst authority = this.startAuthority;\n\t\tif (!authority) return \"goal start requires explicit owner authorization in the current prompt.\";\n\t\tif (authority.tokenBudget === undefined && input.tokenBudget !== undefined) {\n\t\t\treturn \"tokenBudget requires an exact numeric token ceiling in the current owner prompt.\";\n\t\t}\n\t\tif (authority.tokenBudget !== undefined && input.tokenBudget !== authority.tokenBudget) {\n\t\t\treturn `tokenBudget must equal the owner-requested ceiling ${authority.tokenBudget}.`;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * True once the currently held execution lease's goal has crossed into `budget_limited` — set\n\t * synchronously by `chargeExecutionUsage` as soon as a just-charged response crosses the ceiling.\n\t * Wired to the agent's `shouldStopAfterTurn` hook so a mid-turn budget stop ends the loop\n\t * gracefully BEFORE the next provider request is even planned, instead of only being caught by\n\t * `admitProviderRequest`'s throw — which still exists as the backstop for a fresh turn or an\n\t * external admission starting against an already budget_limited goal, but would otherwise also\n\t * fire for a request this same lease was already mid-flight for, surfacing a synthetic error\n\t * message where a clean turn end belongs.\n\t */\n\thasExecutionLeaseCrossedBudgetLimit(): boolean {\n\t\tconst lease = this.executionLease;\n\t\tif (!lease) return false;\n\t\treturn this.resolveExecutionState(lease)?.status === \"budget_limited\";\n\t}\n\n\t/** Reserve only remaining output capacity; actual provider usage is charged on response. */\n\tadmitProviderRequest(): number | undefined {\n\t\tconst lease = this.executionLease;\n\t\tif (!lease) return undefined;\n\t\tthis.flushPendingExecutionUsage(lease);\n\t\tconst state = this.resolveExecutionState(lease);\n\t\tif (state?.status === \"budget_limited\") {\n\t\t\tthrow new GoalBudgetExhaustedError(`goal_token_budget_exhausted: ${state.blockedReason ?? lease.goalId}`);\n\t\t}\n\t\tif (state && !isGoalExecutionActive(state.status)) {\n\t\t\tif (!lease.admittedWhileActive) {\n\t\t\t\t// A fresh turn/continuation is being started against a goal that is already done —\n\t\t\t\t// keep this denied so a dead goal cannot restart itself.\n\t\t\t\tthrow new Error(`goal_execution_not_active: ${state.goalId} is ${state.status}`);\n\t\t\t}\n\t\t\t// This lease already admitted at least one request while the goal was active, so the\n\t\t\t// goal ended mid-turn (e.g. the model itself just called `goal complete`/`block`). Let\n\t\t\t// the already-in-flight turn drain to its closing response instead of throwing an error\n\t\t\t// at the user right after a successful stop.\n\t\t\treturn undefined;\n\t\t}\n\t\tif (!state && lease.goalId !== undefined) {\n\t\t\tthrow new Error(`goal_execution_not_active: ${lease.goalId} no longer exists`);\n\t\t}\n\t\tlease.admittedWhileActive = true;\n\t\tconst tokenBudget = state?.tokenBudget ?? lease.provisionalTokenBudget;\n\t\tif (tokenBudget === undefined) return undefined;\n\t\tconst tokensUsed = state?.tokensUsed ?? lease.pendingTokens;\n\t\tconst remaining = Math.max(0, tokenBudget - tokensUsed);\n\t\tif (remaining < MIN_VIABLE_GOAL_TURN_OUTPUT_TOKENS) {\n\t\t\t// Below the floor, remaining is too small to hand to the provider as an output cap without\n\t\t\t// dooming the turn to a mid-generation truncation that still burns the full input cost.\n\t\t\t// Stop cleanly now instead of sending a request that cannot possibly complete.\n\t\t\tif (state) {\n\t\t\t\tthis.markBudgetLimited(\n\t\t\t\t\t`token budget nearly exhausted (${tokensUsed}/${tokenBudget}, ${remaining} remaining is below the ` +\n\t\t\t\t\t\t`${MIN_VIABLE_GOAL_TURN_OUTPUT_TOKENS}-token minimum viable turn) before provider request`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new GoalBudgetExhaustedError(\n\t\t\t\t`goal_token_budget_exhausted: ${remaining} tokens remain, below the ${MIN_VIABLE_GOAL_TURN_OUTPUT_TOKENS}-token minimum viable turn`,\n\t\t\t);\n\t\t}\n\t\treturn remaining;\n\t}\n\n\tprivate resolveExecutionState(lease: MutableGoalExecutionLease): GoalState | undefined {\n\t\tconst state = this.getState();\n\t\tif (!state) return undefined;\n\t\tif (lease.goalId === state.goalId) return state;\n\t\tif (lease.goalId !== undefined || !lease.adoptNewGoal) return undefined;\n\t\tif (lease.adoptionBaselineGoalId === state.goalId) return undefined;\n\t\tlease.goalId = state.goalId;\n\t\treturn state;\n\t}\n\n\tprivate flushPendingExecutionUsage(lease: MutableGoalExecutionLease): void {\n\t\tif (lease.pendingTokens === 0 && lease.pendingSpendUsd === 0) return;\n\t\tconst state = this.resolveExecutionState(lease);\n\t\tif (!state) {\n\t\t\t// A speculative adopt-new-goal lease (lease.goalId still undefined) that never actually\n\t\t\t// adopted a goal this turn has nowhere to attribute usage — that is normal, not a loss.\n\t\t\t// A lease that WAS bound to a real goal but can no longer resolve it is a genuine loss of\n\t\t\t// buffered spend; fail loudly instead of silently discarding it (matches the cursor-based\n\t\t\t// accounting this replaced, which stopped the goal on `goal_usage_cursor_lost`).\n\t\t\tif (lease.goalId !== undefined) {\n\t\t\t\tthis.deps.emitWarning(\n\t\t\t\t\t`Goal usage cursor is no longer resolvable for '${lease.goalId}'; ${lease.pendingTokens} pending tokens and $${lease.pendingSpendUsd.toFixed(6)} pending spend could not be attributed and were dropped.`,\n\t\t\t\t);\n\t\t\t\tthis.recordContinuationFailure(new Error(\"goal_usage_cursor_lost\"));\n\t\t\t}\n\t\t\tlease.pendingTokens = 0;\n\t\t\tlease.pendingSpendUsd = 0;\n\t\t\treturn;\n\t\t}\n\t\tthis.chargeExecutionUsage(lease, state, lease.pendingTokens, lease.pendingSpendUsd);\n\t}\n\n\tmarkToolUnavailable(): void {\n\t\tthis.stopActiveGoal(\n\t\t\t\"blocked\",\n\t\t\t\"goal_tool_unavailable: the active capability surface cannot update durable goal state\",\n\t\t);\n\t}\n\n\tmarkRunawayBlocked(info: { signature: string; repeats: number }): boolean {\n\t\treturn this.stopActiveGoal(\n\t\t\t\"blocked\",\n\t\t\t`runaway_tool_loop: repeated tool-call signature ${info.signature} ${info.repeats} times without progress`,\n\t\t);\n\t}\n\n\tmarkTerminalToolFailureBlocked(toolName: string): boolean {\n\t\treturn this.stopActiveGoal(\n\t\t\t\"blocked\",\n\t\t\t`terminal_tool_failure: ${toolName} reported an unrecoverable error and terminated the run`,\n\t\t);\n\t}\n\n\tgetRuntimeSnapshot(settings: GoalRuntimeSnapshotSettings): GoalRuntimeSnapshot {\n\t\treturn buildGoalRuntimeSnapshot({\n\t\t\tsessionManager: this.deps.getSessionManager(),\n\t\t\tsettings,\n\t\t\tlaneRecords: this.deps.getLaneRecords(),\n\t\t\ttaskRuntime: this.deps.getTaskRuntimeSnapshot(),\n\t\t\tbackgroundToolTasks: this.deps.getBackgroundToolTasks(),\n\t\t});\n\t}\n\n\tcontinueOnce(options: GoalContinuationOnceOptions): Promise<GoalContinuationOnceResult> {\n\t\treturn this.loop.continueGoalOnce(options);\n\t}\n\n\tcontinueLoop(options: GoalContinuationLoopOptions): Promise<GoalContinuationLoopResult> {\n\t\treturn this.loop.continueGoalLoop(options);\n\t}\n\n\trestoreAfterResume(): void {\n\t\tthis.deps.scheduleGoalAutoContinueFromIdle();\n\t}\n\n\tprivate recordContinuationFailure(error: unknown): void {\n\t\tconst state = this.getState();\n\t\tif (!state || !isGoalExecutionActive(state.status)) return;\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst classified = classifyFailure({ message, provider: this.deps.getModelProvider() });\n\t\tconst status = classified.reason === \"billing_or_quota\" ? \"usage_limited\" : \"blocked\";\n\t\tthis.stopActiveGoal(status, `${classified.reason}: ${message}`);\n\t}\n\n\tprivate markBudgetLimited(reason: string): void {\n\t\tthis.stopActiveGoal(\"budget_limited\", reason);\n\t}\n\n\tprivate stopActiveGoal(status: \"blocked\" | \"usage_limited\" | \"budget_limited\", reason: string): boolean {\n\t\tconst state = this.getState();\n\t\tconst stopped = stopGoalFromSystem(state, { status, reason }, new Date().toISOString());\n\t\tif (!stopped.ok || !state) return false;\n\t\tthis.saveState(stopped.state, getGoalStateRevision(state));\n\t\treturn true;\n\t}\n}\n"]}
1
+ {"version":3,"file":"goal-session-controller.js","sourceRoot":"","sources":["../../../src/core/goals/goal-session-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAaxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAExE,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAA0B,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACvG,OAAO,EACN,wBAAwB,GAGxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAkB,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAChH,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAEN,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACN,yBAAyB,EACzB,uBAAuB,EACvB,0BAA0B,GAC1B,MAAM,yBAAyB,CAAC;AAmBjC;;;;;;;;;;GAUG;AACH,MAAM,kCAAkC,GAAG,KAAK,CAAC;AAEjD,MAAM,wBAAwB,GAAkB,MAAM,CAAC,oBAAoB,CAAC,CAAC;AA2B7E;;;GAGG;AACH,MAAM,OAAO,qBAAqB;IAQjC,YAAY,IAA+B;QAH1B,yBAAoB,GAAG,IAAI,OAAO,EAAqC,CAAC;QAIxF,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,kBAAkB,CAAC;YAClC,sBAAsB,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC;YACvE,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;YAC1D,0BAA0B,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC;YACvE,6BAA6B,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC;YAC/E,qBAAqB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;SACjE,CAAC,CAAC;IACJ,CAAC;IAED,SAAS,CAAC,KAAgB,EAAE,QAA4B;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChC,IACC,QAAQ;YACR,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,EAChG,CAAC;YACF,MAAM,IAAI,KAAK,CACd,6CAA6C,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,QAAQ,WAAW,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,mCAAmC,CAC9L,CAAC;QACH,CAAC;QACD,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACvF,IAAI,CAAC;YACJ,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,WAAW,CACpB,kEAAkE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC1H,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,UAAU,CAAC,KAAgB,EAAE,GAAW;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACrG,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAClE,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACrF,CAAC;QACD,OAAO,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IAC7E,CAAC;IAED,QAAQ;QACP,OAAO,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,IAAY,EAAE,QAAwD;QACxF,OAAO,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,mBAAmB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,kBAAkB,CAAC,IAAY,EAAE,QAAwD;QACxF,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC1D,IAAI,SAAS,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;QAClE,IAAI,SAAS,CAAC,MAAM,KAAK,wBAAwB,EAAE,CAAC;YACnD,IAAI,CAAC,IAAI,CAAC,WAAW,CACpB,+DAA+D,SAAS,CAAC,KAAK,CAAC,MAAM,QAAQ,SAAS,CAAC,KAAK,CAAC,MAAM,oDAAoD,CACvK,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,kBAAkB,CAAC,OAAqB,EAAE,IAAY,EAAE,SAAqC;QAC5F,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,2BAA2B,CAAC,OAAqB,EAAE,QAAwD;QAC1G,MAAM,MAAM,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC9D,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YAClC,OAAO;QACR,CAAC;QACD,IAAI,CAAC,6BAA6B,GAAG,KAAK,CAAC;IAC5C,CAAC;IAED,+BAA+B;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,6BAA6B,CAAC;QACjD,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,IAAI,CAAC,6BAA6B,GAAG,SAAS,CAAC;QAC/C,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAClC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,qBAAqB,CAAC,IAAY,EAAE,GAAY,EAAE,aAAsB;QACvE,MAAM,UAAU,GAAG,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChC,IAAI,OAAO,IAAI,sBAAsB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACvD,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC7D,CAAC;QACD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC;aACjC,MAAM,CAAC,GAAG,UAAU,KAAK,OAAO,EAAE,MAAM,IAAI,MAAM,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC;aAC1E,MAAM,CAAC,KAAK,CAAC;aACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACf,MAAM,MAAM,GAAG,eAAe,CAC7B,OAAO,EACP;YACC,MAAM,EAAE,OAAO;YACf,MAAM,EAAE,QAAQ,MAAM,EAAE;YACxB,QAAQ,EAAE,MAAM,CAAC,SAAS;YAC1B,WAAW,EAAE,MAAM,CAAC,WAAW;SAC/B,EACD,UAAU,CACV,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAClF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IACnD,CAAC;IAED,6FAA6F;IAC7F,sBAAsB,CAAC,IAA4C;QAClE,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,EAAE;YACrC,IAAI,EAAE,4BAA4B;YAClC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,CAAC;YACT,QAAQ,EAAE,CAAC;YACX,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC7B,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,gGAAgG;IAChG,cAAc,CACb,MAA0B,EAC1B,OAAO,GAAgE,EAAE;QAEzE,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QACvD,IAAI,IAAI,CAAC,cAAc;YAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACzF,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAAE,OAAO,SAAS,CAAC;QAC5G,MAAM,KAAK,GAA8B;YACxC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,CAAC,wBAAwB,CAAC,EAAE,IAAI;YAChC,YAAY,EAAE,OAAO,CAAC,YAAY,KAAK,IAAI;YAC3C,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClF,GAAG,CAAC,OAAO,CAAC,sBAAsB,KAAK,SAAS;gBAC/C,CAAC,CAAC,EAAE,sBAAsB,EAAE,OAAO,CAAC,sBAAsB,EAAE;gBAC5D,CAAC,CAAC,EAAE,CAAC;YACN,aAAa,EAAE,CAAC;YAChB,eAAe,EAAE,CAAC;YAClB,mBAAmB,EAAE,KAAK;SAC1B,CAAC;QACF,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,OAAO,KAAK,CAAC;IACd,CAAC;IAED,YAAY,CAAC,KAAqC;QACjD,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,IAAI,IAAI,CAAC,cAAc,KAAK,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QACjH,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACrD,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IACjC,CAAC;IAED,iHAAiH;IACjH,oBAAoB,CAAC,OAAyB;QAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,MAAM,GAAG,cAAc,CAAC;YAC7B,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;YAC7C,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;YAC/C,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC;YACrD,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC;YACvD,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC;SACnD,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvD,IAAI,MAAM,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC;YAAE,OAAO;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,KAAK,CAAC,aAAa,IAAI,MAAM,CAAC;YAC9B,KAAK,CAAC,eAAe,IAAI,QAAQ,CAAC;YAClC,OAAO;QACR,CAAC;QACD,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC;IAEO,oBAAoB,CAC3B,KAAgC,EAChC,KAAgB,EAChB,MAAc,EACd,QAAgB;QAEhB,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,EAAE;YACrC,IAAI,EAAE,4BAA4B;YAClC,KAAK,EAAE,CAAC;YACR,WAAW,EAAE,CAAC;YACd,MAAM;YACN,QAAQ;YACR,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC7B,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;QACrD,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC;QACxB,KAAK,CAAC,eAAe,GAAG,CAAC,CAAC;QAC1B,IACC,qBAAqB,CAAC,OAAO,CAAC,MAAM,CAAC;YACrC,OAAO,CAAC,WAAW,KAAK,SAAS;YACjC,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,WAAW,EAC/C,CAAC;YACF,IAAI,CAAC,iBAAiB,CACrB,2BAA2B,OAAO,CAAC,UAAU,IAAI,CAAC,IAAI,OAAO,CAAC,WAAW,yBAAyB,CAClG,CAAC;QACH,CAAC;IACF,CAAC;IAED,0BAA0B,CAAC,YAAoB;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QACjE,MAAM,OAAO,GAAG,kBAAkB,CACjC,KAAK,EACL,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EACzD,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CACxB,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAC9B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACb,CAAC;IAED,iBAAiB,CAAC,SAAiD;QAClE,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;IACjC,CAAC;IAED,sBAAsB,CAAC,KAA+B;QACrD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC;QACtC,IAAI,CAAC,SAAS;YAAE,OAAO,yEAAyE,CAAC;QACjG,IAAI,SAAS,CAAC,WAAW,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YAC5E,OAAO,kFAAkF,CAAC;QAC3F,CAAC;QACD,IAAI,SAAS,CAAC,WAAW,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,WAAW,EAAE,CAAC;YACxF,OAAO,sDAAsD,SAAS,CAAC,WAAW,GAAG,CAAC;QACvF,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAED;;;;;;;;;OASG;IACH,mCAAmC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACzB,OAAO,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,gBAAgB,CAAC;IACvE,CAAC;IAED,4FAA4F;IAC5F,oBAAoB;QACnB,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,KAAK,EAAE,MAAM,KAAK,gBAAgB,EAAE,CAAC;YACxC,MAAM,IAAI,wBAAwB,CAAC,gCAAgC,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3G,CAAC;QACD,IAAI,KAAK,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;gBAChC,mFAAmF;gBACnF,yDAAyD;gBACzD,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YAClF,CAAC;YACD,qFAAqF;YACrF,uFAAuF;YACvF,wFAAwF;YACxF,6CAA6C;YAC7C,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,CAAC,MAAM,mBAAmB,CAAC,CAAC;QAChF,CAAC;QACD,KAAK,CAAC,mBAAmB,GAAG,IAAI,CAAC;QACjC,MAAM,WAAW,GAAG,KAAK,EAAE,WAAW,IAAI,KAAK,CAAC,sBAAsB,CAAC;QACvE,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAChD,MAAM,UAAU,GAAG,KAAK,EAAE,UAAU,IAAI,KAAK,CAAC,aAAa,CAAC;QAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC,CAAC;QACxD,IAAI,SAAS,GAAG,kCAAkC,EAAE,CAAC;YACpD,2FAA2F;YAC3F,wFAAwF;YACxF,+EAA+E;YAC/E,IAAI,KAAK,EAAE,CAAC;gBACX,IAAI,CAAC,iBAAiB,CACrB,kCAAkC,UAAU,IAAI,WAAW,KAAK,SAAS,0BAA0B;oBAClG,GAAG,kCAAkC,qDAAqD,CAC3F,CAAC;YACH,CAAC;YACD,MAAM,IAAI,wBAAwB,CACjC,gCAAgC,SAAS,6BAA6B,kCAAkC,4BAA4B,CACpI,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAC;IAClB,CAAC;IAEO,qBAAqB,CAAC,KAAgC;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAChD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,YAAY;YAAE,OAAO,SAAS,CAAC;QACxE,IAAI,KAAK,CAAC,sBAAsB,KAAK,KAAK,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QACpE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,OAAO,KAAK,CAAC;IACd,CAAC;IAEO,0BAA0B,CAAC,KAAgC;QAClE,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC,IAAI,KAAK,CAAC,eAAe,KAAK,CAAC;YAAE,OAAO;QACrE,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,wFAAwF;YACxF,wFAAwF;YACxF,0FAA0F;YAC1F,0FAA0F;YAC1F,iFAAiF;YACjF,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAChC,IAAI,CAAC,IAAI,CAAC,WAAW,CACpB,kDAAkD,KAAK,CAAC,MAAM,MAAM,KAAK,CAAC,aAAa,wBAAwB,KAAK,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,0DAA0D,CACzM,CAAC;gBACF,IAAI,CAAC,yBAAyB,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACrE,CAAC;YACD,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC;YACxB,KAAK,CAAC,eAAe,GAAG,CAAC,CAAC;YAC1B,OAAO;QACR,CAAC;QACD,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,aAAa,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IACrF,CAAC;IAED,mBAAmB;QAClB,IAAI,CAAC,cAAc,CAClB,SAAS,EACT,uFAAuF,CACvF,CAAC;IACH,CAAC;IAED,kBAAkB,CAAC,IAA4C;QAC9D,OAAO,IAAI,CAAC,cAAc,CACzB,SAAS,EACT,mDAAmD,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,yBAAyB,CAC1G,CAAC;IACH,CAAC;IAED,8BAA8B,CAAC,QAAgB;QAC9C,OAAO,IAAI,CAAC,cAAc,CACzB,SAAS,EACT,0BAA0B,QAAQ,yDAAyD,CAC3F,CAAC;IACH,CAAC;IAED,kBAAkB,CAAC,QAAqC;QACvD,OAAO,wBAAwB,CAAC;YAC/B,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;YAC7C,QAAQ;YACR,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YACvC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE;YAC/C,mBAAmB,EAAE,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE;SACvD,CAAC,CAAC;IACJ,CAAC;IAED,YAAY,CAAC,OAAoC;QAChD,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,YAAY,CAAC,OAAoC;QAChD,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,kBAAkB;QACjB,IAAI,CAAC,IAAI,CAAC,gCAAgC,EAAE,CAAC;IAC9C,CAAC;IAEO,yBAAyB,CAAC,KAAc;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC;YAAE,OAAO;QAC3D,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,MAAM,UAAU,GAAG,eAAe,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QACxF,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,KAAK,kBAAkB,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;QACtF,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;IACjE,CAAC;IAEO,iBAAiB,CAAC,MAAc;QACvC,IAAI,CAAC,cAAc,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAEO,cAAc,CAAC,MAAsD,EAAE,MAAc;QAC5F,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QACxF,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACb,CAAC;CACD","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { classifyFailure } from \"@caupulican/pi-agent-core/reliability\";\nimport type { SessionManager } from \"@caupulican/pi-agent-core/session\";\nimport type { AgentMessage } from \"@caupulican/pi-agent-core/types\";\nimport type { AssistantMessage } from \"@caupulican/pi-ai\";\nimport type {\n\tGoalContinuationLoopOptions,\n\tGoalContinuationLoopResult,\n\tGoalContinuationOnceOptions,\n\tGoalContinuationOnceResult,\n\tPromptOptions,\n} from \"../agent-session-contracts.ts\";\nimport type { LaneRecord } from \"../autonomy/lane-tracker.ts\";\nimport type { BackgroundToolTaskRef } from \"../background-tool-task-controller.ts\";\nimport { GoalLoopController } from \"../goal-loop-controller.ts\";\nimport { budgetedTokens } from \"../orchestration/capability-gateway.ts\";\nimport type { TaskRuntimeProjection } from \"../orchestration/task-runtime.ts\";\nimport { GoalBudgetExhaustedError } from \"./goal-execution-errors.ts\";\nimport { type GoalStateRevision, getGoalStateRevision, stopGoalFromSystem } from \"./goal-lifecycle.ts\";\nimport {\n\tbuildGoalRuntimeSnapshot,\n\ttype GoalRuntimeSnapshot,\n\ttype GoalRuntimeSnapshotSettings,\n} from \"./goal-runtime-snapshot.ts\";\nimport { applyGoalEvent, type GoalState, isGoalExecutionActive, isGoalUnfinishedStatus } from \"./goal-state.ts\";\nimport { applyGoalAction } from \"./goal-tool-core.ts\";\nimport {\n\ttype ExplicitGoalStartAuthority,\n\tparseExplicitChatGoal,\n\tpriorUserPromptText,\n} from \"./natural-language-goal.ts\";\nimport {\n\tappendGoalClearedSnapshot,\n\tappendGoalStateSnapshot,\n\tgetLatestGoalStateSnapshot,\n} from \"./session-goal-state.ts\";\n\nexport interface GoalSessionControllerDeps {\n\tgetSessionManager(): SessionManager;\n\tgetModelProvider(): string | undefined;\n\tgetLaneRecords(): readonly LaneRecord[];\n\tgetTaskRuntimeSnapshot(): TaskRuntimeProjection | undefined;\n\tgetBackgroundToolTasks(): readonly BackgroundToolTaskRef[];\n\tsynchronizeGoalState(state: GoalState): void;\n\tscheduleGoalAutoContinueFromIdle(): void;\n\tprompt(text: string, options?: PromptOptions): Promise<void>;\n\temitWarning(message: string): void;\n}\n\nexport type ChatGoalAdmission =\n\t| { status: \"not_explicit\" }\n\t| { status: \"started\"; state: GoalState }\n\t| { status: \"unfinished_goal_exists\"; state: GoalState };\n\n/**\n * Smallest remaining goal budget worth handing to the provider as one more request's OUTPUT cap.\n * `admitProviderRequest` returns the goal's remaining TOTAL budget (input+output, cache-weighted) as\n * that cap — correct only because it also narrows further downstream against the model's real output\n * limit. When remaining drops below this floor (e.g. 200k budget, 199.4k used → 600 remaining), handing\n * 600 to the provider as maxTokens produces a request that pays the FULL input cost of the turn only to\n * get cut off mid-generation (`stopReason: \"length\"`) — a doomed, wasted turn. Below the floor, stop\n * the goal cleanly BEFORE sending instead of gambling on a truncated one. Above it, the remaining-total\n * value is a generous (imprecise but safe) protective ceiling — a modest final-turn overrun is\n * acceptable; a truncated turn is not.\n */\nconst MIN_VIABLE_GOAL_TURN_OUTPUT_TOKENS = 1_000;\n\nconst goalExecutionLeaseMarker: unique symbol = Symbol(\"goalExecutionLease\");\n\n/** Identity-bound attribution for one goal-owned foreground execution. */\nexport interface GoalExecutionLease {\n\treadonly goalId?: string;\n\treadonly [goalExecutionLeaseMarker]: true;\n}\n\ninterface MutableGoalExecutionLease extends GoalExecutionLease {\n\tgoalId?: string;\n\tadoptNewGoal: boolean;\n\tadoptionBaselineGoalId?: string;\n\tprovisionalTokenBudget?: number;\n\tpendingTokens: number;\n\tpendingSpendUsd: number;\n\t/** Set once this lease has admitted a provider request while its goal was still active. Lets a\n\t * later admission on the SAME still-held lease recognize \"the goal ended mid-turn\" (drain the\n\t * in-flight turn's wrap-up response) instead of \"a new turn is starting against a dead goal\"\n\t * (which stays denied). */\n\tadmittedWhileActive: boolean;\n}\n\ninterface QueuedOwnerChatGoal {\n\ttext: string;\n\tauthority: ExplicitGoalStartAuthority;\n}\n\n/**\n * Owns durable goal state, exact continuation accounting, and the raw continuation loop. The\n * AgentSession facade supplies process collaborators but no longer implements goal lifecycle rules.\n */\nexport class GoalSessionController {\n\tprivate readonly deps: GoalSessionControllerDeps;\n\tprivate readonly loop: GoalLoopController;\n\tprivate executionLease: MutableGoalExecutionLease | undefined;\n\tprivate startAuthority: ExplicitGoalStartAuthority | undefined;\n\tprivate readonly queuedOwnerChatGoals = new WeakMap<AgentMessage, QueuedOwnerChatGoal>();\n\tprivate queuedOwnerChatExecutionLease: GoalExecutionLease | undefined;\n\n\tconstructor(deps: GoalSessionControllerDeps) {\n\t\tthis.deps = deps;\n\t\tthis.loop = new GoalLoopController({\n\t\t\tgetGoalRuntimeSnapshot: (settings) => this.getRuntimeSnapshot(settings),\n\t\t\tprompt: (text, options) => this.deps.prompt(text, options),\n\t\t\trecordGoalContinuationPass: (pass) => this.recordContinuationPass(pass),\n\t\t\trecordGoalContinuationFailure: (error) => this.recordContinuationFailure(error),\n\t\t\tmarkGoalBudgetLimited: (reason) => this.markBudgetLimited(reason),\n\t\t});\n\t}\n\n\tsaveState(state: GoalState, expected?: GoalStateRevision): string {\n\t\tconst current = this.getState();\n\t\tif (\n\t\t\texpected &&\n\t\t\t(!current || current.goalId !== expected.goalId || (current.revision ?? 0) !== expected.revision)\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Goal state changed concurrently; expected ${expected.goalId}@${expected.revision}, found ${current ? `${current.goalId}@${current.revision ?? 0}` : \"none\"}. Retry against the latest state.`,\n\t\t\t);\n\t\t}\n\t\tconst entryId = appendGoalStateSnapshot(this.deps.getSessionManager(), state, current);\n\t\ttry {\n\t\t\tthis.deps.synchronizeGoalState(state);\n\t\t} catch (error) {\n\t\t\tthis.deps.emitWarning(\n\t\t\t\t`Goal state persisted but durable worker reconciliation failed: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t);\n\t\t}\n\t\treturn entryId;\n\t}\n\n\tclearState(state: GoalState, now: string): string {\n\t\tconst current = this.getState();\n\t\tconst expected = getGoalStateRevision(state);\n\t\tif (!current || current.goalId !== expected.goalId || (current.revision ?? 0) !== expected.revision) {\n\t\t\tthrow new Error(\"Goal state changed concurrently; retry clear against the latest state.\");\n\t\t}\n\t\tif (state.status !== \"completed\" && state.status !== \"cancelled\") {\n\t\t\tthis.deps.synchronizeGoalState(applyGoalEvent(state, { type: \"cancel_goal\", now }));\n\t\t}\n\t\treturn appendGoalClearedSnapshot(this.deps.getSessionManager(), state, now);\n\t}\n\n\tgetState(): GoalState | undefined {\n\t\treturn getLatestGoalStateSnapshot(this.deps.getSessionManager());\n\t}\n\n\t/**\n\t * Promote high-confidence natural-language persistence into the same durable state written by the\n\t * goal tool. This is intentionally narrower than task detection: ordinary work never starts a\n\t * goal, and an unfinished goal is never replaced implicitly.\n\t */\n\tadmitOwnerChatGoal(text: string, messages: readonly { role: string; content?: unknown }[]): ChatGoalAdmission {\n\t\treturn this.admitExplicitChatGoal(text, undefined, priorUserPromptText(messages, text));\n\t}\n\n\tstartOwnerChatGoal(text: string, messages: readonly { role: string; content?: unknown }[]): string | undefined {\n\t\tconst admission = this.admitOwnerChatGoal(text, messages);\n\t\tif (admission.status === \"started\") return admission.state.goalId;\n\t\tif (admission.status === \"unfinished_goal_exists\") {\n\t\t\tthis.deps.emitWarning(\n\t\t\t\t`Explicit chat goal was not started because unfinished goal '${admission.state.goalId}' is ${admission.state.status}. Complete, clear, or explicitly replace it first.`,\n\t\t\t);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tqueueOwnerChatGoal(message: AgentMessage, text: string, authority: ExplicitGoalStartAuthority): void {\n\t\tthis.queuedOwnerChatGoals.set(message, { text, authority });\n\t}\n\n\tactivateQueuedOwnerChatGoal(message: AgentMessage, messages: readonly { role: string; content?: unknown }[]): void {\n\t\tconst queued = this.queuedOwnerChatGoals.get(message);\n\t\tif (!queued) return;\n\t\tthis.queuedOwnerChatGoals.delete(message);\n\t\tconst goalId = this.startOwnerChatGoal(queued.text, messages);\n\t\tif (!goalId) return;\n\t\tthis.setStartAuthority(queued.authority);\n\t\tconst lease = this.beginExecution(goalId);\n\t\tif (!lease) {\n\t\t\tthis.setStartAuthority(undefined);\n\t\t\treturn;\n\t\t}\n\t\tthis.queuedOwnerChatExecutionLease = lease;\n\t}\n\n\tendQueuedOwnerChatGoalExecution(): void {\n\t\tconst lease = this.queuedOwnerChatExecutionLease;\n\t\tif (!lease) return;\n\t\tthis.queuedOwnerChatExecutionLease = undefined;\n\t\tthis.setStartAuthority(undefined);\n\t\tthis.endExecution(lease);\n\t}\n\n\tadmitExplicitChatGoal(text: string, now?: string, priorUserText?: string): ChatGoalAdmission {\n\t\tconst admittedAt = now ?? new Date().toISOString();\n\t\tconst parsed = parseExplicitChatGoal(text, priorUserText);\n\t\tif (!parsed) return { status: \"not_explicit\" };\n\t\tconst current = this.getState();\n\t\tif (current && isGoalUnfinishedStatus(current.status)) {\n\t\t\treturn { status: \"unfinished_goal_exists\", state: current };\n\t\t}\n\t\tconst digest = createHash(\"sha256\")\n\t\t\t.update(`${admittedAt}\\0${current?.goalId ?? \"none\"}\\0${parsed.objective}`)\n\t\t\t.digest(\"hex\")\n\t\t\t.slice(0, 20);\n\t\tconst result = applyGoalAction(\n\t\t\tcurrent,\n\t\t\t{\n\t\t\t\taction: \"start\",\n\t\t\t\tgoalId: `chat-${digest}`,\n\t\t\t\tuserGoal: parsed.objective,\n\t\t\t\ttokenBudget: parsed.tokenBudget,\n\t\t\t},\n\t\t\tadmittedAt,\n\t\t);\n\t\tif (!result.ok) throw new Error(result.error);\n\t\tthis.saveState(result.state, current ? getGoalStateRevision(current) : undefined);\n\t\treturn { status: \"started\", state: result.state };\n\t}\n\n\t/** Attribute turn/wall-clock telemetry after usage has already been charged per response. */\n\trecordContinuationPass(pass: { turns: number; wallClockMs: number }): void {\n\t\tconst state = this.getState();\n\t\tif (!state) return;\n\t\tconst updated = applyGoalEvent(state, {\n\t\t\ttype: \"record_continuation_budget\",\n\t\t\tturns: pass.turns,\n\t\t\twallClockMs: pass.wallClockMs,\n\t\t\ttokens: 0,\n\t\t\tspendUsd: 0,\n\t\t\tnow: new Date().toISOString(),\n\t\t});\n\t\tthis.saveState(updated, getGoalStateRevision(state));\n\t}\n\n\t/** Begin one foreground execution whose provider usage belongs to the specified active goal. */\n\tbeginExecution(\n\t\tgoalId: string | undefined,\n\t\toptions: { adoptNewGoal?: boolean; provisionalTokenBudget?: number } = {},\n\t): GoalExecutionLease | undefined {\n\t\tif (!goalId && !options.adoptNewGoal) return undefined;\n\t\tif (this.executionLease) throw new Error(\"Goal execution attribution is already active\");\n\t\tconst state = this.getState();\n\t\tif (goalId && (!state || state.goalId !== goalId || !isGoalExecutionActive(state.status))) return undefined;\n\t\tconst lease: MutableGoalExecutionLease = {\n\t\t\t...(goalId ? { goalId } : {}),\n\t\t\t[goalExecutionLeaseMarker]: true,\n\t\t\tadoptNewGoal: options.adoptNewGoal === true,\n\t\t\t...(options.adoptNewGoal && state ? { adoptionBaselineGoalId: state.goalId } : {}),\n\t\t\t...(options.provisionalTokenBudget !== undefined\n\t\t\t\t? { provisionalTokenBudget: options.provisionalTokenBudget }\n\t\t\t\t: {}),\n\t\t\tpendingTokens: 0,\n\t\t\tpendingSpendUsd: 0,\n\t\t\tadmittedWhileActive: false,\n\t\t};\n\t\tthis.executionLease = lease;\n\t\treturn lease;\n\t}\n\n\tendExecution(lease: GoalExecutionLease | undefined): void {\n\t\tif (!lease) return;\n\t\tif (this.executionLease !== lease) throw new Error(\"Cannot end goal execution attribution owned by another run\");\n\t\tthis.flushPendingExecutionUsage(this.executionLease);\n\t\tthis.executionLease = undefined;\n\t}\n\n\t/** Charge one observed assistant response exactly once, including routed responses buffered from persistence. */\n\trecordExecutionUsage(message: AssistantMessage): void {\n\t\tconst lease = this.executionLease;\n\t\tif (!lease) return;\n\t\tconst tokens = budgetedTokens({\n\t\t\tinputTokens: Math.max(0, message.usage.input),\n\t\t\toutputTokens: Math.max(0, message.usage.output),\n\t\t\tcacheReadTokens: Math.max(0, message.usage.cacheRead),\n\t\t\tcacheWriteTokens: Math.max(0, message.usage.cacheWrite),\n\t\t\ttotalTokens: Math.max(0, message.usage.totalTokens),\n\t\t});\n\t\tconst spendUsd = Math.max(0, message.usage.cost.total);\n\t\tif (tokens === 0 && spendUsd === 0) return;\n\t\tconst state = this.resolveExecutionState(lease);\n\t\tif (!state) {\n\t\t\tlease.pendingTokens += tokens;\n\t\t\tlease.pendingSpendUsd += spendUsd;\n\t\t\treturn;\n\t\t}\n\t\tthis.chargeExecutionUsage(lease, state, tokens, spendUsd);\n\t}\n\n\tprivate chargeExecutionUsage(\n\t\tlease: MutableGoalExecutionLease,\n\t\tstate: GoalState,\n\t\ttokens: number,\n\t\tspendUsd: number,\n\t): void {\n\t\tconst updated = applyGoalEvent(state, {\n\t\t\ttype: \"record_continuation_budget\",\n\t\t\tturns: 0,\n\t\t\twallClockMs: 0,\n\t\t\ttokens,\n\t\t\tspendUsd,\n\t\t\tnow: new Date().toISOString(),\n\t\t});\n\t\tthis.saveState(updated, getGoalStateRevision(state));\n\t\tlease.pendingTokens = 0;\n\t\tlease.pendingSpendUsd = 0;\n\t\tif (\n\t\t\tisGoalExecutionActive(updated.status) &&\n\t\t\tupdated.tokenBudget !== undefined &&\n\t\t\t(updated.tokensUsed ?? 0) >= updated.tokenBudget\n\t\t) {\n\t\t\tthis.markBudgetLimited(\n\t\t\t\t`token budget exhausted (${updated.tokensUsed ?? 0}/${updated.tokenBudget}) during goal execution`,\n\t\t\t);\n\t\t}\n\t}\n\n\tmarkProtocolFailureBlocked(errorMessage: string): boolean {\n\t\tconst lease = this.executionLease;\n\t\tif (!lease) return false;\n\t\tconst state = this.resolveExecutionState(lease);\n\t\tif (!state || !isGoalExecutionActive(state.status)) return false;\n\t\tconst stopped = stopGoalFromSystem(\n\t\t\tstate,\n\t\t\t{ status: \"blocked\", reason: errorMessage.slice(0, 500) },\n\t\t\tnew Date().toISOString(),\n\t\t);\n\t\tif (!stopped.ok) return false;\n\t\tthis.saveState(stopped.state, getGoalStateRevision(state));\n\t\treturn true;\n\t}\n\n\tsetStartAuthority(authority: ExplicitGoalStartAuthority | undefined): void {\n\t\tthis.startAuthority = authority;\n\t}\n\n\tauthorizeStartFromTool(input: { tokenBudget?: number }): string | undefined {\n\t\tconst authority = this.startAuthority;\n\t\tif (!authority) return \"goal start requires explicit owner authorization in the current prompt.\";\n\t\tif (authority.tokenBudget === undefined && input.tokenBudget !== undefined) {\n\t\t\treturn \"tokenBudget requires an exact numeric token ceiling in the current owner prompt.\";\n\t\t}\n\t\tif (authority.tokenBudget !== undefined && input.tokenBudget !== authority.tokenBudget) {\n\t\t\treturn `tokenBudget must equal the owner-requested ceiling ${authority.tokenBudget}.`;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * True once the currently held execution lease's goal has crossed into `budget_limited` — set\n\t * synchronously by `chargeExecutionUsage` as soon as a just-charged response crosses the ceiling.\n\t * Wired to the agent's `shouldStopAfterTurn` hook so a mid-turn budget stop ends the loop\n\t * gracefully BEFORE the next provider request is even planned, instead of only being caught by\n\t * `admitProviderRequest`'s throw — which still exists as the backstop for a fresh turn or an\n\t * external admission starting against an already budget_limited goal, but would otherwise also\n\t * fire for a request this same lease was already mid-flight for, surfacing a synthetic error\n\t * message where a clean turn end belongs.\n\t */\n\thasExecutionLeaseCrossedBudgetLimit(): boolean {\n\t\tconst lease = this.executionLease;\n\t\tif (!lease) return false;\n\t\treturn this.resolveExecutionState(lease)?.status === \"budget_limited\";\n\t}\n\n\t/** Reserve only remaining output capacity; actual provider usage is charged on response. */\n\tadmitProviderRequest(): number | undefined {\n\t\tconst lease = this.executionLease;\n\t\tif (!lease) return undefined;\n\t\tthis.flushPendingExecutionUsage(lease);\n\t\tconst state = this.resolveExecutionState(lease);\n\t\tif (state?.status === \"budget_limited\") {\n\t\t\tthrow new GoalBudgetExhaustedError(`goal_token_budget_exhausted: ${state.blockedReason ?? lease.goalId}`);\n\t\t}\n\t\tif (state && !isGoalExecutionActive(state.status)) {\n\t\t\tif (!lease.admittedWhileActive) {\n\t\t\t\t// A fresh turn/continuation is being started against a goal that is already done —\n\t\t\t\t// keep this denied so a dead goal cannot restart itself.\n\t\t\t\tthrow new Error(`goal_execution_not_active: ${state.goalId} is ${state.status}`);\n\t\t\t}\n\t\t\t// This lease already admitted at least one request while the goal was active, so the\n\t\t\t// goal ended mid-turn (e.g. the model itself just called `goal complete`/`block`). Let\n\t\t\t// the already-in-flight turn drain to its closing response instead of throwing an error\n\t\t\t// at the user right after a successful stop.\n\t\t\treturn undefined;\n\t\t}\n\t\tif (!state && lease.goalId !== undefined) {\n\t\t\tthrow new Error(`goal_execution_not_active: ${lease.goalId} no longer exists`);\n\t\t}\n\t\tlease.admittedWhileActive = true;\n\t\tconst tokenBudget = state?.tokenBudget ?? lease.provisionalTokenBudget;\n\t\tif (tokenBudget === undefined) return undefined;\n\t\tconst tokensUsed = state?.tokensUsed ?? lease.pendingTokens;\n\t\tconst remaining = Math.max(0, tokenBudget - tokensUsed);\n\t\tif (remaining < MIN_VIABLE_GOAL_TURN_OUTPUT_TOKENS) {\n\t\t\t// Below the floor, remaining is too small to hand to the provider as an output cap without\n\t\t\t// dooming the turn to a mid-generation truncation that still burns the full input cost.\n\t\t\t// Stop cleanly now instead of sending a request that cannot possibly complete.\n\t\t\tif (state) {\n\t\t\t\tthis.markBudgetLimited(\n\t\t\t\t\t`token budget nearly exhausted (${tokensUsed}/${tokenBudget}, ${remaining} remaining is below the ` +\n\t\t\t\t\t\t`${MIN_VIABLE_GOAL_TURN_OUTPUT_TOKENS}-token minimum viable turn) before provider request`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new GoalBudgetExhaustedError(\n\t\t\t\t`goal_token_budget_exhausted: ${remaining} tokens remain, below the ${MIN_VIABLE_GOAL_TURN_OUTPUT_TOKENS}-token minimum viable turn`,\n\t\t\t);\n\t\t}\n\t\treturn remaining;\n\t}\n\n\tprivate resolveExecutionState(lease: MutableGoalExecutionLease): GoalState | undefined {\n\t\tconst state = this.getState();\n\t\tif (!state) return undefined;\n\t\tif (lease.goalId === state.goalId) return state;\n\t\tif (lease.goalId !== undefined || !lease.adoptNewGoal) return undefined;\n\t\tif (lease.adoptionBaselineGoalId === state.goalId) return undefined;\n\t\tlease.goalId = state.goalId;\n\t\treturn state;\n\t}\n\n\tprivate flushPendingExecutionUsage(lease: MutableGoalExecutionLease): void {\n\t\tif (lease.pendingTokens === 0 && lease.pendingSpendUsd === 0) return;\n\t\tconst state = this.resolveExecutionState(lease);\n\t\tif (!state) {\n\t\t\t// A speculative adopt-new-goal lease (lease.goalId still undefined) that never actually\n\t\t\t// adopted a goal this turn has nowhere to attribute usage — that is normal, not a loss.\n\t\t\t// A lease that WAS bound to a real goal but can no longer resolve it is a genuine loss of\n\t\t\t// buffered spend; fail loudly instead of silently discarding it (matches the cursor-based\n\t\t\t// accounting this replaced, which stopped the goal on `goal_usage_cursor_lost`).\n\t\t\tif (lease.goalId !== undefined) {\n\t\t\t\tthis.deps.emitWarning(\n\t\t\t\t\t`Goal usage cursor is no longer resolvable for '${lease.goalId}'; ${lease.pendingTokens} pending tokens and $${lease.pendingSpendUsd.toFixed(6)} pending spend could not be attributed and were dropped.`,\n\t\t\t\t);\n\t\t\t\tthis.recordContinuationFailure(new Error(\"goal_usage_cursor_lost\"));\n\t\t\t}\n\t\t\tlease.pendingTokens = 0;\n\t\t\tlease.pendingSpendUsd = 0;\n\t\t\treturn;\n\t\t}\n\t\tthis.chargeExecutionUsage(lease, state, lease.pendingTokens, lease.pendingSpendUsd);\n\t}\n\n\tmarkToolUnavailable(): void {\n\t\tthis.stopActiveGoal(\n\t\t\t\"blocked\",\n\t\t\t\"goal_tool_unavailable: the active capability surface cannot update durable goal state\",\n\t\t);\n\t}\n\n\tmarkRunawayBlocked(info: { signature: string; repeats: number }): boolean {\n\t\treturn this.stopActiveGoal(\n\t\t\t\"blocked\",\n\t\t\t`runaway_tool_loop: repeated tool-call signature ${info.signature} ${info.repeats} times without progress`,\n\t\t);\n\t}\n\n\tmarkTerminalToolFailureBlocked(toolName: string): boolean {\n\t\treturn this.stopActiveGoal(\n\t\t\t\"blocked\",\n\t\t\t`terminal_tool_failure: ${toolName} reported an unrecoverable error and terminated the run`,\n\t\t);\n\t}\n\n\tgetRuntimeSnapshot(settings: GoalRuntimeSnapshotSettings): GoalRuntimeSnapshot {\n\t\treturn buildGoalRuntimeSnapshot({\n\t\t\tsessionManager: this.deps.getSessionManager(),\n\t\t\tsettings,\n\t\t\tlaneRecords: this.deps.getLaneRecords(),\n\t\t\ttaskRuntime: this.deps.getTaskRuntimeSnapshot(),\n\t\t\tbackgroundToolTasks: this.deps.getBackgroundToolTasks(),\n\t\t});\n\t}\n\n\tcontinueOnce(options: GoalContinuationOnceOptions): Promise<GoalContinuationOnceResult> {\n\t\treturn this.loop.continueGoalOnce(options);\n\t}\n\n\tcontinueLoop(options: GoalContinuationLoopOptions): Promise<GoalContinuationLoopResult> {\n\t\treturn this.loop.continueGoalLoop(options);\n\t}\n\n\trestoreAfterResume(): void {\n\t\tthis.deps.scheduleGoalAutoContinueFromIdle();\n\t}\n\n\tprivate recordContinuationFailure(error: unknown): void {\n\t\tconst state = this.getState();\n\t\tif (!state || !isGoalExecutionActive(state.status)) return;\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst classified = classifyFailure({ message, provider: this.deps.getModelProvider() });\n\t\tconst status = classified.reason === \"billing_or_quota\" ? \"usage_limited\" : \"blocked\";\n\t\tthis.stopActiveGoal(status, `${classified.reason}: ${message}`);\n\t}\n\n\tprivate markBudgetLimited(reason: string): void {\n\t\tthis.stopActiveGoal(\"budget_limited\", reason);\n\t}\n\n\tprivate stopActiveGoal(status: \"blocked\" | \"usage_limited\" | \"budget_limited\", reason: string): boolean {\n\t\tconst state = this.getState();\n\t\tconst stopped = stopGoalFromSystem(state, { status, reason }, new Date().toISOString());\n\t\tif (!stopped.ok || !state) return false;\n\t\tthis.saveState(stopped.state, getGoalStateRevision(state));\n\t\treturn true;\n\t}\n}\n"]}
@@ -23,11 +23,12 @@ export declare function parseRequestedTokenBudget(text: string, objective?: {
23
23
  start: number;
24
24
  end: number;
25
25
  }): number | undefined;
26
- /**
27
- * Recognize only explicit persistence language. Ordinary multi-step work and discussion ABOUT goal
28
- * mechanics deliberately return undefined; those must not silently expand into autonomous work.
29
- */
30
- export declare function parseExplicitChatGoal(text: string): ExplicitChatGoal | undefined;
26
+ /** Latest owner prompt that is not the current classification phrase itself. */
27
+ export declare function priorUserPromptText(messages: readonly {
28
+ role: string;
29
+ content?: unknown;
30
+ }[], currentText: string): string | undefined;
31
+ export declare function parseExplicitChatGoal(text: string, priorUserText?: string): ExplicitChatGoal | undefined;
31
32
  /** Exact owner authority for model-facing goal creation; ordinary work and meta-discussion fail closed. */
32
33
  export declare function parseExplicitGoalStartAuthority(text: string): ExplicitGoalStartAuthority | undefined;
33
34
  //# sourceMappingURL=natural-language-goal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"natural-language-goal.d.ts","sourceRoot":"","sources":["../../../src/core/goals/natural-language-goal.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,0BAA0B;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAkBD;;2CAE2C;AAC3C,qBAAa,yBAA0B,SAAQ,KAAK;IACnD,YAAY,OAAO,EAAE,MAAM,EAG1B;CACD;AAsED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACxC,MAAM,GAAG,SAAS,CAMpB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAgBhF;AAED,2GAA2G;AAC3G,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS,CAMpG"}
1
+ {"version":3,"file":"natural-language-goal.d.ts","sourceRoot":"","sources":["../../../src/core/goals/natural-language-goal.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,0BAA0B;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAkCD;;2CAE2C;AAC3C,qBAAa,yBAA0B,SAAQ,KAAK;IACnD,YAAY,OAAO,EAAE,MAAM,EAG1B;CACD;AAsED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACxC,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACxC,MAAM,GAAG,SAAS,CAMpB;AAyED,gFAAgF;AAChF,wBAAgB,mBAAmB,CAClC,QAAQ,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,EACxD,WAAW,EAAE,MAAM,GACjB,MAAM,GAAG,SAAS,CAUpB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CA4BxG;AAED,2GAA2G;AAC3G,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS,CAMpG"}
@@ -6,12 +6,26 @@ const EXPLICIT_GOAL_PATTERNS = [
6
6
  /^\s*treat\s+this\s+as\s+my\s+(?:persistent\s+)?goal\s*:\s*(.+)$/is,
7
7
  /^\s*i\s+want\s+this\s+as\s+(?:my\s+)?(?:persistent\s+)?goal\s*:\s*(.+)$/is,
8
8
  /^\s*keep\s+working\s+until\s+this\s+is\s+(?:complete|done)\s*:\s*(.+)$/is,
9
+ /^\s*instead of .+,\s*i want to (.+)$/is,
10
+ /^\s*i want to ((?:refactor|rewrite|rebuild|redesign)\b.+)$/is,
9
11
  ];
10
12
  const STANDALONE_GOAL_AUTHORITY_PATTERNS = [
11
13
  // After "goal" require end, whitespace, or punctuation — not a hyphen — so
12
14
  // "this is a goal, use it" authorizes while "this is a goal-oriented design" does not.
13
15
  /^\s*(?:this|that)\s+is\s+(?:now\s+)?a\s+(?:persistent\s+)?goal(?=[\s,.:;!?]|$)/is,
16
+ /^\s*(?:this|the|that)\s+task\s+is\s+(?:now\s+)?a\s+(?:persistent\s+)?goal(?=[\s,.:;!?]|$)/is,
14
17
  /^\s*(?:make|treat)\s+this\s+(?:as\s+)?(?:my\s+|a\s+)?(?:persistent\s+)?goal(?=[\s,.:;!?]|$)/is,
18
+ /^\s*(?:make|treat)\s+this\s+task\s+(?:as\s+)?(?:my\s+|a\s+)?(?:persistent\s+)?goal(?=[\s,.:;!?]|$)/is,
19
+ ];
20
+ const STANDALONE_GOAL_FILLER = /^(?:use it|please|now|ok|okay|thanks|go|do it)(?:[.!?])?$/i;
21
+ const STANDALONE_GOAL_PROCESS_PHRASES = [
22
+ /\bby the way\b/gi,
23
+ /\bi(?:'m| am) handing (?:(?:this|it) )?over(?: to you)?\b/gi,
24
+ /\bhand(?:ing)? (?:(?:this|it) )?over(?: to you)?\b/gi,
25
+ /\buse max(?:imum)? \d+ sub[-\s]?agents?\b/gi,
26
+ /\byou are (?:the )?(?:orchestrator|reviewer|team lead)(?:(?:\s+and|\s*,)\s*(?:also\s+)?(?:the\s+)?(?:orchestrator|reviewer|team lead))*\b/gi,
27
+ /\bhelp you deliver\b/gi,
28
+ /\b(?:orchestrator|reviewer|team lead)\b/gi,
15
29
  ];
16
30
  /** Raised when text unambiguously states a token-budget directive but the amount cannot be resolved
17
31
  * to an exact positive integer. Callers must let this propagate as a loud, explicit failure instead
@@ -112,7 +126,87 @@ export function parseRequestedTokenBudget(text, objective) {
112
126
  * Recognize only explicit persistence language. Ordinary multi-step work and discussion ABOUT goal
113
127
  * mechanics deliberately return undefined; those must not silently expand into autonomous work.
114
128
  */
115
- export function parseExplicitChatGoal(text) {
129
+ function standaloneGoalRemainder(text) {
130
+ for (const pattern of STANDALONE_GOAL_AUTHORITY_PATTERNS) {
131
+ const match = pattern.exec(text);
132
+ if (!match)
133
+ continue;
134
+ return text
135
+ .slice(match.index + match[0].length)
136
+ .replace(/^[\s,.:;!?-]+/, "")
137
+ .replace(/^(?:and|then|so)\s+/i, "")
138
+ .trim();
139
+ }
140
+ return undefined;
141
+ }
142
+ function remainderWithoutBudgetPhrase(remainder) {
143
+ let next = remainder;
144
+ for (const pattern of TOKEN_BUDGET_PATTERNS) {
145
+ next = next.replace(pattern, " ");
146
+ }
147
+ return next
148
+ .replace(/\b(?:with|of|is|a|the|:|=)\b/gi, " ")
149
+ .replace(/\s+/g, " ")
150
+ .trim();
151
+ }
152
+ function remainderWithoutProcessPhrases(remainder) {
153
+ let next = remainder;
154
+ for (const pattern of STANDALONE_GOAL_PROCESS_PHRASES) {
155
+ next = next.replace(pattern, " ");
156
+ }
157
+ return next
158
+ .replace(/\b(?:with|of|is|a|the|to|and|also|you|i|i'm|:|=)\b/gi, " ")
159
+ .replace(/[.,:;!?]/g, " ")
160
+ .replace(/\s+/g, " ")
161
+ .trim();
162
+ }
163
+ function isClassificationRemainder(remainder) {
164
+ if (!remainder || STANDALONE_GOAL_FILLER.test(remainder))
165
+ return true;
166
+ const leftover = remainderWithoutProcessPhrases(remainder);
167
+ if (!leftover || STANDALONE_GOAL_FILLER.test(leftover))
168
+ return true;
169
+ try {
170
+ if (parseRequestedTokenBudget(remainder) === undefined)
171
+ return false;
172
+ }
173
+ catch {
174
+ return false;
175
+ }
176
+ const afterBudget = remainderWithoutBudgetPhrase(leftover);
177
+ return afterBudget.length === 0 || STANDALONE_GOAL_FILLER.test(afterBudget);
178
+ }
179
+ function userMessageText(content) {
180
+ if (typeof content === "string")
181
+ return content.trim();
182
+ if (!Array.isArray(content))
183
+ return "";
184
+ return content
185
+ .filter((block) => typeof block === "object" &&
186
+ block !== null &&
187
+ "type" in block &&
188
+ block.type === "text" &&
189
+ "text" in block &&
190
+ typeof block.text === "string")
191
+ .map((block) => block.text)
192
+ .join("")
193
+ .trim();
194
+ }
195
+ /** Latest owner prompt that is not the current classification phrase itself. */
196
+ export function priorUserPromptText(messages, currentText) {
197
+ const current = currentText.trim();
198
+ for (let index = messages.length - 1; index >= 0; index--) {
199
+ const message = messages[index];
200
+ if (message.role !== "user")
201
+ continue;
202
+ const text = userMessageText(message.content);
203
+ if (!text || text === current)
204
+ continue;
205
+ return text;
206
+ }
207
+ return undefined;
208
+ }
209
+ export function parseExplicitChatGoal(text, priorUserText) {
116
210
  for (const pattern of EXPLICIT_GOAL_PATTERNS) {
117
211
  const match = pattern.exec(text);
118
212
  const rawObjective = match?.[1];
@@ -128,7 +222,20 @@ export function parseExplicitChatGoal(text) {
128
222
  const tokenBudget = parseRequestedTokenBudget(text, objectiveSpan);
129
223
  return { objective, ...(tokenBudget !== undefined ? { tokenBudget } : {}) };
130
224
  }
131
- return undefined;
225
+ const remainder = standaloneGoalRemainder(text);
226
+ if (remainder === undefined)
227
+ return undefined;
228
+ const tokenBudget = parseRequestedTokenBudget(text);
229
+ const inline = remainder && !isClassificationRemainder(remainder) ? remainder : undefined;
230
+ const prior = priorUserText?.trim();
231
+ const objective = inline && inline.length <= MAX_GOAL_OBJECTIVE_LENGTH
232
+ ? inline
233
+ : prior && prior !== text.trim() && prior.length <= MAX_GOAL_OBJECTIVE_LENGTH
234
+ ? prior
235
+ : undefined;
236
+ if (!objective)
237
+ return undefined;
238
+ return { objective, ...(tokenBudget !== undefined ? { tokenBudget } : {}) };
132
239
  }
133
240
  /** Exact owner authority for model-facing goal creation; ordinary work and meta-discussion fail closed. */
134
241
  export function parseExplicitGoalStartAuthority(text) {
@@ -1 +1 @@
1
- {"version":3,"file":"natural-language-goal.js","sourceRoot":"","sources":["../../../src/core/goals/natural-language-goal.ts"],"names":[],"mappings":"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","sourcesContent":["import { MAX_GOAL_OBJECTIVE_LENGTH } from \"./goal-state.ts\";\n\nexport interface ExplicitChatGoal {\n\tobjective: string;\n\ttokenBudget?: number;\n}\n\nexport interface ExplicitGoalStartAuthority {\n\ttokenBudget?: number;\n}\n\nconst EXPLICIT_GOAL_PATTERNS = [\n\t/^\\s*set\\s+(?:this\\s+as\\s+)?a\\s+(?:persistent\\s+)?goal\\s*(?::|to\\s+)\\s*(.+)$/is,\n\t/^\\s*my\\s+persistent\\s+goal\\s+is\\s+to\\s+(.+)$/is,\n\t/^\\s*(?:the|our)\\s+(?:persistent\\s+)?goal\\s+is\\s+to\\s+(.+)$/is,\n\t/^\\s*treat\\s+this\\s+as\\s+my\\s+(?:persistent\\s+)?goal\\s*:\\s*(.+)$/is,\n\t/^\\s*i\\s+want\\s+this\\s+as\\s+(?:my\\s+)?(?:persistent\\s+)?goal\\s*:\\s*(.+)$/is,\n\t/^\\s*keep\\s+working\\s+until\\s+this\\s+is\\s+(?:complete|done)\\s*:\\s*(.+)$/is,\n] as const;\n\nconst STANDALONE_GOAL_AUTHORITY_PATTERNS = [\n\t// After \"goal\" require end, whitespace, or punctuation — not a hyphen — so\n\t// \"this is a goal, use it\" authorizes while \"this is a goal-oriented design\" does not.\n\t/^\\s*(?:this|that)\\s+is\\s+(?:now\\s+)?a\\s+(?:persistent\\s+)?goal(?=[\\s,.:;!?]|$)/is,\n\t/^\\s*(?:make|treat)\\s+this\\s+(?:as\\s+)?(?:my\\s+|a\\s+)?(?:persistent\\s+)?goal(?=[\\s,.:;!?]|$)/is,\n] as const;\n\n/** Raised when text unambiguously states a token-budget directive but the amount cannot be resolved\n * to an exact positive integer. Callers must let this propagate as a loud, explicit failure instead\n * of falling back to an unbounded goal. */\nexport class GoalTokenBudgetParseError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"GoalTokenBudgetParseError\";\n\t}\n}\n\nconst TOKEN_UNIT_MULTIPLIERS: Record<string, number> = {\n\tk: 1_000,\n\tthousand: 1_000,\n\tm: 1_000_000,\n\tmillion: 1_000_000,\n};\n\n/**\n * Resolve a matched numeral into a plain integer, disambiguating a thousands separator from a\n * decimal point. Comma is never a decimal point in this grammar, so any comma-grouped digits\n * (e.g. \"5,000\") are treated as a separator. A dot is genuinely ambiguous (\"1.5\" vs \"1.000.000\"),\n * so it is only treated as a separator when the exactly-3-digit group repeats (e.g. \"1.000.000\");\n * a single dot group falls back to a literal decimal (e.g. \"1.5\", or \"1.000\" read as 1).\n */\nfunction normalizeTokenNumeral(raw: string): number | undefined {\n\t// The caller's capture regex allows \",\" \"_\" \".\" to continue a numeral (they can be internal\n\t// separators), so it greedily swallows a trailing one that is NOT followed by more digits — e.g.\n\t// the sentence-ending \".\" after a dot-grouped \"1.000.000.\" A separator is only ever meaningful\n\t// between digits, so a trailing one is always incidental punctuation; drop it before classifying.\n\tconst compact = raw.replace(/_/g, \"\").replace(/[,.]+$/, \"\");\n\tif (/^[0-9]+$/.test(compact)) return Number(compact);\n\tif (/^[0-9]{1,3}(,[0-9]{3})+\\.[0-9]+$/.test(compact)) return Number(compact.replace(/,/g, \"\"));\n\tif (/^[0-9]{1,3}(,[0-9]{3})+$/.test(compact)) return Number(compact.replace(/,/g, \"\"));\n\tif (/^[0-9]{1,3}(\\.[0-9]{3}){2,}$/.test(compact)) return Number(compact.replace(/\\./g, \"\"));\n\tif (/^[0-9]+\\.[0-9]+$/.test(compact)) return Number(compact);\n\treturn undefined;\n}\n\nfunction parsePositiveTokenCount(raw: string, unit: string | undefined): number | undefined {\n\tconst value = normalizeTokenNumeral(raw);\n\tif (value === undefined) return undefined;\n\tconst multiplier = unit ? (TOKEN_UNIT_MULTIPLIERS[unit.toLowerCase()] ?? 1) : 1;\n\tconst tokens = value * multiplier;\n\treturn Number.isSafeInteger(tokens) && tokens > 0 ? tokens : undefined;\n}\n\nconst TOKEN_BUDGET_PATTERNS = [\n\t/\\btoken\\s+budget\\s*(?:of|is|:|=)?\\s*([0-9][0-9,_.]*)(?:\\s*(thousand|million|k|m)\\b)?/i,\n\t/\\b([0-9][0-9,_.]*)(?:\\s*(thousand|million|k|m)\\b)?\\s*(?:token|tokens)\\s+budget\\b/i,\n\t/\\bbudget\\s*(?:of|is|:|=)?\\s*([0-9][0-9,_.]*)(?:\\s*(thousand|million|k|m)\\b)?\\s*(?:token|tokens)\\b/i,\n] as const;\n\n/**\n * Scan `text` for one explicit token-budget directive. When `trailingOnly` is set, a match only\n * counts if it runs to the end of `text` (ignoring closing punctuation/whitespace) — used to scan\n * inside a captured goal objective, where a budget-shaped phrase embedded mid-sentence usually\n * describes the task's subject matter (e.g. a constant being edited in code), not the agent's own\n * execution ceiling, whereas a trailing clause (\"... with a 40k token budget.\") is a real directive.\n */\nfunction scanTokenBudget(text: string, options: { trailingOnly: boolean }): number | undefined {\n\tfor (const pattern of TOKEN_BUDGET_PATTERNS) {\n\t\tconst match = pattern.exec(text);\n\t\tif (!match) continue;\n\t\tif (options.trailingOnly) {\n\t\t\tconst tail = text.slice(match.index + match[0].length);\n\t\t\tif (!/^[.!?]?\\s*$/.test(tail)) continue;\n\t\t}\n\t\tconst tokens = parsePositiveTokenCount(match[1], match[2]);\n\t\tif (tokens === undefined) {\n\t\t\tthrow new GoalTokenBudgetParseError(\n\t\t\t\t`Token budget phrase \"${match[0].trim()}\" could not be parsed into an exact token ceiling.`,\n\t\t\t);\n\t\t}\n\t\treturn tokens;\n\t}\n\treturn undefined;\n}\n\n/**\n * Parse an explicit token-budget directive from `text`. When `objective` locates a captured goal\n * objective within `text`, a budget-shaped phrase found INSIDE it only counts when it is the\n * trailing clause of the objective; text outside the objective (the prefix/suffix around it) is\n * scanned without that restriction. This keeps a genuine directive (\"... with a 40k token budget.\")\n * working while refusing to adopt a number that is merely part of the task's own subject matter\n * (\"raise the model token budget of 4096 ... to 8192\").\n */\nexport function parseRequestedTokenBudget(\n\ttext: string,\n\tobjective?: { start: number; end: number },\n): number | undefined {\n\tif (!objective) return scanTokenBudget(text, { trailingOnly: false });\n\tconst outside = `${text.slice(0, objective.start)} ${text.slice(objective.end)}`;\n\tconst outsideBudget = scanTokenBudget(outside, { trailingOnly: false });\n\tif (outsideBudget !== undefined) return outsideBudget;\n\treturn scanTokenBudget(text.slice(objective.start, objective.end), { trailingOnly: true });\n}\n\n/**\n * Recognize only explicit persistence language. Ordinary multi-step work and discussion ABOUT goal\n * mechanics deliberately return undefined; those must not silently expand into autonomous work.\n */\nexport function parseExplicitChatGoal(text: string): ExplicitChatGoal | undefined {\n\tfor (const pattern of EXPLICIT_GOAL_PATTERNS) {\n\t\tconst match = pattern.exec(text);\n\t\tconst rawObjective = match?.[1];\n\t\tconst objective = rawObjective?.trim();\n\t\tif (!match || !objective || objective.length > MAX_GOAL_OBJECTIVE_LENGTH) continue;\n\t\t// rawObjective is always a suffix of match[0] (every pattern ends in `(.+)$`), so its start\n\t\t// offset in `text` is match[0]'s length minus its own length.\n\t\tconst objectiveSpan = {\n\t\t\tstart: match.index + (match[0].length - (rawObjective?.length ?? 0)),\n\t\t\tend: match.index + match[0].length,\n\t\t};\n\t\tconst tokenBudget = parseRequestedTokenBudget(text, objectiveSpan);\n\t\treturn { objective, ...(tokenBudget !== undefined ? { tokenBudget } : {}) };\n\t}\n\treturn undefined;\n}\n\n/** Exact owner authority for model-facing goal creation; ordinary work and meta-discussion fail closed. */\nexport function parseExplicitGoalStartAuthority(text: string): ExplicitGoalStartAuthority | undefined {\n\tconst goal = parseExplicitChatGoal(text);\n\tif (goal) return goal.tokenBudget === undefined ? {} : { tokenBudget: goal.tokenBudget };\n\tif (!STANDALONE_GOAL_AUTHORITY_PATTERNS.some((pattern) => pattern.test(text))) return undefined;\n\tconst tokenBudget = parseRequestedTokenBudget(text);\n\treturn tokenBudget === undefined ? {} : { tokenBudget };\n}\n"]}
1
+ {"version":3,"file":"natural-language-goal.js","sourceRoot":"","sources":["../../../src/core/goals/natural-language-goal.ts"],"names":[],"mappings":"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","sourcesContent":["import { MAX_GOAL_OBJECTIVE_LENGTH } from \"./goal-state.ts\";\n\nexport interface ExplicitChatGoal {\n\tobjective: string;\n\ttokenBudget?: number;\n}\n\nexport interface ExplicitGoalStartAuthority {\n\ttokenBudget?: number;\n}\n\nconst EXPLICIT_GOAL_PATTERNS = [\n\t/^\\s*set\\s+(?:this\\s+as\\s+)?a\\s+(?:persistent\\s+)?goal\\s*(?::|to\\s+)\\s*(.+)$/is,\n\t/^\\s*my\\s+persistent\\s+goal\\s+is\\s+to\\s+(.+)$/is,\n\t/^\\s*(?:the|our)\\s+(?:persistent\\s+)?goal\\s+is\\s+to\\s+(.+)$/is,\n\t/^\\s*treat\\s+this\\s+as\\s+my\\s+(?:persistent\\s+)?goal\\s*:\\s*(.+)$/is,\n\t/^\\s*i\\s+want\\s+this\\s+as\\s+(?:my\\s+)?(?:persistent\\s+)?goal\\s*:\\s*(.+)$/is,\n\t/^\\s*keep\\s+working\\s+until\\s+this\\s+is\\s+(?:complete|done)\\s*:\\s*(.+)$/is,\n\t/^\\s*instead of .+,\\s*i want to (.+)$/is,\n\t/^\\s*i want to ((?:refactor|rewrite|rebuild|redesign)\\b.+)$/is,\n] as const;\n\nconst STANDALONE_GOAL_AUTHORITY_PATTERNS = [\n\t// After \"goal\" require end, whitespace, or punctuation — not a hyphen — so\n\t// \"this is a goal, use it\" authorizes while \"this is a goal-oriented design\" does not.\n\t/^\\s*(?:this|that)\\s+is\\s+(?:now\\s+)?a\\s+(?:persistent\\s+)?goal(?=[\\s,.:;!?]|$)/is,\n\t/^\\s*(?:this|the|that)\\s+task\\s+is\\s+(?:now\\s+)?a\\s+(?:persistent\\s+)?goal(?=[\\s,.:;!?]|$)/is,\n\t/^\\s*(?:make|treat)\\s+this\\s+(?:as\\s+)?(?:my\\s+|a\\s+)?(?:persistent\\s+)?goal(?=[\\s,.:;!?]|$)/is,\n\t/^\\s*(?:make|treat)\\s+this\\s+task\\s+(?:as\\s+)?(?:my\\s+|a\\s+)?(?:persistent\\s+)?goal(?=[\\s,.:;!?]|$)/is,\n] as const;\n\nconst STANDALONE_GOAL_FILLER = /^(?:use it|please|now|ok|okay|thanks|go|do it)(?:[.!?])?$/i;\n\nconst STANDALONE_GOAL_PROCESS_PHRASES = [\n\t/\\bby the way\\b/gi,\n\t/\\bi(?:'m| am) handing (?:(?:this|it) )?over(?: to you)?\\b/gi,\n\t/\\bhand(?:ing)? (?:(?:this|it) )?over(?: to you)?\\b/gi,\n\t/\\buse max(?:imum)? \\d+ sub[-\\s]?agents?\\b/gi,\n\t/\\byou are (?:the )?(?:orchestrator|reviewer|team lead)(?:(?:\\s+and|\\s*,)\\s*(?:also\\s+)?(?:the\\s+)?(?:orchestrator|reviewer|team lead))*\\b/gi,\n\t/\\bhelp you deliver\\b/gi,\n\t/\\b(?:orchestrator|reviewer|team lead)\\b/gi,\n] as const;\n\n/** Raised when text unambiguously states a token-budget directive but the amount cannot be resolved\n * to an exact positive integer. Callers must let this propagate as a loud, explicit failure instead\n * of falling back to an unbounded goal. */\nexport class GoalTokenBudgetParseError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"GoalTokenBudgetParseError\";\n\t}\n}\n\nconst TOKEN_UNIT_MULTIPLIERS: Record<string, number> = {\n\tk: 1_000,\n\tthousand: 1_000,\n\tm: 1_000_000,\n\tmillion: 1_000_000,\n};\n\n/**\n * Resolve a matched numeral into a plain integer, disambiguating a thousands separator from a\n * decimal point. Comma is never a decimal point in this grammar, so any comma-grouped digits\n * (e.g. \"5,000\") are treated as a separator. A dot is genuinely ambiguous (\"1.5\" vs \"1.000.000\"),\n * so it is only treated as a separator when the exactly-3-digit group repeats (e.g. \"1.000.000\");\n * a single dot group falls back to a literal decimal (e.g. \"1.5\", or \"1.000\" read as 1).\n */\nfunction normalizeTokenNumeral(raw: string): number | undefined {\n\t// The caller's capture regex allows \",\" \"_\" \".\" to continue a numeral (they can be internal\n\t// separators), so it greedily swallows a trailing one that is NOT followed by more digits — e.g.\n\t// the sentence-ending \".\" after a dot-grouped \"1.000.000.\" A separator is only ever meaningful\n\t// between digits, so a trailing one is always incidental punctuation; drop it before classifying.\n\tconst compact = raw.replace(/_/g, \"\").replace(/[,.]+$/, \"\");\n\tif (/^[0-9]+$/.test(compact)) return Number(compact);\n\tif (/^[0-9]{1,3}(,[0-9]{3})+\\.[0-9]+$/.test(compact)) return Number(compact.replace(/,/g, \"\"));\n\tif (/^[0-9]{1,3}(,[0-9]{3})+$/.test(compact)) return Number(compact.replace(/,/g, \"\"));\n\tif (/^[0-9]{1,3}(\\.[0-9]{3}){2,}$/.test(compact)) return Number(compact.replace(/\\./g, \"\"));\n\tif (/^[0-9]+\\.[0-9]+$/.test(compact)) return Number(compact);\n\treturn undefined;\n}\n\nfunction parsePositiveTokenCount(raw: string, unit: string | undefined): number | undefined {\n\tconst value = normalizeTokenNumeral(raw);\n\tif (value === undefined) return undefined;\n\tconst multiplier = unit ? (TOKEN_UNIT_MULTIPLIERS[unit.toLowerCase()] ?? 1) : 1;\n\tconst tokens = value * multiplier;\n\treturn Number.isSafeInteger(tokens) && tokens > 0 ? tokens : undefined;\n}\n\nconst TOKEN_BUDGET_PATTERNS = [\n\t/\\btoken\\s+budget\\s*(?:of|is|:|=)?\\s*([0-9][0-9,_.]*)(?:\\s*(thousand|million|k|m)\\b)?/i,\n\t/\\b([0-9][0-9,_.]*)(?:\\s*(thousand|million|k|m)\\b)?\\s*(?:token|tokens)\\s+budget\\b/i,\n\t/\\bbudget\\s*(?:of|is|:|=)?\\s*([0-9][0-9,_.]*)(?:\\s*(thousand|million|k|m)\\b)?\\s*(?:token|tokens)\\b/i,\n] as const;\n\n/**\n * Scan `text` for one explicit token-budget directive. When `trailingOnly` is set, a match only\n * counts if it runs to the end of `text` (ignoring closing punctuation/whitespace) — used to scan\n * inside a captured goal objective, where a budget-shaped phrase embedded mid-sentence usually\n * describes the task's subject matter (e.g. a constant being edited in code), not the agent's own\n * execution ceiling, whereas a trailing clause (\"... with a 40k token budget.\") is a real directive.\n */\nfunction scanTokenBudget(text: string, options: { trailingOnly: boolean }): number | undefined {\n\tfor (const pattern of TOKEN_BUDGET_PATTERNS) {\n\t\tconst match = pattern.exec(text);\n\t\tif (!match) continue;\n\t\tif (options.trailingOnly) {\n\t\t\tconst tail = text.slice(match.index + match[0].length);\n\t\t\tif (!/^[.!?]?\\s*$/.test(tail)) continue;\n\t\t}\n\t\tconst tokens = parsePositiveTokenCount(match[1], match[2]);\n\t\tif (tokens === undefined) {\n\t\t\tthrow new GoalTokenBudgetParseError(\n\t\t\t\t`Token budget phrase \"${match[0].trim()}\" could not be parsed into an exact token ceiling.`,\n\t\t\t);\n\t\t}\n\t\treturn tokens;\n\t}\n\treturn undefined;\n}\n\n/**\n * Parse an explicit token-budget directive from `text`. When `objective` locates a captured goal\n * objective within `text`, a budget-shaped phrase found INSIDE it only counts when it is the\n * trailing clause of the objective; text outside the objective (the prefix/suffix around it) is\n * scanned without that restriction. This keeps a genuine directive (\"... with a 40k token budget.\")\n * working while refusing to adopt a number that is merely part of the task's own subject matter\n * (\"raise the model token budget of 4096 ... to 8192\").\n */\nexport function parseRequestedTokenBudget(\n\ttext: string,\n\tobjective?: { start: number; end: number },\n): number | undefined {\n\tif (!objective) return scanTokenBudget(text, { trailingOnly: false });\n\tconst outside = `${text.slice(0, objective.start)} ${text.slice(objective.end)}`;\n\tconst outsideBudget = scanTokenBudget(outside, { trailingOnly: false });\n\tif (outsideBudget !== undefined) return outsideBudget;\n\treturn scanTokenBudget(text.slice(objective.start, objective.end), { trailingOnly: true });\n}\n\n/**\n * Recognize only explicit persistence language. Ordinary multi-step work and discussion ABOUT goal\n * mechanics deliberately return undefined; those must not silently expand into autonomous work.\n */\nfunction standaloneGoalRemainder(text: string): string | undefined {\n\tfor (const pattern of STANDALONE_GOAL_AUTHORITY_PATTERNS) {\n\t\tconst match = pattern.exec(text);\n\t\tif (!match) continue;\n\t\treturn text\n\t\t\t.slice(match.index + match[0].length)\n\t\t\t.replace(/^[\\s,.:;!?-]+/, \"\")\n\t\t\t.replace(/^(?:and|then|so)\\s+/i, \"\")\n\t\t\t.trim();\n\t}\n\treturn undefined;\n}\n\nfunction remainderWithoutBudgetPhrase(remainder: string): string {\n\tlet next = remainder;\n\tfor (const pattern of TOKEN_BUDGET_PATTERNS) {\n\t\tnext = next.replace(pattern, \" \");\n\t}\n\treturn next\n\t\t.replace(/\\b(?:with|of|is|a|the|:|=)\\b/gi, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nfunction remainderWithoutProcessPhrases(remainder: string): string {\n\tlet next = remainder;\n\tfor (const pattern of STANDALONE_GOAL_PROCESS_PHRASES) {\n\t\tnext = next.replace(pattern, \" \");\n\t}\n\treturn next\n\t\t.replace(/\\b(?:with|of|is|a|the|to|and|also|you|i|i'm|:|=)\\b/gi, \" \")\n\t\t.replace(/[.,:;!?]/g, \" \")\n\t\t.replace(/\\s+/g, \" \")\n\t\t.trim();\n}\n\nfunction isClassificationRemainder(remainder: string): boolean {\n\tif (!remainder || STANDALONE_GOAL_FILLER.test(remainder)) return true;\n\tconst leftover = remainderWithoutProcessPhrases(remainder);\n\tif (!leftover || STANDALONE_GOAL_FILLER.test(leftover)) return true;\n\ttry {\n\t\tif (parseRequestedTokenBudget(remainder) === undefined) return false;\n\t} catch {\n\t\treturn false;\n\t}\n\tconst afterBudget = remainderWithoutBudgetPhrase(leftover);\n\treturn afterBudget.length === 0 || STANDALONE_GOAL_FILLER.test(afterBudget);\n}\n\nfunction userMessageText(content: unknown): string {\n\tif (typeof content === \"string\") return content.trim();\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.filter(\n\t\t\t(block): block is { type: \"text\"; text: string } =>\n\t\t\t\ttypeof block === \"object\" &&\n\t\t\t\tblock !== null &&\n\t\t\t\t\"type\" in block &&\n\t\t\t\tblock.type === \"text\" &&\n\t\t\t\t\"text\" in block &&\n\t\t\t\ttypeof block.text === \"string\",\n\t\t)\n\t\t.map((block) => block.text)\n\t\t.join(\"\")\n\t\t.trim();\n}\n\n/** Latest owner prompt that is not the current classification phrase itself. */\nexport function priorUserPromptText(\n\tmessages: readonly { role: string; content?: unknown }[],\n\tcurrentText: string,\n): string | undefined {\n\tconst current = currentText.trim();\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst message = messages[index];\n\t\tif (message.role !== \"user\") continue;\n\t\tconst text = userMessageText(message.content);\n\t\tif (!text || text === current) continue;\n\t\treturn text;\n\t}\n\treturn undefined;\n}\n\nexport function parseExplicitChatGoal(text: string, priorUserText?: string): ExplicitChatGoal | undefined {\n\tfor (const pattern of EXPLICIT_GOAL_PATTERNS) {\n\t\tconst match = pattern.exec(text);\n\t\tconst rawObjective = match?.[1];\n\t\tconst objective = rawObjective?.trim();\n\t\tif (!match || !objective || objective.length > MAX_GOAL_OBJECTIVE_LENGTH) continue;\n\t\t// rawObjective is always a suffix of match[0] (every pattern ends in `(.+)$`), so its start\n\t\t// offset in `text` is match[0]'s length minus its own length.\n\t\tconst objectiveSpan = {\n\t\t\tstart: match.index + (match[0].length - (rawObjective?.length ?? 0)),\n\t\t\tend: match.index + match[0].length,\n\t\t};\n\t\tconst tokenBudget = parseRequestedTokenBudget(text, objectiveSpan);\n\t\treturn { objective, ...(tokenBudget !== undefined ? { tokenBudget } : {}) };\n\t}\n\tconst remainder = standaloneGoalRemainder(text);\n\tif (remainder === undefined) return undefined;\n\tconst tokenBudget = parseRequestedTokenBudget(text);\n\tconst inline = remainder && !isClassificationRemainder(remainder) ? remainder : undefined;\n\tconst prior = priorUserText?.trim();\n\tconst objective =\n\t\tinline && inline.length <= MAX_GOAL_OBJECTIVE_LENGTH\n\t\t\t? inline\n\t\t\t: prior && prior !== text.trim() && prior.length <= MAX_GOAL_OBJECTIVE_LENGTH\n\t\t\t\t? prior\n\t\t\t\t: undefined;\n\tif (!objective) return undefined;\n\treturn { objective, ...(tokenBudget !== undefined ? { tokenBudget } : {}) };\n}\n\n/** Exact owner authority for model-facing goal creation; ordinary work and meta-discussion fail closed. */\nexport function parseExplicitGoalStartAuthority(text: string): ExplicitGoalStartAuthority | undefined {\n\tconst goal = parseExplicitChatGoal(text);\n\tif (goal) return goal.tokenBudget === undefined ? {} : { tokenBudget: goal.tokenBudget };\n\tif (!STANDALONE_GOAL_AUTHORITY_PATTERNS.some((pattern) => pattern.test(text))) return undefined;\n\tconst tokenBudget = parseRequestedTokenBudget(text);\n\treturn tokenBudget === undefined ? {} : { tokenBudget };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/core/tools/bash.ts"],"names":[],"mappings":"AAIA,OAAO,EAIN,KAAK,gBAAgB,EACrB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAIjE,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAc5C,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,wBAAwB,CAAC;AACtF,OAAO,EACN,KAAK,4BAA4B,EAIjC,MAAM,4BAA4B,CAAC;AAWpC,OAAO,EAGN,KAAK,4BAA4B,EACjC,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAsC,KAAK,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAK/G,qGAAqG;AACrG,eAAO,MAAM,+BAA+B,MAAM,CAAC;AACnD,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAKhD,kGAAkG;AAClG,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAExE;AAED,mGAAmG;AACnG,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAExE;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKhF;AAED,QAAA,MAAM,UAAU;;;;EAcd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,OAAO,CAAC,EAAE;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,gBAAgB,CAAC,EAAE,4BAA4B,CAAC;CAChD;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;;;OAMG;IACH,IAAI,EAAE,CACL,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;QACR,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QAC/B,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;KACxB,KACG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CAC1C;AA6FD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAE/G;AAED,gFAAgF;AAChF,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,cAAc,CAErH;AAED,kGAAkG;AAClG,wBAAgB,kCAAkC,CACjD,OAAO,GAAE;IACR,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yHAAyH;IACzH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uFAAuF;IACvF,aAAa,CAAC,EAAE,yBAAyB,CAAC;CACrC,EACN,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC1C,cAAc,CAuChB;AAED,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,gBAAgB,CAAC;AAO5E,MAAM,WAAW,eAAe;IAC/B,qGAAqG;IACrG,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B,oFAAoF;IACpF,wBAAwB,CAAC,EAAE,4BAA4B,CAAC;IACxD,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yHAAyH;IACzH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,uFAAuF;IACvF,yBAAyB,CAAC,EAAE,yBAAyB,CAAC;IACtD,4FAA4F;IAC5F,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAoiBD,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,eAAe,GACvB,cAAc,CAAC,OAAO,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC,CAGhE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAEnG"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/core/tools/bash.ts"],"names":[],"mappings":"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"}