@graphorin/core 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 (134) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +21 -0
  3. package/README.md +70 -0
  4. package/dist/channels/channels.d.ts +156 -0
  5. package/dist/channels/channels.d.ts.map +1 -0
  6. package/dist/channels/channels.js +90 -0
  7. package/dist/channels/channels.js.map +1 -0
  8. package/dist/channels/directive.d.ts +34 -0
  9. package/dist/channels/directive.d.ts.map +1 -0
  10. package/dist/channels/directive.js +29 -0
  11. package/dist/channels/directive.js.map +1 -0
  12. package/dist/channels/dispatch.d.ts +26 -0
  13. package/dist/channels/dispatch.d.ts.map +1 -0
  14. package/dist/channels/dispatch.js +32 -0
  15. package/dist/channels/dispatch.js.map +1 -0
  16. package/dist/channels/index.d.ts +5 -0
  17. package/dist/channels/index.js +6 -0
  18. package/dist/channels/pause.d.ts +84 -0
  19. package/dist/channels/pause.d.ts.map +1 -0
  20. package/dist/channels/pause.js +90 -0
  21. package/dist/channels/pause.js.map +1 -0
  22. package/dist/contracts/auth-token-store.d.ts +45 -0
  23. package/dist/contracts/auth-token-store.d.ts.map +1 -0
  24. package/dist/contracts/checkpoint-store.d.ts +90 -0
  25. package/dist/contracts/checkpoint-store.d.ts.map +1 -0
  26. package/dist/contracts/embedder.d.ts +45 -0
  27. package/dist/contracts/embedder.d.ts.map +1 -0
  28. package/dist/contracts/eval-scorer.d.ts +46 -0
  29. package/dist/contracts/eval-scorer.d.ts.map +1 -0
  30. package/dist/contracts/index.d.ts +22 -0
  31. package/dist/contracts/index.js +6 -0
  32. package/dist/contracts/local-provider-trust.d.ts +36 -0
  33. package/dist/contracts/local-provider-trust.d.ts.map +1 -0
  34. package/dist/contracts/logger.d.ts +53 -0
  35. package/dist/contracts/logger.d.ts.map +1 -0
  36. package/dist/contracts/logger.js +21 -0
  37. package/dist/contracts/logger.js.map +1 -0
  38. package/dist/contracts/memory-store.d.ts +106 -0
  39. package/dist/contracts/memory-store.d.ts.map +1 -0
  40. package/dist/contracts/oauth-server-store.d.ts +81 -0
  41. package/dist/contracts/oauth-server-store.d.ts.map +1 -0
  42. package/dist/contracts/preferred-model.d.ts +60 -0
  43. package/dist/contracts/preferred-model.d.ts.map +1 -0
  44. package/dist/contracts/preferred-model.js +15 -0
  45. package/dist/contracts/preferred-model.js.map +1 -0
  46. package/dist/contracts/provider.d.ts +272 -0
  47. package/dist/contracts/provider.d.ts.map +1 -0
  48. package/dist/contracts/reasoning-retention.d.ts +53 -0
  49. package/dist/contracts/reasoning-retention.d.ts.map +1 -0
  50. package/dist/contracts/redaction-validator.d.ts +59 -0
  51. package/dist/contracts/redaction-validator.d.ts.map +1 -0
  52. package/dist/contracts/sandbox.d.ts +73 -0
  53. package/dist/contracts/sandbox.d.ts.map +1 -0
  54. package/dist/contracts/secret-ref.d.ts +26 -0
  55. package/dist/contracts/secret-ref.d.ts.map +1 -0
  56. package/dist/contracts/secret-value.d.ts +112 -0
  57. package/dist/contracts/secret-value.d.ts.map +1 -0
  58. package/dist/contracts/secret-value.js +24 -0
  59. package/dist/contracts/secret-value.js.map +1 -0
  60. package/dist/contracts/secrets-store.d.ts +87 -0
  61. package/dist/contracts/secrets-store.d.ts.map +1 -0
  62. package/dist/contracts/session-store.d.ts +142 -0
  63. package/dist/contracts/session-store.d.ts.map +1 -0
  64. package/dist/contracts/token-counter.d.ts +28 -0
  65. package/dist/contracts/token-counter.d.ts.map +1 -0
  66. package/dist/contracts/tool.d.ts +264 -0
  67. package/dist/contracts/tool.d.ts.map +1 -0
  68. package/dist/contracts/tracer.d.ts +84 -0
  69. package/dist/contracts/tracer.d.ts.map +1 -0
  70. package/dist/contracts/tracer.js +34 -0
  71. package/dist/contracts/tracer.js.map +1 -0
  72. package/dist/contracts/trigger-store.d.ts +43 -0
  73. package/dist/contracts/trigger-store.d.ts.map +1 -0
  74. package/dist/index.d.ts +59 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +38 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/types/agent-event.d.ts +449 -0
  79. package/dist/types/agent-event.d.ts.map +1 -0
  80. package/dist/types/handoff.d.ts +112 -0
  81. package/dist/types/handoff.d.ts.map +1 -0
  82. package/dist/types/index.d.ts +13 -0
  83. package/dist/types/index.js +6 -0
  84. package/dist/types/memory.d.ts +354 -0
  85. package/dist/types/memory.d.ts.map +1 -0
  86. package/dist/types/message.d.ts +162 -0
  87. package/dist/types/message.d.ts.map +1 -0
  88. package/dist/types/run.d.ts +155 -0
  89. package/dist/types/run.d.ts.map +1 -0
  90. package/dist/types/run.js +31 -0
  91. package/dist/types/run.js.map +1 -0
  92. package/dist/types/sensitivity.d.ts +35 -0
  93. package/dist/types/sensitivity.d.ts.map +1 -0
  94. package/dist/types/sensitivity.js +29 -0
  95. package/dist/types/sensitivity.js.map +1 -0
  96. package/dist/types/session-scope.d.ts +22 -0
  97. package/dist/types/session-scope.d.ts.map +1 -0
  98. package/dist/types/stop-condition.d.ts +62 -0
  99. package/dist/types/stop-condition.d.ts.map +1 -0
  100. package/dist/types/stop-condition.js +81 -0
  101. package/dist/types/stop-condition.js.map +1 -0
  102. package/dist/types/tool-call.d.ts +27 -0
  103. package/dist/types/tool-call.d.ts.map +1 -0
  104. package/dist/types/tool.d.ts +260 -0
  105. package/dist/types/tool.d.ts.map +1 -0
  106. package/dist/types/usage.d.ts +82 -0
  107. package/dist/types/usage.d.ts.map +1 -0
  108. package/dist/types/usage.js +17 -0
  109. package/dist/types/usage.js.map +1 -0
  110. package/dist/types/workflow-event.d.ts +108 -0
  111. package/dist/types/workflow-event.d.ts.map +1 -0
  112. package/dist/utils/assert-never.d.ts +26 -0
  113. package/dist/utils/assert-never.d.ts.map +1 -0
  114. package/dist/utils/assert-never.js +29 -0
  115. package/dist/utils/assert-never.js.map +1 -0
  116. package/dist/utils/async-context.d.ts +37 -0
  117. package/dist/utils/async-context.d.ts.map +1 -0
  118. package/dist/utils/async-context.js +33 -0
  119. package/dist/utils/async-context.js.map +1 -0
  120. package/dist/utils/hash.d.ts +30 -0
  121. package/dist/utils/hash.d.ts.map +1 -0
  122. package/dist/utils/hash.js +102 -0
  123. package/dist/utils/hash.js.map +1 -0
  124. package/dist/utils/index.d.ts +6 -0
  125. package/dist/utils/index.js +7 -0
  126. package/dist/utils/streams.d.ts +59 -0
  127. package/dist/utils/streams.d.ts.map +1 -0
  128. package/dist/utils/streams.js +169 -0
  129. package/dist/utils/streams.js.map +1 -0
  130. package/dist/utils/validation.d.ts +67 -0
  131. package/dist/utils/validation.d.ts.map +1 -0
  132. package/dist/utils/validation.js +36 -0
  133. package/dist/utils/validation.js.map +1 -0
  134. package/package.json +82 -0
