@zhivex-ai/core 0.4.0 → 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.
Files changed (64) hide show
  1. package/dist/agent-approval.d.ts +6 -0
  2. package/dist/agent-approval.d.ts.map +1 -0
  3. package/dist/agent-approval.js +38 -0
  4. package/dist/agent-approval.js.map +1 -0
  5. package/dist/agent-handoff.d.ts +11 -0
  6. package/dist/agent-handoff.d.ts.map +1 -0
  7. package/dist/agent-handoff.js +20 -0
  8. package/dist/agent-handoff.js.map +1 -0
  9. package/dist/agent-store.d.ts +20 -0
  10. package/dist/agent-store.d.ts.map +1 -0
  11. package/dist/agent-store.js +252 -0
  12. package/dist/agent-store.js.map +1 -0
  13. package/dist/agent.d.ts +8 -0
  14. package/dist/agent.d.ts.map +1 -0
  15. package/dist/agent.js +701 -0
  16. package/dist/agent.js.map +1 -0
  17. package/dist/catalog.js +1 -1
  18. package/dist/catalog.js.map +1 -1
  19. package/dist/errors.d.ts +8 -0
  20. package/dist/errors.d.ts.map +1 -1
  21. package/dist/errors.js +9 -0
  22. package/dist/errors.js.map +1 -1
  23. package/dist/generate-text.d.ts.map +1 -1
  24. package/dist/generate-text.js +87 -9
  25. package/dist/generate-text.js.map +1 -1
  26. package/dist/index.d.ts +13 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +10 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/live-agent.d.ts +3 -0
  31. package/dist/live-agent.d.ts.map +1 -0
  32. package/dist/live-agent.js +565 -0
  33. package/dist/live-agent.js.map +1 -0
  34. package/dist/mcp.d.ts +40 -0
  35. package/dist/mcp.d.ts.map +1 -0
  36. package/dist/mcp.js +167 -0
  37. package/dist/mcp.js.map +1 -0
  38. package/dist/messages.d.ts +9 -1
  39. package/dist/messages.d.ts.map +1 -1
  40. package/dist/messages.js +55 -0
  41. package/dist/messages.js.map +1 -1
  42. package/dist/observability.d.ts +51 -0
  43. package/dist/observability.d.ts.map +1 -0
  44. package/dist/observability.js +276 -0
  45. package/dist/observability.js.map +1 -0
  46. package/dist/realtime.d.ts +52 -0
  47. package/dist/realtime.d.ts.map +1 -0
  48. package/dist/realtime.js +304 -0
  49. package/dist/realtime.js.map +1 -0
  50. package/dist/stream.d.ts +5 -2
  51. package/dist/stream.d.ts.map +1 -1
  52. package/dist/stream.js +1 -0
  53. package/dist/stream.js.map +1 -1
  54. package/dist/tool-registry.d.ts +17 -0
  55. package/dist/tool-registry.d.ts.map +1 -0
  56. package/dist/tool-registry.js +74 -0
  57. package/dist/tool-registry.js.map +1 -0
  58. package/dist/types.d.ts +589 -6
  59. package/dist/types.d.ts.map +1 -1
  60. package/dist/ui.d.ts +4 -2
  61. package/dist/ui.d.ts.map +1 -1
  62. package/dist/ui.js +47 -0
  63. package/dist/ui.js.map +1 -1
  64. package/package.json +1 -1
