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.
- package/.env.example +12 -0
- package/CHANGELOG.md +825 -0
- package/DOCUMENTATION.md +217 -59
- package/README.md +42 -1
- package/config/agents/examples/harness.yaml +3 -1
- package/config/agents/examples/model_zoo.yaml +10 -9
- package/config/agents/syndicateSchema.yaml +50 -16
- package/config/agents/templates/account_memory.yaml +2 -6
- package/config/agents/templates/case_desk.yaml +3 -9
- package/config/agents/templates/draft_review.yaml +3 -9
- package/config/agents/templates/intake_extractor.yaml +1 -3
- package/config/agents/templates/research_brief.yaml +3 -9
- package/config/agents/templates/research_desk.yaml +3 -9
- package/config/agents/templates/review_panel.yaml +4 -12
- package/config/agents/templates/support_triage.yaml +4 -12
- package/config/agents/templates/systems_operator.yaml +2 -6
- package/db/hardening.sql +7 -1
- package/db/migrations/0013_tool_credentials.sql +260 -0
- package/dist/lib/a2a/app.d.ts +70 -6
- package/dist/lib/a2a/app.js +107 -2
- package/dist/lib/a2a/executor.d.ts +20 -3
- package/dist/lib/a2a/executor.js +66 -7
- package/dist/lib/a2a/remoteAgent.d.ts +24 -9
- package/dist/lib/a2a/remoteAgent.js +31 -14
- package/dist/lib/compile.d.ts +121 -30
- package/dist/lib/compile.js +137 -124
- package/dist/lib/compileAdk.d.ts +29 -0
- package/dist/lib/compileAdk.js +132 -0
- package/dist/lib/compileNative.d.ts +85 -0
- package/dist/lib/compileNative.js +222 -0
- package/dist/lib/config.d.ts +6 -5
- package/dist/lib/config.js +6 -5
- package/dist/lib/doctor.js +1 -0
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +2 -1
- package/dist/lib/loadSyndicate.d.ts +18 -0
- package/dist/lib/memory/erase.d.ts +5 -3
- package/dist/lib/memory/erase.js +5 -2
- package/dist/lib/memory/namespace.d.ts +8 -1
- package/dist/lib/memory/namespace.js +12 -6
- package/dist/lib/memory/providers.js +2 -1
- package/dist/lib/memory/supabaseMemoryService.d.ts +37 -3
- package/dist/lib/memory/supabaseMemoryService.js +42 -2
- package/dist/lib/model.d.ts +47 -0
- package/dist/lib/model.js +37 -0
- package/dist/lib/models/adapterResolver.d.ts +113 -0
- package/dist/lib/models/adapterResolver.js +136 -0
- package/dist/lib/models/adkGeminiAdapter.d.ts +90 -0
- package/dist/lib/models/adkGeminiAdapter.js +367 -0
- package/dist/lib/models/adkShim.d.ts +111 -0
- package/dist/lib/models/adkShim.js +136 -0
- package/dist/lib/models/capabilities.d.ts +3 -0
- package/dist/lib/models/capabilities.js +20 -13
- package/dist/lib/models/chatCompletionsAdapter.d.ts +279 -0
- package/dist/lib/models/chatCompletionsAdapter.js +854 -0
- package/dist/lib/models/circuitBreaker.d.ts +42 -0
- package/dist/lib/models/circuitBreaker.js +70 -0
- package/dist/lib/models/claudeAdapter.d.ts +103 -0
- package/dist/lib/models/claudeAdapter.js +669 -0
- package/dist/lib/models/claudeLlm.d.ts +39 -62
- package/dist/lib/models/claudeLlm.js +44 -349
- package/dist/lib/models/claudeModels.d.ts +127 -0
- package/dist/lib/models/claudeModels.js +237 -0
- package/dist/lib/models/contract.d.ts +395 -0
- package/dist/lib/models/contract.js +39 -0
- package/dist/lib/models/endpoints.js +2 -1
- package/dist/lib/models/errorResponse.d.ts +50 -0
- package/dist/lib/models/errorResponse.js +48 -0
- package/dist/lib/models/fallback.d.ts +17 -10
- package/dist/lib/models/fallback.js +53 -42
- package/dist/lib/models/fallbackAdapter.d.ts +55 -0
- package/dist/lib/models/fallbackAdapter.js +62 -0
- package/dist/lib/models/gateway.js +2 -1
- package/dist/lib/models/gatewayAdapter.d.ts +51 -0
- package/dist/lib/models/gatewayAdapter.js +81 -0
- package/dist/lib/models/gatewayLlm.d.ts +12 -33
- package/dist/lib/models/gatewayLlm.js +14 -75
- package/dist/lib/models/geminiAdapter.d.ts +123 -0
- package/dist/lib/models/geminiAdapter.js +831 -0
- package/dist/lib/models/geminiState.d.ts +25 -0
- package/dist/lib/models/geminiState.js +25 -0
- package/dist/lib/models/genaiMapping.d.ts +263 -0
- package/dist/lib/models/genaiMapping.js +862 -0
- package/dist/lib/models/gptAdapter.d.ts +240 -0
- package/dist/lib/models/gptAdapter.js +804 -0
- package/dist/lib/models/gptLlm.d.ts +63 -123
- package/dist/lib/models/gptLlm.js +88 -602
- package/dist/lib/models/grokAdapter.d.ts +86 -0
- package/dist/lib/models/grokAdapter.js +142 -0
- package/dist/lib/models/grokLlm.d.ts +22 -45
- package/dist/lib/models/grokLlm.js +22 -67
- package/dist/lib/models/kimiAdapter.d.ts +157 -0
- package/dist/lib/models/kimiAdapter.js +203 -0
- package/dist/lib/models/kimiLlm.d.ts +15 -107
- package/dist/lib/models/kimiLlm.js +17 -153
- package/dist/lib/models/ollamaAdapter.d.ts +125 -0
- package/dist/lib/models/ollamaAdapter.js +155 -0
- package/dist/lib/models/ollamaLlm.d.ts +11 -107
- package/dist/lib/models/ollamaLlm.js +13 -151
- package/dist/lib/models/openAiCompatibleLlm.d.ts +73 -216
- package/dist/lib/models/openAiCompatibleLlm.js +109 -671
- package/dist/lib/models/providerState.d.ts +63 -0
- package/dist/lib/models/providerState.js +61 -0
- package/dist/lib/models/reasoning.d.ts +26 -0
- package/dist/lib/models/reasoning.js +59 -0
- package/dist/lib/models/registry.d.ts +58 -35
- package/dist/lib/models/registry.js +89 -118
- package/dist/lib/models/retry.d.ts +2 -1
- package/dist/lib/models/retry.js +3 -2
- package/dist/lib/models/schemaNormalize.d.ts +98 -0
- package/dist/lib/models/schemaNormalize.js +321 -1
- package/dist/lib/models/tracedGemini.d.ts +41 -0
- package/dist/lib/models/tracedGemini.js +98 -0
- package/dist/lib/models/urls.d.ts +11 -0
- package/dist/lib/models/urls.js +16 -0
- package/dist/lib/net/redirects.d.ts +21 -2
- package/dist/lib/net/redirects.js +11 -34
- package/dist/lib/observability/audit.d.ts +5 -1
- package/dist/lib/observability/lineage.d.ts +14 -0
- package/dist/lib/observability/lineage.js +33 -0
- package/dist/lib/observability/supabaseSpanExporter.d.ts +10 -4
- package/dist/lib/observability/supabaseSpanExporter.js +17 -9
- package/dist/lib/observability/tracer.d.ts +26 -8
- package/dist/lib/observability/tracer.js +43 -18
- package/dist/lib/runtime/adkMemoryBridge.d.ts +46 -0
- package/dist/lib/runtime/adkMemoryBridge.js +68 -0
- package/dist/lib/runtime/adkSessionBridge.d.ts +78 -0
- package/dist/lib/runtime/adkSessionBridge.js +176 -0
- package/dist/lib/runtime/credentials.d.ts +59 -0
- package/dist/lib/runtime/credentials.js +62 -0
- package/dist/lib/runtime/events.d.ts +229 -0
- package/dist/lib/runtime/events.js +274 -0
- package/dist/lib/runtime/logging.d.ts +32 -0
- package/dist/lib/runtime/logging.js +55 -0
- package/dist/lib/runtime/memoryService.d.ts +72 -0
- package/dist/lib/runtime/memoryService.js +25 -0
- package/dist/lib/runtime/native/agentLoop.d.ts +203 -0
- package/dist/lib/runtime/native/agentLoop.js +687 -0
- package/dist/lib/runtime/native/compaction.d.ts +103 -0
- package/dist/lib/runtime/native/compaction.js +191 -0
- package/dist/lib/runtime/native/delegate.d.ts +98 -0
- package/dist/lib/runtime/native/delegate.js +173 -0
- package/dist/lib/runtime/native/history.d.ts +83 -0
- package/dist/lib/runtime/native/history.js +312 -0
- package/dist/lib/runtime/native/interrupts.d.ts +126 -0
- package/dist/lib/runtime/native/interrupts.js +291 -0
- package/dist/lib/runtime/native/request.d.ts +215 -0
- package/dist/lib/runtime/native/request.js +585 -0
- package/dist/lib/runtime/native/selfCorrection.d.ts +106 -0
- package/dist/lib/runtime/native/selfCorrection.js +253 -0
- package/dist/lib/runtime/native/step.d.ts +148 -0
- package/dist/lib/runtime/native/step.js +239 -0
- package/dist/lib/runtime/native/taskMode.d.ts +64 -0
- package/dist/lib/runtime/native/taskMode.js +126 -0
- package/dist/lib/runtime/native/telemetry.d.ts +75 -0
- package/dist/lib/runtime/native/telemetry.js +299 -0
- package/dist/lib/runtime/native/tempState.d.ts +31 -0
- package/dist/lib/runtime/native/tempState.js +56 -0
- package/dist/lib/runtime/nativeTurn.d.ts +86 -0
- package/dist/lib/runtime/nativeTurn.js +107 -0
- package/dist/lib/runtime/questions.d.ts +29 -7
- package/dist/lib/runtime/questions.js +47 -32
- package/dist/lib/runtime/runtimeFlag.d.ts +30 -0
- package/dist/lib/runtime/runtimeFlag.js +50 -0
- package/dist/lib/runtime/sessions.d.ts +166 -0
- package/dist/lib/runtime/sessions.js +201 -0
- package/dist/lib/runtime/syndicateTurn.d.ts +41 -5
- package/dist/lib/runtime/syndicateTurn.js +202 -32
- package/dist/lib/session/supabaseSessionService.d.ts +64 -17
- package/dist/lib/session/supabaseSessionService.js +148 -105
- package/dist/lib/session/transcript.d.ts +68 -22
- package/dist/lib/session/transcript.js +102 -28
- package/dist/lib/skills.js +33 -7
- package/dist/lib/storage/postgres/credentialStore.d.ts +20 -0
- package/dist/lib/storage/postgres/credentialStore.js +82 -0
- package/dist/lib/storage/postgres/index.d.ts +12 -0
- package/dist/lib/storage/postgres/index.js +6 -1
- package/dist/lib/storage/postgres/sessionService.d.ts +43 -15
- package/dist/lib/storage/postgres/sessionService.js +128 -66
- package/dist/lib/syndicateSchema.d.ts +47 -0
- package/dist/lib/syndicateSchema.js +72 -3
- package/dist/lib/toolRegistry.d.ts +15 -2
- package/dist/lib/toolRegistry.js +33 -17
- package/dist/lib/tools/adkTool.d.ts +81 -0
- package/dist/lib/tools/adkTool.js +268 -0
- package/dist/lib/tools/auth.d.ts +118 -0
- package/dist/lib/tools/auth.js +89 -0
- package/dist/lib/tools/collectionsSearchTool.d.ts +7 -6
- package/dist/lib/tools/collectionsSearchTool.js +11 -26
- package/dist/lib/tools/credentialCipher.d.ts +58 -0
- package/dist/lib/tools/credentialCipher.js +116 -0
- package/dist/lib/tools/credentialStore.d.ts +77 -0
- package/dist/lib/tools/credentialStore.js +246 -0
- package/dist/lib/tools/examples.d.ts +43 -0
- package/dist/lib/tools/examples.js +62 -0
- package/dist/lib/tools/generateImageTool.d.ts +15 -6
- package/dist/lib/tools/generateImageTool.js +19 -29
- package/dist/lib/tools/inspectImageTool.d.ts +9 -6
- package/dist/lib/tools/inspectImageTool.js +13 -17
- package/dist/lib/tools/mcpToolFactory.d.ts +42 -1
- package/dist/lib/tools/mcpToolFactory.js +46 -47
- package/dist/lib/tools/memoryTools.d.ts +61 -0
- package/dist/lib/tools/memoryTools.js +119 -0
- package/dist/lib/tools/nativeTools.d.ts +38 -0
- package/dist/lib/tools/nativeTools.js +43 -0
- package/dist/lib/tools/oauthConsent.d.ts +181 -0
- package/dist/lib/tools/oauthConsent.js +330 -0
- package/dist/lib/tools/openapi/call.d.ts +108 -0
- package/dist/lib/tools/openapi/call.js +295 -0
- package/dist/lib/tools/openapi/parse.d.ts +147 -0
- package/dist/lib/tools/openapi/parse.js +570 -0
- package/dist/lib/tools/openapiTools.d.ts +25 -17
- package/dist/lib/tools/openapiTools.js +124 -121
- package/dist/lib/tools/scienceTools.d.ts +14 -14
- package/dist/lib/tools/skillToolset.d.ts +58 -87
- package/dist/lib/tools/skillToolset.js +61 -142
- package/dist/lib/tools/skills/env.d.ts +58 -0
- package/dist/lib/tools/skills/env.js +165 -0
- package/dist/lib/tools/skills/executor.d.ts +114 -0
- package/dist/lib/tools/skills/executor.js +331 -0
- package/dist/lib/tools/skills/frontmatter.d.ts +79 -0
- package/dist/lib/tools/skills/frontmatter.js +215 -0
- package/dist/lib/tools/skills/loader.d.ts +91 -0
- package/dist/lib/tools/skills/loader.js +257 -0
- package/dist/lib/tools/skills/tools.d.ts +187 -0
- package/dist/lib/tools/skills/tools.js +386 -0
- package/dist/lib/tools/taskTools.d.ts +15 -15
- package/dist/lib/tools/tool.d.ts +354 -0
- package/dist/lib/tools/tool.js +304 -0
- package/dist/lib/tools/toolContract.d.ts +89 -33
- package/dist/lib/tools/toolContract.js +104 -82
- package/dist/lib/tools/urlContextTool.d.ts +3 -0
- package/dist/lib/tools/urlContextTool.js +5 -1
- package/dist/lib/tools/webExtractTool.d.ts +2 -2
- package/dist/lib/tools/webExtractTool.js +2 -1
- package/dist/lib/tools/webSearchTool.d.ts +6 -9
- package/dist/lib/tools/webSearchTool.js +14 -59
- package/dist/lib/tools/wikiTools.d.ts +19 -19
- package/dist/lib/tools/wikiTools.js +13 -9
- package/dist/lib/tools/xApiSearchTool.d.ts +2 -2
- package/dist/lib/tools/xApiSearchTool.js +2 -1
- package/dist/lib/tools/xSearchTool.d.ts +7 -9
- package/dist/lib/tools/xSearchTool.js +11 -62
- package/dist/lib/tools/xaiSearchParams.d.ts +41 -0
- package/dist/lib/tools/xaiSearchParams.js +126 -0
- package/dist/lib/wiki/agentRun.d.ts +12 -0
- package/dist/lib/wiki/agentRun.js +72 -34
- package/dist/lib/wiki/entities.d.ts +12 -0
- package/dist/lib/wiki/entities.js +45 -3
- package/dist/lib/workflow/agentNode.d.ts +136 -0
- package/dist/lib/workflow/agentNode.js +274 -0
- package/dist/lib/workflow/graph.d.ts +177 -0
- package/dist/lib/workflow/graph.js +458 -0
- package/dist/lib/workflow/nodeEvents.d.ts +50 -0
- package/dist/lib/workflow/nodeEvents.js +101 -0
- package/dist/lib/workflow/pause.d.ts +122 -0
- package/dist/lib/workflow/pause.js +180 -0
- package/dist/lib/workflow/resume.d.ts +165 -0
- package/dist/lib/workflow/resume.js +440 -0
- package/dist/lib/workflow/route.d.ts +58 -0
- package/dist/lib/workflow/route.js +69 -0
- package/dist/lib/workflow/scheduler.d.ts +415 -0
- package/dist/lib/workflow/scheduler.js +743 -0
- package/dist/lib/workflow/toolNode.d.ts +127 -0
- package/dist/lib/workflow/toolNode.js +236 -0
- package/dist/lib/workflow/turn.d.ts +118 -0
- package/dist/lib/workflow/turn.js +216 -0
- package/dist/lib/workflowConfig.d.ts +3 -2
- package/dist/lib/workflowConfig.js +3 -12
- package/dist/scripts/a2a_server.js +4 -3
- package/dist/scripts/assistant_worker.d.ts +2 -1
- package/dist/scripts/assistant_worker.js +9 -4
- package/dist/scripts/syndicate_chat.js +19 -10
- package/package.json +4 -1
- package/skills/briefs/melchizedek-author.md +3 -2
- package/skills/briefs/melchizedek-models.md +13 -9
- package/skills/briefs/melchizedek.md +3 -3
- package/skills/melchizedek/SKILL.md +2 -1
- package/skills/melchizedek-author/SKILL.md +2 -1
- package/skills/melchizedek-author/assets/minimal.yaml +2 -0
- package/skills/melchizedek-models/SKILL.md +23 -6
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/models/providerState.ts — provider-opaque reasoning state carried on a
|
|
3
|
+
* model content part from one model step to the next (ADR 0046).
|
|
4
|
+
*
|
|
5
|
+
* WHY: some providers want back, on the next request of a tool loop, state
|
|
6
|
+
* only they can read: Anthropic's signed `thinking` and `redacted_thinking`
|
|
7
|
+
* blocks, OpenAI's and xAI's reasoning items, Moonshot's reasoning_content.
|
|
8
|
+
* ADK's request is built from each event's `content` alone (event metadata
|
|
9
|
+
* never reaches it), and @google/genai serializes a part field by field, so
|
|
10
|
+
* the state rides as one extra field on a part the model actually produced:
|
|
11
|
+
*
|
|
12
|
+
* { functionCall: {...}, providerState: { provider, kind, payload } }
|
|
13
|
+
*
|
|
14
|
+
* THE RULES:
|
|
15
|
+
* - The adapter that produced the response writes it, on the part the
|
|
16
|
+
* state belongs before (Claude: the part its signed blocks preceded).
|
|
17
|
+
* - Only an adapter of the same `provider` replays it, and only the `kind`
|
|
18
|
+
* it wrote (and, when `model` is set, only that model). Every other
|
|
19
|
+
* adapter ignores the field, so a model switch between steps drops the
|
|
20
|
+
* state rather than misreading it.
|
|
21
|
+
* - `payload` is opaque to everything but the writer, JSON-serializable,
|
|
22
|
+
* and replayed verbatim. The session services store it with the event;
|
|
23
|
+
* the transcript projection drops it with the rest of a past turn's
|
|
24
|
+
* machinery (lib/session/transcript.ts).
|
|
25
|
+
*/
|
|
26
|
+
/** The field name on a content part. */
|
|
27
|
+
export declare const PROVIDER_STATE_FIELD = "providerState";
|
|
28
|
+
export interface ProviderState {
|
|
29
|
+
/** The writer's provider id (lib/models/providerMap.ts), e.g. `anthropic`. */
|
|
30
|
+
provider: string;
|
|
31
|
+
/** What the payload is, in the writer's terms, e.g. `thinking_blocks`. */
|
|
32
|
+
kind: string;
|
|
33
|
+
/**
|
|
34
|
+
* The model that wrote it, when the provider binds the state to a model
|
|
35
|
+
* (Anthropic's signed thinking): a reader skips state another model wrote.
|
|
36
|
+
*/
|
|
37
|
+
model?: string;
|
|
38
|
+
/** Opaque to everyone but the writer; replayed verbatim. */
|
|
39
|
+
payload: unknown;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The state `provider` wrote on a part, or undefined when the part carries
|
|
43
|
+
* none, another provider's, another kind, a malformed one, or (with `model`
|
|
44
|
+
* given) one another model wrote.
|
|
45
|
+
*/
|
|
46
|
+
export declare function providerStateOf(part: unknown, provider: string, kind: string, model?: string): ProviderState | undefined;
|
|
47
|
+
/** A copy of `part` carrying `state`; the input is not mutated. */
|
|
48
|
+
export declare function withProviderState<T extends object>(part: T, state: ProviderState): T & {
|
|
49
|
+
providerState: ProviderState;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Where the current turn starts in `contents`: the index of the last user
|
|
53
|
+
* content that is not purely tool results, or -1 when there is none (every
|
|
54
|
+
* content is then this turn's, the first included). The model contents
|
|
55
|
+
* after it are this turn's tool loop, the only place an adapter replays its
|
|
56
|
+
* state. Earlier turns' state is left out: dropping it from the front of
|
|
57
|
+
* the history is allowed, and the stored history before it may differ from
|
|
58
|
+
* what the model saw (tool payloads are elided before storage).
|
|
59
|
+
*/
|
|
60
|
+
export declare function currentTurnStart(contents: ReadonlyArray<{
|
|
61
|
+
role?: string;
|
|
62
|
+
parts?: ReadonlyArray<unknown>;
|
|
63
|
+
}>): number;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/models/providerState.ts — provider-opaque reasoning state carried on a
|
|
3
|
+
* model content part from one model step to the next (ADR 0046).
|
|
4
|
+
*
|
|
5
|
+
* WHY: some providers want back, on the next request of a tool loop, state
|
|
6
|
+
* only they can read: Anthropic's signed `thinking` and `redacted_thinking`
|
|
7
|
+
* blocks, OpenAI's and xAI's reasoning items, Moonshot's reasoning_content.
|
|
8
|
+
* ADK's request is built from each event's `content` alone (event metadata
|
|
9
|
+
* never reaches it), and @google/genai serializes a part field by field, so
|
|
10
|
+
* the state rides as one extra field on a part the model actually produced:
|
|
11
|
+
*
|
|
12
|
+
* { functionCall: {...}, providerState: { provider, kind, payload } }
|
|
13
|
+
*
|
|
14
|
+
* THE RULES:
|
|
15
|
+
* - The adapter that produced the response writes it, on the part the
|
|
16
|
+
* state belongs before (Claude: the part its signed blocks preceded).
|
|
17
|
+
* - Only an adapter of the same `provider` replays it, and only the `kind`
|
|
18
|
+
* it wrote (and, when `model` is set, only that model). Every other
|
|
19
|
+
* adapter ignores the field, so a model switch between steps drops the
|
|
20
|
+
* state rather than misreading it.
|
|
21
|
+
* - `payload` is opaque to everything but the writer, JSON-serializable,
|
|
22
|
+
* and replayed verbatim. The session services store it with the event;
|
|
23
|
+
* the transcript projection drops it with the rest of a past turn's
|
|
24
|
+
* machinery (lib/session/transcript.ts).
|
|
25
|
+
*/
|
|
26
|
+
/** The field name on a content part. */
|
|
27
|
+
export const PROVIDER_STATE_FIELD = 'providerState';
|
|
28
|
+
/**
|
|
29
|
+
* The state `provider` wrote on a part, or undefined when the part carries
|
|
30
|
+
* none, another provider's, another kind, a malformed one, or (with `model`
|
|
31
|
+
* given) one another model wrote.
|
|
32
|
+
*/
|
|
33
|
+
export function providerStateOf(part, provider, kind, model) {
|
|
34
|
+
const state = part?.[PROVIDER_STATE_FIELD];
|
|
35
|
+
if (!state || typeof state !== 'object')
|
|
36
|
+
return undefined;
|
|
37
|
+
if (state.provider !== provider || state.kind !== kind)
|
|
38
|
+
return undefined;
|
|
39
|
+
return model !== undefined && state.model !== undefined && state.model !== model ? undefined : state;
|
|
40
|
+
}
|
|
41
|
+
/** A copy of `part` carrying `state`; the input is not mutated. */
|
|
42
|
+
export function withProviderState(part, state) {
|
|
43
|
+
return { ...part, [PROVIDER_STATE_FIELD]: state };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Where the current turn starts in `contents`: the index of the last user
|
|
47
|
+
* content that is not purely tool results, or -1 when there is none (every
|
|
48
|
+
* content is then this turn's, the first included). The model contents
|
|
49
|
+
* after it are this turn's tool loop, the only place an adapter replays its
|
|
50
|
+
* state. Earlier turns' state is left out: dropping it from the front of
|
|
51
|
+
* the history is allowed, and the stored history before it may differ from
|
|
52
|
+
* what the model saw (tool payloads are elided before storage).
|
|
53
|
+
*/
|
|
54
|
+
export function currentTurnStart(contents) {
|
|
55
|
+
for (let i = contents.length - 1; i >= 0; i--) {
|
|
56
|
+
const c = contents[i];
|
|
57
|
+
if (c.role === 'user' && (c.parts ?? []).some((p) => !p?.functionResponse))
|
|
58
|
+
return i;
|
|
59
|
+
}
|
|
60
|
+
return -1;
|
|
61
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/models/reasoning.ts — the generateContentConfig fields a `reasoning:`
|
|
3
|
+
* setting becomes for one model (ADR 0047).
|
|
4
|
+
*
|
|
5
|
+
* WHY HERE: the compiler maps an agent's `reasoning:` key through this, and
|
|
6
|
+
* a model adapter on the contract (lib/models/geminiAdapter.ts) maps a
|
|
7
|
+
* ModelRequest's `reasoning` the same way. Keeping it out of lib/compile.ts
|
|
8
|
+
* keeps ADK out of an adapter's imports. lib/compile.ts re-exports both
|
|
9
|
+
* names, so existing imports keep working.
|
|
10
|
+
*/
|
|
11
|
+
import type { ReasoningLevel, ReasoningSetting } from './contract.ts';
|
|
12
|
+
/**
|
|
13
|
+
* Thinking tokens per level, for the providers that take a budget (Claude,
|
|
14
|
+
* Gemini 2.x). The same table rounds a `budget_tokens` value up to a level
|
|
15
|
+
* for the providers that take only a level or an effort word.
|
|
16
|
+
*/
|
|
17
|
+
export declare const REASONING_BUDGETS: Readonly<Record<ReasoningLevel, number>>;
|
|
18
|
+
/**
|
|
19
|
+
* The generateContentConfig fields a `reasoning:` setting becomes for one
|
|
20
|
+
* model (ADR 0047). `reasoningEffort` is always set, so the gateway (which
|
|
21
|
+
* may serve any id) carries the level too; the Claude adapter reads it first
|
|
22
|
+
* on the adaptive generations (ADR 0049), and the genai SDK drops it from a
|
|
23
|
+
* Gemini request. Claude and Gemini also get the `thinkingConfig` their
|
|
24
|
+
* adapters read.
|
|
25
|
+
*/
|
|
26
|
+
export declare function reasoningConfig(model: string, setting: ReasoningSetting): Record<string, unknown>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { providerForModel } from './providerMap.js';
|
|
2
|
+
/**
|
|
3
|
+
* Thinking tokens per level, for the providers that take a budget (Claude,
|
|
4
|
+
* Gemini 2.x). The same table rounds a `budget_tokens` value up to a level
|
|
5
|
+
* for the providers that take only a level or an effort word.
|
|
6
|
+
*/
|
|
7
|
+
export const REASONING_BUDGETS = { none: 0, low: 2048, medium: 8192, high: 16384 };
|
|
8
|
+
const GEMINI_THINKING_LEVEL = { none: 'MINIMAL', low: 'LOW', medium: 'MEDIUM', high: 'HIGH' };
|
|
9
|
+
/** The smallest level whose budget covers the setting: never less thought than asked. */
|
|
10
|
+
function reasoningLevel(setting) {
|
|
11
|
+
if (typeof setting === 'string')
|
|
12
|
+
return setting;
|
|
13
|
+
const n = setting.budget_tokens;
|
|
14
|
+
return n <= 0 ? 'none' : n <= REASONING_BUDGETS.low ? 'low' : n <= REASONING_BUDGETS.medium ? 'medium' : 'high';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The effort word for `generateContentConfig.reasoningEffort`, which the
|
|
18
|
+
* chat-completions adapters, the gateway and the Responses adapters read.
|
|
19
|
+
* A word the provider lacks becomes its nearest setting above.
|
|
20
|
+
*/
|
|
21
|
+
function reasoningEffort(model, level) {
|
|
22
|
+
switch (providerForModel(model)) {
|
|
23
|
+
case 'openai':
|
|
24
|
+
if (level !== 'none')
|
|
25
|
+
return level;
|
|
26
|
+
// o-series cannot stop reasoning; the first GPT-5 generation says
|
|
27
|
+
// "minimal"; GPT-5.1 and later say "none".
|
|
28
|
+
return /^o\d/.test(model) ? 'low' : /^gpt-5(?![.\d])/.test(model) ? 'minimal' : 'none';
|
|
29
|
+
case 'xai':
|
|
30
|
+
return level === 'none' ? 'low' : level; // Grok 4.5/4.7 cannot stop reasoning
|
|
31
|
+
case 'moonshot':
|
|
32
|
+
return level === 'medium' ? 'high' : level; // K3 has low | high | max
|
|
33
|
+
default:
|
|
34
|
+
return level;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The generateContentConfig fields a `reasoning:` setting becomes for one
|
|
39
|
+
* model (ADR 0047). `reasoningEffort` is always set, so the gateway (which
|
|
40
|
+
* may serve any id) carries the level too; the Claude adapter reads it first
|
|
41
|
+
* on the adaptive generations (ADR 0049), and the genai SDK drops it from a
|
|
42
|
+
* Gemini request. Claude and Gemini also get the `thinkingConfig` their
|
|
43
|
+
* adapters read.
|
|
44
|
+
*/
|
|
45
|
+
export function reasoningConfig(model, setting) {
|
|
46
|
+
const level = reasoningLevel(setting);
|
|
47
|
+
const budget = typeof setting === 'string' ? REASONING_BUDGETS[setting] : setting.budget_tokens;
|
|
48
|
+
const out = { reasoningEffort: reasoningEffort(model, level) };
|
|
49
|
+
const provider = providerForModel(model);
|
|
50
|
+
if (provider === 'anthropic')
|
|
51
|
+
out.thinkingConfig = { thinkingBudget: budget };
|
|
52
|
+
if (provider === 'gemini') {
|
|
53
|
+
// Gemini 3 takes a level; 2.x and older take only a budget. An explicit
|
|
54
|
+
// budget is sent as one on any Gemini, except 0, which is `none`.
|
|
55
|
+
const budgetOnly = /^gemini-[12]\./.test(model);
|
|
56
|
+
out.thinkingConfig = budgetOnly || (typeof setting !== 'string' && budget > 0) ? { thinkingBudget: budget } : { thinkingLevel: GEMINI_THINKING_LEVEL[level] };
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
@@ -3,28 +3,49 @@
|
|
|
3
3
|
* optionality: an agent's YAML declares `model`, and this module makes sure
|
|
4
4
|
* that string reaches the right provider adapter.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* THREE RESOLUTION PATHS, ONE PREFIX TABLE (lib/models/providerMap.ts):
|
|
7
7
|
*
|
|
8
8
|
* 1. registerAvailableProviders() — for entrypoints that pass `model` as a
|
|
9
9
|
* STRING to LlmAgent (scripts/syndicate_chat.ts). Registers every
|
|
10
|
-
*
|
|
11
|
-
* registry then string-matches supportedModels patterns:
|
|
10
|
+
* provider's own ADK class whose credentials exist into the ADK
|
|
11
|
+
* LLMRegistry; the registry then string-matches supportedModels patterns:
|
|
12
12
|
* claude-* → ClaudeLlm gpt-* / o<digit>* → GptLlm
|
|
13
13
|
* grok-* → GrokLlm ollama/<model> → OllamaLlm
|
|
14
14
|
* kimi-* → KimiLlm gemini-* → TracedGemini (ADK's Gemini + llm.request spans)
|
|
15
|
+
* Each non-Gemini class is the ADK shim around its contract adapter,
|
|
16
|
+
* with the provider's own toLlmResponse (ADR 0056, ADR 0057); never a
|
|
17
|
+
* bare adkShimClass, which would lose it.
|
|
15
18
|
*
|
|
16
|
-
* 2. resolveModel() —
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* 2. resolveModel() — the ADK BaseLlm INSTANCE for one id, for BYOK paths
|
|
20
|
+
* (lib/a2a/app.ts), where a per-request API key or endpoint must be
|
|
21
|
+
* injected. The same classes. The YAML model string always wins over
|
|
22
|
+
* the X-Provider header (which only selects a DEFAULT model when the
|
|
23
|
+
* YAML omits `model` — a deprecated affordance).
|
|
24
|
+
*
|
|
25
|
+
* 3. resolveAdapter() — the engine's own ModelAdapter (lib/models/
|
|
26
|
+
* contract.ts, ADR 0048) for one id, with no ADK LLMRegistry, for the
|
|
27
|
+
* native loop (ADR 0045). The same transport rule (the gateway when the
|
|
28
|
+
* direct key is absent), the same BYOK and endpoint injection. Gemini
|
|
29
|
+
* ids get the temporary AdkGeminiAdapter until gate G3, or the engine's
|
|
30
|
+
* GeminiAdapter when GEMINI_ADAPTER=engine or `{ gemini: 'engine' }`
|
|
31
|
+
* asks for it (ADR 0060). resolveAdapterWithFallback() wraps a pair in a
|
|
32
|
+
* FallbackAdapter; the ADK path keeps FallbackLlm(shim, shim) (ADR 0053).
|
|
33
|
+
*
|
|
34
|
+
* Paths 2 and 3 read one routing step (routeFor) and one table per path
|
|
35
|
+
* keyed by provider, so a key or endpoint reaches the same place on both.
|
|
36
|
+
* routeFor and the contract table live in lib/models/adapterResolver.ts,
|
|
37
|
+
* which imports no ADK; `melchizedek-agents/model` exports its resolver,
|
|
38
|
+
* which gives a Gemini id GeminiAdapter (ADR 0068).
|
|
21
39
|
*
|
|
22
40
|
* Register BEFORE constructing any agent: the LLMRegistry caches model→class
|
|
23
41
|
* resolution (LRU), so late registration can be masked by stale cache hits.
|
|
24
42
|
*/
|
|
25
|
-
import {
|
|
26
|
-
import type { BaseLlm, GeminiParams, LlmRequest, LlmResponse } from '@google/adk';
|
|
43
|
+
import type { BaseLlm } from '@google/adk';
|
|
27
44
|
import type { ProviderEndpoint } from './endpoints.ts';
|
|
45
|
+
import type { ModelAdapter } from './contract.ts';
|
|
46
|
+
import type { GeminiAdapterChoice, ResolveAdapterOptions } from './adapterResolver.ts';
|
|
47
|
+
import type { FallbackAdapterOptions } from './fallbackAdapter.ts';
|
|
48
|
+
import { TracedGemini } from './tracedGemini.ts';
|
|
28
49
|
import { GatewayLlm } from './gatewayLlm.ts';
|
|
29
50
|
import { PROVIDERS, providerForModel, providerKeyPresent } from './providerMap.ts';
|
|
30
51
|
import type { ProviderId } from './providerMap.ts';
|
|
@@ -32,30 +53,12 @@ export { providerForModel, providerKeyPresent, PROVIDERS };
|
|
|
32
53
|
export { endpointFromEnv, endpointLabel, endpointProblems, PLATFORMS_FOR, platformFromEnv, providerReady, } from './endpoints.ts';
|
|
33
54
|
export type { Platform, ProviderEndpoint } from './endpoints.ts';
|
|
34
55
|
export type { ProviderId };
|
|
56
|
+
export type { GeminiAdapterChoice, ResolveAdapterOptions };
|
|
35
57
|
export { gatewayConfig, gatewayProblem, gatewayUsable, planTransport, GATEWAYS } from './gateway.ts';
|
|
36
58
|
export type { GatewayId, GatewayInfo, TransportPlan } from './gateway.ts';
|
|
37
59
|
export { describeCapabilities, capabilitySummary } from './capabilities.ts';
|
|
38
60
|
export type { CapabilityReport } from './capabilities.ts';
|
|
39
|
-
export { GatewayLlm };
|
|
40
|
-
export declare class TracedGemini extends Gemini {
|
|
41
|
-
static readonly supportedModels: Array<string | RegExp>;
|
|
42
|
-
/**
|
|
43
|
-
* The Gemini platform (ADR 0023) applies to every construction, the
|
|
44
|
-
* LLMRegistry's included: on Vertex AI the client authenticates with
|
|
45
|
-
* Google Application Default Credentials for the configured project and
|
|
46
|
-
* location, and an AI Studio key (the environment's or a caller's) is not
|
|
47
|
-
* sent. `endpoint` overrides the environment's (the credentials plug point).
|
|
48
|
-
*/
|
|
49
|
-
constructor(params?: GeminiParams & {
|
|
50
|
-
endpoint?: ProviderEndpoint;
|
|
51
|
-
});
|
|
52
|
-
generateContentAsync(llmRequest: LlmRequest, stream?: boolean, abortSignal?: AbortSignal): AsyncGenerator<LlmResponse, void>;
|
|
53
|
-
/** Tags the llm.request span (web_search = Gemini grounding), then
|
|
54
|
-
* delegates to ADK's Gemini. Runs inside the span context. The abort
|
|
55
|
-
* signal is forwarded so a canceled turn stops the request in flight
|
|
56
|
-
* (ADK's Gemini puts it on the genai request config). */
|
|
57
|
-
private tagAndGenerate;
|
|
58
|
-
}
|
|
61
|
+
export { GatewayLlm, TracedGemini };
|
|
59
62
|
export interface ProviderStatus {
|
|
60
63
|
provider: ProviderId;
|
|
61
64
|
label: string;
|
|
@@ -89,7 +92,7 @@ export interface ResolveModelOptions {
|
|
|
89
92
|
/**
|
|
90
93
|
* DEPRECATED — the A2A X-Provider header. Only consulted when `model` is
|
|
91
94
|
* undefined, to pick that provider's default model. A model id in the
|
|
92
|
-
* YAML always wins.
|
|
95
|
+
* YAML always wins. It also names the provider `apiKey` belongs to.
|
|
93
96
|
*/
|
|
94
97
|
defaultProvider?: string;
|
|
95
98
|
/**
|
|
@@ -100,9 +103,29 @@ export interface ResolveModelOptions {
|
|
|
100
103
|
endpoint?: Partial<ProviderEndpoint>;
|
|
101
104
|
}
|
|
102
105
|
/**
|
|
103
|
-
* Resolves a model id (from YAML) to a provider adapter INSTANCE
|
|
104
|
-
* a per-request apiKey where the provider accepts one.
|
|
105
|
-
* undefined, falls back to the default model of
|
|
106
|
-
* Gemini).
|
|
106
|
+
* Resolves a model id (from YAML) to a provider adapter INSTANCE for the ADK
|
|
107
|
+
* runtime, injecting a per-request apiKey where the provider accepts one.
|
|
108
|
+
* When `model` is undefined, falls back to the default model of
|
|
109
|
+
* `defaultProvider` (or Gemini).
|
|
107
110
|
*/
|
|
108
111
|
export declare function resolveModel(model: string | undefined, options?: ResolveModelOptions): BaseLlm;
|
|
112
|
+
/** GEMINI_ADAPTER (`adk`, the default here, or `engine`). Any other value is a configuration error. */
|
|
113
|
+
export declare function geminiAdapterChoice(env?: NodeJS.ProcessEnv): GeminiAdapterChoice;
|
|
114
|
+
/**
|
|
115
|
+
* Resolves a model id to the engine's own ModelAdapter (ADR 0048), from the
|
|
116
|
+
* same prefix table and transport rule as resolveModel, with no ADK
|
|
117
|
+
* LLMRegistry: the provider's adapter when its key (env, BYOK or endpoint)
|
|
118
|
+
* is present, the gateway's when it is absent and MODEL_GATEWAY is set.
|
|
119
|
+
* The adapter opens no span and charges nothing: its caller does (ADR 0053).
|
|
120
|
+
*/
|
|
121
|
+
export declare function resolveAdapter(modelId: string, options?: ResolveAdapterOptions): ModelAdapter;
|
|
122
|
+
/**
|
|
123
|
+
* An agent's model and its `fallback_model:` on the contract path: a
|
|
124
|
+
* FallbackAdapter (ADR 0044) around resolveAdapter's two adapters, or the
|
|
125
|
+
* primary alone when there is no fallback. The caller's key stays with its
|
|
126
|
+
* own provider: unless `keyProvider` says otherwise it belongs to the
|
|
127
|
+
* primary's, so a fallback on another provider resolves from server env.
|
|
128
|
+
* Nothing calls this yet; the ADK path's pair stays
|
|
129
|
+
* FallbackLlm(shim(primary), shim(fallback)) (ADR 0053).
|
|
130
|
+
*/
|
|
131
|
+
export declare function resolveAdapterWithFallback(modelId: string, fallbackId: string | undefined, options?: ResolveAdapterOptions, fallbackOptions?: FallbackAdapterOptions): ModelAdapter;
|
|
@@ -3,105 +3,62 @@
|
|
|
3
3
|
* optionality: an agent's YAML declares `model`, and this module makes sure
|
|
4
4
|
* that string reaches the right provider adapter.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* THREE RESOLUTION PATHS, ONE PREFIX TABLE (lib/models/providerMap.ts):
|
|
7
7
|
*
|
|
8
8
|
* 1. registerAvailableProviders() — for entrypoints that pass `model` as a
|
|
9
9
|
* STRING to LlmAgent (scripts/syndicate_chat.ts). Registers every
|
|
10
|
-
*
|
|
11
|
-
* registry then string-matches supportedModels patterns:
|
|
10
|
+
* provider's own ADK class whose credentials exist into the ADK
|
|
11
|
+
* LLMRegistry; the registry then string-matches supportedModels patterns:
|
|
12
12
|
* claude-* → ClaudeLlm gpt-* / o<digit>* → GptLlm
|
|
13
13
|
* grok-* → GrokLlm ollama/<model> → OllamaLlm
|
|
14
14
|
* kimi-* → KimiLlm gemini-* → TracedGemini (ADK's Gemini + llm.request spans)
|
|
15
|
+
* Each non-Gemini class is the ADK shim around its contract adapter,
|
|
16
|
+
* with the provider's own toLlmResponse (ADR 0056, ADR 0057); never a
|
|
17
|
+
* bare adkShimClass, which would lose it.
|
|
15
18
|
*
|
|
16
|
-
* 2. resolveModel() —
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* 2. resolveModel() — the ADK BaseLlm INSTANCE for one id, for BYOK paths
|
|
20
|
+
* (lib/a2a/app.ts), where a per-request API key or endpoint must be
|
|
21
|
+
* injected. The same classes. The YAML model string always wins over
|
|
22
|
+
* the X-Provider header (which only selects a DEFAULT model when the
|
|
23
|
+
* YAML omits `model` — a deprecated affordance).
|
|
24
|
+
*
|
|
25
|
+
* 3. resolveAdapter() — the engine's own ModelAdapter (lib/models/
|
|
26
|
+
* contract.ts, ADR 0048) for one id, with no ADK LLMRegistry, for the
|
|
27
|
+
* native loop (ADR 0045). The same transport rule (the gateway when the
|
|
28
|
+
* direct key is absent), the same BYOK and endpoint injection. Gemini
|
|
29
|
+
* ids get the temporary AdkGeminiAdapter until gate G3, or the engine's
|
|
30
|
+
* GeminiAdapter when GEMINI_ADAPTER=engine or `{ gemini: 'engine' }`
|
|
31
|
+
* asks for it (ADR 0060). resolveAdapterWithFallback() wraps a pair in a
|
|
32
|
+
* FallbackAdapter; the ADK path keeps FallbackLlm(shim, shim) (ADR 0053).
|
|
33
|
+
*
|
|
34
|
+
* Paths 2 and 3 read one routing step (routeFor) and one table per path
|
|
35
|
+
* keyed by provider, so a key or endpoint reaches the same place on both.
|
|
36
|
+
* routeFor and the contract table live in lib/models/adapterResolver.ts,
|
|
37
|
+
* which imports no ADK; `melchizedek-agents/model` exports its resolver,
|
|
38
|
+
* which gives a Gemini id GeminiAdapter (ADR 0068).
|
|
21
39
|
*
|
|
22
40
|
* Register BEFORE constructing any agent: the LLMRegistry caches model→class
|
|
23
41
|
* resolution (LRU), so late registration can be masked by stale cache hits.
|
|
24
42
|
*/
|
|
25
43
|
import { Gemini, LLMRegistry } from '@google/adk';
|
|
26
|
-
import { endpointFromEnv, endpointProblems,
|
|
27
|
-
import { currentTurnSignal } from '../runtime/turnControl.js';
|
|
28
|
-
import { errorStatus, retryUntilFirstYield } from './retry.js';
|
|
44
|
+
import { endpointFromEnv, endpointProblems, providerReady } from './endpoints.js';
|
|
29
45
|
import { DEFAULT_CLAUDE_MODEL, DEFAULT_GEMINI_MODEL, DEFAULT_GPT_MODEL, DEFAULT_GROK_MODEL, DEFAULT_KIMI_MODEL, DEFAULT_OLLAMA_MODEL, } from '../config.js';
|
|
30
|
-
import {
|
|
46
|
+
import { AdkGeminiAdapter } from './adkGeminiAdapter.js';
|
|
47
|
+
import { adapterResolver, geminiAdapterSetting, normalizeProvider, routeFor, scopedKey } from './adapterResolver.js';
|
|
48
|
+
import { TracedGemini } from './tracedGemini.js';
|
|
31
49
|
import { ClaudeLlm, registerClaudeLlm } from './claudeLlm.js';
|
|
32
50
|
import { GptLlm, registerGptLlm } from './gptLlm.js';
|
|
33
51
|
import { GrokLlm, registerGrokLlm } from './grokLlm.js';
|
|
34
52
|
import { KimiLlm, registerKimiLlm } from './kimiLlm.js';
|
|
35
53
|
import { OllamaLlm, registerOllamaLlm } from './ollamaLlm.js';
|
|
36
54
|
import { GatewayLlm, registerGatewayLlm } from './gatewayLlm.js';
|
|
37
|
-
import { gatewayConfig, gatewayProblem, gatewayUsable
|
|
55
|
+
import { gatewayConfig, gatewayProblem, gatewayUsable } from './gateway.js';
|
|
38
56
|
import { PROVIDERS, providerForModel, providerKeyPresent, } from './providerMap.js';
|
|
39
57
|
export { providerForModel, providerKeyPresent, PROVIDERS };
|
|
40
58
|
export { endpointFromEnv, endpointLabel, endpointProblems, PLATFORMS_FOR, platformFromEnv, providerReady, } from './endpoints.js';
|
|
41
59
|
export { gatewayConfig, gatewayProblem, gatewayUsable, planTransport, GATEWAYS } from './gateway.js';
|
|
42
60
|
export { describeCapabilities, capabilitySummary } from './capabilities.js';
|
|
43
|
-
export { GatewayLlm };
|
|
44
|
-
// ── TracedGemini ─────────────────────────────────────────────────────────────
|
|
45
|
-
// ADK's built-in Gemini adapter, wrapped so Gemini calls emit the same
|
|
46
|
-
// per-request llm.request spans (tokens, latency) as every other provider,
|
|
47
|
-
// and get the shared transient-failure retries (lib/models/retry.ts).
|
|
48
|
-
export class TracedGemini extends Gemini {
|
|
49
|
-
// CRITICAL: reuse Gemini's exact regex instances. The LLMRegistry dict is
|
|
50
|
-
// keyed by the regex OBJECT — registering the same instances REPLACES the
|
|
51
|
-
// built-in Gemini entries instead of adding shadowed duplicates.
|
|
52
|
-
static supportedModels = Gemini.supportedModels;
|
|
53
|
-
/**
|
|
54
|
-
* The Gemini platform (ADR 0023) applies to every construction, the
|
|
55
|
-
* LLMRegistry's included: on Vertex AI the client authenticates with
|
|
56
|
-
* Google Application Default Credentials for the configured project and
|
|
57
|
-
* location, and an AI Studio key (the environment's or a caller's) is not
|
|
58
|
-
* sent. `endpoint` overrides the environment's (the credentials plug point).
|
|
59
|
-
*/
|
|
60
|
-
constructor(params = {}) {
|
|
61
|
-
const { endpoint: given, ...rest } = params;
|
|
62
|
-
const e = given ?? endpointFromEnv('gemini');
|
|
63
|
-
const model = rest.model ? platformModel(e, rest.model) : rest.model;
|
|
64
|
-
super(e.platform === 'vertex'
|
|
65
|
-
? { ...rest, model, apiKey: e.apiKey, vertexai: true, project: e.project, location: e.location }
|
|
66
|
-
: { ...rest, model, ...(e.apiKey && !rest.apiKey ? { apiKey: e.apiKey } : {}) });
|
|
67
|
-
}
|
|
68
|
-
async *generateContentAsync(llmRequest, stream, abortSignal) {
|
|
69
|
-
yield* traceLlmGeneration({ provider: 'gemini', model: this.model, llmRequest }, this.tagAndGenerate(llmRequest, stream, abortSignal ?? currentTurnSignal()));
|
|
70
|
-
}
|
|
71
|
-
/** Tags the llm.request span (web_search = Gemini grounding), then
|
|
72
|
-
* delegates to ADK's Gemini. Runs inside the span context. The abort
|
|
73
|
-
* signal is forwarded so a canceled turn stops the request in flight
|
|
74
|
-
* (ADK's Gemini puts it on the genai request config). */
|
|
75
|
-
async *tagAndGenerate(llmRequest, stream, abortSignal) {
|
|
76
|
-
const hasGrounding = (llmRequest.config?.tools ?? []).some((t) => t && (t.googleSearch || t.googleSearchRetrieval));
|
|
77
|
-
if (hasGrounding)
|
|
78
|
-
setLlmSpanAttribute('llm.web_search.native', true);
|
|
79
|
-
// Retries live here, not in genai's own httpOptions.retryOptions: that
|
|
80
|
-
// hook (p-retry 4, client-level only) ignores the abort signal — it
|
|
81
|
-
// sleeps and re-sends after a canceled turn — honours no Retry-After,
|
|
82
|
-
// does not retry Node's "fetch failed" resets, and replaces a 4xx's
|
|
83
|
-
// error body (e.g. "API key not valid") with a bare statusText. Wrapping
|
|
84
|
-
// the call keeps genai's ApiError intact and applies the same policy as
|
|
85
|
-
// every other adapter. A retry is only made while nothing has been
|
|
86
|
-
// yielded, so a stream that fails mid-reply is surfaced, not replayed.
|
|
87
|
-
// ADK's request preprocessing is idempotent, so re-sending the same
|
|
88
|
-
// llmRequest is safe. Both the registry class and resolveModel()'s
|
|
89
|
-
// per-request instances are TracedGemini, so both get this.
|
|
90
|
-
try {
|
|
91
|
-
yield* retryUntilFirstYield(() => super.generateContentAsync(llmRequest, stream, abortSignal), {
|
|
92
|
-
signal: abortSignal,
|
|
93
|
-
onRetry: ({ retries }) => setLlmSpanAttribute('llm.retries', retries),
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
catch (err) {
|
|
97
|
-
// genai's ApiError carries the status; put it where the ledger reads.
|
|
98
|
-
const status = errorStatus(err);
|
|
99
|
-
if (status !== undefined)
|
|
100
|
-
setLlmSpanAttribute('llm.http_status', status);
|
|
101
|
-
throw err;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
61
|
+
export { GatewayLlm, TracedGemini };
|
|
105
62
|
/** Availability report without side effects (used by demos and key gates). */
|
|
106
63
|
export function providerStatuses() {
|
|
107
64
|
const gw = gatewayUsable() ? gatewayConfig() : null;
|
|
@@ -229,50 +186,64 @@ const DEFAULT_MODEL_FOR = {
|
|
|
229
186
|
ollama: DEFAULT_OLLAMA_MODEL,
|
|
230
187
|
};
|
|
231
188
|
/**
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
189
|
+
* Each provider's ADK class for a direct route: the provider's own exported
|
|
190
|
+
* class, so GptLlm's and the chat-completions shims' toLlmResponse keep the
|
|
191
|
+
* ledger's usage meaning (ADR 0056, ADR 0057). Grok has no platforms, so it
|
|
192
|
+
* takes no endpoint; Kimi takes its base URL; Ollama is local and takes
|
|
193
|
+
* neither.
|
|
194
|
+
*/
|
|
195
|
+
const ADK_LLM = {
|
|
196
|
+
ollama: (r) => new OllamaLlm({ model: r.model }),
|
|
197
|
+
anthropic: (r) => new ClaudeLlm({ model: r.model, apiKey: r.apiKey, endpoint: r.endpoint }),
|
|
198
|
+
openai: (r) => new GptLlm({ model: r.model, apiKey: r.apiKey, endpoint: r.endpoint }),
|
|
199
|
+
xai: (r) => new GrokLlm({ model: r.model, apiKey: r.apiKey }),
|
|
200
|
+
moonshot: (r) => new KimiLlm({ model: r.model, apiKey: r.apiKey, baseUrl: r.endpoint?.baseURL }),
|
|
201
|
+
gemini: (r) => new TracedGemini({ model: r.model, apiKey: r.apiKey, endpoint: r.endpoint }),
|
|
202
|
+
};
|
|
203
|
+
/**
|
|
204
|
+
* Resolves a model id (from YAML) to a provider adapter INSTANCE for the ADK
|
|
205
|
+
* runtime, injecting a per-request apiKey where the provider accepts one.
|
|
206
|
+
* When `model` is undefined, falls back to the default model of
|
|
207
|
+
* `defaultProvider` (or Gemini).
|
|
236
208
|
*/
|
|
237
209
|
export function resolveModel(model, options = {}) {
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
// to a different provider's adapter would override the server's env key
|
|
243
|
-
// (adapters prefer a passed key) and fail auth — e.g. a Gemini key sent to
|
|
244
|
-
// xAI. Cross-provider agents therefore resolve keys from server env.
|
|
245
|
-
const apiKey = providerForModel(model ?? DEFAULT_MODEL_FOR[normalizeProvider(options.defaultProvider)]) === normalizeProvider(options.defaultProvider)
|
|
246
|
-
? options.apiKey
|
|
247
|
-
: undefined;
|
|
248
|
-
// The fallback rule (lib/models/gateway.ts): the direct adapter whenever
|
|
249
|
-
// the provider's key — from env, or the caller's own BYOK key — is
|
|
250
|
-
// present; the gateway stand-in only when it is absent and a gateway is
|
|
251
|
-
// configured. The gateway key is server env only, never a request header.
|
|
252
|
-
const provider = providerForModel(resolved);
|
|
253
|
-
const endpoint = options.endpoint ? mergeEndpoint(provider, options.endpoint) : undefined;
|
|
254
|
-
if (planTransport(resolved, { callerKey: !!apiKey || !!endpoint }).transport === 'gateway') {
|
|
255
|
-
return new GatewayLlm({ model: resolved });
|
|
256
|
-
}
|
|
257
|
-
switch (provider) {
|
|
258
|
-
case 'ollama':
|
|
259
|
-
return new OllamaLlm({ model: resolved });
|
|
260
|
-
case 'anthropic':
|
|
261
|
-
return new ClaudeLlm({ model: resolved, apiKey, endpoint });
|
|
262
|
-
case 'openai':
|
|
263
|
-
return new GptLlm({ model: resolved, apiKey, endpoint });
|
|
264
|
-
case 'xai':
|
|
265
|
-
return new GrokLlm({ model: resolved, apiKey });
|
|
266
|
-
case 'moonshot':
|
|
267
|
-
return new KimiLlm({ model: resolved, apiKey, baseUrl: endpoint?.baseURL });
|
|
268
|
-
case 'gemini':
|
|
269
|
-
return new TracedGemini({ model: resolved, apiKey, endpoint });
|
|
270
|
-
}
|
|
210
|
+
const keyProvider = normalizeProvider(options.defaultProvider);
|
|
211
|
+
const resolved = model ?? DEFAULT_MODEL_FOR[keyProvider];
|
|
212
|
+
const route = routeFor(resolved, scopedKey(resolved, options.apiKey, keyProvider), options.endpoint);
|
|
213
|
+
return route.transport === 'gateway' ? new GatewayLlm({ model: resolved }) : ADK_LLM[route.provider](route);
|
|
271
214
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
215
|
+
// ── Contract adapters (the native runtime) ───────────────────────────────────
|
|
216
|
+
/** GEMINI_ADAPTER (`adk`, the default here, or `engine`). Any other value is a configuration error. */
|
|
217
|
+
export function geminiAdapterChoice(env = process.env) {
|
|
218
|
+
return geminiAdapterSetting(env) ?? 'adk';
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* The contract resolver with the temporary AdkGeminiAdapter (ADR 0060): a
|
|
222
|
+
* Gemini id gets it until gate G3, or the engine's GeminiAdapter when
|
|
223
|
+
* GEMINI_ADAPTER=engine or `{ gemini: 'engine' }` asks for it. The
|
|
224
|
+
* ADK-free resolver in lib/models/adapterResolver.ts, which
|
|
225
|
+
* `melchizedek-agents/model` exports, defaults to GeminiAdapter (ADR 0068).
|
|
226
|
+
*/
|
|
227
|
+
const WITH_ADK_GEMINI = adapterResolver((r) => new AdkGeminiAdapter(r));
|
|
228
|
+
/**
|
|
229
|
+
* Resolves a model id to the engine's own ModelAdapter (ADR 0048), from the
|
|
230
|
+
* same prefix table and transport rule as resolveModel, with no ADK
|
|
231
|
+
* LLMRegistry: the provider's adapter when its key (env, BYOK or endpoint)
|
|
232
|
+
* is present, the gateway's when it is absent and MODEL_GATEWAY is set.
|
|
233
|
+
* The adapter opens no span and charges nothing: its caller does (ADR 0053).
|
|
234
|
+
*/
|
|
235
|
+
export function resolveAdapter(modelId, options = {}) {
|
|
236
|
+
return WITH_ADK_GEMINI.resolveAdapter(modelId, options);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* An agent's model and its `fallback_model:` on the contract path: a
|
|
240
|
+
* FallbackAdapter (ADR 0044) around resolveAdapter's two adapters, or the
|
|
241
|
+
* primary alone when there is no fallback. The caller's key stays with its
|
|
242
|
+
* own provider: unless `keyProvider` says otherwise it belongs to the
|
|
243
|
+
* primary's, so a fallback on another provider resolves from server env.
|
|
244
|
+
* Nothing calls this yet; the ADK path's pair stays
|
|
245
|
+
* FallbackLlm(shim(primary), shim(fallback)) (ADR 0053).
|
|
246
|
+
*/
|
|
247
|
+
export function resolveAdapterWithFallback(modelId, fallbackId, options = {}, fallbackOptions = {}) {
|
|
248
|
+
return WITH_ADK_GEMINI.resolveAdapterWithFallback(modelId, fallbackId, options, fallbackOptions);
|
|
278
249
|
}
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
* THE POLICY:
|
|
15
15
|
* - Bounded: MODEL_RETRY_MAX_ATTEMPTS total attempts (default 3, clamped
|
|
16
16
|
* 1..10; 1 disables retries). Matches the vendor SDKs' 1 + 2 retries.
|
|
17
|
-
* - Retried: HTTP 408/409/425/429/500/502/503/504
|
|
17
|
+
* - Retried: HTTP 408/409/425/429/500/502/503/504/529 (Anthropic's
|
|
18
|
+
* "overloaded"), and connection-level
|
|
18
19
|
* failures that say nothing about the request (ECONNRESET, ETIMEDOUT,
|
|
19
20
|
* EPIPE, ECONNABORTED, EAI_AGAIN, undici socket/connect-timeout). Every
|
|
20
21
|
* other 4xx is the request's own fault and is never repeated.
|
package/dist/lib/models/retry.js
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
* THE POLICY:
|
|
15
15
|
* - Bounded: MODEL_RETRY_MAX_ATTEMPTS total attempts (default 3, clamped
|
|
16
16
|
* 1..10; 1 disables retries). Matches the vendor SDKs' 1 + 2 retries.
|
|
17
|
-
* - Retried: HTTP 408/409/425/429/500/502/503/504
|
|
17
|
+
* - Retried: HTTP 408/409/425/429/500/502/503/504/529 (Anthropic's
|
|
18
|
+
* "overloaded"), and connection-level
|
|
18
19
|
* failures that say nothing about the request (ECONNRESET, ETIMEDOUT,
|
|
19
20
|
* EPIPE, ECONNABORTED, EAI_AGAIN, undici socket/connect-timeout). Every
|
|
20
21
|
* other 4xx is the request's own fault and is never repeated.
|
|
@@ -51,7 +52,7 @@
|
|
|
51
52
|
* setLlmSpanAttribute).
|
|
52
53
|
*/
|
|
53
54
|
export const RETRYABLE_STATUSES = new Set([
|
|
54
|
-
408, 409, 425, 429, 500, 502, 503, 504,
|
|
55
|
+
408, 409, 425, 429, 500, 502, 503, 504, 529,
|
|
55
56
|
]);
|
|
56
57
|
export const RETRYABLE_NETWORK_CODES = new Set([
|
|
57
58
|
'ECONNRESET',
|