melchizedek-agents 0.17.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 (290) hide show
  1. package/.env.example +35 -3
  2. package/AGENT_SETUP.md +2 -1
  3. package/CHANGELOG.md +929 -0
  4. package/DOCUMENTATION.md +290 -66
  5. package/README.md +42 -1
  6. package/config/agents/examples/harness.yaml +3 -1
  7. package/config/agents/examples/model_zoo.yaml +10 -9
  8. package/config/agents/syndicateSchema.yaml +63 -16
  9. package/config/agents/templates/account_memory.yaml +2 -6
  10. package/config/agents/templates/case_desk.yaml +3 -9
  11. package/config/agents/templates/draft_review.yaml +3 -9
  12. package/config/agents/templates/intake_extractor.yaml +1 -3
  13. package/config/agents/templates/research_brief.yaml +3 -9
  14. package/config/agents/templates/research_desk.yaml +3 -9
  15. package/config/agents/templates/review_panel.yaml +4 -12
  16. package/config/agents/templates/support_triage.yaml +4 -12
  17. package/config/agents/templates/systems_operator.yaml +2 -6
  18. package/db/hardening.sql +10 -3
  19. package/db/migrations/0012_audit_log.sql +98 -0
  20. package/db/migrations/0013_tool_credentials.sql +260 -0
  21. package/dist/lib/a2a/app.d.ts +90 -6
  22. package/dist/lib/a2a/app.js +201 -6
  23. package/dist/lib/a2a/executor.d.ts +54 -7
  24. package/dist/lib/a2a/executor.js +134 -16
  25. package/dist/lib/a2a/remoteAgent.d.ts +24 -9
  26. package/dist/lib/a2a/remoteAgent.js +31 -14
  27. package/dist/lib/compile.d.ts +121 -31
  28. package/dist/lib/compile.js +153 -113
  29. package/dist/lib/compileAdk.d.ts +29 -0
  30. package/dist/lib/compileAdk.js +132 -0
  31. package/dist/lib/compileNative.d.ts +85 -0
  32. package/dist/lib/compileNative.js +222 -0
  33. package/dist/lib/config.d.ts +13 -5
  34. package/dist/lib/config.js +13 -5
  35. package/dist/lib/doctor.js +1 -0
  36. package/dist/lib/index.d.ts +2 -1
  37. package/dist/lib/index.js +2 -1
  38. package/dist/lib/loadEnv.d.ts +5 -0
  39. package/dist/lib/loadEnv.js +7 -0
  40. package/dist/lib/loadSyndicate.d.ts +22 -0
  41. package/dist/lib/memory/erase.d.ts +5 -3
  42. package/dist/lib/memory/erase.js +5 -2
  43. package/dist/lib/memory/namespace.d.ts +8 -1
  44. package/dist/lib/memory/namespace.js +12 -6
  45. package/dist/lib/memory/providers.d.ts +27 -0
  46. package/dist/lib/memory/providers.js +30 -1
  47. package/dist/lib/memory/supabaseMemoryService.d.ts +37 -3
  48. package/dist/lib/memory/supabaseMemoryService.js +42 -2
  49. package/dist/lib/model.d.ts +47 -0
  50. package/dist/lib/model.js +37 -0
  51. package/dist/lib/models/adapterResolver.d.ts +113 -0
  52. package/dist/lib/models/adapterResolver.js +136 -0
  53. package/dist/lib/models/adkGeminiAdapter.d.ts +90 -0
  54. package/dist/lib/models/adkGeminiAdapter.js +367 -0
  55. package/dist/lib/models/adkShim.d.ts +111 -0
  56. package/dist/lib/models/adkShim.js +136 -0
  57. package/dist/lib/models/capabilities.d.ts +3 -0
  58. package/dist/lib/models/capabilities.js +20 -13
  59. package/dist/lib/models/chatCompletionsAdapter.d.ts +279 -0
  60. package/dist/lib/models/chatCompletionsAdapter.js +854 -0
  61. package/dist/lib/models/circuitBreaker.d.ts +42 -0
  62. package/dist/lib/models/circuitBreaker.js +70 -0
  63. package/dist/lib/models/claudeAdapter.d.ts +103 -0
  64. package/dist/lib/models/claudeAdapter.js +669 -0
  65. package/dist/lib/models/claudeLlm.d.ts +39 -62
  66. package/dist/lib/models/claudeLlm.js +44 -349
  67. package/dist/lib/models/claudeModels.d.ts +127 -0
  68. package/dist/lib/models/claudeModels.js +237 -0
  69. package/dist/lib/models/contract.d.ts +395 -0
  70. package/dist/lib/models/contract.js +39 -0
  71. package/dist/lib/models/endpoints.js +2 -1
  72. package/dist/lib/models/errorResponse.d.ts +50 -0
  73. package/dist/lib/models/errorResponse.js +48 -0
  74. package/dist/lib/models/fallback.d.ts +48 -0
  75. package/dist/lib/models/fallback.js +116 -0
  76. package/dist/lib/models/fallbackAdapter.d.ts +55 -0
  77. package/dist/lib/models/fallbackAdapter.js +62 -0
  78. package/dist/lib/models/gateway.js +2 -1
  79. package/dist/lib/models/gatewayAdapter.d.ts +51 -0
  80. package/dist/lib/models/gatewayAdapter.js +81 -0
  81. package/dist/lib/models/gatewayLlm.d.ts +12 -33
  82. package/dist/lib/models/gatewayLlm.js +14 -75
  83. package/dist/lib/models/geminiAdapter.d.ts +123 -0
  84. package/dist/lib/models/geminiAdapter.js +831 -0
  85. package/dist/lib/models/geminiState.d.ts +25 -0
  86. package/dist/lib/models/geminiState.js +25 -0
  87. package/dist/lib/models/genaiMapping.d.ts +263 -0
  88. package/dist/lib/models/genaiMapping.js +862 -0
  89. package/dist/lib/models/gptAdapter.d.ts +240 -0
  90. package/dist/lib/models/gptAdapter.js +804 -0
  91. package/dist/lib/models/gptLlm.d.ts +63 -123
  92. package/dist/lib/models/gptLlm.js +88 -602
  93. package/dist/lib/models/grokAdapter.d.ts +86 -0
  94. package/dist/lib/models/grokAdapter.js +142 -0
  95. package/dist/lib/models/grokLlm.d.ts +22 -45
  96. package/dist/lib/models/grokLlm.js +22 -67
  97. package/dist/lib/models/kimiAdapter.d.ts +157 -0
  98. package/dist/lib/models/kimiAdapter.js +203 -0
  99. package/dist/lib/models/kimiLlm.d.ts +15 -107
  100. package/dist/lib/models/kimiLlm.js +17 -153
  101. package/dist/lib/models/ollamaAdapter.d.ts +125 -0
  102. package/dist/lib/models/ollamaAdapter.js +155 -0
  103. package/dist/lib/models/ollamaLlm.d.ts +11 -107
  104. package/dist/lib/models/ollamaLlm.js +13 -151
  105. package/dist/lib/models/openAiCompatibleLlm.d.ts +73 -216
  106. package/dist/lib/models/openAiCompatibleLlm.js +109 -671
  107. package/dist/lib/models/providerState.d.ts +63 -0
  108. package/dist/lib/models/providerState.js +61 -0
  109. package/dist/lib/models/reasoning.d.ts +26 -0
  110. package/dist/lib/models/reasoning.js +59 -0
  111. package/dist/lib/models/registry.d.ts +58 -35
  112. package/dist/lib/models/registry.js +89 -118
  113. package/dist/lib/models/retry.d.ts +2 -1
  114. package/dist/lib/models/retry.js +3 -2
  115. package/dist/lib/models/schemaNormalize.d.ts +98 -0
  116. package/dist/lib/models/schemaNormalize.js +321 -1
  117. package/dist/lib/models/tracedGemini.d.ts +41 -0
  118. package/dist/lib/models/tracedGemini.js +98 -0
  119. package/dist/lib/models/urls.d.ts +11 -0
  120. package/dist/lib/models/urls.js +16 -0
  121. package/dist/lib/net/redirects.d.ts +21 -2
  122. package/dist/lib/net/redirects.js +11 -34
  123. package/dist/lib/observability/audit.d.ts +25 -0
  124. package/dist/lib/observability/audit.js +39 -0
  125. package/dist/lib/observability/lineage.d.ts +14 -0
  126. package/dist/lib/observability/lineage.js +33 -0
  127. package/dist/lib/observability/metrics.d.ts +6 -0
  128. package/dist/lib/observability/supabaseSpanExporter.d.ts +10 -4
  129. package/dist/lib/observability/supabaseSpanExporter.js +17 -9
  130. package/dist/lib/observability/tracer.d.ts +39 -8
  131. package/dist/lib/observability/tracer.js +59 -20
  132. package/dist/lib/runtime/adkMemoryBridge.d.ts +46 -0
  133. package/dist/lib/runtime/adkMemoryBridge.js +68 -0
  134. package/dist/lib/runtime/adkSessionBridge.d.ts +78 -0
  135. package/dist/lib/runtime/adkSessionBridge.js +176 -0
  136. package/dist/lib/runtime/credentials.d.ts +59 -0
  137. package/dist/lib/runtime/credentials.js +62 -0
  138. package/dist/lib/runtime/events.d.ts +229 -0
  139. package/dist/lib/runtime/events.js +274 -0
  140. package/dist/lib/runtime/logging.d.ts +32 -0
  141. package/dist/lib/runtime/logging.js +55 -0
  142. package/dist/lib/runtime/memoryService.d.ts +72 -0
  143. package/dist/lib/runtime/memoryService.js +25 -0
  144. package/dist/lib/runtime/native/agentLoop.d.ts +203 -0
  145. package/dist/lib/runtime/native/agentLoop.js +687 -0
  146. package/dist/lib/runtime/native/compaction.d.ts +103 -0
  147. package/dist/lib/runtime/native/compaction.js +191 -0
  148. package/dist/lib/runtime/native/delegate.d.ts +98 -0
  149. package/dist/lib/runtime/native/delegate.js +173 -0
  150. package/dist/lib/runtime/native/history.d.ts +83 -0
  151. package/dist/lib/runtime/native/history.js +312 -0
  152. package/dist/lib/runtime/native/interrupts.d.ts +126 -0
  153. package/dist/lib/runtime/native/interrupts.js +291 -0
  154. package/dist/lib/runtime/native/request.d.ts +215 -0
  155. package/dist/lib/runtime/native/request.js +585 -0
  156. package/dist/lib/runtime/native/selfCorrection.d.ts +106 -0
  157. package/dist/lib/runtime/native/selfCorrection.js +253 -0
  158. package/dist/lib/runtime/native/step.d.ts +148 -0
  159. package/dist/lib/runtime/native/step.js +239 -0
  160. package/dist/lib/runtime/native/taskMode.d.ts +64 -0
  161. package/dist/lib/runtime/native/taskMode.js +126 -0
  162. package/dist/lib/runtime/native/telemetry.d.ts +75 -0
  163. package/dist/lib/runtime/native/telemetry.js +299 -0
  164. package/dist/lib/runtime/native/tempState.d.ts +31 -0
  165. package/dist/lib/runtime/native/tempState.js +56 -0
  166. package/dist/lib/runtime/nativeTurn.d.ts +86 -0
  167. package/dist/lib/runtime/nativeTurn.js +107 -0
  168. package/dist/lib/runtime/questions.d.ts +29 -7
  169. package/dist/lib/runtime/questions.js +47 -32
  170. package/dist/lib/runtime/runtimeFlag.d.ts +30 -0
  171. package/dist/lib/runtime/runtimeFlag.js +50 -0
  172. package/dist/lib/runtime/sessions.d.ts +166 -0
  173. package/dist/lib/runtime/sessions.js +201 -0
  174. package/dist/lib/runtime/syndicateTurn.d.ts +44 -6
  175. package/dist/lib/runtime/syndicateTurn.js +205 -33
  176. package/dist/lib/session/supabaseSessionService.d.ts +64 -17
  177. package/dist/lib/session/supabaseSessionService.js +148 -105
  178. package/dist/lib/session/transcript.d.ts +68 -22
  179. package/dist/lib/session/transcript.js +102 -28
  180. package/dist/lib/skills.js +33 -7
  181. package/dist/lib/storage/postgres/credentialStore.d.ts +20 -0
  182. package/dist/lib/storage/postgres/credentialStore.js +82 -0
  183. package/dist/lib/storage/postgres/index.d.ts +15 -0
  184. package/dist/lib/storage/postgres/index.js +7 -0
  185. package/dist/lib/storage/postgres/sessionService.d.ts +43 -15
  186. package/dist/lib/storage/postgres/sessionService.js +128 -66
  187. package/dist/lib/syndicateSchema.d.ts +55 -0
  188. package/dist/lib/syndicateSchema.js +91 -7
  189. package/dist/lib/toolRegistry.d.ts +15 -2
  190. package/dist/lib/toolRegistry.js +33 -17
  191. package/dist/lib/tools/adkTool.d.ts +81 -0
  192. package/dist/lib/tools/adkTool.js +268 -0
  193. package/dist/lib/tools/auth.d.ts +118 -0
  194. package/dist/lib/tools/auth.js +89 -0
  195. package/dist/lib/tools/collectionsSearchTool.d.ts +7 -6
  196. package/dist/lib/tools/collectionsSearchTool.js +11 -26
  197. package/dist/lib/tools/credentialCipher.d.ts +58 -0
  198. package/dist/lib/tools/credentialCipher.js +116 -0
  199. package/dist/lib/tools/credentialStore.d.ts +77 -0
  200. package/dist/lib/tools/credentialStore.js +246 -0
  201. package/dist/lib/tools/examples.d.ts +43 -0
  202. package/dist/lib/tools/examples.js +62 -0
  203. package/dist/lib/tools/generateImageTool.d.ts +15 -6
  204. package/dist/lib/tools/generateImageTool.js +19 -29
  205. package/dist/lib/tools/inspectImageTool.d.ts +9 -6
  206. package/dist/lib/tools/inspectImageTool.js +13 -17
  207. package/dist/lib/tools/mcpToolFactory.d.ts +68 -1
  208. package/dist/lib/tools/mcpToolFactory.js +106 -50
  209. package/dist/lib/tools/memoryTools.d.ts +61 -0
  210. package/dist/lib/tools/memoryTools.js +119 -0
  211. package/dist/lib/tools/nativeTools.d.ts +38 -0
  212. package/dist/lib/tools/nativeTools.js +43 -0
  213. package/dist/lib/tools/oauthConsent.d.ts +181 -0
  214. package/dist/lib/tools/oauthConsent.js +330 -0
  215. package/dist/lib/tools/openapi/call.d.ts +108 -0
  216. package/dist/lib/tools/openapi/call.js +295 -0
  217. package/dist/lib/tools/openapi/parse.d.ts +147 -0
  218. package/dist/lib/tools/openapi/parse.js +570 -0
  219. package/dist/lib/tools/openapiTools.d.ts +31 -17
  220. package/dist/lib/tools/openapiTools.js +150 -117
  221. package/dist/lib/tools/scienceTools.d.ts +14 -14
  222. package/dist/lib/tools/skillToolset.d.ts +58 -87
  223. package/dist/lib/tools/skillToolset.js +61 -142
  224. package/dist/lib/tools/skills/env.d.ts +58 -0
  225. package/dist/lib/tools/skills/env.js +165 -0
  226. package/dist/lib/tools/skills/executor.d.ts +114 -0
  227. package/dist/lib/tools/skills/executor.js +331 -0
  228. package/dist/lib/tools/skills/frontmatter.d.ts +79 -0
  229. package/dist/lib/tools/skills/frontmatter.js +215 -0
  230. package/dist/lib/tools/skills/loader.d.ts +91 -0
  231. package/dist/lib/tools/skills/loader.js +257 -0
  232. package/dist/lib/tools/skills/tools.d.ts +187 -0
  233. package/dist/lib/tools/skills/tools.js +386 -0
  234. package/dist/lib/tools/taskTools.d.ts +15 -15
  235. package/dist/lib/tools/tool.d.ts +354 -0
  236. package/dist/lib/tools/tool.js +304 -0
  237. package/dist/lib/tools/toolContract.d.ts +89 -33
  238. package/dist/lib/tools/toolContract.js +104 -82
  239. package/dist/lib/tools/urlContextTool.d.ts +3 -0
  240. package/dist/lib/tools/urlContextTool.js +5 -1
  241. package/dist/lib/tools/webExtractTool.d.ts +2 -2
  242. package/dist/lib/tools/webExtractTool.js +2 -1
  243. package/dist/lib/tools/webSearchTool.d.ts +6 -9
  244. package/dist/lib/tools/webSearchTool.js +14 -59
  245. package/dist/lib/tools/wikiTools.d.ts +19 -19
  246. package/dist/lib/tools/wikiTools.js +13 -9
  247. package/dist/lib/tools/xApiSearchTool.d.ts +2 -2
  248. package/dist/lib/tools/xApiSearchTool.js +2 -1
  249. package/dist/lib/tools/xSearchTool.d.ts +7 -9
  250. package/dist/lib/tools/xSearchTool.js +11 -62
  251. package/dist/lib/tools/xaiSearchParams.d.ts +41 -0
  252. package/dist/lib/tools/xaiSearchParams.js +126 -0
  253. package/dist/lib/wiki/agentRun.d.ts +12 -0
  254. package/dist/lib/wiki/agentRun.js +72 -34
  255. package/dist/lib/wiki/entities.d.ts +12 -0
  256. package/dist/lib/wiki/entities.js +45 -3
  257. package/dist/lib/workflow/agentNode.d.ts +136 -0
  258. package/dist/lib/workflow/agentNode.js +274 -0
  259. package/dist/lib/workflow/graph.d.ts +177 -0
  260. package/dist/lib/workflow/graph.js +458 -0
  261. package/dist/lib/workflow/nodeEvents.d.ts +50 -0
  262. package/dist/lib/workflow/nodeEvents.js +101 -0
  263. package/dist/lib/workflow/pause.d.ts +122 -0
  264. package/dist/lib/workflow/pause.js +180 -0
  265. package/dist/lib/workflow/resume.d.ts +165 -0
  266. package/dist/lib/workflow/resume.js +440 -0
  267. package/dist/lib/workflow/route.d.ts +58 -0
  268. package/dist/lib/workflow/route.js +69 -0
  269. package/dist/lib/workflow/scheduler.d.ts +415 -0
  270. package/dist/lib/workflow/scheduler.js +743 -0
  271. package/dist/lib/workflow/toolNode.d.ts +127 -0
  272. package/dist/lib/workflow/toolNode.js +236 -0
  273. package/dist/lib/workflow/turn.d.ts +118 -0
  274. package/dist/lib/workflow/turn.js +216 -0
  275. package/dist/lib/workflowConfig.d.ts +3 -2
  276. package/dist/lib/workflowConfig.js +3 -12
  277. package/dist/scripts/a2a_server.js +55 -11
  278. package/dist/scripts/assistant_worker.d.ts +2 -1
  279. package/dist/scripts/assistant_worker.js +9 -4
  280. package/dist/scripts/db.d.ts +9 -0
  281. package/dist/scripts/db.js +30 -15
  282. package/dist/scripts/syndicate_chat.js +19 -10
  283. package/package.json +6 -3
  284. package/skills/briefs/melchizedek-author.md +3 -2
  285. package/skills/briefs/melchizedek-models.md +13 -9
  286. package/skills/briefs/melchizedek.md +3 -3
  287. package/skills/melchizedek/SKILL.md +2 -1
  288. package/skills/melchizedek-author/SKILL.md +2 -1
  289. package/skills/melchizedek-author/assets/minimal.yaml +2 -0
  290. package/skills/melchizedek-models/SKILL.md +23 -6
