@kindgi/agents 0.0.0-bootstrap.0 → 0.1.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 (240) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +131 -2
  3. package/dist/agent-turn-flow.d.ts +57 -0
  4. package/dist/agent-turn-flow.d.ts.map +1 -0
  5. package/dist/agent-turn-flow.js +172 -0
  6. package/dist/agent-turn-flow.js.map +1 -0
  7. package/dist/conversation-binding.d.ts +111 -0
  8. package/dist/conversation-binding.d.ts.map +1 -0
  9. package/dist/conversation-binding.js +4 -0
  10. package/dist/conversation-binding.js.map +1 -0
  11. package/dist/define.d.ts +180 -0
  12. package/dist/define.d.ts.map +1 -0
  13. package/dist/define.js +361 -0
  14. package/dist/define.js.map +1 -0
  15. package/dist/errors.d.ts +62 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +4 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/guardrails-gate.d.ts +169 -0
  20. package/dist/guardrails-gate.d.ts.map +1 -0
  21. package/dist/guardrails-gate.js +202 -0
  22. package/dist/guardrails-gate.js.map +1 -0
  23. package/dist/handlers/budget-check.d.ts +22 -0
  24. package/dist/handlers/budget-check.d.ts.map +1 -0
  25. package/dist/handlers/budget-check.js +109 -0
  26. package/dist/handlers/budget-check.js.map +1 -0
  27. package/dist/handlers/build-initial-messages.d.ts +17 -0
  28. package/dist/handlers/build-initial-messages.d.ts.map +1 -0
  29. package/dist/handlers/build-initial-messages.js +86 -0
  30. package/dist/handlers/build-initial-messages.js.map +1 -0
  31. package/dist/handlers/compose-result.d.ts +10 -0
  32. package/dist/handlers/compose-result.d.ts.map +1 -0
  33. package/dist/handlers/compose-result.js +79 -0
  34. package/dist/handlers/compose-result.js.map +1 -0
  35. package/dist/handlers/constants.d.ts +8 -0
  36. package/dist/handlers/constants.d.ts.map +1 -0
  37. package/dist/handlers/constants.js +10 -0
  38. package/dist/handlers/constants.js.map +1 -0
  39. package/dist/handlers/context.d.ts +210 -0
  40. package/dist/handlers/context.d.ts.map +1 -0
  41. package/dist/handlers/context.js +4 -0
  42. package/dist/handlers/context.js.map +1 -0
  43. package/dist/handlers/dispatch-tools.d.ts +15 -0
  44. package/dist/handlers/dispatch-tools.d.ts.map +1 -0
  45. package/dist/handlers/dispatch-tools.js +511 -0
  46. package/dist/handlers/dispatch-tools.js.map +1 -0
  47. package/dist/handlers/errors.d.ts +133 -0
  48. package/dist/handlers/errors.d.ts.map +1 -0
  49. package/dist/handlers/errors.js +134 -0
  50. package/dist/handlers/errors.js.map +1 -0
  51. package/dist/handlers/evaluate-guardrails.d.ts +14 -0
  52. package/dist/handlers/evaluate-guardrails.d.ts.map +1 -0
  53. package/dist/handlers/evaluate-guardrails.js +128 -0
  54. package/dist/handlers/evaluate-guardrails.js.map +1 -0
  55. package/dist/handlers/final-iteration.d.ts +7 -0
  56. package/dist/handlers/final-iteration.d.ts.map +1 -0
  57. package/dist/handlers/final-iteration.js +26 -0
  58. package/dist/handlers/final-iteration.js.map +1 -0
  59. package/dist/handlers/index.d.ts +5 -0
  60. package/dist/handlers/index.d.ts.map +1 -0
  61. package/dist/handlers/index.js +41 -0
  62. package/dist/handlers/index.js.map +1 -0
  63. package/dist/handlers/model-call.d.ts +13 -0
  64. package/dist/handlers/model-call.d.ts.map +1 -0
  65. package/dist/handlers/model-call.js +136 -0
  66. package/dist/handlers/model-call.js.map +1 -0
  67. package/dist/handlers/persist-final-message.d.ts +14 -0
  68. package/dist/handlers/persist-final-message.d.ts.map +1 -0
  69. package/dist/handlers/persist-final-message.js +54 -0
  70. package/dist/handlers/persist-final-message.js.map +1 -0
  71. package/dist/handlers/persist-provenance.d.ts +12 -0
  72. package/dist/handlers/persist-provenance.d.ts.map +1 -0
  73. package/dist/handlers/persist-provenance.js +34 -0
  74. package/dist/handlers/persist-provenance.js.map +1 -0
  75. package/dist/handlers/persist-user-message.d.ts +15 -0
  76. package/dist/handlers/persist-user-message.d.ts.map +1 -0
  77. package/dist/handlers/persist-user-message.js +59 -0
  78. package/dist/handlers/persist-user-message.js.map +1 -0
  79. package/dist/handlers/public-types.d.ts +201 -0
  80. package/dist/handlers/public-types.d.ts.map +1 -0
  81. package/dist/handlers/public-types.js +4 -0
  82. package/dist/handlers/public-types.js.map +1 -0
  83. package/dist/handlers/rehydrate.d.ts +8 -0
  84. package/dist/handlers/rehydrate.d.ts.map +1 -0
  85. package/dist/handlers/rehydrate.js +94 -0
  86. package/dist/handlers/rehydrate.js.map +1 -0
  87. package/dist/handlers/render-prompt.d.ts +12 -0
  88. package/dist/handlers/render-prompt.d.ts.map +1 -0
  89. package/dist/handlers/render-prompt.js +41 -0
  90. package/dist/handlers/render-prompt.js.map +1 -0
  91. package/dist/handlers/resolve-tools.d.ts +10 -0
  92. package/dist/handlers/resolve-tools.d.ts.map +1 -0
  93. package/dist/handlers/resolve-tools.js +55 -0
  94. package/dist/handlers/resolve-tools.js.map +1 -0
  95. package/dist/handlers/result-shape.d.ts +94 -0
  96. package/dist/handlers/result-shape.d.ts.map +1 -0
  97. package/dist/handlers/result-shape.js +19 -0
  98. package/dist/handlers/result-shape.js.map +1 -0
  99. package/dist/handlers/run-retrievals.d.ts +10 -0
  100. package/dist/handlers/run-retrievals.d.ts.map +1 -0
  101. package/dist/handlers/run-retrievals.js +64 -0
  102. package/dist/handlers/run-retrievals.js.map +1 -0
  103. package/dist/handlers/run-snapshot.d.ts +4 -0
  104. package/dist/handlers/run-snapshot.d.ts.map +1 -0
  105. package/dist/handlers/run-snapshot.js +26 -0
  106. package/dist/handlers/run-snapshot.js.map +1 -0
  107. package/dist/handlers/setup.d.ts +25 -0
  108. package/dist/handlers/setup.d.ts.map +1 -0
  109. package/dist/handlers/setup.js +231 -0
  110. package/dist/handlers/setup.js.map +1 -0
  111. package/dist/handlers/structured-output.d.ts +38 -0
  112. package/dist/handlers/structured-output.d.ts.map +1 -0
  113. package/dist/handlers/structured-output.js +89 -0
  114. package/dist/handlers/structured-output.js.map +1 -0
  115. package/dist/handlers/tool-errors.d.ts +56 -0
  116. package/dist/handlers/tool-errors.d.ts.map +1 -0
  117. package/dist/handlers/tool-errors.js +73 -0
  118. package/dist/handlers/tool-errors.js.map +1 -0
  119. package/dist/handlers/tool-hitl.d.ts +45 -0
  120. package/dist/handlers/tool-hitl.d.ts.map +1 -0
  121. package/dist/handlers/tool-hitl.js +81 -0
  122. package/dist/handlers/tool-hitl.js.map +1 -0
  123. package/dist/handlers/turn-environment.d.ts +26 -0
  124. package/dist/handlers/turn-environment.d.ts.map +1 -0
  125. package/dist/handlers/turn-environment.js +154 -0
  126. package/dist/handlers/turn-environment.js.map +1 -0
  127. package/dist/hitl-policy.d.ts +45 -0
  128. package/dist/hitl-policy.d.ts.map +1 -0
  129. package/dist/hitl-policy.js +74 -0
  130. package/dist/hitl-policy.js.map +1 -0
  131. package/dist/index.d.ts +31 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +19 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/invoke.d.ts +36 -0
  136. package/dist/invoke.d.ts.map +1 -0
  137. package/dist/invoke.js +228 -0
  138. package/dist/invoke.js.map +1 -0
  139. package/dist/migrations-dir.d.ts +11 -0
  140. package/dist/migrations-dir.d.ts.map +1 -0
  141. package/dist/migrations-dir.js +14 -0
  142. package/dist/migrations-dir.js.map +1 -0
  143. package/dist/project-run-result.d.ts +23 -0
  144. package/dist/project-run-result.d.ts.map +1 -0
  145. package/dist/project-run-result.js +116 -0
  146. package/dist/project-run-result.js.map +1 -0
  147. package/dist/prompt.d.ts +83 -0
  148. package/dist/prompt.d.ts.map +1 -0
  149. package/dist/prompt.js +119 -0
  150. package/dist/prompt.js.map +1 -0
  151. package/dist/provenance-emit.d.ts +44 -0
  152. package/dist/provenance-emit.d.ts.map +1 -0
  153. package/dist/provenance-emit.js +51 -0
  154. package/dist/provenance-emit.js.map +1 -0
  155. package/dist/registry.d.ts +38 -0
  156. package/dist/registry.d.ts.map +1 -0
  157. package/dist/registry.js +125 -0
  158. package/dist/registry.js.map +1 -0
  159. package/dist/retrieval.d.ts +47 -0
  160. package/dist/retrieval.d.ts.map +1 -0
  161. package/dist/retrieval.js +155 -0
  162. package/dist/retrieval.js.map +1 -0
  163. package/dist/run-snapshot-binding.d.ts +77 -0
  164. package/dist/run-snapshot-binding.d.ts.map +1 -0
  165. package/dist/run-snapshot-binding.js +4 -0
  166. package/dist/run-snapshot-binding.js.map +1 -0
  167. package/dist/schema.d.ts +497 -0
  168. package/dist/schema.d.ts.map +1 -0
  169. package/dist/schema.js +133 -0
  170. package/dist/schema.js.map +1 -0
  171. package/dist/streaming.d.ts +118 -0
  172. package/dist/streaming.d.ts.map +1 -0
  173. package/dist/streaming.js +17 -0
  174. package/dist/streaming.js.map +1 -0
  175. package/dist/tenant-policy.d.ts +16 -0
  176. package/dist/tenant-policy.d.ts.map +1 -0
  177. package/dist/tenant-policy.js +77 -0
  178. package/dist/tenant-policy.js.map +1 -0
  179. package/dist/types.d.ts +435 -0
  180. package/dist/types.d.ts.map +1 -0
  181. package/dist/types.js +4 -0
  182. package/dist/types.js.map +1 -0
  183. package/dist/versioning.d.ts +29 -0
  184. package/dist/versioning.d.ts.map +1 -0
  185. package/dist/versioning.js +58 -0
  186. package/dist/versioning.js.map +1 -0
  187. package/migrations/0000_sparkling_talkback.sql +18 -0
  188. package/migrations/0001_tired_warhawk.sql +16 -0
  189. package/migrations/0002_violet_ezekiel.sql +2 -0
  190. package/migrations/meta/0000_snapshot.json +172 -0
  191. package/migrations/meta/0001_snapshot.json +275 -0
  192. package/migrations/meta/0002_snapshot.json +287 -0
  193. package/migrations/meta/_journal.json +27 -0
  194. package/package.json +76 -4
  195. package/src/agent-turn-flow.ts +183 -0
  196. package/src/conversation-binding.ts +147 -0
  197. package/src/define.ts +572 -0
  198. package/src/errors.ts +80 -0
  199. package/src/guardrails-gate.ts +342 -0
  200. package/src/handlers/budget-check.ts +143 -0
  201. package/src/handlers/build-initial-messages.ts +103 -0
  202. package/src/handlers/compose-result.ts +90 -0
  203. package/src/handlers/constants.ts +10 -0
  204. package/src/handlers/context.ts +226 -0
  205. package/src/handlers/dispatch-tools.ts +633 -0
  206. package/src/handlers/errors.ts +282 -0
  207. package/src/handlers/evaluate-guardrails.ts +153 -0
  208. package/src/handlers/final-iteration.ts +30 -0
  209. package/src/handlers/index.ts +63 -0
  210. package/src/handlers/model-call.ts +151 -0
  211. package/src/handlers/persist-final-message.ts +67 -0
  212. package/src/handlers/persist-provenance.ts +39 -0
  213. package/src/handlers/persist-user-message.ts +70 -0
  214. package/src/handlers/public-types.ts +209 -0
  215. package/src/handlers/rehydrate.ts +161 -0
  216. package/src/handlers/render-prompt.ts +46 -0
  217. package/src/handlers/resolve-tools.ts +68 -0
  218. package/src/handlers/result-shape.ts +113 -0
  219. package/src/handlers/run-retrievals.ts +77 -0
  220. package/src/handlers/run-snapshot.ts +44 -0
  221. package/src/handlers/setup.ts +269 -0
  222. package/src/handlers/structured-output.ts +117 -0
  223. package/src/handlers/tool-errors.ts +122 -0
  224. package/src/handlers/tool-hitl.ts +126 -0
  225. package/src/handlers/turn-environment.ts +191 -0
  226. package/src/hitl-policy.ts +128 -0
  227. package/src/index.ts +154 -0
  228. package/src/invoke.ts +299 -0
  229. package/src/migrations-dir.ts +17 -0
  230. package/src/project-run-result.ts +131 -0
  231. package/src/prompt.ts +185 -0
  232. package/src/provenance-emit.ts +100 -0
  233. package/src/registry.ts +164 -0
  234. package/src/retrieval.ts +219 -0
  235. package/src/run-snapshot-binding.ts +87 -0
  236. package/src/schema.ts +154 -0
  237. package/src/streaming.ts +153 -0
  238. package/src/tenant-policy.ts +78 -0
  239. package/src/types.ts +453 -0
  240. package/src/versioning.ts +77 -0
