@a5c-ai/agent-runtime 5.0.1-staging.04ca6ab00d21

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 (170) hide show
  1. package/README.md +23 -0
  2. package/dist/apiResult.d.ts +19 -0
  3. package/dist/apiResult.d.ts.map +1 -0
  4. package/dist/apiResult.js +16 -0
  5. package/dist/background/state.d.ts +14 -0
  6. package/dist/background/state.d.ts.map +1 -0
  7. package/dist/background/state.js +25 -0
  8. package/dist/backgroundProcessRegistry.d.ts +66 -0
  9. package/dist/backgroundProcessRegistry.d.ts.map +1 -0
  10. package/dist/backgroundProcessRegistry.js +202 -0
  11. package/dist/cost/claudeCodeParser.d.ts +81 -0
  12. package/dist/cost/claudeCodeParser.d.ts.map +1 -0
  13. package/dist/cost/claudeCodeParser.js +232 -0
  14. package/dist/cost/collector.d.ts +42 -0
  15. package/dist/cost/collector.d.ts.map +1 -0
  16. package/dist/cost/collector.js +105 -0
  17. package/dist/cost/effectCost.d.ts +23 -0
  18. package/dist/cost/effectCost.d.ts.map +1 -0
  19. package/dist/cost/effectCost.js +26 -0
  20. package/dist/cost/index.d.ts +19 -0
  21. package/dist/cost/index.d.ts.map +1 -0
  22. package/dist/cost/index.js +39 -0
  23. package/dist/cost/journal.d.ts +40 -0
  24. package/dist/cost/journal.d.ts.map +1 -0
  25. package/dist/cost/journal.js +137 -0
  26. package/dist/cost/types.d.ts +164 -0
  27. package/dist/cost/types.d.ts.map +1 -0
  28. package/dist/cost/types.js +228 -0
  29. package/dist/daemon/automationExecutor.d.ts +16 -0
  30. package/dist/daemon/automationExecutor.d.ts.map +1 -0
  31. package/dist/daemon/automationExecutor.js +222 -0
  32. package/dist/daemon/config.d.ts +8 -0
  33. package/dist/daemon/config.d.ts.map +1 -0
  34. package/dist/daemon/config.js +209 -0
  35. package/dist/daemon/daemonLog.d.ts +13 -0
  36. package/dist/daemon/daemonLog.d.ts.map +1 -0
  37. package/dist/daemon/daemonLog.js +64 -0
  38. package/dist/daemon/fileWatcher.d.ts +9 -0
  39. package/dist/daemon/fileWatcher.d.ts.map +1 -0
  40. package/dist/daemon/fileWatcher.js +141 -0
  41. package/dist/daemon/index.d.ts +13 -0
  42. package/dist/daemon/index.d.ts.map +1 -0
  43. package/dist/daemon/index.js +22 -0
  44. package/dist/daemon/lifecycle.d.ts +12 -0
  45. package/dist/daemon/lifecycle.d.ts.map +1 -0
  46. package/dist/daemon/lifecycle.js +257 -0
  47. package/dist/daemon/loop.d.ts +21 -0
  48. package/dist/daemon/loop.d.ts.map +1 -0
  49. package/dist/daemon/loop.js +196 -0
  50. package/dist/daemon/timerScheduler.d.ts +13 -0
  51. package/dist/daemon/timerScheduler.d.ts.map +1 -0
  52. package/dist/daemon/timerScheduler.js +122 -0
  53. package/dist/daemon/types.d.ts +93 -0
  54. package/dist/daemon/types.d.ts.map +1 -0
  55. package/dist/daemon/types.js +25 -0
  56. package/dist/daemon/webhookListener.d.ts +6 -0
  57. package/dist/daemon/webhookListener.d.ts.map +1 -0
  58. package/dist/daemon/webhookListener.js +110 -0
  59. package/dist/execution/index.d.ts +8 -0
  60. package/dist/execution/index.d.ts.map +1 -0
  61. package/dist/execution/index.js +12 -0
  62. package/dist/execution/modes/docker.d.ts +21 -0
  63. package/dist/execution/modes/docker.d.ts.map +1 -0
  64. package/dist/execution/modes/docker.js +125 -0
  65. package/dist/execution/modes/index.d.ts +10 -0
  66. package/dist/execution/modes/index.d.ts.map +1 -0
  67. package/dist/execution/modes/index.js +14 -0
  68. package/dist/execution/modes/kubernetes.d.ts +29 -0
  69. package/dist/execution/modes/kubernetes.d.ts.map +1 -0
  70. package/dist/execution/modes/kubernetes.js +121 -0
  71. package/dist/execution/modes/local.d.ts +23 -0
  72. package/dist/execution/modes/local.d.ts.map +1 -0
  73. package/dist/execution/modes/local.js +102 -0
  74. package/dist/execution/modes/ssh.d.ts +23 -0
  75. package/dist/execution/modes/ssh.d.ts.map +1 -0
  76. package/dist/execution/modes/ssh.js +134 -0
  77. package/dist/execution/provider.d.ts +32 -0
  78. package/dist/execution/provider.d.ts.map +1 -0
  79. package/dist/execution/provider.js +90 -0
  80. package/dist/execution/types.d.ts +105 -0
  81. package/dist/execution/types.d.ts.map +1 -0
  82. package/dist/execution/types.js +9 -0
  83. package/dist/index.d.ts +11 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +42 -0
  86. package/dist/observability/health.d.ts +19 -0
  87. package/dist/observability/health.d.ts.map +1 -0
  88. package/dist/observability/health.js +129 -0
  89. package/dist/observability/index.d.ts +6 -0
  90. package/dist/observability/index.d.ts.map +1 -0
  91. package/dist/observability/index.js +20 -0
  92. package/dist/observability/runStatus.d.ts +44 -0
  93. package/dist/observability/runStatus.d.ts.map +1 -0
  94. package/dist/observability/runStatus.js +169 -0
  95. package/dist/observability/timeline.d.ts +11 -0
  96. package/dist/observability/timeline.d.ts.map +1 -0
  97. package/dist/observability/timeline.js +176 -0
  98. package/dist/observability/types.d.ts +62 -0
  99. package/dist/observability/types.d.ts.map +1 -0
  100. package/dist/observability/types.js +8 -0
  101. package/dist/observability/webhooks.d.ts +68 -0
  102. package/dist/observability/webhooks.d.ts.map +1 -0
  103. package/dist/observability/webhooks.js +132 -0
  104. package/dist/resources/budget-tracker.d.ts +56 -0
  105. package/dist/resources/budget-tracker.d.ts.map +1 -0
  106. package/dist/resources/budget-tracker.js +131 -0
  107. package/dist/resources/concurrency-guard.d.ts +55 -0
  108. package/dist/resources/concurrency-guard.d.ts.map +1 -0
  109. package/dist/resources/concurrency-guard.js +132 -0
  110. package/dist/resources/index.d.ts +12 -0
  111. package/dist/resources/index.d.ts.map +1 -0
  112. package/dist/resources/index.js +20 -0
  113. package/dist/resources/manager.d.ts +49 -0
  114. package/dist/resources/manager.d.ts.map +1 -0
  115. package/dist/resources/manager.js +111 -0
  116. package/dist/resources/timeout-cascade.d.ts +56 -0
  117. package/dist/resources/timeout-cascade.d.ts.map +1 -0
  118. package/dist/resources/timeout-cascade.js +145 -0
  119. package/dist/resources/types.d.ts +108 -0
  120. package/dist/resources/types.d.ts.map +1 -0
  121. package/dist/resources/types.js +9 -0
  122. package/dist/session/context.d.ts +22 -0
  123. package/dist/session/context.d.ts.map +1 -0
  124. package/dist/session/context.js +113 -0
  125. package/dist/session/continuityState.d.ts +39 -0
  126. package/dist/session/continuityState.d.ts.map +1 -0
  127. package/dist/session/continuityState.js +164 -0
  128. package/dist/session/cost.d.ts +63 -0
  129. package/dist/session/cost.d.ts.map +1 -0
  130. package/dist/session/cost.js +194 -0
  131. package/dist/session/discovery.d.ts +22 -0
  132. package/dist/session/discovery.d.ts.map +1 -0
  133. package/dist/session/discovery.js +35 -0
  134. package/dist/session/history.d.ts +30 -0
  135. package/dist/session/history.d.ts.map +1 -0
  136. package/dist/session/history.js +143 -0
  137. package/dist/session/index.d.ts +20 -0
  138. package/dist/session/index.d.ts.map +1 -0
  139. package/dist/session/index.js +78 -0
  140. package/dist/session/memoryExtraction.d.ts +65 -0
  141. package/dist/session/memoryExtraction.d.ts.map +1 -0
  142. package/dist/session/memoryExtraction.js +201 -0
  143. package/dist/session/parse.d.ts +45 -0
  144. package/dist/session/parse.d.ts.map +1 -0
  145. package/dist/session/parse.js +170 -0
  146. package/dist/session/persistence.d.ts +46 -0
  147. package/dist/session/persistence.d.ts.map +1 -0
  148. package/dist/session/persistence.js +180 -0
  149. package/dist/session/types.d.ts +267 -0
  150. package/dist/session/types.d.ts.map +1 -0
  151. package/dist/session/types.js +45 -0
  152. package/dist/session/write.d.ts +61 -0
  153. package/dist/session/write.d.ts.map +1 -0
  154. package/dist/session/write.js +213 -0
  155. package/dist/telemetry/audit-log.d.ts +56 -0
  156. package/dist/telemetry/audit-log.d.ts.map +1 -0
  157. package/dist/telemetry/audit-log.js +59 -0
  158. package/dist/telemetry/index.d.ts +9 -0
  159. package/dist/telemetry/index.d.ts.map +1 -0
  160. package/dist/telemetry/index.js +15 -0
  161. package/dist/telemetry/provider.d.ts +39 -0
  162. package/dist/telemetry/provider.d.ts.map +1 -0
  163. package/dist/telemetry/provider.js +91 -0
  164. package/dist/telemetry/span-tree.d.ts +46 -0
  165. package/dist/telemetry/span-tree.d.ts.map +1 -0
  166. package/dist/telemetry/span-tree.js +93 -0
  167. package/dist/telemetry/types.d.ts +85 -0
  168. package/dist/telemetry/types.d.ts.map +1 -0
  169. package/dist/telemetry/types.js +21 -0
  170. package/package.json +90 -0
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ /**
3
+ * GAP-PERF-008: Structured Continuity State.
4
+ *
5
+ * Structured state that persists across session compaction. Captures
6
+ * key decisions, current phase, and working context for seamless
7
+ * resume after context compression.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.CONTINUITY_STATE_SCHEMA_VERSION = void 0;
44
+ exports.getContinuityStatePath = getContinuityStatePath;
45
+ exports.getContinuityState = getContinuityState;
46
+ exports.setCurrentPhase = setCurrentPhase;
47
+ exports.upsertDecision = upsertDecision;
48
+ exports.updateWorkingContext = updateWorkingContext;
49
+ exports.buildContinuityResumePrompt = buildContinuityResumePrompt;
50
+ const fs = __importStar(require("node:fs/promises"));
51
+ const path = __importStar(require("node:path"));
52
+ // ---------------------------------------------------------------------------
53
+ // Constants
54
+ // ---------------------------------------------------------------------------
55
+ exports.CONTINUITY_STATE_SCHEMA_VERSION = "2026.01.continuity-state-v1";
56
+ // ---------------------------------------------------------------------------
57
+ // Internal helpers
58
+ // ---------------------------------------------------------------------------
59
+ function emptyContinuityState() {
60
+ return {
61
+ schemaVersion: exports.CONTINUITY_STATE_SCHEMA_VERSION,
62
+ updatedAt: new Date().toISOString(),
63
+ currentPhase: null,
64
+ decisions: [],
65
+ workingContext: { focus: "", blockers: [], nextSteps: [] },
66
+ };
67
+ }
68
+ async function readRaw(filePath) {
69
+ let raw;
70
+ try {
71
+ raw = await fs.readFile(filePath, "utf8");
72
+ }
73
+ catch {
74
+ return emptyContinuityState();
75
+ }
76
+ try {
77
+ const data = JSON.parse(raw);
78
+ return {
79
+ schemaVersion: typeof data.schemaVersion === "string" ? data.schemaVersion : exports.CONTINUITY_STATE_SCHEMA_VERSION,
80
+ updatedAt: typeof data.updatedAt === "string" ? data.updatedAt : new Date().toISOString(),
81
+ currentPhase: data.currentPhase ?? null,
82
+ decisions: Array.isArray(data.decisions) ? data.decisions : [],
83
+ workingContext: data.workingContext ?? { focus: "", blockers: [], nextSteps: [] },
84
+ };
85
+ }
86
+ catch {
87
+ return emptyContinuityState();
88
+ }
89
+ }
90
+ async function writeRaw(filePath, data) {
91
+ const dir = path.dirname(filePath);
92
+ const tempPath = `${filePath}.tmp.${process.pid}`;
93
+ await fs.mkdir(dir, { recursive: true });
94
+ await fs.writeFile(tempPath, JSON.stringify(data, null, 2), "utf8");
95
+ await fs.rename(tempPath, filePath);
96
+ }
97
+ // ---------------------------------------------------------------------------
98
+ // Public API
99
+ // ---------------------------------------------------------------------------
100
+ function getContinuityStatePath(stateDir, sessionId) {
101
+ return path.join(stateDir, `${sessionId}.continuity.json`);
102
+ }
103
+ async function getContinuityState(stateDir, sessionId) {
104
+ return readRaw(getContinuityStatePath(stateDir, sessionId));
105
+ }
106
+ async function setCurrentPhase(stateDir, sessionId, phase) {
107
+ const filePath = getContinuityStatePath(stateDir, sessionId);
108
+ const state = await readRaw(filePath);
109
+ state.currentPhase = { ...phase, startedAt: new Date().toISOString() };
110
+ state.updatedAt = new Date().toISOString();
111
+ await writeRaw(filePath, state);
112
+ }
113
+ async function upsertDecision(stateDir, sessionId, decision) {
114
+ const filePath = getContinuityStatePath(stateDir, sessionId);
115
+ const state = await readRaw(filePath);
116
+ const existing = state.decisions.findIndex((d) => d.key === decision.key);
117
+ const entry = { ...decision, madeAt: new Date().toISOString() };
118
+ if (existing >= 0) {
119
+ state.decisions[existing] = entry;
120
+ }
121
+ else {
122
+ state.decisions.push(entry);
123
+ }
124
+ state.updatedAt = new Date().toISOString();
125
+ await writeRaw(filePath, state);
126
+ }
127
+ async function updateWorkingContext(stateDir, sessionId, updates) {
128
+ const filePath = getContinuityStatePath(stateDir, sessionId);
129
+ const state = await readRaw(filePath);
130
+ if (updates.focus !== undefined)
131
+ state.workingContext.focus = updates.focus;
132
+ if (updates.blockers !== undefined)
133
+ state.workingContext.blockers = updates.blockers;
134
+ if (updates.nextSteps !== undefined)
135
+ state.workingContext.nextSteps = updates.nextSteps;
136
+ state.updatedAt = new Date().toISOString();
137
+ await writeRaw(filePath, state);
138
+ }
139
+ async function buildContinuityResumePrompt(stateDir, sessionId) {
140
+ const state = await getContinuityState(stateDir, sessionId);
141
+ const sections = [];
142
+ if (state.currentPhase) {
143
+ sections.push(`## Current Phase: ${state.currentPhase.name}\n${state.currentPhase.description}`);
144
+ }
145
+ if (state.decisions.length > 0) {
146
+ const items = state.decisions.map((d) => {
147
+ const rationale = d.rationale ? ` (${d.rationale})` : "";
148
+ return `- **${d.key}**: ${d.value}${rationale}`;
149
+ });
150
+ sections.push(`## Key Decisions\n${items.join("\n")}`);
151
+ }
152
+ const wc = state.workingContext;
153
+ if (wc.focus || wc.blockers.length > 0 || wc.nextSteps.length > 0) {
154
+ const parts = [];
155
+ if (wc.focus)
156
+ parts.push(`**Focus**: ${wc.focus}`);
157
+ if (wc.blockers.length > 0)
158
+ parts.push(`**Blockers**: ${wc.blockers.join(", ")}`);
159
+ if (wc.nextSteps.length > 0)
160
+ parts.push(`**Next Steps**: ${wc.nextSteps.join(", ")}`);
161
+ sections.push(`## Working Context\n${parts.join("\n")}`);
162
+ }
163
+ return sections.length > 0 ? sections.join("\n\n") : "";
164
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * GAP-SESSION-004: Session-Level Cost Tracking and Budgets.
3
+ *
4
+ * Aggregates cost data from runs within a session. Supports configurable
5
+ * budgets with threshold alerts and auto-pause.
6
+ * Uses the same atomic temp-file + rename pattern as context.ts.
7
+ */
8
+ export interface SessionBudget {
9
+ /** Maximum cost in USD. 0 = unlimited. */
10
+ maxCostUsd: number;
11
+ /** Alert threshold percentages (default: [50, 80, 100]). */
12
+ alertThresholds: number[];
13
+ /** Whether to auto-pause orchestration when budget exceeded. */
14
+ autoPause: boolean;
15
+ }
16
+ export interface SessionCostState {
17
+ totalCostUsd: number;
18
+ totalInputTokens: number;
19
+ totalOutputTokens: number;
20
+ runCosts: Array<{
21
+ runId: string;
22
+ costUsd: number;
23
+ inputTokens: number;
24
+ outputTokens: number;
25
+ }>;
26
+ budget?: SessionBudget;
27
+ triggeredThresholds: number[];
28
+ paused: boolean;
29
+ lastUpdatedAt: string;
30
+ }
31
+ export interface SessionBudgetAlert {
32
+ thresholdPct: number;
33
+ currentCostUsd: number;
34
+ budgetUsd: number;
35
+ currentPct: number;
36
+ message: string;
37
+ }
38
+ export interface BudgetCheckResult {
39
+ exceeded: boolean;
40
+ alerts: SessionBudgetAlert[];
41
+ shouldPause: boolean;
42
+ }
43
+ export interface RunCostUpdate {
44
+ runId: string;
45
+ costUsd: number;
46
+ inputTokens: number;
47
+ outputTokens: number;
48
+ }
49
+ export declare function getSessionCostPath(stateDir: string, sessionId: string): string;
50
+ export declare function getSessionCost(stateDir: string, sessionId: string): Promise<SessionCostState>;
51
+ export declare function updateSessionCost(stateDir: string, sessionId: string, update: RunCostUpdate): Promise<SessionCostState>;
52
+ export declare function setSessionBudget(stateDir: string, sessionId: string, budget: SessionBudget): Promise<SessionCostState>;
53
+ /**
54
+ * Pure function: evaluate budget thresholds against current cost.
55
+ * Returns new alerts (excluding already-triggered thresholds).
56
+ */
57
+ export declare function checkBudget(costState: SessionCostState): BudgetCheckResult;
58
+ /**
59
+ * Persist triggered thresholds back to cost state after checkBudget produces alerts.
60
+ * Call this after processing alerts to prevent re-triggering.
61
+ */
62
+ export declare function markThresholdsTriggered(stateDir: string, sessionId: string, thresholds: number[]): Promise<void>;
63
+ //# sourceMappingURL=cost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../../src/session/cost.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,MAAM,WAAW,aAAa;IAC5B,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gEAAgE;IAChE,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/F,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAwDD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAEnG;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,gBAAgB,CAAC,CAiC3B;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,gBAAgB,CAAC,CAO3B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,gBAAgB,GAAG,iBAAiB,CA2B1E;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -0,0 +1,194 @@
1
+ "use strict";
2
+ /**
3
+ * GAP-SESSION-004: Session-Level Cost Tracking and Budgets.
4
+ *
5
+ * Aggregates cost data from runs within a session. Supports configurable
6
+ * budgets with threshold alerts and auto-pause.
7
+ * Uses the same atomic temp-file + rename pattern as context.ts.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.getSessionCostPath = getSessionCostPath;
44
+ exports.getSessionCost = getSessionCost;
45
+ exports.updateSessionCost = updateSessionCost;
46
+ exports.setSessionBudget = setSessionBudget;
47
+ exports.checkBudget = checkBudget;
48
+ exports.markThresholdsTriggered = markThresholdsTriggered;
49
+ const node_fs_1 = require("node:fs");
50
+ const path = __importStar(require("node:path"));
51
+ // ---------------------------------------------------------------------------
52
+ // Internal helpers
53
+ // ---------------------------------------------------------------------------
54
+ function emptyCostState() {
55
+ return {
56
+ totalCostUsd: 0,
57
+ totalInputTokens: 0,
58
+ totalOutputTokens: 0,
59
+ runCosts: [],
60
+ triggeredThresholds: [],
61
+ paused: false,
62
+ lastUpdatedAt: new Date().toISOString(),
63
+ };
64
+ }
65
+ async function readRaw(filePath) {
66
+ let raw;
67
+ try {
68
+ raw = await node_fs_1.promises.readFile(filePath, "utf8");
69
+ }
70
+ catch (error) {
71
+ const err = error;
72
+ if (err.code === "ENOENT")
73
+ return emptyCostState();
74
+ return emptyCostState();
75
+ }
76
+ try {
77
+ const data = JSON.parse(raw);
78
+ return {
79
+ totalCostUsd: typeof data.totalCostUsd === "number" ? data.totalCostUsd : 0,
80
+ totalInputTokens: typeof data.totalInputTokens === "number" ? data.totalInputTokens : 0,
81
+ totalOutputTokens: typeof data.totalOutputTokens === "number" ? data.totalOutputTokens : 0,
82
+ runCosts: Array.isArray(data.runCosts) ? data.runCosts : [],
83
+ budget: data.budget,
84
+ triggeredThresholds: Array.isArray(data.triggeredThresholds) ? data.triggeredThresholds : [],
85
+ paused: typeof data.paused === "boolean" ? data.paused : false,
86
+ lastUpdatedAt: typeof data.lastUpdatedAt === "string" ? data.lastUpdatedAt : new Date().toISOString(),
87
+ };
88
+ }
89
+ catch {
90
+ return emptyCostState();
91
+ }
92
+ }
93
+ async function writeRaw(filePath, data) {
94
+ const dir = path.dirname(filePath);
95
+ const tempPath = `${filePath}.tmp.${process.pid}`;
96
+ await node_fs_1.promises.mkdir(dir, { recursive: true });
97
+ await node_fs_1.promises.writeFile(tempPath, JSON.stringify(data, null, 2), "utf8");
98
+ await node_fs_1.promises.rename(tempPath, filePath);
99
+ }
100
+ // ---------------------------------------------------------------------------
101
+ // Public API
102
+ // ---------------------------------------------------------------------------
103
+ function getSessionCostPath(stateDir, sessionId) {
104
+ return path.join(stateDir, `${sessionId}.cost.json`);
105
+ }
106
+ async function getSessionCost(stateDir, sessionId) {
107
+ return readRaw(getSessionCostPath(stateDir, sessionId));
108
+ }
109
+ async function updateSessionCost(stateDir, sessionId, update) {
110
+ const filePath = getSessionCostPath(stateDir, sessionId);
111
+ const data = await readRaw(filePath);
112
+ // Check for duplicate run cost entry and update or add
113
+ const existingIdx = data.runCosts.findIndex((r) => r.runId === update.runId);
114
+ if (existingIdx >= 0) {
115
+ // Update existing entry (re-aggregation): subtract old, add new
116
+ const old = data.runCosts[existingIdx];
117
+ data.totalCostUsd += update.costUsd - old.costUsd;
118
+ data.totalInputTokens += update.inputTokens - old.inputTokens;
119
+ data.totalOutputTokens += update.outputTokens - old.outputTokens;
120
+ data.runCosts[existingIdx] = {
121
+ runId: update.runId,
122
+ costUsd: update.costUsd,
123
+ inputTokens: update.inputTokens,
124
+ outputTokens: update.outputTokens,
125
+ };
126
+ }
127
+ else {
128
+ data.totalCostUsd += update.costUsd;
129
+ data.totalInputTokens += update.inputTokens;
130
+ data.totalOutputTokens += update.outputTokens;
131
+ data.runCosts.push({
132
+ runId: update.runId,
133
+ costUsd: update.costUsd,
134
+ inputTokens: update.inputTokens,
135
+ outputTokens: update.outputTokens,
136
+ });
137
+ }
138
+ data.lastUpdatedAt = new Date().toISOString();
139
+ await writeRaw(filePath, data);
140
+ return data;
141
+ }
142
+ async function setSessionBudget(stateDir, sessionId, budget) {
143
+ const filePath = getSessionCostPath(stateDir, sessionId);
144
+ const data = await readRaw(filePath);
145
+ data.budget = budget;
146
+ data.lastUpdatedAt = new Date().toISOString();
147
+ await writeRaw(filePath, data);
148
+ return data;
149
+ }
150
+ /**
151
+ * Pure function: evaluate budget thresholds against current cost.
152
+ * Returns new alerts (excluding already-triggered thresholds).
153
+ */
154
+ function checkBudget(costState) {
155
+ if (!costState.budget || costState.budget.maxCostUsd <= 0) {
156
+ return { exceeded: false, alerts: [], shouldPause: false };
157
+ }
158
+ const { maxCostUsd, alertThresholds, autoPause } = costState.budget;
159
+ const currentPct = (costState.totalCostUsd / maxCostUsd) * 100;
160
+ const exceeded = currentPct >= 100;
161
+ const alerts = [];
162
+ for (const threshold of alertThresholds) {
163
+ if (currentPct >= threshold && !costState.triggeredThresholds.includes(threshold)) {
164
+ alerts.push({
165
+ thresholdPct: threshold,
166
+ currentCostUsd: costState.totalCostUsd,
167
+ budgetUsd: maxCostUsd,
168
+ currentPct,
169
+ message: `Session cost ${currentPct.toFixed(1)}% of budget ($${costState.totalCostUsd.toFixed(4)} / $${maxCostUsd.toFixed(2)})`,
170
+ });
171
+ }
172
+ }
173
+ return {
174
+ exceeded,
175
+ alerts,
176
+ shouldPause: exceeded && autoPause,
177
+ };
178
+ }
179
+ /**
180
+ * Persist triggered thresholds back to cost state after checkBudget produces alerts.
181
+ * Call this after processing alerts to prevent re-triggering.
182
+ */
183
+ async function markThresholdsTriggered(stateDir, sessionId, thresholds) {
184
+ if (thresholds.length === 0)
185
+ return;
186
+ const filePath = getSessionCostPath(stateDir, sessionId);
187
+ const data = await readRaw(filePath);
188
+ const existing = new Set(data.triggeredThresholds);
189
+ for (const t of thresholds)
190
+ existing.add(t);
191
+ data.triggeredThresholds = [...existing];
192
+ data.lastUpdatedAt = new Date().toISOString();
193
+ await writeRaw(filePath, data);
194
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Mapping of harness identifiers to their native session environment variables.
3
+ *
4
+ * Only Pi-specific env vars are kept here. External harness session discovery
5
+ * is handled by agent-mux session management.
6
+ */
7
+ export declare const HARNESS_ENV_VARS: Record<string, string[]>;
8
+ /**
9
+ * Resolve the current session ID from the ambient environment (markers + env vars).
10
+ *
11
+ * This is used for "autodiscovery" in contexts where no explicit session ID
12
+ * was provided (e.g. journaling low-level events).
13
+ *
14
+ * Precedence:
15
+ * 1. Harness-native env vars (Pi / oh-my-pi)
16
+ * 2. AGENT_SESSION_ID
17
+ * 3. PID-scoped marker for the given harness (fallback only)
18
+ *
19
+ * External harness session discovery is delegated to agent-mux.
20
+ */
21
+ export declare function resolveAmbientSessionId(harness?: string): string | undefined;
22
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/session/discovery.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAGrD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO5E"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HARNESS_ENV_VARS = void 0;
4
+ exports.resolveAmbientSessionId = resolveAmbientSessionId;
5
+ const babysitter_sdk_1 = require("@a5c-ai/babysitter-sdk");
6
+ /**
7
+ * Mapping of harness identifiers to their native session environment variables.
8
+ *
9
+ * Only Pi-specific env vars are kept here. External harness session discovery
10
+ * is handled by agent-mux session management.
11
+ */
12
+ exports.HARNESS_ENV_VARS = {
13
+ "pi": ["PI_SESSION_ID"],
14
+ "oh-my-pi": ["OMP_SESSION_ID"],
15
+ };
16
+ /**
17
+ * Resolve the current session ID from the ambient environment (markers + env vars).
18
+ *
19
+ * This is used for "autodiscovery" in contexts where no explicit session ID
20
+ * was provided (e.g. journaling low-level events).
21
+ *
22
+ * Precedence:
23
+ * 1. Harness-native env vars (Pi / oh-my-pi)
24
+ * 2. AGENT_SESSION_ID
25
+ * 3. PID-scoped marker for the given harness (fallback only)
26
+ *
27
+ * External harness session discovery is delegated to agent-mux.
28
+ */
29
+ function resolveAmbientSessionId(harness) {
30
+ if (!harness) {
31
+ return process.env.AGENT_SESSION_ID;
32
+ }
33
+ const envVars = exports.HARNESS_ENV_VARS[harness] || [];
34
+ return (0, babysitter_sdk_1.resolveSessionIdWithMarker)(harness, {}, envVars);
35
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Session history persistence for GAP-SESSION-002.
3
+ *
4
+ * Stores accumulated decisions, run summaries, and context snapshots
5
+ * in a dedicated <sessionId>.history.json file alongside the session state.
6
+ * Uses the same atomic temp-file + rename pattern as context.ts.
7
+ */
8
+ import type { SessionDecision, SessionRunSummary, SessionContextSnapshot, SessionHistory } from "./types";
9
+ /** Get the file path for a session's history JSON file. */
10
+ export declare function getSessionHistoryPath(stateDir: string, sessionId: string): string;
11
+ /**
12
+ * Append a decision to the session's history.
13
+ * Automatically adds a timestamp.
14
+ */
15
+ export declare function addDecision(stateDir: string, sessionId: string, decision: Omit<SessionDecision, "timestamp">): Promise<void>;
16
+ /**
17
+ * Append a run summary to the session's history.
18
+ */
19
+ export declare function addRunSummary(stateDir: string, sessionId: string, summary: SessionRunSummary): Promise<void>;
20
+ /**
21
+ * Save a context snapshot to the session's history.
22
+ * Automatically adds a timestamp.
23
+ */
24
+ export declare function saveContextSnapshot(stateDir: string, sessionId: string, snapshot: Omit<SessionContextSnapshot, "timestamp">): Promise<void>;
25
+ /**
26
+ * Get the full session history: SessionContext fields + history arrays.
27
+ * Returns empty defaults when files do not exist.
28
+ */
29
+ export declare function getSessionHistory(stateDir: string, sessionId: string): Promise<SessionHistory>;
30
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/session/history.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,EACf,MAAM,SAAS,CAAC;AAOjB,2DAA2D;AAC3D,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjF;AAuDD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC,GAC3C,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,IAAI,CAAC,sBAAsB,EAAE,WAAW,CAAC,GAClD,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CAazB"}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ /**
3
+ * Session history persistence for GAP-SESSION-002.
4
+ *
5
+ * Stores accumulated decisions, run summaries, and context snapshots
6
+ * in a dedicated <sessionId>.history.json file alongside the session state.
7
+ * Uses the same atomic temp-file + rename pattern as context.ts.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.getSessionHistoryPath = getSessionHistoryPath;
44
+ exports.addDecision = addDecision;
45
+ exports.addRunSummary = addRunSummary;
46
+ exports.saveContextSnapshot = saveContextSnapshot;
47
+ exports.getSessionHistory = getSessionHistory;
48
+ const node_fs_1 = require("node:fs");
49
+ const path = __importStar(require("node:path"));
50
+ const context_1 = require("./context");
51
+ // ---------------------------------------------------------------------------
52
+ // Path helper
53
+ // ---------------------------------------------------------------------------
54
+ /** Get the file path for a session's history JSON file. */
55
+ function getSessionHistoryPath(stateDir, sessionId) {
56
+ return path.join(stateDir, `${sessionId}.history.json`);
57
+ }
58
+ function emptyHistoryData() {
59
+ return { decisions: [], runSummaries: [], contextSnapshots: [] };
60
+ }
61
+ async function readRawHistory(filePath) {
62
+ let raw;
63
+ try {
64
+ raw = await node_fs_1.promises.readFile(filePath, "utf8");
65
+ }
66
+ catch (error) {
67
+ const err = error;
68
+ if (err.code === "ENOENT") {
69
+ return emptyHistoryData();
70
+ }
71
+ return emptyHistoryData();
72
+ }
73
+ try {
74
+ const data = JSON.parse(raw);
75
+ return {
76
+ decisions: Array.isArray(data.decisions) ? data.decisions : [],
77
+ runSummaries: Array.isArray(data.runSummaries) ? data.runSummaries : [],
78
+ contextSnapshots: Array.isArray(data.contextSnapshots) ? data.contextSnapshots : [],
79
+ };
80
+ }
81
+ catch {
82
+ return emptyHistoryData();
83
+ }
84
+ }
85
+ async function writeRawHistory(filePath, data) {
86
+ const dir = path.dirname(filePath);
87
+ const tempPath = `${filePath}.tmp.${process.pid}`;
88
+ await node_fs_1.promises.mkdir(dir, { recursive: true });
89
+ await node_fs_1.promises.writeFile(tempPath, JSON.stringify(data, null, 2), "utf8");
90
+ await node_fs_1.promises.rename(tempPath, filePath);
91
+ }
92
+ function nowTimestamp() {
93
+ return new Date().toISOString();
94
+ }
95
+ // ---------------------------------------------------------------------------
96
+ // Public API
97
+ // ---------------------------------------------------------------------------
98
+ /**
99
+ * Append a decision to the session's history.
100
+ * Automatically adds a timestamp.
101
+ */
102
+ async function addDecision(stateDir, sessionId, decision) {
103
+ const filePath = getSessionHistoryPath(stateDir, sessionId);
104
+ const data = await readRawHistory(filePath);
105
+ data.decisions.push({ ...decision, timestamp: nowTimestamp() });
106
+ await writeRawHistory(filePath, data);
107
+ }
108
+ /**
109
+ * Append a run summary to the session's history.
110
+ */
111
+ async function addRunSummary(stateDir, sessionId, summary) {
112
+ const filePath = getSessionHistoryPath(stateDir, sessionId);
113
+ const data = await readRawHistory(filePath);
114
+ data.runSummaries.push(summary);
115
+ await writeRawHistory(filePath, data);
116
+ }
117
+ /**
118
+ * Save a context snapshot to the session's history.
119
+ * Automatically adds a timestamp.
120
+ */
121
+ async function saveContextSnapshot(stateDir, sessionId, snapshot) {
122
+ const filePath = getSessionHistoryPath(stateDir, sessionId);
123
+ const data = await readRawHistory(filePath);
124
+ data.contextSnapshots.push({ ...snapshot, timestamp: nowTimestamp() });
125
+ await writeRawHistory(filePath, data);
126
+ }
127
+ /**
128
+ * Get the full session history: SessionContext fields + history arrays.
129
+ * Returns empty defaults when files do not exist.
130
+ */
131
+ async function getSessionHistory(stateDir, sessionId) {
132
+ const [context, rawHistory] = await Promise.all([
133
+ (0, context_1.getSessionContext)(stateDir, sessionId),
134
+ readRawHistory(getSessionHistoryPath(stateDir, sessionId)),
135
+ ]);
136
+ return {
137
+ notes: context.notes,
138
+ sharedKnowledge: context.sharedKnowledge,
139
+ decisions: rawHistory.decisions,
140
+ runSummaries: rawHistory.runSummaries,
141
+ contextSnapshots: rawHistory.contextSnapshots,
142
+ };
143
+ }