@corenel/harness 0.10.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/dist/approvals/decisionLog.d.ts +21 -0
  2. package/dist/approvals/decisionLog.d.ts.map +1 -0
  3. package/dist/approvals/decisionLog.js +129 -0
  4. package/dist/approvals/decisionLog.js.map +1 -0
  5. package/dist/approvals/hooks.d.ts +18 -0
  6. package/dist/approvals/hooks.d.ts.map +1 -0
  7. package/dist/approvals/hooks.js +34 -0
  8. package/dist/approvals/hooks.js.map +1 -0
  9. package/dist/approvals/index.d.ts +10 -0
  10. package/dist/approvals/index.d.ts.map +1 -0
  11. package/dist/approvals/index.js +10 -0
  12. package/dist/approvals/index.js.map +1 -0
  13. package/dist/approvals/service.d.ts +46 -0
  14. package/dist/approvals/service.d.ts.map +1 -0
  15. package/dist/approvals/service.js +181 -0
  16. package/dist/approvals/service.js.map +1 -0
  17. package/dist/approvals/settings.d.ts +20 -0
  18. package/dist/approvals/settings.d.ts.map +1 -0
  19. package/dist/approvals/settings.js +32 -0
  20. package/dist/approvals/settings.js.map +1 -0
  21. package/dist/approvals/shellTools.d.ts +10 -0
  22. package/dist/approvals/shellTools.d.ts.map +1 -0
  23. package/dist/approvals/shellTools.js +17 -0
  24. package/dist/approvals/shellTools.js.map +1 -0
  25. package/dist/approvals/standingStore.d.ts +15 -0
  26. package/dist/approvals/standingStore.d.ts.map +1 -0
  27. package/dist/approvals/standingStore.js +50 -0
  28. package/dist/approvals/standingStore.js.map +1 -0
  29. package/dist/approvals/suggest.d.ts +15 -0
  30. package/dist/approvals/suggest.d.ts.map +1 -0
  31. package/dist/approvals/suggest.js +23 -0
  32. package/dist/approvals/suggest.js.map +1 -0
  33. package/dist/approvals/summarize.d.ts +7 -0
  34. package/dist/approvals/summarize.d.ts.map +1 -0
  35. package/dist/approvals/summarize.js +70 -0
  36. package/dist/approvals/summarize.js.map +1 -0
  37. package/dist/approvals/testTextStore.d.ts +6 -0
  38. package/dist/approvals/testTextStore.d.ts.map +1 -0
  39. package/dist/approvals/testTextStore.js +11 -0
  40. package/dist/approvals/testTextStore.js.map +1 -0
  41. package/dist/approvals/textStore.d.ts +9 -0
  42. package/dist/approvals/textStore.d.ts.map +1 -0
  43. package/dist/approvals/textStore.js +2 -0
  44. package/dist/approvals/textStore.js.map +1 -0
  45. package/dist/audit/canonical.d.ts +5 -0
  46. package/dist/audit/canonical.d.ts.map +1 -0
  47. package/dist/audit/canonical.js +15 -0
  48. package/dist/audit/canonical.js.map +1 -0
  49. package/dist/audit/ids.d.ts +3 -0
  50. package/dist/audit/ids.d.ts.map +1 -0
  51. package/dist/audit/ids.js +11 -0
  52. package/dist/audit/ids.js.map +1 -0
  53. package/dist/audit/index.d.ts +7 -0
  54. package/dist/audit/index.d.ts.map +1 -0
  55. package/dist/audit/index.js +7 -0
  56. package/dist/audit/index.js.map +1 -0
  57. package/dist/audit/log.d.ts +64 -0
  58. package/dist/audit/log.d.ts.map +1 -0
  59. package/dist/audit/log.js +457 -0
  60. package/dist/audit/log.js.map +1 -0
  61. package/dist/audit/recorder.d.ts +31 -0
  62. package/dist/audit/recorder.d.ts.map +1 -0
  63. package/dist/audit/recorder.js +185 -0
  64. package/dist/audit/recorder.js.map +1 -0
  65. package/dist/audit/runAudit.d.ts +38 -0
  66. package/dist/audit/runAudit.d.ts.map +1 -0
  67. package/dist/audit/runAudit.js +99 -0
  68. package/dist/audit/runAudit.js.map +1 -0
  69. package/dist/audit/verify.d.ts +14 -0
  70. package/dist/audit/verify.d.ts.map +1 -0
  71. package/dist/audit/verify.js +47 -0
  72. package/dist/audit/verify.js.map +1 -0
  73. package/dist/conversation.d.ts +31 -0
  74. package/dist/conversation.d.ts.map +1 -1
  75. package/dist/conversation.js +33 -0
  76. package/dist/conversation.js.map +1 -1
  77. package/dist/core/hash.d.ts +2 -0
  78. package/dist/core/hash.d.ts.map +1 -0
  79. package/dist/core/hash.js +9 -0
  80. package/dist/core/hash.js.map +1 -0
  81. package/dist/core/loop.d.ts +18 -0
  82. package/dist/core/loop.d.ts.map +1 -1
  83. package/dist/core/loop.js +67 -6
  84. package/dist/core/loop.js.map +1 -1
  85. package/dist/core/spawn.d.ts +59 -4
  86. package/dist/core/spawn.d.ts.map +1 -1
  87. package/dist/core/spawn.js +83 -5
  88. package/dist/core/spawn.js.map +1 -1
  89. package/dist/core/turnVerify.d.ts +25 -0
  90. package/dist/core/turnVerify.d.ts.map +1 -0
  91. package/dist/core/turnVerify.js +177 -0
  92. package/dist/core/turnVerify.js.map +1 -0
  93. package/dist/dag/executeNode.d.ts +7 -0
  94. package/dist/dag/executeNode.d.ts.map +1 -1
  95. package/dist/dag/executeNode.js +3 -0
  96. package/dist/dag/executeNode.js.map +1 -1
  97. package/dist/guardrail/guardrail.d.ts +7 -0
  98. package/dist/guardrail/guardrail.d.ts.map +1 -1
  99. package/dist/guardrail/guardrail.js +8 -0
  100. package/dist/guardrail/guardrail.js.map +1 -1
  101. package/dist/guardrail/index.d.ts +2 -2
  102. package/dist/guardrail/index.d.ts.map +1 -1
  103. package/dist/guardrail/index.js +2 -2
  104. package/dist/guardrail/index.js.map +1 -1
  105. package/dist/guardrail/permission-service.d.ts +41 -6
  106. package/dist/guardrail/permission-service.d.ts.map +1 -1
  107. package/dist/guardrail/permission-service.js +118 -11
  108. package/dist/guardrail/permission-service.js.map +1 -1
  109. package/dist/guardrail/serialize.d.ts.map +1 -1
  110. package/dist/guardrail/serialize.js +2 -0
  111. package/dist/guardrail/serialize.js.map +1 -1
  112. package/dist/guardrail/validate.d.ts.map +1 -1
  113. package/dist/guardrail/validate.js +3 -1
  114. package/dist/guardrail/validate.js.map +1 -1
  115. package/dist/install/lockfile.d.ts +13 -5
  116. package/dist/install/lockfile.d.ts.map +1 -1
  117. package/dist/install/lockfile.js +31 -2
  118. package/dist/install/lockfile.js.map +1 -1
  119. package/dist/orchestrator/agentSearch.d.ts +15 -0
  120. package/dist/orchestrator/agentSearch.d.ts.map +1 -0
  121. package/dist/orchestrator/agentSearch.js +112 -0
  122. package/dist/orchestrator/agentSearch.js.map +1 -0
  123. package/dist/orchestrator/agentTags.d.ts +13 -0
  124. package/dist/orchestrator/agentTags.d.ts.map +1 -0
  125. package/dist/orchestrator/agentTags.js +48 -0
  126. package/dist/orchestrator/agentTags.js.map +1 -0
  127. package/dist/orchestrator/branch.d.ts +9 -0
  128. package/dist/orchestrator/branch.d.ts.map +1 -0
  129. package/dist/orchestrator/branch.js +26 -0
  130. package/dist/orchestrator/branch.js.map +1 -0
  131. package/dist/orchestrator/checks.d.ts +16 -0
  132. package/dist/orchestrator/checks.d.ts.map +1 -0
  133. package/dist/orchestrator/checks.js +66 -0
  134. package/dist/orchestrator/checks.js.map +1 -0
  135. package/dist/orchestrator/planDoc.d.ts +41 -0
  136. package/dist/orchestrator/planDoc.d.ts.map +1 -0
  137. package/dist/orchestrator/planDoc.js +181 -0
  138. package/dist/orchestrator/planDoc.js.map +1 -0
  139. package/dist/orchestrator/record.d.ts +110 -0
  140. package/dist/orchestrator/record.d.ts.map +1 -0
  141. package/dist/orchestrator/record.js +221 -0
  142. package/dist/orchestrator/record.js.map +1 -0
  143. package/dist/orchestrator/sidecarTools.d.ts +7 -0
  144. package/dist/orchestrator/sidecarTools.d.ts.map +1 -0
  145. package/dist/orchestrator/sidecarTools.js +141 -0
  146. package/dist/orchestrator/sidecarTools.js.map +1 -0
  147. package/dist/prompts/config.d.ts.map +1 -1
  148. package/dist/prompts/config.js +11 -0
  149. package/dist/prompts/config.js.map +1 -1
  150. package/dist/prompts/index.d.ts +0 -6
  151. package/dist/prompts/index.d.ts.map +1 -1
  152. package/dist/prompts/index.js +10 -17
  153. package/dist/prompts/index.js.map +1 -1
  154. package/dist/prompts/init.d.ts +12 -0
  155. package/dist/prompts/init.d.ts.map +1 -0
  156. package/dist/prompts/init.js +48 -0
  157. package/dist/prompts/init.js.map +1 -0
  158. package/dist/prompts/library/defaults.generated.d.ts.map +1 -1
  159. package/dist/prompts/library/defaults.generated.js +29 -12
  160. package/dist/prompts/library/defaults.generated.js.map +1 -1
  161. package/dist/redact.d.ts.map +1 -1
  162. package/dist/redact.js +1 -0
  163. package/dist/redact.js.map +1 -1
  164. package/dist/rooms/findings.d.ts +14 -0
  165. package/dist/rooms/findings.d.ts.map +1 -1
  166. package/dist/rooms/findings.js +37 -0
  167. package/dist/rooms/findings.js.map +1 -1
  168. package/dist/sessions/blobGc.d.ts.map +1 -1
  169. package/dist/sessions/blobGc.js +2 -5
  170. package/dist/sessions/blobGc.js.map +1 -1
  171. package/dist/sessions/childSessions.d.ts +12 -0
  172. package/dist/sessions/childSessions.d.ts.map +1 -0
  173. package/dist/sessions/childSessions.js +43 -0
  174. package/dist/sessions/childSessions.js.map +1 -0
  175. package/dist/sessions/fileRecallStore.d.ts.map +1 -1
  176. package/dist/sessions/fileRecallStore.js +1 -3
  177. package/dist/sessions/fileRecallStore.js.map +1 -1
  178. package/dist/sessions/fileSessionStore.d.ts +11 -7
  179. package/dist/sessions/fileSessionStore.d.ts.map +1 -1
  180. package/dist/sessions/fileSessionStore.js +27 -16
  181. package/dist/sessions/fileSessionStore.js.map +1 -1
  182. package/dist/sessions/inflight.js +0 -0
  183. package/dist/sessions/inflight.js.map +1 -1
  184. package/dist/sessions/jsonl.d.ts +4 -0
  185. package/dist/sessions/jsonl.d.ts.map +1 -1
  186. package/dist/sessions/jsonl.js +1 -0
  187. package/dist/sessions/jsonl.js.map +1 -1
  188. package/dist/sessions/testFs.d.ts.map +1 -1
  189. package/dist/sessions/testFs.js +1 -1
  190. package/dist/sessions/testFs.js.map +1 -1
  191. package/dist/sidecar/host.d.ts +194 -3
  192. package/dist/sidecar/host.d.ts.map +1 -1
  193. package/dist/sidecar/host.js +401 -6
  194. package/dist/sidecar/host.js.map +1 -1
  195. package/dist/sidecar/identity.d.ts +44 -0
  196. package/dist/sidecar/identity.d.ts.map +1 -0
  197. package/dist/sidecar/identity.js +45 -0
  198. package/dist/sidecar/identity.js.map +1 -0
  199. package/dist/sidecar/server.d.ts +250 -4
  200. package/dist/sidecar/server.d.ts.map +1 -1
  201. package/dist/sidecar/server.js +866 -46
  202. package/dist/sidecar/server.js.map +1 -1
  203. package/dist/skillSource.js +1 -1
  204. package/dist/skillSource.js.map +1 -1
  205. package/dist/skills.d.ts +23 -7
  206. package/dist/skills.d.ts.map +1 -1
  207. package/dist/skills.js +62 -37
  208. package/dist/skills.js.map +1 -1
  209. package/dist/tools/callAgent.d.ts +29 -12
  210. package/dist/tools/callAgent.d.ts.map +1 -1
  211. package/dist/tools/callAgent.js +120 -14
  212. package/dist/tools/callAgent.js.map +1 -1
  213. package/dist/tools/crewList.d.ts +33 -0
  214. package/dist/tools/crewList.d.ts.map +1 -0
  215. package/dist/tools/crewList.js +66 -0
  216. package/dist/tools/crewList.js.map +1 -0
  217. package/dist/tools/files.d.ts.map +1 -1
  218. package/dist/tools/files.js +11 -5
  219. package/dist/tools/files.js.map +1 -1
  220. package/dist/tools/findAgent.d.ts +23 -0
  221. package/dist/tools/findAgent.d.ts.map +1 -0
  222. package/dist/tools/findAgent.js +58 -0
  223. package/dist/tools/findAgent.js.map +1 -0
  224. package/dist/tools/namespaces.d.ts.map +1 -1
  225. package/dist/tools/namespaces.js +7 -0
  226. package/dist/tools/namespaces.js.map +1 -1
  227. package/dist/tools/orchestrate.d.ts +4 -0
  228. package/dist/tools/orchestrate.d.ts.map +1 -0
  229. package/dist/tools/orchestrate.js +38 -0
  230. package/dist/tools/orchestrate.js.map +1 -0
  231. package/dist/tools/orchestration.d.ts +24 -0
  232. package/dist/tools/orchestration.d.ts.map +1 -0
  233. package/dist/tools/orchestration.js +173 -0
  234. package/dist/tools/orchestration.js.map +1 -0
  235. package/dist/tools/orchestrationSet.d.ts +6 -0
  236. package/dist/tools/orchestrationSet.d.ts.map +1 -0
  237. package/dist/tools/orchestrationSet.js +12 -0
  238. package/dist/tools/orchestrationSet.js.map +1 -0
  239. package/dist/tools/roomTools.d.ts +6 -0
  240. package/dist/tools/roomTools.d.ts.map +1 -1
  241. package/dist/tools/roomTools.js +26 -2
  242. package/dist/tools/roomTools.js.map +1 -1
  243. package/dist/tools/skillTool.d.ts +15 -0
  244. package/dist/tools/skillTool.d.ts.map +1 -0
  245. package/dist/tools/skillTool.js +39 -0
  246. package/dist/tools/skillTool.js.map +1 -0
  247. package/dist/tools/urlGuard.d.ts +7 -0
  248. package/dist/tools/urlGuard.d.ts.map +1 -1
  249. package/dist/tools/urlGuard.js +54 -18
  250. package/dist/tools/urlGuard.js.map +1 -1
  251. package/package.json +6 -2
