@tangle-network/agent-runtime 0.4.2 → 0.5.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.
package/README.md CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  Reusable runtime lifecycle for domain-specific agents.
4
4
 
5
- `agent-runtime` is the shared skeleton for tax, legal, GTM, creative,
6
- agent-builder generated agents, blueprint-agent, redteam, and similar packages.
7
- It does not own domain policy, tools, connectors, or UI. It standardizes the
8
- task lifecycle and delegates domain behavior to an adapter.
5
+ `agent-runtime` is the shared skeleton for domain agents, generated agents,
6
+ red-team harnesses, coding agents, and similar packages. It does not own domain
7
+ policy, tools, connectors, model routing, or UI. It standardizes the task
8
+ lifecycle and delegates domain behavior to an adapter.
9
9
 
10
10
  ```txt
11
11
  TaskSpec
@@ -16,6 +16,16 @@ TaskSpec
16
16
  -> Run evidence
17
17
  ```
18
18
 
19
+ For product agents that already have a streaming backend, use the stream kernel:
20
+
21
+ ```txt
22
+ TaskSpec
23
+ -> Knowledge readiness
24
+ -> Session create/resume
25
+ -> Backend stream
26
+ -> Sanitized RuntimeStreamEvent/SSE
27
+ ```
28
+
19
29
  ## Install
20
30
 
