@tangle-network/agent-runtime 0.94.11 → 0.94.12

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 (58) hide show
  1. package/README.md +65 -1
  2. package/dist/agent.d.ts +2 -1
  3. package/dist/agent.js +2 -1
  4. package/dist/agent.js.map +1 -1
  5. package/dist/{agentic-generator-JT47GnAp.d.ts → agentic-generator-DDMM45kZ.d.ts} +2 -2
  6. package/dist/analyst-loop.d.ts +2 -1
  7. package/dist/backends-BO4Jqoe2.d.ts +134 -0
  8. package/dist/chunk-AEG3NGJ2.js +639 -0
  9. package/dist/chunk-AEG3NGJ2.js.map +1 -0
  10. package/dist/{chunk-OLZ6ZZQ2.js → chunk-D3H7F6L2.js} +11 -8
  11. package/dist/chunk-D3H7F6L2.js.map +1 -0
  12. package/dist/{chunk-5LIOH5DR.js → chunk-PCURO3DL.js} +4 -4
  13. package/dist/chunk-PCURO3DL.js.map +1 -0
  14. package/dist/{chunk-YP6B7RZ2.js → chunk-U33YZ7B2.js} +6 -635
  15. package/dist/chunk-U33YZ7B2.js.map +1 -0
  16. package/dist/chunk-VYA2YEKA.js +1187 -0
  17. package/dist/chunk-VYA2YEKA.js.map +1 -0
  18. package/dist/{chunk-MXBQNVFE.js → chunk-XP5KDM3R.js} +5 -5
  19. package/dist/{completion-gate-Bn4AZ_Kw.d.ts → completion-gate-D1gX1-hg.d.ts} +1 -1
  20. package/dist/conversation.d.ts +793 -0
  21. package/dist/conversation.js +56 -0
  22. package/dist/conversation.js.map +1 -0
  23. package/dist/{coordination-DzwagV_s.d.ts → coordination-Dr_axlAf.d.ts} +5 -4
  24. package/dist/environment-provider.d.ts +3 -2
  25. package/dist/{improve-BucbjddC.d.ts → improve-BN3HyXIO.d.ts} +1 -1
  26. package/dist/index.d.ts +28 -942
  27. package/dist/index.js +58 -1159
  28. package/dist/index.js.map +1 -1
  29. package/dist/intelligence.d.ts +5 -4
  30. package/dist/intelligence.js +5 -5
  31. package/dist/knowledge.d.ts +7 -6
  32. package/dist/lifecycle.d.ts +2 -2
  33. package/dist/lifecycle.js +1 -1
  34. package/dist/{loop-runner-bin-D6K_C6op.d.ts → loop-runner-bin-BRQSQdHa.d.ts} +2 -2
  35. package/dist/loop-runner-bin.d.ts +6 -5
  36. package/dist/loop-runner-bin.js +4 -3
  37. package/dist/loops.d.ts +15 -14
  38. package/dist/loops.js +2 -1
  39. package/dist/mcp/index.d.ts +9 -8
  40. package/dist/mcp/index.js +2 -1
  41. package/dist/mcp/index.js.map +1 -1
  42. package/dist/{mcp-serve-verifier-i6nTNSnu.d.ts → mcp-serve-verifier-DQQDbuyz.d.ts} +1 -1
  43. package/dist/{openai-tools-0wACz8f8.d.ts → openai-tools-fnj6SRVg.d.ts} +1 -1
  44. package/dist/primeintellect/index.d.ts +214 -0
  45. package/dist/primeintellect/index.js +1120 -0
  46. package/dist/primeintellect/index.js.map +1 -0
  47. package/dist/profiles.d.ts +2 -1
  48. package/dist/{sanitize-Dcbjp0tU.d.ts → sanitize-BTSsdBXw.d.ts} +1 -1
  49. package/dist/{supervise-CzyytS-o.d.ts → supervise-DmYOug5f.d.ts} +4 -4
  50. package/dist/{types-CogNCaw7.d.ts → types-1d5QGK3t.d.ts} +1 -1
  51. package/dist/types-BwoZWq-i.d.ts +510 -0
  52. package/dist/{types-CKmyZ9TP.d.ts → types-ByAYqlVb.d.ts} +3 -509
  53. package/dist/{worktree-fanout-Bn7w_1bM.d.ts → worktree-fanout-CPprU-qI.d.ts} +3 -3
  54. package/package.json +15 -3
  55. package/dist/chunk-5LIOH5DR.js.map +0 -1
  56. package/dist/chunk-OLZ6ZZQ2.js.map +0 -1
  57. package/dist/chunk-YP6B7RZ2.js.map +0 -1
  58. /package/dist/{chunk-MXBQNVFE.js.map → chunk-XP5KDM3R.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -1,957 +1,43 @@
1
- import { AgentProfile, MaximumCharge, AgentEvalError, AnalystFinding, KnowledgeReadinessReport, RunRecord, ControlEvalResult } from '@tangle-network/agent-eval';
1
+ import { AgentEvalError, AnalystFinding, KnowledgeReadinessReport, RunRecord, ControlEvalResult } from '@tangle-network/agent-eval';
2
2
  export { AgentEvalError, AgentEvalErrorCode, ConfigError, ControlBudget, ControlDecision, ControlEvalResult, ControlRunResult, ControlStep, DataAcquisitionPlan, JudgeError, KnowledgeReadinessReport, KnowledgeRequirement, NotFoundError, RunRecord, ValidationError } from '@tangle-network/agent-eval';
3
- import { h as AgentBackendInput, O as OpenAIChatTool, i as OpenAIChatToolChoice, j as OpenAIChatResponseFormat, k as AgentExecutionBackend, l as AgentBackendContext, a as RuntimeStreamEvent, K as KnowledgeReadinessDecision, m as RunAgentTaskOptions, n as AgentTaskRunResult, o as RunAgentTaskStreamOptions, p as RuntimeSessionStore, q as RuntimeSession, R as RuntimeHooks } from './types-CKmyZ9TP.js';
4
- export { r as AgentAdapter, s as AgentKnowledgeProvider, A as AgentRuntimeEvent, t as AgentRuntimeEventSink, u as AgentTaskContext, v as AgentTaskSpec, b as AgentTaskStatus, B as BackendErrorDetail, w as RuntimeDecisionEvidenceRef, x as RuntimeDecisionKind, y as RuntimeDecisionPoint, z as RuntimeHookContext, C as RuntimeHookErrorContext, F as RuntimeHookEvent, G as RuntimeHookPhase, H as RuntimeHookTarget, J as RuntimeRunHandle, M as RuntimeRunPersistenceAdapter, N as RuntimeRunRow, P as composeRuntimeHooks, Q as defineRuntimeHooks, T as notifyRuntimeDecisionPoint, U as notifyRuntimeHookEvent, W as startRuntimeRun } from './types-CKmyZ9TP.js';
3
+ import { c as createOpenAICompatibleBackend } from './backends-BO4Jqoe2.js';
4
+ export { a as createIterableBackend, b as createSandboxPromptBackend } from './backends-BO4Jqoe2.js';
5
5
  export { AgentCandidateCodeSource, AgentCandidateCodeSurfaceSource, AgentCandidateModelGrantActivateInput, AgentCandidateModelGrantClient, AgentCandidateModelGrantReservation, AgentCandidateModelGrantReserveInput, AgentCandidateModelGrantSettleInput, AgentCandidateProfileSource, AgentCandidateWorkspaceArchiveLimits, BuildAgentCandidateBundleInput, CaptureAgentCandidateWorkspaceOptions, CapturedAgentCandidateWorkspace, CreateAgentCandidateWorkspacePortOptions, CreateProtectedAgentCandidateModelPortOptions, DisposePreparedAgentCandidateOptions, FileAgentCandidateExecutionClaimStore, FileAgentCandidateExecutionClaimStoreOptions, RecoverExpiredAgentCandidateOptions, applyExactAgentProfileDiff, buildAgentCandidateBundle, candidateExecutionClaim, captureAgentCandidateWorkspace, captureAgentCandidateWorkspaceFiles, createAgentCandidateWorkspacePort, createProtectedAgentCandidateModelPort, disposePreparedAgentCandidateExecution, parseExactAgentProfile, parseExactAgentProfileDiff, persistCandidateOutputArtifact, recoverExpiredAgentCandidateExecution, verifyAgentCandidateBundle } from './candidate-execution/index.js';
6
6
  export { d as AgentCandidateArtifactPort, e as AgentCandidateBenchmarkGraderIdentity, f as AgentCandidateBenchmarkGraderPort, A as AgentCandidateBundleInput, g as AgentCandidateContainerPort, h as AgentCandidateExecutionAttemptRecord, i as AgentCandidateExecutionAttemptRef, j as AgentCandidateExecutionClaim, k as AgentCandidateExecutionClaimResult, l as AgentCandidateExecutionClaimStore, m as AgentCandidateExecutionCleanupHandles, n as AgentCandidateExecutionFailureClass, o as AgentCandidateExecutionFinishResult, p as AgentCandidateExecutionLease, q as AgentCandidateExecutionPhase, r as AgentCandidateExecutionPhaseResult, b as AgentCandidateExecutionPorts, s as AgentCandidateExecutionRecoveryEvidence, t as AgentCandidateExecutionStageResult, u as AgentCandidateExecutionTerminalRecord, v as AgentCandidateExecutionTerminalResult, w as AgentCandidateExecutionUsage, x as AgentCandidateExecutorFinalCapture, y as AgentCandidateExecutorMemoryCapture, z as AgentCandidateExecutorPort, B as AgentCandidateExecutorProfileFile, C as AgentCandidateExecutorRequest, D as AgentCandidateExecutorStopRequest, F as AgentCandidateExecutorTaskOutcomeCapture, G as AgentCandidateExecutorWorkspaceFile, H as AgentCandidateExecutorWorkspaceInput, I as AgentCandidateMemoryPort, J as AgentCandidateMemoryResetResult, K as AgentCandidateModelLimits, L as AgentCandidateModelPort, M as AgentCandidateOutputArtifactPort, N as AgentCandidateOutputPurpose, O as AgentCandidateProtectedModelActivation, Q as AgentCandidateProtectedModelCall, R as AgentCandidateProtectedModelReservation, S as AgentCandidateProtectedModelSettlement, T as AgentCandidateProtectedRunCapture, U as AgentCandidateRepositoryPort, V as AgentCandidateRetryRejection, c as AgentCandidateRunFinalization, a as AgentCandidateTaskExecution, W as AgentCandidateVerificationPorts, X as AgentCandidateWorkspacePort, Y as CANDIDATE_TRACE_ENV, Z as CANDIDATE_TRACE_TAGS, _ as CanonicalCandidateDocument, E as ExecutePreparedAgentCandidateOptions, $ as InMemoryAgentCandidateExecutionClaimStore, P as PrepareAgentCandidateExecutionOptions, a0 as PreparedAgentCandidateExecution, a1 as PreparedAgentCandidateInstruction, a2 as PreparedAgentCandidateLaunch, a3 as PreparedAgentCandidateTrace, a4 as ResolvedAgentCandidateContainer, a5 as VerifiedAgentCandidate, a6 as VerifiedAgentCandidateTaskOutcome, a7 as executePreparedAgentCandidate, a8 as prepareAgentCandidateExecution, a9 as sealAgentCandidateBundle } from './prepare-DIeVgQG3.js';
7
- import { Scenario, ProfileDispatchFn, ProposeContext, SurfaceProposer } from '@tangle-network/agent-eval/campaign';
8
- import { C as CandidateGenerator } from './agentic-generator-JT47GnAp.js';
9
- export { A as AGENTIC_PROFILE_RESOURCE_ROOT, a as AgenticGeneratorOptions, b as AgenticGeneratorShotDisposition, c as AgenticGeneratorShotExecution, d as AgenticGeneratorShotReceipt, I as ImprovementDriverOptions, M as ManagedImprovementDriver, V as Verifier, e as VerifyResult, f as agenticGenerator, g as commandVerifier, i as improvementDriver } from './agentic-generator-JT47GnAp.js';
10
- export { c as ImproveCodeOptions, d as ImproveMemoryOptions, a as ImproveOptions, b as ImproveResult, e as ImproveSkillsOptions, I as ImproveSurface, f as applyImprovementWinnerToProfile, i as improve } from './improve-BucbjddC.js';
11
- export { M as McpServeSpec, m as mcpServeVerifier } from './mcp-serve-verifier-i6nTNSnu.js';
12
- import { AgentProfileDiff, AgentProfile as AgentProfile$1 } from '@tangle-network/agent-interface';
13
- import { Scenario as Scenario$1, SelfImproveOptions } from '@tangle-network/agent-eval/contract';
7
+ export { AuthSource, BackendCallPolicy, CircuitBreakerConfig, CircuitBreakerState, CircuitOpenError, Conversation, ConversationDriveState, ConversationJournal, ConversationJournalEntry, ConversationParticipant, ConversationPolicy, ConversationResult, ConversationStreamEvent, ConversationTurn, D1DatabaseLike, D1StmtLike, DEFAULT_MAX_DEPTH, DeadlineExceededError, FORWARD_HEADERS, FileConversationJournal, ForwardHeaderName, HaltContext, HaltPredicate, HaltReason, HaltSignal, InMemoryConversationJournal, PersonaConversationResult, PersonaDriver, PropagatedHeaders, RetryBackoff, RetryableErrorPredicate, RunConversationOptions, RunPersonaConfig, RunPersonaConversationOptions, SqlAdapter, SqlConversationJournal, TurnOrder, buildForwardHeaders, computeBackoff, createConversationBackend, d1ToSqlAdapter, defaultIsRetryable, defineConversation, isDepthExceeded, makePerAttemptSignal, readDepth, runConversation, runConversationStream, runPersonaConversation, runPersonaDispatch, sleep, slugifySpeaker, turnId } from './conversation.js';
8
+ import { C as CandidateGenerator } from './agentic-generator-DDMM45kZ.js';
9
+ export { A as AGENTIC_PROFILE_RESOURCE_ROOT, a as AgenticGeneratorOptions, b as AgenticGeneratorShotDisposition, c as AgenticGeneratorShotExecution, d as AgenticGeneratorShotReceipt, I as ImprovementDriverOptions, M as ManagedImprovementDriver, V as Verifier, e as VerifyResult, f as agenticGenerator, g as commandVerifier, i as improvementDriver } from './agentic-generator-DDMM45kZ.js';
10
+ export { c as ImproveCodeOptions, d as ImproveMemoryOptions, a as ImproveOptions, b as ImproveResult, e as ImproveSkillsOptions, I as ImproveSurface, f as applyImprovementWinnerToProfile, i as improve } from './improve-BN3HyXIO.js';
11
+ export { M as McpServeSpec, m as mcpServeVerifier } from './mcp-serve-verifier-DQQDbuyz.js';
12
+ import { ProposeContext, SurfaceProposer } from '@tangle-network/agent-eval/campaign';
13
+ import { AgentProfileDiff, AgentProfile } from '@tangle-network/agent-interface';
14
+ import { Scenario, SelfImproveOptions } from '@tangle-network/agent-eval/contract';
14
15
  import { S as SurfaceImprovementEdit } from './improvement-adapter-BieWeK5J.js';
15
16
  import { I as ImprovementAdapter } from './types-BC3bZpH0.js';
16
17
  export { AgentKnowledgeReadinessCheckOptions, KnowledgeImprovementJobMeasurement, KnowledgeImprovementJobResult, KnowledgeReadinessCheck, KnowledgeReadinessCheckInput, KnowledgeReadinessCheckResult, RESEARCH_SUPERVISOR_SYSTEM_PROMPT, RunKnowledgeImprovementJobOptions, SupervisedKnowledgeUpdateInput, SupervisedKnowledgeUpdateOptions, SupervisedKnowledgeUpdateResult, SupervisedKnowledgeUpdater, createAgentKnowledgeReadinessCheck, createSupervisedKnowledgeUpdater, formatSupervisedKnowledgeTask, knowledgeReadinessDeliverable, runKnowledgeImprovementJob, runSupervisedKnowledgeUpdate } from './knowledge.js';
17
- export { D as DELEGATED_LOOP_MODES, a as DelegatedLoopMode, b as DelegatedLoopRegistry, c as DelegatedLoopResult, d as DelegatedLoopRunner, L as LoopRunnerCliArgs, e as LoopRunnerCliResult, R as ResearchLoopResult, f as ResearchLoopRunnerOptions, g as RunDelegatedLoopOptions, V as VetoedFact, W as WorktreeLoopRunnerOptions, h as auditLoopRunner, i as isDelegatedLoopMode, p as parseLoopRunnerArgv, r as researchLoopRunner, j as runDelegatedLoop, k as runLoopRunnerCli, s as selfImproveLoopRunner, w as worktreeLoopRunner } from './loop-runner-bin-D6K_C6op.js';
18
- export { m as mcpToolsForRuntimeMcp, a as mcpToolsForRuntimeMcpSubset } from './openai-tools-0wACz8f8.js';
19
- export { b0 as EvalRunEvent, b1 as EvalRunGeneration, b2 as EvalRunsExportConfig, b3 as EvalRunsExportResult, b4 as INTELLIGENCE_WIRE_VERSION, b5 as LoopSpanNode, b6 as OtelAttribute, b7 as OtelExportConfig, b8 as OtelExporter, b9 as OtelSpan, ba as RuntimeEventOtelOptions, bb as buildLoopOtelSpans, bc as buildLoopSpanNodes, bd as buildRuntimeEventOtelSpans, be as createOtelExporter, bf as exportEvalRuns, bg as loopEventToOtelSpan } from './coordination-DzwagV_s.js';
20
- import { c as RuntimeTelemetryOptions } from './sanitize-Dcbjp0tU.js';
21
- export { d as RuntimeEventCollector, e as RuntimeStreamEventCollector, S as SanitizedKnowledgeReadinessReport, f as createRuntimeEventCollector, g as createRuntimeStreamEventCollector, s as sanitizeAgentRuntimeEvent, h as sanitizeKnowledgeReadinessReport, i as sanitizeRuntimeStreamEvent } from './sanitize-Dcbjp0tU.js';
22
- import '@tangle-network/sandbox';
18
+ export { D as DELEGATED_LOOP_MODES, a as DelegatedLoopMode, b as DelegatedLoopRegistry, c as DelegatedLoopResult, d as DelegatedLoopRunner, L as LoopRunnerCliArgs, e as LoopRunnerCliResult, R as ResearchLoopResult, f as ResearchLoopRunnerOptions, g as RunDelegatedLoopOptions, V as VetoedFact, W as WorktreeLoopRunnerOptions, h as auditLoopRunner, i as isDelegatedLoopMode, p as parseLoopRunnerArgv, r as researchLoopRunner, j as runDelegatedLoop, k as runLoopRunnerCli, s as selfImproveLoopRunner, w as worktreeLoopRunner } from './loop-runner-bin-BRQSQdHa.js';
19
+ export { m as mcpToolsForRuntimeMcp, a as mcpToolsForRuntimeMcpSubset } from './openai-tools-fnj6SRVg.js';
20
+ export { b0 as EvalRunEvent, b1 as EvalRunGeneration, b2 as EvalRunsExportConfig, b3 as EvalRunsExportResult, b4 as INTELLIGENCE_WIRE_VERSION, b5 as LoopSpanNode, b6 as OtelAttribute, b7 as OtelExportConfig, b8 as OtelExporter, b9 as OtelSpan, ba as RuntimeEventOtelOptions, bb as buildLoopOtelSpans, bc as buildLoopSpanNodes, bd as buildRuntimeEventOtelSpans, be as createOtelExporter, bf as exportEvalRuns, bg as loopEventToOtelSpan } from './coordination-Dr_axlAf.js';
21
+ import { K as KnowledgeReadinessDecision, A as AgentBackendInput, c as AgentExecutionBackend, h as RunAgentTaskOptions, i as AgentTaskRunResult, j as RunAgentTaskStreamOptions, R as RuntimeStreamEvent, k as RuntimeSessionStore, l as RuntimeSession } from './types-BwoZWq-i.js';
22
+ export { m as AgentAdapter, d as AgentBackendContext, n as AgentKnowledgeProvider, e as AgentRuntimeEvent, o as AgentRuntimeEventSink, p as AgentTaskContext, g as AgentTaskSpec, f as AgentTaskStatus, B as BackendErrorDetail, b as OpenAIChatResponseFormat, O as OpenAIChatTool, a as OpenAIChatToolChoice } from './types-BwoZWq-i.js';
23
+ import { R as RuntimeHooks } from './types-ByAYqlVb.js';
24
+ export { c as RuntimeDecisionEvidenceRef, d as RuntimeDecisionKind, e as RuntimeDecisionPoint, f as RuntimeHookContext, g as RuntimeHookErrorContext, h as RuntimeHookEvent, i as RuntimeHookPhase, j as RuntimeHookTarget, k as RuntimeRunHandle, l as RuntimeRunPersistenceAdapter, m as RuntimeRunRow, n as composeRuntimeHooks, o as defineRuntimeHooks, p as notifyRuntimeDecisionPoint, q as notifyRuntimeHookEvent, s as startRuntimeRun } from './types-ByAYqlVb.js';
25
+ import { c as RuntimeTelemetryOptions } from './sanitize-BTSsdBXw.js';
26
+ export { d as RuntimeEventCollector, e as RuntimeStreamEventCollector, S as SanitizedKnowledgeReadinessReport, f as createRuntimeEventCollector, g as createRuntimeStreamEventCollector, s as sanitizeAgentRuntimeEvent, h as sanitizeKnowledgeReadinessReport, i as sanitizeRuntimeStreamEvent } from './sanitize-BTSsdBXw.js';
23
27
  import './local-harness-ZqCx51u7.js';
24
28
  import 'node:child_process';
25
29
  import '@tangle-network/agent-knowledge';
26
- import './supervise-CzyytS-o.js';
27
- import './types-CogNCaw7.js';
28
- import './completion-gate-Bn4AZ_Kw.js';
30
+ import './supervise-DmYOug5f.js';
31
+ import './types-1d5QGK3t.js';
32
+ import '@tangle-network/sandbox';
33
+ import './completion-gate-D1gX1-hg.js';
29
34
  import '@tangle-network/agent-profile-materialize';
30
35
  import './kb-gate-CwHO0vz6.js';
31
- import './worktree-fanout-Bn7w_1bM.js';
36
+ import './worktree-fanout-CPprU-qI.js';
32
37
  import './substrate-DO2GHNg2.js';
33
38
  import './environment-provider.js';
34
39
  import '@tangle-network/agent-interface/environment-provider';
35
40
 
36
- /**
37
- *
38
- * Backend factories for `runAgentTaskStream`. Three shapes ship in core:
39
- *
40
- * - `createIterableBackend` — wrap any custom async iterable into a backend
41
- * - `createSandboxPromptBackend` — sandbox / sidecar `streamPrompt` clients
42
- * - `createOpenAICompatibleBackend` — OpenAI-style chat completions endpoints
43
- *
44
- * Adapters stay thin: domain repos own auth, model selection, and the concrete
45
- * tool surface. The factories handle session creation, stream normalization,
46
- * and graceful end-of-stream signalling.
47
- *
48
- * @stable
49
- */
50
-
51
- /** Wrap any custom async-iterable stream into a typed `AgentExecutionBackend`. @stable */
52
- declare function createIterableBackend<TInput extends AgentBackendInput>(options: {
53
- kind: string;
54
- start?: AgentExecutionBackend<TInput>['start'];
55
- resume?: AgentExecutionBackend<TInput>['resume'];
56
- stream: AgentExecutionBackend<TInput>['stream'];
57
- stop?: AgentExecutionBackend<TInput>['stop'];
58
- }): AgentExecutionBackend<TInput>;
59
- /** Build an `AgentExecutionBackend` backed by a sandbox/sidecar `streamPrompt` call. @stable */
60
- declare function createSandboxPromptBackend<TBox, TInput extends AgentBackendInput = AgentBackendInput>(options: {
61
- kind?: string;
62
- getBox(input: TInput, context: Omit<AgentBackendContext, 'session'>): Promise<TBox> | TBox;
63
- streamPrompt(box: TBox, message: string, context: AgentBackendContext): AsyncIterable<unknown>;
64
- mapEvent?: (event: unknown, context: AgentBackendContext) => RuntimeStreamEvent | undefined;
65
- getSessionId?: (box: TBox, input: TInput) => string | undefined;
66
- }): AgentExecutionBackend<TInput>;
67
- /** @stable */
68
- /**
69
- * Retry policy for transient transport errors (rate limits, upstream
70
- * timeouts). Defaults to 5 attempts with exponential backoff starting at
71
- * 1s, ±25% jitter, capped at 30s. Set `maxAttempts: 1` to disable retries.
72
- *
73
- * Retried status codes:
74
- * - 408 Request Timeout
75
- * - 425 Too Early
76
- * - 429 Too Many Requests
77
- * - 500 / 502 / 503 / 504 — upstream transient failures
78
- *
79
- * Hard failures (401, 403, 4xx other than the above) propagate immediately.
80
- */
81
- interface BackendRetryPolicy {
82
- /** Total attempts including the first try. Default 5. */
83
- maxAttempts?: number;
84
- /** Initial backoff in ms before the second attempt. Default 1000. */
85
- initialBackoffMs?: number;
86
- /** Hard ceiling on backoff in ms. Default 30000. */
87
- maxBackoffMs?: number;
88
- /** Jitter fraction in [0, 1]. Default 0.25 (±25%). */
89
- jitter?: number;
90
- /** Status codes that trigger a retry. Default: 408, 425, 429, 500, 502, 503, 504. */
91
- retryStatuses?: ReadonlyArray<number>;
92
- /**
93
- * Per-attempt wall-clock deadline in ms. If a single fetch attempt does
94
- * not return headers within this window the attempt is aborted and
95
- * retried. Default 120000 (2 min). Without this a hung upstream blocks
96
- * the attempt indefinitely — observed in production as a 15-minute
97
- * `fetch failed` that burned an entire eval persona. Set to 0 to disable.
98
- */
99
- requestTimeoutMs?: number;
100
- }
101
- /**
102
- *
103
- * OpenAI-compat streaming backend. Routes `runAgentTaskStream` through any
104
- * `POST /chat/completions` endpoint that speaks OpenAI's SSE protocol —
105
- * Tangle Router, OpenAI direct, OpenRouter, Groq, DeepSeek, Together. The
106
- * router also fronts Anthropic models in Anthropic-native SSE shape; this
107
- * backend handles both.
108
- *
109
- * ### Tool calls
110
- *
111
- * Pass `tools` (and optionally `toolChoice`) to forward an OpenAI Chat
112
- * Completions `tools[]` array on every request. Streamed `tool_call` chunks
113
- * are buffered until the model finalizes them (either `finish_reason:
114
- * 'tool_calls'` for OpenAI shape or a `content_block_stop` for Anthropic
115
- * `tool_use` blocks proxied through the router), then emitted as a single
116
- * `tool_call` RuntimeStreamEvent with the assembled `args`.
117
- *
118
- * The backend does NOT execute tools — it surfaces calls for the caller's
119
- * own dispatcher (typically the product's MCP / sandbox runtime) to fulfill
120
- * and feed back as a subsequent `messages` turn. This keeps the transport
121
- * thin and lets the agent host own tool dispatch policy.
122
- *
123
- * ### Fail-loud errors
124
- *
125
- * Non-success HTTP responses (4xx/5xx) and exhausted retry budgets throw
126
- * `BackendTransportError` from inside the `stream()` generator. The runtime
127
- * catches the throw, yields a `backend_error` with a typed `error` field
128
- * (`kind`, `status`, truncated `body`) and a terminal `final` event with
129
- * `status: 'failed'` carrying the same detail. Consumers MUST map
130
- * `final.error` onto their `RunRecord.error` — silently treating an empty
131
- * `finalText` as "agent produced nothing" hides credit exhaustion, auth
132
- * failure, and upstream outages.
133
- *
134
- * @stable
135
- */
136
- declare function createOpenAICompatibleBackend<TInput extends AgentBackendInput = AgentBackendInput>(options: {
137
- apiKey: string;
138
- baseUrl: string;
139
- model: string;
140
- kind?: string;
141
- /**
142
- * OpenAI Chat Completions `tools[]` definitions surfaced to the model on
143
- * every request. Omit to send a tool-free request (existing behavior).
144
- * The runtime makes no assumption about the dispatcher — calls stream out
145
- * as `tool_call` events and the caller is responsible for executing them
146
- * and feeding `tool_result` messages back on a follow-up turn.
147
- */
148
- tools?: ReadonlyArray<OpenAIChatTool>;
149
- /**
150
- * OpenAI Chat Completions `tool_choice`. Default `undefined` (request
151
- * omits the field; provider falls back to its own default — typically
152
- * `'auto'`).
153
- */
154
- toolChoice?: OpenAIChatToolChoice;
155
- /**
156
- * OpenAI Chat Completions `response_format`. Omit for provider default text.
157
- */
158
- responseFormat?: OpenAIChatResponseFormat;
159
- /** OpenAI Chat Completions `temperature`. Omit for provider default. */
160
- temperature?: number;
161
- /** Maximum completion tokens, sent as OpenAI-compatible `max_tokens`. Omit for provider default. */
162
- maxTokens?: number;
163
- fetchImpl?: typeof fetch;
164
- retry?: BackendRetryPolicy;
165
- }): AgentExecutionBackend<TInput>;
166
-
167
- /**
168
- *
169
- * Per-call resilience policy for participant backends: deadline, retry with
170
- * backoff, and a circuit breaker. Each policy is applied *around* a single
171
- * turn's backend invocation, not across the whole conversation — the
172
- * conversation-level credit cap and `maxTurns` bound the broader run.
173
- *
174
- * Deadlines abort the underlying backend stream via `AbortSignal` linkage so
175
- * the OpenAI/SDK clients tear down their HTTP request cleanly instead of
176
- * leaking sockets. Retries replay the same logical turn (same `turnId`) so
177
- * any caching gateway can dedupe. Circuit breakers are *per participant*: A's
178
- * failures don't open B's breaker.
179
- *
180
- * @stable
181
- */
182
- /** Pure judgment of whether an error is worth retrying. Defaults: TimeoutError, AbortError, fetch-level network errors. */
183
- type RetryableErrorPredicate = (err: unknown) => boolean;
184
- /** Backoff between attempts. Constant ms, or `(attempt: 1-indexed) => ms`. */
185
- type RetryBackoff = number | ((attempt: number) => number);
186
- /** Circuit-breaker tuning. `failuresToOpen` consecutive failures opens it; closed only after `cooldownMs`. */
187
- interface CircuitBreakerConfig {
188
- failuresToOpen: number;
189
- cooldownMs: number;
190
- }
191
- interface BackendCallPolicy {
192
- /** Per-attempt wall clock limit. Exceeding fires an AbortSignal and is treated as a retryable failure. */
193
- perAttemptDeadlineMs?: number;
194
- /** Number of retries after the first attempt; total attempts = 1 + maxRetries. Default 0. */
195
- maxRetries?: number;
196
- /** Backoff between attempts. Default 250ms with jitter. */
197
- retryBackoffMs?: RetryBackoff;
198
- /** Custom retry classifier. Defaults to {@link defaultIsRetryable}. */
199
- isRetryable?: RetryableErrorPredicate;
200
- /** Circuit breaker that opens after N consecutive failures per participant. */
201
- circuitBreaker?: CircuitBreakerConfig;
202
- }
203
- /** Thrown when the circuit breaker is open for a participant and no retry is allowed yet. */
204
- declare class CircuitOpenError extends Error {
205
- constructor(participant: string, retryAfterMs: number);
206
- }
207
- /** Thrown when a backend call exceeds its per-attempt deadline. */
208
- declare class DeadlineExceededError extends Error {
209
- constructor(deadlineMs: number);
210
- }
211
- /**
212
- * Default retryable classification — network/timeout class errors. Errors
213
- * a model deliberately throws (validation, refusal, 4xx) are not retried;
214
- * those represent real outcomes, not transient infrastructure faults.
215
- */
216
- declare const defaultIsRetryable: RetryableErrorPredicate;
217
- /** Live circuit-breaker state — one instance per (participant, conversation run). */
218
- declare class CircuitBreakerState {
219
- private readonly config;
220
- private consecutiveFailures;
221
- private openedAt;
222
- constructor(config: CircuitBreakerConfig | undefined);
223
- /**
224
- * Check whether the next call is allowed. Throws `CircuitOpenError` when
225
- * the breaker is open and the cooldown hasn't elapsed.
226
- */
227
- preflight(participant: string, now?: number): void;
228
- recordSuccess(): void;
229
- recordFailure(now?: number): void;
230
- }
231
- /**
232
- * Build a per-attempt AbortSignal linked to the parent signal AND fired when
233
- * the deadline elapses. The returned `dispose()` MUST be called in a
234
- * `finally` (clears the timer, detaches the listener) so we don't leak.
235
- *
236
- * When the deadline fires, the signal's `reason` is a `DeadlineExceededError`
237
- * — callers can detect timeout-vs-cancel by reading `signal.reason` after
238
- * the underlying operation throws.
239
- */
240
- declare function makePerAttemptSignal(parentSignal: AbortSignal | undefined, deadlineMs: number | undefined): {
241
- signal: AbortSignal;
242
- dispose: () => void;
243
- getDeadlineError(): DeadlineExceededError | undefined;
244
- };
245
- /** Compute the delay before the next attempt. Default: 250ms exponential with jitter. */
246
- declare function computeBackoff(spec: RetryBackoff | undefined, attempt: number): number;
247
- /** Resolve after `ms` milliseconds — used for retry backoff in conversation call policy. */
248
- declare function sleep(ms: number): Promise<void>;
249
-
250
- /**
251
- *
252
- * Cross-gateway forwarding headers — the wire-level contract that makes
253
- * agent-to-agent communication composable across organizational boundaries.
254
- * Every header here is read on inbound and re-emitted on outbound, so a chain
255
- * `caller → A's gateway → A's runtime → B's gateway → B's runtime` ends with
256
- * B billing the original user, the depth counter monotonically incremented,
257
- * and the run/turn correlation IDs preserved end-to-end.
258
- *
259
- * The actual depth refusal (HTTP 413 at MAX_DEPTH) is enforced by
260
- * `agent-gateway`'s middleware; this module owns the names + the propagation
261
- * rules so both sides agree.
262
- *
263
- * Full protocol: `docs/agent-bus-protocol.md`.
264
- *
265
- * @stable
266
- */
267
- /** Standard names — lowercased so Headers maps interop on every runtime. */
268
- declare const FORWARD_HEADERS: {
269
- /** Forwarded original-user identity (`Bearer sk-tan-<user>`); downstream gateways bill against this. */
270
- readonly authorization: "x-tangle-forwarded-authorization";
271
- /** Monotonically incremented on every gateway hop. Refused at MAX_DEPTH. */
272
- readonly depth: "x-tangle-forwarded-depth";
273
- /** Top-level conversation run identifier, propagated through every nested call. */
274
- readonly runId: "x-tangle-runid";
275
- /** This call's turn within the run; deterministic + stable across retries. */
276
- readonly turnId: "x-tangle-turnid";
277
- /** When the call is *inside* another turn (recursion), the parent turn's id. */
278
- readonly parentTurnId: "x-tangle-parent-turnid";
279
- /** Logical conversation peer label at the sending side, for trace stitching. */
280
- readonly speaker: "x-tangle-speaker";
281
- };
282
- type ForwardHeaderName = (typeof FORWARD_HEADERS)[keyof typeof FORWARD_HEADERS];
283
- /** Hard cap on chained gateway hops; refused beyond this. Default keeps recursion bounded. */
284
- declare const DEFAULT_MAX_DEPTH = 4;
285
- /**
286
- * Read the depth counter off an inbound request. Missing → 0 (caller is the
287
- * origin). Non-integer → throws — silent coercion would let a bad caller
288
- * reset depth and bypass the limit.
289
- */
290
- declare function readDepth(headers: Readonly<Record<string, string | string[] | undefined>>): number;
291
- /**
292
- * Refuse further forwarding when the inbound depth has reached the limit.
293
- * Callers (the gateway middleware) translate the boolean to an HTTP 413.
294
- */
295
- declare function isDepthExceeded(inboundDepth: number, max?: number): boolean;
296
- /**
297
- * Build the headers to emit on an outbound participant call, given the
298
- * conversation's propagation context. Depth is incremented from the inbound
299
- * value; runId / turnId / speaker stamp the current hop; the user's
300
- * `Authorization` is preserved verbatim so the downstream gateway bills the
301
- * right wallet.
302
- */
303
- declare function buildForwardHeaders(input: {
304
- inboundDepth: number;
305
- forwardedAuthorization?: string;
306
- runId: string;
307
- turnId: string;
308
- parentTurnId?: string;
309
- speaker: string;
310
- }): Record<string, string>;
311
- /**
312
- * Header bag carried through `AgentBackendContext.propagatedHeaders` so
313
- * backends that opt in can merge them into their outbound HTTP requests.
314
- * Distinct from `buildForwardHeaders` so callers can attach extra
315
- * non-protocol headers (e.g. tracing) without colliding.
316
- */
317
- type PropagatedHeaders = Readonly<Record<string, string>>;
318
-
319
- /**
320
- *
321
- * Durable conversation transcript — survives a driver process crash mid-run.
322
- * The runner journals every committed turn before yielding `turn_end`, so a
323
- * resumed run replays the same `runId` against the same journal and picks up
324
- * from the first un-recorded turn. Combined with the deterministic
325
- * `turnId(runId, index, speaker)`, a retried turn collides with the prior
326
- * attempt's id and any caching gateway can dedupe.
327
- *
328
- * The interface is small enough that a Cloudflare D1 / R2 / postgres adapter
329
- * is ~30 lines. The in-memory adapter is the default for tests and scratch.
330
- * The file adapter (JSONL on disk) is the default-durable choice when no
331
- * upstream store is wired.
332
- *
333
- * @stable
334
- */
335
-
336
- interface ConversationJournalEntry {
337
- runId: string;
338
- startedAt: string;
339
- /** Set when the run reaches a terminal state. */
340
- halted?: HaltReason;
341
- endedAt?: string;
342
- turns: ConversationTurn[];
343
- }
344
- interface ConversationJournal {
345
- /**
346
- * Load any prior state for `runId`. Returns `undefined` for a fresh run.
347
- * Implementations MUST NOT mutate the returned object — the runner clones
348
- * before continuing — but the runtime treats absence and emptiness
349
- * identically, so a journal with zero turns is equivalent to "fresh."
350
- */
351
- loadRun(runId: string): Promise<ConversationJournalEntry | undefined>;
352
- /**
353
- * Initialise journal state for a fresh run. Called once per run, before any
354
- * `appendTurn`. Idempotent: calling with an existing runId is a no-op if
355
- * the entry already exists with the same `startedAt`.
356
- */
357
- beginRun(runId: string, startedAt: string): Promise<void>;
358
- /**
359
- * Append a committed turn. The runner only calls this AFTER the turn's
360
- * backend stream completed and the credit total has been updated, so an
361
- * appended turn is observed-committed and never speculative.
362
- */
363
- appendTurn(runId: string, turn: ConversationTurn): Promise<void>;
364
- /**
365
- * Record the run's terminal halt reason + end time. Once called, the run
366
- * is observed-final; subsequent `loadRun` returns the same halt.
367
- */
368
- recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void>;
369
- }
370
- /** In-memory `ConversationJournal` — suitable for testing and single-process runs. */
371
- declare class InMemoryConversationJournal implements ConversationJournal {
372
- private readonly entries;
373
- loadRun(runId: string): Promise<ConversationJournalEntry | undefined>;
374
- beginRun(runId: string, startedAt: string): Promise<void>;
375
- appendTurn(runId: string, turn: ConversationTurn): Promise<void>;
376
- recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void>;
377
- }
378
- /**
379
- * JSONL on disk. One line per record; first line is the `begin`, subsequent
380
- * lines are `turn` records, terminal line is `halt`. Replays the whole file
381
- * on `loadRun` — cheap for the conversation sizes this is designed for
382
- * (thousands of turns, not millions). For huge runs, plug in a real DB
383
- * adapter; the interface is small.
384
- *
385
- * Each `appendTurn` / `recordHalt` calls `fsync` after the write so a
386
- * process crash between writes never loses an acknowledged turn.
387
- */
388
- declare class FileConversationJournal implements ConversationJournal {
389
- private readonly path;
390
- constructor(path: string);
391
- loadRun(runId: string): Promise<ConversationJournalEntry | undefined>;
392
- beginRun(runId: string, startedAt: string): Promise<void>;
393
- appendTurn(runId: string, turn: ConversationTurn): Promise<void>;
394
- recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void>;
395
- private appendRecord;
396
- }
397
-
398
- /**
399
- *
400
- * Public types for multi-agent conversations. A `Conversation` is two-or-more
401
- * participants taking turns through their own `AgentExecutionBackend`s, driven
402
- * by a `ConversationPolicy` (turn order, halting, hard credit ceiling).
403
- *
404
- * Each participant's backend can resolve to any reachable endpoint —
405
- * in-process iterable, local cli-bridge, sandbox, router, or a remote
406
- * agent-gateway — so the same `runConversation` call drives same-machine,
407
- * same-cloud, and cross-cloud orchestration without code change.
408
- *
409
- * @stable
410
- */
411
-
412
- /** @stable */
413
- interface ConversationParticipant {
414
- /**
415
- * Stable name used as the speaker label in the transcript. Must be unique
416
- * within a `Conversation`.
417
- */
418
- name: string;
419
- /**
420
- * Backend that runs this participant's turn. Reuses the existing
421
- * `AgentExecutionBackend` contract from `runAgentTaskStream`, so any
422
- * registered backend (iterable, sandbox, OpenAI-compatible) works without
423
- * adaptation.
424
- */
425
- backend: AgentExecutionBackend;
426
- /**
427
- * Optional human label for traces / dashboards. Distinct from `name`, which
428
- * is the addressing key.
429
- */
430
- label?: string;
431
- /**
432
- * Optional per-participant override of the conversation's default
433
- * `callPolicy`. Use to tighten the deadline or raise the retry budget for
434
- * a participant known to be slow or flaky.
435
- */
436
- callPolicy?: BackendCallPolicy;
437
- /**
438
- * Who pays for THIS participant's outbound calls?
439
- *
440
- * - `'forward-user'` (default) — propagate the caller's
441
- * `X-Tangle-Forwarded-Authorization` so the downstream gateway bills the
442
- * original user. Right for pass-through agents that aggregate/route
443
- * without taking economic risk.
444
- * - `'agent-owned'` — DO NOT forward the user's auth; the participant's
445
- * backend uses its own credentials (typically a sk-tan-AGENT or x402
446
- * wallet baked into the backend at construction). Downstream charges
447
- * land on the agent, not the user. Right for resold-bundle agents that
448
- * take margin between their inbound price and their sub-agent costs.
449
- * - `(state) => AuthSource` — per-turn / per-condition decision, e.g. base
450
- * sub-services are agent-owned but premium add-ons forward the user.
451
- *
452
- * The agent's own credentials live on the backend (set at construction
453
- * time, e.g. `createOpenAICompatibleBackend({ apiKey })`); this field is
454
- * purely about *whether to also forward the user's identity downstream*.
455
- */
456
- authSource?: AuthSource;
457
- }
458
- /** @stable */
459
- type AuthSource = 'forward-user' | 'agent-owned' | ((state: ConversationDriveState) => 'forward-user' | 'agent-owned');
460
- /** @stable */
461
- type TurnOrder = 'alternate' | 'round-robin' | ((state: ConversationDriveState) => number);
462
- /** @stable */
463
- interface ConversationDriveState {
464
- transcript: readonly ConversationTurn[];
465
- turnIndex: number;
466
- spentCreditsCents: number;
467
- }
468
- /** @stable */
469
- interface HaltContext extends ConversationDriveState {
470
- lastTurn: ConversationTurn;
471
- }
472
- /** @stable */
473
- interface HaltSignal {
474
- halted: true;
475
- reason: string;
476
- }
477
- /** @stable */
478
- type HaltPredicate = (ctx: HaltContext) => boolean | HaltSignal | Promise<boolean | HaltSignal>;
479
- /** @stable */
480
- type HaltReason = {
481
- kind: 'max_turns';
482
- turns: number;
483
- } | {
484
- kind: 'max_credits';
485
- spentCents: number;
486
- capCents: number;
487
- } | {
488
- kind: 'predicate';
489
- reason: string;
490
- } | {
491
- kind: 'abort';
492
- } | {
493
- kind: 'participant_error';
494
- participant: string;
495
- message: string;
496
- };
497
- /** @stable */
498
- interface ConversationPolicy {
499
- /** Hard cap on speaker-turns. Each call into a participant's backend counts as 1. */
500
- maxTurns: number;
501
- /**
502
- * Hard cap on aggregate credit spend across all participants, in cents.
503
- * Computed by summing `llm_call.costUsd` from every participant's stream.
504
- * Unset (`undefined`) means no credit ceiling — the run is bounded only by
505
- * `maxTurns` and `haltOn`.
506
- */
507
- maxCreditsCents?: number;
508
- /**
509
- * Speaker selection. Defaults to `'alternate'` for two-participant
510
- * conversations and `'round-robin'` for any other arity.
511
- */
512
- turnOrder?: TurnOrder;
513
- /**
514
- * Optional convergence / content-based halt. Called after every turn ends;
515
- * returning truthy stops the loop with `{ kind: 'predicate', ... }`.
516
- */
517
- haltOn?: HaltPredicate;
518
- /**
519
- * Default per-turn resilience policy applied to every participant call
520
- * (deadline, retries, circuit breaker). Individual participants may
521
- * override via `ConversationParticipant.callPolicy`.
522
- */
523
- defaultCallPolicy?: BackendCallPolicy;
524
- }
525
- /** @stable */
526
- interface ConversationTurn {
527
- index: number;
528
- speaker: string;
529
- /**
530
- * Deterministic turn identifier — stable across retries of the same logical
531
- * turn so caching gateways and trace backends can dedupe. Shape:
532
- * `${runId}.t${index}.${speakerSlug}`.
533
- */
534
- turnId: string;
535
- text: string;
536
- /**
537
- * Aggregated backend usage for this turn alone. Populated from any
538
- * `llm_call` stream events the backend emitted; `undefined` when the
539
- * backend reports no usage.
540
- */
541
- usage?: {
542
- tokensIn?: number;
543
- tokensOut?: number;
544
- costUsd?: number;
545
- latencyMs?: number;
546
- model?: string;
547
- };
548
- /**
549
- * Number of attempts that ran before this turn committed. `1` is the
550
- * common case; higher means the call policy retried after transient
551
- * failures.
552
- */
553
- attempts: number;
554
- startedAt: string;
555
- endedAt: string;
556
- }
557
- /** @stable */
558
- interface Conversation {
559
- participants: readonly ConversationParticipant[];
560
- policy: ConversationPolicy;
561
- }
562
- /** @stable */
563
- interface RunConversationOptions {
564
- /** First message kicking off the conversation. Routes to the first speaker. */
565
- seed: string;
566
- /**
567
- * Optional run identifier for cross-participant trace correlation. Auto-
568
- * generated when omitted. Reusing a runId against the same `journal`
569
- * resumes the prior run — the runner replays the persisted transcript and
570
- * continues from the first un-recorded turn.
571
- */
572
- runId?: string;
573
- /** Cancellation signal — aborts mid-stream and halts with `{ kind: 'abort' }`. */
574
- signal?: AbortSignal;
575
- /**
576
- * Event sink for per-turn micro-events. Distinct from the result transcript:
577
- * the sink fires for every text-delta, every turn-start/end, and the
578
- * conversation-start/end markers. Used to drive SSE / dashboard updates
579
- * without waiting for the conversation to finish.
580
- */
581
- onEvent?: (event: ConversationStreamEvent) => void | Promise<void>;
582
- /**
583
- * Optional durable transcript. When set, the runner persists every
584
- * committed turn before yielding `turn_end`. Reusing the same `runId`
585
- * against the same journal resumes from the last committed turn — so a
586
- * driver process crash mid-run loses zero acknowledged turns.
587
- */
588
- journal?: ConversationJournal;
589
- /**
590
- * Headers to forward verbatim to every participant backend call (gateway
591
- * propagation: `X-Tangle-Forwarded-Authorization`, run/turn correlation,
592
- * depth counter). Backends opt in by reading `propagatedHeaders` from
593
- * their `AgentBackendContext`; backends that ignore the field still work.
594
- */
595
- propagatedHeaders?: PropagatedHeaders;
596
- /**
597
- * Inbound depth at the point this driver was invoked. The runner
598
- * increments it on every outbound participant call; gateways refuse at
599
- * `DEFAULT_MAX_DEPTH`. Default 0 (origin caller).
600
- */
601
- inboundDepth?: number;
602
- /**
603
- * Parent turn id when this conversation is *inside* another turn (i.e. the
604
- * driver is itself a participant via `createConversationBackend`). The
605
- * runner stamps each outbound call with this as `X-Tangle-Parent-TurnId`
606
- * so trace stitching survives nested orchestration.
607
- */
608
- parentTurnId?: string;
609
- }
610
- /** @stable */
611
- interface ConversationResult {
612
- runId: string;
613
- transcript: ConversationTurn[];
614
- turns: number;
615
- spentCreditsCents: number;
616
- halted: HaltReason;
617
- durationMs: number;
618
- startedAt: string;
619
- endedAt: string;
620
- }
621
- /** @stable */
622
- type ConversationStreamEvent = {
623
- type: 'conversation_start';
624
- runId: string;
625
- participants: readonly string[];
626
- seed: string;
627
- timestamp: string;
628
- } | {
629
- type: 'conversation_resumed';
630
- runId: string;
631
- participants: readonly string[];
632
- transcript: readonly ConversationTurn[];
633
- timestamp: string;
634
- } | {
635
- type: 'turn_start';
636
- runId: string;
637
- index: number;
638
- speaker: string;
639
- turnId: string;
640
- attempt: number;
641
- timestamp: string;
642
- } | {
643
- type: 'turn_text_delta';
644
- runId: string;
645
- index: number;
646
- speaker: string;
647
- turnId: string;
648
- text: string;
649
- timestamp?: string;
650
- } | {
651
- type: 'turn_retry';
652
- runId: string;
653
- index: number;
654
- speaker: string;
655
- turnId: string;
656
- attempt: number;
657
- reason: string;
658
- timestamp: string;
659
- } | {
660
- type: 'turn_end';
661
- runId: string;
662
- turn: ConversationTurn;
663
- timestamp: string;
664
- } | {
665
- type: 'conversation_end';
666
- runId: string;
667
- result: ConversationResult;
668
- timestamp: string;
669
- };
670
-
671
- /**
672
- *
673
- * Wrap a `Conversation` so it satisfies `AgentExecutionBackend`. The result is
674
- * an addressable "single agent" whose internal behavior is an N-party
675
- * orchestrated conversation — the recursion primitive that lets a swarm be a
676
- * participant inside another swarm, or be published behind a single
677
- * agent-gateway endpoint.
678
- *
679
- * Stream events from inner participants are NOT forwarded verbatim. Outer
680
- * callers see one `text_delta` per inner turn (the turn's full text), tagged
681
- * with `[speaker] ` prefix so the outer transcript stays attributable. The
682
- * conversation's `conversation_end` halt reason rides on a `final` event.
683
- *
684
- * @stable
685
- */
686
-
687
- declare function createConversationBackend(options: {
688
- conversation: Conversation;
689
- /** Optional backend kind label. Defaults to `'conversation'`. */
690
- kind?: string;
691
- }): AgentExecutionBackend;
692
-
693
- /**
694
- *
695
- * Declarative constructor for a multi-agent `Conversation`. Validates inputs
696
- * fail-loud at definition time (duplicate participant names, alternate order
697
- * with ≠2 participants, non-positive `maxTurns`) so misconfiguration is caught
698
- * before `runConversation` is called and not buried inside a streaming run.
699
- *
700
- * @stable
701
- */
702
-
703
- declare function defineConversation(input: {
704
- participants: ConversationParticipant[];
705
- policy: ConversationPolicy;
706
- }): Conversation;
707
-
708
- /**
709
- *
710
- * Durable conversation journal backed by any SQL store. Adapter-agnostic by
711
- * design: callers wire a `SqlAdapter` against their driver of choice (D1,
712
- * postgres, sqlite, libSQL…) and the same journal implementation persists
713
- * conversation runs durably across process restarts. The schema is two
714
- * tables — runs (latest state) + events (append-only log) — so a partial
715
- * crash in the middle of a turn leaves an unambiguous "last committed turn"
716
- * to resume from.
717
- *
718
- * Why not bake in a specific driver? agent-runtime ships against multiple
719
- * runtimes (Cloudflare Workers, Node, Bun, Deno) and consumers' fleets have
720
- * already standardized on one of D1 / postgres / sqlite / libSQL. Adapter
721
- * indirection costs ~5 lines per driver in the consumer's code and keeps the
722
- * SDK free of native deps.
723
- *
724
- * @example D1 (Cloudflare Workers)
725
- * import { SqlConversationJournal, d1ToSqlAdapter } from '@tangle-network/agent-runtime'
726
- * const journal = new SqlConversationJournal(d1ToSqlAdapter(env.DB))
727
- * await journal.migrate() // once at deploy
728
- * await runConversation(conv, { seed, journal, runId: 'run_abc' })
729
- *
730
- * @example node-postgres
731
- * import { Pool } from 'pg'
732
- * const pool = new Pool({ connectionString: process.env.DATABASE_URL })
733
- * const pg: SqlAdapter = {
734
- * exec: async (sql, params = []) => {
735
- * const r = await pool.query(sql, params as never)
736
- * return { rowsAffected: r.rowCount ?? 0 }
737
- * },
738
- * query: async (sql, params = []) => (await pool.query(sql, params as never)).rows,
739
- * }
740
- * const journal = new SqlConversationJournal(pg)
741
- * await journal.migrate()
742
- *
743
- * @stable
744
- */
745
-
746
- /**
747
- * Minimal SQL driver shape. Implementations forward to whichever client the
748
- * deployment already uses; agent-runtime takes no opinion on which.
749
- *
750
- * Parameter placeholders MUST be `?` (positional). All adapters listed in the
751
- * file header accept this convention.
752
- */
753
- interface SqlAdapter {
754
- /** Execute a write statement (INSERT/UPDATE/DELETE/DDL). */
755
- exec(sql: string, params?: readonly unknown[]): Promise<{
756
- rowsAffected: number;
757
- }>;
758
- /** Execute a read statement (SELECT). Returns rows as plain objects. */
759
- query<TRow = Record<string, unknown>>(sql: string, params?: readonly unknown[]): Promise<TRow[]>;
760
- }
761
- /**
762
- * Adapt a Cloudflare D1 binding to the SqlAdapter shape. Lives here so D1
763
- * consumers don't have to write the wrapper themselves; the runtime never
764
- * imports `@cloudflare/workers-types` directly (peer-style typing).
765
- */
766
- declare function d1ToSqlAdapter(db: D1DatabaseLike): SqlAdapter;
767
- /**
768
- * Structural type matching the surface of `D1Database` we depend on, so the
769
- * SDK never imports `@cloudflare/workers-types`. Consumers pass their real
770
- * `D1Database` from `env.DB` and TS structural compatibility lines it up.
771
- */
772
- interface D1DatabaseLike {
773
- prepare(sql: string): D1StmtLike;
774
- }
775
- interface D1StmtLike {
776
- bind(...params: unknown[]): D1StmtLike;
777
- run(): Promise<unknown>;
778
- all<TRow = unknown>(): Promise<{
779
- results?: TRow[];
780
- }>;
781
- }
782
- /**
783
- * SQL-backed ConversationJournal. Two tables — runs (one row per runId, holds
784
- * start/halt timestamps + halt reason) and turns (one row per committed turn,
785
- * payload is the ConversationTurn JSON). Replays the turns table on
786
- * `loadRun` and writes append-only per `appendTurn`.
787
- */
788
- declare class SqlConversationJournal implements ConversationJournal {
789
- private readonly db;
790
- private readonly table;
791
- /**
792
- * @param db SQL adapter (D1, postgres, sqlite, libSQL — all work)
793
- * @param table Table-name prefix; the journal creates `${table}_runs` and
794
- * `${table}_turns`. Lets multiple journals share a database
795
- * without colliding (e.g. one per product surface).
796
- */
797
- constructor(db: SqlAdapter, table?: string);
798
- /**
799
- * Create the journal's tables if absent. Idempotent. Call once at deploy
800
- * (or at app boot) — running on every request is harmless but adds latency.
801
- */
802
- migrate(): Promise<void>;
803
- loadRun(runId: string): Promise<ConversationJournalEntry | undefined>;
804
- beginRun(runId: string, startedAt: string): Promise<void>;
805
- appendTurn(runId: string, turn: ConversationTurn): Promise<void>;
806
- recordHalt(runId: string, halt: HaltReason, endedAt: string): Promise<void>;
807
- }
808
-
809
- /**
810
- *
811
- * Conversation orchestrator. Drives N participants in turn through their own
812
- * `AgentExecutionBackend`s, aggregating per-turn text + usage, enforcing
813
- * `maxTurns` / `maxCreditsCents` / `haltOn`, and emitting per-event stream
814
- * markers so callers can plumb the run through SSE without buffering.
815
- *
816
- * `runConversation` returns the full result; `runConversationStream` returns
817
- * an `AsyncIterable<ConversationStreamEvent>` for callers that want to
818
- * forward events as they arrive. Both share one driving loop.
819
- *
820
- * Distributed-systems primitives layered on top of the loop:
821
- * - **Idempotent turn ids** — `turnId(runId, index, speaker)` stays stable
822
- * across retries so caching gateways can dedupe.
823
- * - **Durable journal** — optional `ConversationJournal` persists every
824
- * committed turn; reusing a runId against the same journal resumes
825
- * transparently from the last committed turn.
826
- * - **Per-turn call policy** — deadline, retry-with-backoff, and a
827
- * per-participant circuit breaker. Retries replay the same logical turn
828
- * (same `turnId`); the retry loop lives inside the outer generator so
829
- * deltas yield naturally without cross-coroutine buffering.
830
- * - **Header propagation** — run/turn/depth headers (+ forwarded user
831
- * authorization) stamped onto every outbound backend call so downstream
832
- * gateways can bill the right user and enforce `X-Tangle-Forwarded-Depth`.
833
- *
834
- * Credit cap is enforced *between turns*, not mid-stream: a turn that
835
- * overshoots the cap completes, the cap then halts the conversation before
836
- * the next turn.
837
- *
838
- * @stable
839
- */
840
-
841
- declare function runConversation(conversation: Conversation, options: RunConversationOptions): Promise<ConversationResult>;
842
- /** Streaming conversation orchestrator: drives N participants in turn through their own backends, enforcing `maxTurns` / `maxCreditsCents` / `haltOn`, yielding per-event stream markers. */
843
- declare function runConversationStream(conversation: Conversation, options: RunConversationOptions): AsyncIterable<ConversationStreamEvent>;
844
-
845
- /**
846
- * `runPersonaConversation` — the persona loop runner: run a WORKER `AgentProfile`
847
- * (the agent under test) as a multi-round conversation driven by a PERSONA (the
848
- * simulated user), over the persistent conversation transcript.
849
- *
850
- * It is profiles-vs-profiles: the persona is itself a driver `AgentProfile` (an
851
- * LLM role-playing the user from its facts) — `runConversation` runs the two
852
- * against each other. Scripted persona turns are kept as a deterministic
853
- * fast-path. Only the WORKER is metered (it is the side under test); the
854
- * persona-driver is the test harness, not billed against the agent.
855
- *
856
- * `runPersonaDispatch` wraps the runner as a `ProfileDispatchFn` so it drops
857
- * straight into `runProfileMatrix({ dispatch })` — the same loop serves a single
858
- * cell and the whole matrix, replacing the per-agent hand-rolled
859
- * `dispatchWithSurface` bridges.
860
- */
861
-
862
- /** A persona that drives the conversation: either a full driver `AgentProfile`
863
- * (an LLM user-sim) or a deterministic script of user turns (the fast-path). */
864
- type PersonaDriver = {
865
- kind: 'profile';
866
- profile: AgentProfile;
867
- } | {
868
- kind: 'scripted';
869
- turns: string[];
870
- };
871
- interface RunPersonaConversationOptions {
872
- /** The agent under test. Metered; its rendered prompt leads its turns. */
873
- worker: AgentProfile;
874
- /** The simulated user driving the dialogue. */
875
- persona: PersonaDriver;
876
- /** Turn an `AgentProfile` into a runnable backend (router / sandbox / fake).
877
- * Applied to the worker and to a `profile`-kind persona. */
878
- backendFor: (profile: AgentProfile, role: 'worker' | 'persona') => AgentExecutionBackend;
879
- /** Render a profile's system prompt — prepended to that profile's messages. */
880
- systemPromptOf: (profile: AgentProfile) => string;
881
- /** Speaker-turn cap. Default for a scripted persona = `2 * turns.length`
882
- * (worker answers each user turn). REQUIRED for a `profile` persona. */
883
- maxTurns?: number;
884
- /** Kickoff message routed to the first speaker (the persona). Default 'Begin.' */
885
- seed?: string;
886
- /** Content-based "until satisfied" halt, called after every turn. `maxTurns` is the
887
- * hard ceiling; this is the early stop (the persona declares the goal met / unreachable). */
888
- haltOn?: HaltPredicate;
889
- signal?: AbortSignal;
890
- /** Worker participant / transcript speaker label. Default 'agent'. */
891
- workerName?: string;
892
- }
893
- interface PersonaConversationResult {
894
- transcript: ConversationTurn[];
895
- turns: number;
896
- halted: HaltReason;
897
- /** Worker-only spend (the side under test). */
898
- costUsd: number;
899
- tokensIn: number;
900
- tokensOut: number;
901
- }
902
- /**
903
- * Run one worker profile against one persona as a multi-round conversation.
904
- * The persona leads (participant 0): it speaks, the worker answers, repeat,
905
- * until `maxTurns`. Returns the persistent transcript + worker-only usage.
906
- */
907
- declare function runPersonaConversation(opts: RunPersonaConversationOptions): Promise<PersonaConversationResult>;
908
- interface RunPersonaConfig<TScenario extends Scenario, TArtifact> {
909
- /** Turn an `AgentProfile` into a runnable backend (router / sandbox / fake). */
910
- backendFor: (profile: AgentProfile, role: 'worker' | 'persona') => AgentExecutionBackend;
911
- /** Render a profile's system prompt. */
912
- systemPromptOf: (profile: AgentProfile) => string;
913
- /** The persona driving each scenario — a driver profile or scripted turns. */
914
- personaOf: (scenario: TScenario) => PersonaDriver;
915
- /** Build the scored artifact from the finished transcript. */
916
- artifactOf: (transcript: ConversationTurn[], scenario: TScenario) => TArtifact;
917
- /** Speaker-turn cap (required when a persona is profile-driven). */
918
- maxTurns?: (scenario: TScenario) => number;
919
- seed?: (scenario: TScenario) => string;
920
- workerName?: string;
921
- /** Provider- or executor-enforced maximum for the whole worker conversation.
922
- * Required before execution when the enclosing campaign is cost-capped. */
923
- maximumCharge?: MaximumCharge | ((worker: AgentProfile, scenario: TScenario) => MaximumCharge | undefined);
924
- }
925
- /**
926
- * Wrap {@link runPersonaConversation} as a `ProfileDispatchFn` for
927
- * `runProfileMatrix`: the profile axis is the worker-under-test, the scenario
928
- * axis is the persona, and the runner is the cell. Meters the worker through
929
- * `ctx.cost` so the matrix's backend-integrity guard sees real usage.
930
- */
931
- declare function runPersonaDispatch<TScenario extends Scenario, TArtifact>(config: RunPersonaConfig<TScenario, TArtifact>): ProfileDispatchFn<TScenario, TArtifact>;
932
-
933
- /**
934
- *
935
- * Deterministic turn identifier. Stable across retries of the same logical
936
- * turn so backends (and any caching gateway in between) can dedupe on it.
937
- * A retry triggered by a network blip or deadline timeout MUST produce the
938
- * same `turn_id`; only the underlying attempt count differs.
939
- *
940
- * Shape: `${runId}.t${index}.${speakerSlug}` — readable in logs, sortable by
941
- * turn index, attributable to a speaker. Slugify keeps the speaker portion
942
- * URL-safe so it can ride in HTTP headers without escaping.
943
- *
944
- * @stable
945
- */
946
- declare function turnId(runId: string, index: number, speaker: string): string;
947
- /**
948
- * Reduce a speaker name to ASCII alphanumerics + dashes. Preserves enough
949
- * substance to read in a log line; collisions between speakers within a
950
- * single Conversation are prevented by `defineConversation`'s
951
- * unique-name check, so the slug only needs to be deterministic, not unique.
952
- */
953
- declare function slugifySpeaker(speaker: string): string;
954
-
955
41
  /**
956
42
  * `handleChatTurn` — framework-neutral chat-turn HTTP orchestrator.
957
43
  * Owns the NDJSON `ChatStreamEvent` line protocol, the `session.run.*`
@@ -1183,7 +269,7 @@ interface AgentProfileDiffProposal {
1183
269
  rationale?: string;
1184
270
  }
1185
271
  type ProfileDiffProposerContext<TFindings = unknown> = ProposeContext<TFindings> & {
1186
- profile: AgentProfile$1;
272
+ profile: AgentProfile;
1187
273
  };
1188
274
  interface ProfileDiffProposerOptions<TFindings = unknown> {
1189
275
  proposeDiffs(context: ProfileDiffProposerContext<TFindings>): Promise<readonly AgentProfileDiffProposal[]> | readonly AgentProfileDiffProposal[];
@@ -1262,7 +348,7 @@ interface RawTraceDistillerOptions {
1262
348
  * scenarios, judge, agent,
1263
349
  * })
1264
350
  */
1265
- declare function rawTraceDistiller<TScenario extends Scenario$1 = Scenario$1, TArtifact = unknown>(options?: RawTraceDistillerOptions): NonNullable<SelfImproveOptions<TScenario, TArtifact>['analyzeGeneration']>;
351
+ declare function rawTraceDistiller<TScenario extends Scenario = Scenario, TArtifact = unknown>(options?: RawTraceDistillerOptions): NonNullable<SelfImproveOptions<TScenario, TArtifact>['analyzeGeneration']>;
1266
352
 
1267
353
  /**
1268
354
  *
@@ -1710,4 +796,4 @@ interface StreamToolLoopOptions<Raw> {
1710
796
  * `capped` if it stops for any non-completed reason with calls still pending. */
1711
797
  declare function streamToolLoop<Raw>(opts: StreamToolLoopOptions<Raw>): AsyncGenerator<StreamToolLoopYield<Raw>, void, unknown>;
1712
798
 
1713
- export { AgentBackendContext, AgentBackendInput, type AgentBackendKind, AgentExecutionBackend, type AgentProfileDiffProposal, AgentTaskRunResult, type AuthSource, type BackendCallPolicy, BackendTransportError, CandidateGenerator, type ChatStreamEvent, type ChatTurnHooks, type ChatTurnIdentity, type ChatTurnProducer, type ChatTurnResult, type CircuitBreakerConfig, CircuitBreakerState, CircuitOpenError, type Conversation, type ConversationDriveState, type ConversationJournal, type ConversationJournalEntry, type ConversationParticipant, type ConversationPolicy, type ConversationResult, type ConversationStreamEvent, type ConversationTurn, type D1DatabaseLike, type D1StmtLike, DEFAULT_MAX_DEPTH, DEFAULT_ROUTER_BASE_URL, DeadlineExceededError, FORWARD_HEADERS, FileConversationJournal, type ForwardHeaderName, type HaltContext, type HaltPredicate, type HaltReason, type HaltSignal, InMemoryConversationJournal, InMemoryRuntimeSessionStore, type ModelInfo, OpenAIChatResponseFormat, OpenAIChatTool, OpenAIChatToolChoice, type PersonaConversationResult, type PersonaDriver, PlannerError, type ProfileDiffProposerContext, type ProfileDiffProposerOptions, type PropagatedHeaders, type RawTraceDistillerOptions, type ReflectiveGeneratorOptions, type ResolveAgentBackendOptions, type ResolvedChatModel, type RetryBackoff, type RetryableErrorPredicate, type RouterEnv, type RunChatTurnInput, type RunConversationOptions, type RunPersonaConfig, type RunPersonaConversationOptions, type RunToolLoopOptions, RuntimeHooks, RuntimeRunStateError, RuntimeSessionStore, RuntimeStreamEvent, RuntimeTelemetryOptions, type SqlAdapter, SqlConversationJournal, type StreamToolLoopOptions, type StreamToolLoopYield, type ToolCallOutcome, type ToolLoopAssistantToolCall, type ToolLoopCall, type ToolLoopEvent, type ToolLoopMessage, type ToolLoopResult, type ToolLoopStopReason, type TurnOrder, applyRunRecordDefaults, buildForwardHeaders, cleanModelId, computeBackoff, createConversationBackend, createIterableBackend, createOpenAICompatibleBackend, createSandboxPromptBackend, d1ToSqlAdapter, decideKnowledgeReadiness, defaultIsRetryable, defineConversation, deriveExecutionId, getModels, handleChatTurn, isDepthExceeded, makePerAttemptSignal, mcpBuildPrompt, profileDiffProposer, rawTraceDistiller, readDepth, readinessServerSentEvent, reflectiveGenerator, resolveAgentBackend, resolveChatModel, resolveRouterBaseUrl, runAgentTask, runAgentTaskStream, runConversation, runConversationStream, runPersonaConversation, runPersonaDispatch, runToolLoop, runtimeStreamServerSentEvent, sleep, slugifySpeaker, streamToolLoop, toolBuildPrompt, turnId, validateChatModelId };
799
+ export { AgentBackendInput, type AgentBackendKind, AgentExecutionBackend, type AgentProfileDiffProposal, AgentTaskRunResult, BackendTransportError, CandidateGenerator, type ChatStreamEvent, type ChatTurnHooks, type ChatTurnIdentity, type ChatTurnProducer, type ChatTurnResult, DEFAULT_ROUTER_BASE_URL, InMemoryRuntimeSessionStore, type ModelInfo, PlannerError, type ProfileDiffProposerContext, type ProfileDiffProposerOptions, type RawTraceDistillerOptions, type ReflectiveGeneratorOptions, type ResolveAgentBackendOptions, type ResolvedChatModel, type RouterEnv, type RunChatTurnInput, type RunToolLoopOptions, RuntimeHooks, RuntimeRunStateError, RuntimeSessionStore, RuntimeStreamEvent, RuntimeTelemetryOptions, type StreamToolLoopOptions, type StreamToolLoopYield, type ToolCallOutcome, type ToolLoopAssistantToolCall, type ToolLoopCall, type ToolLoopEvent, type ToolLoopMessage, type ToolLoopResult, type ToolLoopStopReason, applyRunRecordDefaults, cleanModelId, createOpenAICompatibleBackend, decideKnowledgeReadiness, deriveExecutionId, getModels, handleChatTurn, mcpBuildPrompt, profileDiffProposer, rawTraceDistiller, readinessServerSentEvent, reflectiveGenerator, resolveAgentBackend, resolveChatModel, resolveRouterBaseUrl, runAgentTask, runAgentTaskStream, runToolLoop, runtimeStreamServerSentEvent, streamToolLoop, toolBuildPrompt, validateChatModelId };