@graphorin/core 0.6.0 → 0.7.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 (112) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +14 -8
  3. package/dist/channels/channels.d.ts.map +1 -1
  4. package/dist/channels/index.d.ts +2 -2
  5. package/dist/channels/index.js +2 -2
  6. package/dist/channels/pause.d.ts +47 -2
  7. package/dist/channels/pause.d.ts.map +1 -1
  8. package/dist/channels/pause.js +62 -2
  9. package/dist/channels/pause.js.map +1 -1
  10. package/dist/contracts/checkpoint-store.d.ts +97 -1
  11. package/dist/contracts/checkpoint-store.d.ts.map +1 -1
  12. package/dist/contracts/checkpoint-store.js.map +1 -1
  13. package/dist/contracts/index.d.ts +5 -5
  14. package/dist/contracts/index.js +2 -1
  15. package/dist/contracts/memory-store.d.ts +59 -2
  16. package/dist/contracts/memory-store.d.ts.map +1 -1
  17. package/dist/contracts/provider.d.ts +20 -6
  18. package/dist/contracts/provider.d.ts.map +1 -1
  19. package/dist/contracts/session-store.d.ts +10 -2
  20. package/dist/contracts/session-store.d.ts.map +1 -1
  21. package/dist/contracts/tool.d.ts +75 -1
  22. package/dist/contracts/tool.d.ts.map +1 -1
  23. package/dist/contracts/tool.js +57 -0
  24. package/dist/contracts/tool.js.map +1 -0
  25. package/dist/contracts/tracer.d.ts +53 -5
  26. package/dist/contracts/tracer.d.ts.map +1 -1
  27. package/dist/contracts/tracer.js.map +1 -1
  28. package/dist/index.d.ts +14 -9
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +11 -7
  31. package/dist/index.js.map +1 -1
  32. package/dist/package.js +6 -0
  33. package/dist/package.js.map +1 -0
  34. package/dist/types/agent-event-wire.d.ts +74 -0
  35. package/dist/types/agent-event-wire.d.ts.map +1 -0
  36. package/dist/types/agent-event-wire.js +130 -0
  37. package/dist/types/agent-event-wire.js.map +1 -0
  38. package/dist/types/agent-event.d.ts +48 -6
  39. package/dist/types/agent-event.d.ts.map +1 -1
  40. package/dist/types/index.d.ts +3 -2
  41. package/dist/types/index.js +2 -1
  42. package/dist/types/memory.d.ts +11 -0
  43. package/dist/types/memory.d.ts.map +1 -1
  44. package/dist/types/run.d.ts +86 -4
  45. package/dist/types/run.d.ts.map +1 -1
  46. package/dist/types/run.js.map +1 -1
  47. package/dist/types/tool.d.ts +10 -0
  48. package/dist/types/tool.d.ts.map +1 -1
  49. package/dist/types/usage.d.ts +11 -1
  50. package/dist/types/usage.d.ts.map +1 -1
  51. package/dist/types/usage.js.map +1 -1
  52. package/dist/utils/binary-json.d.ts +165 -0
  53. package/dist/utils/binary-json.d.ts.map +1 -0
  54. package/dist/utils/binary-json.js +240 -0
  55. package/dist/utils/binary-json.js.map +1 -0
  56. package/dist/utils/index.d.ts +2 -1
  57. package/dist/utils/index.js +2 -1
  58. package/dist/utils/validation.d.ts +10 -1
  59. package/dist/utils/validation.d.ts.map +1 -1
  60. package/dist/utils/validation.js +1 -1
  61. package/dist/utils/validation.js.map +1 -1
  62. package/package.json +9 -7
  63. package/src/channels/channels.ts +206 -0
  64. package/src/channels/directive.ts +41 -0
  65. package/src/channels/dispatch.ts +37 -0
  66. package/src/channels/durable.ts +151 -0
  67. package/src/channels/index.ts +62 -0
  68. package/src/channels/pause.ts +216 -0
  69. package/src/contracts/auth-token-store.ts +42 -0
  70. package/src/contracts/checkpoint-store.ts +256 -0
  71. package/src/contracts/embedder.ts +42 -0
  72. package/src/contracts/eval-scorer.ts +44 -0
  73. package/src/contracts/index.ts +112 -0
  74. package/src/contracts/local-provider-trust.ts +33 -0
  75. package/src/contracts/logger.ts +61 -0
  76. package/src/contracts/memory-store.ts +187 -0
  77. package/src/contracts/oauth-server-store.ts +78 -0
  78. package/src/contracts/preferred-model.ts +56 -0
  79. package/src/contracts/provider.ts +316 -0
  80. package/src/contracts/reasoning-retention.ts +52 -0
  81. package/src/contracts/redaction-validator.ts +56 -0
  82. package/src/contracts/sandbox.ts +70 -0
  83. package/src/contracts/secret-ref.ts +22 -0
  84. package/src/contracts/secret-value.ts +117 -0
  85. package/src/contracts/secrets-store.ts +90 -0
  86. package/src/contracts/session-store.ts +163 -0
  87. package/src/contracts/token-counter.ts +23 -0
  88. package/src/contracts/tool.ts +397 -0
  89. package/src/contracts/tracer.ts +219 -0
  90. package/src/contracts/trigger-store.ts +40 -0
  91. package/src/index.ts +23 -0
  92. package/src/types/agent-event-wire.ts +193 -0
  93. package/src/types/agent-event.ts +579 -0
  94. package/src/types/handoff.ts +111 -0
  95. package/src/types/index.ts +148 -0
  96. package/src/types/memory.ts +427 -0
  97. package/src/types/message.ts +174 -0
  98. package/src/types/run.ts +312 -0
  99. package/src/types/sensitivity.ts +35 -0
  100. package/src/types/session-scope.ts +18 -0
  101. package/src/types/stop-condition.ts +108 -0
  102. package/src/types/tool-call.ts +24 -0
  103. package/src/types/tool.ts +324 -0
  104. package/src/types/usage.ts +120 -0
  105. package/src/types/workflow-event.ts +132 -0
  106. package/src/utils/assert-never.ts +24 -0
  107. package/src/utils/async-context.ts +55 -0
  108. package/src/utils/binary-json.ts +425 -0
  109. package/src/utils/hash.ts +122 -0
  110. package/src/utils/index.ts +57 -0
  111. package/src/utils/streams.ts +233 -0
  112. package/src/utils/validation.ts +82 -0