@@ -0,0 +1,185 @@
1
+ import { argsHash } from './canonical.js';
2
+ import { newSpanId, newTraceId } from './ids.js';
3
+ /** Loop stop-reason assignments (packages/harness/core/loop.ts), the sidecar
4
+ * executor's 'budget' override (packages/sidecar/src/runner/executor.ts), and
5
+ * the provider finish reasons the loop passes through verbatim as
6
+ * `streamed.finishReason` -- recorded rather than bucketed, per review.
7
+ * Anything else (an arbitrary caller-supplied outcome) becomes 'other' so
8
+ * free text can never smuggle content into the log. */
9
+ const OUTCOMES = new Set([
10
+ 'stop', 'aborted', 'policy', 'error', 'stuck', 'max_turns', 'budget',
11
+ 'length', 'tool_calls', 'end_turn', 'content_filter',
12
+ ]);
13
+ const safeOutcome = (s) => (OUTCOMES.has(s) ? s : 'other');
14
+ /** Tool names that delegate to another agent. A callee spawned while one of
15
+ * these is open on its spawning frame nests under THAT call's span; see
16
+ * AgentFrame.openDelegation. */
17
+ const DELEGATION_TOOLS = new Set(['call_agent', 'spawn_agent', 'spawn_agents']);
18
+ export function createAuditRecorder(opts) {
19
+ const now = opts.now ?? (() => Date.now());
20
+ const ids = opts.ids ?? { trace: newTraceId, span: newSpanId };
21
+ const hash = opts.hash ?? argsHash;
22
+ const trace = ids.trace();
23
+ const base = { v: 1, trace, host: opts.ctx.host, ...(opts.ctx.session ? { session: opts.ctx.session } : {}), ...(opts.ctx.run ? { run: opts.ctx.run } : {}) };
24
+ const iso = () => new Date(now()).toISOString();
25
+ /** Never let a caller-supplied `emit` break the recorder: a throw is
26
+ * caught and swallowed on the spot, per call -- there is no retry or
27
+ * fallback re-emit, so a failing emit can never double-emit a line under a
28
+ * different payload. */
29
+ const safeEmit = (d) => {
30
+ try {
31
+ opts.emit(d);
32
+ }
33
+ catch { /* swallowed: an emit failure is the host's problem, never the run's */ }
34
+ };
35
+ const root = { span: ids.span(), agent: opts.ctx.agent, started: now(), turn: 0, depth: 0, tools: new Map() };
36
+ const children = new Map();
37
+ let finished = false;
38
+ const agentOf = (f) => (f.agent ? { agent: f.agent } : {});
39
+ const draft = (f, d) => ({ ...base, ts: iso(), ...agentOf(f), ...(f.turn ? { turn: f.turn } : {}), ...d });
40
+ /** Every public call is queued here so the emitted order always matches
41
+ * call order, even across an async hash (see the module comment). A step
42
+ * that throws (should never happen -- every emit already goes through
43
+ * `safeEmit`) is swallowed too: a bad step must never break the chain for
44
+ * whatever was queued after it, and must never surface as an unhandled
45
+ * rejection. */
46
+ let chain = Promise.resolve();
47
+ const enqueue = (step) => {
48
+ chain = chain.then(async () => { try {
49
+ await step();
50
+ }
51
+ catch { /* swallowed, see above */ } });
52
+ };
53
+ safeEmit(draft(root, { span: root.span, kind: 'invoke_agent', phase: 'start',
54
+ ...(opts.ctx.agent ? { 'gen_ai.agent.name': opts.ctx.agent } : {}),
55
+ ...(opts.ctx.model ? { 'gen_ai.request.model': opts.ctx.model } : {}) }));
56
+ async function toolCallStep(f, e) {
57
+ const span = ids.span();
58
+ f.tools.set(e.id, { span, started: now(), name: e.name });
59
+ if (DELEGATION_TOOLS.has(e.name))
60
+ f.openDelegation = { span, callId: e.id };
61
+ let h;
62
+ try {
63
+ h = await hash(e.args);
64
+ }
65
+ catch {
66
+ h = 'unhashable';
67
+ }
68
+ safeEmit(draft(f, { span, parent: f.span, kind: 'execute_tool', phase: 'start',
69
+ 'gen_ai.tool.name': e.name, 'gen_ai.tool.call.id': e.id, argsHash: h }));
70
+ }
71
+ function toolResultStep(f, e) {
72
+ // Clear the open-delegation marker on ITS call's result regardless of
73
+ // whether a callee ever actually spawned (e.g. call_agent refused before
74
+ // reaching ctx.spawn) -- otherwise a dead marker would wrongly parent the
75
+ // next, unrelated spawn on this frame.
76
+ if (f.openDelegation?.callId === e.id)
77
+ f.openDelegation = undefined;
78
+ const t = f.tools.get(e.id);
79
+ if (!t)
80
+ return;
81
+ f.tools.delete(e.id);
82
+ const status = e.isError ? 'failed' : 'completed';
83
+ safeEmit(draft(f, { span: t.span, parent: f.span, kind: 'execute_tool', phase: 'end',
84
+ 'gen_ai.tool.name': t.name, 'gen_ai.tool.call.id': e.id, status, durMs: e.durationMs ?? now() - t.started }));
85
+ }
86
+ function usageStep(f, e) {
87
+ safeEmit(draft(f, { span: ids.span(), parent: f.span, kind: 'chat', phase: 'point',
88
+ ...(e.model ? { 'gen_ai.request.model': e.model } : {}),
89
+ 'gen_ai.usage.input_tokens': e.usage.promptTokens, 'gen_ai.usage.output_tokens': e.usage.completionTokens }));
90
+ }
91
+ async function onAgentEventStep(f, e) {
92
+ if (finished)
93
+ return;
94
+ if (e.type === 'turn') {
95
+ f.turn = e.turn;
96
+ return;
97
+ }
98
+ if (e.type === 'tool-call') {
99
+ await toolCallStep(f, e);
100
+ return;
101
+ }
102
+ if (e.type === 'tool-result') {
103
+ toolResultStep(f, e);
104
+ return;
105
+ }
106
+ if (e.type === 'usage') {
107
+ usageStep(f, e);
108
+ return;
109
+ }
110
+ }
111
+ function closeChildStep(nodeId, outcome) {
112
+ const c = children.get(nodeId);
113
+ if (!c)
114
+ return;
115
+ children.delete(nodeId);
116
+ safeEmit(draft(c, { span: c.span, ...(c.parent ? { parent: c.parent } : {}), kind: 'invoke_agent', phase: 'end', outcome, durMs: now() - c.started }));
117
+ }
118
+ /** Resolve which frame SPAWNED this child (by `parentId`, falling back to
119
+ * root when it names no live child -- e.g. the root's own node id, or a
120
+ * frame that already closed), then nest the child under that frame's
121
+ * currently open delegation-tool span, or the frame's own span otherwise.
122
+ * A node-start with no `parentId` at all is the host's own synthetic root
123
+ * marker (workerHandler.ts's 'Session' start) -- not a delegation, so it is
124
+ * ignored: the recorder already has its own `root`. */
125
+ function nodeStartStep(e) {
126
+ if (e.parentId === undefined)
127
+ return;
128
+ const spawningFrame = children.get(e.parentId) ?? root;
129
+ const parentSpan = spawningFrame.openDelegation?.span ?? spawningFrame.span;
130
+ const c = { span: ids.span(), parent: parentSpan, ...(e.agentName ? { agent: e.agentName } : {}), started: now(), turn: 0, depth: spawningFrame.depth + 1, tools: new Map() };
131
+ children.set(e.nodeId, c);
132
+ safeEmit(draft(c, { span: c.span, parent: c.parent, kind: 'invoke_agent', phase: 'start', ...(e.agentName ? { 'gen_ai.agent.name': e.agentName } : {}) }));
133
+ }
134
+ return {
135
+ trace,
136
+ whenIdle: () => chain,
137
+ onEvent(e) { enqueue(() => onAgentEventStep(root, e)); },
138
+ onNodeEvent(e) {
139
+ enqueue(async () => {
140
+ if (finished)
141
+ return;
142
+ if (e.type === 'node-start') {
143
+ nodeStartStep(e);
144
+ return;
145
+ }
146
+ if (e.type === 'node-event') {
147
+ const c = children.get(e.nodeId);
148
+ if (c)
149
+ await onAgentEventStep(c, e.event);
150
+ return;
151
+ }
152
+ if (e.type === 'node-done') {
153
+ closeChildStep(e.nodeId, safeOutcome(e.output.stopReason));
154
+ return;
155
+ }
156
+ if (e.type === 'node-error')
157
+ closeChildStep(e.nodeId, 'error');
158
+ });
159
+ },
160
+ onDecision(e) {
161
+ enqueue(() => {
162
+ if (finished)
163
+ return;
164
+ const f = (e.nodeId ? children.get(e.nodeId) : undefined) ?? root;
165
+ safeEmit(draft(f, { span: ids.span(), parent: f.span, kind: 'permission', phase: 'point',
166
+ 'gen_ai.tool.name': e.subject.name, level: e.level, decision: e.decision,
167
+ decidedBy: e.by, ...(e.policy ? { policy: e.policy } : {}) }));
168
+ });
169
+ },
170
+ finish(outcome) {
171
+ enqueue(() => {
172
+ if (finished)
173
+ return;
174
+ finished = true;
175
+ // Deepest callee first: closing a parent before its still-open child
176
+ // would read as though the child outlived it.
177
+ const order = [...children.entries()].sort((a, b) => b[1].depth - a[1].depth).map(([id]) => id);
178
+ for (const id of order)
179
+ closeChildStep(id, 'aborted');
180
+ safeEmit(draft(root, { span: root.span, kind: 'invoke_agent', phase: 'end', outcome: safeOutcome(outcome), durMs: now() - root.started }));
181
+ });
182
+ },
183
+ };
184
+ }
185
+ //# sourceMappingURL=recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../audit/recorder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { AgentEvent, AuditSettings, DecisionEvent, NodeEvent } from '@corenel/protocol';
2
+ import { type AuditRunContext } from './recorder';
3
+ import type { AuditLog } from './log';
4
+ /** The host side of the audit bridge. The host owns the log (one writer per
5
+ * location), so `logFor` must hand back the SAME AuditLog for the same
6
+ * location on every run; a run never creates one. */
7
+ export interface AuditBridgeHost {
8
+ /** A log for this run's location, or null when auditing is off or unavailable. */
9
+ logFor(ctx: {
10
+ session?: string;
11
+ }): Promise<AuditLog | null>;
12
+ settings(): AuditSettings;
13
+ }
14
+ /** How long a finished run may wait for its audit lines to be written before
15
+ * it resolves anyway. */
16
+ export declare const AUDIT_FINISH_BOUND_MS = 5000;
17
+ /** The event a run emits when its audit lost lines or could not confirm them. */
18
+ export type AuditIncompleteEvent = Extract<AgentEvent, {
19
+ type: 'audit-incomplete';
20
+ }>;
21
+ export interface RunAudit {
22
+ onEvent(e: AgentEvent): void;
23
+ onNodeEvent(e: NodeEvent): void;
24
+ onDecision(e: DecisionEvent): void;
25
+ /** Close the run's lines, wait for them to be written and flush the log.
26
+ * Never rejects and resolves within AUDIT_FINISH_BOUND_MS. Returns the
27
+ * `audit-incomplete` event to surface, or null when nothing was lost. */
28
+ finish(outcome: string): Promise<AuditIncompleteEvent | null>;
29
+ }
30
+ /** Start a run's audit, or null when there is no host. The recorder writes
31
+ * its first line at once, before the host's log (async) can arrive, so lines
32
+ * are buffered until it resolves, then drained in order (see RunAuditState).
33
+ * A `logFor` that throws or rejects means auditing was wanted and failed, so
34
+ * every line counts as lost. Nothing here can fail the run. */
35
+ export declare function startRunAudit(host: AuditBridgeHost | null, ctx: AuditRunContext & {
36
+ run: string;
37
+ }): RunAudit | null;
38
+ //# sourceMappingURL=runAudit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runAudit.d.ts","sourceRoot":"","sources":["../../audit/runAudit.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAc,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACzG,OAAO,EAA2C,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEtC;;qDAEqD;AACrD,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,MAAM,CAAC,GAAG,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAC5D,QAAQ,IAAI,aAAa,CAAC;CAC3B;AAED;yBACyB;AACzB,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,iFAAiF;AACjF,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAAC;AAErF,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAChC,UAAU,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC;;6EAEyE;IACzE,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;CAC/D;AAuCD;;;;+DAI+D;AAC/D,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,EAAE,GAAG,EAAE,eAAe,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,QAAQ,GAAG,IAAI,CA+DnH"}
@@ -0,0 +1,99 @@
1
+ import { createAuditRecorder } from './recorder.js';
2
+ /** How long a finished run may wait for its audit lines to be written before
3
+ * it resolves anyway. */
4
+ export const AUDIT_FINISH_BOUND_MS = 5000;
5
+ /** What a run's audit lost, once its lines have been written (or not). */
6
+ function auditLoss(state, timedOut) {
7
+ if (!state.settled) {
8
+ // The log never arrived (only the bound gets here): everything buffered
9
+ // is lost, and so is every line after this -- the count is a lower
10
+ // bound, so the finish is also unconfirmed.
11
+ const lost = state.pending?.length ?? 0;
12
+ state.pending = null;
13
+ state.released = true;
14
+ return { lost, unconfirmed: true };
15
+ }
16
+ if (state.failed)
17
+ return { lost: state.pending?.length ?? 0 };
18
+ if (!state.log)
19
+ return null;
20
+ const lost = Math.max(0, state.log.lost() - state.baseline);
21
+ return timedOut ? { lost, unconfirmed: true } : { lost };
22
+ }
23
+ /** Start a run's audit, or null when there is no host. The recorder writes
24
+ * its first line at once, before the host's log (async) can arrive, so lines
25
+ * are buffered until it resolves, then drained in order (see RunAuditState).
26
+ * A `logFor` that throws or rejects means auditing was wanted and failed, so
27
+ * every line counts as lost. Nothing here can fail the run. */
28
+ export function startRunAudit(host, ctx) {
29
+ if (!host)
30
+ return null;
31
+ const state = { settled: false, log: null, failed: false, released: false, pending: [], baseline: 0 };
32
+ const ready = Promise.resolve()
33
+ .then(() => host.logFor({ session: ctx.session }))
34
+ .then((l) => {
35
+ if (state.released)
36
+ return;
37
+ state.settled = true;
38
+ if (!l) {
39
+ state.pending = null;
40
+ return;
41
+ }
42
+ state.baseline = l.lost();
43
+ state.log = l;
44
+ const buffered = state.pending ?? [];
45
+ state.pending = null;
46
+ for (const d of buffered)
47
+ l.append(d);
48
+ }, () => { state.settled = true; state.failed = true; })
49
+ .catch(() => { state.settled = true; state.failed = true; });
50
+ const recorder = createAuditRecorder({
51
+ ctx: {
52
+ host: ctx.host, run: ctx.run,
53
+ ...(ctx.session ? { session: ctx.session } : {}),
54
+ ...(ctx.agent ? { agent: ctx.agent } : {}),
55
+ ...(ctx.model ? { model: ctx.model } : {}),
56
+ },
57
+ emit: (d) => {
58
+ if (state.released)
59
+ return;
60
+ if (state.pending)
61
+ state.pending.push(d);
62
+ else
63
+ state.log?.append(d);
64
+ },
65
+ });
66
+ return {
67
+ onEvent: (e) => recorder.onEvent(e),
68
+ onNodeEvent: (e) => recorder.onNodeEvent(e),
69
+ onDecision: (e) => recorder.onDecision(e),
70
+ /* The whole sequence is bounded by AUDIT_FINISH_BOUND_MS and never
71
+ * rejects, so it can neither fail the run nor hold it longer than the
72
+ * bound. A sequence cut off by the bound still reports: the buffered lines
73
+ * as lost when the log never arrived (a lower bound, so `unconfirmed`
74
+ * too), else just `unconfirmed` (whenIdle or flush hung). */
75
+ async finish(outcome) {
76
+ let timer;
77
+ const deadline = new Promise((r) => { timer = setTimeout(() => r('timeout'), AUDIT_FINISH_BOUND_MS); });
78
+ try {
79
+ recorder.finish(outcome);
80
+ const written = (async () => {
81
+ await recorder.whenIdle();
82
+ await ready;
83
+ await state.log?.flush();
84
+ return 'written';
85
+ })().catch(() => 'written');
86
+ const how = await Promise.race([written, deadline]);
87
+ const loss = auditLoss(state, how === 'timeout');
88
+ return loss && (loss.lost > 0 || loss.unconfirmed) ? { type: 'audit-incomplete', ...loss } : null;
89
+ }
90
+ catch {
91
+ return null; // swallowed: the audit must never fail or delay a run
92
+ }
93
+ finally {
94
+ clearTimeout(timer);
95
+ }
96
+ },
97
+ };
98
+ }
99
+ //# sourceMappingURL=runAudit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runAudit.js","sourceRoot":"","sources":["../../audit/runAudit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { AuditHost, FileService } from '@corenel/protocol';
2
+ export type ChainResult = {
3
+ ok: true;
4
+ lines: number;
5
+ } | {
6
+ ok: false;
7
+ at: {
8
+ file: string;
9
+ line: number;
10
+ };
11
+ reason: 'prev-mismatch' | 'missing-segment' | 'unparseable';
12
+ };
13
+ export declare function verifyAuditChain(files: FileService, root: string, host: AuditHost, writerId?: string): Promise<ChainResult>;
14
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../audit/verify.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhE,MAAM,MAAM,WAAW,GACnB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,MAAM,EAAE,eAAe,GAAG,iBAAiB,GAAG,aAAa,CAAA;CAAE,CAAC;AAEnH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GACnE,OAAO,CAAC,WAAW,CAAC,CA0CtB"}
@@ -0,0 +1,47 @@
1
+ import { activeSegmentName, auditFileNames, lineHash, sortedAuditArchives } from './log.js';
2
+ export async function verifyAuditChain(files, root, host, writerId) {
3
+ const names = auditFileNames(await files.list(root));
4
+ const archives = sortedAuditArchives(names, host, writerId);
5
+ const order = [...archives];
6
+ const active = activeSegmentName(host, writerId);
7
+ if (names.includes(active))
8
+ order.push({ name: active });
9
+ let prevHash = null;
10
+ let total = 0;
11
+ for (let f = 0; f < order.length; f++) {
12
+ const seg = order[f];
13
+ const file = `${root}/${seg.name}`;
14
+ const before = f > 0 ? order[f - 1] : null;
15
+ if (before && seg.date !== undefined && before.date === seg.date && seg.n !== (before.n ?? 0) + 1) {
16
+ return { ok: false, at: { file, line: 1 }, reason: 'missing-segment' };
17
+ }
18
+ const raw = (await files.read(file)).split('\n');
19
+ /* A well-formed segment ends with '\n', leaving one empty tail element;
20
+ * anything else in that last slot is a torn line. */
21
+ if (raw.length && raw[raw.length - 1] === '')
22
+ raw.pop();
23
+ let first = true;
24
+ for (let i = 0; i < raw.length; i++) {
25
+ const line = raw[i];
26
+ let parsed;
27
+ try {
28
+ parsed = JSON.parse(line);
29
+ }
30
+ catch {
31
+ return { ok: false, at: { file, line: i + 1 }, reason: 'unparseable' };
32
+ }
33
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
34
+ return { ok: false, at: { file, line: i + 1 }, reason: 'unparseable' };
35
+ }
36
+ const prev = parsed.prev;
37
+ if (prevHash !== null && prev !== prevHash) {
38
+ return { ok: false, at: { file, line: i + 1 }, reason: first ? 'missing-segment' : 'prev-mismatch' };
39
+ }
40
+ prevHash = await lineHash(line);
41
+ first = false;
42
+ total += 1;
43
+ }
44
+ }
45
+ return { ok: true, lines: total };
46
+ }
47
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../audit/verify.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,19 @@
1
1
  import type { ChatCompletionMessageParam } from 'openai/resources/chat/completions';
