@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,89 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ import { compileInlineSchema } from '@kindgi/schema';
4
+ /** Default number of repair attempts. */
5
+ export const DEFAULT_MAX_REPAIRS = 1;
6
+ /** Marks the messages this module adds, so they can be counted. */
7
+ const REPAIR_MARKER = '[kindgi:output-repair]';
8
+ /**
9
+ * The answer's text as JSON. Accepts a bare JSON value or one fenced
10
+ * as ```json … ``` (models often fence it).
11
+ */
12
+ export function parseJsonAnswer(content) {
13
+ if (typeof content !== 'string') {
14
+ return { kind: 'invalid', errors: ['the answer is not text'] };
15
+ }
16
+ const text = unfence(content.trim());
17
+ if (text.length === 0)
18
+ return { kind: 'invalid', errors: ['the answer is empty'] };
19
+ try {
20
+ return { kind: 'ok', value: JSON.parse(text) };
21
+ }
22
+ catch (cause) {
23
+ return {
24
+ kind: 'invalid',
25
+ errors: [
26
+ `the answer is not valid JSON (${cause instanceof Error ? cause.message : String(cause)})`,
27
+ ],
28
+ };
29
+ }
30
+ }
31
+ function unfence(text) {
32
+ const fenced = /^```(?:json)?\s*\n([\s\S]*?)\n?```$/i.exec(text);
33
+ return fenced?.[1]?.trim() ?? text;
34
+ }
35
+ export function outputChecker(spec) {
36
+ const compiled = compileInlineSchema(spec.schema);
37
+ if (compiled.kind === 'err') {
38
+ // `defineAgent` compiles the schema, so this is an agent built by hand.
39
+ const reason = compiled.error.message;
40
+ return {
41
+ check: () => ({ kind: 'invalid', errors: [`the output schema is invalid: ${reason}`] }),
42
+ };
43
+ }
44
+ const validator = compiled.value;
45
+ return {
46
+ check(content) {
47
+ const parsed = parseJsonAnswer(content);
48
+ if (parsed.kind === 'invalid')
49
+ return parsed;
50
+ const validated = validator.validate(parsed.value);
51
+ if (validated.kind === 'ok')
52
+ return parsed;
53
+ return { kind: 'invalid', errors: describeErrors(validated.error.errors) };
54
+ },
55
+ };
56
+ }
57
+ /** Ajv errors as `path message` lines the model can act on. */
58
+ function describeErrors(errors) {
59
+ const list = errors.map((raw) => {
60
+ const e = raw;
61
+ const where = e.instancePath === undefined || e.instancePath === '' ? '(root)' : e.instancePath;
62
+ return `${where} ${e.message ?? 'is invalid'}`;
63
+ });
64
+ return list.length > 0 ? list : ['the answer does not match the schema'];
65
+ }
66
+ /** Whether a message is one of this module's repair requests. */
67
+ export function isRepairMessage(m) {
68
+ return m.role === 'user' && typeof m.content === 'string' && m.content.startsWith(REPAIR_MARKER);
69
+ }
70
+ /** How many repairs this turn has asked for so far. */
71
+ export function repairsSoFar(messages) {
72
+ return messages.filter(isRepairMessage).length;
73
+ }
74
+ /** The message asking the model to fix its answer. */
75
+ export function repairMessage(spec, errors) {
76
+ const name = spec.name ?? 'output';
77
+ return {
78
+ role: 'user',
79
+ content: [
80
+ REPAIR_MARKER,
81
+ `Your answer must be the ${name} as JSON matching this JSON Schema, and nothing else:`,
82
+ JSON.stringify(spec.schema),
83
+ 'It did not fit:',
84
+ ...errors.map((e) => `- ${e}`),
85
+ `Reply again with only the corrected ${name} JSON.`,
86
+ ].join('\n'),
87
+ };
88
+ }
89
+ //# sourceMappingURL=structured-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-output.js","sourceRoot":"","sources":["../../src/handlers/structured-output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Retrying failed tool calls. A failure the turn's policy retries goes
3
+ * back to the model as the call's result — what failed and why — and
4
+ * the turn continues; the model can correct the call. Each retry costs a
5
+ * step, so `budget.maxSteps` still bounds the turn. A failure the policy
6
+ * doesn't retry, or one past `maxRetries`, fails the turn as before.
7
+ *
8
+ * Retries are counted from the turn's messages (the results this module
9
+ * writes carry a marker), so a replayed turn counts the same.
10
+ */
11
+ import type { ModelMessage } from '@kindgi/capabilities';
12
+ import { type ToolErrorKind, type ToolErrorsSpec } from '@kindgi/policy-contract';
13
+ /** Without an agent setting: one retry, for failures where nothing ran. */
14
+ export declare const DEFAULT_TOOL_ERRORS: Required<ToolErrorsSpec>;
15
+ /** The policy a turn applies. */
16
+ export interface ToolErrorPolicy {
17
+ readonly maxRetries: number;
18
+ readonly retryOn: ReadonlySet<ToolErrorKind>;
19
+ }
20
+ /**
21
+ * The agent's setting (or the default), capped by the tenant's
22
+ * `tool-errors` policy: the fewer retries, and only the kinds both
23
+ * allow — like every tenant policy, it can only make the turn stricter.
24
+ */
25
+ export declare function effectiveToolErrorPolicy(agent: ToolErrorsSpec | undefined, tenantCap: ToolErrorsSpec | undefined): ToolErrorPolicy;
26
+ /**
27
+ * Which kind of failure a tool call's error is: arguments that failed
28
+ * the input schema, a tool the agent doesn't have, or a tool that ran
29
+ * and failed.
30
+ */
31
+ export declare function toolErrorKindOf(error: {
32
+ readonly code: string;
33
+ readonly cause?: unknown;
34
+ }): ToolErrorKind;
35
+ /** Marks the results this module writes, so they can be counted. */
36
+ declare const RETRY_MARKER = "tool-error-retry";
37
+ /** What the model sees for a failed call it may retry. */
38
+ export interface ToolErrorResult {
39
+ readonly kindgi: typeof RETRY_MARKER;
40
+ readonly status: 'failed';
41
+ readonly error: {
42
+ readonly kind: ToolErrorKind;
43
+ readonly message: string;
44
+ readonly issues?: readonly unknown[];
45
+ };
46
+ readonly instruction: string;
47
+ }
48
+ export declare function toolErrorResult(kind: ToolErrorKind, message: string, issues: readonly unknown[] | undefined): ToolErrorResult;
49
+ /**
50
+ * Retries this turn has taken: the marked tool results after the turn's
51
+ * user message. Earlier turns' results come back as history; they don't
52
+ * count.
53
+ */
54
+ export declare function toolRetriesSoFar(messages: readonly ModelMessage[]): number;
55
+ export {};
56
+ //# sourceMappingURL=tool-errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-errors.d.ts","sourceRoot":"","sources":["../../src/handlers/tool-errors.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAoB,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAIpG,2EAA2E;AAC3E,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,cAAc,CAGxD,CAAC;AAEF,iCAAiC;AACjC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,cAAc,GAAG,SAAS,EACjC,SAAS,EAAE,cAAc,GAAG,SAAS,GACpC,eAAe,CAQjB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,aAAa,CAIhB;AAED,oEAAoE;AACpE,QAAA,MAAM,YAAY,qBAAqB,CAAC;AAExC,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,YAAY,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;QAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;KACtC,CAAC;IACF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAQD,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,GACrC,eAAe,CAOjB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAU1E"}
@@ -0,0 +1,73 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ import { TOOL_ERROR_KINDS } from '@kindgi/policy-contract';
4
+ import { isRepairMessage } from './structured-output.js';
5
+ /** Without an agent setting: one retry, for failures where nothing ran. */
6
+ export const DEFAULT_TOOL_ERRORS = {
7
+ maxRetries: 1,
8
+ retryOn: ['invalid-arguments', 'unknown-tool'],
9
+ };
10
+ /**
11
+ * The agent's setting (or the default), capped by the tenant's
12
+ * `tool-errors` policy: the fewer retries, and only the kinds both
13
+ * allow — like every tenant policy, it can only make the turn stricter.
14
+ */
15
+ export function effectiveToolErrorPolicy(agent, tenantCap) {
16
+ const maxRetries = Math.min(agent?.maxRetries ?? DEFAULT_TOOL_ERRORS.maxRetries, tenantCap?.maxRetries ?? Number.POSITIVE_INFINITY);
17
+ const allowed = new Set(tenantCap?.retryOn ?? TOOL_ERROR_KINDS);
18
+ const retryOn = (agent?.retryOn ?? DEFAULT_TOOL_ERRORS.retryOn).filter((k) => allowed.has(k));
19
+ return { maxRetries, retryOn: new Set(retryOn) };
20
+ }
21
+ /**
22
+ * Which kind of failure a tool call's error is: arguments that failed
23
+ * the input schema, a tool the agent doesn't have, or a tool that ran
24
+ * and failed.
25
+ */
26
+ export function toolErrorKindOf(error) {
27
+ if (error.code === 'unresolved-tool')
28
+ return 'unknown-tool';
29
+ const inner = error.cause?.code;
30
+ return inner === 'input-validation-failed' ? 'invalid-arguments' : 'tool-error';
31
+ }
32
+ /** Marks the results this module writes, so they can be counted. */
33
+ const RETRY_MARKER = 'tool-error-retry';
34
+ const INSTRUCTIONS = {
35
+ 'invalid-arguments': "Fix the arguments to match the tool's input schema and call it again.",
36
+ 'unknown-tool': 'Call one of the tools you were given instead.',
37
+ 'tool-error': 'The tool failed. Call it again if a retry makes sense, or answer without it.',
38
+ };
39
+ export function toolErrorResult(kind, message, issues) {
40
+ return {
41
+ kindgi: RETRY_MARKER,
42
+ status: 'failed',
43
+ error: { kind, message, ...(issues !== undefined && { issues }) },
44
+ instruction: INSTRUCTIONS[kind],
45
+ };
46
+ }
47
+ /**
48
+ * Retries this turn has taken: the marked tool results after the turn's
49
+ * user message. Earlier turns' results come back as history; they don't
50
+ * count.
51
+ */
52
+ export function toolRetriesSoFar(messages) {
53
+ let start = 0;
54
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
55
+ const m = messages[i];
56
+ if (m !== undefined && m.role === 'user' && !isRepairMessage(m)) {
57
+ start = i + 1;
58
+ break;
59
+ }
60
+ }
61
+ return messages.slice(start).filter(isRetryResult).length;
62
+ }
63
+ function isRetryResult(m) {
64
+ if (m.role !== 'tool')
65
+ return false;
66
+ try {
67
+ return JSON.parse(m.content).kindgi === RETRY_MARKER;
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ }
73
+ //# sourceMappingURL=tool-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-errors.js","sourceRoot":"","sources":["../../src/handlers/tool-errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { Tool } from '@kindgi/tools';
2
+ import type { Agent, ToolHitlMode } from '../types.js';
3
+ export interface ResolvedToolHitl {
4
+ readonly mode: ToolHitlMode;
5
+ readonly requiredRole: 'standard' | 'senior' | 'admin';
6
+ }
7
+ export declare function resolveToolHitl(agent: Agent, tool: Tool): ResolvedToolHitl;
8
+ /**
9
+ * Deterministic hash of tool arguments — used as the cache key for
10
+ * `ask_on_first_use`. Sorted-key JSON so reordered args don't produce
11
+ * a different hash.
12
+ */
13
+ export declare function hashToolArgs(args: unknown): string;
14
+ /**
15
+ * Deterministic waitpoint token for a tool-call gate. Includes both
16
+ * the model-generated call id (unique per iteration) AND the args hash
17
+ * so kernel flow replay lands on the same token, and a re-issued
18
+ * tool-call in a later iteration gets its own gate.
19
+ */
20
+ export declare function computeToolCallWaitToken(input: {
21
+ readonly runId: string;
22
+ readonly callId: string;
23
+ readonly argsHash: string;
24
+ }): string;
25
+ /**
26
+ * Shape the tool-level waitpoint resolves to when the reviewer decides.
27
+ * Same shape as session-gate decisions — the approvals-complete route
28
+ * materializes it identically.
29
+ */
30
+ export interface ToolHitlDecision {
31
+ readonly decided: 'approve' | 'reject';
32
+ readonly rationale?: string;
33
+ }
34
+ /**
35
+ * In-conversation cache of decisions for `ask_on_first_use`. Persisted
36
+ * on `agent_conversations.metadata.hitlToolDecisions` — a flat map of
37
+ * `${toolId}:${argsHash}` → decision. Read/write goes through the
38
+ * conversation row's metadata via the standard update path.
39
+ */
40
+ export interface ToolDecisionCacheKey {
41
+ readonly toolId: string;
42
+ readonly argsHash: string;
43
+ }
44
+ export declare function cacheKeyFor(key: ToolDecisionCacheKey): string;
45
+ //# sourceMappingURL=tool-hitl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-hitl.d.ts","sourceRoot":"","sources":["../../src/handlers/tool-hitl.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAgB,MAAM,aAAa,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;CACxD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,GAAG,gBAAgB,CAkC1E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAElD;AAWD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,GAAG,MAAM,CAKT;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,QAAQ,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,oBAAoB,GAAG,MAAM,CAE7D"}
@@ -0,0 +1,81 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ //
4
+ // Tool-level HITL — resolves the effective `ToolHitlMode` for a given
5
+ // (agent, tool) pair. Consumed by `dispatch-tools.ts` to
6
+ // decide whether a tool call parks the run on a kernel waitpoint before
7
+ // dispatch.
8
+ //
9
+ // Resolution order (narrower wins, framework default is fail-open):
10
+ // 1. `agent.conversationPolicy.hitl.tools.overrides[toolId]` — exact match
11
+ // 2. `agent.conversationPolicy.hitl.tools.default` — agent-wide default
12
+ // 3. per-tool default from `Tool.mutating` — safe fallback
13
+ // - `mutating: false` → `never_ask`
14
+ // - `mutating: true` or absent → `ask_on_first_use` (defaults safer)
15
+ //
16
+ // The effective-policy resolver (`hitl-policy.ts`) layers the tenant
17
+ // cap on top.
18
+ //
19
+ import { createHash } from 'node:crypto';
20
+ export function resolveToolHitl(agent, tool) {
21
+ const hitl = agent.conversationPolicy?.hitl;
22
+ const toolsPolicy = hitl?.tools;
23
+ const defaultRole = hitl?.defaultReviewerRole ?? 'standard';
24
+ // Opt-in: agents that don't declare `hitl.tools` get no tool-level
25
+ // gates. Matches the design's "fail-open" default — HITL is opt-in
26
+ // at the agent level, not implicit.
27
+ if (toolsPolicy === undefined) {
28
+ return { mode: 'never_ask', requiredRole: defaultRole };
29
+ }
30
+ // 1. Explicit override for this toolId.
31
+ const rawOverride = toolsPolicy.overrides?.[tool.id];
32
+ if (rawOverride !== undefined) {
33
+ const rule = typeof rawOverride === 'string' ? { mode: rawOverride } : rawOverride;
34
+ return {
35
+ mode: rule.mode,
36
+ requiredRole: rule.requiredRole ?? defaultRole,
37
+ };
38
+ }
39
+ // 2. Agent-wide default.
40
+ if (toolsPolicy.default !== undefined) {
41
+ return { mode: toolsPolicy.default, requiredRole: defaultRole };
42
+ }
43
+ // 3. Per-tool default from Tool.mutating — only reached when
44
+ // `hitl.tools` is present (opt-in) but neither an override nor a
45
+ // default matches. Read-only tools skip the gate; mutating tools
46
+ // ask on first use.
47
+ const mode = tool.mutating === false ? 'never_ask' : 'ask_on_first_use';
48
+ return { mode, requiredRole: defaultRole };
49
+ }
50
+ /**
51
+ * Deterministic hash of tool arguments — used as the cache key for
52
+ * `ask_on_first_use`. Sorted-key JSON so reordered args don't produce
53
+ * a different hash.
54
+ */
55
+ export function hashToolArgs(args) {
56
+ return createHash('sha256').update(canonicalStringify(args)).digest('hex').slice(0, 40);
57
+ }
58
+ function canonicalStringify(value) {
59
+ if (value === null || typeof value !== 'object')
60
+ return JSON.stringify(value);
61
+ if (Array.isArray(value))
62
+ return `[${value.map(canonicalStringify).join(',')}]`;
63
+ const entries = Object.entries(value).sort(([a], [b]) => a.localeCompare(b));
64
+ return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalStringify(v)}`).join(',')}}`;
65
+ }
66
+ /**
67
+ * Deterministic waitpoint token for a tool-call gate. Includes both
68
+ * the model-generated call id (unique per iteration) AND the args hash
69
+ * so kernel flow replay lands on the same token, and a re-issued
70
+ * tool-call in a later iteration gets its own gate.
71
+ */
72
+ export function computeToolCallWaitToken(input) {
73
+ return createHash('sha256')
74
+ .update(`tool-call:${input.runId}:${input.callId}:${input.argsHash}`)
75
+ .digest('hex')
76
+ .slice(0, 40);
77
+ }
78
+ export function cacheKeyFor(key) {
79
+ return `${key.toolId}:${key.argsHash}`;
80
+ }
81
+ //# sourceMappingURL=tool-hitl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-hitl.js","sourceRoot":"","sources":["../../src/handlers/tool-hitl.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type EffectiveHitlPolicy } from '../hitl-policy.js';
2
+ import type { Conversation } from '../types.js';
3
+ import type { TurnContext } from './context.js';
4
+ /** The conversation the turn runs in: open, and opened with this agent version. */
5
+ export declare function loadTurnConversation(ctx: TurnContext): Promise<Conversation>;
6
+ /** The model a turn was routed to, as `setup` journals it. */
7
+ export interface PinnedRoute {
8
+ readonly providerId: string;
9
+ readonly model: string;
10
+ }
11
+ /**
12
+ * Resolve the turn's guardrails, tools, tenant policy, tool-error policy
13
+ * and model onto `ctx`. With `pinned`, the route is that provider and
14
+ * model, still under the tenant's current policy; one no longer
15
+ * registered or allowed fails the turn.
16
+ */
17
+ export declare function resolveTurnEnvironment(ctx: TurnContext, pinned?: PinnedRoute): Promise<PinnedRoute & {
18
+ readonly toolCount: number;
19
+ }>;
20
+ /**
21
+ * The turn's approval rules: the agent's, held to the tenant's `hitl`
22
+ * policy. A policy that can't be evaluated fails the turn — running
23
+ * without it would skip the tenant's approvals.
24
+ */
25
+ export declare function resolveTurnHitlPolicy(ctx: TurnContext): Promise<EffectiveHitlPolicy>;
26
+ //# sourceMappingURL=turn-environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-environment.d.ts","sourceRoot":"","sources":["../../src/handlers/turn-environment.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,KAAK,mBAAmB,EAA8B,MAAM,mBAAmB,CAAC;AAEzF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD,mFAAmF;AACnF,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CA4BlF;AAED,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,WAAW,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,WAAW,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAkFvD;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiB1F"}
@@ -0,0 +1,154 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+ /**
4
+ * What a turn runs against: its conversation, and the guardrails, tools,
5
+ * policies and model it resolves at the start. `setup` resolves them
6
+ * once per turn; a resumed turn resolves them again (see
7
+ * `rehydrateTurnContext`), pinned to the model `setup` routed to, since
8
+ * the kernel doesn't re-run a step that already completed and these live
9
+ * on the in-memory `TurnContext`.
10
+ */
11
+ import { route } from '@kindgi/capabilities';
12
+ import { resolveGuardrails } from '../guardrails-gate.js';
13
+ import { resolveEffectiveHitlPolicy } from '../hitl-policy.js';
14
+ import { mergeTenantPolicies } from '../tenant-policy.js';
15
+ import { throwAgentTurnFailure } from './errors.js';
16
+ import { resolveTurnTools } from './resolve-tools.js';
17
+ import { effectiveToolErrorPolicy } from './tool-errors.js';
18
+ /** The conversation the turn runs in: open, and opened with this agent version. */
19
+ export async function loadTurnConversation(ctx) {
20
+ const conv = await ctx.bindings.conversationBinding.getConversation(ctx.input.tenantId, ctx.input.conversationId);
21
+ if (conv.kind === 'err')
22
+ throwAgentTurnFailure(conv.error);
23
+ if (conv.value.closedAt !== undefined) {
24
+ const err = {
25
+ code: 'conversation-closed',
26
+ message: `Conversation "${ctx.input.conversationId}" is closed`,
27
+ conversationId: ctx.input.conversationId,
28
+ };
29
+ throwAgentTurnFailure(err);
30
+ }
31
+ if (conv.value.agentId !== ctx.input.agent.id ||
32
+ conv.value.agentVersion !== ctx.input.agent.version) {
33
+ throwAgentTurnFailure({
34
+ code: 'agent-version-mismatch',
35
+ message: `Conversation opened with ${conv.value.agentId}@${conv.value.agentVersion}; invoked with ${ctx.input.agent.id}@${ctx.input.agent.version}`,
36
+ conversationId: ctx.input.conversationId,
37
+ expectedVersion: conv.value.agentVersion,
38
+ actualVersion: ctx.input.agent.version,
39
+ });
40
+ }
41
+ ctx.conversation = conv.value;
42
+ return conv.value;
43
+ }
44
+ /**
45
+ * Resolve the turn's guardrails, tools, tenant policy, tool-error policy
46
+ * and model onto `ctx`. With `pinned`, the route is that provider and
47
+ * model, still under the tenant's current policy; one no longer
48
+ * registered or allowed fails the turn.
49
+ */
50
+ export async function resolveTurnEnvironment(ctx, pinned) {
51
+ const invResolution = resolveGuardrails(ctx.input.agent, ctx.bindings);
52
+ if (invResolution.missing.length > 0) {
53
+ throwAgentTurnFailure({
54
+ code: 'unresolved-guardrail',
55
+ message: `Agent "${ctx.input.agent.id}" references guardrails not in the registry: ${invResolution.missing.join(', ')}`,
56
+ guardrailIds: invResolution.missing,
57
+ });
58
+ }
59
+ ctx.guardrails = invResolution.resolved;
60
+ // This turn's tools come from the tenant's own registry — never a
61
+ // registry shared across concurrent turns of other tenants.
62
+ const tenantTools = await ctx.bindings.toolRegistry.forTenant(ctx.input.tenantId);
63
+ ctx.tools = resolveTurnTools(tenantTools, ctx.input.agent);
64
+ const capability = ctx.input.agent.capabilities[0];
65
+ if (capability === undefined) {
66
+ throwAgentTurnFailure({
67
+ code: 'capability-routing-failed',
68
+ message: `Agent "${ctx.input.agent.id}" has no capabilities declared`,
69
+ cause: null,
70
+ });
71
+ }
72
+ // Merge the static tenant policy with the one derived from the
73
+ // policy registry (if wired); the result is at least as strict as
74
+ // each (see `mergeTenantPolicies`).
75
+ const derivedPolicy = ctx.bindings.policyRegistry !== undefined
76
+ ? await ctx.bindings.policyRegistry.evaluate('model-routing', { tenantId: ctx.input.tenantId })
77
+ : undefined;
78
+ const effectivePolicy = mergeTenantPolicies(ctx.bindings.tenantPolicy, derivedPolicy);
79
+ if (effectivePolicy !== undefined)
80
+ ctx.tenantPolicy = effectivePolicy;
81
+ ctx.toolErrorPolicy = await resolveToolErrorPolicy(ctx);
82
+ // Storage-backed registries need an async hydration
83
+ // step before the sync `list(tenantId)` call — they read persisted
84
+ // providers from `ProviderRegistryBinding` and instantiate each via
85
+ // its adapter factory. In-memory implementations (dev-echo,
86
+ // tests) leave `hydrate` undefined and this is a no-op.
87
+ if (ctx.bindings.providerRegistry.hydrate !== undefined) {
88
+ await ctx.bindings.providerRegistry.hydrate(ctx.input.tenantId);
89
+ }
90
+ // A pinned route narrows the policy to exactly that provider and model.
91
+ const routingPolicy = pinned === undefined
92
+ ? effectivePolicy
93
+ : mergeTenantPolicies(effectivePolicy, {
94
+ tenantId: ctx.input.tenantId,
95
+ providers: { allow: [pinned.providerId] },
96
+ models: { allow: [pinned.model] },
97
+ });
98
+ const routed = route({
99
+ capability,
100
+ providers: ctx.bindings.providerRegistry.list(ctx.input.tenantId),
101
+ ...(routingPolicy !== undefined && { tenantPolicy: routingPolicy }),
102
+ ...(ctx.input.agent.preferredProvider !== undefined && {
103
+ preferredProvider: ctx.input.agent.preferredProvider,
104
+ }),
105
+ ...(ctx.input.agent.preferredModel !== undefined && {
106
+ preferredModel: ctx.input.agent.preferredModel,
107
+ }),
108
+ });
109
+ if (routed.kind === 'err') {
110
+ throwAgentTurnFailure({
111
+ code: 'capability-routing-failed',
112
+ message: pinned === undefined
113
+ ? routed.error.message
114
+ : `The turn was routed to ${pinned.providerId}/${pinned.model}, which is no longer registered or allowed: ${routed.error.message}`,
115
+ cause: routed.error,
116
+ });
117
+ }
118
+ ctx.provider = routed.value.provider;
119
+ ctx.model = routed.value.model;
120
+ return {
121
+ providerId: routed.value.provider.metadata.id,
122
+ model: routed.value.model.name,
123
+ toolCount: ctx.tools.definitions.length,
124
+ };
125
+ }
126
+ /**
127
+ * The turn's approval rules: the agent's, held to the tenant's `hitl`
128
+ * policy. A policy that can't be evaluated fails the turn — running
129
+ * without it would skip the tenant's approvals.
130
+ */
131
+ export async function resolveTurnHitlPolicy(ctx) {
132
+ let tenant;
133
+ if (ctx.bindings.policyRegistry !== undefined) {
134
+ try {
135
+ tenant = await ctx.bindings.policyRegistry.evaluate('hitl', { tenantId: ctx.input.tenantId });
136
+ }
137
+ catch (cause) {
138
+ throwAgentTurnFailure({
139
+ code: 'tenant-policy-unavailable',
140
+ message: `The tenant's hitl policy could not be applied: ${cause instanceof Error ? cause.message : String(cause)}`,
141
+ policyKind: 'hitl',
142
+ });
143
+ }
144
+ }
145
+ return resolveEffectiveHitlPolicy({ tenant, agent: ctx.input.agent });
146
+ }
147
+ /** The agent's `toolErrors`, capped by the tenant's `tool-errors` policy. */
148
+ async function resolveToolErrorPolicy(ctx) {
149
+ const cap = ctx.bindings.policyRegistry !== undefined
150
+ ? await ctx.bindings.policyRegistry.evaluate('tool-errors', { tenantId: ctx.input.tenantId })
151
+ : undefined;
152
+ return effectiveToolErrorPolicy(ctx.input.agent.toolErrors, cap);
153
+ }
154
+ //# sourceMappingURL=turn-environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-environment.js","sourceRoot":"","sources":["../../src/handlers/turn-environment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { type HitlSpec } from '@kindgi/policy-contract';
2
+ import type { Agent, ToolHitlMode, ToolHitlRule } from './types.js';
3
+ export interface EffectiveHitlPolicy {
4
+ /**
5
+ * Session-turn count gate. Absent = no session gate.
6
+ * Merged from `agent.conversationPolicy.hitl.afterTurns` and
7
+ * `agent.conversationPolicy.hitlAfterTurns` (either fires;
8
+ * `hitl.afterTurns` wins when both are set).
9
+ */
10
+ readonly turn?: {
11
+ readonly afterTurns: number;
12
+ };
13
+ /**
14
+ * Tool-level policy. Absent = no tool gates (agents opt in
15
+ * explicitly). Same shape as `agent.conversationPolicy.hitl.tools`,
16
+ * with string overrides normalized to rules and tenant overrides
17
+ * applied; the per-tool default (from `Tool.mutating`) is applied at
18
+ * dispatch time.
19
+ */
20
+ readonly tools?: {
21
+ readonly default?: ToolHitlMode;
22
+ readonly overrides: ReadonlyMap<string, ToolHitlRule>;
23
+ };
24
+ /**
25
+ * The tenant's per-tool rules: a floor under the agent's gate for
26
+ * that tool. A tool's gate is the stricter of the two; tools the
27
+ * tenant names nothing for keep the agent's.
28
+ */
29
+ readonly toolFloors?: ReadonlyMap<string, ToolHitlRule>;
30
+ readonly defaultReviewerRole: 'standard' | 'senior' | 'admin';
31
+ /** Millisecond timeout used at enqueue time. */
32
+ readonly timeoutMs: number;
33
+ readonly onTimeout: 'auto-approve' | 'auto-reject' | 'escalate';
34
+ }
35
+ /**
36
+ * Compute the effective HITL policy for a given (tenant, agent) pair:
37
+ * framework defaults overlaid with the agent's policy, then held to the
38
+ * tenant's `hitl` policy (only stricter). `tenant: undefined` — the
39
+ * tenant has none.
40
+ */
41
+ export declare function resolveEffectiveHitlPolicy(input: {
42
+ readonly tenant: HitlSpec | undefined;
43
+ readonly agent: Agent;
44
+ }): EffectiveHitlPolicy;
45
+ //# sourceMappingURL=hitl-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hitl-policy.d.ts","sourceRoot":"","sources":["../src/hitl-policy.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,KAAK,QAAQ,EAA4B,MAAM,yBAAyB,CAAC;AAElF,OAAO,KAAK,EAAE,KAAK,EAA0B,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5F,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;QAChC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;KACvD,CAAC;IACF;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACxD,QAAQ,CAAC,mBAAmB,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC9D,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,cAAc,GAAG,aAAa,GAAG,UAAU,CAAC;CACjE;AAYD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB,GAAG,mBAAmB,CAsDtB"}