@@ -0,0 +1,579 @@
1
+ import type { RunError, RunState, RunStatus } from './run.js';
2
+ import type { ContentChunk, ToolError } from './tool.js';
3
+ import type { Usage } from './usage.js';
4
+
5
+ /**
6
+ * Discriminated union of every event produced by `Agent.stream(...)`.
7
+ *
8
+ * Each variant has a literal `type` field used as the discriminator. The
9
+ * union is exhaustive: `assertNever(...)` catches missed variants at
10
+ * compile time.
11
+ *
12
+ * Wire contract (two layers): the server delivers events inside an
13
+ * envelope `{ eventId, subject, type, payload }` where `payload` is the
14
+ * JSON-safe `WireAgentEvent` projection (`toWireAgentEvent`), NOT this
15
+ * raw union - three variants (`file.generated`, `tool.execute.partial`,
16
+ * `agent.end`) carry `Uint8Array`/`URL` payloads that plain
17
+ * `JSON.stringify` would corrupt. `@graphorin/protocol` validates the
18
+ * envelope and leaves `payload` opaque (`z.unknown()`); clients decode
19
+ * with `fromWireAgentEvent`. Adding a variant here counts as a
20
+ * wire-format change; track it through changesets.
21
+ *
22
+ * Correlation policy (W-049): events are consumed from a per-run
23
+ * stream, so cross-run attribution is the ENVELOPE's job (`subject`
24
+ * carries `agentId`/`runId`); an in-payload `runId` exists only on the
25
+ * variants that historically carry one and is deliberately NOT
26
+ * retrofitted onto the rest. Within one tool lifecycle the correlation
27
+ * key is `toolCallId`; `toolName` is duplicated onto the
28
+ * `tool.execute.*` variants purely for subscriber convenience.
29
+ *
30
+ * @stable
31
+ */
32
+ export type AgentEvent<TOutput = string> =
33
+ | AgentStartEvent
34
+ | StepStartEvent
35
+ | TextDeltaEvent
36
+ | TextCompleteEvent
37
+ | ReasoningDeltaEvent
38
+ | ToolCallStartEvent
39
+ | ToolCallDeltaEvent
40
+ | ToolCallEndEvent
41
+ | ToolExecuteStartEvent
42
+ | ToolExecuteProgressEvent
43
+ | ToolExecutePartialEvent
44
+ | ToolExecuteEndEvent
45
+ | ToolExecuteErrorEvent
46
+ | ToolApprovalRequestedEvent
47
+ | ToolApprovalGrantedEvent
48
+ | ToolApprovalDeniedEvent
49
+ | ContextCompactedEvent
50
+ | HandoffEvent
51
+ | AgentSteeredEvent
52
+ | AgentFollowUpQueuedEvent
53
+ | AgentCancellingEvent
54
+ | AgentModelFellbackEvent
55
+ | AgentFanOutSpawnedEvent
56
+ | AgentFanOutMergedEvent
57
+ | AgentEvaluatorIterationEvent
58
+ | AgentEvaluatorConvergedEvent
59
+ | AgentProgressWrittenEvent
60
+ | AgentProgressReadEvent
61
+ | AgentLateralLeakDetectedEvent
62
+ | FileGeneratedEvent
63
+ | SourceCitedEvent
64
+ | StepEndEvent
65
+ | GuardrailTrippedEvent
66
+ | VerifierResultEvent
67
+ | SubagentEvent
68
+ | AgentEndEvent<TOutput>
69
+ | AgentErrorEvent;
70
+
71
+ /**
72
+ * W-036: a CHILD sub-agent's event forwarded into the parent stream,
73
+ * wrapped so it never aliases the parent's own step/run events. Which
74
+ * child events forward is governed by the `forwardEvents` policy on
75
+ * the handoff entry / `AgentToToolOptions` (default `'lifecycle'`).
76
+ *
77
+ * @stable
78
+ */
79
+ export interface SubagentEvent {
80
+ readonly type: 'subagent.event';
81
+ /** The PARENT-side toolCallId of the handoff / sub-agent call. */
82
+ readonly toolCallId: string;
83
+ /** The child agent's configured name. */
84
+ readonly agentName: string;
85
+ /** The child's event, verbatim. */
86
+ readonly event: AgentEvent<unknown>;
87
+ }
88
+
89
+ /** @stable */
90
+ export interface AgentStartEvent {
91
+ readonly type: 'agent.start';
92
+ readonly runId: string;
93
+ readonly agentId: string;
94
+ }
95
+
96
+ /** @stable */
97
+ export interface StepStartEvent {
98
+ readonly type: 'step.start';
99
+ readonly stepNumber: number;
100
+ }
101
+
102
+ /** @stable */
103
+ export interface TextDeltaEvent {
104
+ readonly type: 'text.delta';
105
+ readonly delta: string;
106
+ }
107
+
108
+ /** @stable */
109
+ export interface TextCompleteEvent {
110
+ readonly type: 'text.complete';
111
+ readonly text: string;
112
+ }
113
+
114
+ /** @stable */
115
+ export interface ReasoningDeltaEvent {
116
+ readonly type: 'reasoning.delta';
117
+ readonly delta: string;
118
+ }
119
+
120
+ /** @stable */
121
+ export interface ToolCallStartEvent {
122
+ readonly type: 'tool.call.start';
123
+ readonly toolCallId: string;
124
+ readonly toolName: string;
125
+ readonly args: unknown;
126
+ }
127
+
128
+ /** @stable */
129
+ export interface ToolCallDeltaEvent {
130
+ readonly type: 'tool.call.delta';
131
+ readonly toolCallId: string;
132
+ readonly argsDelta: string;
133
+ }
134
+
135
+ /** @stable */
136
+ export interface ToolCallEndEvent {
137
+ readonly type: 'tool.call.end';
138
+ readonly toolCallId: string;
139
+ readonly finalArgs: unknown;
140
+ }
141
+
142
+ /** @stable */
143
+ export interface ToolExecuteStartEvent {
144
+ readonly type: 'tool.execute.start';
145
+ readonly toolCallId: string;
146
+ /**
147
+ * Convenience duplicate of the executing tool's name (W-049).
148
+ * Correlation within a tool lifecycle is by `toolCallId`; this field
149
+ * spares direct subscribers a stateful join back to the
150
+ * `tool.call.start` that carried the name. Optional for wire
151
+ * compatibility; the agent runtime always fills it.
152
+ */
153
+ readonly toolName?: string;
154
+ }
155
+
156
+ /**
157
+ * Emitted by streaming-hint tools via `ctx.reportProgress(...)`. Counter
158
+ * pair `(current, total?)` is consumer-rendered as a percentage when both
159
+ * fields are present.
160
+ *
161
+ * @stable
162
+ */
163
+ export interface ToolExecuteProgressEvent {
164
+ readonly type: 'tool.execute.progress';
165
+ readonly toolName: string;
166
+ readonly toolCallId: string;
167
+ readonly current: number;
168
+ readonly total?: number;
169
+ readonly message?: string;
170
+ readonly stepNumber: number;
171
+ readonly ts: number;
172
+ }
173
+
174
+ /**
175
+ * Emitted by streaming-hint tools via `ctx.streamContent(...)`. Each
176
+ * chunk is concatenated into the assembled `output` per the
177
+ * buffer-becomes-output discipline. `chunkIndex` is monotone per
178
+ * `(toolCallId)` so subscribers can detect drops.
179
+ *
180
+ * @stable
181
+ */
182
+ export interface ToolExecutePartialEvent {
183
+ readonly type: 'tool.execute.partial';
184
+ readonly toolName: string;
185
+ readonly toolCallId: string;
186
+ readonly chunk: ContentChunk;
187
+ readonly chunkIndex: number;
188
+ readonly stepNumber: number;
189
+ readonly ts: number;
190
+ }
191
+
192
+ /** @stable */
193
+ export interface ToolExecuteEndEvent {
194
+ readonly type: 'tool.execute.end';
195
+ readonly toolCallId: string;
196
+ /** See {@link ToolExecuteStartEvent.toolName} (W-049). */
197
+ readonly toolName?: string;
198
+ readonly result: unknown;
199
+ readonly durationMs: number;
200
+ }
201
+
202
+ /** @stable */
203
+ export interface ToolExecuteErrorEvent {
204
+ readonly type: 'tool.execute.error';
205
+ readonly toolCallId: string;
206
+ /** See {@link ToolExecuteStartEvent.toolName} (W-049). */
207
+ readonly toolName?: string;
208
+ readonly error: ToolError;
209
+ }
210
+
211
+ /** @stable */
212
+ export interface ToolApprovalRequestedEvent {
213
+ readonly type: 'tool.approval.requested';
214
+ readonly toolCallId: string;
215
+ readonly reason?: string;
216
+ }
217
+
218
+ /** @stable */
219
+ export interface ToolApprovalGrantedEvent {
220
+ readonly type: 'tool.approval.granted';
221
+ readonly toolCallId: string;
222
+ }
223
+
224
+ /** @stable */
225
+ export interface ToolApprovalDeniedEvent {
226
+ readonly type: 'tool.approval.denied';
227
+ readonly toolCallId: string;
228
+ readonly reason?: string;
229
+ }
230
+
231
+ /**
232
+ * Emitted when the runtime auto-compacts the in-flight session
233
+ * message-history to fit the context window.
234
+ *
235
+ * @stable
236
+ */
237
+ export interface ContextCompactedEvent {
238
+ readonly type: 'context.compacted';
239
+ readonly runId: string;
240
+ readonly sessionId: string;
241
+ readonly agentId: string;
242
+ readonly beforeTokens: number;
243
+ readonly afterTokens: number;
244
+ readonly summaryTokens: number;
245
+ readonly durationMs: number;
246
+ readonly source: 'auto-trigger' | 'manual' | 'pre-step';
247
+ readonly hooksFiredCount: number;
248
+ }
249
+
250
+ /** @stable */
251
+ export interface HandoffEvent {
252
+ readonly type: 'handoff';
253
+ readonly fromAgentId: string;
254
+ readonly toAgentId: string;
255
+ readonly reason?: string;
256
+ }
257
+
258
+ /**
259
+ * A provider-generated file surfaced from the model stream (AG-26) -
260
+ * previously these `'file'` provider events were silently dropped.
261
+ *
262
+ * @stable
263
+ */
264
+ export interface FileGeneratedEvent {
265
+ readonly type: 'file.generated';
266
+ readonly mimeType: string;
267
+ readonly data: Uint8Array;
268
+ }
269
+
270
+ /**
271
+ * A provider citation surfaced from the model stream (AG-26) -
272
+ * previously these `'source'` provider events were silently dropped.
273
+ *
274
+ * @stable
275
+ */
276
+ export interface SourceCitedEvent {
277
+ readonly type: 'source.cited';
278
+ readonly uri: string;
279
+ readonly title?: string;
280
+ }
281
+
282
+ /** @stable */
283
+ export interface StepEndEvent {
284
+ readonly type: 'step.end';
285
+ readonly stepNumber: number;
286
+ readonly usage: Usage;
287
+ }
288
+
289
+ /** @stable */
290
+ export interface GuardrailTrippedEvent {
291
+ readonly type: 'guardrail.tripped';
292
+ readonly guardrailName: string;
293
+ readonly phase: 'input' | 'output';
294
+ readonly reason?: string;
295
+ }
296
+
297
+ /**
298
+ * Outcome of a terminal-response verifier check (C3). Emitted once per
299
+ * verifier per verification round; a failed verifier's `feedback` is
300
+ * also appended to the transcript so the model can address it.
301
+ *
302
+ * @stable
303
+ */
304
+ export interface VerifierResultEvent {
305
+ readonly type: 'verifier.result';
306
+ readonly verifierId: string;
307
+ readonly ok: boolean;
308
+ readonly feedback?: string;
309
+ readonly stepNumber: number;
310
+ }
311
+
312
+ /** @stable */
313
+ export interface AgentEndEvent<TOutput = string> {
314
+ readonly type: 'agent.end';
315
+ readonly runId: string;
316
+ readonly result: AgentResult<TOutput>;
317
+ }
318
+
319
+ /** @stable */
320
+ export interface AgentErrorEvent {
321
+ readonly type: 'agent.error';
322
+ readonly error: { readonly message: string; readonly code: string };
323
+ }
324
+
325
+ /**
326
+ * Emitted when `agent.steer(...)` queues an intervention to flow into
327
+ * the next provider call within the current run.
328
+ *
329
+ * @stable
330
+ */
331
+ export interface AgentSteeredEvent {
332
+ readonly type: 'agent.steered';
333
+ readonly runId: string;
334
+ }
335
+
336
+ /**
337
+ * Emitted when `agent.followUp(...)` queues a follow-up turn to fire
338
+ * after the current turn completes.
339
+ *
340
+ * @stable
341
+ */
342
+ export interface AgentFollowUpQueuedEvent {
343
+ readonly type: 'agent.followup.queued';
344
+ readonly runId: string;
345
+ }
346
+
347
+ /**
348
+ * Emitted at the moment `agent.abort({ ... })` is called, before any
349
+ * pending tool / provider calls have terminated. Subscribers use this
350
+ * to render "cancelling..." UI before the run actually winds down.
351
+ *
352
+ * @stable
353
+ */
354
+ export interface AgentCancellingEvent {
355
+ readonly type: 'agent.cancelling';
356
+ readonly runId: string;
357
+ readonly drain: boolean;
358
+ readonly onPendingApprovals: 'deny' | 'hold' | 'fail';
359
+ }
360
+
361
+ /**
362
+ * Emitted exactly once per agent-level model-fallback transition.
363
+ * Identifies the failed primary, the next model in
364
+ * `Agent.fallbackModels`, the eligible reason taxonomy, the
365
+ * 1-based step number and the 1-based attempt index within the step.
366
+ *
367
+ * The event fires BEFORE the new model's stream starts so that
368
+ * observers see the transition before any of the new model's
369
+ * subsequent events flow.
370
+ *
371
+ * @stable
372
+ */
373
+ export interface AgentModelFellbackEvent {
374
+ readonly type: 'agent.model.fellback';
375
+ readonly runId: string;
376
+ readonly sessionId: string;
377
+ readonly agentId: string;
378
+ readonly from: string;
379
+ readonly to: string;
380
+ readonly reason: 'rate-limit' | 'capacity' | 'context-length' | 'transient';
381
+ readonly stepNumber: number;
382
+ readonly attempt: number;
383
+ }
384
+
385
+ /**
386
+ * Emitted when `Agent.fanOut(...)` begins to spawn its sub-agents.
387
+ *
388
+ * @stable
389
+ */
390
+ export interface AgentFanOutSpawnedEvent {
391
+ readonly type: 'agent.fanout.spawned';
392
+ readonly runId: string;
393
+ readonly sessionId: string;
394
+ readonly agentId: string;
395
+ readonly fanOutId: string;
396
+ readonly childCount: number;
397
+ readonly mergeStrategyKind: 'concat' | 'first-success' | 'judge-merge' | 'custom';
398
+ readonly spawnedAtIso: string;
399
+ }
400
+
401
+ /**
402
+ * Per-child result entry surfaced on
403
+ * {@link AgentFanOutMergedEvent.childMetadata}.
404
+ *
405
+ * @stable
406
+ */
407
+ export interface FanOutChildMetadata {
408
+ readonly agentId: string;
409
+ readonly status: 'completed' | 'failed' | 'budget-exceeded' | 'cancelled';
410
+ readonly tokensUsed: number;
411
+ readonly toolCallCount: number;
412
+ readonly durationMs: number;
413
+ }
414
+
415
+ /**
416
+ * Emitted when the fan-out merge step completes.
417
+ *
418
+ * @stable
419
+ */
420
+ export interface AgentFanOutMergedEvent {
421
+ readonly type: 'agent.fanout.merged';
422
+ readonly runId: string;
423
+ readonly sessionId: string;
424
+ readonly agentId: string;
425
+ readonly fanOutId: string;
426
+ readonly childCount: number;
427
+ readonly successfulChildCount: number;
428
+ readonly mergeStrategyKind: 'concat' | 'first-success' | 'judge-merge' | 'custom';
429
+ readonly mergeDurationMs: number;
430
+ readonly childMetadata: ReadonlyArray<FanOutChildMetadata>;
431
+ }
432
+
433
+ /**
434
+ * Emitted per iteration of an `evaluatorOptimizer({...})` loop.
435
+ *
436
+ * @stable
437
+ */
438
+ export interface AgentEvaluatorIterationEvent {
439
+ readonly type: 'agent.evaluator.iteration';
440
+ readonly runId: string;
441
+ readonly sessionId: string;
442
+ readonly agentId: string;
443
+ readonly iteration: number;
444
+ readonly score: number;
445
+ readonly pass: boolean;
446
+ readonly critique: string;
447
+ readonly durationMs: number;
448
+ }
449
+
450
+ /**
451
+ * Emitted at the termination of an `evaluatorOptimizer({...})` loop.
452
+ *
453
+ * @stable
454
+ */
455
+ export interface AgentEvaluatorConvergedEvent {
456
+ readonly type: 'agent.evaluator.converged';
457
+ readonly runId: string;
458
+ readonly sessionId: string;
459
+ readonly agentId: string;
460
+ readonly totalIterations: number;
461
+ readonly finalScore: number;
462
+ readonly terminationReason: 'pass' | 'maxIterations' | 'generator-exhausted' | 'cancelled';
463
+ }
464
+
465
+ /**
466
+ * Reference to a persisted progress artifact returned by
467
+ * `agent.progress.write(...)` and `agent.progress.read(...)`.
468
+ *
469
+ * @stable
470
+ */
471
+ export interface ProgressArtifactRef {
472
+ readonly path: string;
473
+ readonly role: string;
474
+ readonly seq: number;
475
+ readonly sizeBytes: number;
476
+ readonly sensitivity: 'public' | 'internal' | 'secret';
477
+ readonly tags?: ReadonlyArray<string>;
478
+ readonly writtenAtIso: string;
479
+ readonly sha256: string;
480
+ }
481
+
482
+ /**
483
+ * Emitted after `agent.progress.write(...)` completes.
484
+ *
485
+ * @stable
486
+ */
487
+ export interface AgentProgressWrittenEvent {
488
+ readonly type: 'agent.progress.written';
489
+ readonly runId: string;
490
+ readonly sessionId: string;
491
+ readonly agentId: string;
492
+ readonly ref: ProgressArtifactRef;
493
+ }
494
+
495
+ /**
496
+ * Emitted after `agent.progress.read(...)` completes.
497
+ *
498
+ * @stable
499
+ */
500
+ export interface AgentProgressReadEvent {
501
+ readonly type: 'agent.progress.read';
502
+ readonly runId: string;
503
+ readonly sessionId: string;
504
+ readonly agentId: string;
505
+ readonly refs: ReadonlyArray<ProgressArtifactRef>;
506
+ readonly queriedRunId: string;
507
+ readonly queriedRole: string | undefined;
508
+ }
509
+
510
+ /**
511
+ * Lateral-leak vector classification surfaced on
512
+ * {@link AgentLateralLeakDetectedEvent.vector}.
513
+ *
514
+ * - `'causality-laundering'` - the assistant message references
515
+ * information about a denied earlier action via an indirect chain.
516
+ * - `'commentary-phase'` - operator-only commentary content was
517
+ * about to escape the session-output boundary.
518
+ * - `'sideways-injection'` - a low-trust child of an
519
+ * `Agent.fanOut(...)` `'judge-merge'` strategy contributed
520
+ * disproportionately to the merged output.
521
+ * - `'protocol-header'` - control-character bytes or a
522
+ * protocol-frame separator was about to escape one of the
523
+ * internal-service delivery boundaries.
524
+ *
525
+ * @stable
526
+ */
527
+ export type LateralLeakVector =
528
+ | 'causality-laundering'
529
+ | 'commentary-phase'
530
+ | 'sideways-injection'
531
+ | 'protocol-header';
532
+
533
+ /**
534
+ * Emitted when the lateral-leak defense layer flags or blocks a
535
+ * suspected leak.
536
+ *
537
+ * @stable
538
+ */
539
+ export interface AgentLateralLeakDetectedEvent {
540
+ readonly type: 'agent.lateral-leak.detected';
541
+ readonly runId: string;
542
+ readonly sessionId: string;
543
+ readonly agentId: string;
544
+ readonly vector: LateralLeakVector;
545
+ readonly severity: 'info' | 'warn' | 'block';
546
+ readonly causalityChain: ReadonlyArray<string>;
547
+ readonly messageContentSha256: string;
548
+ readonly matchedPattern?: string;
549
+ readonly decision: 'detect' | 'flag' | 'strip' | 'block';
550
+ readonly detectedAtIso: string;
551
+ }
552
+
553
+ /**
554
+ * Final result of an agent run-loop invocation, returned by
555
+ * `agent.run(...)` and carried by the `agent.end` event.
556
+ *
557
+ * A failed run **resolves** with `status: 'failed'` and the error in
558
+ * `error` - `agent.run(...)` does not reject on run failure (only on
559
+ * configuration/usage errors thrown before the loop starts). A suspended
560
+ * run resolves with `status: 'awaiting_approval'` and a resumable
561
+ * `state` (AG-9).
562
+ *
563
+ * @stable
564
+ */
565
+ export interface AgentResult<TOutput = string> {
566
+ readonly output: TOutput;
567
+ readonly usage: Usage;
568
+ /** Terminal status of this run-loop invocation. */
569
+ readonly status: RunStatus;
570
+ /** Populated when the run failed; mirrors `RunState.error`. */
571
+ readonly error?: RunError;
572
+ /**
573
+ * The run's final state. Resumable when `status === 'awaiting_approval'`
574
+ * - pass it back to `agent.run(...)` / `agent.stream(...)` (optionally
575
+ * round-tripped through `runStateToJSON`/`runStateFromJSON` for
576
+ * durability). Treat as an immutable snapshot.
577
+ */
578
+ readonly state: RunState;
579
+ }
@@ -0,0 +1,111 @@
1
+ import type { Message } from './message.js';
2
+
3
+ /**
4
+ * Filter applied to the parent's message history when handing off control
5
+ * to a target agent. Implementations live in `@graphorin/agent` (e.g.
6
+ * `filters.lastN(10)`); the contract type lives here so every package
7
+ * (server, sessions, observability, …) can type a parameter as
8
+ * `HandoffFilter` without an agent dependency.
9
+ *
10
+ * The default for the agent runtime is `lastN(10)` (per the security-first
11
+ * compose policy). Filters should be **pure** - they receive a frozen
12
+ * history and return a fresh array.
13
+ *
14
+ * @stable
15
+ */
16
+ export type HandoffFilter = (history: readonly Message[]) => readonly Message[];
17
+
18
+ /**
19
+ * Declarative handoff target. The value carries a reference to the target
20
+ * agent (`agentId` - looked up at runtime via the `AgentRegistry`) plus
21
+ * optional metadata used by the runtime when constructing the
22
+ * `transfer_to_<agentName>` virtual tool.
23
+ *
24
+ * @stable
25
+ */
26
+ export interface Handoff {
27
+ /** ID of the target agent (looked up via `AgentRegistry`). */
28
+ readonly targetAgentId: string;
29
+ /** Optional human-readable name, surfaced in the virtual tool name. */
30
+ readonly targetAgentName?: string;
31
+ /** Optional input filter applied to the parent's history. */
32
+ readonly inputFilter?: HandoffFilter;
33
+ /** Optional human-readable reason rendered in the audit log. */
34
+ readonly reason?: string;
35
+ }
36
+
37
+ /**
38
+ * Stable, serializable description of the input filter applied to a
39
+ * handoff. Persisted alongside `HandoffRecord` and round-tripped through
40
+ * the JSONL session export so a replay can re-construct the filter
41
+ * stack even after the runtime filter implementations evolve.
42
+ *
43
+ * The discriminator `kind` is an open string union - well-known kinds
44
+ * include `'full' | 'last-n' | 'last-user' | 'summary' |
45
+ * 'sensitivity-filter' | 'compose' | 'custom'`. The accompanying `meta`
46
+ * carries kind-specific data (for example `{ n: 10 }` for `'last-n'`,
47
+ * `{ summary: '...' }` for `'summary'`, or
48
+ * `{ messagesPassedCount, strippedReasoningCount, ... }` summary stats
49
+ * for `'compose'`). New kinds may be added freely; consumers must not
50
+ * assume an exhaustive switch.
51
+ *
52
+ * @stable
53
+ */
54
+ export interface HandoffInputFilterDescriptor {
55
+ readonly kind: string;
56
+ readonly meta?: Readonly<Record<string, unknown>>;
57
+ }
58
+
59
+ /**
60
+ * How the parent's secrets surface is propagated to the sub-agent
61
+ * during a handoff. The default - `'inherit-allowlist'` with an empty
62
+ * inherited list - applies the principle of least authority: the sub-
63
+ * agent inherits only the keys the operator has explicitly named.
64
+ *
65
+ * - `'inherit-allowlist'` - inherit the keys named in
66
+ * `inheritedSecrets`. Empty list = no inheritance.
67
+ * - `'isolated'` - the sub-agent runs with an empty secrets surface.
68
+ * - `'forward-explicit'` - every secret access on the sub-agent's side
69
+ * must be explicitly broadened by the operator with a recorded
70
+ * `secretsOverrideReason`.
71
+ *
72
+ * @stable
73
+ */
74
+ export type HandoffSecretsInheritance = 'inherit-allowlist' | 'isolated' | 'forward-explicit';
75
+
76
+ /**
77
+ * Recorded handoff event captured on `RunState.handoffs` and replayed by
78
+ * the JSONL session export. The shape is wire-stable.
79
+ *
80
+ * @stable
81
+ */
82
+ export interface HandoffRecord {
83
+ readonly fromAgentId: string;
84
+ readonly toAgentId: string;
85
+ readonly stepNumber: number;
86
+ readonly at: string;
87
+ readonly reason?: string;
88
+ /**
89
+ * Serializable input-filter descriptor applied at handoff time. When
90
+ * undefined the runtime defaults applied (commonly
91
+ * `compose(lastN(10), stripReasoning, stripSensitiveOutputs)`); the
92
+ * concrete filter implementations live in `@graphorin/agent`.
93
+ */
94
+ readonly inputFilter?: HandoffInputFilterDescriptor;
95
+ /**
96
+ * Sub-agent secrets propagation policy. Defaults to
97
+ * `'inherit-allowlist'` with empty `inheritedSecrets`.
98
+ */
99
+ readonly secretsInheritance?: HandoffSecretsInheritance;
100
+ /**
101
+ * Keys inherited by the sub-agent under the
102
+ * `'inherit-allowlist'` / `'forward-explicit'` policies. Never the
103
+ * secret values themselves - only the public key names.
104
+ */
105
+ readonly inheritedSecrets?: ReadonlyArray<string>;
106
+ /**
107
+ * Operator-supplied justification for broadening or narrowing the
108
+ * default secrets surface. Surfaced in audit logs.
109
+ */
110
+ readonly secretsOverrideReason?: string;
111
+ }