2
+ import type { TurnVerification } from '@corenel/protocol';
2
3
  /** Per-turn telemetry shown under an assistant turn (tokens / cost / wall-clock). */
3
4
  export interface TurnStats {
5
+ /** Prompt tokens summed over every model call in the turn -- what was billed,
6
+ * NOT the context size (each call resends the whole prompt). */
4
7
  inTok: number;
5
8
  outTok: number;
6
9
  cost: number;
7
10
  ms: number;
11
+ /** The largest single request's prompt tokens: the context the turn occupied. */
12
+ ctxTok?: number;
13
+ /** Of `inTok`, how many the provider served from its prompt cache. */
14
+ cachedTok?: number;
15
+ /** Model calls the turn made. */
16
+ calls?: number;
8
17
  }
9
18
  /** One assistant conversation turn — the live-buffer data shape. Owned by the
10
19
  * kernel (the UI Transcript renders it; runtime/AgentPanel pass it around). */
@@ -20,6 +29,16 @@ export interface ConversationTurn {
20
29
  * about the conversation in front of you, and because the file only exists
21
30
  * for a run that had a session to write beside. Absent on every other turn. */
22
31
  checkpoint?: string;
32
+ /** What the turn's mutating tool calls OBSERVABLY changed, from the loop's
33
+ * `turn-verified` event. Runtime data shown beside the reply; absent when the
34
+ * turn made no mutating calls. */
35
+ verification?: TurnVerification;
36
+ /** Set when the run's audit log lost entries, or could not confirm them
37
+ * written (the run's `audit-incomplete` event). Absent otherwise. */
38
+ auditIncomplete?: {
39
+ lost: number;
40
+ unconfirmed?: boolean;
41
+ };
23
42
  }