package/dist/agent.js ADDED
@@ -0,0 +1,701 @@
1
+ import { createAgentApprovalMessage, getAgentApprovalRequests } from "./agent-approval.js";
2
+ import { createAgentHandoffMessage } from "./agent-handoff.js";
3
+ import { GuardrailTriggeredError, ValidationError } from "./errors.js";
4
+ import { generateText, normalizeMessages, streamText } from "./generate-text.js";
5
+ import { toToolSet } from "./tool-registry.js";
6
+ const randomId = (prefix) => `${prefix}_${Math.random().toString(36).slice(2, 10)}`;
7
+ const joinInstructions = (...parts) => {
8
+ const content = parts.map((part) => part?.trim()).filter((part) => Boolean(part));
9
+ return content.length ? content.join("\n\n") : undefined;
10
+ };
11
+ const hasToolCalls = (messages) => messages.some((message) => message.parts.some((part) => part.type === "tool-call"));
12
+ const snapshotRequest = (request) => ({
13
+ messages: request.messages,
14
+ toolChoice: request.toolChoice,
15
+ toolExecution: request.toolExecution,
16
+ temperature: request.temperature,
17
+ maxTokens: request.maxTokens,
18
+ reasoning: request.reasoning,
19
+ providerOptions: request.providerOptions,
20
+ timeoutMs: request.timeoutMs,
21
+ maxRetries: request.maxRetries,
22
+ retryBackoffMs: request.retryBackoffMs
23
+ });
24
+ const snapshotResponse = (response) => ({
25
+ messages: response.messages ?? (response.message ? [response.message] : []),
26
+ text: response.text,
27
+ finishReason: response.finishReason,
28
+ providerFinishReason: response.providerFinishReason,
29
+ usage: response.usage
30
+ });
31
+ const countToolCalls = (messages) => messages.reduce((total, message) => total + message.parts.filter((part) => part.type === "tool-call").length, 0);
32
+ const mapSteps = (steps, offset, toolResults) => {
33
+ let toolResultCursor = 0;
34
+ return steps.map((step, index) => {
35
+ const response = snapshotResponse(step.response);
36
+ const toolCallCount = countToolCalls(response.messages);
37
+ const stepToolResults = toolResults.slice(toolResultCursor, toolResultCursor + toolCallCount);
38
+ toolResultCursor += toolCallCount;
39
+ const finishedAt = Date.now();
40
+ return {
41
+ index: offset + index + 1,
42
+ status: "completed",
43
+ startedAt: finishedAt,
44
+ finishedAt,
45
+ request: snapshotRequest(step.request),
46
+ response,
47
+ toolResults: stepToolResults
48
+ };
49
+ });
50
+ };
51
+ const cloneMetadata = (...values) => {
52
+ const merged = Object.assign({}, ...values.filter(Boolean));
53
+ return Object.keys(merged).length ? merged : undefined;
54
+ };
55
+ const toOutput = (state) => ({
56
+ status: state.status,
57
+ outputText: state.outputText,
58
+ finishReason: state.finishReason,
59
+ providerFinishReason: state.providerFinishReason,
60
+ usage: state.usage,
61
+ messages: state.messages,
62
+ steps: state.steps,
63
+ toolResults: state.toolResults,
64
+ state,
65
+ error: state.error
66
+ });
67
+ const cloneState = (state) => JSON.parse(JSON.stringify(state));
68
+ const createBaseState = (provider, modelId, initialMessages, maxSteps, metadata, agentId, runId, handoff) => {
69
+ const startedAt = Date.now();
70
+ return {
71
+ runId,
72
+ agentId,
73
+ parentRunId: handoff?.fromRunId,
74
+ provider,
75
+ modelId,
76
+ status: "running",
77
+ messages: initialMessages,
78
+ steps: [],
79
+ toolResults: [],
80
+ currentStep: 0,
81
+ maxSteps,
82
+ outputText: "",
83
+ pendingApprovals: [],
84
+ metadata,
85
+ handoff,
86
+ startedAt,
87
+ updatedAt: startedAt
88
+ };
89
+ };
90
+ const ensureValidStateInput = (input) => {
91
+ if (input.approvals?.length && !input.state) {
92
+ throw new ValidationError('The "approvals" option requires an existing agent "state".');
93
+ }
94
+ if (!input.state) {
95
+ return;
96
+ }
97
+ if (input.prompt !== undefined || input.messages !== undefined || input.system !== undefined || input.handoff !== undefined) {
98
+ throw new ValidationError('Pass either "state" or a fresh "prompt"/"messages" input, but not both.');
99
+ }
100
+ };
101
+ const injectContextMessages = (messages, extraMessages) => {
102
+ if (!extraMessages.length) {
103
+ return messages;
104
+ }
105
+ if (messages[0]?.role === "system") {
106
+ return [messages[0], ...extraMessages, ...messages.slice(1)];
107
+ }
108
+ return [...extraMessages, ...messages];
109
+ };
110
+ const prepareFreshMessages = async (agent, input, runId) => {
111
+ let messages = normalizeMessages({
112
+ prompt: input.prompt,
113
+ messages: input.messages,
114
+ system: joinInstructions(agent.instructions, input.system)
115
+ });
116
+ const handoffMessages = input.handoff
117
+ ? [createAgentHandoffMessage(input.handoff), ...input.handoff.contextMessages.filter((message) => message.role !== "system")]
118
+ : [];
119
+ messages = injectContextMessages(messages, handoffMessages);
120
+ const memoryMessages = agent.memory
121
+ ? await agent.memory.load({
122
+ runId,
123
+ agentId: agent.id,
124
+ metadata: cloneMetadata(agent.metadata, input.metadata)
125
+ })
126
+ : [];
127
+ messages = injectContextMessages(messages, memoryMessages);
128
+ return {
129
+ messages,
130
+ memoryMessages
131
+ };
132
+ };
133
+ const applyApprovalResponses = (messages, approvals, pendingApprovals) => {
134
+ if (!approvals?.length) {
135
+ return {
136
+ messages,
137
+ pendingApprovals
138
+ };
139
+ }
140
+ const pendingById = new Map(pendingApprovals.map((approval) => [approval.id, approval]));
141
+ for (const approval of approvals) {
142
+ const pending = pendingById.get(approval.approvalRequestId);
143
+ if (!pending) {
144
+ throw new ValidationError(`Unknown approval request "${approval.approvalRequestId}".`);
145
+ }
146
+ if (pending.provider !== approval.provider) {
147
+ throw new ValidationError(`Approval request "${approval.approvalRequestId}" belongs to provider "${pending.provider}", not "${approval.provider}".`);
148
+ }
149
+ }
150
+ return {
151
+ messages: [...messages, createAgentApprovalMessage(approvals)],
152
+ pendingApprovals: pendingApprovals.filter((pending) => !approvals.some((approval) => approval.approvalRequestId === pending.id))
153
+ };
154
+ };
155
+ const finalizeState = (state, result, newSteps, newToolResults) => {
156
+ const nextCurrentStep = state.currentStep + newSteps.length;
157
+ const exhausted = nextCurrentStep >= state.maxSteps;
158
+ const lastStep = newSteps.at(-1);
159
+ const unresolvedToolCalls = lastStep?.response ? hasToolCalls(lastStep.response.messages) : false;
160
+ const pendingApprovals = getAgentApprovalRequests(newSteps.flatMap((step) => step.response?.messages ?? []));
161
+ if (pendingApprovals.length) {
162
+ state.status = "suspended";
163
+ state.error = undefined;
164
+ if (lastStep) {
165
+ lastStep.status = "suspended";
166
+ }
167
+ }
168
+ else if (exhausted && unresolvedToolCalls) {
169
+ state.status = "failed";
170
+ state.error = {
171
+ message: "Agent exhausted maxSteps before reaching a terminal response."
172
+ };
173
+ if (lastStep) {
174
+ lastStep.status = "failed";
175
+ lastStep.error = state.error;
176
+ }
177
+ }
178
+ else {
179
+ state.status = "completed";
180
+ state.error = undefined;
181
+ }
182
+ state.messages = result.messages;
183
+ state.steps = [...state.steps, ...newSteps];
184
+ state.toolResults = [...state.toolResults, ...newToolResults];
185
+ state.currentStep = nextCurrentStep;
186
+ state.outputText = result.text;
187
+ state.finishReason = result.finishReason;
188
+ state.providerFinishReason = result.providerFinishReason;
189
+ state.usage = result.usage;
190
+ state.pendingApprovals = pendingApprovals;
191
+ state.updatedAt = Date.now();
192
+ return toOutput(state);
193
+ };
194
+ const emitTelemetryEvent = async (agent, event) => {
195
+ await agent.onTelemetryEvent?.(event);
196
+ };
197
+ const persistState = async (agent, state) => {
198
+ state.updatedAt = Date.now();
199
+ await agent.store?.save(cloneState(state));
200
+ await emitTelemetryEvent(agent, {
201
+ type: "state-saved",
202
+ runId: state.runId,
203
+ agentId: state.agentId,
204
+ status: state.status
205
+ });
206
+ await agent.memory?.save?.({
207
+ runId: state.runId,
208
+ agentId: state.agentId,
209
+ state: cloneState(state),
210
+ metadata: state.metadata
211
+ });
212
+ };
213
+ const approvalsFromEvents = (messages) => getAgentApprovalRequests(messages);
214
+ const emitFinalizedStepTelemetry = async (agent, state, steps) => {
215
+ for (const step of steps) {
216
+ await emitTelemetryEvent(agent, {
217
+ type: "step-finish",
218
+ runId: state.runId,
219
+ agentId: state.agentId,
220
+ step
221
+ });
222
+ }
223
+ };
224
+ const emitApprovalTelemetry = async (agent, state, approvals) => {
225
+ for (const approval of approvals) {
226
+ await emitTelemetryEvent(agent, {
227
+ type: "approval-request",
228
+ runId: state.runId,
229
+ agentId: state.agentId,
230
+ approval
231
+ });
232
+ }
233
+ };
234
+ const emitToolApprovalTelemetry = async (agent, state, event) => {
235
+ await emitTelemetryEvent(agent, {
236
+ type: "tool-approval",
237
+ runId: state.runId,
238
+ agentId: state.agentId,
239
+ toolCall: event.request.toolCall,
240
+ approved: event.decision.approved,
241
+ reason: event.decision.reason,
242
+ metadata: event.decision.metadata
243
+ });
244
+ };
245
+ const normalizeGuardrailTrigger = (value) => value?.triggered ? value : undefined;
246
+ const applyGuardrailFailure = (state, stage, trigger) => ({
247
+ ...state,
248
+ status: "failed",
249
+ error: {
250
+ message: trigger.reason ?? `Agent ${stage} guardrail triggered.`
251
+ },
252
+ updatedAt: Date.now()
253
+ });
254
+ const runGuardrails = async (agent, state, stage, guardrails, requestFactory) => {
255
+ for (const [index, guardrail] of (guardrails ?? []).entries()) {
256
+ const trigger = normalizeGuardrailTrigger(await guardrail(requestFactory(index)));
257
+ if (!trigger) {
258
+ continue;
259
+ }
260
+ await emitTelemetryEvent(agent, {
261
+ type: "guardrail-triggered",
262
+ runId: state.runId,
263
+ agentId: state.agentId,
264
+ stage,
265
+ reason: trigger.reason ?? `Agent ${stage} guardrail #${index + 1} triggered.`,
266
+ metadata: trigger.metadata
267
+ });
268
+ return trigger;
269
+ }
270
+ return undefined;
271
+ };
272
+ const resolveContext = async (agent, input) => {
273
+ let loadedState = input.state;
274
+ if (!loadedState && input.runId && agent.store) {
275
+ loadedState = await agent.store.load(input.runId);
276
+ }
277
+ const normalizedInput = loadedState ? { ...input, state: loadedState } : input;
278
+ ensureValidStateInput(normalizedInput);
279
+ const metadata = cloneMetadata(agent.metadata, loadedState?.metadata, input.metadata, input.handoff?.metadata);
280
+ if (loadedState) {
281
+ const maxSteps = input.maxSteps ?? loadedState.maxSteps;
282
+ const resumed = applyApprovalResponses(loadedState.messages, input.approvals, loadedState.pendingApprovals);
283
+ return {
284
+ state: {
285
+ ...loadedState,
286
+ agentId: loadedState.agentId ?? agent.id,
287
+ provider: agent.model.provider,
288
+ modelId: agent.model.modelId,
289
+ maxSteps,
290
+ messages: resumed.messages,
291
+ pendingApprovals: resumed.pendingApprovals,
292
+ metadata,
293
+ updatedAt: Date.now()
294
+ },
295
+ messages: resumed.messages,
296
+ remainingSteps: Math.max(0, maxSteps - loadedState.currentStep),
297
+ memoryMessages: []
298
+ };
299
+ }
300
+ const runId = input.runId ?? randomId("run");
301
+ const maxSteps = Math.max(1, input.maxSteps ?? agent.maxSteps ?? 1);
302
+ const prepared = await prepareFreshMessages(agent, input, runId);
303
+ return {
304
+ state: createBaseState(agent.model.provider, agent.model.modelId, prepared.messages, maxSteps, metadata, agent.id, runId, input.handoff),
305
+ messages: prepared.messages,
306
+ remainingSteps: maxSteps,
307
+ memoryMessages: prepared.memoryMessages
308
+ };
309
+ };
310
+ const createGenerateOptions = (agent, state, input, messages, maxSteps) => ({
311
+ model: agent.model,
312
+ messages,
313
+ tools: toToolSet(input.tools ?? agent.tools),
314
+ toolChoice: input.toolChoice,
315
+ toolExecution: input.toolExecution ?? agent.toolExecution,
316
+ toolApprovalPolicy: input.toolApprovalPolicy ?? agent.toolApprovalPolicy,
317
+ onToolApprovalDecision: async (event) => {
318
+ await emitToolApprovalTelemetry(agent, state, event);
319
+ },
320
+ maxSteps,
321
+ temperature: input.temperature ?? agent.temperature,
322
+ maxTokens: input.maxTokens ?? agent.maxTokens,
323
+ reasoning: input.reasoning ?? agent.reasoning,
324
+ providerOptions: input.providerOptions ?? agent.providerOptions,
325
+ abortSignal: input.abortSignal,
326
+ timeoutMs: input.timeoutMs,
327
+ maxRetries: input.maxRetries,
328
+ retryBackoffMs: input.retryBackoffMs
329
+ });
330
+ const emptyAsyncIterable = async function* () {
331
+ return;
332
+ };
333
+ const createFailedState = (state, message) => ({
334
+ ...state,
335
+ status: "failed",
336
+ error: {
337
+ message
338
+ },
339
+ updatedAt: Date.now()
340
+ });
341
+ const emitRunStartTelemetry = async (agent, state, memoryMessages, approvals) => {
342
+ await emitTelemetryEvent(agent, {
343
+ type: "run-start",
344
+ runId: state.runId,
345
+ agentId: state.agentId,
346
+ provider: state.provider,
347
+ modelId: state.modelId,
348
+ maxSteps: state.maxSteps
349
+ });
350
+ if (state.handoff) {
351
+ await emitTelemetryEvent(agent, {
352
+ type: "handoff",
353
+ runId: state.runId,
354
+ agentId: state.agentId,
355
+ handoff: state.handoff
356
+ });
357
+ }
358
+ if (memoryMessages.length) {
359
+ await emitTelemetryEvent(agent, {
360
+ type: "memory-loaded",
361
+ runId: state.runId,
362
+ agentId: state.agentId,
363
+ messageCount: memoryMessages.length
364
+ });
365
+ }
366
+ for (const approval of approvals ?? []) {
367
+ await emitTelemetryEvent(agent, {
368
+ type: "approval-resolved",
369
+ runId: state.runId,
370
+ agentId: state.agentId,
371
+ approval
372
+ });
373
+ }
374
+ };
375
+ const emitRunFinishTelemetry = async (agent, state) => {
376
+ await emitTelemetryEvent(agent, {
377
+ type: "run-finish",
378
+ runId: state.runId,
379
+ agentId: state.agentId,
380
+ status: state.status,
381
+ state: cloneState(state)
382
+ });
383
+ };
384
+ export const createAgent = (definition) => ({
385
+ ...definition,
386
+ metadata: cloneMetadata(definition.metadata)
387
+ });
388
+ export const runAgent = async (agent, input = {}) => {
389
+ const context = await resolveContext(agent, input);
390
+ await emitRunStartTelemetry(agent, context.state, context.memoryMessages, input.approvals);
391
+ if (context.state.status === "completed" || context.state.status === "cancelled") {
392
+ return toOutput(context.state);
393
+ }
394
+ if (context.state.status === "suspended" && context.state.pendingApprovals.length > 0 && !input.approvals?.length) {
395
+ return toOutput(context.state);
396
+ }
397
+ if (context.remainingSteps === 0) {
398
+ const state = createFailedState(context.state, "Agent exhausted maxSteps before reaching a terminal response.");
399
+ await persistState(agent, state);
400
+ await emitRunFinishTelemetry(agent, state);
401
+ return toOutput(state);
402
+ }
403
+ const inputGuardrail = await runGuardrails(agent, context.state, "input", agent.inputGuardrails, () => ({
404
+ runId: context.state.runId,
405
+ agentId: context.state.agentId,
406
+ messages: context.messages,
407
+ metadata: context.state.metadata
408
+ }));
409
+ if (inputGuardrail) {
410
+ const failedState = applyGuardrailFailure(context.state, "input", inputGuardrail);
411
+ await persistState(agent, failedState);
412
+ await emitRunFinishTelemetry(agent, failedState);
413
+ return toOutput(failedState);
414
+ }
415
+ await emitTelemetryEvent(agent, {
416
+ type: "step-start",
417
+ runId: context.state.runId,
418
+ agentId: context.state.agentId,
419
+ stepIndex: context.state.currentStep + 1
420
+ });
421
+ try {
422
+ const result = await generateText(createGenerateOptions(agent, context.state, input, context.messages, context.remainingSteps));
423
+ const newSteps = mapSteps(result.steps, context.state.currentStep, result.toolResults);
424
+ let output = finalizeState(context.state, result, newSteps, result.toolResults);
425
+ const outputGuardrail = await runGuardrails(agent, output.state, "output", agent.outputGuardrails, () => ({
426
+ runId: output.state.runId,
427
+ agentId: output.state.agentId,
428
+ state: cloneState(output.state),
429
+ output,
430
+ metadata: output.state.metadata
431
+ }));
432
+ if (outputGuardrail) {
433
+ output = toOutput(applyGuardrailFailure(output.state, "output", outputGuardrail));
434
+ }
435
+ await emitFinalizedStepTelemetry(agent, output.state, newSteps);
436
+ await emitApprovalTelemetry(agent, output.state, approvalsFromEvents(newSteps.flatMap((step) => step.response?.messages ?? [])));
437
+ await persistState(agent, output.state);
438
+ await emitRunFinishTelemetry(agent, output.state);
439
+ return output;
440
+ }
441
+ catch (error) {
442
+ const failedState = createFailedState(context.state, error instanceof Error ? error.message : String(error));
443
+ await persistState(agent, failedState);
444
+ await emitRunFinishTelemetry(agent, failedState);
445
+ throw error;
446
+ }
447
+ };
448
+ export const streamAgent = (agent, input = {}) => {
449
+ const subscribers = new Set();
450
+ const history = [];
451
+ let done = false;
452
+ const publish = (value) => {
453
+ history.push(value);
454
+ for (const subscriber of subscribers) {
455
+ subscriber(value);
456
+ }
457
+ if (value.done) {
458
+ done = true;
459
+ }
460
+ };
461
+ const createEventStream = async function* () {
462
+ let cursor = 0;
463
+ while (true) {
464
+ while (cursor < history.length) {
465
+ const item = history[cursor];
466
+ cursor += 1;
467
+ if (item.done) {
468
+ return;
469
+ }
470
+ yield item.value;
471
+ }
472
+ if (done) {
473
+ return;
474
+ }
475
+ await new Promise((resolve) => {
476
+ const subscriber = (value) => {
477
+ subscribers.delete(subscriber);
478
+ resolve(value);
479
+ };
480
+ subscribers.add(subscriber);
481
+ });
482
+ }
483
+ };
484
+ const runner = (async () => {
485
+ const context = await resolveContext(agent, input);
486
+ await emitRunStartTelemetry(agent, context.state, context.memoryMessages, input.approvals);
487
+ if (context.state.status === "completed" || context.state.status === "cancelled") {
488
+ publish({ done: true, value: undefined });
489
+ return {
490
+ output: toOutput(context.state),
491
+ textStream: emptyAsyncIterable()
492
+ };
493
+ }
494
+ if (context.state.status === "suspended" && context.state.pendingApprovals.length > 0 && !input.approvals?.length) {
495
+ publish({ done: true, value: undefined });
496
+ return {
497
+ output: toOutput(context.state),
498
+ textStream: emptyAsyncIterable()
499
+ };
500
+ }
501
+ if (context.remainingSteps === 0) {
502
+ const state = createFailedState(context.state, "Agent exhausted maxSteps before reaching a terminal response.");
503
+ await persistState(agent, state);
504
+ await emitRunFinishTelemetry(agent, state);
505
+ publish({ done: true, value: undefined });
506
+ return {
507
+ output: toOutput(state),
508
+ textStream: emptyAsyncIterable()
509
+ };
510
+ }
511
+ const inputGuardrail = await runGuardrails(agent, context.state, "input", agent.inputGuardrails, () => ({
512
+ runId: context.state.runId,
513
+ agentId: context.state.agentId,
514
+ messages: context.messages,
515
+ metadata: context.state.metadata
516
+ }));
517
+ if (inputGuardrail) {
518
+ const failedState = applyGuardrailFailure(context.state, "input", inputGuardrail);
519
+ await persistState(agent, failedState);
520
+ await emitRunFinishTelemetry(agent, failedState);
521
+ publish({
522
+ done: false,
523
+ value: {
524
+ type: "error",
525
+ error: new GuardrailTriggeredError("input", failedState.error?.message ?? "Agent input guardrail triggered.", {
526
+ metadata: inputGuardrail.metadata
527
+ })
528
+ }
529
+ });
530
+ publish({
531
+ done: false,
532
+ value: {
533
+ type: "agent-run-finish",
534
+ status: failedState.status,
535
+ state: failedState
536
+ }
537
+ });
538
+ publish({ done: true, value: undefined });
539
+ return {
540
+ output: toOutput(failedState),
541
+ textStream: emptyAsyncIterable()
542
+ };
543
+ }
544
+ publish({
545
+ done: false,
546
+ value: {
547
+ type: "agent-run-start",
548
+ currentStep: context.state.currentStep + 1,
549
+ maxSteps: context.state.maxSteps
550
+ }
551
+ });
552
+ for (const approval of input.approvals ?? []) {
553
+ publish({
554
+ done: false,
555
+ value: {
556
+ type: "agent-approval-resolved",
557
+ approval
558
+ }
559
+ });
560
+ }
561
+ publish({
562
+ done: false,
563
+ value: {
564
+ type: "agent-step-start",
565
+ stepIndex: context.state.currentStep + 1
566
+ }
567
+ });
568
+ await emitTelemetryEvent(agent, {
569
+ type: "step-start",
570
+ runId: context.state.runId,
571
+ agentId: context.state.agentId,
572
+ stepIndex: context.state.currentStep + 1
573
+ });
574
+ const streamResult = streamText(createGenerateOptions(agent, context.state, input, context.messages, context.remainingSteps));
575
+ const approvalRequests = [];
576
+ const eventRelay = (async () => {
577
+ for await (const event of streamResult.eventStream) {
578
+ publish({ done: false, value: event });
579
+ if (event.type === "provider-data" &&
580
+ typeof event.data === "object" &&
581
+ event.data !== null &&
582
+ !Array.isArray(event.data) &&
583
+ event.data.type === "mcp_approval_request" &&
584
+ typeof event.data.id === "string" &&
585
+ typeof event.data.name === "string" &&
586
+ typeof event.data.arguments === "string") {
587
+ const approval = {
588
+ provider: event.provider,
589
+ id: event.data.id,
590
+ name: event.data.name,
591
+ arguments: event.data.arguments,
592
+ serverLabel: typeof event.data.server_label === "string" ? event.data.server_label : undefined,
593
+ rawData: event.data
594
+ };
595
+ approvalRequests.push(approval);
596
+ publish({
597
+ done: false,
598
+ value: {
599
+ type: "agent-approval-request",
600
+ approval
601
+ }
602
+ });
603
+ await emitTelemetryEvent(agent, {
604
+ type: "approval-request",
605
+ runId: context.state.runId,
606
+ agentId: context.state.agentId,
607
+ approval
608
+ });
609
+ }
610
+ }
611
+ })();
612
+ const output = (async () => {
613
+ try {
614
+ await eventRelay;
615
+ const final = await streamResult.collect();
616
+ const newSteps = mapSteps(final.steps, context.state.currentStep, final.toolResults);
617
+ let result = finalizeState(context.state, final, newSteps, final.toolResults);
618
+ const outputGuardrail = await runGuardrails(agent, result.state, "output", agent.outputGuardrails, () => ({
619
+ runId: result.state.runId,
620
+ agentId: result.state.agentId,
621
+ state: cloneState(result.state),
622
+ output: result,
623
+ metadata: result.state.metadata
624
+ }));
625
+ if (outputGuardrail) {
626
+ result = toOutput(applyGuardrailFailure(result.state, "output", outputGuardrail));
627
+ publish({
628
+ done: false,
629
+ value: {
630
+ type: "error",
631
+ error: new GuardrailTriggeredError("output", result.state.error?.message ?? "Agent output guardrail triggered.", { metadata: outputGuardrail.metadata })
632
+ }
633
+ });
634
+ }
635
+ for (const step of newSteps) {
636
+ publish({
637
+ done: false,
638
+ value: {
639
+ type: "agent-step-finish",
640
+ step
641
+ }
642
+ });
643
+ }
644
+ await emitFinalizedStepTelemetry(agent, result.state, newSteps);
645
+ if (!approvalRequests.length) {
646
+ await emitApprovalTelemetry(agent, result.state, approvalsFromEvents(newSteps.flatMap((step) => step.response?.messages ?? [])));
647
+ }
648
+ await persistState(agent, result.state);
649
+ await emitRunFinishTelemetry(agent, result.state);
650
+ publish({
651
+ done: false,
652
+ value: {
653
+ type: "agent-run-finish",
654
+ status: result.status,
655
+ state: result.state
656
+ }
657
+ });
658
+ publish({ done: true, value: undefined });
659
+ return result;
660
+ }
661
+ catch (error) {
662
+ const failedState = createFailedState(context.state, error instanceof Error ? error.message : String(error));
663
+ await persistState(agent, failedState);
664
+ await emitRunFinishTelemetry(agent, failedState);
665
+ publish({
666
+ done: false,
667
+ value: {
668
+ type: "error",
669
+ error: error instanceof Error ? error : new Error(String(error))
670
+ }
671
+ });
672
+ publish({
673
+ done: false,
674
+ value: {
675
+ type: "agent-run-finish",
676
+ status: failedState.status,
677
+ state: failedState
678
+ }
679
+ });
680
+ publish({ done: true, value: undefined });
681
+ throw error;
682
+ }
683
+ })();
684
+ return {
685
+ output,
686
+ textStream: streamResult.textStream
687
+ };
688
+ })();
689
+ return {
690
+ eventStream: createEventStream(),
691
+ textStream: (async function* () {
692
+ const started = await runner;
693
+ for await (const chunk of started.textStream) {
694
+ yield chunk;
695
+ }
696
+ })(),
697
+ collect: async () => (await runner).output
698
+ };
699
+ };
700
+ export const resumeAgent = async (agent, input) => runAgent(agent, input);
701
+ //# sourceMappingURL=agent.js.map