melchizedek-agents 0.18.0 → 0.19.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 (281) hide show
  1. package/.env.example +12 -0
  2. package/CHANGELOG.md +825 -0
  3. package/DOCUMENTATION.md +217 -59
  4. package/README.md +42 -1
  5. package/config/agents/examples/harness.yaml +3 -1
  6. package/config/agents/examples/model_zoo.yaml +10 -9
  7. package/config/agents/syndicateSchema.yaml +50 -16
  8. package/config/agents/templates/account_memory.yaml +2 -6
  9. package/config/agents/templates/case_desk.yaml +3 -9
  10. package/config/agents/templates/draft_review.yaml +3 -9
  11. package/config/agents/templates/intake_extractor.yaml +1 -3
  12. package/config/agents/templates/research_brief.yaml +3 -9
  13. package/config/agents/templates/research_desk.yaml +3 -9
  14. package/config/agents/templates/review_panel.yaml +4 -12
  15. package/config/agents/templates/support_triage.yaml +4 -12
  16. package/config/agents/templates/systems_operator.yaml +2 -6
  17. package/db/hardening.sql +7 -1
  18. package/db/migrations/0013_tool_credentials.sql +260 -0
  19. package/dist/lib/a2a/app.d.ts +70 -6
  20. package/dist/lib/a2a/app.js +107 -2
  21. package/dist/lib/a2a/executor.d.ts +20 -3
  22. package/dist/lib/a2a/executor.js +66 -7
  23. package/dist/lib/a2a/remoteAgent.d.ts +24 -9
  24. package/dist/lib/a2a/remoteAgent.js +31 -14
  25. package/dist/lib/compile.d.ts +121 -30
  26. package/dist/lib/compile.js +137 -124
  27. package/dist/lib/compileAdk.d.ts +29 -0
  28. package/dist/lib/compileAdk.js +132 -0
  29. package/dist/lib/compileNative.d.ts +85 -0
  30. package/dist/lib/compileNative.js +222 -0
  31. package/dist/lib/config.d.ts +6 -5
  32. package/dist/lib/config.js +6 -5
  33. package/dist/lib/doctor.js +1 -0
  34. package/dist/lib/index.d.ts +2 -1
  35. package/dist/lib/index.js +2 -1
  36. package/dist/lib/loadSyndicate.d.ts +18 -0
  37. package/dist/lib/memory/erase.d.ts +5 -3
  38. package/dist/lib/memory/erase.js +5 -2
  39. package/dist/lib/memory/namespace.d.ts +8 -1
  40. package/dist/lib/memory/namespace.js +12 -6
  41. package/dist/lib/memory/providers.js +2 -1
  42. package/dist/lib/memory/supabaseMemoryService.d.ts +37 -3
  43. package/dist/lib/memory/supabaseMemoryService.js +42 -2
  44. package/dist/lib/model.d.ts +47 -0
  45. package/dist/lib/model.js +37 -0
  46. package/dist/lib/models/adapterResolver.d.ts +113 -0
  47. package/dist/lib/models/adapterResolver.js +136 -0
  48. package/dist/lib/models/adkGeminiAdapter.d.ts +90 -0
  49. package/dist/lib/models/adkGeminiAdapter.js +367 -0
  50. package/dist/lib/models/adkShim.d.ts +111 -0
  51. package/dist/lib/models/adkShim.js +136 -0
  52. package/dist/lib/models/capabilities.d.ts +3 -0
  53. package/dist/lib/models/capabilities.js +20 -13
  54. package/dist/lib/models/chatCompletionsAdapter.d.ts +279 -0
  55. package/dist/lib/models/chatCompletionsAdapter.js +854 -0
  56. package/dist/lib/models/circuitBreaker.d.ts +42 -0
  57. package/dist/lib/models/circuitBreaker.js +70 -0
  58. package/dist/lib/models/claudeAdapter.d.ts +103 -0
  59. package/dist/lib/models/claudeAdapter.js +669 -0
  60. package/dist/lib/models/claudeLlm.d.ts +39 -62
  61. package/dist/lib/models/claudeLlm.js +44 -349
  62. package/dist/lib/models/claudeModels.d.ts +127 -0
  63. package/dist/lib/models/claudeModels.js +237 -0
  64. package/dist/lib/models/contract.d.ts +395 -0
  65. package/dist/lib/models/contract.js +39 -0
  66. package/dist/lib/models/endpoints.js +2 -1
  67. package/dist/lib/models/errorResponse.d.ts +50 -0
  68. package/dist/lib/models/errorResponse.js +48 -0
  69. package/dist/lib/models/fallback.d.ts +17 -10
  70. package/dist/lib/models/fallback.js +53 -42
  71. package/dist/lib/models/fallbackAdapter.d.ts +55 -0
  72. package/dist/lib/models/fallbackAdapter.js +62 -0
  73. package/dist/lib/models/gateway.js +2 -1
  74. package/dist/lib/models/gatewayAdapter.d.ts +51 -0
  75. package/dist/lib/models/gatewayAdapter.js +81 -0
  76. package/dist/lib/models/gatewayLlm.d.ts +12 -33
  77. package/dist/lib/models/gatewayLlm.js +14 -75
  78. package/dist/lib/models/geminiAdapter.d.ts +123 -0
  79. package/dist/lib/models/geminiAdapter.js +831 -0
  80. package/dist/lib/models/geminiState.d.ts +25 -0
  81. package/dist/lib/models/geminiState.js +25 -0
  82. package/dist/lib/models/genaiMapping.d.ts +263 -0
  83. package/dist/lib/models/genaiMapping.js +862 -0
  84. package/dist/lib/models/gptAdapter.d.ts +240 -0
  85. package/dist/lib/models/gptAdapter.js +804 -0
  86. package/dist/lib/models/gptLlm.d.ts +63 -123
  87. package/dist/lib/models/gptLlm.js +88 -602
  88. package/dist/lib/models/grokAdapter.d.ts +86 -0
  89. package/dist/lib/models/grokAdapter.js +142 -0
  90. package/dist/lib/models/grokLlm.d.ts +22 -45
  91. package/dist/lib/models/grokLlm.js +22 -67
  92. package/dist/lib/models/kimiAdapter.d.ts +157 -0
  93. package/dist/lib/models/kimiAdapter.js +203 -0
  94. package/dist/lib/models/kimiLlm.d.ts +15 -107
  95. package/dist/lib/models/kimiLlm.js +17 -153
  96. package/dist/lib/models/ollamaAdapter.d.ts +125 -0
  97. package/dist/lib/models/ollamaAdapter.js +155 -0
  98. package/dist/lib/models/ollamaLlm.d.ts +11 -107
  99. package/dist/lib/models/ollamaLlm.js +13 -151
  100. package/dist/lib/models/openAiCompatibleLlm.d.ts +73 -216
  101. package/dist/lib/models/openAiCompatibleLlm.js +109 -671
  102. package/dist/lib/models/providerState.d.ts +63 -0
  103. package/dist/lib/models/providerState.js +61 -0
  104. package/dist/lib/models/reasoning.d.ts +26 -0
  105. package/dist/lib/models/reasoning.js +59 -0
  106. package/dist/lib/models/registry.d.ts +58 -35
  107. package/dist/lib/models/registry.js +89 -118
  108. package/dist/lib/models/retry.d.ts +2 -1
  109. package/dist/lib/models/retry.js +3 -2
  110. package/dist/lib/models/schemaNormalize.d.ts +98 -0
  111. package/dist/lib/models/schemaNormalize.js +321 -1
  112. package/dist/lib/models/tracedGemini.d.ts +41 -0
  113. package/dist/lib/models/tracedGemini.js +98 -0
  114. package/dist/lib/models/urls.d.ts +11 -0
  115. package/dist/lib/models/urls.js +16 -0
  116. package/dist/lib/net/redirects.d.ts +21 -2
  117. package/dist/lib/net/redirects.js +11 -34
  118. package/dist/lib/observability/audit.d.ts +5 -1
  119. package/dist/lib/observability/lineage.d.ts +14 -0
  120. package/dist/lib/observability/lineage.js +33 -0
  121. package/dist/lib/observability/supabaseSpanExporter.d.ts +10 -4
  122. package/dist/lib/observability/supabaseSpanExporter.js +17 -9
  123. package/dist/lib/observability/tracer.d.ts +26 -8
  124. package/dist/lib/observability/tracer.js +43 -18
  125. package/dist/lib/runtime/adkMemoryBridge.d.ts +46 -0
  126. package/dist/lib/runtime/adkMemoryBridge.js +68 -0
  127. package/dist/lib/runtime/adkSessionBridge.d.ts +78 -0
  128. package/dist/lib/runtime/adkSessionBridge.js +176 -0
  129. package/dist/lib/runtime/credentials.d.ts +59 -0
  130. package/dist/lib/runtime/credentials.js +62 -0
  131. package/dist/lib/runtime/events.d.ts +229 -0
  132. package/dist/lib/runtime/events.js +274 -0
  133. package/dist/lib/runtime/logging.d.ts +32 -0
  134. package/dist/lib/runtime/logging.js +55 -0
  135. package/dist/lib/runtime/memoryService.d.ts +72 -0
  136. package/dist/lib/runtime/memoryService.js +25 -0
  137. package/dist/lib/runtime/native/agentLoop.d.ts +203 -0
  138. package/dist/lib/runtime/native/agentLoop.js +687 -0
  139. package/dist/lib/runtime/native/compaction.d.ts +103 -0
  140. package/dist/lib/runtime/native/compaction.js +191 -0
  141. package/dist/lib/runtime/native/delegate.d.ts +98 -0
  142. package/dist/lib/runtime/native/delegate.js +173 -0
  143. package/dist/lib/runtime/native/history.d.ts +83 -0
  144. package/dist/lib/runtime/native/history.js +312 -0
  145. package/dist/lib/runtime/native/interrupts.d.ts +126 -0
  146. package/dist/lib/runtime/native/interrupts.js +291 -0
  147. package/dist/lib/runtime/native/request.d.ts +215 -0
  148. package/dist/lib/runtime/native/request.js +585 -0
  149. package/dist/lib/runtime/native/selfCorrection.d.ts +106 -0
  150. package/dist/lib/runtime/native/selfCorrection.js +253 -0
  151. package/dist/lib/runtime/native/step.d.ts +148 -0
  152. package/dist/lib/runtime/native/step.js +239 -0
  153. package/dist/lib/runtime/native/taskMode.d.ts +64 -0
  154. package/dist/lib/runtime/native/taskMode.js +126 -0
  155. package/dist/lib/runtime/native/telemetry.d.ts +75 -0
  156. package/dist/lib/runtime/native/telemetry.js +299 -0
  157. package/dist/lib/runtime/native/tempState.d.ts +31 -0
  158. package/dist/lib/runtime/native/tempState.js +56 -0
  159. package/dist/lib/runtime/nativeTurn.d.ts +86 -0
  160. package/dist/lib/runtime/nativeTurn.js +107 -0
  161. package/dist/lib/runtime/questions.d.ts +29 -7
  162. package/dist/lib/runtime/questions.js +47 -32
  163. package/dist/lib/runtime/runtimeFlag.d.ts +30 -0
  164. package/dist/lib/runtime/runtimeFlag.js +50 -0
  165. package/dist/lib/runtime/sessions.d.ts +166 -0
  166. package/dist/lib/runtime/sessions.js +201 -0
  167. package/dist/lib/runtime/syndicateTurn.d.ts +41 -5
  168. package/dist/lib/runtime/syndicateTurn.js +202 -32
  169. package/dist/lib/session/supabaseSessionService.d.ts +64 -17
  170. package/dist/lib/session/supabaseSessionService.js +148 -105
  171. package/dist/lib/session/transcript.d.ts +68 -22
  172. package/dist/lib/session/transcript.js +102 -28
  173. package/dist/lib/skills.js +33 -7
  174. package/dist/lib/storage/postgres/credentialStore.d.ts +20 -0
  175. package/dist/lib/storage/postgres/credentialStore.js +82 -0
  176. package/dist/lib/storage/postgres/index.d.ts +12 -0
  177. package/dist/lib/storage/postgres/index.js +6 -1
  178. package/dist/lib/storage/postgres/sessionService.d.ts +43 -15
  179. package/dist/lib/storage/postgres/sessionService.js +128 -66
  180. package/dist/lib/syndicateSchema.d.ts +47 -0
  181. package/dist/lib/syndicateSchema.js +72 -3
  182. package/dist/lib/toolRegistry.d.ts +15 -2
  183. package/dist/lib/toolRegistry.js +33 -17
  184. package/dist/lib/tools/adkTool.d.ts +81 -0
  185. package/dist/lib/tools/adkTool.js +268 -0
  186. package/dist/lib/tools/auth.d.ts +118 -0
  187. package/dist/lib/tools/auth.js +89 -0
  188. package/dist/lib/tools/collectionsSearchTool.d.ts +7 -6
  189. package/dist/lib/tools/collectionsSearchTool.js +11 -26
  190. package/dist/lib/tools/credentialCipher.d.ts +58 -0
  191. package/dist/lib/tools/credentialCipher.js +116 -0
  192. package/dist/lib/tools/credentialStore.d.ts +77 -0
  193. package/dist/lib/tools/credentialStore.js +246 -0
  194. package/dist/lib/tools/examples.d.ts +43 -0
  195. package/dist/lib/tools/examples.js +62 -0
  196. package/dist/lib/tools/generateImageTool.d.ts +15 -6
  197. package/dist/lib/tools/generateImageTool.js +19 -29
  198. package/dist/lib/tools/inspectImageTool.d.ts +9 -6
  199. package/dist/lib/tools/inspectImageTool.js +13 -17
  200. package/dist/lib/tools/mcpToolFactory.d.ts +42 -1
  201. package/dist/lib/tools/mcpToolFactory.js +46 -47
  202. package/dist/lib/tools/memoryTools.d.ts +61 -0
  203. package/dist/lib/tools/memoryTools.js +119 -0
  204. package/dist/lib/tools/nativeTools.d.ts +38 -0
  205. package/dist/lib/tools/nativeTools.js +43 -0
  206. package/dist/lib/tools/oauthConsent.d.ts +181 -0
  207. package/dist/lib/tools/oauthConsent.js +330 -0
  208. package/dist/lib/tools/openapi/call.d.ts +108 -0
  209. package/dist/lib/tools/openapi/call.js +295 -0
  210. package/dist/lib/tools/openapi/parse.d.ts +147 -0
  211. package/dist/lib/tools/openapi/parse.js +570 -0
  212. package/dist/lib/tools/openapiTools.d.ts +25 -17
  213. package/dist/lib/tools/openapiTools.js +124 -121
  214. package/dist/lib/tools/scienceTools.d.ts +14 -14
  215. package/dist/lib/tools/skillToolset.d.ts +58 -87
  216. package/dist/lib/tools/skillToolset.js +61 -142
  217. package/dist/lib/tools/skills/env.d.ts +58 -0
  218. package/dist/lib/tools/skills/env.js +165 -0
  219. package/dist/lib/tools/skills/executor.d.ts +114 -0
  220. package/dist/lib/tools/skills/executor.js +331 -0
  221. package/dist/lib/tools/skills/frontmatter.d.ts +79 -0
  222. package/dist/lib/tools/skills/frontmatter.js +215 -0
  223. package/dist/lib/tools/skills/loader.d.ts +91 -0
  224. package/dist/lib/tools/skills/loader.js +257 -0
  225. package/dist/lib/tools/skills/tools.d.ts +187 -0
  226. package/dist/lib/tools/skills/tools.js +386 -0
  227. package/dist/lib/tools/taskTools.d.ts +15 -15
  228. package/dist/lib/tools/tool.d.ts +354 -0
  229. package/dist/lib/tools/tool.js +304 -0
  230. package/dist/lib/tools/toolContract.d.ts +89 -33
  231. package/dist/lib/tools/toolContract.js +104 -82
  232. package/dist/lib/tools/urlContextTool.d.ts +3 -0
  233. package/dist/lib/tools/urlContextTool.js +5 -1
  234. package/dist/lib/tools/webExtractTool.d.ts +2 -2
  235. package/dist/lib/tools/webExtractTool.js +2 -1
  236. package/dist/lib/tools/webSearchTool.d.ts +6 -9
  237. package/dist/lib/tools/webSearchTool.js +14 -59
  238. package/dist/lib/tools/wikiTools.d.ts +19 -19
  239. package/dist/lib/tools/wikiTools.js +13 -9
  240. package/dist/lib/tools/xApiSearchTool.d.ts +2 -2
  241. package/dist/lib/tools/xApiSearchTool.js +2 -1
  242. package/dist/lib/tools/xSearchTool.d.ts +7 -9
  243. package/dist/lib/tools/xSearchTool.js +11 -62
  244. package/dist/lib/tools/xaiSearchParams.d.ts +41 -0
  245. package/dist/lib/tools/xaiSearchParams.js +126 -0
  246. package/dist/lib/wiki/agentRun.d.ts +12 -0
  247. package/dist/lib/wiki/agentRun.js +72 -34
  248. package/dist/lib/wiki/entities.d.ts +12 -0
  249. package/dist/lib/wiki/entities.js +45 -3
  250. package/dist/lib/workflow/agentNode.d.ts +136 -0
  251. package/dist/lib/workflow/agentNode.js +274 -0
  252. package/dist/lib/workflow/graph.d.ts +177 -0
  253. package/dist/lib/workflow/graph.js +458 -0
  254. package/dist/lib/workflow/nodeEvents.d.ts +50 -0
  255. package/dist/lib/workflow/nodeEvents.js +101 -0
  256. package/dist/lib/workflow/pause.d.ts +122 -0
  257. package/dist/lib/workflow/pause.js +180 -0
  258. package/dist/lib/workflow/resume.d.ts +165 -0
  259. package/dist/lib/workflow/resume.js +440 -0
  260. package/dist/lib/workflow/route.d.ts +58 -0
  261. package/dist/lib/workflow/route.js +69 -0
  262. package/dist/lib/workflow/scheduler.d.ts +415 -0
  263. package/dist/lib/workflow/scheduler.js +743 -0
  264. package/dist/lib/workflow/toolNode.d.ts +127 -0
  265. package/dist/lib/workflow/toolNode.js +236 -0
  266. package/dist/lib/workflow/turn.d.ts +118 -0
  267. package/dist/lib/workflow/turn.js +216 -0
  268. package/dist/lib/workflowConfig.d.ts +3 -2
  269. package/dist/lib/workflowConfig.js +3 -12
  270. package/dist/scripts/a2a_server.js +4 -3
  271. package/dist/scripts/assistant_worker.d.ts +2 -1
  272. package/dist/scripts/assistant_worker.js +9 -4
  273. package/dist/scripts/syndicate_chat.js +19 -10
  274. package/package.json +4 -1
  275. package/skills/briefs/melchizedek-author.md +3 -2
  276. package/skills/briefs/melchizedek-models.md +13 -9
  277. package/skills/briefs/melchizedek.md +3 -3
  278. package/skills/melchizedek/SKILL.md +2 -1
  279. package/skills/melchizedek-author/SKILL.md +2 -1
  280. package/skills/melchizedek-author/assets/minimal.yaml +2 -0
  281. package/skills/melchizedek-models/SKILL.md +23 -6