24
43
  /** Is this turn a COMPACTION SEAM rather than something said?
25
44
  *
@@ -30,4 +49,16 @@ export interface ConversationTurn {
30
49
  * reports (a seam is an unsent note; counting it would inflate the very number
31
50
  * the panel exists to give), and the runtime writes them. */
32
51
  export declare function isCheckpointTurn(t: ConversationTurn): boolean;
52
+ /**
53
+ * A stored session's `messages` as conversation turns.
54
+ *
55
+ * TWO SHAPES REACH THIS. A browser session stores `ConversationTurn[]` (nested:
56
+ * each entry has its own `messages`), while a daemon run and a delegated
57
+ * subagent's saved session store the flat `{ role, content }` list. Casting the
58
+ * flat list to turns made every turn's `messages` undefined, and the chat threw
59
+ * on the first render that read one. Flat messages are grouped into turns, one
60
+ * per user message (anything before the first user message forms its own turn).
61
+ * Anything that is not an object is dropped.
62
+ */
63
+ export declare function turnsFromSessionMessages(raw: unknown): ConversationTurn[];
33
64
  //# sourceMappingURL=conversation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../conversation.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAGpF,qFAAqF;AACrF,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;+EAC+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,4EAA4E;IAC5E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;mFAI+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;6DAO6D;AAC7D,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAG7D"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../conversation.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,qFAAqF;AACrF,MAAM,WAAW,SAAS;IACxB;oEACgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;+EAC+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,4EAA4E;IAC5E,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;mFAI+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;sCAEkC;IAClC,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC;yEACqE;IACrE,eAAe,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC3D;AAED;;;;;;;6DAO6D;AAC7D,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAG7D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,EAAE,CAmBzE"}