@@ -0,0 +1,103 @@
1
+ /**
2
+ * lib/runtime/native/compaction.ts — context compaction on the native loop:
3
+ * the YAML's `context:` block, run as ADK runs it (ADR 0033, ADR 0045).
4
+ *
5
+ * WHY this file exists:
6
+ * On the ADK runtime `context:` compiles to ADK's TokenBasedContextCompactor
7
+ * with an LlmSummarizer (lib/compile.ts), which ADK's
8
+ * ContextCompactorRequestProcessor runs before every model step of the
9
+ * agent. A session either runtime wrote must be one the other continues,
10
+ * so this is that compactor and that summarizer, rule for rule
11
+ * (context/token_based_context_compactor.js, context/compaction_utils.js
12
+ * and context/summarizers/llm_summarizer.js in @google/adk 2.2), and the
13
+ * event it stores is the one ADK stores:
14
+ *
15
+ * - WHEN. Before each model step, over the session's active events (the
16
+ * latest compaction and what follows it, in the run's isolation scope).
17
+ * The raw events (compactions aside) must number more than
18
+ * `keep_recent_events`, and the cut must leave something to summarize:
19
+ * the cut starts `keep_recent_events` from the end and moves back while
20
+ * it would separate a call from its answer. Then the prompt size must
21
+ * pass `compact_after_tokens`: the latest active event's
22
+ * usageMetadata.promptTokenCount, or, when no event carries one, the
23
+ * characters of the agent's projected history (text, and each call and
24
+ * answer as JSON) divided by 4, rounded up.
25
+ * - WHAT IS SUMMARIZED. The raw events before the cut, after the active
26
+ * compaction when there is one, so a later summary folds the earlier in.
27
+ * - THE CALL. One user message: ADK's default prompt, a blank line, then
28
+ * per event `[Event i - Author: <author>]`, its text (thoughts aside) and
29
+ * a blank line. No system prompt, no tools, not streamed. It goes to
30
+ * `summary_model` (default the agent's own model), as a leaf adapter
31
+ * with no fallback, through traceLlmGeneration as the shim calls it: the
32
+ * llm.request span, under the agent span and outside any model.call,
33
+ * and the turn's charge (ADR 0053, ADR 0076). The summary is the first
34
+ * response's first part's text and each later response's; a first
35
+ * response with no text throws "LLM failed to return a valid summary.",
36
+ * as ADK does, and the turn fails.
37
+ * - THE EVENT. author `system`, no invocation id, content `{ role: model,
38
+ * parts: [{ text: summary }] }`, `isCompacted: true`, `startTime` and
39
+ * `endTime` (the first and last summarized events' timestamps),
40
+ * `compactedContent`, and the run's isolation scope. The loop appends it
41
+ * before the step, so the step's request already reads it: the history
42
+ * builder (lib/runtime/native/history.ts) puts
43
+ * "[Previous Context Summary]:\n<summary>" in place of the events up to
44
+ * `endTime`. The full history stays stored.
45
+ *
46
+ * NOT PORTED: ADK's before/after context-compaction plugin hooks. No plugin
47
+ * the engine installs implements them.
48
+ */
49
+ import type { ModelAdapter, ModelRequest } from '../../models/contract.ts';
50
+ import type { TurnEvent } from '../events.ts';
51
+ import type { Session } from '../sessions.ts';
52
+ import type { CompactedEvent } from './history.ts';
53
+ /** An agent's `context:` block, in the YAML's spelling (ADR 0033). */
54
+ export interface ContextConfig {
55
+ /** Compact when the last request's prompt passed this many tokens. */
56
+ compact_after_tokens: number;
57
+ /** Events kept verbatim after the summary. Default 6. */
58
+ keep_recent_events?: number;
59
+ /** The model that writes the summary. Default: the agent's own. */
60
+ summary_model?: string;
61
+ }
62
+ export declare const DEFAULT_KEEP_RECENT_EVENTS = 6;
63
+ /** ADK's LlmSummarizer default prompt, which compile's summarizer uses. */
64
+ export declare const SUMMARY_PROMPT = "The following is a conversation history between a user and an AI agent. Please summarize the conversation, focusing on key information and decisions made, as well as any unresolved questions or tasks. The summary should be concise and capture the essence of the interaction.";
65
+ /** ADK's message when the summarizer's first response has no text. */
66
+ export declare const SUMMARY_FAILED = "LLM failed to return a valid summary.";
67
+ /** Where the agent stands when it compacts. */
68
+ export interface CompactionScope {
69
+ agentName: string;
70
+ session: Session;
71
+ branch?: string;
72
+ isolationScope?: string;
73
+ }
74
+ /** Where the verbatim tail starts: `keep` from the end, moved back so no answer loses its call. */
75
+ export declare function retainStartIndex(raw: readonly TurnEvent[], keep: number): number;
76
+ /**
77
+ * The events a compaction would summarize now (the active compaction first,
78
+ * when there is one), or undefined when the agent should not compact.
79
+ */
80
+ export declare function eventsToCompact(config: ContextConfig, scope: CompactionScope): TurnEvent[] | undefined;
81
+ /** The one request the summarizer sends, as the shim maps ADK's LlmRequest for it. */
82
+ export declare function summaryRequest(events: readonly TurnEvent[], model: string, signal?: AbortSignal): ModelRequest;
83
+ /**
84
+ * Summarizes `events` with `adapter` under `model` and returns the
85
+ * compacted event (not stored). Charged and traced as one model call.
86
+ * Throws SUMMARY_FAILED when the first response carries no text.
87
+ */
88
+ export declare function summarize(events: readonly TurnEvent[], adapter: ModelAdapter, model: string, options?: {
89
+ signal?: AbortSignal;
90
+ isolationScope?: string;
91
+ }): Promise<CompactedEvent>;
92
+ /**
93
+ * Before a model step: the compacted event when the agent's `context:` says
94
+ * to compact now, else undefined. The caller stores it before the step.
95
+ */
96
+ export declare function compactBeforeStep(agent: {
97
+ name: string;
98
+ model: string;
99
+ context?: ContextConfig;
100
+ }, scope: Omit<CompactionScope, 'agentName'> & {
101
+ adapterFor: (model: string) => ModelAdapter;
102
+ signal?: AbortSignal;
103
+ }): Promise<CompactedEvent | undefined>;
@@ -0,0 +1,191 @@
1
+ /**
2
+ * lib/runtime/native/compaction.ts — context compaction on the native loop:
3
+ * the YAML's `context:` block, run as ADK runs it (ADR 0033, ADR 0045).
4
+ *
5
+ * WHY this file exists:
6
+ * On the ADK runtime `context:` compiles to ADK's TokenBasedContextCompactor
7
+ * with an LlmSummarizer (lib/compile.ts), which ADK's
8
+ * ContextCompactorRequestProcessor runs before every model step of the
9
+ * agent. A session either runtime wrote must be one the other continues,
10
+ * so this is that compactor and that summarizer, rule for rule
11
+ * (context/token_based_context_compactor.js, context/compaction_utils.js
12
+ * and context/summarizers/llm_summarizer.js in @google/adk 2.2), and the
13
+ * event it stores is the one ADK stores:
14
+ *
15
+ * - WHEN. Before each model step, over the session's active events (the
16
+ * latest compaction and what follows it, in the run's isolation scope).
17
+ * The raw events (compactions aside) must number more than
18
+ * `keep_recent_events`, and the cut must leave something to summarize:
19
+ * the cut starts `keep_recent_events` from the end and moves back while
20
+ * it would separate a call from its answer. Then the prompt size must
21
+ * pass `compact_after_tokens`: the latest active event's
22
+ * usageMetadata.promptTokenCount, or, when no event carries one, the
23
+ * characters of the agent's projected history (text, and each call and
24
+ * answer as JSON) divided by 4, rounded up.
25
+ * - WHAT IS SUMMARIZED. The raw events before the cut, after the active
26
+ * compaction when there is one, so a later summary folds the earlier in.
27
+ * - THE CALL. One user message: ADK's default prompt, a blank line, then
28
+ * per event `[Event i - Author: <author>]`, its text (thoughts aside) and
29
+ * a blank line. No system prompt, no tools, not streamed. It goes to
30
+ * `summary_model` (default the agent's own model), as a leaf adapter
31
+ * with no fallback, through traceLlmGeneration as the shim calls it: the
32
+ * llm.request span, under the agent span and outside any model.call,
33
+ * and the turn's charge (ADR 0053, ADR 0076). The summary is the first
34
+ * response's first part's text and each later response's; a first
35
+ * response with no text throws "LLM failed to return a valid summary.",
36
+ * as ADK does, and the turn fails.
37
+ * - THE EVENT. author `system`, no invocation id, content `{ role: model,
38
+ * parts: [{ text: summary }] }`, `isCompacted: true`, `startTime` and
39
+ * `endTime` (the first and last summarized events' timestamps),
40
+ * `compactedContent`, and the run's isolation scope. The loop appends it
41
+ * before the step, so the step's request already reads it: the history
42
+ * builder (lib/runtime/native/history.ts) puts
43
+ * "[Previous Context Summary]:\n<summary>" in place of the events up to
44
+ * `endTime`. The full history stays stored.
45
+ *
46
+ * NOT PORTED: ADK's before/after context-compaction plugin hooks. No plugin
47
+ * the engine installs implements them.
48
+ */
49
+ import { llmRequestToModelRequest, modelResponseToLlmResponse } from '../../models/genaiMapping.js';
50
+ import { traceLlmGeneration } from '../../observability/tracer.js';
51
+ import { createTurnEvent, getFunctionCalls, getFunctionResponses } from '../events.js';
52
+ import { activeEvents, contentsOf, isCompacted } from './history.js';
53
+ export const DEFAULT_KEEP_RECENT_EVENTS = 6;
54
+ /** ADK's LlmSummarizer default prompt, which compile's summarizer uses. */
55
+ export const SUMMARY_PROMPT = 'The following is a conversation history between a user and an AI agent. Please summarize the conversation, focusing on key information and decisions made, as well as any unresolved questions or tasks. The summary should be concise and capture the essence of the interaction.';
56
+ /** ADK's message when the summarizer's first response has no text. */
57
+ export const SUMMARY_FAILED = 'LLM failed to return a valid summary.';
58
+ const CHARS_PER_TOKEN = 4;
59
+ // ── When (ADK's shouldCompact) ───────────────────────────────────────────────
60
+ /** Where the verbatim tail starts: `keep` from the end, moved back so no answer loses its call. */
61
+ export function retainStartIndex(raw, keep) {
62
+ let start = Math.max(0, raw.length - keep);
63
+ while (start > 0) {
64
+ if (getFunctionResponses(raw[start]).length > 0 && getFunctionCalls(raw[start - 1]).length > 0)
65
+ start--;
66
+ else
67
+ break;
68
+ }
69
+ return start;
70
+ }
71
+ /** The latest prompt token count an active event carries, else the estimate from the projected history. */
72
+ function promptTokens(active, scope) {
73
+ for (let i = active.length - 1; i >= 0; i--) {
74
+ const count = active[i]?.usageMetadata?.promptTokenCount;
75
+ if (count !== undefined)
76
+ return count;
77
+ }
78
+ // ADK estimates from getContents with no isolation scope: scoped events count for nothing here.
79
+ let chars = 0;
80
+ for (const content of contentsOf(active, scope.agentName, scope.branch, undefined)) {
81
+ for (const part of content.parts ?? []) {
82
+ if (part.text)
83
+ chars += part.text.length;
84
+ if (part.functionCall)
85
+ chars += JSON.stringify(part.functionCall).length;
86
+ if (part.functionResponse)
87
+ chars += JSON.stringify(part.functionResponse).length;
88
+ }
89
+ }
90
+ return chars <= 0 ? undefined : Math.ceil(chars / CHARS_PER_TOKEN);
91
+ }
92
+ /**
93
+ * The events a compaction would summarize now (the active compaction first,
94
+ * when there is one), or undefined when the agent should not compact.
95
+ */
96
+ export function eventsToCompact(config, scope) {
97
+ const keep = config.keep_recent_events ?? DEFAULT_KEEP_RECENT_EVENTS;
98
+ const active = activeEvents(scope.session.events, scope.isolationScope);
99
+ const raw = active.filter((e) => !isCompacted(e));
100
+ if (raw.length <= keep)
101
+ return undefined;
102
+ const start = retainStartIndex(raw, keep);
103
+ if (start === 0)
104
+ return undefined;
105
+ const tokens = promptTokens(active, scope);
106
+ if (tokens === undefined || tokens <= config.compact_after_tokens)
107
+ return undefined;
108
+ const present = active.find(isCompacted);
109
+ const cut = raw.slice(0, start);
110
+ return present ? [present, ...cut] : cut;
111
+ }
112
+ // ── The summary (ADK's LlmSummarizer) ────────────────────────────────────────
113
+ /** An event's text, thoughts aside (ADK's stringifyContent). */
114
+ function textOf(event) {
115
+ const parts = event.content?.parts;
116
+ if (!parts)
117
+ return '';
118
+ return parts
119
+ .filter((p) => !p.thought)
120
+ .map((p) => p.text ?? '')
121
+ .join('');
122
+ }
123
+ /** The one request the summarizer sends, as the shim maps ADK's LlmRequest for it. */
124
+ export function summaryRequest(events, model, signal) {
125
+ let formatted = '';
126
+ events.forEach((event, i) => {
127
+ formatted += `[Event ${i + 1} - Author: ${event.author}]\n`;
128
+ formatted += `${textOf(event)}\n\n`;
129
+ });
130
+ const llmRequest = {
131
+ contents: [{ role: 'user', parts: [{ text: `${SUMMARY_PROMPT}\n\n${formatted}` }] }],
132
+ toolsDict: {},
133
+ liveConnectConfig: {},
134
+ };
135
+ return llmRequestToModelRequest(llmRequest, { model, stream: false, ...(signal ? { signal } : {}) });
136
+ }
137
+ /**
138
+ * Summarizes `events` with `adapter` under `model` and returns the
139
+ * compacted event (not stored). Charged and traced as one model call.
140
+ * Throws SUMMARY_FAILED when the first response carries no text.
141
+ */
142
+ export async function summarize(events, adapter, model, options = {}) {
143
+ if (events.length === 0)
144
+ throw new Error('Cannot summarize an empty list of events.');
145
+ const startTime = events[0].timestamp;
146
+ const endTime = events[events.length - 1].timestamp;
147
+ const request = summaryRequest(events, model, options.signal);
148
+ async function* inner() {
149
+ for await (const response of adapter.generate(request))
150
+ yield modelResponseToLlmResponse(response);
151
+ }
152
+ const responses = traceLlmGeneration({ provider: adapter.provider, model, request }, inner());
153
+ // As ADK: the first response must carry text; nothing after a failure is read.
154
+ const first = await responses.next();
155
+ const head = first.done ? undefined : first.value.content?.parts?.[0]?.text;
156
+ if (!head)
157
+ throw new Error(SUMMARY_FAILED);
158
+ let summary = head;
159
+ for await (const chunk of responses) {
160
+ const text = chunk.content?.parts?.[0]?.text;
161
+ if (text)
162
+ summary += text;
163
+ }
164
+ const event = {
165
+ ...createTurnEvent({ author: 'system', content: { role: 'model', parts: [{ text: summary }] } }),
166
+ isCompacted: true,
167
+ startTime,
168
+ endTime,
169
+ compactedContent: summary,
170
+ };
171
+ if (options.isolationScope !== undefined)
172
+ event.isolationScope = options.isolationScope;
173
+ return event;
174
+ }
175
+ // ── The loop's hook ──────────────────────────────────────────────────────────
176
+ /**
177
+ * Before a model step: the compacted event when the agent's `context:` says
178
+ * to compact now, else undefined. The caller stores it before the step.
179
+ */
180
+ export async function compactBeforeStep(agent, scope) {
181
+ if (!agent.context)
182
+ return undefined;
183
+ const events = eventsToCompact(agent.context, { ...scope, agentName: agent.name });
184
+ if (!events)
185
+ return undefined;
186
+ const model = agent.context.summary_model ?? agent.model;
187
+ return summarize(events, scope.adapterFor(model), model, {
188
+ ...(scope.signal ? { signal: scope.signal } : {}),
189
+ ...(scope.isolationScope !== undefined ? { isolationScope: scope.isolationScope } : {}),
190
+ });
191
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * lib/runtime/native/delegate.ts — delegation on the native loop: a
3
+ * subagent runs as a tool, with its own child loop (WS2-6, ADR 0074).
4
+ *
5
+ * WHY this file exists:
6
+ * A DELEGATE syndicate (lib/compile.ts) lists each subagent on its
7
+ * orchestrator as ADK's AgentTool. The native loop (agentLoop.ts) runs
8
+ * the same delegation without ADK, and a session either runtime wrote must
9
+ * be one the other continues, so a delegated call stores what ADK's
10
+ * AgentTool stores, ids and times aside. tests/nativeDelegate.test.ts runs
11
+ * the boundary suite's delegation cases, a nested syndicate and the
12
+ * council example both ways and compares every session.
13
+ *
14
+ * ONE CALL, AS ADK'S AgentTool RUNS IT:
15
+ * 1. The message: `{ role: 'user', parts: [{ text: args.request }] }`.
16
+ * 2. The subagent's session: the one under the subagent's own name as the
17
+ * app name, with the caller's user id and session id. It is created on
18
+ * the first call, with the caller's state as it stands (the session's,
19
+ * then this call's writes; `temp:` keys dropped), and kept: a later
20
+ * call, in this turn or another, continues it. This is not a branch of
21
+ * the caller's session; ADK's AgentTool runs a Runner of its own.
22
+ * 3. A turn already stopped answers an empty text, before or after the
23
+ * message is stored.
24
+ * 4. The message is stored as a user event under a fresh invocation id
25
+ * (`e-<uuid>`), and the subagent runs on runAgentLoop as the root of
26
+ * its run: not streamed, under the turn's controls and signal (its
27
+ * calls count toward max_steps), with the caller's memory.
28
+ * 5. Each event the child stores has its stateDelta, `temp:` keys aside,
29
+ * written into the call's own state delta, so it lands on the caller's
30
+ * response event. Once the turn has stopped, ADK's Runner yields no
31
+ * more events: the answer is read from the last one it yielded.
32
+ * 6. The answer is the last event's text: its non-thought text parts
33
+ * joined by a newline, or '' when it has no parts. With an output
34
+ * schema it is parsed as JSON; text that does not parse fails the call
35
+ * with the parser's message, as on ADK.
36
+ *
37
+ * A PAUSE INSIDE A SUBAGENT (an ask_user call, an approval request) cannot
38
+ * reach the caller, exactly as under ADK (ADR 0028): the child run ends
39
+ * paused, its last event carries no text, the call answers '', and the gated
40
+ * tool never runs. WS6-2a lifts this.
41
+ *
42
+ * Calls to subagents in one step run one after another, in call order, as
43
+ * ADK runs them; running them concurrently is WS6.
44
+ *
45
+ * NESTED SYNDICATES: a `yaml_reference` subagent is the nested syndicate's
46
+ * orchestrator, named as the entry, listing its own subagent tools. It runs
47
+ * here like any subagent, and its own delegations open sessions under their
48
+ * own names, as on ADK.
49
+ *
50
+ * The DELEGATE relay fallback (an orchestrator that echoes a tool name or
51
+ * says nothing) stays in lib/runtime/syndicateTurn.ts: it reads the drained
52
+ * run, whichever runtime produced it.
53
+ *
54
+ * ADK stays out of this file: an ADK AgentTool is recognized by ADK's global
55
+ * symbol only to refuse it, with a message naming what to list instead.
56
+ */
57
+ import type { Tool, ToolContext } from '../../tools/tool.ts';
58
+ import type { TurnEvent } from '../events.ts';
59
+ import type { AgentLoopContext, AgentLoopEnd } from './agentLoop.ts';
60
+ import type { NativeAgent } from './request.ts';
61
+ /** Where a subagent tool keeps the agent it runs. A global symbol, so a second copy of this module still finds it. */
62
+ export declare const SUBAGENT: unique symbol;
63
+ /** A subagent listed on its caller as a tool: the declaration ADK's AgentTool gives it, and the agent the call runs. */
64
+ export interface SubagentTool extends Tool {
65
+ readonly [SUBAGENT]: NativeAgent;
66
+ }
67
+ /**
68
+ * `agent` as a tool its caller lists, as lib/compile.ts lists a subagent as
69
+ * an AgentTool: named for the agent, described by its description, taking
70
+ * one string `request`. Only the native loop runs it.
71
+ */
72
+ export declare function subagentTool(agent: NativeAgent): SubagentTool;
73
+ /**
74
+ * The agent a delegated call runs: the one a subagent tool (or anything
75
+ * carrying SUBAGENT) holds, else undefined. Throws for an ADK AgentTool that
76
+ * carries none: its LlmAgent cannot run on the native loop.
77
+ */
78
+ export declare function subagentOf(tool: unknown): NativeAgent | undefined;
79
+ /** What a delegated call needs from its caller's step. */
80
+ export interface DelegationScope {
81
+ /** The caller's loop context: its session, store, adapters, memory, signal. */
82
+ ctx: AgentLoopContext;
83
+ /** The caller's session state as the step left it. */
84
+ stateBase: Readonly<Record<string, unknown>>;
85
+ /** The turn's signal, as the step sent it. */
86
+ signal?: AbortSignal;
87
+ /** The loop the child runs on (agentLoop.ts passes its own runAgentLoop). */
88
+ runLoop: (agent: NativeAgent, ctx: AgentLoopContext) => AsyncGenerator<TurnEvent, AgentLoopEnd>;
89
+ /** Calls sharing this key run one after another (agentLoop.ts passes the step's scope). */
90
+ queue: object;
91
+ }
92
+ /**
93
+ * Runs one delegated call: `agent` on its own session with the call's
94
+ * `request` as its message, the child's state writes recorded in `context`.
95
+ * Resolves to the call's result: the subagent's answer, '' for none. Throws what the child run
96
+ * throws, and for an output-schema answer that does not parse.
97
+ */
98
+ export declare function runSubagent(agent: NativeAgent, args: Record<string, unknown>, context: ToolContext, scope: DelegationScope): Promise<unknown>;
@@ -0,0 +1,173 @@
1
+ /**
2
+ * lib/runtime/native/delegate.ts — delegation on the native loop: a
3
+ * subagent runs as a tool, with its own child loop (WS2-6, ADR 0074).
4
+ *
5
+ * WHY this file exists:
6
+ * A DELEGATE syndicate (lib/compile.ts) lists each subagent on its
7
+ * orchestrator as ADK's AgentTool. The native loop (agentLoop.ts) runs
8
+ * the same delegation without ADK, and a session either runtime wrote must
9
+ * be one the other continues, so a delegated call stores what ADK's
10
+ * AgentTool stores, ids and times aside. tests/nativeDelegate.test.ts runs
11
+ * the boundary suite's delegation cases, a nested syndicate and the
12
+ * council example both ways and compares every session.
13
+ *
14
+ * ONE CALL, AS ADK'S AgentTool RUNS IT:
15
+ * 1. The message: `{ role: 'user', parts: [{ text: args.request }] }`.
16
+ * 2. The subagent's session: the one under the subagent's own name as the
17
+ * app name, with the caller's user id and session id. It is created on
18
+ * the first call, with the caller's state as it stands (the session's,
19
+ * then this call's writes; `temp:` keys dropped), and kept: a later
20
+ * call, in this turn or another, continues it. This is not a branch of
21
+ * the caller's session; ADK's AgentTool runs a Runner of its own.
22
+ * 3. A turn already stopped answers an empty text, before or after the
23
+ * message is stored.
24
+ * 4. The message is stored as a user event under a fresh invocation id
25
+ * (`e-<uuid>`), and the subagent runs on runAgentLoop as the root of
26
+ * its run: not streamed, under the turn's controls and signal (its
27
+ * calls count toward max_steps), with the caller's memory.
28
+ * 5. Each event the child stores has its stateDelta, `temp:` keys aside,
29
+ * written into the call's own state delta, so it lands on the caller's
30
+ * response event. Once the turn has stopped, ADK's Runner yields no
31
+ * more events: the answer is read from the last one it yielded.
32
+ * 6. The answer is the last event's text: its non-thought text parts
33
+ * joined by a newline, or '' when it has no parts. With an output
34
+ * schema it is parsed as JSON; text that does not parse fails the call
35
+ * with the parser's message, as on ADK.
36
+ *
37
+ * A PAUSE INSIDE A SUBAGENT (an ask_user call, an approval request) cannot
38
+ * reach the caller, exactly as under ADK (ADR 0028): the child run ends
39
+ * paused, its last event carries no text, the call answers '', and the gated
40
+ * tool never runs. WS6-2a lifts this.
41
+ *
42
+ * Calls to subagents in one step run one after another, in call order, as
43
+ * ADK runs them; running them concurrently is WS6.
44
+ *
45
+ * NESTED SYNDICATES: a `yaml_reference` subagent is the nested syndicate's
46
+ * orchestrator, named as the entry, listing its own subagent tools. It runs
47
+ * here like any subagent, and its own delegations open sessions under their
48
+ * own names, as on ADK.
49
+ *
50
+ * The DELEGATE relay fallback (an orchestrator that echoes a tool name or
51
+ * says nothing) stays in lib/runtime/syndicateTurn.ts: it reads the drained
52
+ * run, whichever runtime produced it.
53
+ *
54
+ * ADK stays out of this file: an ADK AgentTool is recognized by ADK's global
55
+ * symbol only to refuse it, with a message naming what to list instead.
56
+ */
57
+ import { randomUUID } from 'node:crypto';
58
+ import { createTurnEvent } from '../events.js';
59
+ import { TEMP_STATE_PREFIX } from '../sessions.js';
60
+ import { SelfCorrection } from './selfCorrection.js';
61
+ // ── The subagent tool ────────────────────────────────────────────────────────
62
+ /** Where a subagent tool keeps the agent it runs. A global symbol, so a second copy of this module still finds it. */
63
+ export const SUBAGENT = Symbol.for('melchizedek.subagent');
64
+ /** ADK's own mark on an AgentTool (agent_tool.js). */
65
+ const ADK_AGENT_TOOL = Symbol.for('google.adk.agentTool');
66
+ /**
67
+ * `agent` as a tool its caller lists, as lib/compile.ts lists a subagent as
68
+ * an AgentTool: named for the agent, described by its description, taking
69
+ * one string `request`. Only the native loop runs it.
70
+ */
71
+ export function subagentTool(agent) {
72
+ return {
73
+ name: agent.name,
74
+ [SUBAGENT]: agent,
75
+ declaration: () => ({
76
+ name: agent.name,
77
+ description: agent.description ?? '',
78
+ parameters: { type: 'object', properties: { request: { type: 'string' } }, required: ['request'] },
79
+ }),
80
+ execute: async () => {
81
+ throw new Error(`${agent.name}: a subagent tool runs only on the native loop (lib/runtime/native/agentLoop.ts)`);
82
+ },
83
+ };
84
+ }
85
+ /**
86
+ * The agent a delegated call runs: the one a subagent tool (or anything
87
+ * carrying SUBAGENT) holds, else undefined. Throws for an ADK AgentTool that
88
+ * carries none: its LlmAgent cannot run on the native loop.
89
+ */
90
+ export function subagentOf(tool) {
91
+ if (!tool || typeof tool !== 'object')
92
+ return undefined;
93
+ const agent = tool[SUBAGENT];
94
+ if (agent && typeof agent === 'object')
95
+ return agent;
96
+ if (tool[ADK_AGENT_TOOL] === true) {
97
+ const name = tool.name;
98
+ throw new Error(`${String(name)}: an ADK AgentTool cannot run on the native loop; list subagentTool(agent) (lib/runtime/native/delegate.ts)`);
99
+ }
100
+ return undefined;
101
+ }
102
+ const queues = new WeakMap();
103
+ /** Runs `run` after every earlier call queued under `key`, whether it succeeded or not. */
104
+ function inTurn(key, run) {
105
+ const before = queues.get(key) ?? Promise.resolve();
106
+ const mine = before.then(run, run);
107
+ queues.set(key, mine.then(() => undefined, () => undefined));
108
+ return mine;
109
+ }
110
+ /** ADK's AgentTool answer: the last event's non-thought text, joined by a newline. */
111
+ function answerOf(agent, last) {
112
+ const parts = last?.content?.parts;
113
+ if (!parts?.length)
114
+ return '';
115
+ const text = parts
116
+ .filter((p) => !p.thought)
117
+ .map((p) => p.text)
118
+ .filter((t) => t)
119
+ .join('\n');
120
+ return agent.outputSchema ? JSON.parse(text) : text;
121
+ }
122
+ /**
123
+ * Runs one delegated call: `agent` on its own session with the call's
124
+ * `request` as its message, the child's state writes recorded in `context`.
125
+ * Resolves to the call's result: the subagent's answer, '' for none. Throws what the child run
126
+ * throws, and for an output-schema answer that does not parse.
127
+ */
128
+ export function runSubagent(agent, args, context, scope) {
129
+ return inTurn(scope.queue, () => runChild(agent, args, context, scope));
130
+ }
131
+ async function runChild(agent, args, context, scope) {
132
+ const { ctx, signal } = scope;
133
+ const { sessions } = ctx;
134
+ const parent = ctx.session;
135
+ const content = { role: 'user', parts: [{ text: args.request }] };
136
+ const key = { appName: agent.name, userId: parent.userId, sessionId: parent.id };
137
+ const session = (await sessions.get(key)) ?? (await sessions.create({ ...key, state: { ...scope.stateBase, ...context.stateDelta } }));
138
+ if (signal?.aborted)
139
+ return '';
140
+ const invocationId = `e-${randomUUID()}`;
141
+ await sessions.append(session, createTurnEvent({ invocationId, author: 'user', content }));
142
+ if (signal?.aborted)
143
+ return '';
144
+ const loop = scope.runLoop(agent, {
145
+ session,
146
+ sessions,
147
+ invocationId,
148
+ userContent: content,
149
+ stream: false,
150
+ // ADK's AgentTool builds its sub-runner without the reflect-and-retry
151
+ // plugins, so a subagent's own errors are not retried (ADR 0075).
152
+ selfCorrection: new SelfCorrection({ model_errors: 0, tool_errors: 0 }),
153
+ ...(ctx.memory ? { memory: ctx.memory } : {}),
154
+ // The parent's grants, pinned to the root's app (ADR 0072). Not its consent step: a subagent's
155
+ // pause would end inside the call, as ADK's AgentTool swallows it (ADR 0085).
156
+ ...(ctx.credentials ? { credentials: ctx.credentials } : {}),
157
+ ...(ctx.signal ? { signal: ctx.signal } : {}),
158
+ ...(ctx.adapterFor ? { adapterFor: ctx.adapterFor } : {}),
159
+ ...(ctx.log ? { log: ctx.log } : {}),
160
+ });
161
+ let last;
162
+ for await (const event of loop) {
163
+ // ADK's Runner stops yielding once the turn stopped: the answer is the last event it yielded.
164
+ if (signal?.aborted)
165
+ break;
166
+ for (const [k, v] of Object.entries(event.actions?.stateDelta ?? {})) {
167
+ if (!k.startsWith(TEMP_STATE_PREFIX))
168
+ context.state.set(k, v);
169
+ }
170
+ last = event;
171
+ }
172
+ return answerOf(agent, last);
173
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * lib/runtime/native/history.ts — which stored events a native model call
3
+ * sees, and in what form (ADR 0045, ADR 0066).
4
+ *
5
+ * WHY this file exists:
6
+ * A model request's history is the session's events projected for one
7
+ * agent: its own turns as they are, the person's words as they are,
8
+ * another agent's turns retold as context, approvals and credential
9
+ * requests left out, and a tool's late answer moved next to the call it
10
+ * answers. ADK's content processor does this on the ADK runtime
11
+ * (agents/processors/content_processor_utils.js in @google/adk 2.2), and a
12
+ * session one runtime wrote must read the same on the other, so this is
13
+ * that processor, rule for rule, over TurnEvents:
14
+ *
15
+ * - includeContents `default`: every visible event; `none`: from the
16
+ * latest message by the person or by another agent, reaching back to
17
+ * the calls its tool answers answer (getCurrentTurnContents).
18
+ * - Skipped: an event with no role, or whose first part is empty text; an
19
+ * event on another branch (a branch that is not a prefix of this one);
20
+ * an event in another isolation scope; ADK's credential, confirmation
21
+ * and input-request calls and answers.
22
+ * - Another agent's event becomes a user message: "For context:", then
23
+ * `[name] said: …`, `[name] called tool …`, `[name] tool … returned
24
+ * result: …`, any other part copied.
25
+ * - The latest compaction summary stands in for the events it covers, as
26
+ * "[Previous Context Summary]:\n<summary>".
27
+ * - The answer to the latest call is merged and moved next to that call;
28
+ * an earlier call's answers likewise.
29
+ * - ADK's own call ids (`adk-…`) are removed: the provider never sees them.
30
+ * The contents are deep copies, so nothing here changes a stored event.
31
+ *
32
+ * The result is genai-shaped content, as stored. The request builder maps it
33
+ * to the model contract through lib/models/genaiMapping.ts, the same mapping
34
+ * the ADK shim applies, so both runtimes hand an adapter the same messages.
35
+ */
36
+ import type { TurnContent, TurnEvent } from '../events.ts';
37
+ /** ADK prefixes the call ids it makes with this (AF_FUNCTION_CALL_ID_PREFIX). */
38
+ export declare const ADK_CALL_ID_PREFIX = "adk-";
39
+ /** ADK's framework calls that a model never sees in its history. */
40
+ export declare const REQUEST_CONFIRMATION_CALL = "adk_request_confirmation";
41
+ export declare const REQUEST_CREDENTIAL_CALL = "adk_request_credential";
42
+ export declare const REQUEST_INPUT_CALL = "adk_request_input";
43
+ /** Where in a session the projecting agent stands. */
44
+ export interface HistoryScope {
45
+ /** The agent whose request this is: its own events stay as they are. */
46
+ agentName: string;
47
+ /** `default` (the conversation) or `none` (the current turn only). */
48
+ includeContents?: 'default' | 'none';
49
+ /** The invocation's branch; undefined at the root. */
50
+ branch?: string;
51
+ /** The invocation's isolation scope; undefined outside one. */
52
+ isolationScope?: string;
53
+ }
54
+ /**
55
+ * A compaction as ADK stores it (and as lib/runtime/native/compaction.ts
56
+ * writes it): a summary in place of the events from `startTime` to `endTime`.
57
+ */
58
+ export interface CompactedEvent extends TurnEvent {
59
+ isCompacted: true;
60
+ compactedContent?: string;
61
+ startTime?: number;
62
+ endTime?: number;
63
+ isScratchpad?: boolean;
64
+ }
65
+ export declare function isCompacted(event: TurnEvent): event is CompactedEvent;
66
+ /** The latest compaction and what follows it, or every visible event when there is none (ADK's getActiveEvents). */
67
+ export declare function activeEvents(events: readonly TurnEvent[], scope: string | undefined): TurnEvent[];
68
+ export declare function isSegmentPrefix(current: string | undefined, target: string | undefined): boolean;
69
+ /** The contents of every visible event, projected for `agentName` (ADK's getContents). The compactor's estimate reads it too. */
70
+ export declare function contentsOf(events: readonly TurnEvent[], agentName: string, branch: string | undefined, scope: string | undefined): TurnContent[];
71
+ /**
72
+ * The genai contents a model request carries for `scope.agentName`, from
73
+ * the session's events (oldest first), as ADK's content processor builds
74
+ * them for the same session.
75
+ */
76
+ export declare function projectHistory(events: readonly TurnEvent[], scope: HistoryScope): TurnContent[];
77
+ /**
78
+ * An agent with `code_execution: gemini`: a content that ends in code
79
+ * becomes that code as a fenced block, and a content that is only a result
80
+ * becomes the result as a user message (ADK's convertCodeExecutionParts,
81
+ * which its code-execution processor applies to every content). In place.
82
+ */
83
+ export declare function convertCodeExecutionParts(content: TurnContent): void;