@@ -1,42 +1,22 @@
1
- /**
2
- * lib/runtime/questions.ts — an agent asks the person a question mid-turn,
3
- * and the next message is the answer.
4
- *
5
- * WHY: A syndicate that is put in front of users needs to ask: "which of
6
- * these three accounts?", "what is the order number?". Before this, an
7
- * agent could only end its turn with a question in its text and hope the
8
- * next message answered it, with nothing in the session saying a question
9
- * was open. `ask_user` is ADK's long-running tool mechanism under one YAML
10
- * name: the call is recorded, the run ends without a response to it, the
11
- * turn ends `input-required` (`result.input`), and the next message on the
12
- * conversation becomes the call's response, so the agent resumes its own
13
- * tool loop where it asked, with the question and the answer side by side
14
- * in its history.
15
- *
16
- * The same `input-required` path carries a workflow's `ask_user` node
17
- * (lib/workflow.ts) and an approval (ADR 0028); a client handles all three
18
- * by showing `result.input` (or the approval) and sending the next message.
19
- *
20
- * WHERE: only on an agent the turn runs directly (the orchestrator, or a
21
- * plan-dispatch route), as with approval gates: inside a delegated
22
- * subagent ADK swallows the pause. Not inside a workflow node yet. The
23
- * schema refuses both.
24
- */
25
- import { LongRunningFunctionTool } from '@google/adk';
26
1
  import { z } from 'zod';