@@ -11,4 +11,37 @@ export function isCheckpointTurn(t) {
11
11
  const first = t.messages[0];
12
12
  return typeof first?.content === 'string' && first.content.startsWith(CHECKPOINT_MARKER);
13
13
  }
14
+ /**
15
+ * A stored session's `messages` as conversation turns.
16
+ *
17
+ * TWO SHAPES REACH THIS. A browser session stores `ConversationTurn[]` (nested:
18
+ * each entry has its own `messages`), while a daemon run and a delegated
19
+ * subagent's saved session store the flat `{ role, content }` list. Casting the
20
+ * flat list to turns made every turn's `messages` undefined, and the chat threw
21
+ * on the first render that read one. Flat messages are grouped into turns, one
22
+ * per user message (anything before the first user message forms its own turn).
23
+ * Anything that is not an object is dropped.
24
+ */
25
+ export function turnsFromSessionMessages(raw) {
26
+ if (!Array.isArray(raw))
27
+ return [];
28
+ const items = raw.filter((m) => !!m && typeof m === 'object');
29
+ if (items.every((m) => Array.isArray(m.messages)))
30
+ return items;
31
+ const turns = [];
32
+ let current = null;
33
+ items.forEach((m, i) => {
34
+ if (Array.isArray(m.messages)) {
35
+ current = null;
36
+ turns.push(m);
37
+ return;
38
+ }
39
+ if (!current || m.role === 'user') {
40
+ current = { id: `stored-${i}`, included: true, messages: [] };
41
+ turns.push(current);
42
+ }
43
+ current.messages.push(m);
44
+ });
45
+ return turns;
46
+ }
14
47
  //# sourceMappingURL=conversation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.js","sourceRoot":"","sources":["../conversation.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AA0B1D;;;;;;;6DAO6D;AAC7D,MAAM,UAAU,gBAAgB,CAAC,CAAmB;IAClD,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC5B,OAAO,OAAO,KAAK,EAAE,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;AAC3F,CAAC"}
