melchizedek-agents 1.0.0 → 1.0.2

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 (57) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/DOCUMENTATION.md +11 -9
  3. package/config/agents/examples/critic.yaml +12 -7
  4. package/config/agents/examples/image_production.yaml +2 -2
  5. package/config/agents/examples/librarian.yaml +1 -1
  6. package/config/agents/examples/pipeline.yaml +1 -1
  7. package/config/agents/examples/research.yaml +3 -2
  8. package/config/agents/examples/scribe.yaml +5 -4
  9. package/config/agents/examples/weather.yaml +2 -1
  10. package/config/agents/syndicateSchema.yaml +18 -15
  11. package/dist/lib/dispatch.d.ts +4 -4
  12. package/dist/lib/dispatch.js +4 -4
  13. package/dist/lib/syndicateSchema.js +6 -6
  14. package/package.json +2 -2
  15. package/skills/briefs/melchizedek-author.md +1 -1
  16. package/skills/melchizedek-author/SKILL.md +1 -1
  17. package/skills/melchizedek-author/assets/minimal.yaml +1 -1
  18. package/dist/lib/adkPeer.d.ts +0 -63
  19. package/dist/lib/adkPeer.js +0 -240
  20. package/dist/lib/compileAdk.d.ts +0 -32
  21. package/dist/lib/compileAdk.js +0 -142
  22. package/dist/lib/models/adkGeminiAdapter.d.ts +0 -90
  23. package/dist/lib/models/adkGeminiAdapter.js +0 -369
  24. package/dist/lib/models/adkShim.d.ts +0 -111
  25. package/dist/lib/models/adkShim.js +0 -136
  26. package/dist/lib/models/claudeLlm.d.ts +0 -79
  27. package/dist/lib/models/claudeLlm.js +0 -87
  28. package/dist/lib/models/fallback.d.ts +0 -48
  29. package/dist/lib/models/fallback.js +0 -116
  30. package/dist/lib/models/gatewayLlm.d.ts +0 -36
  31. package/dist/lib/models/gatewayLlm.js +0 -44
  32. package/dist/lib/models/gptLlm.d.ts +0 -99
  33. package/dist/lib/models/gptLlm.js +0 -129
  34. package/dist/lib/models/grokLlm.d.ts +0 -50
  35. package/dist/lib/models/grokLlm.js +0 -56
  36. package/dist/lib/models/kimiLlm.d.ts +0 -31
  37. package/dist/lib/models/kimiLlm.js +0 -35
  38. package/dist/lib/models/ollamaLlm.d.ts +0 -37
  39. package/dist/lib/models/ollamaLlm.js +0 -42
  40. package/dist/lib/models/openAiCompatibleLlm.d.ts +0 -96
  41. package/dist/lib/models/openAiCompatibleLlm.js +0 -156
  42. package/dist/lib/models/tracedGemini.d.ts +0 -41
  43. package/dist/lib/models/tracedGemini.js +0 -98
  44. package/dist/lib/runtime/adkMemoryBridge.d.ts +0 -46
  45. package/dist/lib/runtime/adkMemoryBridge.js +0 -68
  46. package/dist/lib/runtime/adkSessionBridge.d.ts +0 -78
  47. package/dist/lib/runtime/adkSessionBridge.js +0 -176
  48. package/dist/lib/tools/adkTool.d.ts +0 -81
  49. package/dist/lib/tools/adkTool.js +0 -268
  50. package/dist/lib/tools/collectionsSearchTool.d.ts +0 -56
  51. package/dist/lib/tools/collectionsSearchTool.js +0 -71
  52. package/dist/lib/tools/urlContextTool.d.ts +0 -32
  53. package/dist/lib/tools/urlContextTool.js +0 -43
  54. package/dist/lib/tools/webSearchTool.d.ts +0 -51
  55. package/dist/lib/tools/webSearchTool.js +0 -82
  56. package/dist/lib/tools/xSearchTool.d.ts +0 -59
  57. package/dist/lib/tools/xSearchTool.js +0 -74