@@ -0,0 +1,31 @@
1
+ //#region src/types/run.ts
2
+ /**
3
+ * Snapshot helper used by `@graphorin/observability` aggregators to
4
+ * convert the on-disk `usageByModel` shape into the canonical
5
+ * {@link ModelUsage} array. Pure utility — kept in core so consumers
6
+ * do not have to take an observability dependency just to flatten a
7
+ * run-state breakdown.
8
+ *
9
+ * @stable
10
+ */
11
+ function flattenUsageByModel(byModel) {
12
+ if (byModel === void 0) return [];
13
+ const out = [];
14
+ for (const [modelId, entry] of Object.entries(byModel)) {
15
+ const m = {
16
+ modelId,
17
+ promptTokens: entry.promptTokens,
18
+ completionTokens: entry.completionTokens,
19
+ totalTokens: entry.totalTokens,
20
+ callCount: entry.attemptCount,
21
+ ...entry.reasoningTokens !== void 0 ? { reasoningTokens: entry.reasoningTokens } : {},
22
+ ...entry.cost !== void 0 ? { cost: entry.cost } : {}
23
+ };
24
+ out.push(m);
25
+ }
26
+ return out;
27
+ }
28
+
29
+ //#endregion
30
+ export { flattenUsageByModel };
31
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","names":["out: ModelUsage[]","m: ModelUsage"],"sources":["../../src/types/run.ts"],"sourcesContent":["import type { Tracer } from '../contracts/tracer.js';\nimport type { HandoffRecord } from './handoff.js';\nimport type { Message } from './message.js';\nimport type { CompletedToolCall, ToolApproval } from './tool.js';\nimport type { ModelUsage, Usage, UsageAccumulator } from './usage.js';\n\n/**\n * Status of an in-flight or completed agent run. Append-only persistence\n * stores expose this verbatim on the `runs` table.\n *\n * @stable\n */\nexport type RunStatus = 'running' | 'completed' | 'failed' | 'aborted' | 'awaiting_approval';\n\n/**\n * Single step inside an agent run. The agent runtime appends one\n * `RunStep` per provider call.\n *\n * @stable\n */\nexport interface RunStep {\n readonly stepNumber: number;\n readonly startedAt: string;\n readonly endedAt?: string;\n readonly usage?: Usage;\n readonly toolCalls: readonly CompletedToolCall[];\n /**\n * Stable agent id active for this step (changes after a handoff).\n */\n readonly agentId: string;\n}\n\n/**\n * Per-model usage breakdown carried alongside the aggregate\n * {@link Usage} on {@link RunState}. Populated by the per-step retry\n * loop when `Agent.fallbackModels` fires; for runs that never fall\n * back, the map carries a single entry for the primary model with\n * `attemptCount: 1`.\n *\n * The aggregate `RunState.usage` is always the sum of every entry's\n * `Usage` portion (the field is asserted in tests).\n *\n * @stable\n */\nexport interface RunStateUsageByModel {\n readonly [modelId: string]: Usage & { readonly attemptCount: number };\n}\n\n/**\n * The full, serializable state of a run. The agent runtime persists this\n * to the checkpoint store on every `awaiting_approval` boundary, so a\n * separate process can resume the run.\n *\n * The shape is intentionally JSON-stable: every nested type is plain\n * `JSON`-encodable (no `Map`, no `Set`, no `Date`).\n *\n * @stable\n */\nexport interface RunState {\n readonly id: string;\n readonly agentId: string;\n readonly currentAgentId: string;\n readonly sessionId: string;\n readonly userId?: string;\n status: RunStatus;\n readonly steps: RunStep[];\n readonly messages: Message[];\n readonly pendingApprovals: ToolApproval[];\n readonly handoffs: HandoffRecord[];\n readonly usage: Usage;\n /**\n * Per-model usage breakdown. Populated by the per-step retry loop\n * when `Agent.fallbackModels` fires (RB-48 / suggested DEC-164 /\n * suggested ADR-052). Backward-compat: rehydrating a serialized\n * state that omits the field synthesizes a single-entry map for\n * the primary model.\n */\n usageByModel?: RunStateUsageByModel;\n /**\n * AG-19: coarse data-flow taint summary, carried across suspend/resume so a\n * resumed run does not start with an empty ledger that silently un-gates\n * sinks exposed before the suspend. Structurally matches\n * `@graphorin/security`'s `TaintLedgerSnapshot` (core takes no security\n * dependency); only the load-bearing flags are persisted — never the tracked\n * untrusted text spans.\n */\n taintSummary?: RunTaintSummary;\n /**\n * AG-19: names of deferred tools promoted by `tool_search` this run, carried\n * across suspend/resume so discovered tools remain in the per-step catalogue.\n */\n promotedTools?: ReadonlyArray<string>;\n readonly startedAt: string;\n finishedAt?: string;\n error?: RunError;\n}\n\n/**\n * Coarse, serializable data-flow taint summary persisted in {@link RunState}\n * across suspend/resume (AG-19). Structurally identical to\n * `@graphorin/security`'s `TaintLedgerSnapshot`; carries no untrusted text.\n *\n * @stable\n */\nexport interface RunTaintSummary {\n readonly untrustedSeen: boolean;\n readonly sensitiveSeen: boolean;\n readonly untrustedSourceKinds: ReadonlyArray<string>;\n}\n\n/**\n * Snapshot helper used by `@graphorin/observability` aggregators to\n * convert the on-disk `usageByModel` shape into the canonical\n * {@link ModelUsage} array. Pure utility — kept in core so consumers\n * do not have to take an observability dependency just to flatten a\n * run-state breakdown.\n *\n * @stable\n */\nexport function flattenUsageByModel(\n byModel: RunStateUsageByModel | undefined,\n): ReadonlyArray<ModelUsage> {\n if (byModel === undefined) return [];\n const out: ModelUsage[] = [];\n for (const [modelId, entry] of Object.entries(byModel)) {\n const m: ModelUsage = {\n modelId,\n promptTokens: entry.promptTokens,\n completionTokens: entry.completionTokens,\n totalTokens: entry.totalTokens,\n callCount: entry.attemptCount,\n ...(entry.reasoningTokens !== undefined ? { reasoningTokens: entry.reasoningTokens } : {}),\n ...(entry.cost !== undefined ? { cost: entry.cost } : {}),\n };\n out.push(m);\n }\n return out;\n}\n\n/**\n * Failure carried by `RunState.error`. The shape mirrors the wire format\n * used by `agent.error` events.\n *\n * @stable\n */\nexport interface RunError {\n readonly message: string;\n readonly code: string;\n readonly details?: unknown;\n}\n\n/**\n * Per-run dependency / context bag handed to every tool, hook and\n * provider middleware in scope. Generic over the user-defined deps shape.\n *\n * `tracer`, `signal`, `usage` and `state` are always present; everything\n * else is optional.\n *\n * @stable\n */\nexport interface RunContext<TDeps = unknown> {\n readonly runId: string;\n readonly sessionId: string;\n readonly userId?: string;\n readonly agentId: string;\n readonly deps: TDeps;\n readonly tracer: Tracer;\n readonly signal: AbortSignal;\n readonly usage: UsageAccumulator;\n readonly stepNumber: number;\n readonly messages: ReadonlyArray<Message>;\n readonly state: RunState;\n}\n"],"mappings":";;;;;;;;;;AAuHA,SAAgB,oBACd,SAC2B;AAC3B,KAAI,YAAY,OAAW,QAAO,EAAE;CACpC,MAAMA,MAAoB,EAAE;AAC5B,MAAK,MAAM,CAAC,SAAS,UAAU,OAAO,QAAQ,QAAQ,EAAE;EACtD,MAAMC,IAAgB;GACpB;GACA,cAAc,MAAM;GACpB,kBAAkB,MAAM;GACxB,aAAa,MAAM;GACnB,WAAW,MAAM;GACjB,GAAI,MAAM,oBAAoB,SAAY,EAAE,iBAAiB,MAAM,iBAAiB,GAAG,EAAE;GACzF,GAAI,MAAM,SAAS,SAAY,EAAE,MAAM,MAAM,MAAM,GAAG,EAAE;GACzD;AACD,MAAI,KAAK,EAAE;;AAEb,QAAO"}
@@ -0,0 +1,35 @@
1
+ //#region src/types/sensitivity.d.ts
2
+ /**
3
+ * Sensitivity tier for any piece of data flowing through Graphorin.
4
+ *
5
+ * - `'public'` — non-sensitive content; safe for any provider, any sink.
6
+ * - `'internal'` — default for user-generated content; safe for trusted
7
+ * providers (loopback / private-network) but redacted for public-tls
8
+ * exporters and replay consumers.
9
+ * - `'secret'` — credentials, tokens, encryption keys; only ever stays
10
+ * in-process and is never serialized to the wire by default.
11
+ *
12
+ * @stable
13
+ */
14
+ type Sensitivity = 'public' | 'internal' | 'secret';
15
+ /**
16
+ * Strict ordering used by sensitivity-aware filters
17
+ * (`record.sensitivity ⊆ provider.acceptsSensitivity`).
18
+ *
19
+ * @stable
20
+ */
21
+ declare const SENSITIVITY_ORDER: readonly Sensitivity[];
22
+ /**
23
+ * Return `true` iff `record` is allowed to flow to a sink declaring `accepts`.
24
+ *
25
+ * Comparison is **subset** semantics: the record's tier must be one of the
26
+ * tiers in `accepts` (it's not enough for the record's tier to be lower).
27
+ * That mirrors the way provider `acceptsSensitivity` is declared in the
28
+ * Graphorin trust matrix.
29
+ *
30
+ * @stable
31
+ */
32
+ declare function acceptsSensitivity(accepts: readonly Sensitivity[], record: Sensitivity): boolean;
33
+ //#endregion
34
+ export { SENSITIVITY_ORDER, Sensitivity, acceptsSensitivity };
35
+ //# sourceMappingURL=sensitivity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sensitivity.d.ts","names":[],"sources":["../../src/types/sensitivity.ts"],"sourcesContent":[],"mappings":";;AAYA;AAQA;AAYA;;;;;;;;;KApBY,WAAA;;;;;;;cAQC,4BAA4B;;;;;;;;;;;iBAYzB,kBAAA,mBAAqC,uBAAuB"}
@@ -0,0 +1,29 @@
1
+ //#region src/types/sensitivity.ts
2
+ /**
3
+ * Strict ordering used by sensitivity-aware filters
4
+ * (`record.sensitivity ⊆ provider.acceptsSensitivity`).
5
+ *
6
+ * @stable
7
+ */
8
+ const SENSITIVITY_ORDER = [
9
+ "public",
10
+ "internal",
11
+ "secret"
12
+ ];
13
+ /**
14
+ * Return `true` iff `record` is allowed to flow to a sink declaring `accepts`.
15
+ *
16
+ * Comparison is **subset** semantics: the record's tier must be one of the
17
+ * tiers in `accepts` (it's not enough for the record's tier to be lower).
18
+ * That mirrors the way provider `acceptsSensitivity` is declared in the
19
+ * Graphorin trust matrix.
20
+ *
21
+ * @stable
22
+ */
23
+ function acceptsSensitivity(accepts, record) {
24
+ return accepts.includes(record);
25
+ }
26
+
27
+ //#endregion
28
+ export { SENSITIVITY_ORDER, acceptsSensitivity };
29
+ //# sourceMappingURL=sensitivity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sensitivity.js","names":["SENSITIVITY_ORDER: readonly Sensitivity[]"],"sources":["../../src/types/sensitivity.ts"],"sourcesContent":["/**\n * Sensitivity tier for any piece of data flowing through Graphorin.\n *\n * - `'public'` — non-sensitive content; safe for any provider, any sink.\n * - `'internal'` — default for user-generated content; safe for trusted\n * providers (loopback / private-network) but redacted for public-tls\n * exporters and replay consumers.\n * - `'secret'` — credentials, tokens, encryption keys; only ever stays\n * in-process and is never serialized to the wire by default.\n *\n * @stable\n */\nexport type Sensitivity = 'public' | 'internal' | 'secret';\n\n/**\n * Strict ordering used by sensitivity-aware filters\n * (`record.sensitivity ⊆ provider.acceptsSensitivity`).\n *\n * @stable\n */\nexport const SENSITIVITY_ORDER: readonly Sensitivity[] = ['public', 'internal', 'secret'] as const;\n\n/**\n * Return `true` iff `record` is allowed to flow to a sink declaring `accepts`.\n *\n * Comparison is **subset** semantics: the record's tier must be one of the\n * tiers in `accepts` (it's not enough for the record's tier to be lower).\n * That mirrors the way provider `acceptsSensitivity` is declared in the\n * Graphorin trust matrix.\n *\n * @stable\n */\nexport function acceptsSensitivity(accepts: readonly Sensitivity[], record: Sensitivity): boolean {\n return accepts.includes(record);\n}\n"],"mappings":";;;;;;;AAoBA,MAAaA,oBAA4C;CAAC;CAAU;CAAY;CAAS;;;;;;;;;;;AAYzF,SAAgB,mBAAmB,SAAiC,QAA8B;AAChG,QAAO,QAAQ,SAAS,OAAO"}
@@ -0,0 +1,22 @@
1
+ //#region src/types/session-scope.d.ts
2
+ /**
3
+ * Identifies a logical conversational scope: who the user is, which agent
4
+ * is in charge, and (when known) which session they're inside.
5
+ *
6
+ * Used as a parameter to almost every Memory / Sessions API. The agent and
7
+ * session fields are optional because some scopes are user-wide (e.g.
8
+ * shared facts attached to a user, not a particular agent).
9
+ *
10
+ * @stable
11
+ */
12
+ interface SessionScope {
13
+ /** Stable identifier of the user (single-user-per-process by default). */
14
+ readonly userId: string;
15
+ /** Identifier of the agent owning the scope, when applicable. */
16
+ readonly agentId?: string;
17
+ /** Identifier of the session, when applicable. */
18
+ readonly sessionId?: string;
19
+ }
20
+ //#endregion
21
+ export { SessionScope };
22
+ //# sourceMappingURL=session-scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-scope.d.ts","names":[],"sources":["../../src/types/session-scope.ts"],"sourcesContent":[],"mappings":";;AAUA;;;;;;;;;UAAiB,YAAA"}
@@ -0,0 +1,62 @@
1
+ import { RunState } from "./run.js";
2
+
3
+ //#region src/types/stop-condition.d.ts
4
+
5
+ /**
6
+ * Predicate consulted by the agent runtime after every step to decide
7
+ * whether the loop should stop.
8
+ *
9
+ * Stop conditions are pure — they look at the current `RunState` and
10
+ * return a boolean. The runtime never re-orders or short-circuits the
11
+ * order in which operands of `and` / `or` are evaluated, so users can
12
+ * rely on the obvious left-to-right semantics.
13
+ *
14
+ * @stable
15
+ */
16
+ interface StopCondition {
17
+ /** Human-friendly label included in observability spans. */
18
+ readonly description: string;
19
+ /** Returns `true` when the run should stop on this state. */
20
+ readonly check: (state: RunState) => boolean;
21
+ }
22
+ /**
23
+ * Stop after `n` total steps (`stepNumber >= n`). The default condition
24
+ * for the agent runtime is `isStepCount(50)`.
25
+ *
26
+ * @stable
27
+ */
28
+ declare function isStepCount(n: number): StopCondition;
29
+ /**
30
+ * Stop as soon as the most recent assistant message contains a tool call
31
+ * with the given name.
32
+ *
33
+ * @stable
34
+ */
35
+ declare function hasToolCall(toolName: string): StopCondition;
36
+ /**
37
+ * Stop when the run reaches a terminal status.
38
+ *
39
+ * @stable
40
+ */
41
+ declare const isTerminal: StopCondition;
42
+ /**
43
+ * Stop when **any** of the supplied conditions is satisfied.
44
+ *
45
+ * @stable
46
+ */
47
+ declare function or(...conditions: readonly StopCondition[]): StopCondition;
48
+ /**
49
+ * Stop only when **all** of the supplied conditions are satisfied.
50
+ *
51
+ * @stable
52
+ */
53
+ declare function and(...conditions: readonly StopCondition[]): StopCondition;
54
+ /**
55
+ * Negate the supplied condition.
56
+ *
57
+ * @stable
58
+ */
59
+ declare function not(condition: StopCondition): StopCondition;
60
+ //#endregion
61
+ export { StopCondition, and, hasToolCall, isStepCount, isTerminal, not, or };
62
+ //# sourceMappingURL=stop-condition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop-condition.d.ts","names":[],"sources":["../../src/types/stop-condition.ts"],"sourcesContent":[],"mappings":";;;;;;AAaA;AAaA;AAgBA;AAyBA;AAWA;AAYA;AAYA;;;UAzFiB,aAAA;;;;0BAIS;;;;;;;;iBASV,WAAA,aAAwB;;;;;;;iBAgBxB,WAAA,oBAA+B;;;;;;cAyBlC,YAAY;;;;;;iBAWT,EAAA,yBAA2B,kBAAkB;;;;;;iBAY7C,GAAA,yBAA4B,kBAAkB;;;;;;iBAY9C,GAAA,YAAe,gBAAgB"}
@@ -0,0 +1,81 @@
1
+ //#region src/types/stop-condition.ts
2
+ /**
3
+ * Stop after `n` total steps (`stepNumber >= n`). The default condition
4
+ * for the agent runtime is `isStepCount(50)`.
5
+ *
6
+ * @stable
7
+ */
8
+ function isStepCount(n) {
9
+ if (!Number.isFinite(n) || n <= 0) throw new RangeError(`isStepCount: n must be a positive integer (got ${String(n)})`);
10
+ return {
11
+ description: `step >= ${n}`,
12
+ check: (state) => state.steps.length >= n
13
+ };
14
+ }
15
+ /**
16
+ * Stop as soon as the most recent assistant message contains a tool call
17
+ * with the given name.
18
+ *
19
+ * @stable
20
+ */
21
+ function hasToolCall(toolName) {
22
+ return {
23
+ description: `tool-call:${toolName}`,
24
+ check: (state) => {
25
+ for (let i = state.messages.length - 1; i >= 0; i--) {
26
+ const msg = state.messages[i];
27
+ if (msg && msg.role === "assistant") {
28
+ if (msg.toolCalls?.some((c) => c.toolName === toolName)) return true;
29
+ return false;
30
+ }
31
+ }
32
+ return false;
33
+ }
34
+ };
35
+ }
36
+ /**
37
+ * Stop when the run reaches a terminal status.
38
+ *
39
+ * @stable
40
+ */
41
+ const isTerminal = {
42
+ description: "status:terminal",
43
+ check: (state) => state.status === "completed" || state.status === "failed" || state.status === "aborted"
44
+ };
45
+ /**
46
+ * Stop when **any** of the supplied conditions is satisfied.
47
+ *
48
+ * @stable
49
+ */
50
+ function or(...conditions) {
51
+ return {
52
+ description: `or(${conditions.map((c) => c.description).join(", ")})`,
53
+ check: (state) => conditions.some((c) => c.check(state))
54
+ };
55
+ }
56
+ /**
57
+ * Stop only when **all** of the supplied conditions are satisfied.
58
+ *
59
+ * @stable
60
+ */
61
+ function and(...conditions) {
62
+ return {
63
+ description: `and(${conditions.map((c) => c.description).join(", ")})`,
64
+ check: (state) => conditions.every((c) => c.check(state))
65
+ };
66
+ }
67
+ /**
68
+ * Negate the supplied condition.
69
+ *
70
+ * @stable
71
+ */
72
+ function not(condition) {
73
+ return {
74
+ description: `not(${condition.description})`,
75
+ check: (state) => !condition.check(state)
76
+ };
77
+ }
78
+
79
+ //#endregion
80
+ export { and, hasToolCall, isStepCount, isTerminal, not, or };
81
+ //# sourceMappingURL=stop-condition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop-condition.js","names":["isTerminal: StopCondition"],"sources":["../../src/types/stop-condition.ts"],"sourcesContent":["import type { RunState } from './run.js';\n\n/**\n * Predicate consulted by the agent runtime after every step to decide\n * whether the loop should stop.\n *\n * Stop conditions are pure — they look at the current `RunState` and\n * return a boolean. The runtime never re-orders or short-circuits the\n * order in which operands of `and` / `or` are evaluated, so users can\n * rely on the obvious left-to-right semantics.\n *\n * @stable\n */\nexport interface StopCondition {\n /** Human-friendly label included in observability spans. */\n readonly description: string;\n /** Returns `true` when the run should stop on this state. */\n readonly check: (state: RunState) => boolean;\n}\n\n/**\n * Stop after `n` total steps (`stepNumber >= n`). The default condition\n * for the agent runtime is `isStepCount(50)`.\n *\n * @stable\n */\nexport function isStepCount(n: number): StopCondition {\n if (!Number.isFinite(n) || n <= 0) {\n throw new RangeError(`isStepCount: n must be a positive integer (got ${String(n)})`);\n }\n return {\n description: `step >= ${n}`,\n check: (state): boolean => state.steps.length >= n,\n };\n}\n\n/**\n * Stop as soon as the most recent assistant message contains a tool call\n * with the given name.\n *\n * @stable\n */\nexport function hasToolCall(toolName: string): StopCondition {\n return {\n description: `tool-call:${toolName}`,\n check: (state): boolean => {\n for (let i = state.messages.length - 1; i >= 0; i--) {\n const msg = state.messages[i];\n if (msg && msg.role === 'assistant') {\n const calls = msg.toolCalls;\n if (calls?.some((c) => c.toolName === toolName)) {\n return true;\n }\n // First assistant message without the call → not yet matched.\n return false;\n }\n }\n return false;\n },\n };\n}\n\n/**\n * Stop when the run reaches a terminal status.\n *\n * @stable\n */\nexport const isTerminal: StopCondition = {\n description: 'status:terminal',\n check: (state): boolean =>\n state.status === 'completed' || state.status === 'failed' || state.status === 'aborted',\n};\n\n/**\n * Stop when **any** of the supplied conditions is satisfied.\n *\n * @stable\n */\nexport function or(...conditions: readonly StopCondition[]): StopCondition {\n return {\n description: `or(${conditions.map((c) => c.description).join(', ')})`,\n check: (state): boolean => conditions.some((c) => c.check(state)),\n };\n}\n\n/**\n * Stop only when **all** of the supplied conditions are satisfied.\n *\n * @stable\n */\nexport function and(...conditions: readonly StopCondition[]): StopCondition {\n return {\n description: `and(${conditions.map((c) => c.description).join(', ')})`,\n check: (state): boolean => conditions.every((c) => c.check(state)),\n };\n}\n\n/**\n * Negate the supplied condition.\n *\n * @stable\n */\nexport function not(condition: StopCondition): StopCondition {\n return {\n description: `not(${condition.description})`,\n check: (state): boolean => !condition.check(state),\n };\n}\n"],"mappings":";;;;;;;AA0BA,SAAgB,YAAY,GAA0B;AACpD,KAAI,CAAC,OAAO,SAAS,EAAE,IAAI,KAAK,EAC9B,OAAM,IAAI,WAAW,kDAAkD,OAAO,EAAE,CAAC,GAAG;AAEtF,QAAO;EACL,aAAa,WAAW;EACxB,QAAQ,UAAmB,MAAM,MAAM,UAAU;EAClD;;;;;;;;AASH,SAAgB,YAAY,UAAiC;AAC3D,QAAO;EACL,aAAa,aAAa;EAC1B,QAAQ,UAAmB;AACzB,QAAK,IAAI,IAAI,MAAM,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;IACnD,MAAM,MAAM,MAAM,SAAS;AAC3B,QAAI,OAAO,IAAI,SAAS,aAAa;AAEnC,SADc,IAAI,WACP,MAAM,MAAM,EAAE,aAAa,SAAS,CAC7C,QAAO;AAGT,YAAO;;;AAGX,UAAO;;EAEV;;;;;;;AAQH,MAAaA,aAA4B;CACvC,aAAa;CACb,QAAQ,UACN,MAAM,WAAW,eAAe,MAAM,WAAW,YAAY,MAAM,WAAW;CACjF;;;;;;AAOD,SAAgB,GAAG,GAAG,YAAqD;AACzE,QAAO;EACL,aAAa,MAAM,WAAW,KAAK,MAAM,EAAE,YAAY,CAAC,KAAK,KAAK,CAAC;EACnE,QAAQ,UAAmB,WAAW,MAAM,MAAM,EAAE,MAAM,MAAM,CAAC;EAClE;;;;;;;AAQH,SAAgB,IAAI,GAAG,YAAqD;AAC1E,QAAO;EACL,aAAa,OAAO,WAAW,KAAK,MAAM,EAAE,YAAY,CAAC,KAAK,KAAK,CAAC;EACpE,QAAQ,UAAmB,WAAW,OAAO,MAAM,EAAE,MAAM,MAAM,CAAC;EACnE;;;;;;;AAQH,SAAgB,IAAI,WAAyC;AAC3D,QAAO;EACL,aAAa,OAAO,UAAU,YAAY;EAC1C,QAAQ,UAAmB,CAAC,UAAU,MAAM,MAAM;EACnD"}
@@ -0,0 +1,27 @@
1
+ //#region src/types/tool-call.d.ts
2
+ /**
3
+ * The {@link ToolCall} leaf type lives in its own module so that
4
+ * `message.ts` (which references `ToolCall`) and `tool.ts` (which
5
+ * references `MessageContent`) can both depend on it without forming a
6
+ * circular import. `tool.ts` re-exports `ToolCall` for backwards
7
+ * compatibility, so external import paths are unchanged.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ /**
12
+ * A single tool invocation the model requested, normalised by the
13
+ * provider layer and handed to the tool executor for parallel dispatch.
14
+ *
15
+ * @stable
16
+ */
17
+ interface ToolCall {
18
+ /** Stable identifier the model uses to correlate input and output. */
19
+ readonly toolCallId: string;
20
+ /** Tool name as registered in the `ToolRegistry`. */
21
+ readonly toolName: string;
22
+ /** Validated input matching the tool's `inputSchema`. */
23
+ readonly args: unknown;
24
+ }
25
+ //#endregion
26
+ export { ToolCall };
27
+ //# sourceMappingURL=tool-call.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-call.d.ts","names":[],"sources":["../../src/types/tool-call.ts"],"sourcesContent":[],"mappings":";;AAgBA;;;;;;;;;;;;;;UAAiB,QAAA"}
@@ -0,0 +1,260 @@
1
+ import { ToolCall } from "./tool-call.js";
2
+ import { MessageContent } from "./message.js";
3
+
4
+ //#region src/types/tool.d.ts
5
+
6
+ /**
7
+ * Sandbox isolation level requested for a tool's `execute` method.
8
+ *
9
+ * The exact semantics live in `@graphorin/security`; downstream packages
10
+ * type their config field as `SandboxPolicy` so they don't take a security
11
+ * dependency just to type their inputs.
12
+ *
13
+ * @stable
14
+ */
15
+ type SandboxPolicy = 'none' | 'sandboxed' | 'isolated' | 'docker';
16
+ /**
17
+ * Memory-modification guard tier requested for a tool's `execute` method.
18
+ *
19
+ * Mirrors the tier classification consumed by `@graphorin/security`'s
20
+ * memory-modification guard so downstream packages can type their tool
21
+ * metadata against this discriminator without a hard dependency on the
22
+ * security package.
23
+ *
24
+ * - `'pure'` — no side effects of any kind.
25
+ * - `'side-effecting-no-memory'` — observable side effects outside of
26
+ * the framework's memory tiers (e.g. external HTTP).
27
+ * - `'memory-aware'` — mutates the framework's memory
28
+ * tiers via the sanctioned `ctx.memory.*` surface only.
29
+ * - `'unknown'` — no declaration; the runtime applies
30
+ * the audit-only baseline.
31
+ * - `'untrusted'` — third-party / untrusted skill code;
32
+ * the runtime forces the strictest snapshot policy.
33
+ *
34
+ * @stable
35
+ */
36
+ type MemoryGuardTier = 'pure' | 'side-effecting-no-memory' | 'memory-aware' | 'unknown' | 'untrusted';
37
+ /**
38
+ * Side-effect classification declared by a tool author.
39
+ *
40
+ * Surfaced uniformly by the tool dispatcher, downstream session
41
+ * cassette layers, retry middleware, and approval-policy derivations.
42
+ *
43
+ * - `'pure'` — deterministic; same `(input, ctx)` always
44
+ * yields the same output; no I/O of any kind.
45
+ * - `'read-only'` — queries external systems but never
46
+ * mutates them (e.g. database SELECT, HTTP GET).
47
+ * - `'side-effecting'` — mutates state inside the agent's logical
48
+ * boundary (e.g. memory writes, cache writes).
49
+ * - `'external-stateful'` — mutates state outside the agent's
50
+ * boundary that other systems can observe (e.g. issue creation,
51
+ * message dispatch, payment).
52
+ *
53
+ * @stable
54
+ */
55
+ type SideEffectClass = 'pure' | 'read-only' | 'side-effecting' | 'external-stateful';
56
+ /**
57
+ * Inbound prompt-injection sanitization policy applied to a tool's
58
+ * result body before it reaches the conversation history.
59
+ *
60
+ * - `'pass-through'` — no scan; bytes-equal forwarding
61
+ * (the trusted-built-in default).
62
+ * - `'detect-and-flag'` — scan; emit a flag span attribute
63
+ * + audit row but do not modify the body.
64
+ * - `'detect-and-strip'` — replace each match with the
65
+ * `[REDACTED:imperative-pattern]` literal token.
66
+ * - `'detect-and-wrap'` — wrap the body in the
67
+ * `<<<untrusted_content>>>` envelope without stripping matches.
68
+ * - `'detect-and-strip-and-wrap'` — both strip matches and wrap the
69
+ * resulting body (the untrusted-source default).
70
+ *
71
+ * @stable
72
+ */
73
+ type InboundSanitizationPolicy = 'pass-through' | 'detect-and-flag' | 'detect-and-strip' | 'detect-and-wrap' | 'detect-and-strip-and-wrap';
74
+ /**
75
+ * Result-envelope truncation strategy applied to a tool's assembled
76
+ * output before it reaches the conversation history.
77
+ *
78
+ * - `'middle'` — keep head and tail; insert annotation in the
79
+ * middle (the default).
80
+ * - `'tail'` — keep the tail; insert annotation at the
81
+ * head.
82
+ * - `'spill-to-file'` — keep the head; spill the un-truncated body
83
+ * to a per-run artifact file; insert annotation with the artifact
84
+ * path.
85
+ * - `'summarize'` — invoke the agent's configured summarizer
86
+ * and replace the body with the summary.
87
+ *
88
+ * @stable
89
+ */
90
+ type TruncationStrategy = 'middle' | 'tail' | 'spill-to-file' | 'summarize';
91
+ /**
92
+ * Trust class assigned to a registered tool. The class is computed at
93
+ * registration time from the registration source and the declared
94
+ * sandbox policy; downstream layers (sanitization, audit) read the
95
+ * class to pick the right default policy.
96
+ *
97
+ * @stable
98
+ */
99
+ type ToolTrustClass = 'first-party-built-in' | 'first-party-user-defined' | 'skill-trusted' | 'skill-untrusted' | 'mcp-derived' | 'web-search';
100
+ /**
101
+ * Source descriptor attached to a `Tool` registration. Mirrors the
102
+ * registration-time provenance the dispatcher uses to derive the
103
+ * trust class and to compute the four collision audit row kinds.
104
+ *
105
+ * @stable
106
+ */
107
+ type ToolSource = {
108
+ readonly kind: 'first-party';
109
+ } | {
110
+ readonly kind: 'built-in';
111
+ readonly subsystem: string;
112
+ } | {
113
+ readonly kind: 'skill';
114
+ readonly skillName: string;
115
+ readonly trustLevel: 'trusted' | 'untrusted';
116
+ } | {
117
+ readonly kind: 'mcp';
118
+ readonly serverIdentity: string;
119
+ } | {
120
+ readonly kind: 'web-search';
121
+ readonly providerName: string;
122
+ };
123
+ /**
124
+ * Single chunk of streamed tool content. Streaming-hint tools emit one
125
+ * chunk per `ctx.streamContent(...)` call; the executor concatenates
126
+ * the chunks into the assembled `output` per the buffer-becomes-output
127
+ * discipline.
128
+ *
129
+ * @stable
130
+ */
131
+ type ContentChunk = {
132
+ readonly kind: 'text';
133
+ readonly text: string;
134
+ } | {
135
+ readonly kind: 'json-delta';
136
+ readonly path: string;
137
+ readonly value: unknown;
138
+ } | {
139
+ readonly kind: 'image';
140
+ readonly data: Uint8Array;
141
+ readonly mediaType: string;
142
+ };
143
+ /**
144
+ * The successful outcome of a tool invocation, returned to the model.
145
+ *
146
+ * @stable
147
+ */
148
+ interface ToolResult<TOutput = unknown> {
149
+ readonly toolCallId: string;
150
+ readonly toolName: string;
151
+ readonly output: TOutput;
152
+ /**
153
+ * Optional content parts to append to the conversation (images, files,
154
+ * etc.). Tools that emit binary results use this field instead of trying
155
+ * to encode the binary into `output`.
156
+ */
157
+ readonly contentParts?: readonly MessageContent[];
158
+ readonly durationMs: number;
159
+ /**
160
+ * Set when the tool's output was large enough to be stored behind a
161
+ * handle (the `'spill-to-file'` truncation strategy, or — later — an MCP
162
+ * `resource_link`) instead of being inlined in full. The runtime inlines
163
+ * only the bounded {@link ResultHandle.preview} and lets the model fetch
164
+ * the rest on demand via the built-in `read_result` tool. Absent for
165
+ * results that were inlined directly.
166
+ */
167
+ readonly resultHandle?: ResultHandle;
168
+ }
169
+ /**
170
+ * An opaque, run-scoped reference to a large tool result that was stored
171
+ * out of the conversation buffer rather than inlined in full. The agent
172
+ * inlines {@link preview} (plus a retrieval hint) and registers the
173
+ * built-in `read_result` tool so the model can page through the full
174
+ * artifact behind {@link uri} on demand — keeping large results out of the
175
+ * context window (P1-4).
176
+ *
177
+ * @stable
178
+ */
179
+ interface ResultHandle {
180
+ /**
181
+ * Opaque, run-scoped URI — e.g. `graphorin-spill:<runId>/<toolCallId>.json`
182
+ * for a spill artifact. Never a raw filesystem path: the reader resolves
183
+ * it within the configured artifact root, so the model cannot use it to
184
+ * read arbitrary files.
185
+ */
186
+ readonly uri: string;
187
+ /** Backing store kind. `'spill-file'` today; `'resource-link'` is reserved for MCP (WI-13). */
188
+ readonly kind: 'spill-file' | 'resource-link';
189
+ /** A bounded preview of the full body (already inlined alongside the handle). */
190
+ readonly preview: string;
191
+ /** Total byte size of the full stored artifact, when known. */
192
+ readonly bytes?: number;
193
+ /** MIME type of the stored artifact, when known. */
194
+ readonly mediaType?: string;
195
+ /**
196
+ * Trust class of the tool that PRODUCED the stored body (TL-6).
197
+ * `read_result` re-applies inbound sanitization and dataflow
198
+ * provenance by this class, so an untrusted spill cannot launder to
199
+ * trusted through the built-in reader.
200
+ */
201
+ readonly producerTrustClass?: ToolTrustClass;
202
+ }
203
+ /**
204
+ * Discriminator used by `ToolError.kind`. The list is exhaustive: any new
205
+ * kind must extend the union here and every `assertNever` switch.
206
+ *
207
+ * @stable
208
+ */
209
+ type ToolErrorKind = 'approval_denied' | 'sandbox_violation' | 'timeout' | 'invalid_input' | 'invalid_output' | 'execution_failed' | 'unknown_tool' | 'aborted' | 'inbound_sanitization_blocked' | 'dataflow_policy_blocked' | 'rate_limited';
210
+ /**
211
+ * The unsuccessful outcome of a tool invocation. The model sees a textual
212
+ * representation of `message`; the runtime sees the typed shape.
213
+ *
214
+ * @stable
215
+ */
216
+ interface ToolError {
217
+ readonly toolCallId: string;
218
+ readonly toolName: string;
219
+ readonly kind: ToolErrorKind;
220
+ readonly message: string;
221
+ /** Optional underlying cause (chained errors). */
222
+ readonly cause?: unknown;
223
+ /** Optional remediation hint for human readers. */
224
+ readonly hint?: string;
225
+ }
226
+ /**
227
+ * Either a `ToolResult` or a `ToolError`. The runtime always returns one
228
+ * of the two — there is no implicit "tool fell through" outcome.
229
+ *
230
+ * @stable
231
+ */
232
+ type ToolOutcome<TOutput = unknown> = ToolResult<TOutput> | ToolError;
233
+ /**
234
+ * Pending approval bookkeeping: a tool that needed human confirmation
235
+ * before execution. Stored on `RunState.pendingApprovals` until the
236
+ * caller resumes the run with a granted/denied decision.
237
+ *
238
+ * @stable
239
+ */
240
+ interface ToolApproval {
241
+ readonly toolCallId: string;
242
+ readonly toolName: string;
243
+ readonly args: unknown;
244
+ readonly reason?: string;
245
+ readonly requestedAt: string;
246
+ }
247
+ /**
248
+ * A `ToolCall` paired with its outcome and execution metadata. Captured
249
+ * on `RunState.completedToolCalls` after a successful or failed run.
250
+ *
251
+ * @stable
252
+ */
253
+ interface CompletedToolCall<TOutput = unknown> {
254
+ readonly call: ToolCall;
255
+ readonly outcome: ToolOutcome<TOutput>;
256
+ readonly stepNumber: number;
257
+ }
258
+ //#endregion
259
+ export { CompletedToolCall, ContentChunk, InboundSanitizationPolicy, MemoryGuardTier, ResultHandle, SandboxPolicy, SideEffectClass, ToolApproval, ToolError, ToolErrorKind, ToolOutcome, ToolResult, ToolSource, ToolTrustClass, TruncationStrategy };
260
+ //# sourceMappingURL=tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool.d.ts","names":[],"sources":["../../src/types/tool.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAWA;AAsBA;AAyBA;AAmBA;AAuBA;AAUA;AAeY,KAlHA,aAAA,GAkHU,MAAA,GAAA,WAAA,GAAA,UAAA,GAAA,QAAA;AAmBtB;AAgBA;;;;;AAgCA;AA+BA;AAmBA;AAiBA;;;;;AASA;AAcA;;;;;KAzPY,eAAA;;;;;;;;;;;;;;;;;;;KAyBA,eAAA;;;;;;;;;;;;;;;;;;KAmBA,yBAAA;;;;;;;;;;;;;;;;;KAuBA,kBAAA;;;;;;;;;KAUA,cAAA;;;;;;;;KAeA,UAAA;;;;;;;;;;;;;;;;;;;;;;;;KAmBA,YAAA;;;;;;;;;iBAGiC;;;;;;;;UAa5B;;;mBAGE;;;;;;mCAAO,cAAA;;;;;;;;;;0BAgBA;;;;;;;;;;;;UAaT,YAAA;;;;;;;;;;;;;;;;;;;;;;gCAsBe;;;;;;;;KASpB,aAAA;;;;;;;UAmBK,SAAA;;;iBAGA;;;;;;;;;;;;;KAcL,iCAAiC,WAAW,WAAW;;;;;;;;UASlD,YAAA;;;;;;;;;;;;;UAcA;iBACA;oBACG,YAAY"}