1
+ {"version":3,"file":"conversation.js","sourceRoot":"","sources":["../conversation.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAyC1D;;;;;;;6DAO6D;AAC7D,MAAM,UAAU,gBAAgB,CAAC,CAAmB;IAClD,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC5B,OAAO,OAAO,KAAK,EAAE,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;AAC3F,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAY;IACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAgC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;IAC5F,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAAE,OAAO,KAAsC,CAAC;IACjG,MAAM,KAAK,GAAuB,EAAE,CAAC;IACrC,IAAI,OAAO,GAA4B,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,CAAgC,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAClC,OAAO,GAAG,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;YAC9D,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAA0C,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function sha256Hex(text: string): Promise<string>;
2
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../core/hash.ts"],"names":[],"mappings":"AAGA,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI7D"}
@@ -0,0 +1,9 @@
1
+ /* sha-256 as lowercase hex, for the turn verifier's before/after comparison.
2
+ * WebCrypto, so the same code runs in the browser worker and in Node >= 19
3
+ * (the sidecar), which is why it lives in the kernel rather than in src/lib. */
4
+ export async function sha256Hex(text) {
5
+ const bytes = new TextEncoder().encode(text);
6
+ const digest = await globalThis.crypto.subtle.digest('SHA-256', bytes);
7
+ return Array.from(new Uint8Array(digest), (b) => b.toString(16).padStart(2, '0')).join('');
8
+ }
9
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../core/hash.ts"],"names":[],"mappings":"AAAA;;gFAEgF;AAChF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACvE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC7F,CAAC"}
@@ -5,6 +5,7 @@ import { type RecoveryConfig } from './recovery';
5
5
  import type { Policy } from '@corenel/protocol';
6
6
  import type { PermissionService } from '../guardrail/permission-service';
7
7
  import { type CompressionConfig } from '../compression';
8
+ import { type SkillEntry } from '../tools/skillTool';
8
9
  export interface RunAgentArgs {
9
10
  client: OpenAI;
10
11
  model: string;
@@ -22,12 +23,21 @@ export interface RunAgentArgs {
22
23
  /** Deferred tool names this conversation loaded on earlier runs. Names no
23
24
  * longer among `deferredTools` are dropped and reported via `tools-loaded`. */
24
25
  loadedTools?: string[];
26
+ /** Enabled skills, read in full by the host. When non-empty the system prompt
27
+ * gains a one-line-per-skill index and the run gains `use_skill`, which
28
+ * returns a body on demand (tools/skillTool.ts) -- bodies never ride every
29
+ * request. Data rather than file access, because a run does not always
30
+ * execute where the skill files can be read (the browser worker). */
31
+ skills?: SkillEntry[];
25
32
  toolCtx: ToolContext;
26
33
  maxTurns?: number;
27
34
  /** Governance policy for the run (guardrail gates). Defaults to STANDARD_POLICY. */
28
35
  policy?: Policy;
29
36
  /** Per-tool permission resolver. When omitted, tools run without an approval gate. */
30
37
  permission?: PermissionService;
38
+ /** The spawned child this run is, stamped onto every permission decision it
39
+ * reports (`DecisionEvent.nodeId`). Absent for a root run. */
40
+ decisionNodeId?: string;
31
41
  /** Customize the tool-result text a refused tool call gets. The kernel is
32
42
  * host-agnostic and cannot know WHY a decision came back "deny" — a real
33
43
  * person declining an interactive prompt, and a non-interactive host that
@@ -98,6 +108,14 @@ export interface RunAgentResult {
98
108
  * checkpoint reports only what survives: those messages are genuinely gone
99
109
  * from the array, and the seam in the transcript is what stands in for them. */
100
110
  appended: number;
111
+ /** The largest single request's prompt tokens -- the context this run actually
112
+ * occupied. `usage.promptTokens` is the SUM over every call (what was billed),
113
+ * and each call resends the whole prompt, so a three-call turn at 46K sums to
114
+ * 138K; showing that sum as "in" reads as a context problem that isn't one.
115
+ * Optional because hand-built runners (tests, delegating hosts) don't measure it. */
116
+ contextTokens?: number;
117
+ /** Model calls this run made. */
118
+ calls?: number;
101
119
  }
102
120
  /** The most tools one request may carry.
103
121
  *
@@ -1 +1 @@
1
- {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../core/loop.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,0BAA0B,EAAsB,MAAM,mCAAmC,CAAC;AACxG,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAA4B,MAAM,mBAAmB,CAAC;AAE7G,OAAO,EACY,KAAK,cAAc,EAErC,MAAM,YAAY,CAAC;AAMpB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAA0D,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMhH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd;kDAC8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB;;;kFAG8E;IAC9E,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC;IAC5B;oFACgF;IAChF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B;;;;;;;;6EAQyE;IACzE,wBAAwB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACxD,oEAAoE;IACpE,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC;;;;;iCAK6B;IAC7B,UAAU,CAAC,EAAE;QACX,SAAS,EAAE,CAAC,SAAS,EAAE,0BAA0B,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QACxE,MAAM,CAAC,EAAE,CACP,IAAI,EAAE,0BAA0B,EAChC,QAAQ,EAAE,0BAA0B,GAAG,IAAI,KACxC,OAAO,CAAC,MAAM,CAAC,CAAC;QACrB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7D,CAAC;IACF,oFAAoF;IACpF,QAAQ,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IACnC;0FACsF;IACtF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;yEAOqE;IACrE,aAAa,CAAC,EAAE,MAAM,0BAA0B,EAAE,CAAC;IACnD;;4DAEwD;IACxD,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC;IACpC;;;0EAGsE;IACtE,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACpD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;oFAYgF;IAChF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;gEAWgE;AAChE,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,cAAc,CAAC,CAykB1E"}
1
+ {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../core/loop.ts"],"names":[],"mappings":"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"}