@@ -0,0 +1,111 @@
1
+ import type { RunBinding } from '@kindgi/runtime';
2
+ import type { Result, Semver, TenantId } from '@kindgi/types';
3
+ import type { AgentError } from './errors.js';
4
+ import type { AgentId, Conversation, ConversationId, ConversationMessage, MessageRole } from './types.js';
5
+ export interface OpenConversationInput {
6
+ readonly tenantId: TenantId;
7
+ readonly agentId: AgentId;
8
+ readonly agentVersion: Semver;
9
+ readonly title: string;
10
+ readonly participantId?: string;
11
+ readonly scope: Readonly<Record<string, unknown>>;
12
+ readonly metadata?: Readonly<Record<string, unknown>>;
13
+ }
14
+ export interface ListConversationsInput {
15
+ readonly tenantId: TenantId;
16
+ readonly agentId?: AgentId;
17
+ readonly participantId?: string;
18
+ /** If true, only conversations without a `closedAt` are returned. Default false. */
19
+ readonly openOnly?: boolean;
20
+ readonly limit?: number;
21
+ }
22
+ export interface AppendMessageInput {
23
+ readonly tenantId: TenantId;
24
+ readonly conversationId: ConversationId;
25
+ readonly role: MessageRole;
26
+ readonly content: string | Readonly<Record<string, unknown>>;
27
+ readonly actor?: string;
28
+ readonly toolCall?: {
29
+ readonly toolId: string;
30
+ readonly invocationId: string;
31
+ };
32
+ /**
33
+ * When true, this message is a mid-turn assistant emission (e.g. the
34
+ * assistant message that contains tool calls before the final
35
+ * response). `turnCount` is NOT incremented for these — one turn is
36
+ * one user↔agent exchange, not one message. Default false; the final
37
+ * assistant response for a turn omits this flag (counts as a turn).
38
+ */
39
+ readonly isIntermediate?: boolean;
40
+ }
41
+ export interface ReadMessagesInput {
42
+ readonly tenantId: TenantId;
43
+ readonly conversationId: ConversationId;
44
+ readonly sinceSequence?: number;
45
+ readonly limit?: number;
46
+ }
47
+ /**
48
+ * Keyset marker used by `listConversationsPage`. When present, only
49
+ * rows strictly before this marker (by `openedAt` desc, then `id`
50
+ * desc) are returned. The api route encodes / decodes this to an
51
+ * opaque wire cursor.
52
+ */
53
+ export interface ConversationPageCursor {
54
+ /** ISO 8601 `openedAt` timestamp of the last row from the previous page. */
55
+ readonly openedAt: string;
56
+ readonly id: ConversationId;
57
+ }
58
+ export interface ListConversationsPageInput {
59
+ readonly tenantId: TenantId;
60
+ readonly agentId?: AgentId;
61
+ /** When set, filter to open (no closedAt) or closed (closedAt set) rows only. */
62
+ readonly status?: 'open' | 'closed';
63
+ /** Keyset for the next page — see `ConversationPageCursor`. */
64
+ readonly before?: ConversationPageCursor;
65
+ /**
66
+ * Row cap PER PAGE. Impls fetch `limit + 1` internally to compute
67
+ * `hasMore` without a second query.
68
+ */
69
+ readonly limit: number;
70
+ }
71
+ export interface ConversationPage {
72
+ readonly data: readonly Conversation[];
73
+ readonly hasMore: boolean;
74
+ }
75
+ /**
76
+ * `ConversationBinding` — the public seam between @kindgi/agents and
77
+ * whatever conversation-store implementation a deployment plugs in
78
+ * (the Kindgi runtime ships a Postgres-backed one; alternatives possible).
79
+ *
80
+ * Every method is tenant-scoped: RLS (or the moral equivalent for
81
+ * non-Postgres impls) is expected to be enforced inside the binding.
82
+ * Callers pass the tenant on every method — the binding does not
83
+ * carry request-scoped identity.
84
+ *
85
+ * `closeConversation` accepts an optional `RunBinding` so the impl can
86
+ * cascade-cancel pending waitpoints owned by runs in the closing
87
+ * conversation. Impls without access to the run lifecycle skip the
88
+ * cascade.
89
+ *
90
+ * `appendMessage` / `readMessages` route message content through the
91
+ * memory subsystem — impls capture a `MemoryQueryBinding` at
92
+ * construction and expose it here transparently.
93
+ */
94
+ export interface ConversationBinding {
95
+ openConversation(input: OpenConversationInput): Promise<Result<Conversation, AgentError>>;
96
+ getConversation(tenantId: TenantId, id: ConversationId): Promise<Result<Conversation, AgentError>>;
97
+ listConversations(input: ListConversationsInput): Promise<Result<readonly Conversation[], AgentError>>;
98
+ /**
99
+ * Cursor-paginated + keyset-ordered variant of `listConversations`
100
+ * for the HTTP surface. Sort: `openedAt DESC, id DESC` (chronological
101
+ * — most-recently-opened first, id disambiguating). Fills the
102
+ * `hasMore` marker inline. Filters: `agentId`, `status` (`open` /
103
+ * `closed`), `before` keyset.
104
+ */
105
+ listConversationsPage(input: ListConversationsPageInput): Promise<Result<ConversationPage, AgentError>>;
106
+ closeConversation(tenantId: TenantId, id: ConversationId, runBinding?: RunBinding): Promise<Result<Conversation, AgentError>>;
107
+ deleteConversation(tenantId: TenantId, id: ConversationId): Promise<Result<void, AgentError>>;
108
+ appendMessage(input: AppendMessageInput): Promise<Result<ConversationMessage, AgentError>>;
109
+ readMessages(input: ReadMessagesInput): Promise<Result<readonly ConversationMessage[], AgentError>>;
110
+ }
111
+ //# sourceMappingURL=conversation-binding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-binding.d.ts","sourceRoot":"","sources":["../src/conversation-binding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ export {};
4
+ //# sourceMappingURL=conversation-binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-binding.js","sourceRoot":"","sources":["../src/conversation-binding.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC"}
@@ -0,0 +1,180 @@
1
+ import { type ToolErrorsSpec } from '@kindgi/policy-contract';
2
+ import { type AnySchema } from '@kindgi/schema';
3
+ import type { Result } from '@kindgi/types';
4
+ import type { InvalidAgentError } from './errors.js';
5
+ import type { Agent, ConversationPolicy, PromptParameter, RetrievalIntent, ToolRef, TurnBudget } from './types.js';
6
+ /**
7
+ * Public API to construct an agent definition. Validates every field,
8
+ * brands ids, and returns a `Result` — no throws.
9
+ *
10
+ * ```ts
11
+ * const agent = defineAgent({
12
+ * id: 'acme.citation-verifier',
13
+ * version: '1.0.0',
14
+ * name: 'Citation Verifier',
15
+ * instructions: 'Verify every citation against the case-law index.',
16
+ * capabilities: [{ needs: [{ feature: 'structured-output' }] }],
17
+ * tools: [{ id: 'acme.verify-citation', version: '1.0.0' }],
18
+ * retrieval: [{ types: ['prior-verification'], scope: 'same-project' }],
19
+ * guardrails: ['no-hallucinated-citations'],
20
+ * });
21
+ * if (agent.kind === 'err') throw new Error(agent.error.message);
22
+ * registry.register(agent.value);
23
+ * ```
24
+ */
25
+ export declare function defineAgent(spec: DefineAgentSpec): Result<Agent, InvalidAgentError>;
26
+ /**
27
+ * Author-facing input shape for `defineAgent`. `id` and `version` are
28
+ * strings (they get branded inside `defineAgent`); array fields are
29
+ * `readonly` so callers can pass literal arrays.
30
+ *
31
+ * ## Field-by-field authoring guide
32
+ *
33
+ * The most common author mistake is treating `tools` as a list of
34
+ * tool ids (strings). It is NOT — it is a list of `{id, version}`
35
+ * refs where `version` is an npm-style semver RANGE (`'^1.0.0'`,
36
+ * `'~1.2.3'`, `'1.0.0'`, `'>=1.0.0 <2.0.0'`). Resolution happens at
37
+ * run start via `semver.maxSatisfying`.
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * const agent = defineAgent({
42
+ * id: 'my-pack.summarizer',
43
+ * version: '1.0.0',
44
+ * name: 'Summarizer',
45
+ * instructions: 'Summarize the user message in one sentence.',
46
+ * capabilities: [{ needs: [{ feature: 'tool-use' }] }],
47
+ * tools: [
48
+ * { id: 'my-pack.fetch-doc', version: '^0.1.0' },
49
+ * ],
50
+ * retrieval: [],
51
+ * guardrails: [],
52
+ * budget: { maxSteps: 6, maxCostUsd: 0.1, maxWallMs: 30_000 },
53
+ * });
54
+ * ```
55
+ */
56
+ export interface DefineAgentSpec {
57
+ /**
58
+ * Business identifier. Convention: `<pack-id>.<agent-name>` (e.g.
59
+ * `'acme.contract-reviewer'`). Non-empty. Gets branded as
60
+ * `AgentId` inside `defineAgent`.
61
+ */
62
+ readonly id: string;
63
+ /**
64
+ * Exact semver of THIS agent revision (e.g. `'1.0.0'`,
65
+ * `'0.2.1-alpha.3'`). Distinct from tool version RANGES on
66
+ * `tools[]`. Every publish under the same id must bump this.
67
+ */
68
+ readonly version: string;
69
+ /** Human-readable name for UI and logs. */
70
+ readonly name: string;
71
+ /** Optional longer description shown in catalogs / admin surfaces. */
72
+ readonly description?: string;
73
+ /**
74
+ * The system prompt. Sent to the model with every turn as the
75
+ * baseline instructions. Load-bearing — this is where you shape
76
+ * the agent's behavior (persona, output format, tool-use policy).
77
+ */
78
+ readonly instructions: string;
79
+ /**
80
+ * Required capabilities the agent needs from a `ModelProvider`.
81
+ * Typically one entry: `[{ needs: [{ feature: 'tool-use' }] }]`
82
+ * for a tool-calling agent, `[{ needs: [{ feature: 'structured-output' }] }]`
83
+ * for an agent that returns schema-constrained JSON. The router uses
84
+ * the first entry to pick a compatible provider from the tenant's
85
+ * `ProviderRegistry`.
86
+ */
87
+ readonly capabilities: Agent['capabilities'];
88
+ /**
89
+ * Tools the agent may call. **NOT** a list of tool ids —
90
+ * a list of `{id, version}` refs where `version` is an npm-style
91
+ * semver range. At run start, each ref resolves against the
92
+ * registered versions via `semver.maxSatisfying`; unresolvable
93
+ * refs fail the turn with `tool-version-unresolvable`.
94
+ *
95
+ * The model sees each tool's `id`, `description`, and input
96
+ * schema — write tool descriptions carefully (that's what the
97
+ * LLM reads to decide when to call).
98
+ */
99
+ readonly tools: readonly ToolRef[];
100
+ /**
101
+ * Retrieval intents the agent runs BEFORE calling the model.
102
+ * Each intent names fact types, a scope, and a retrieval mode; the
103
+ * results are injected into the model input as retrieved
104
+ * context. Empty array `[]` = no retrieval, model sees only the
105
+ * conversation history + user message.
106
+ */
107
+ readonly retrieval: readonly RetrievalIntent[];
108
+ /**
109
+ * Guardrail IDs that guard this agent's turns. Each id must
110
+ * resolve among the guardrails bound for the run, or the turn fails
111
+ * with `unresolved-guardrail`. Guardrails are evaluated once per
112
+ * turn, on the final response before it is stored — see
113
+ * `defineCheck` for the checker side.
114
+ *
115
+ * Empty array `[]` = no guarding.
116
+ */
117
+ readonly guardrails: readonly string[];
118
+ /**
119
+ * Optional named prompt parameters. Callers pass values for these
120
+ * in `invokeAgent({parameters: {...}})`; the framework substitutes
121
+ * them into `instructions`. Each parameter declares its type +
122
+ * default. Absent = agent takes no runtime parameters.
123
+ */
124
+ readonly parameters?: readonly PromptParameter[];
125
+ /**
126
+ * Preferred model provider by id. Soft hint — the router prefers
127
+ * this provider when it satisfies `capabilities.needs` + tenant
128
+ * policy, falling back to normal capability-based selection when
129
+ * the preferred provider is unregistered or filtered out. Enables
130
+ * A/B'ing agents across providers without churning registrations:
131
+ * register several, pin the agent to the one you want to test.
132
+ *
133
+ * The value is a `ProviderMetadata.id` string (e.g.
134
+ * `'anthropic-claude-sonnet-4-6'`). Unset = capability-match only.
135
+ */
136
+ readonly preferredProvider?: string;
137
+ /**
138
+ * Preferred model name within the selected provider. Soft hint — see
139
+ * `Agent.preferredModel`.
140
+ */
141
+ readonly preferredModel?: string;
142
+ /**
143
+ * A typed result: the final answer must be JSON matching `schema`
144
+ * (JSON Schema, or a Zod schema converted at definition time). An
145
+ * invalid answer is sent back to the model with the problems listed,
146
+ * up to `maxRepairs` times (default 1). See `AgentOutputSpec`.
147
+ */
148
+ readonly output?: {
149
+ readonly schema: AnySchema;
150
+ readonly name?: string;
151
+ readonly maxRepairs?: number;
152
+ };
153
+ /**
154
+ * What the turn does when a tool call fails: the failure goes back to
155
+ * the model as the call's result, so it can correct the call, up to
156
+ * `maxRetries` times per turn, for the kinds in `retryOn`. Default:
157
+ * one retry, for `invalid-arguments` and `unknown-tool` (nothing ran).
158
+ * A tenant's `tool-errors` policy can lower it. See `ToolErrorsSpec`.
159
+ */
160
+ readonly toolErrors?: ToolErrorsSpec;
161
+ /**
162
+ * Per-conversation behavior — how much history to load, when to
163
+ * gate on HITL, when to auto-close. Every field optional; defaults
164
+ * are "load the full history, no HITL, no auto-close". See
165
+ * `ConversationPolicy` for the full shape including tool-level
166
+ * HITL rules.
167
+ */
168
+ readonly conversationPolicy?: ConversationPolicy;
169
+ /**
170
+ * Turn budget caps. `maxSteps` limits model+tool call loop
171
+ * iterations per turn; `maxCostUsd` caps model spend per turn;
172
+ * `maxWallMs` bounds turn wall-clock time. Exceeding any cap
173
+ * ends the turn with a `budget-exceeded` failure. Sensible dev
174
+ * defaults: `{maxSteps: 6, maxCostUsd: 0.1, maxWallMs: 30_000}`.
175
+ */
176
+ readonly budget?: TurnBudget;
177
+ /** Free-form tags for catalog filtering. Not interpreted by the runtime. */
178
+ readonly tags?: readonly string[];
179
+ }
180
+ //# sourceMappingURL=define.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAA0B,MAAM,yBAAyB,CAAC;AACtF,OAAO,EACL,KAAK,SAAS,EAKf,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,EAAU,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EACV,KAAK,EAGL,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,OAAO,EACP,UAAU,EACX,MAAM,YAAY,CAAC;AAIpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAAC,KAAK,EAAE,iBAAiB,CAAC,CA6BnF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAC7C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;IACnC;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C;;;;;;;;OAQG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACjD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;IACF;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC;IACrC;;;;;;OAMG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACjD;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC"}
package/dist/define.js ADDED
@@ -0,0 +1,361 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ import { validateToolErrorsSpec } from '@kindgi/policy-contract';
4
+ import { compileInlineSchema, isZodSchema, loadZodConverterSync, toJSONSchemaSync, } from '@kindgi/schema';
5
+ /**
6
+ * Public API to construct an agent definition. Validates every field,
7
+ * brands ids, and returns a `Result` — no throws.
8
+ *
9
+ * ```ts
10
+ * const agent = defineAgent({
11
+ * id: 'acme.citation-verifier',
12
+ * version: '1.0.0',
13
+ * name: 'Citation Verifier',
14
+ * instructions: 'Verify every citation against the case-law index.',
15
+ * capabilities: [{ needs: [{ feature: 'structured-output' }] }],
16
+ * tools: [{ id: 'acme.verify-citation', version: '1.0.0' }],
17
+ * retrieval: [{ types: ['prior-verification'], scope: 'same-project' }],
18
+ * guardrails: ['no-hallucinated-citations'],
19
+ * });
20
+ * if (agent.kind === 'err') throw new Error(agent.error.message);
21
+ * registry.register(agent.value);
22
+ * ```
23
+ */
24
+ export function defineAgent(spec) {
25
+ const issues = [
26
+ ...validateIdentity(spec),
27
+ ...validateContent(spec),
28
+ ...validateArrays(spec),
29
+ ...validateRetrieval(spec),
30
+ ...validateParameters(spec.parameters),
31
+ ...validateBudget(spec.budget),
32
+ ...validateConversationPolicy(spec.conversationPolicy),
33
+ ...validateToolErrors(spec.toolErrors),
34
+ ];
35
+ const output = resolveOutput(spec.output);
36
+ if (output.kind === 'err')
37
+ issues.push(...output.issues);
38
+ if (issues.length > 0) {
39
+ return {
40
+ kind: 'err',
41
+ error: {
42
+ code: 'invalid-agent',
43
+ message: `Agent "${String(spec.id)}" is invalid (${issues.length} issue${issues.length === 1 ? '' : 's'})`,
44
+ issues,
45
+ },
46
+ };
47
+ }
48
+ return {
49
+ kind: 'ok',
50
+ value: buildAgent(spec, output.kind === 'ok' ? output.value : undefined),
51
+ };
52
+ }
53
+ const SEMVER_RE = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
54
+ function validateIdentity(spec) {
55
+ const out = [];
56
+ if (typeof spec.id !== 'string' || spec.id.trim().length === 0) {
57
+ out.push({ path: '/id', message: 'id must be a non-empty string' });
58
+ }
59
+ if (typeof spec.version !== 'string' || !SEMVER_RE.test(spec.version)) {
60
+ out.push({ path: '/version', message: 'version must be a valid semver string' });
61
+ }
62
+ if (typeof spec.name !== 'string' || spec.name.trim().length === 0) {
63
+ out.push({ path: '/name', message: 'name must be a non-empty string' });
64
+ }
65
+ return out;
66
+ }
67
+ function validateContent(spec) {
68
+ const out = [];
69
+ if (typeof spec.instructions !== 'string' || spec.instructions.trim().length === 0) {
70
+ out.push({ path: '/instructions', message: 'instructions must be a non-empty string' });
71
+ }
72
+ if (!Array.isArray(spec.capabilities) || spec.capabilities.length === 0) {
73
+ out.push({
74
+ path: '/capabilities',
75
+ message: 'capabilities must be a non-empty array of Capability declarations',
76
+ });
77
+ }
78
+ return out;
79
+ }
80
+ function validateArrays(spec) {
81
+ const out = [];
82
+ if (!Array.isArray(spec.tools)) {
83
+ out.push({
84
+ path: '/tools',
85
+ message: 'tools must be an array of { id: string, version: string } refs. No bare-string ids — every tool must carry a semver range.',
86
+ });
87
+ }
88
+ else {
89
+ spec.tools.forEach((ref, i) => out.push(...validateToolRef(ref, i)));
90
+ }
91
+ if (!Array.isArray(spec.guardrails)) {
92
+ out.push({ path: '/guardrails', message: 'guardrails must be an array of guardrail ids' });
93
+ }
94
+ return out;
95
+ }
96
+ function validateToolRef(ref, i) {
97
+ const out = [];
98
+ if (ref === null || typeof ref !== 'object') {
99
+ out.push({
100
+ path: `/tools/${i}`,
101
+ message: 'each tool must be a { id, version } object; bare-string ids are not allowed',
102
+ });
103
+ return out;
104
+ }
105
+ const obj = ref;
106
+ if (typeof obj.id !== 'string' || obj.id.trim().length === 0) {
107
+ out.push({ path: `/tools/${i}/id`, message: 'tool id must be a non-empty string' });
108
+ }
109
+ if (typeof obj.version !== 'string' || obj.version.trim().length === 0) {
110
+ out.push({
111
+ path: `/tools/${i}/version`,
112
+ message: 'tool version must be a non-empty semver range string (e.g., "1.2.3", "^1.2.3", "~1.2.3"). Deep grammar validation runs at dispatch time via the `semver` library.',
113
+ });
114
+ }
115
+ return out;
116
+ }
117
+ function validateRetrieval(spec) {
118
+ if (!Array.isArray(spec.retrieval)) {
119
+ return [{ path: '/retrieval', message: 'retrieval must be an array of RetrievalIntents' }];
120
+ }
121
+ const out = [];
122
+ spec.retrieval.forEach((intent, i) => out.push(...validateIntent(intent, i)));
123
+ return out;
124
+ }
125
+ function validateIntent(intent, i) {
126
+ const out = [];
127
+ if (!Array.isArray(intent.types) || intent.types.length === 0) {
128
+ out.push({
129
+ path: `/retrieval/${i}/types`,
130
+ message: 'each retrieval intent must declare at least one type',
131
+ });
132
+ }
133
+ if (intent.scope !== 'same-conversation' &&
134
+ intent.scope !== 'same-project' &&
135
+ intent.scope !== 'tenant') {
136
+ out.push({
137
+ path: `/retrieval/${i}/scope`,
138
+ message: 'scope must be same-conversation, same-project, or tenant',
139
+ });
140
+ }
141
+ if (intent.limit !== undefined && (!Number.isInteger(intent.limit) || intent.limit <= 0)) {
142
+ out.push({ path: `/retrieval/${i}/limit`, message: 'limit must be a positive integer' });
143
+ }
144
+ return out;
145
+ }
146
+ const VALID_PARAM_TYPES = new Set(['string', 'number', 'boolean', 'date']);
147
+ const AUTO_INJECTED_NAMES = new Set(['today', 'now', 'agent', 'conversation']);
148
+ function validateParameters(parameters) {
149
+ if (parameters === undefined)
150
+ return [];
151
+ const out = [];
152
+ const seen = new Set();
153
+ parameters.forEach((p, i) => {
154
+ if (typeof p.name !== 'string' || p.name.trim().length === 0) {
155
+ out.push({ path: `/parameters/${i}/name`, message: 'name must be a non-empty string' });
156
+ }
157
+ if (seen.has(p.name)) {
158
+ out.push({
159
+ path: `/parameters/${i}/name`,
160
+ message: `duplicate parameter name "${p.name}"`,
161
+ });
162
+ }
163
+ seen.add(p.name);
164
+ if (AUTO_INJECTED_NAMES.has(p.name)) {
165
+ out.push({
166
+ path: `/parameters/${i}/name`,
167
+ message: `"${p.name}" is a reserved auto-injected variable — do not declare it as a parameter`,
168
+ });
169
+ }
170
+ if (!VALID_PARAM_TYPES.has(p.type)) {
171
+ out.push({
172
+ path: `/parameters/${i}/type`,
173
+ message: 'type must be string, number, boolean, or date',
174
+ });
175
+ }
176
+ });
177
+ return out;
178
+ }
179
+ function validateBudget(budget) {
180
+ if (budget === undefined)
181
+ return [];
182
+ const out = [];
183
+ if (budget.maxSteps !== undefined &&
184
+ (!Number.isInteger(budget.maxSteps) || budget.maxSteps <= 0)) {
185
+ out.push({ path: '/budget/maxSteps', message: 'maxSteps must be a positive integer' });
186
+ }
187
+ if (budget.maxCostUsd !== undefined &&
188
+ (typeof budget.maxCostUsd !== 'number' || budget.maxCostUsd < 0)) {
189
+ out.push({
190
+ path: '/budget/maxCostUsd',
191
+ message: 'maxCostUsd must be a non-negative number',
192
+ });
193
+ }
194
+ if (budget.maxWallMs !== undefined &&
195
+ (!Number.isInteger(budget.maxWallMs) || budget.maxWallMs <= 0)) {
196
+ out.push({ path: '/budget/maxWallMs', message: 'maxWallMs must be a positive integer' });
197
+ }
198
+ return out;
199
+ }
200
+ function validateToolErrors(toolErrors) {
201
+ if (toolErrors === undefined)
202
+ return [];
203
+ const checked = validateToolErrorsSpec(toolErrors);
204
+ return checked.kind === 'ok'
205
+ ? []
206
+ : checked.issues.map((i) => ({ path: `/toolErrors${i.path}`, message: i.message }));
207
+ }
208
+ function validateConversationPolicy(policy) {
209
+ if (policy === undefined)
210
+ return [];
211
+ const out = [];
212
+ if (policy.historyLimit !== undefined &&
213
+ (!Number.isInteger(policy.historyLimit) || policy.historyLimit <= 0)) {
214
+ out.push({
215
+ path: '/conversationPolicy/historyLimit',
216
+ message: 'historyLimit must be a positive integer',
217
+ });
218
+ }
219
+ if (policy.autoCloseAfterInactiveSeconds !== undefined &&
220
+ (!Number.isInteger(policy.autoCloseAfterInactiveSeconds) ||
221
+ policy.autoCloseAfterInactiveSeconds <= 0)) {
222
+ out.push({
223
+ path: '/conversationPolicy/autoCloseAfterInactiveSeconds',
224
+ message: 'autoCloseAfterInactiveSeconds must be a positive integer',
225
+ });
226
+ }
227
+ if (policy.hitlAfterTurns !== undefined &&
228
+ (!Number.isInteger(policy.hitlAfterTurns) || policy.hitlAfterTurns <= 0)) {
229
+ out.push({
230
+ path: '/conversationPolicy/hitlAfterTurns',
231
+ message: 'hitlAfterTurns must be a positive integer',
232
+ });
233
+ }
234
+ // Nested hitl policy.
235
+ if (policy.hitl !== undefined) {
236
+ const h = policy.hitl;
237
+ if (h.afterTurns !== undefined && (!Number.isInteger(h.afterTurns) || h.afterTurns <= 0)) {
238
+ out.push({
239
+ path: '/conversationPolicy/hitl/afterTurns',
240
+ message: 'hitl.afterTurns must be a positive integer',
241
+ });
242
+ }
243
+ if (h.timeoutMs !== undefined && (!Number.isInteger(h.timeoutMs) || h.timeoutMs <= 0)) {
244
+ out.push({
245
+ path: '/conversationPolicy/hitl/timeoutMs',
246
+ message: 'hitl.timeoutMs must be a positive integer (ms)',
247
+ });
248
+ }
249
+ const ROLES = new Set(['standard', 'senior', 'admin']);
250
+ if (h.defaultReviewerRole !== undefined &&
251
+ !ROLES.has(h.defaultReviewerRole)) {
252
+ out.push({
253
+ path: '/conversationPolicy/hitl/defaultReviewerRole',
254
+ message: 'hitl.defaultReviewerRole must be one of: standard, senior, admin',
255
+ });
256
+ }
257
+ const MODES = new Set(['never_ask', 'ask_on_first_use', 'always_ask']);
258
+ if (h.tools?.default !== undefined && !MODES.has(h.tools.default)) {
259
+ out.push({
260
+ path: '/conversationPolicy/hitl/tools/default',
261
+ message: 'hitl.tools.default must be one of: never_ask, ask_on_first_use, always_ask',
262
+ });
263
+ }
264
+ if (h.tools?.overrides !== undefined) {
265
+ for (const [toolId, rule] of Object.entries(h.tools.overrides)) {
266
+ const mode = typeof rule === 'string' ? rule : rule.mode;
267
+ if (!MODES.has(mode)) {
268
+ out.push({
269
+ path: `/conversationPolicy/hitl/tools/overrides/${toolId}`,
270
+ message: 'override mode must be one of: never_ask, ask_on_first_use, always_ask',
271
+ });
272
+ }
273
+ if (typeof rule === 'object' &&
274
+ rule.requiredRole !== undefined &&
275
+ !ROLES.has(rule.requiredRole)) {
276
+ out.push({
277
+ path: `/conversationPolicy/hitl/tools/overrides/${toolId}/requiredRole`,
278
+ message: 'override requiredRole must be one of: standard, senior, admin',
279
+ });
280
+ }
281
+ }
282
+ }
283
+ }
284
+ return out;
285
+ }
286
+ /** The output spec in its wire form: JSON Schema that compiles, and a valid repair count. */
287
+ function resolveOutput(output) {
288
+ if (output === undefined)
289
+ return { kind: 'none' };
290
+ const issues = [];
291
+ if (output.maxRepairs !== undefined &&
292
+ (!Number.isInteger(output.maxRepairs) || output.maxRepairs < 0)) {
293
+ issues.push({
294
+ path: '/output/maxRepairs',
295
+ message: 'maxRepairs must be a non-negative integer',
296
+ });
297
+ }
298
+ if (output.name !== undefined && (typeof output.name !== 'string' || output.name.length === 0)) {
299
+ issues.push({ path: '/output/name', message: 'name must be a non-empty string' });
300
+ }
301
+ let schema;
302
+ if (isZodSchema(output.schema)) {
303
+ // The output side: downstream steps read every field, defaulted ones included.
304
+ const converted = toJSONSchemaSync(output.schema, loadZodConverterSync(), 'output');
305
+ if (converted.kind === 'err') {
306
+ return {
307
+ kind: 'err',
308
+ issues: [...issues, { path: '/output/schema', message: converted.error.message }],
309
+ };
310
+ }
311
+ schema = converted.value;
312
+ }
313
+ else {
314
+ schema = output.schema;
315
+ }
316
+ const compiled = compileInlineSchema(schema);
317
+ if (compiled.kind === 'err') {
318
+ issues.push({ path: '/output/schema', message: compiled.error.message });
319
+ }
320
+ if (issues.length > 0)
321
+ return { kind: 'err', issues };
322
+ return {
323
+ kind: 'ok',
324
+ value: {
325
+ schema,
326
+ ...(output.name !== undefined && { name: output.name }),
327
+ ...(output.maxRepairs !== undefined && { maxRepairs: output.maxRepairs }),
328
+ },
329
+ };
330
+ }
331
+ function buildAgent(spec, output) {
332
+ return {
333
+ id: spec.id,
334
+ version: spec.version,
335
+ name: spec.name,
336
+ ...(spec.description !== undefined && { description: spec.description }),
337
+ instructions: spec.instructions,
338
+ capabilities: spec.capabilities.map((c) => ({ ...c })),
339
+ tools: [...spec.tools],
340
+ retrieval: spec.retrieval.map((r) => ({ ...r })),
341
+ guardrails: [...spec.guardrails],
342
+ ...(spec.parameters !== undefined && {
343
+ parameters: spec.parameters.map((p) => ({ ...p })),
344
+ }),
345
+ ...(spec.preferredProvider !== undefined && { preferredProvider: spec.preferredProvider }),
346
+ ...(spec.preferredModel !== undefined && { preferredModel: spec.preferredModel }),
347
+ ...(spec.conversationPolicy !== undefined && {
348
+ conversationPolicy: { ...spec.conversationPolicy },
349
+ }),
350
+ ...(spec.budget !== undefined && { budget: { ...spec.budget } }),
351
+ ...(spec.tags !== undefined && { tags: [...spec.tags] }),
352
+ ...(output !== undefined && { output }),
353
+ ...(spec.toolErrors !== undefined && {
354
+ toolErrors: {
355
+ ...spec.toolErrors,
356
+ ...(spec.toolErrors.retryOn !== undefined && { retryOn: [...spec.toolErrors.retryOn] }),
357
+ },
358
+ }),
359
+ };
360
+ }
361
+ //# sourceMappingURL=define.js.map