@@ -1,50 +0,0 @@
1
- /**
2
- * lib/models/grokLlm.ts — xAI Grok for ADK's LLMRegistry: GptLlm (the ADK
3
- * shim around a Responses adapter) built on GrokAdapter
4
- * (lib/models/grokAdapter.ts).
5
- *
6
- * WHY this file exists:
7
- * Model optionality is a primary driver of this framework: the agent YAML
8
- * declares `model`, and the registry routes it to the right provider.
9
- * xAI's Agent Tools API is wire-compatible with OpenAI's Responses API, so
10
- * GrokAdapter extends GptAdapter and overrides only the vendor hooks
11
- * (endpoint, key, timeout, reasoning effort, native tools), and GrokLlm
12
- * extends GptLlm, which keeps the ADK path's usage meaning and
13
- * server-side tool record (ADR 0056). Grok gets:
14
- * - native web_search (server-side, with source citations)
15
- * - x_search (live X posts) and collections_search (hosted document
16
- * stores via the file_search wire shape — see collectionsSearchTool.ts)
17
- * - reasoning summaries surfaced as { thought: true } THINKING output
18
- * - reasoning carried across a tool loop on grok-4.5, 4.6 and 4.7
19
- * (encrypted reasoning items as providerState, store: false — ADR 0050)
20
- * - SSE streaming (ADK RunConfig streamingMode: SSE → partial deltas)
21
- * - structured outputs (YAML outputSchema → text.format json_schema)
22
- * - function tools with call_id round-tripping, lowercase schemas
23
- *
24
- * HOW TO ENABLE:
25
- * 1. Add your API key to .env as XAI_API_KEY (console.x.ai — paid).
26
- * 2. Set model: "grok-4.7" (or any grok-* id) in your YAML.
27
- * registerAvailableProviders() registers this adapter when the key is set.
28
- * grok-4.5, 4.6 and 4.7 requests carry reasoning effort 'medium' unless the
29
- * agent sets `reasoning:` — DEFAULT_GROK_REASONING_EFFORT (lib/config.ts).
30
- *
31
- * API-DRIFT NOTE: every xAI-specific choice is confined to GrokAdapter's
32
- * overrides, so upstream drift stays a one-file fix. xAI's Responses endpoint
33
- * reports the serving backend in the response `model` field (e.g.
34
- * "grok-4.3"), which may differ from the requested id; invalid ids are
35
- * rejected with "Model not found".
36
- */
37
- import { GptLlm } from './gptLlm.ts';
38
- import type { GptLlmOptions } from './gptLlm.ts';
39
- import { GrokAdapter } from './grokAdapter.ts';
40
- export { DEFAULT_GROK_TIMEOUT_MS, grokTimeoutMs } from './grokAdapter.ts';
41
- export declare class GrokLlm extends GptLlm {
42
- /** Any model: "grok-*" in a YAML config routes here after registration. */
43
- static readonly supportedModels: Array<string | RegExp>;
44
- protected static createAdapter(options: GptLlmOptions): GrokAdapter;
45
- }
46
- /**
47
- * Registers GrokLlm with the ADK LLMRegistry. Called by
48
- * registerAvailableProviders() when XAI_API_KEY is present.
49
- */
50
- export declare function registerGrokLlm(): void;
@@ -1,56 +0,0 @@
1
- /**
2
- * lib/models/grokLlm.ts — xAI Grok for ADK's LLMRegistry: GptLlm (the ADK
3
- * shim around a Responses adapter) built on GrokAdapter
4
- * (lib/models/grokAdapter.ts).
5
- *
6
- * WHY this file exists:
7
- * Model optionality is a primary driver of this framework: the agent YAML
8
- * declares `model`, and the registry routes it to the right provider.
9
- * xAI's Agent Tools API is wire-compatible with OpenAI's Responses API, so
10
- * GrokAdapter extends GptAdapter and overrides only the vendor hooks
11
- * (endpoint, key, timeout, reasoning effort, native tools), and GrokLlm
12
- * extends GptLlm, which keeps the ADK path's usage meaning and
13
- * server-side tool record (ADR 0056). Grok gets:
14
- * - native web_search (server-side, with source citations)
15
- * - x_search (live X posts) and collections_search (hosted document
16
- * stores via the file_search wire shape — see collectionsSearchTool.ts)
17
- * - reasoning summaries surfaced as { thought: true } THINKING output
18
- * - reasoning carried across a tool loop on grok-4.5, 4.6 and 4.7
19
- * (encrypted reasoning items as providerState, store: false — ADR 0050)
20
- * - SSE streaming (ADK RunConfig streamingMode: SSE → partial deltas)
21
- * - structured outputs (YAML outputSchema → text.format json_schema)
22
- * - function tools with call_id round-tripping, lowercase schemas
23
- *
24
- * HOW TO ENABLE:
25
- * 1. Add your API key to .env as XAI_API_KEY (console.x.ai — paid).
26
- * 2. Set model: "grok-4.7" (or any grok-* id) in your YAML.
27
- * registerAvailableProviders() registers this adapter when the key is set.
28
- * grok-4.5, 4.6 and 4.7 requests carry reasoning effort 'medium' unless the
29
- * agent sets `reasoning:` — DEFAULT_GROK_REASONING_EFFORT (lib/config.ts).
30
- *
31
- * API-DRIFT NOTE: every xAI-specific choice is confined to GrokAdapter's
32
- * overrides, so upstream drift stays a one-file fix. xAI's Responses endpoint
33
- * reports the serving backend in the response `model` field (e.g.
34
- * "grok-4.3"), which may differ from the requested id; invalid ids are
35
- * rejected with "Model not found".
36
- */
37
- import { requireAdk } from '../adkPeer.js';
38
- import { GptLlm } from './gptLlm.js';
39
- import { GrokAdapter } from './grokAdapter.js';
40
- export { DEFAULT_GROK_TIMEOUT_MS, grokTimeoutMs } from './grokAdapter.js';
41
- // ── GrokLlm ───────────────────────────────────────────────────────────────────
42
- export class GrokLlm extends GptLlm {
43
- /** Any model: "grok-*" in a YAML config routes here after registration. */
44
- static supportedModels = [/^grok-.+/];
45
- static createAdapter(options) {
46
- return new GrokAdapter(options);
47
- }
48
- }
49
- // ── Registration helper ───────────────────────────────────────────────────────
50
- /**
51
- * Registers GrokLlm with the ADK LLMRegistry. Called by
52
- * registerAvailableProviders() when XAI_API_KEY is present.
53
- */
54
- export function registerGrokLlm() {
55
- requireAdk("Registering a model class with ADK's LLMRegistry").LLMRegistry.register(GrokLlm);
56
- }
@@ -1,31 +0,0 @@
1
- /**
2
- * lib/models/kimiLlm.ts — Moonshot AI (Kimi), as an ADK BaseLlm for the
3
- * LLMRegistry.
4
- *
5
- * WHY this file exists:
6
- * The provider's work is KimiAdapter (lib/models/kimiAdapter.ts), on the
7
- * engine's own model contract; its header covers the family, cost, the
8
- * reasoning controls per generation, and reasoning_content on tool loops
9
- * (ADR 0046). ADK still runs every turn, so this class runs the adapter
10
- * under ADK: it is the chat-completions shim
11
- * (lib/models/openAiCompatibleLlm.ts, ADR 0057), registered for any
12
- * `kimi-*` id when MOONSHOT_API_KEY is set. The constructor and
13
- * supportedModels are what they were before the adapter moved onto the
14
- * contract, so lib/models/registry.ts and every caller are unchanged. On
15
- * this path an agent's older spelling `reasoningEffort: max` still reaches
16
- * K3, which the contract has no level for.
17
- */
18
- import { OpenAiCompatibleLlm } from './openAiCompatibleLlm.ts';
19
- export { MOONSHOT_BASE_URL, isKimiK3, wantsReasoningReplay } from './kimiAdapter.ts';
20
- export declare class KimiLlm extends OpenAiCompatibleLlm {
21
- /** Any model: "kimi-*" in a YAML config routes here after registration. */
22
- static readonly supportedModels: Array<string | RegExp>;
23
- /** `apiKey` defaults to MOONSHOT_API_KEY; `baseUrl` to MOONSHOT_BASE_URL, else https://api.moonshot.ai/v1. */
24
- constructor({ model, apiKey, baseUrl }: {
25
- model: string;
26
- apiKey?: string;
27
- baseUrl?: string;
28
- });
29
- }
30
- /** Registers KimiLlm with the ADK LLMRegistry (called when MOONSHOT_API_KEY is set). */
31
- export declare function registerKimiLlm(): void;
@@ -1,35 +0,0 @@
1
- /**
2
- * lib/models/kimiLlm.ts — Moonshot AI (Kimi), as an ADK BaseLlm for the
3
- * LLMRegistry.
4
- *
5
- * WHY this file exists:
6
- * The provider's work is KimiAdapter (lib/models/kimiAdapter.ts), on the
7
- * engine's own model contract; its header covers the family, cost, the
8
- * reasoning controls per generation, and reasoning_content on tool loops
9
- * (ADR 0046). ADK still runs every turn, so this class runs the adapter
10
- * under ADK: it is the chat-completions shim
11
- * (lib/models/openAiCompatibleLlm.ts, ADR 0057), registered for any
12
- * `kimi-*` id when MOONSHOT_API_KEY is set. The constructor and
13
- * supportedModels are what they were before the adapter moved onto the
14
- * contract, so lib/models/registry.ts and every caller are unchanged. On
15
- * this path an agent's older spelling `reasoningEffort: max` still reaches
16
- * K3, which the contract has no level for.
17
- */
18
- import { requireAdk } from '../adkPeer.js';
19
- import { KimiAdapter } from './kimiAdapter.js';
20
- import { OpenAiCompatibleLlm } from './openAiCompatibleLlm.js';
21
- export { MOONSHOT_BASE_URL, isKimiK3, wantsReasoningReplay } from './kimiAdapter.js';
22
- // ── KimiLlm ───────────────────────────────────────────────────────────────────
23
- export class KimiLlm extends OpenAiCompatibleLlm {
24
- /** Any model: "kimi-*" in a YAML config routes here after registration. */
25
- static supportedModels = [/^kimi-.+/];
26
- /** `apiKey` defaults to MOONSHOT_API_KEY; `baseUrl` to MOONSHOT_BASE_URL, else https://api.moonshot.ai/v1. */
27
- constructor({ model, apiKey, baseUrl }) {
28
- super(new KimiAdapter({ model, apiKey, baseUrl }), { model });
29
- }
30
- }
31
- // ── Registration helper ───────────────────────────────────────────────────────
32
- /** Registers KimiLlm with the ADK LLMRegistry (called when MOONSHOT_API_KEY is set). */
33
- export function registerKimiLlm() {
34
- requireAdk("Registering a model class with ADK's LLMRegistry").LLMRegistry.register(KimiLlm);
35
- }
@@ -1,37 +0,0 @@
1
- /**
2
- * lib/models/ollamaLlm.ts — open-weight / local models served by Ollama, as
3
- * an ADK BaseLlm for the LLMRegistry.
4
- *
5
- * WHY this file exists:
6
- * The provider's work is OllamaAdapter (lib/models/ollamaAdapter.ts), on
7
- * the engine's own model contract; its header says how to install Ollama,
8
- * which model to pull, and what a local model cannot do. ADK still runs
9
- * every turn, so this class runs the adapter under ADK: it is the
10
- * chat-completions shim (lib/models/openAiCompatibleLlm.ts, ADR 0057),
11
- * registered for any `ollama/<model>` id. The constructor and
12
- * supportedModels are what they were before the adapter moved onto the
13
- * contract, so lib/models/registry.ts and every caller are unchanged.
14
- */
15
- import { OpenAiCompatibleLlm } from './openAiCompatibleLlm.ts';
16
- export declare class OllamaLlm extends OpenAiCompatibleLlm {
17
- /**
18
- * Model ids namespaced "ollama/<model>" route here after registration,
19
- * e.g. model: "ollama/qwen3:8b" in a syndicate YAML.
20
- */
21
- static readonly supportedModels: Array<string | RegExp>;
22
- /** `baseUrl` defaults to OLLAMA_BASE_URL, else http://localhost:11434/v1. */
23
- constructor({ model, baseUrl }: {
24
- model: string;
25
- baseUrl?: string;
26
- });
27
- }
28
- /**
29
- * Registers OllamaLlm with the ADK LLMRegistry.
30
- *
31
- * Unlike registerClaudeLlm(), this needs no key gate — a local provider has
32
- * no credential to check. Registration is still explicit (not at import
33
- * time) so entrypoints stay in control of which providers are active.
34
- * If Ollama isn't running, agents fail at call time with a clear
35
- * OLLAMA_UNREACHABLE message that says how to start it.
36
- */
37
- export declare function registerOllamaLlm(): void;
@@ -1,42 +0,0 @@
1
- /**
2
- * lib/models/ollamaLlm.ts — open-weight / local models served by Ollama, as
3
- * an ADK BaseLlm for the LLMRegistry.
4
- *
5
- * WHY this file exists:
6
- * The provider's work is OllamaAdapter (lib/models/ollamaAdapter.ts), on
7
- * the engine's own model contract; its header says how to install Ollama,
8
- * which model to pull, and what a local model cannot do. ADK still runs
9
- * every turn, so this class runs the adapter under ADK: it is the
10
- * chat-completions shim (lib/models/openAiCompatibleLlm.ts, ADR 0057),
11
- * registered for any `ollama/<model>` id. The constructor and
12
- * supportedModels are what they were before the adapter moved onto the
13
- * contract, so lib/models/registry.ts and every caller are unchanged.
14
- */
15
- import { requireAdk } from '../adkPeer.js';
16
- import { OllamaAdapter } from './ollamaAdapter.js';
17
- import { OpenAiCompatibleLlm } from './openAiCompatibleLlm.js';
18
- // ── OllamaLlm ─────────────────────────────────────────────────────────────────
19
- export class OllamaLlm extends OpenAiCompatibleLlm {
20
- /**
21
- * Model ids namespaced "ollama/<model>" route here after registration,
22
- * e.g. model: "ollama/qwen3:8b" in a syndicate YAML.
23
- */
24
- static supportedModels = [/^ollama\/.+/];
25
- /** `baseUrl` defaults to OLLAMA_BASE_URL, else http://localhost:11434/v1. */
26
- constructor({ model, baseUrl }) {
27
- super(new OllamaAdapter({ model, baseUrl }), { model });
28
- }
29
- }
30
- // ── Registration helper ───────────────────────────────────────────────────────
31
- /**
32
- * Registers OllamaLlm with the ADK LLMRegistry.
33
- *
34
- * Unlike registerClaudeLlm(), this needs no key gate — a local provider has
35
- * no credential to check. Registration is still explicit (not at import
36
- * time) so entrypoints stay in control of which providers are active.
37
- * If Ollama isn't running, agents fail at call time with a clear
38
- * OLLAMA_UNREACHABLE message that says how to start it.
39
- */
40
- export function registerOllamaLlm() {
41
- requireAdk("Registering a model class with ADK's LLMRegistry").LLMRegistry.register(OllamaLlm);
42
- }
@@ -1,96 +0,0 @@
1
- /**
2
- * lib/models/openAiCompatibleLlm.ts — the ADK shim base for every
3
- * chat-completions adapter (Ollama, Kimi, the gateway).
4
- *
5
- * WHY this file exists:
6
- * The chat-completions translation lives on the engine's own model
7
- * contract, in lib/models/chatCompletionsAdapter.ts and one adapter per
8
- * provider (ollamaAdapter.ts, kimiAdapter.ts, gatewayAdapter.ts). ADK
9
- * still runs every turn (ADR 0045), so each adapter runs behind an ADK
10
- * BaseLlm: OllamaLlm, KimiLlm and GatewayLlm, subclasses of this class,
11
- * which is an AdkShim (lib/models/adkShim.ts, ADR 0053). The shim charges
12
- * the turn, opens the llm.request span and maps the request and responses;
13
- * the adapter does the provider's work.
14
- *
15
- * WHAT THIS CLASS ADDS TO THE SHIM (ADR 0057): the ADK path stays what it
16
- * was before the adapters moved onto the contract.
17
- * - The request: an agent's older generateContentConfig spelling that the
18
- * contract leaves out rides beside it (olderSpellingOf): an effort word
19
- * that is no contract level (Kimi K3's `max`). JSON mode without a
20
- * schema is the contract's `outputFormat` (ADR 0061).
21
- * - The response: the final keeps the shape these classes always yielded,
22
- * which the ledger and FallbackLlm read. usageMetadata counts the
23
- * reasoning inside candidatesTokenCount, as the provider's
24
- * completion_tokens does, so llm.tokens.output and the turn's charge are
25
- * unchanged (the shim's default is Gemini's meaning, which excludes it).
26
- * finishReason is set only for a reply cut short (MAX_TOKENS); a final
27
- * with no parts keeps its empty content; an HTTP failure keeps its
28
- * top-level `status` and `retryable` beside the verdict in
29
- * customMetadata.
30
- *
31
- * A /chat/completions provider of your own is a ChatCompletionsAdapter
32
- * subclass (the endpoint, headers, wire name, reasoning field and error
33
- * wording), run under ADK as `adkShim(adapter)` or as a subclass of this
34
- * class.
35
- */
36
- import type { GenerateContentConfig } from '@google/genai';
37
- import type { LlmRequest, LlmResponse } from '@google/adk';
38
- import { AdkShim } from './adkShim.ts';
39
- import type { AdkShimOptions } from './adkShim.ts';
40
- import type { ModelResponse, Usage } from './contract.ts';
41
- import type { ModelRequestOptions } from './genaiMapping.ts';
42
- import type { ChatCompletionsAdapter, ChatCompletionsRequest, ChatMessage, OlderSpelling } from './chatCompletionsAdapter.ts';
43
- export { REASONING_CONTENT_KIND, splitThinkBlocks, ThinkStreamSplitter } from './chatCompletionsAdapter.ts';
44
- /**
45
- * What a generateContentConfig asks of a chat-completions provider that the
46
- * contract has no field for, or undefined when it asks nothing more:
47
- * `reasoningEffort` when it is a word no ReasoningSetting carries (`max`,
48
- * `xhigh`), sent as written. JSON mode without a schema is no longer here:
49
- * the genai mapping reads it as `outputFormat: 'json'` (ADR 0061).
50
- */
51
- export declare function olderSpellingOf(config: GenerateContentConfig | undefined): OlderSpelling | undefined;
52
- /**
53
- * Usage as the chat-completions classes have always reported it on the ADK
54
- * path: candidatesTokenCount is the provider's completion_tokens, reasoning
55
- * included, and thoughtsTokenCount the reasoning part of it.
56
- */
57
- export declare function chatUsageMetadata(usage: Usage): NonNullable<LlmResponse['usageMetadata']>;
58
- export declare abstract class OpenAiCompatibleLlm extends AdkShim {
59
- readonly adapter: ChatCompletionsAdapter;
60
- constructor(adapter: ChatCompletionsAdapter, options?: AdkShimOptions);
61
- /** Provider id for telemetry: the adapter's (a gateway reports the upstream provider). */
62
- protected providerId(): string;
63
- /** How the request reaches the provider: 'direct' or 'gateway:<id>' (llm.transport). */
64
- protected transport(): string;
65
- /** The chat messages the adapter sends for this LlmRequest. */
66
- protected buildMessages(llmRequest: LlmRequest): ChatMessage[];
67
- /** The function tools the adapter sends for this LlmRequest (lowercase schemas). */
68
- protected buildTools(llmRequest: LlmRequest): unknown[];
69
- /** The genai mapping's request, with the older spelling the contract leaves out. */
70
- protected toModelRequest(llmRequest: LlmRequest, options: ModelRequestOptions): ChatCompletionsRequest;
71
- /** The genai mapping's response, in the shape these classes have always yielded (see the header). */
72
- protected toLlmResponse(response: ModelResponse): LlmResponse;
73
- }
74
- /**
75
- * Stamps an HTTP error response with its numeric status and whether that
76
- * status is transient, and the same verdict in customMetadata
77
- * ('error.retryable', 'error.status'), where FallbackLlm reads it
78
- * (lib/models/errorResponse.ts). The chat-completions shims take these
79
- * fields from their adapter's error final instead (toLlmResponse).
80
- */
81
- export declare function withHttpStatus(resp: LlmResponse, status: number): LlmResponse;
82
- type GenaiUsage = NonNullable<ReturnType<typeof mapUsage>>;
83
- /** Two genai usage records summed, field by field. */
84
- export declare function addUsage(a: GenaiUsage | undefined, b: GenaiUsage | undefined): GenaiUsage | undefined;
85
- /**
86
- * OpenAI-style usage → GenAI usageMetadata in the ADK-path meaning
87
- * (completion_tokens, reasoning included, as candidatesTokenCount), or
88
- * undefined when absent. The contract's meaning is chatUsage in
89
- * lib/models/chatCompletionsAdapter.ts.
90
- */
91
- export declare function mapUsage(usage: any): {
92
- promptTokenCount?: number;
93
- candidatesTokenCount?: number;
94
- thoughtsTokenCount?: number;
95
- totalTokenCount?: number;
96
- } | undefined;
@@ -1,156 +0,0 @@
1
- /**
2
- * lib/models/openAiCompatibleLlm.ts — the ADK shim base for every
3
- * chat-completions adapter (Ollama, Kimi, the gateway).
4
- *
5
- * WHY this file exists:
6
- * The chat-completions translation lives on the engine's own model
7
- * contract, in lib/models/chatCompletionsAdapter.ts and one adapter per
8
- * provider (ollamaAdapter.ts, kimiAdapter.ts, gatewayAdapter.ts). ADK
9
- * still runs every turn (ADR 0045), so each adapter runs behind an ADK
10
- * BaseLlm: OllamaLlm, KimiLlm and GatewayLlm, subclasses of this class,
11
- * which is an AdkShim (lib/models/adkShim.ts, ADR 0053). The shim charges
12
- * the turn, opens the llm.request span and maps the request and responses;
13
- * the adapter does the provider's work.
14
- *
15
- * WHAT THIS CLASS ADDS TO THE SHIM (ADR 0057): the ADK path stays what it
16
- * was before the adapters moved onto the contract.
17
- * - The request: an agent's older generateContentConfig spelling that the
18
- * contract leaves out rides beside it (olderSpellingOf): an effort word
19
- * that is no contract level (Kimi K3's `max`). JSON mode without a
20
- * schema is the contract's `outputFormat` (ADR 0061).
21
- * - The response: the final keeps the shape these classes always yielded,
22
- * which the ledger and FallbackLlm read. usageMetadata counts the
23
- * reasoning inside candidatesTokenCount, as the provider's
24
- * completion_tokens does, so llm.tokens.output and the turn's charge are
25
- * unchanged (the shim's default is Gemini's meaning, which excludes it).
26
- * finishReason is set only for a reply cut short (MAX_TOKENS); a final
27
- * with no parts keeps its empty content; an HTTP failure keeps its
28
- * top-level `status` and `retryable` beside the verdict in
29
- * customMetadata.
30
- *
31
- * A /chat/completions provider of your own is a ChatCompletionsAdapter
32
- * subclass (the endpoint, headers, wire name, reasoning field and error
33
- * wording), run under ADK as `adkShim(adapter)` or as a subclass of this
34
- * class.
35
- */
36
- import { FinishReason } from '@google/genai';
37
- import { AdkShim } from './adkShim.js';
38
- import { setLlmSpanAttribute } from '../observability/tracer.js';
39
- import { isRetryableStatus } from './retry.js';
40
- import { statusDecision, withRetryVerdict } from './errorResponse.js';
41
- export { REASONING_CONTENT_KIND, splitThinkBlocks, ThinkStreamSplitter } from './chatCompletionsAdapter.js';
42
- /** The effort words a contract ReasoningSetting carries (genaiMapping's reasoningOf); any other rides as the older spelling. */
43
- const CONTRACT_EFFORT_WORDS = new Set(['none', 'minimal', 'low', 'medium', 'high']);
44
- /**
45
- * What a generateContentConfig asks of a chat-completions provider that the
46
- * contract has no field for, or undefined when it asks nothing more:
47
- * `reasoningEffort` when it is a word no ReasoningSetting carries (`max`,
48
- * `xhigh`), sent as written. JSON mode without a schema is no longer here:
49
- * the genai mapping reads it as `outputFormat: 'json'` (ADR 0061).
50
- */
51
- export function olderSpellingOf(config) {
52
- const cfg = (config ?? {});
53
- const out = {};
54
- const effort = cfg.reasoningEffort;
55
- if (typeof effort === 'string' && !CONTRACT_EFFORT_WORDS.has(effort))
56
- out.reasoningEffort = effort;
57
- return Object.keys(out).length > 0 ? out : undefined;
58
- }
59
- /**
60
- * Usage as the chat-completions classes have always reported it on the ADK
61
- * path: candidatesTokenCount is the provider's completion_tokens, reasoning
62
- * included, and thoughtsTokenCount the reasoning part of it.
63
- */
64
- export function chatUsageMetadata(usage) {
65
- return {
66
- promptTokenCount: usage.inputTokens,
67
- candidatesTokenCount: usage.outputTokens,
68
- ...(usage.thinkingTokens !== undefined ? { thoughtsTokenCount: usage.thinkingTokens } : {}),
69
- totalTokenCount: usage.inputTokens + usage.outputTokens,
70
- };
71
- }
72
- // ── OpenAiCompatibleLlm ──────────────────────────────────────────────────────
73
- export class OpenAiCompatibleLlm extends AdkShim {
74
- constructor(adapter, options = {}) {
75
- super(adapter, options);
76
- }
77
- /** Provider id for telemetry: the adapter's (a gateway reports the upstream provider). */
78
- providerId() {
79
- return this.adapter.provider;
80
- }
81
- /** How the request reaches the provider: 'direct' or 'gateway:<id>' (llm.transport). */
82
- transport() {
83
- return this.adapter.transport();
84
- }
85
- /** The chat messages the adapter sends for this LlmRequest. */
86
- buildMessages(llmRequest) {
87
- return this.adapter.messagesFor(this.toModelRequest(llmRequest, { model: this.model }));
88
- }
89
- /** The function tools the adapter sends for this LlmRequest (lowercase schemas). */
90
- buildTools(llmRequest) {
91
- return this.adapter.toolsFor(this.toModelRequest(llmRequest, { model: this.model }));
92
- }
93
- /** The genai mapping's request, with the older spelling the contract leaves out. */
94
- toModelRequest(llmRequest, options) {
95
- const request = super.toModelRequest(llmRequest, options);
96
- const olderSpelling = olderSpellingOf(llmRequest.config);
97
- return olderSpelling ? { ...request, olderSpelling } : request;
98
- }
99
- /** The genai mapping's response, in the shape these classes have always yielded (see the header). */
100
- toLlmResponse(response) {
101
- const mapped = super.toLlmResponse(response);
102
- if (response.partial)
103
- return mapped;
104
- const { finishReason: _finish, usageMetadata: _usage, ...rest } = mapped;
105
- const error = response.error;
106
- return {
107
- ...(error ? {} : { content: { role: 'model', parts: [] } }),
108
- ...rest,
109
- ...(!error && response.finishReason === 'max_tokens' ? { finishReason: FinishReason.MAX_TOKENS } : {}),
110
- ...(response.usage ? { usageMetadata: chatUsageMetadata(response.usage) } : {}),
111
- ...(error?.status !== undefined ? { status: error.status, retryable: error.retryable } : {}),
112
- };
113
- }
114
- }
115
- // ── Kept for callers of the ADK-path helpers ─────────────────────────────────
116
- /**
117
- * Stamps an HTTP error response with its numeric status and whether that
118
- * status is transient, and the same verdict in customMetadata
119
- * ('error.retryable', 'error.status'), where FallbackLlm reads it
120
- * (lib/models/errorResponse.ts). The chat-completions shims take these
121
- * fields from their adapter's error final instead (toLlmResponse).
122
- */
123
- export function withHttpStatus(resp, status) {
124
- setLlmSpanAttribute('llm.http_status', status);
125
- return { ...withRetryVerdict(resp, statusDecision(status)), status, retryable: isRetryableStatus(status) };
126
- }
127
- /** Two genai usage records summed, field by field. */
128
- export function addUsage(a, b) {
129
- if (!a)
130
- return b;
131
- if (!b)
132
- return a;
133
- const out = {};
134
- for (const k of ['promptTokenCount', 'candidatesTokenCount', 'thoughtsTokenCount', 'totalTokenCount']) {
135
- if (a[k] !== undefined || b[k] !== undefined)
136
- out[k] = (a[k] ?? 0) + (b[k] ?? 0);
137
- }
138
- return out;
139
- }
140
- /**
141
- * OpenAI-style usage → GenAI usageMetadata in the ADK-path meaning
142
- * (completion_tokens, reasoning included, as candidatesTokenCount), or
143
- * undefined when absent. The contract's meaning is chatUsage in
144
- * lib/models/chatCompletionsAdapter.ts.
145
- */
146
- export function mapUsage(usage) {
147
- if (!usage || typeof usage !== 'object')
148
- return undefined;
149
- const reasoning = usage.completion_tokens_details?.reasoning_tokens;
150
- return {
151
- ...(usage.prompt_tokens !== undefined ? { promptTokenCount: usage.prompt_tokens } : {}),
152
- ...(usage.completion_tokens !== undefined ? { candidatesTokenCount: usage.completion_tokens } : {}),
153
- ...(reasoning !== undefined ? { thoughtsTokenCount: reasoning } : {}),
154
- ...(usage.total_tokens !== undefined ? { totalTokenCount: usage.total_tokens } : {}),
155
- };
156
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * lib/models/tracedGemini.ts — ADK's built-in Gemini, wrapped so Gemini calls
3
- * emit the same per-request llm.request spans (tokens, latency) as every other
4
- * provider, and get the shared transient-failure retries (lib/models/retry.ts).
5
- *
6
- * WHY its own module: two modules use it. lib/models/registry.ts registers it
7
- * for every Gemini id on the ADK path and builds it in resolveModel, and the
8
- * temporary AdkGeminiAdapter (lib/models/adkGeminiAdapter.ts) runs its calls
9
- * through generateWithRetries. registry.ts also builds that adapter in
10
- * resolveAdapter, so the class living in registry.ts would be an ESM import
11
- * cycle. registry.ts re-exports it, so `TracedGemini` imports from there keep
12
- * working.
13
- */
14
- import { Gemini } from '../adkPeer.ts';
15
- import type { GeminiParams, LlmRequest, LlmResponse } from '@google/adk';
16
- import type { ProviderEndpoint } from './endpoints.ts';
17
- export declare class TracedGemini extends Gemini {
18
- #private;
19
- static readonly supportedModels: Array<string | RegExp>;
20
- /**
21
- * The Gemini platform (ADR 0023) applies to every construction, the
22
- * LLMRegistry's included: on Vertex AI the client authenticates with
23
- * Google Application Default Credentials for the configured project and
24
- * location, and an AI Studio key (the environment's or a caller's) is not
25
- * sent. `endpoint` overrides the environment's (the credentials plug point).
26
- */
27
- constructor(params?: GeminiParams & {
28
- endpoint?: ProviderEndpoint;
29
- });
30
- generateContentAsync(llmRequest: LlmRequest, stream?: boolean, abortSignal?: AbortSignal): AsyncGenerator<LlmResponse, void>;
31
- /**
32
- * One call through ADK's Gemini with the shared retries, tagging whatever
33
- * llm.request span is active (llm.web_search.native for Gemini grounding,
34
- * llm.retries, llm.http_status). generateContentAsync opens that span
35
- * around it; AdkGeminiAdapter (lib/models/adkGeminiAdapter.ts) runs it
36
- * inside the span its own caller opens (ADR 0053). A failed call throws,
37
- * as ADK's Gemini does. The abort signal is forwarded so a canceled turn stops the
38
- * request in flight (ADK's Gemini puts it on the genai request config).
39
- */
40
- generateWithRetries(llmRequest: LlmRequest, stream?: boolean, abortSignal?: AbortSignal): AsyncGenerator<LlmResponse, void>;
41
- }
@@ -1,98 +0,0 @@
1
- /**
2
- * lib/models/tracedGemini.ts — ADK's built-in Gemini, wrapped so Gemini calls
3
- * emit the same per-request llm.request spans (tokens, latency) as every other
4
- * provider, and get the shared transient-failure retries (lib/models/retry.ts).
5
- *
6
- * WHY its own module: two modules use it. lib/models/registry.ts registers it
7
- * for every Gemini id on the ADK path and builds it in resolveModel, and the
8
- * temporary AdkGeminiAdapter (lib/models/adkGeminiAdapter.ts) runs its calls
9
- * through generateWithRetries. registry.ts also builds that adapter in
10
- * resolveAdapter, so the class living in registry.ts would be an ESM import
11
- * cycle. registry.ts re-exports it, so `TracedGemini` imports from there keep
12
- * working.
13
- */
14
- import { Gemini } from '../adkPeer.js';
15
- import { endpointFromEnv, platformModel } from './endpoints.js';
16
- import { llmRequestToModelRequest } from './genaiMapping.js';
17
- import { errorStatus, retryUntilFirstYield } from './retry.js';
18
- import { setLlmSpanAttribute, traceLlmGeneration } from '../observability/tracer.js';
19
- import { currentTurnSignal } from '../runtime/turnControl.js';
20
- export class TracedGemini extends Gemini {
21
- // CRITICAL: reuse Gemini's exact regex instances. The LLMRegistry dict is
22
- // keyed by the regex OBJECT — registering the same instances REPLACES the
23
- // built-in Gemini entries instead of adding shadowed duplicates.
24
- static supportedModels = Gemini.supportedModels;
25
- /**
26
- * The Gemini platform (ADR 0023) applies to every construction, the
27
- * LLMRegistry's included: on Vertex AI the client authenticates with
28
- * Google Application Default Credentials for the configured project and
29
- * location, and an AI Studio key (the environment's or a caller's) is not
30
- * sent. `endpoint` overrides the environment's (the credentials plug point).
31
- */
32
- constructor(params = {}) {
33
- const { endpoint: given, ...rest } = params;
34
- const e = given ?? endpointFromEnv('gemini');
35
- const model = rest.model ? platformModel(e, rest.model) : rest.model;
36
- super(e.platform === 'vertex'
37
- ? { ...rest, model, apiKey: e.apiKey, vertexai: true, project: e.project, location: e.location }
38
- : { ...rest, model, ...(e.apiKey && !rest.apiKey ? { apiKey: e.apiKey } : {}) });
39
- this.#vertex = e.platform === 'vertex';
40
- }
41
- /** True when the client runs on Vertex AI (ADR 0023). */
42
- #vertex;
43
- async *generateContentAsync(llmRequest, stream, abortSignal) {
44
- yield* traceLlmGeneration({
45
- provider: 'gemini',
46
- model: this.model,
47
- request: () => llmRequestToModelRequest(llmRequest, { model: llmRequest.model || this.model, stream }),
48
- }, this.generateWithRetries(llmRequest, stream, abortSignal ?? currentTurnSignal()));
49
- }
50
- /**
51
- * One call through ADK's Gemini with the shared retries, tagging whatever
52
- * llm.request span is active (llm.web_search.native for Gemini grounding,
53
- * llm.retries, llm.http_status). generateContentAsync opens that span
54
- * around it; AdkGeminiAdapter (lib/models/adkGeminiAdapter.ts) runs it
55
- * inside the span its own caller opens (ADR 0053). A failed call throws,
56
- * as ADK's Gemini does. The abort signal is forwarded so a canceled turn stops the
57
- * request in flight (ADK's Gemini puts it on the genai request config).
58
- */
59
- async *generateWithRetries(llmRequest, stream, abortSignal) {
60
- // The compiler asks every agent's config for includeServerSideToolInvocations
61
- // (lib/compile.ts), which the Gemini API needs beside function
62
- // declarations. @google/genai refuses it on Vertex AI before any request
63
- // is sent ("only supported in Gemini Developer API mode"), so on Vertex
64
- // it is left off, and the call goes out as it did before the flag.
65
- const toolConfig = llmRequest.config?.toolConfig;
66
- if (this.#vertex && toolConfig && 'includeServerSideToolInvocations' in toolConfig) {
67
- const { includeServerSideToolInvocations: _vertexRefuses, ...kept } = toolConfig;
68
- llmRequest.config = { ...llmRequest.config, toolConfig: kept };
69
- }
70
- const hasGrounding = (llmRequest.config?.tools ?? []).some((t) => t && (t.googleSearch || t.googleSearchRetrieval));
71
- if (hasGrounding)
72
- setLlmSpanAttribute('llm.web_search.native', true);
73
- // Retries live here, not in genai's own httpOptions.retryOptions: that
74
- // hook (p-retry 4, client-level only) ignores the abort signal — it
75
- // sleeps and re-sends after a canceled turn — honours no Retry-After,
76
- // does not retry Node's "fetch failed" resets, and replaces a 4xx's
77
- // error body (e.g. "API key not valid") with a bare statusText. Wrapping
78
- // the call keeps genai's ApiError intact and applies the same policy as
79
- // every other adapter. A retry is only made while nothing has been
80
- // yielded, so a stream that fails mid-reply is surfaced, not replayed.
81
- // ADK's request preprocessing is idempotent, so re-sending the same
82
- // llmRequest is safe. The registry class, resolveModel()'s per-request
83
- // instances and AdkGeminiAdapter's are all TracedGemini, so all get this.
84
- try {
85
- yield* retryUntilFirstYield(() => super.generateContentAsync(llmRequest, stream, abortSignal), {
86
- signal: abortSignal,
87
- onRetry: ({ retries }) => setLlmSpanAttribute('llm.retries', retries),
88
- });
89
- }
90
- catch (err) {
91
- // genai's ApiError carries the status; put it where the ledger reads.
92
- const status = errorStatus(err);
93
- if (status !== undefined)
94
- setLlmSpanAttribute('llm.http_status', status);
95
- throw err;
96
- }
97
- }
98
- }