2
+ import { defineTool } from '../tools/toolContract.js';
3
+ import { inputRequestFrom } from '../workflowConfig.js';
27
4
  /** The registry name, and the function-call name an open question carries. */
28
5
  export const ASK_USER = 'ask_user';
29
6
  export const MAX_OPTIONS = 10;
30
7
  /**
31
- * The tool. Its execute returns nothing: a long-running call with no result
32
- * ends the run, and ADK waits for a function response with the call's id.
8
+ * The tool, an own Tool marked long-running; the registry hands the ADK
9
+ * runtime its FunctionTool (lib/tools/adkTool.ts). Its execute returns
10
+ * nothing: a long-running call with no result ends the run, and the runtime
11
+ * waits for a function response with the call's id.
33
12
  */
34
- export const askUserTool = new LongRunningFunctionTool({
13
+ export const askUserTool = defineTool({
35
14
  name: ASK_USER,
15
+ longRunning: true,
36
16
  description: 'Ask the person one question and wait for their answer before you continue: a missing detail you need, or a choice only they can make. ' +
37
17
  'Pass `options` when the answer is one of a few choices. The turn ends here; the person\'s next message is the answer, returned to you as this call\'s result. ' +
38
18
  'Ask only what you cannot find out or reasonably assume, one question per call.',
39
- parameters: z.object({
19
+ schema: z.object({
40
20
  question: z.string().min(1).max(500).describe('The question, as the person will read it.'),
41
21
  options: z
42
22
  .array(z.string().min(1).max(120))
@@ -45,9 +25,8 @@ export const askUserTool = new LongRunningFunctionTool({
45
25
  .describe('The choices, when the answer is one of a few. Omit for a free answer.'),
46
26
  }),
47
27
  execute: async (_args, context) => {
48
- if (context)
49
- context.actions.skipSummarization = true;
50
- return null;
28
+ context.actions.skipSummarization = true;
29
+ return undefined;
51
30
  },
52
31
  });
53
32
  const partsOf = (e) => (e.content?.parts ?? []);
@@ -69,6 +48,9 @@ export function questionFrom(author, call) {
69
48
  * The question still waiting for an answer in a session, or undefined. A
70
49
  * question the person moved past (a text message after it was answered)
71
50
  * is not pending; an answered one carries a function response with its id.
51
+ * Only an agent asks: an `ask_user` call in an event the user authored is
52
+ * no question, so the next message never becomes its answer (as approvals
53
+ * refuse a user-authored request, ADR 0077; ADR 0088).
72
54
  */
73
55
  export function pendingQuestion(events) {
74
56
  const answered = new Set();
@@ -80,6 +62,8 @@ export function pendingQuestion(events) {
80
62
  if (p.functionResponse?.name === ASK_USER && p.functionResponse.id)
81
63
  answered.add(p.functionResponse.id);
82
64
  }
65
+ if (e.author === 'user')
66
+ continue;
83
67
  for (const p of partsOf(e)) {
84
68
  const call = p.functionCall;
85
69
  if (call?.name !== ASK_USER || !call.id || answered.has(call.id))
@@ -89,6 +73,37 @@ export function pendingQuestion(events) {
89
73
  }
90
74
  return undefined;
91
75
  }
76
+ /**
77
+ * The workflow question (`adk_request_input`, an ask_user node's request)
78
+ * still open in a session's events, or undefined. The answer is stored as
79
+ * the person's next text message, not as a function response, so a text
80
+ * message after the question closes it; a function response with its id
81
+ * answers it too. As with pendingQuestion, only a node asks: a request in
82
+ * an event the user authored is none. The resume (lib/workflow/resume.ts)
83
+ * reads the same events to route the answer.
84
+ */
85
+ export function pendingWorkflowInput(events) {
86
+ const answered = new Set();
87
+ for (let i = events.length - 1; i >= 0; i--) {
88
+ const e = events[i];
89
+ if (hasUserText(e))
90
+ return undefined;
91
+ for (const p of partsOf(e))
92
+ if (p.functionResponse?.id)
93
+ answered.add(p.functionResponse.id);
94
+ if (e.author === 'user')
95
+ continue;
96
+ for (const p of partsOf(e)) {
97
+ const call = p.functionCall;
98
+ if (!call || (call.id && answered.has(call.id)))
99
+ continue;
100
+ const input = inputRequestFrom(e.author, call);
101
+ if (input)
102
+ return input;
103
+ }
104
+ }
105
+ return undefined;
106
+ }
92
107
  /** The message part that answers question `id` with the person's text. */
93
108
  export function questionAnswerPart(id, answer) {
94
109
  return { functionResponse: { id, name: ASK_USER, response: { result: answer } } };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * lib/runtime/runtimeFlag.ts — which runtime runs a turn: MELCHIZEDEK_RUNTIME
3
+ * and the turn's `runtime` option (ADR 0045, ADR 0073).
4
+ *
5
+ * `adk` runs each agent on Google ADK's Runner, `native` on the engine's own
6
+ * agent loop (lib/runtime/native/agentLoop.ts). The default is `adk` until
7
+ * the release that makes native the default (ADR 0045). A feature the native
8
+ * runtime does not run yet fails before any model call with
9
+ * UnsupportedOnRuntimeError, which names the feature and the runtime.
10
+ *
11
+ * A leaf module: it imports nothing, so every caller (the compiler, the
12
+ * turn runner, the wiki agent runner) can read the flag without a cycle.
13
+ */
14
+ /** The runtime a turn runs on: Google ADK's Runner, or the engine's own loop. */
15
+ export type RuntimeName = 'adk' | 'native';
16
+ export declare const RUNTIMES: readonly RuntimeName[];
17
+ /** The runtime when neither the turn nor MELCHIZEDEK_RUNTIME names one. */
18
+ export declare const DEFAULT_RUNTIME: RuntimeName;
19
+ /** MELCHIZEDEK_RUNTIME as set, or undefined when unset or blank. Any other value is a configuration error. */
20
+ export declare function runtimeSetting(env?: NodeJS.ProcessEnv): RuntimeName | undefined;
21
+ /** The runtime to use: the caller's option, else MELCHIZEDEK_RUNTIME, else adk. */
22
+ export declare function chooseRuntime(option?: string, env?: NodeJS.ProcessEnv): RuntimeName;
23
+ /** A feature the chosen runtime does not run yet. Thrown before any model call. */
24
+ export declare class UnsupportedOnRuntimeError extends Error {
25
+ readonly feature: string;
26
+ readonly runtime: RuntimeName;
27
+ constructor(feature: string, runtime: RuntimeName, where: string);
28
+ }
29
+ /** The error for a feature the native runtime does not run yet; `where` names the agent or syndicate. */
30
+ export declare function unsupportedOnNative(feature: string, where: string): UnsupportedOnRuntimeError;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * lib/runtime/runtimeFlag.ts — which runtime runs a turn: MELCHIZEDEK_RUNTIME
3
+ * and the turn's `runtime` option (ADR 0045, ADR 0073).
4
+ *
5
+ * `adk` runs each agent on Google ADK's Runner, `native` on the engine's own
6
+ * agent loop (lib/runtime/native/agentLoop.ts). The default is `adk` until
7
+ * the release that makes native the default (ADR 0045). A feature the native
8
+ * runtime does not run yet fails before any model call with
9
+ * UnsupportedOnRuntimeError, which names the feature and the runtime.
10
+ *
11
+ * A leaf module: it imports nothing, so every caller (the compiler, the
12
+ * turn runner, the wiki agent runner) can read the flag without a cycle.
13
+ */
14
+ export const RUNTIMES = ['adk', 'native'];
15
+ /** The runtime when neither the turn nor MELCHIZEDEK_RUNTIME names one. */
16
+ export const DEFAULT_RUNTIME = 'adk';
17
+ function asRuntime(raw, source) {
18
+ const value = raw.trim().toLowerCase();
19
+ if (value === 'adk' || value === 'native')
20
+ return value;
21
+ throw new Error(`${source} must be "adk" or "native".`);
22
+ }
23
+ /** MELCHIZEDEK_RUNTIME as set, or undefined when unset or blank. Any other value is a configuration error. */
24
+ export function runtimeSetting(env = process.env) {
25
+ const raw = env.MELCHIZEDEK_RUNTIME;
26
+ if (!raw || !raw.trim())
27
+ return undefined;
28
+ return asRuntime(raw, 'MELCHIZEDEK_RUNTIME');
29
+ }
30
+ /** The runtime to use: the caller's option, else MELCHIZEDEK_RUNTIME, else adk. */
31
+ export function chooseRuntime(option, env = process.env) {
32
+ if (option !== undefined)
33
+ return asRuntime(option, 'The runtime option');
34
+ return runtimeSetting(env) ?? DEFAULT_RUNTIME;
35
+ }
36
+ /** A feature the chosen runtime does not run yet. Thrown before any model call. */
37
+ export class UnsupportedOnRuntimeError extends Error {
38
+ feature;
39
+ runtime;
40
+ constructor(feature, runtime, where) {
41
+ super(`${where}: ${feature} is not supported on the ${runtime} runtime yet. Run it on the ${runtime === 'native' ? 'adk' : 'native'} runtime (MELCHIZEDEK_RUNTIME, or the turn's runtime option).`);
42
+ this.name = 'UnsupportedOnRuntimeError';
43
+ this.feature = feature;
44
+ this.runtime = runtime;
45
+ }
46
+ }
47
+ /** The error for a feature the native runtime does not run yet; `where` names the agent or syndicate. */
48
+ export function unsupportedOnNative(feature, where) {
49
+ return new UnsupportedOnRuntimeError(feature, 'native', where);
50
+ }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * lib/runtime/sessions.ts — the engine's own session interface, the rules
3
+ * every store applies, and a store that lives in the process (ADR 0045,
4
+ * ADR 0052).
5
+ *
6
+ * WHY this file exists:
7
+ * The native runtime reads and writes sessions without ADK. The durable
8
+ * stores (lib/session/supabaseSessionService.ts, lib/storage/postgres/
9
+ * sessionService.ts) and the transcript projection (lib/session/
10
+ * transcript.ts) implement SessionService beside ADK's BaseSessionService,
11
+ * and lib/runtime/adkSessionBridge.ts gives a store that has only one of
12
+ * the two the other, until ADK leaves at 1.0 (ADR 0058). The shapes are
13
+ * ADK's JSON (a Session holds TurnEvents, lib/runtime/events.ts), so both
14
+ * runtimes read and write the same rows.
15
+ *
16
+ * ONE MEANING ACROSS STORES:
17
+ * Where ADK's own services disagree with the engine's durable stores, the
18
+ * interface takes the durable stores' meaning, because that is what
19
+ * production runs and what a test on this in-process store should see.
20
+ * Where the two durable stores differ, it takes the Postgres store's,
21
+ * which never loses an event:
22
+ * - `afterTimestamp` keeps events strictly after it, and `numRecentEvents`
23
+ * then keeps the newest of those (ADK's in-memory store counts first
24
+ * and keeps an event at the timestamp itself).
25
+ * - Creating a session whose id exists returns it unchanged, events and
26
+ * all, so a second create never resets a conversation (ADK's in-memory
27
+ * store resets it).
28
+ * - Paging reports at least one page (listPage).
29
+ * - `app:` and `user:` state keys stay in the session's own state, as both
30
+ * durable stores keep them; ADK's in-memory store shares them across
31
+ * sessions. No syndicate writes such a key.
32
+ * The method names are not ADK's (create, not createSession), so one class
33
+ * can implement this interface and extend ADK's base during the dual
34
+ * period without either signature constraining the other.
35
+ *
36
+ * NO RUNTIME IMPORTS: every import here is a type, and nothing in this
37
+ * module's import graph names @google/* (tests/events.test.ts asserts it).
38
+ */
39
+ import type { TurnEvent } from './events.ts';
40
+ /** A conversation's address. Stores key it as `<appName>:<userId>:<sessionId>`. */
41
+ export interface SessionKey {
42
+ /** The syndicate (or, for a DELEGATE subagent's own row, the subagent's name). */
43
+ appName: string;
44
+ userId: string;
45
+ sessionId: string;
46
+ }
47
+ /** A conversation: the same JSON as ADK's `Session`. */
48
+ export interface Session {
49
+ id: string;
50
+ appName: string;
51
+ userId: string;
52
+ /** Written only through events' `stateDelta` (applyEvent). Never holds a `temp:` key. */
53
+ state: Record<string, unknown>;
54
+ /** Oldest first. */
55
+ events: TurnEvent[];
56
+ /** Milliseconds since the epoch: the last appended event's timestamp, or the creation time. */
57
+ lastUpdateTime: number;
58
+ }
59
+ export interface CreateSessionRequest {
60
+ appName: string;
61
+ userId: string;
62
+ /** A new UUID when absent. */
63
+ sessionId?: string;
64
+ /** Initial state; `temp:` keys are dropped. */
65
+ state?: Record<string, unknown>;
66
+ }
67
+ export interface GetSessionOptions {
68
+ /** Keep only the newest N events (after `afterTimestamp`, when both are set). Ignored unless above zero. */
69
+ numRecentEvents?: number;
70
+ /** Keep only events whose timestamp is strictly greater. Ignored when 0 or absent. */
71
+ afterTimestamp?: number;
72
+ }
73
+ export interface ListSessionsRequest {
74
+ appName: string;
75
+ /** Every user's sessions when absent. */
76
+ userId?: string;
77
+ /** Page size. Every session matching, in one page, when absent. */
78
+ limit?: number;
79
+ /** Zero-based index of the first session. Ignored when `page` and `limit` are both set. */
80
+ offset?: number;
81
+ /** One-based page number. Needs `limit`; wins over `offset`. */
82
+ page?: number;
83
+ /** By last update, ties by id. Insertion order when absent. */
84
+ order?: 'asc' | 'desc';
85
+ }
86
+ export interface ListSessionsResult {
87
+ /** The page's sessions, each without its events. */
88
+ sessions: Session[];
89
+ /** One-based. */
90
+ page: number;
91
+ /** The page size, or every matching session's count when no limit was asked for. */
92
+ limit: number;
93
+ /** Sessions matching, across every page. */
94
+ totalItems: number;
95
+ /** At least 1. */
96
+ totalPages: number;
97
+ }
98
+ /**
99
+ * Where conversations live. Every method fails by throwing, with a message a
100
+ * person can act on; reading a session that does not exist is not a failure.
101
+ */
102
+ export interface SessionService {
103
+ create(request: CreateSessionRequest): Promise<Session>;
104
+ /** A copy: changing it changes nothing stored. Undefined when there is no such session. */
105
+ get(key: SessionKey, options?: GetSessionOptions): Promise<Session | undefined>;
106
+ list(request: ListSessionsRequest): Promise<ListSessionsResult>;
107
+ /** Deletes the session and its events. Deleting one that does not exist does nothing. */
108
+ delete(key: SessionKey): Promise<void>;
109
+ /**
110
+ * Records `event` in `session` (applyEvent's rules, on the caller's copy)
111
+ * and in the store, and returns the event as stored. A partial event is
112
+ * returned as it is and recorded nowhere. Two copies of one session
113
+ * appending in turn both land: each append adds its own event.
114
+ */
115
+ append(session: Session, event: TurnEvent): Promise<TurnEvent>;
116
+ }
117
+ /** State keys with this prefix last for one invocation and are never stored. */
118
+ export declare const TEMP_STATE_PREFIX = "temp:";
119
+ /** A copy of `record` without its `temp:` keys, in the same key order. */
120
+ export declare function withoutTempKeys(record: Record<string, unknown>): Record<string, unknown>;
121
+ /**
122
+ * Applies one event to a live session, as ADK's BaseSessionService does,
123
+ * and returns the event as a store keeps it:
124
+ * 1. A partial event is returned as it is, and the session is untouched.
125
+ * 2. The stored event's `stateDelta` loses its `temp:` keys (a copy; the
126
+ * given event is never changed).
127
+ * 3. Each remaining delta key is written into `session.state`.
128
+ * 4. The event replaces the session's event with the same id, or is
129
+ * appended.
130
+ * 5. `session.lastUpdateTime` becomes the event's timestamp.
131
+ */
132
+ export declare function applyEvent(session: Session, event: TurnEvent): TurnEvent;
133
+ /** The events a read with `options` returns, oldest first (GetSessionOptions). */
134
+ export declare function selectEvents(events: readonly TurnEvent[], options?: GetSessionOptions): TurnEvent[];
135
+ /**
136
+ * The window a list request asks for: a zero-based offset and, when a limit
137
+ * was given, the page size. `page` wins over `offset` only beside a limit.
138
+ */
139
+ export declare function listWindow(request: Pick<ListSessionsRequest, 'limit' | 'offset' | 'page'>): {
140
+ offset: number;
141
+ limit?: number;
142
+ };
143
+ /** The paging figures a list result reports, given how many sessions matched. */
144
+ export declare function listPage(totalItems: number, request: Pick<ListSessionsRequest, 'limit' | 'offset' | 'page'>): Omit<ListSessionsResult, 'sessions'>;
145
+ export interface InProcessSessionOptions {
146
+ /** The clock for a new session's lastUpdateTime. Default Date.now. */
147
+ now?: () => number;
148
+ }
149
+ /**
150
+ * Sessions held in this process, lost when it exits: the store for a
151
+ * syndicate with no durable one, and for tests. Every read hands out a copy
152
+ * and every append stores a copy, so no caller shares an object with the
153
+ * store. An append to a session the store does not hold (deleted while its
154
+ * turn ran) keeps the caller's session as it stands after the event.
155
+ */
156
+ export declare class InProcessSessionService implements SessionService {
157
+ private readonly sessions;
158
+ private readonly now;
159
+ constructor(options?: InProcessSessionOptions);
160
+ private static key;
161
+ create(request: CreateSessionRequest): Promise<Session>;
162
+ get(key: SessionKey, options?: GetSessionOptions): Promise<Session | undefined>;
163
+ list(request: ListSessionsRequest): Promise<ListSessionsResult>;
164
+ delete(key: SessionKey): Promise<void>;
165
+ append(session: Session, event: TurnEvent): Promise<TurnEvent>;
166
+ }
@@ -0,0 +1,201 @@
1
+ /**
2
+ * lib/runtime/sessions.ts — the engine's own session interface, the rules
3
+ * every store applies, and a store that lives in the process (ADR 0045,
4
+ * ADR 0052).
5
+ *
6
+ * WHY this file exists:
7
+ * The native runtime reads and writes sessions without ADK. The durable
8
+ * stores (lib/session/supabaseSessionService.ts, lib/storage/postgres/
9
+ * sessionService.ts) and the transcript projection (lib/session/
10
+ * transcript.ts) implement SessionService beside ADK's BaseSessionService,
11
+ * and lib/runtime/adkSessionBridge.ts gives a store that has only one of
12
+ * the two the other, until ADK leaves at 1.0 (ADR 0058). The shapes are
13
+ * ADK's JSON (a Session holds TurnEvents, lib/runtime/events.ts), so both
14
+ * runtimes read and write the same rows.
15
+ *
16
+ * ONE MEANING ACROSS STORES:
17
+ * Where ADK's own services disagree with the engine's durable stores, the
18
+ * interface takes the durable stores' meaning, because that is what
19
+ * production runs and what a test on this in-process store should see.
20
+ * Where the two durable stores differ, it takes the Postgres store's,
21
+ * which never loses an event:
22
+ * - `afterTimestamp` keeps events strictly after it, and `numRecentEvents`
23
+ * then keeps the newest of those (ADK's in-memory store counts first
24
+ * and keeps an event at the timestamp itself).
25
+ * - Creating a session whose id exists returns it unchanged, events and
26
+ * all, so a second create never resets a conversation (ADK's in-memory
27
+ * store resets it).
28
+ * - Paging reports at least one page (listPage).
29
+ * - `app:` and `user:` state keys stay in the session's own state, as both
30
+ * durable stores keep them; ADK's in-memory store shares them across
31
+ * sessions. No syndicate writes such a key.
32
+ * The method names are not ADK's (create, not createSession), so one class
33
+ * can implement this interface and extend ADK's base during the dual
34
+ * period without either signature constraining the other.
35
+ *
36
+ * NO RUNTIME IMPORTS: every import here is a type, and nothing in this
37
+ * module's import graph names @google/* (tests/events.test.ts asserts it).
38
+ */
39
+ // ── The rules every store applies ────────────────────────────────────────────
40
+ /** State keys with this prefix last for one invocation and are never stored. */
41
+ export const TEMP_STATE_PREFIX = 'temp:';
42
+ /**
43
+ * Sets an own property even when the key is `__proto__`: JSON.parse makes
44
+ * that an own key, and plain assignment would re-parent the object instead.
45
+ */
46
+ function setOwn(target, key, value) {
47
+ Object.defineProperty(target, key, { value, writable: true, enumerable: true, configurable: true });
48
+ }
49
+ /** A copy of `record` without its `temp:` keys, in the same key order. */
50
+ export function withoutTempKeys(record) {
51
+ const out = {};
52
+ for (const [key, value] of Object.entries(record))
53
+ if (!key.startsWith(TEMP_STATE_PREFIX))
54
+ setOwn(out, key, value);
55
+ return out;
56
+ }
57
+ /**
58
+ * Applies one event to a live session, as ADK's BaseSessionService does,
59
+ * and returns the event as a store keeps it:
60
+ * 1. A partial event is returned as it is, and the session is untouched.
61
+ * 2. The stored event's `stateDelta` loses its `temp:` keys (a copy; the
62
+ * given event is never changed).
63
+ * 3. Each remaining delta key is written into `session.state`.
64
+ * 4. The event replaces the session's event with the same id, or is
65
+ * appended.
66
+ * 5. `session.lastUpdateTime` becomes the event's timestamp.
67
+ */
68
+ export function applyEvent(session, event) {
69
+ if (event.partial)
70
+ return event;
71
+ let stored = event;
72
+ const delta = event.actions?.stateDelta;
73
+ if (delta) {
74
+ const kept = withoutTempKeys(delta);
75
+ if (Object.keys(kept).length !== Object.keys(delta).length) {
76
+ stored = { ...event, actions: { ...event.actions, stateDelta: kept } };
77
+ }
78
+ for (const [key, value] of Object.entries(kept))
79
+ setOwn(session.state, key, value);
80
+ }
81
+ const at = session.events.findIndex((e) => e.id === stored.id);
82
+ if (at >= 0)
83
+ session.events[at] = stored;
84
+ else
85
+ session.events.push(stored);
86
+ session.lastUpdateTime = stored.timestamp;
87
+ return stored;
88
+ }
89
+ /** A finite number, rounded down; undefined otherwise. */
90
+ function whole(n) {
91
+ return typeof n === 'number' && Number.isFinite(n) ? Math.floor(n) : undefined;
92
+ }
93
+ /** The events a read with `options` returns, oldest first (GetSessionOptions). */
94
+ export function selectEvents(events, options = {}) {
95
+ let out = [...events];
96
+ const after = options.afterTimestamp;
97
+ if (after)
98
+ out = out.filter((e) => e.timestamp > after);
99
+ const n = whole(options.numRecentEvents);
100
+ if (n !== undefined && n > 0)
101
+ out = out.slice(-n);
102
+ return out;
103
+ }
104
+ /**
105
+ * The window a list request asks for: a zero-based offset and, when a limit
106
+ * was given, the page size. `page` wins over `offset` only beside a limit.
107
+ */
108
+ export function listWindow(request) {
109
+ const limitRaw = whole(request.limit);
110
+ const limit = limitRaw === undefined ? undefined : Math.max(0, limitRaw);
111
+ const page = whole(request.page);
112
+ const offset = limit !== undefined && page !== undefined ? (Math.max(1, page) - 1) * limit : Math.max(0, whole(request.offset) ?? 0);
113
+ return limit === undefined ? { offset } : { offset, limit };
114
+ }
115
+ /** The paging figures a list result reports, given how many sessions matched. */
116
+ export function listPage(totalItems, request) {
117
+ const { offset, limit } = listWindow(request);
118
+ return {
119
+ page: limit ? Math.floor(offset / limit) + 1 : 1,
120
+ limit: limit ?? totalItems,
121
+ totalItems,
122
+ totalPages: limit ? Math.max(1, Math.ceil(totalItems / limit)) : 1,
123
+ };
124
+ }
125
+ /**
126
+ * Sessions held in this process, lost when it exits: the store for a
127
+ * syndicate with no durable one, and for tests. Every read hands out a copy
128
+ * and every append stores a copy, so no caller shares an object with the
129
+ * store. An append to a session the store does not hold (deleted while its
130
+ * turn ran) keeps the caller's session as it stands after the event.
131
+ */
132
+ export class InProcessSessionService {
133
+ sessions = new Map();
134
+ now;
135
+ constructor(options = {}) {
136
+ this.now = options.now ?? Date.now;
137
+ }
138
+ static key(appName, userId, sessionId) {
139
+ return JSON.stringify([appName, userId, sessionId]);
140
+ }
141
+ async create(request) {
142
+ const id = request.sessionId || globalThis.crypto.randomUUID();
143
+ const key = InProcessSessionService.key(request.appName, request.userId, id);
144
+ const existing = this.sessions.get(key);
145
+ if (existing)
146
+ return structuredClone(existing);
147
+ const session = {
148
+ id,
149
+ appName: request.appName,
150
+ userId: request.userId,
151
+ state: withoutTempKeys(structuredClone(request.state ?? {})),
152
+ events: [],
153
+ lastUpdateTime: this.now(),
154
+ };
155
+ this.sessions.set(key, session);
156
+ return structuredClone(session);
157
+ }
158
+ async get(key, options) {
159
+ const held = this.sessions.get(InProcessSessionService.key(key.appName, key.userId, key.sessionId));
160
+ if (!held)
161
+ return undefined;
162
+ const copy = structuredClone(held);
163
+ copy.events = selectEvents(copy.events, options);
164
+ return copy;
165
+ }
166
+ async list(request) {
167
+ const matching = [...this.sessions.values()].filter((s) => s.appName === request.appName && (request.userId === undefined || s.userId === request.userId));
168
+ if (request.order) {
169
+ const sign = request.order === 'asc' ? 1 : -1;
170
+ matching.sort((a, b) => sign * (a.lastUpdateTime - b.lastUpdateTime) || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
171
+ }
172
+ const { offset, limit } = listWindow(request);
173
+ const window = matching.slice(offset, limit === undefined ? undefined : offset + limit);
174
+ return {
175
+ sessions: window.map((s) => ({
176
+ id: s.id,
177
+ appName: s.appName,
178
+ userId: s.userId,
179
+ state: structuredClone(s.state),
180
+ events: [],
181
+ lastUpdateTime: s.lastUpdateTime,
182
+ })),
183
+ ...listPage(matching.length, request),
184
+ };
185
+ }
186
+ async delete(key) {
187
+ this.sessions.delete(InProcessSessionService.key(key.appName, key.userId, key.sessionId));
188
+ }
189
+ async append(session, event) {
190
+ if (event.partial)
191
+ return event;
192
+ const stored = applyEvent(session, event);
193
+ const key = InProcessSessionService.key(session.appName, session.userId, session.id);
194
+ const held = this.sessions.get(key);
195
+ if (held)
196
+ applyEvent(held, structuredClone(stored));
197
+ else
198
+ this.sessions.set(key, structuredClone(session));
199
+ return stored;
200
+ }
201
+ }
@@ -25,9 +25,25 @@
25
25
  * subagents, nested syndicates), an optional deadline bounds wall-clock
26
26
  * time, and an outer AbortSignal cancels it. All three abort the provider
27
27
  * request in flight, not just the loop around it.
28
+ *
29
+ * ── Runtimes (ADR 0045, ADR 0073) ─────────────────────────────────────────
30
+ * Each agent of a turn runs on ADK's Runner (the default) or on the
31
+ * engine's own agent loop: the turn's `runtime` option, else
32
+ * MELCHIZEDEK_RUNTIME. Both compile the same AgentSpec (lib/compile.ts),
33
+ * store the same events and drain through drainAgentStream, so everything
34
+ * else here is shared. What native does not run yet fails before any model
35
+ * call, naming the feature (lib/runtime/nativeTurn.ts).
28
36
  */
29
37
  import type { BasePlugin } from '@google/adk';
30
38
  import type { BaseMemoryService, BaseSessionService, Event, LlmAgent } from '@google/adk';
39
+ import type { RuntimeName } from './runtimeFlag.ts';
40
+ import type { ToolCredentials } from '../tools/oauthConsent.ts';
41
+ import type { PendingConsent } from './credentials.ts';
42
+ export { CREDENTIAL_REQUEST, credentialResponsePart, describeConsent, pendingConsent } from './credentials.ts';
43
+ export type { PendingConsent } from './credentials.ts';
44
+ export type { ToolCredentials } from '../tools/oauthConsent.ts';
45
+ export { chooseRuntime, runtimeSetting, DEFAULT_RUNTIME, RUNTIMES, UnsupportedOnRuntimeError } from './runtimeFlag.ts';
46
+ export type { RuntimeName } from './runtimeFlag.ts';
31
47
  import type { PendingInput } from '../workflow.ts';
32
48
  export { describeInput } from '../workflow.ts';
33
49
  export type { PendingInput } from '../workflow.ts';
@@ -93,8 +109,15 @@ export interface SyndicateTurnOptions {
93
109
  memoryService?: BaseMemoryService;
94
110
  /** Model resolution, unknown-tool handling, nested loading. */
95
111
  compile?: CompileOptions;
96
- /** Applied to every compiled agent before it runs (eval tool replay). */
112
+ /** Applied to every compiled agent before it runs (eval tool replay). ADK runtime only. */
97
113
  transformAgent?: (agent: LlmAgent) => LlmAgent;
114
+ /**
115
+ * The runtime that runs the turn's agents: `adk` (Google ADK's Runner) or
116
+ * `native` (the engine's own loop). Default: MELCHIZEDEK_RUNTIME, else
117
+ * `adk`. A feature native does not run yet throws UnsupportedOnRuntimeError
118
+ * before any model call.
119
+ */
120
+ runtime?: RuntimeName;
98
121
  /** Plan-dispatch only: skip the classifier and run this route. Overrides
99
122
  * in the YAML still win, as they do in production. */
100
123
  forceRoute?: string;
@@ -109,6 +132,15 @@ export interface SyndicateTurnOptions {
109
132
  /** Root-span metadata; `false` disables tracing for the turn. */
110
133
  trace?: TraceOptions | false;
111
134
  events?: TurnEvents;
135
+ /**
136
+ * The turn's tool credentials (ADR 0072) and consent step (ADR 0085), on
137
+ * the native runtime. The store is pinned to `appName`; a tool reads the
138
+ * grant of `userId` only. With `consent`, a call whose provider the user
139
+ * has not granted pauses the turn input-required (`result.consent`), and
140
+ * the next message after the grant resumes it. Omitted: tools have no
141
+ * `accessToken`, as before.
142
+ */
143
+ toolCredentials?: ToolCredentials;
112
144
  }
113
145
  /** What one agent's event stream amounted to. */
114
146
  export interface DrainedRun {
@@ -159,8 +191,9 @@ export interface DrainedRun {
159
191
  export type TurnStage = 'classify' | 'dispatch' | 'delegate' | 'workflow';
160
192
  export interface RouteDecision extends RouteResolution {
161
193
  /** `approval`: the turn resumed the route that asked for an approval (ADR 0028).
162
- * `answer`: the message answered the route's open `ask_user` question. */
163
- decidedBy: 'override' | 'forced' | 'classifier' | 'approval' | 'answer';
194
+ * `answer`: the message answered the route's open `ask_user` question.
195
+ * `consent`: the turn resumed the route whose call waited for an OAuth grant (ADR 0085). */
196
+ decidedBy: 'override' | 'forced' | 'classifier' | 'approval' | 'answer' | 'consent';
164
197
  }
165
198
  export interface SyndicateTurnResult {
166
199
  /** completed: an answer was produced. failed: an error, a deadline or the
@@ -173,6 +206,10 @@ export interface SyndicateTurnResult {
173
206
  /** The question a workflow's `ask_user` node asked, when status is
174
207
  * input-required. The next message on the conversation is the answer. */
175
208
  input?: PendingInput;
209
+ /** The OAuth grant a paused call waits for, when status is input-required
210
+ * (ADR 0085): the person opens `consent.authUri`; their next message after
211
+ * the grant is stored resumes the call. */
212
+ consent?: PendingConsent;
176
213
  /** The text the user receives (relay fallback and guards applied). */
177
214
  text: string;
178
215
  error?: {
@@ -207,8 +244,7 @@ export interface TurnUsage {
207
244
  outputTokens: number;
208
245
  thinkingTokens: number;
209
246
  }
210
- export declare const DEFAULT_MODEL_ERROR_RETRIES = 2;
211
- export declare const DEFAULT_TOOL_ERROR_RETRIES = 3;
247
+ export { DEFAULT_MODEL_ERROR_RETRIES, DEFAULT_TOOL_ERROR_RETRIES } from './native/selfCorrection.ts';
212
248
  /**
213
249
  * ADK's reflect-and-retry plugins, on by default. The model plugin turns a
214
250
  * reply ADK marks malformed (MALFORMED_FUNCTION_CALL) into a retry with