21
31
  ```bash
@@ -72,6 +82,63 @@ Events cover readiness, question answering, acquisition, control-loop steps,
72
82
  and task completion. This keeps streaming UI, logs, and telemetry out of domain
73
83
  adapters while making every runtime transition observable.
74
84
 
85
+ This package does not stream model tokens for you. Domain adapters and product
86
+ routes still own model calls, tool execution, and token streaming. `agent-runtime`
87
+ emits lifecycle events around those actions, and provides small helpers for
88
+ safe telemetry streams:
89
+
90
+ ```ts
91
+ import { readinessServerSentEvent } from '@tangle-network/agent-runtime'
92
+
93
+ writer.write(encoder.encode(readinessServerSentEvent(readinessReport)))
94
+ ```
95
+
96
+ Use these helpers when an app wants to expose readiness or runtime metadata over
97
+ Server-Sent Events without leaking raw task inputs, credentials, or evidence.
98
+
99
+ For main product loops, prefer `runAgentTaskStream` with an execution backend:
100
+
101
+ ```ts
102
+ import {
103
+ InMemoryRuntimeSessionStore,
104
+ createSandboxPromptBackend,
105
+ runAgentTaskStream,
106
+ runtimeStreamServerSentEvent,
107
+ } from '@tangle-network/agent-runtime'
108
+
109
+ const backend = createSandboxPromptBackend({
110
+ getBox: () => sandboxClient.get(sandboxId),
111
+ streamPrompt: (box, message) => box.streamPrompt(message),
112
+ getSessionId: (box) => box.id,
113
+ })
114
+
115
+ const sessions = new InMemoryRuntimeSessionStore()
116
+
117
+ for await (const event of runAgentTaskStream({
118
+ task,
119
+ backend,
120
+ input: { message },
121
+ sessionId,
122
+ resume: Boolean(sessionId),
123
+ sessionStore: sessions,
124
+ })) {
125
+ writer.write(encoder.encode(runtimeStreamServerSentEvent(event)))
126
+ }
127
+ ```
128
+
129
+ `runAgentTaskStream` is the product-facing kernel. It readiness-gates execution,
130
+ creates or resumes a backend session, normalizes text/tool/artifact/error/final
131
+ events, and lets callers persist resumable session history. The package ships
132
+ SDK-agnostic adapter factories for:
133
+
134
+ - `createOpenAICompatibleBackend` for TCloud/OpenAI-compatible chat APIs.
135
+ - `createCliBridgeBackend` for HTTP CLI bridge streams.
136
+ - `createSandboxPromptBackend` for sandbox/sidecar `streamPrompt` clients.
137
+ - `createIterableBackend` for custom coding harnesses or browser agents.
138
+
139
+ The adapters are intentionally thin. Product repos still own client
140
+ construction, auth, concrete tool permissions, and UI behavior.
141
+
75
142
  For logs, reports, and UI telemetry, do not serialize raw events directly.
76
143
  Use the built-in sanitized collector:
77
144
 
package/dist/index.d.ts CHANGED
@@ -126,6 +126,176 @@ type AgentRuntimeEvent<TState = unknown, TAction = unknown, TActionResult = unkn
126
126
  reason: string;
127
127
  };
128
128
  type AgentRuntimeEventSink<TState = unknown, TAction = unknown, TActionResult = unknown, TEval extends ControlEvalResult = ControlEvalResult> = (event: AgentRuntimeEvent<TState, TAction, TActionResult, TEval>) => Promise<void> | void;
129
+ type RuntimeStreamEvent = {
130
+ type: 'task_start';
131
+ task: AgentTaskSpec;
132
+ timestamp: string;
133
+ } | {
134
+ type: 'readiness_start';
135
+ task: AgentTaskSpec;
136
+ timestamp: string;
137
+ } | {
138
+ type: 'readiness_end';
139
+ task: AgentTaskSpec;
140
+ knowledge: KnowledgeReadinessReport;
141
+ decision: KnowledgeReadinessDecision;
142
+ timestamp: string;
143
+ } | {
144
+ type: 'questions_start';
145
+ task: AgentTaskSpec;
146
+ questions: UserQuestion[];
147
+ timestamp: string;
148
+ } | {
149
+ type: 'questions_end';
150
+ task: AgentTaskSpec;
151
+ questions: UserQuestion[];
152
+ userAnswers: Record<string, string>;
153
+ timestamp: string;
154
+ } | {
155
+ type: 'acquisition_start';
156
+ task: AgentTaskSpec;
157
+ acquisitionPlans: DataAcquisitionPlan[];
158
+ timestamp: string;
159
+ } | {
160
+ type: 'acquisition_end';
161
+ task: AgentTaskSpec;
162
+ acquisitionPlans: DataAcquisitionPlan[];
163
+ acquiredEvidenceIds: string[];
164
+ timestamp: string;
165
+ } | {
166
+ type: 'session_created';
167
+ task: AgentTaskSpec;
168
+ session: RuntimeSession;
169
+ timestamp: string;
170
+ } | {
171
+ type: 'session_resumed';
172
+ task: AgentTaskSpec;
173
+ session: RuntimeSession;
174
+ timestamp: string;
175
+ } | {
176
+ type: 'backend_start';
177
+ task: AgentTaskSpec;
178
+ session: RuntimeSession;
179
+ backend: string;
180
+ timestamp: string;
181
+ } | {
182
+ type: 'text_delta';
183
+ task?: AgentTaskSpec;
184
+ session?: RuntimeSession;
185
+ text: string;
186
+ timestamp?: string;
187
+ } | {
188
+ type: 'reasoning_delta';
189
+ task?: AgentTaskSpec;
190
+ session?: RuntimeSession;
191
+ text: string;
192
+ timestamp?: string;
193
+ } | {
194
+ type: 'tool_call';
195
+ task?: AgentTaskSpec;
196
+ session?: RuntimeSession;
197
+ toolName: string;
198
+ toolCallId?: string;
199
+ args?: unknown;
200
+ timestamp?: string;
201
+ } | {
202
+ type: 'tool_result';
203
+ task?: AgentTaskSpec;
204
+ session?: RuntimeSession;
205
+ toolName: string;
206
+ toolCallId?: string;
207
+ result?: unknown;
208
+ timestamp?: string;
209
+ } | {
210
+ type: 'artifact';
211
+ task?: AgentTaskSpec;
212
+ session?: RuntimeSession;
213
+ artifactId: string;
214
+ name?: string;
215
+ mimeType?: string;
216
+ uri?: string;
217
+ metadata?: Record<string, unknown>;
218
+ timestamp?: string;
219
+ } | {
220
+ type: 'backend_error';
221
+ task: AgentTaskSpec;
222
+ session?: RuntimeSession;
223
+ backend: string;
224
+ message: string;
225
+ recoverable: boolean;
226
+ timestamp: string;
227
+ } | {
228
+ type: 'backend_end';
229
+ task: AgentTaskSpec;
230
+ session: RuntimeSession;
231
+ backend: string;
232
+ timestamp: string;
233
+ } | {
234
+ type: 'task_end';
235
+ task: AgentTaskSpec;
236
+ status: AgentTaskStatus;
237
+ reason: string;
238
+ timestamp: string;
239
+ } | {
240
+ type: 'final';
241
+ task: AgentTaskSpec;
242
+ session?: RuntimeSession;
243
+ status: AgentTaskStatus;
244
+ reason: string;
245
+ text?: string;
246
+ metadata?: Record<string, unknown>;
247
+ timestamp: string;
248
+ };
249
+ interface RuntimeSession {
250
+ id: string;
251
+ backend: string;
252
+ status: 'active' | 'completed' | 'failed' | 'aborted';
253
+ resumeToken?: string;
254
+ createdAt: string;
255
+ updatedAt: string;
256
+ metadata?: Record<string, unknown>;
257
+ }
258
+ interface RuntimeSessionStore {
259
+ get(sessionId: string): Promise<RuntimeSession | undefined> | RuntimeSession | undefined;
260
+ put(session: RuntimeSession): Promise<void> | void;
261
+ appendEvent?(sessionId: string, event: RuntimeStreamEvent): Promise<void> | void;
262
+ listEvents?(sessionId: string): Promise<RuntimeStreamEvent[]> | RuntimeStreamEvent[];
263
+ }
264
+ interface AgentBackendInput {
265
+ task: AgentTaskSpec;
266
+ message?: string;
267
+ messages?: Array<{
268
+ role: string;
269
+ content: string;
270
+ }>;
271
+ inputs?: Record<string, unknown>;
272
+ }
273
+ interface AgentBackendContext {
274
+ task: AgentTaskSpec;
275
+ knowledge: KnowledgeReadinessReport;
276
+ session: RuntimeSession;
277
+ signal?: AbortSignal;
278
+ }
279
+ interface AgentExecutionBackend<TInput extends AgentBackendInput = AgentBackendInput> {
280
+ kind: string;
281
+ start?(input: TInput, context: Omit<AgentBackendContext, 'session'> & {
282
+ requestedSessionId?: string;
283
+ }): Promise<RuntimeSession> | RuntimeSession;
284
+ resume?(session: RuntimeSession, input: TInput, context: Omit<AgentBackendContext, 'session'>): Promise<RuntimeSession> | RuntimeSession;
285
+ stream(input: TInput, context: AgentBackendContext): AsyncIterable<RuntimeStreamEvent>;
286
+ stop?(session: RuntimeSession, reason: string): Promise<void> | void;
287
+ }
288
+ interface RunAgentTaskStreamOptions<TInput extends AgentBackendInput = AgentBackendInput> {
289
+ task: AgentTaskSpec;
290
+ backend: AgentExecutionBackend<TInput>;
291
+ input?: Omit<TInput, 'task'>;
292
+ knowledge?: AgentKnowledgeProvider;
293
+ sessionStore?: RuntimeSessionStore;
294
+ sessionId?: string;
295
+ resume?: boolean;
296
+ signal?: AbortSignal;
297
+ minimumReadinessScore?: number;
298
+ }
129
299
  interface RunAgentTaskOptions<TState, TAction, TActionResult, TEval extends ControlEvalResult = ControlEvalResult> {
130
300
  task: AgentTaskSpec;
131
301
  adapter: AgentAdapter<TState, TAction, TActionResult, TEval>;
@@ -233,15 +403,53 @@ interface ServerSentEventOptions {
233
403
  id?: string;
234
404
  retry?: number;
235
405
  }
406
+ declare class InMemoryRuntimeSessionStore implements RuntimeSessionStore {
407
+ private readonly sessions;
408
+ private readonly events;
409
+ get(sessionId: string): RuntimeSession | undefined;
410
+ put(session: RuntimeSession): void;
411
+ appendEvent(sessionId: string, event: RuntimeStreamEvent): void;
412
+ listEvents(sessionId: string): RuntimeStreamEvent[];
413
+ }
236
414
  declare function runAgentTask<TState, TAction, TActionResult, TEval extends ControlEvalResult = ControlEvalResult>(options: RunAgentTaskOptions<TState, TAction, TActionResult, TEval>): Promise<AgentTaskRunResult<TState, TAction, TActionResult, TEval>>;
237
415
  declare function summarizeAgentTaskRun<TState, TAction, TActionResult, TEval extends ControlEvalResult>(result: AgentTaskRunResult<TState, TAction, TActionResult, TEval>): AgentTaskRunSummary;
416
+ declare function runAgentTaskStream<TInput extends AgentBackendInput = AgentBackendInput>(options: RunAgentTaskStreamOptions<TInput>): AsyncIterable<RuntimeStreamEvent>;
238
417
  declare function decideKnowledgeReadiness(report: KnowledgeReadinessReport, options?: {
239
418
  minimumScore?: number;
240
419
  }): KnowledgeReadinessDecision;
241
420
  declare function sanitizeKnowledgeReadinessReport(report: KnowledgeReadinessReport, options?: RuntimeTelemetryOptions): SanitizedKnowledgeReadinessReport;
242
421
  declare function sanitizeAgentRuntimeEvent<TState, TAction, TActionResult, TEval extends ControlEvalResult>(event: AgentRuntimeEvent<TState, TAction, TActionResult, TEval>, options?: RuntimeTelemetryOptions): Record<string, unknown>;
422
+ declare function sanitizeRuntimeStreamEvent(event: RuntimeStreamEvent, options?: RuntimeTelemetryOptions): Record<string, unknown>;
243
423
  declare function createRuntimeEventCollector<TState = unknown, TAction = unknown, TActionResult = unknown, TEval extends ControlEvalResult = ControlEvalResult>(options?: RuntimeTelemetryOptions): RuntimeEventCollector<TState, TAction, TActionResult, TEval>;
244
424
  declare function encodeServerSentEvent(data: unknown, options?: ServerSentEventOptions): string;
245
425
  declare function readinessServerSentEvent(report: KnowledgeReadinessReport, options?: RuntimeTelemetryOptions & ServerSentEventOptions): string;
426
+ declare function runtimeStreamServerSentEvent(event: RuntimeStreamEvent, options?: RuntimeTelemetryOptions & ServerSentEventOptions): string;
427
+ declare function createIterableBackend<TInput extends AgentBackendInput>(options: {
428
+ kind: string;
429
+ start?: AgentExecutionBackend<TInput>['start'];
430
+ resume?: AgentExecutionBackend<TInput>['resume'];
431
+ stream: AgentExecutionBackend<TInput>['stream'];
432
+ stop?: AgentExecutionBackend<TInput>['stop'];
433
+ }): AgentExecutionBackend<TInput>;
434
+ declare function createSandboxPromptBackend<TBox, TInput extends AgentBackendInput = AgentBackendInput>(options: {
435
+ kind?: string;
436
+ getBox(input: TInput, context: Omit<AgentBackendContext, 'session'>): Promise<TBox> | TBox;
437
+ streamPrompt(box: TBox, message: string, context: AgentBackendContext): AsyncIterable<unknown>;
438
+ mapEvent?: (event: unknown, context: AgentBackendContext) => RuntimeStreamEvent | undefined;
439
+ getSessionId?: (box: TBox, input: TInput) => string | undefined;
440
+ }): AgentExecutionBackend<TInput>;
441
+ declare function createCliBridgeBackend<TInput extends AgentBackendInput = AgentBackendInput>(options: {
442
+ url: string;
443
+ bearer?: string;
444
+ kind?: string;
445
+ fetchImpl?: typeof fetch;
446
+ }): AgentExecutionBackend<TInput>;
447
+ declare function createOpenAICompatibleBackend<TInput extends AgentBackendInput = AgentBackendInput>(options: {
448
+ apiKey: string;
449
+ baseUrl: string;
450
+ model: string;
451
+ kind?: string;
452
+ fetchImpl?: typeof fetch;
453
+ }): AgentExecutionBackend<TInput>;
246
454
 
247
- export { type AgentAdapter, type AgentKnowledgeProvider, type AgentRuntimeEvent, type AgentRuntimeEventSink, type AgentTaskContext, type AgentTaskRunResult, type AgentTaskRunSummary, type AgentTaskSpec, type AgentTaskStatus, type KnowledgeReadinessDecision, type RunAgentTaskOptions, type RuntimeEventCollector, type RuntimeTelemetryOptions, type SanitizedKnowledgeReadinessReport, type SanitizedKnowledgeRequirement, type ServerSentEventOptions, createRuntimeEventCollector, decideKnowledgeReadiness, encodeServerSentEvent, readinessServerSentEvent, runAgentTask, sanitizeAgentRuntimeEvent, sanitizeKnowledgeReadinessReport, summarizeAgentTaskRun };
455
+ export { type AgentAdapter, type AgentBackendContext, type AgentBackendInput, type AgentExecutionBackend, type AgentKnowledgeProvider, type AgentRuntimeEvent, type AgentRuntimeEventSink, type AgentTaskContext, type AgentTaskRunResult, type AgentTaskRunSummary, type AgentTaskSpec, type AgentTaskStatus, InMemoryRuntimeSessionStore, type KnowledgeReadinessDecision, type RunAgentTaskOptions, type RunAgentTaskStreamOptions, type RuntimeEventCollector, type RuntimeSession, type RuntimeSessionStore, type RuntimeStreamEvent, type RuntimeTelemetryOptions, type SanitizedKnowledgeReadinessReport, type SanitizedKnowledgeRequirement, type ServerSentEventOptions, createCliBridgeBackend, createIterableBackend, createOpenAICompatibleBackend, createRuntimeEventCollector, createSandboxPromptBackend, decideKnowledgeReadiness, encodeServerSentEvent, readinessServerSentEvent, runAgentTask, runAgentTaskStream, runtimeStreamServerSentEvent, sanitizeAgentRuntimeEvent, sanitizeKnowledgeReadinessReport, sanitizeRuntimeStreamEvent, summarizeAgentTaskRun };