melchizedek-agents 0.9.6 → 0.16.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 +272 -0
- package/AGENT_SETUP.md +39 -23
- package/CHANGELOG.md +623 -0
- package/DOCUMENTATION.md +429 -109
- package/QUICKSTART.md +92 -18
- package/README.md +45 -5
- package/config/agents/README.md +46 -1
- package/config/agents/examples/ares.yaml +117 -40
- package/config/agents/examples/assistant.yaml +159 -0
- package/config/agents/examples/augustin.yaml +154 -51
- package/config/agents/examples/cartographers.yaml +91 -23
- package/config/agents/examples/claude.yaml +45 -6
- package/config/agents/examples/council.yaml +23 -8
- package/config/agents/examples/critic.yaml +57 -21
- package/config/agents/examples/delegation.yaml +76 -9
- package/config/agents/examples/hierarchical.yaml +55 -8
- package/config/agents/examples/image_production.yaml +54 -16
- package/config/agents/examples/librarian.yaml +70 -14
- package/config/agents/examples/model_zoo.yaml +105 -29
- package/config/agents/examples/patient_advocate.yaml +102 -34
- package/config/agents/examples/research.yaml +250 -0
- package/config/agents/examples/scribe.yaml +242 -0
- package/config/agents/examples/scriptorium.yaml +87 -24
- package/config/agents/examples/style_council.yaml +31 -9
- package/config/agents/examples/syndicate.yaml +29 -10
- package/config/agents/examples/tutor.yaml +10 -3
- package/config/agents/syndicateSchema.yaml +44 -9
- package/config/agents/templates/README.md +58 -0
- package/config/agents/templates/account_memory.yaml +153 -0
- package/config/agents/templates/case_desk.yaml +188 -0
- package/config/agents/templates/conversational.yaml +110 -0
- package/config/agents/templates/draft_review.yaml +130 -0
- package/config/agents/templates/intake_extractor.yaml +152 -0
- package/config/agents/templates/research_brief.yaml +169 -0
- package/config/agents/templates/research_desk.yaml +152 -0
- package/config/agents/templates/review_panel.yaml +188 -0
- package/config/agents/templates/support_triage.yaml +273 -0
- package/config/agents/templates/systems_operator.yaml +157 -0
- package/db/hardening.sql +202 -0
- package/db/memory_v2.sql +77 -0
- package/db/migrations/0001_base.sql +167 -0
- package/db/migrations/0002_erase_scope.sql +172 -0
- package/db/migrations/0003_postgres_storage.sql +58 -0
- package/db/migrations/0004_usage.sql +94 -0
- package/db/migrations/0005_agent_registry.sql +200 -0
- package/db/migrations/0006_task_leases.sql +25 -0
- package/db/migrations/0007_memory_commit.sql +134 -0
- package/db/migrations/0008_memory_retention.sql +37 -0
- package/db/migrations/0009_task_queue.sql +51 -0
- package/db/migrations/0010_erase_complete.sql +180 -0
- package/db/telemetry.sql +401 -0
- package/demo/README.md +77 -0
- package/demo/a2a_demo.mjs +95 -0
- package/dist/lib/a2a/app.d.ts +253 -0
- package/dist/lib/a2a/app.js +751 -0
- package/dist/lib/a2a/executor.d.ts +167 -0
- package/dist/lib/a2a/executor.js +548 -0
- package/dist/lib/a2a/identity.d.ts +122 -0
- package/dist/lib/a2a/identity.js +254 -0
- package/dist/lib/a2a/policy.d.ts +110 -0
- package/dist/lib/a2a/policy.js +178 -0
- package/dist/lib/a2a/redisLimits.d.ts +26 -0
- package/dist/lib/a2a/redisLimits.js +31 -0
- package/dist/lib/a2a/remoteAgent.d.ts +91 -0
- package/dist/lib/a2a/remoteAgent.js +268 -0
- package/dist/lib/a2a/turnLock.d.ts +28 -0
- package/dist/lib/a2a/turnLock.js +76 -0
- package/dist/lib/compile.d.ts +11 -1
- package/dist/lib/compile.js +109 -8
- package/dist/lib/config.d.ts +7 -7
- package/dist/lib/config.js +7 -7
- package/dist/lib/doctor.d.ts +145 -0
- package/dist/lib/doctor.js +517 -0
- package/dist/lib/grounding.d.ts +2 -2
- package/dist/lib/grounding.js +2 -2
- package/dist/lib/guards/index.d.ts +37 -0
- package/dist/lib/guards/index.js +66 -0
- package/dist/lib/guards/science.d.ts +117 -0
- package/dist/lib/guards/science.js +444 -0
- package/dist/lib/index.d.ts +37 -2
- package/dist/lib/index.js +35 -4
- package/dist/lib/loadEnv.d.ts +23 -11
- package/dist/lib/loadEnv.js +77 -29
- package/dist/lib/loadSyndicate.d.ts +97 -5
- package/dist/lib/loadSyndicate.js +176 -76
- package/dist/lib/memory/erase.d.ts +24 -0
- package/dist/lib/memory/erase.js +47 -0
- package/dist/lib/memory/namespace.d.ts +37 -0
- package/dist/lib/memory/namespace.js +74 -0
- package/dist/lib/memory/providers.d.ts +99 -0
- package/dist/lib/memory/providers.js +240 -0
- package/dist/lib/memory/store.d.ts +74 -0
- package/dist/lib/memory/store.js +108 -0
- package/dist/lib/memory/supabaseMemoryService.d.ts +69 -9
- package/dist/lib/memory/supabaseMemoryService.js +239 -125
- package/dist/lib/models/capabilities.d.ts +103 -0
- package/dist/lib/models/capabilities.js +291 -0
- package/dist/lib/models/claudeLlm.d.ts +10 -1
- package/dist/lib/models/claudeLlm.js +57 -27
- package/dist/lib/models/endpoints.d.ts +100 -0
- package/dist/lib/models/endpoints.js +282 -0
- package/dist/lib/models/gateway.d.ts +107 -0
- package/dist/lib/models/gateway.js +157 -0
- package/dist/lib/models/gatewayLlm.d.ts +57 -0
- package/dist/lib/models/gatewayLlm.js +105 -0
- package/dist/lib/models/gptLlm.d.ts +51 -2
- package/dist/lib/models/gptLlm.js +169 -26
- package/dist/lib/models/grokLlm.d.ts +19 -10
- package/dist/lib/models/grokLlm.js +29 -14
- package/dist/lib/models/ollamaLlm.d.ts +26 -0
- package/dist/lib/models/ollamaLlm.js +43 -1
- package/dist/lib/models/openAiCompatibleLlm.d.ts +67 -2
- package/dist/lib/models/openAiCompatibleLlm.js +200 -37
- package/dist/lib/models/providerMap.js +9 -2
- package/dist/lib/models/registry.d.ts +42 -5
- package/dist/lib/models/registry.js +140 -29
- package/dist/lib/models/retry.d.ts +146 -0
- package/dist/lib/models/retry.js +305 -0
- package/dist/lib/models/schemaNormalize.d.ts +20 -0
- package/dist/lib/models/schemaNormalize.js +43 -0
- package/dist/lib/net/addressGuard.d.ts +60 -0
- package/dist/lib/net/addressGuard.js +216 -0
- package/dist/lib/observability/embeddings.d.ts +11 -2
- package/dist/lib/observability/embeddings.js +18 -14
- package/dist/lib/observability/metrics.d.ts +36 -0
- package/dist/lib/observability/metrics.js +86 -0
- package/dist/lib/observability/redact.d.ts +29 -0
- package/dist/lib/observability/redact.js +102 -0
- package/dist/lib/observability/supabaseSpanExporter.d.ts +2 -0
- package/dist/lib/observability/supabaseSpanExporter.js +22 -6
- package/dist/lib/observability/tracer.d.ts +10 -0
- package/dist/lib/observability/tracer.js +70 -3
- package/dist/lib/persistence/supabaseProvider.d.ts +11 -0
- package/dist/lib/persistence/supabaseProvider.js +32 -6
- package/dist/lib/registry.d.ts +87 -0
- package/dist/lib/registry.js +146 -0
- package/dist/lib/runtime/approvals.d.ts +44 -0
- package/dist/lib/runtime/approvals.js +67 -0
- package/dist/lib/runtime/syndicateTurn.d.ts +233 -0
- package/dist/lib/runtime/syndicateTurn.js +597 -0
- package/dist/lib/runtime/turnControl.d.ts +90 -0
- package/dist/lib/runtime/turnControl.js +131 -0
- package/dist/lib/session/supabaseSessionService.js +1 -1
- package/dist/lib/session/transcript.d.ts +9 -1
- package/dist/lib/session/transcript.js +15 -7
- package/dist/lib/skills.d.ts +50 -0
- package/dist/lib/skills.js +138 -0
- package/dist/lib/storage/postgres/index.d.ts +98 -0
- package/dist/lib/storage/postgres/index.js +146 -0
- package/dist/lib/storage/postgres/memoryStore.d.ts +11 -0
- package/dist/lib/storage/postgres/memoryStore.js +82 -0
- package/dist/lib/storage/postgres/sessionService.d.ts +51 -0
- package/dist/lib/storage/postgres/sessionService.js +225 -0
- package/dist/lib/storage/postgres/taskQueue.d.ts +22 -0
- package/dist/lib/storage/postgres/taskQueue.js +101 -0
- package/dist/lib/storage/postgres/taskStore.d.ts +55 -0
- package/dist/lib/storage/postgres/taskStore.js +168 -0
- package/dist/lib/storage/schema.d.ts +27 -0
- package/dist/lib/storage/schema.js +50 -0
- package/dist/lib/storage/schemaVersion.d.ts +25 -0
- package/dist/lib/storage/schemaVersion.js +46 -0
- package/dist/lib/syndicateSchema.d.ts +275 -0
- package/dist/lib/syndicateSchema.js +534 -0
- package/dist/lib/toolRegistry.d.ts +15 -0
- package/dist/lib/toolRegistry.js +59 -10
- package/dist/lib/tools/collectionsSearchTool.js +1 -1
- package/dist/lib/tools/mcpServe.d.ts +45 -0
- package/dist/lib/tools/mcpServe.js +88 -0
- package/dist/lib/tools/mcpToolFactory.d.ts +2 -0
- package/dist/lib/tools/mcpToolFactory.js +41 -21
- package/dist/lib/tools/science/corrections.d.ts +42 -0
- package/dist/lib/tools/science/corrections.js +115 -0
- package/dist/lib/tools/science/europepmc.d.ts +51 -0
- package/dist/lib/tools/science/europepmc.js +127 -0
- package/dist/lib/tools/science/http.d.ts +31 -0
- package/dist/lib/tools/science/http.js +104 -0
- package/dist/lib/tools/science/openalex.d.ts +30 -0
- package/dist/lib/tools/science/openalex.js +81 -0
- package/dist/lib/tools/science/trials.d.ts +58 -0
- package/dist/lib/tools/science/trials.js +203 -0
- package/dist/lib/tools/science/types.d.ts +69 -0
- package/dist/lib/tools/science/types.js +48 -0
- package/dist/lib/tools/scienceTools.d.ts +100 -0
- package/dist/lib/tools/scienceTools.js +277 -0
- package/dist/lib/tools/taskTools.d.ts +204 -0
- package/dist/lib/tools/taskTools.js +374 -0
- package/dist/lib/tools/toolContract.d.ts +17 -4
- package/dist/lib/tools/toolContract.js +13 -5
- package/dist/lib/tools/webExtractTool.d.ts +13 -10
- package/dist/lib/tools/webExtractTool.js +23 -55
- package/dist/lib/tools/webSearchTool.d.ts +2 -1
- package/dist/lib/tools/webSearchTool.js +4 -3
- package/dist/lib/tools/wikiTools.d.ts +2 -2
- package/dist/lib/tools/wikiTools.js +12 -12
- package/dist/lib/tools/xApiSearchTool.d.ts +194 -0
- package/dist/lib/tools/xApiSearchTool.js +583 -0
- package/dist/lib/tools/xSearchTool.js +1 -1
- package/dist/lib/wiki/agentRun.js +1 -1
- package/dist/lib/wiki/builder.js +21 -6
- package/dist/lib/wiki/dive.js +2 -2
- package/dist/lib/wiki/entities.d.ts +2 -2
- package/dist/lib/wiki/entities.js +7 -7
- package/dist/lib/wiki/extract.js +5 -1
- package/dist/lib/wiki/fill.js +5 -5
- package/dist/lib/wiki/format.d.ts +7 -5
- package/dist/lib/wiki/format.js +2 -2
- package/dist/lib/wiki/graph.js +2 -2
- package/dist/lib/wiki/lint.js +2 -2
- package/dist/lib/wiki/markdown.d.ts +1 -1
- package/dist/lib/wiki/markdown.js +6 -1
- package/dist/lib/wiki/pipeline.js +2 -2
- package/dist/lib/wiki/vault.js +2 -2
- package/dist/scripts/a2a_server.d.ts +17 -11
- package/dist/scripts/a2a_server.js +405 -1028
- package/dist/scripts/assistant_worker.d.ts +33 -0
- package/dist/scripts/assistant_worker.js +193 -0
- package/dist/scripts/db.d.ts +26 -0
- package/dist/scripts/db.js +179 -0
- package/dist/scripts/doctor.d.ts +23 -0
- package/dist/scripts/doctor.js +90 -0
- package/dist/scripts/init.d.ts +43 -0
- package/dist/scripts/init.js +152 -0
- package/dist/scripts/registry.d.ts +25 -0
- package/dist/scripts/registry.js +182 -0
- package/dist/scripts/skills_install.d.ts +7 -0
- package/dist/scripts/skills_install.js +137 -0
- package/dist/scripts/syndicate_chat.js +159 -276
- package/package.json +90 -16
- package/skills/README.md +74 -0
- package/skills/briefs/README.md +16 -0
- package/skills/briefs/_shared.md +16 -0
- package/skills/briefs/melchizedek-author.md +60 -0
- package/skills/briefs/melchizedek-memory.md +47 -0
- package/skills/briefs/melchizedek-models.md +47 -0
- package/skills/briefs/melchizedek-scribe.md +37 -0
- package/skills/briefs/melchizedek-serve.md +56 -0
- package/skills/briefs/melchizedek.md +69 -0
- package/skills/briefs/skills-readme.md +33 -0
- package/skills/melchizedek/SKILL.md +159 -0
- package/skills/melchizedek-author/SKILL.md +99 -0
- package/skills/melchizedek-author/templates/minimal.yaml +60 -0
- package/skills/melchizedek-memory/SKILL.md +138 -0
- package/skills/melchizedek-models/SKILL.md +137 -0
- package/skills/melchizedek-scribe/SKILL.md +72 -0
- package/skills/melchizedek-scribe/templates/brief.md +27 -0
- package/skills/melchizedek-serve/SKILL.md +119 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/models/capabilities.ts — what an agent keeps and loses on the path
|
|
3
|
+
* its model will actually take.
|
|
4
|
+
*
|
|
5
|
+
* WHY this file exists:
|
|
6
|
+
* A model id is the whole routing decision, and some of what an agent
|
|
7
|
+
* declares only exists on one provider: Gemini grounding, xAI's x_search
|
|
8
|
+
* and Collections, the server-side web_search sentinel that every cloud
|
|
9
|
+
* adapter turns into its provider's native search. Until now the only
|
|
10
|
+
* defence against losing one was a one-time console.warn inside an
|
|
11
|
+
* adapter. This module states the loss BEFORE a request is made, per
|
|
12
|
+
* agent, on the RESOLVED transport (direct or gateway), so the doctor
|
|
13
|
+
* (lib/doctor.ts), the A2A startup log (lib/compile.ts) and the ledger
|
|
14
|
+
* (llm.capability.dropped) all say the same thing.
|
|
15
|
+
*
|
|
16
|
+
* It knows nothing about gateways beyond planTransport(); a future
|
|
17
|
+
* transport that restores a native feature changes the table here, not
|
|
18
|
+
* the callers.
|
|
19
|
+
*/
|
|
20
|
+
import { PROVIDERS } from './providerMap.js';
|
|
21
|
+
import { planTransport } from './gateway.js';
|
|
22
|
+
import { nativeSearchOn, PLATFORMS_FOR, platformFromEnv } from './endpoints.js';
|
|
23
|
+
/** The platform a direct path uses (ADR 0023); a misconfigured one reads as direct here, the doctor reports it. */
|
|
24
|
+
function directPlatform(provider) {
|
|
25
|
+
try {
|
|
26
|
+
return platformFromEnv(provider);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return 'direct';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Server-side tool sentinels and the providers whose DIRECT adapter
|
|
34
|
+
* honours them natively. Anything not listed is a client-side function
|
|
35
|
+
* tool and travels on every path.
|
|
36
|
+
*/
|
|
37
|
+
export const SERVER_SIDE_TOOLS = {
|
|
38
|
+
web_search: ['gemini', 'anthropic', 'openai', 'xai'],
|
|
39
|
+
google_search: ['gemini'],
|
|
40
|
+
x_search: ['xai'],
|
|
41
|
+
collections_search: ['xai'],
|
|
42
|
+
};
|
|
43
|
+
export function describeCapabilities(model, tools = [], opts = {}) {
|
|
44
|
+
const plan = planTransport(model, opts);
|
|
45
|
+
const platform = plan.transport === 'direct' && plan.provider !== 'ollama' ? directPlatform(plan.provider) : undefined;
|
|
46
|
+
const native = [];
|
|
47
|
+
const dropped = [];
|
|
48
|
+
const portable = [];
|
|
49
|
+
for (const name of tools) {
|
|
50
|
+
const providers = SERVER_SIDE_TOOLS[name];
|
|
51
|
+
if (!providers) {
|
|
52
|
+
portable.push(name);
|
|
53
|
+
}
|
|
54
|
+
else if (plan.transport === 'direct' && providers.includes(plan.provider) && nativeSearchOn(plan.provider, platform ?? 'direct')) {
|
|
55
|
+
native.push(name);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
dropped.push(name);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
model,
|
|
63
|
+
provider: plan.provider,
|
|
64
|
+
providerLabel: PROVIDERS[plan.provider].label,
|
|
65
|
+
transport: plan.transport,
|
|
66
|
+
...(plan.gateway ? { gateway: plan.gateway.id } : {}),
|
|
67
|
+
...(platform && platform !== 'direct' ? { platform } : {}),
|
|
68
|
+
funded: plan.funded,
|
|
69
|
+
keyEnv: plan.keyEnv,
|
|
70
|
+
native,
|
|
71
|
+
dropped,
|
|
72
|
+
portable,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* One line for a startup log, or undefined when there is nothing to say —
|
|
77
|
+
* a funded direct path with no dropped tool is the quiet default.
|
|
78
|
+
*/
|
|
79
|
+
export function capabilitySummary(agentName, r) {
|
|
80
|
+
if (!r.funded) {
|
|
81
|
+
return `${agentName}: ${r.model} has no route — set ${r.keyEnv ?? 'a provider key'} (or a MODEL_GATEWAY).`;
|
|
82
|
+
}
|
|
83
|
+
const via = r.transport === 'gateway' ? ` via gateway:${r.gateway}` : '';
|
|
84
|
+
if (r.dropped.length === 0) {
|
|
85
|
+
return via ? `${agentName}: ${r.model}${via}.` : undefined;
|
|
86
|
+
}
|
|
87
|
+
const why = r.transport === 'gateway'
|
|
88
|
+
? 'a gateway cannot enable upstream native search'
|
|
89
|
+
: r.provider === 'ollama'
|
|
90
|
+
? 'a local model has no native search'
|
|
91
|
+
: r.platform
|
|
92
|
+
? `native search is not sent to ${r.providerLabel} on ${r.platform}`
|
|
93
|
+
: `${r.providerLabel} has no native ${r.dropped.join('/')}`;
|
|
94
|
+
return `${agentName}: ${r.model}${via} — dropped ${r.dropped.join(', ')} (${why}).`;
|
|
95
|
+
}
|
|
96
|
+
// ── The capability matrix (ADR 0019) ─────────────────────────────────────────
|
|
97
|
+
//
|
|
98
|
+
// "Multi-model" promises that any provider can run any role, orchestrators
|
|
99
|
+
// included. This table states, per resolved path (a direct provider, or the
|
|
100
|
+
// gateway transport), what an agent can rely on. Each cell describes what the
|
|
101
|
+
// ADAPTER SENDS, not how a given model behaves once it receives the request:
|
|
102
|
+
//
|
|
103
|
+
// supported the feature reaches the provider in its native form
|
|
104
|
+
// degraded it reaches the provider in a weaker form; `note` names the loss
|
|
105
|
+
// unsupported the adapter does not send it; `note` says what happens instead
|
|
106
|
+
//
|
|
107
|
+
// `evidence: 'test'` cells are asserted against the real outgoing request body
|
|
108
|
+
// in tests/capabilityMatrix.test.ts, so changing an adapter without changing
|
|
109
|
+
// its row fails a test. `evidence: 'adk'` cells are ADK's own Gemini adapter,
|
|
110
|
+
// which this repo does not build requests for.
|
|
111
|
+
export const CAPABILITIES = [
|
|
112
|
+
'delegation',
|
|
113
|
+
'memory_tools',
|
|
114
|
+
'structured_output',
|
|
115
|
+
'thinking_with_tools',
|
|
116
|
+
'streaming',
|
|
117
|
+
'vision',
|
|
118
|
+
'native_search',
|
|
119
|
+
];
|
|
120
|
+
export const CAPABILITY_LABELS = {
|
|
121
|
+
delegation: 'delegation (subagents as tools)',
|
|
122
|
+
memory_tools: 'memory tools (load_memory)',
|
|
123
|
+
structured_output: 'structured output (outputSchema)',
|
|
124
|
+
thinking_with_tools: 'thinking with tool use',
|
|
125
|
+
streaming: 'token streaming',
|
|
126
|
+
vision: 'image input',
|
|
127
|
+
native_search: 'native web search',
|
|
128
|
+
};
|
|
129
|
+
const ok = (evidence = 'test', note) => note ? { support: 'supported', note, evidence } : { support: 'supported', evidence };
|
|
130
|
+
const degraded = (note) => ({ support: 'degraded', note, evidence: 'test' });
|
|
131
|
+
const unsupported = (note) => ({ support: 'unsupported', note, evidence: 'test' });
|
|
132
|
+
const nativeSearch = (row) => SERVER_SIDE_TOOLS.web_search.includes(row)
|
|
133
|
+
? ok(row === 'gemini' ? 'adk' : 'test')
|
|
134
|
+
: unsupported('no native search on this path; the web_search sentinel is dropped (use web_extract)');
|
|
135
|
+
const RESPONSES_REASONING_NOTE = 'reasoning is requested, but reasoning items are not carried across tool calls, so the model re-reasons each step';
|
|
136
|
+
const CHAT_THINKING_NOTE = 'thinkingConfig budgets are ignored on chat-completions; generateContentConfig.reasoningEffort is the lever';
|
|
137
|
+
export const CAPABILITY_MATRIX = {
|
|
138
|
+
gemini: {
|
|
139
|
+
delegation: ok('adk'),
|
|
140
|
+
memory_tools: ok('adk'),
|
|
141
|
+
structured_output: ok('adk'),
|
|
142
|
+
thinking_with_tools: ok('adk'),
|
|
143
|
+
streaming: ok('adk'),
|
|
144
|
+
vision: ok('adk'),
|
|
145
|
+
native_search: nativeSearch('gemini'),
|
|
146
|
+
},
|
|
147
|
+
anthropic: {
|
|
148
|
+
delegation: ok(),
|
|
149
|
+
memory_tools: ok(),
|
|
150
|
+
structured_output: ok('test', 'sent as a forced tool call; with a thinking budget the tool is offered under tool_choice auto'),
|
|
151
|
+
thinking_with_tools: unsupported('signed thinking blocks are not replayed on tool loops, which Anthropic requires; give a thinking Claude agent no tools'),
|
|
152
|
+
streaming: ok(),
|
|
153
|
+
vision: unsupported('image parts are dropped from the request; route image work to a Gemini, GPT or vision Ollama agent'),
|
|
154
|
+
native_search: nativeSearch('anthropic'),
|
|
155
|
+
},
|
|
156
|
+
openai: {
|
|
157
|
+
delegation: ok(),
|
|
158
|
+
memory_tools: ok(),
|
|
159
|
+
structured_output: ok(),
|
|
160
|
+
thinking_with_tools: degraded(RESPONSES_REASONING_NOTE),
|
|
161
|
+
streaming: ok(),
|
|
162
|
+
vision: ok('test', 'user-turn images only'),
|
|
163
|
+
native_search: nativeSearch('openai'),
|
|
164
|
+
},
|
|
165
|
+
xai: {
|
|
166
|
+
delegation: ok(),
|
|
167
|
+
memory_tools: ok(),
|
|
168
|
+
structured_output: ok(),
|
|
169
|
+
thinking_with_tools: degraded(RESPONSES_REASONING_NOTE),
|
|
170
|
+
streaming: ok(),
|
|
171
|
+
vision: ok('test', 'user-turn images only'),
|
|
172
|
+
native_search: nativeSearch('xai'),
|
|
173
|
+
},
|
|
174
|
+
ollama: {
|
|
175
|
+
delegation: ok(),
|
|
176
|
+
memory_tools: ok(),
|
|
177
|
+
structured_output: degraded('JSON mode only (json_object): the output is JSON but the schema is not enforced'),
|
|
178
|
+
thinking_with_tools: degraded(CHAT_THINKING_NOTE),
|
|
179
|
+
streaming: ok(),
|
|
180
|
+
vision: ok('test', 'needs a vision model, e.g. ollama/qwen3-vl:8b'),
|
|
181
|
+
native_search: nativeSearch('ollama'),
|
|
182
|
+
},
|
|
183
|
+
gateway: {
|
|
184
|
+
delegation: ok(),
|
|
185
|
+
memory_tools: ok(),
|
|
186
|
+
structured_output: ok('test', 'strict json_schema; upstream support varies by model'),
|
|
187
|
+
thinking_with_tools: degraded(CHAT_THINKING_NOTE),
|
|
188
|
+
streaming: ok(),
|
|
189
|
+
vision: ok('test', 'upstream model must accept images'),
|
|
190
|
+
native_search: unsupported('a gateway cannot enable upstream native search; the web_search sentinel is dropped'),
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
/** The matrix cell for a model on the path it will actually take. */
|
|
194
|
+
export function capabilityOf(model, capability, opts = {}) {
|
|
195
|
+
const plan = planTransport(model, opts);
|
|
196
|
+
const row = plan.transport === 'gateway' ? 'gateway' : plan.provider;
|
|
197
|
+
if (row !== 'gateway' && row !== 'ollama') {
|
|
198
|
+
const cell = platformCell(row, directPlatform(row), capability);
|
|
199
|
+
if (cell)
|
|
200
|
+
return { row, ...cell };
|
|
201
|
+
}
|
|
202
|
+
return { row, ...CAPABILITY_MATRIX[row][capability] };
|
|
203
|
+
}
|
|
204
|
+
export function requiredCapabilities(agent) {
|
|
205
|
+
const tools = agent.tools ?? [];
|
|
206
|
+
const needs = new Set();
|
|
207
|
+
if (agent.delegates)
|
|
208
|
+
needs.add('delegation');
|
|
209
|
+
if (tools.includes('load_memory'))
|
|
210
|
+
needs.add('memory_tools');
|
|
211
|
+
if (agent.outputSchema)
|
|
212
|
+
needs.add('structured_output');
|
|
213
|
+
const thinking = agent.generateContentConfig?.thinkingConfig;
|
|
214
|
+
const thinks = !!thinking && (thinking.thinkingBudget ?? 0) !== 0;
|
|
215
|
+
if (thinks && (tools.length > 0 || agent.delegates))
|
|
216
|
+
needs.add('thinking_with_tools');
|
|
217
|
+
if (tools.includes('web_search'))
|
|
218
|
+
needs.add('native_search');
|
|
219
|
+
return [...needs];
|
|
220
|
+
}
|
|
221
|
+
/** The capabilities an agent needs that its resolved path does not fully give it. */
|
|
222
|
+
export function capabilityGaps(model, agent, opts = {}) {
|
|
223
|
+
const gaps = [];
|
|
224
|
+
for (const capability of requiredCapabilities(agent)) {
|
|
225
|
+
const cell = capabilityOf(model, capability, opts);
|
|
226
|
+
if (cell.support === 'supported')
|
|
227
|
+
continue;
|
|
228
|
+
gaps.push({ capability, support: cell.support, row: cell.row, ...(cell.note ? { note: cell.note } : {}) });
|
|
229
|
+
}
|
|
230
|
+
return gaps;
|
|
231
|
+
}
|
|
232
|
+
// ── Cloud platforms (ADR 0023) ───────────────────────────────────────────────
|
|
233
|
+
//
|
|
234
|
+
// On Vertex AI, Bedrock and Azure OpenAI the adapter sends the same request
|
|
235
|
+
// as on the provider's own API (the vendor SDK's platform client speaks the
|
|
236
|
+
// same dialect), so every cell is the provider's row, except where the
|
|
237
|
+
// adapter deliberately sends less. Native search is the one such cell today.
|
|
238
|
+
/** The cell that differs from the provider's row on a platform, or undefined. */
|
|
239
|
+
export function platformCell(provider, platform, capability) {
|
|
240
|
+
if (platform === 'direct' || capability !== 'native_search')
|
|
241
|
+
return undefined;
|
|
242
|
+
if (nativeSearchOn(provider, platform))
|
|
243
|
+
return undefined;
|
|
244
|
+
return unsupported(`not sent on ${PLATFORM_LABEL[platform]}; the web_search sentinel is dropped (use web_extract)`);
|
|
245
|
+
}
|
|
246
|
+
const PLATFORM_LABEL = {
|
|
247
|
+
direct: 'the provider API',
|
|
248
|
+
vertex: 'Vertex AI',
|
|
249
|
+
bedrock: 'Bedrock',
|
|
250
|
+
azure: 'Azure OpenAI',
|
|
251
|
+
};
|
|
252
|
+
const SUPPORT_MARK = { supported: '✓', degraded: '◐', unsupported: '✗' };
|
|
253
|
+
/** The matrix as a Markdown table plus notes, for documentation and the doctor. */
|
|
254
|
+
export function renderCapabilityMatrix() {
|
|
255
|
+
const rows = Object.keys(CAPABILITY_MATRIX);
|
|
256
|
+
const label = (r) => (r === 'gateway' ? 'Gateway (any id)' : PROVIDERS[r].label);
|
|
257
|
+
const lines = [];
|
|
258
|
+
lines.push(`| Capability | ${rows.map(label).join(' | ')} |`);
|
|
259
|
+
lines.push(`|---|${rows.map(() => '---').join('|')}|`);
|
|
260
|
+
const notes = [];
|
|
261
|
+
for (const cap of CAPABILITIES) {
|
|
262
|
+
const cells = rows.map((r) => {
|
|
263
|
+
const cell = CAPABILITY_MATRIX[r][cap];
|
|
264
|
+
if (!cell.note)
|
|
265
|
+
return SUPPORT_MARK[cell.support];
|
|
266
|
+
notes.push(`${label(r)} · ${CAPABILITY_LABELS[cap]}: ${cell.note}.`);
|
|
267
|
+
return `${SUPPORT_MARK[cell.support]}${notes.length}`;
|
|
268
|
+
});
|
|
269
|
+
lines.push(`| ${CAPABILITY_LABELS[cap]} | ${cells.join(' | ')} |`);
|
|
270
|
+
}
|
|
271
|
+
lines.push('');
|
|
272
|
+
lines.push('✓ supported · ◐ degraded · ✗ unsupported. Gemini cells are ADK\'s own adapter; every other cell is asserted against the request the adapter sends.');
|
|
273
|
+
lines.push('');
|
|
274
|
+
notes.forEach((n, i) => lines.push(`${i + 1}. ${n}`));
|
|
275
|
+
lines.push('');
|
|
276
|
+
lines.push('**Cloud platforms** (ADR 0023): the same adapter and request as the provider\'s own API, except as listed. These paths are tested against mocks, not against the live clouds.');
|
|
277
|
+
lines.push('');
|
|
278
|
+
lines.push('| Path | Differs from the provider row |');
|
|
279
|
+
lines.push('|---|---|');
|
|
280
|
+
for (const provider of Object.keys(PLATFORMS_FOR)) {
|
|
281
|
+
for (const platform of PLATFORMS_FOR[provider]) {
|
|
282
|
+
if (platform === 'direct')
|
|
283
|
+
continue;
|
|
284
|
+
const diffs = CAPABILITIES.map((cap) => [cap, platformCell(provider, platform, cap)])
|
|
285
|
+
.filter(([, cell]) => cell)
|
|
286
|
+
.map(([cap, cell]) => `${CAPABILITY_LABELS[cap]}: ${SUPPORT_MARK[cell.support]} ${cell.note ?? ''}`.trim());
|
|
287
|
+
lines.push(`| ${PROVIDERS[provider].label} on ${PLATFORM_LABEL[platform]} | ${diffs.join('; ') || 'nothing'} |`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return lines.join('\n');
|
|
291
|
+
}
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
import { BaseLlm } from '@google/adk';
|
|
49
49
|
import type { LlmRequest, LlmResponse } from '@google/adk';
|
|
50
50
|
import type { BaseLlmConnection } from '@google/adk';
|
|
51
|
+
import type { ProviderEndpoint } from './endpoints.ts';
|
|
51
52
|
/** ADK toolsDict → Anthropic tool definitions (lowercase schemas; the
|
|
52
53
|
* web_search sentinel becomes Anthropic's native server tool). */
|
|
53
54
|
export declare function buildAnthropicTools(llmRequest: LlmRequest): any[];
|
|
@@ -58,9 +59,17 @@ export declare class ClaudeLlm extends BaseLlm {
|
|
|
58
59
|
*/
|
|
59
60
|
static readonly supportedModels: Array<string | RegExp>;
|
|
60
61
|
private apiKey?;
|
|
61
|
-
|
|
62
|
+
private endpoint?;
|
|
63
|
+
private searchDropWarned;
|
|
64
|
+
/**
|
|
65
|
+
* `endpoint` (ADR 0023): where the request goes — Anthropic's API (or a
|
|
66
|
+
* proxy at its base URL), Bedrock, or Vertex AI. Default: the environment's
|
|
67
|
+
* (`ANTHROPIC_PLATFORM`).
|
|
68
|
+
*/
|
|
69
|
+
constructor({ model, apiKey, endpoint }: {
|
|
62
70
|
model: string;
|
|
63
71
|
apiKey?: string;
|
|
72
|
+
endpoint?: ProviderEndpoint;
|
|
64
73
|
});
|
|
65
74
|
/**
|
|
66
75
|
* Main generation method called by the ADK Runner for every turn.
|
|
@@ -46,9 +46,11 @@
|
|
|
46
46
|
* translated to Anthropic's tool_use / tool_result blocks.
|
|
47
47
|
*/
|
|
48
48
|
import { BaseLlm, LLMRegistry } from '@google/adk';
|
|
49
|
-
import { traceLlmGeneration, setLlmSpanAttribute, } from
|
|
50
|
-
import { wantsWebSearch, isWebSearchSentinel, } from
|
|
51
|
-
import {
|
|
49
|
+
import { traceLlmGeneration, setLlmSpanAttribute, } from '../observability/tracer.js';
|
|
50
|
+
import { wantsWebSearch, isWebSearchSentinel, } from '../tools/webSearchTool.js';
|
|
51
|
+
import { providerRequestOptions } from '../runtime/turnControl.js';
|
|
52
|
+
import { toLowercaseJsonSchema, toolDeclarationFor } from './schemaNormalize.js';
|
|
53
|
+
import { claudeClientSpec, endpointFromEnv, instantiateClient, nativeSearchOn, platformModel, SdkMissingError } from './endpoints.js';
|
|
52
54
|
/** Anthropic's minimum extended-thinking budget. */
|
|
53
55
|
/** Name of the synthetic tool that carries an ADK outputSchema answer. */
|
|
54
56
|
const STRUCTURED_OUTPUT_TOOL = 'structured_output';
|
|
@@ -61,12 +63,12 @@ export function buildAnthropicTools(llmRequest) {
|
|
|
61
63
|
for (const [, tool] of Object.entries(llmRequest.toolsDict ?? {})) {
|
|
62
64
|
if (isWebSearchSentinel(tool))
|
|
63
65
|
continue; // added as a server tool below
|
|
64
|
-
const
|
|
65
|
-
if (
|
|
66
|
+
const decl = toolDeclarationFor(tool);
|
|
67
|
+
if (decl) {
|
|
66
68
|
anthropicTools.push({
|
|
67
|
-
name:
|
|
68
|
-
description:
|
|
69
|
-
input_schema:
|
|
69
|
+
name: decl.name,
|
|
70
|
+
description: decl.description,
|
|
71
|
+
input_schema: decl.parameters,
|
|
70
72
|
});
|
|
71
73
|
}
|
|
72
74
|
}
|
|
@@ -89,9 +91,17 @@ export class ClaudeLlm extends BaseLlm {
|
|
|
89
91
|
*/
|
|
90
92
|
static supportedModels = [/^claude-.+/];
|
|
91
93
|
apiKey;
|
|
92
|
-
|
|
94
|
+
endpoint;
|
|
95
|
+
searchDropWarned = false;
|
|
96
|
+
/**
|
|
97
|
+
* `endpoint` (ADR 0023): where the request goes — Anthropic's API (or a
|
|
98
|
+
* proxy at its base URL), Bedrock, or Vertex AI. Default: the environment's
|
|
99
|
+
* (`ANTHROPIC_PLATFORM`).
|
|
100
|
+
*/
|
|
101
|
+
constructor({ model, apiKey, endpoint }) {
|
|
93
102
|
super({ model });
|
|
94
103
|
this.apiKey = apiKey;
|
|
104
|
+
this.endpoint = endpoint;
|
|
95
105
|
}
|
|
96
106
|
/**
|
|
97
107
|
* Main generation method called by the ADK Runner for every turn.
|
|
@@ -105,29 +115,36 @@ export class ClaudeLlm extends BaseLlm {
|
|
|
105
115
|
yield* traceLlmGeneration({ provider: 'anthropic', model: this.model, llmRequest }, this.generateInner(llmRequest, stream));
|
|
106
116
|
}
|
|
107
117
|
async *generateInner(llmRequest, stream) {
|
|
108
|
-
|
|
109
|
-
|
|
118
|
+
let endpoint;
|
|
119
|
+
try {
|
|
120
|
+
endpoint = this.endpoint ?? endpointFromEnv('anthropic');
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
yield { errorCode: 'ENDPOINT_MISCONFIGURED', errorMessage: err.message };
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const spec = claudeClientSpec(endpoint, this.apiKey || endpoint.apiKey || process.env.ANTHROPIC_API_KEY);
|
|
127
|
+
if ('error' in spec) {
|
|
110
128
|
yield {
|
|
111
|
-
errorCode: 'MISSING_API_KEY',
|
|
112
|
-
errorMessage:
|
|
129
|
+
errorCode: endpoint.platform === 'direct' ? 'MISSING_API_KEY' : 'ENDPOINT_MISCONFIGURED',
|
|
130
|
+
errorMessage: spec.error,
|
|
113
131
|
};
|
|
114
132
|
return;
|
|
115
133
|
}
|
|
116
|
-
// Dynamic import — only loads
|
|
117
|
-
//
|
|
118
|
-
|
|
134
|
+
// Dynamic import — only loads the SDK (Anthropic's, or its Bedrock or
|
|
135
|
+
// Vertex AI client) when actually called, so the framework boots without
|
|
136
|
+
// it for users of other providers. All three share the Messages API.
|
|
137
|
+
let client;
|
|
119
138
|
try {
|
|
120
|
-
|
|
121
|
-
Anthropic = mod.default ?? mod.Anthropic;
|
|
139
|
+
client = await instantiateClient(spec);
|
|
122
140
|
}
|
|
123
|
-
catch {
|
|
141
|
+
catch (err) {
|
|
124
142
|
yield {
|
|
125
|
-
errorCode: 'SDK_NOT_INSTALLED',
|
|
126
|
-
errorMessage:
|
|
143
|
+
errorCode: err instanceof SdkMissingError ? 'SDK_NOT_INSTALLED' : 'ENDPOINT_MISCONFIGURED',
|
|
144
|
+
errorMessage: err.message,
|
|
127
145
|
};
|
|
128
146
|
return;
|
|
129
147
|
}
|
|
130
|
-
const client = new Anthropic({ apiKey });
|
|
131
148
|
// ── Translate ADK Contents → Anthropic messages ──────────────────────────
|
|
132
149
|
const systemParts = [];
|
|
133
150
|
const messages = [];
|
|
@@ -186,9 +203,22 @@ export class ClaudeLlm extends BaseLlm {
|
|
|
186
203
|
systemParts.unshift(text);
|
|
187
204
|
}
|
|
188
205
|
// ── Build Anthropic tool definitions from ADK toolsDict ──────────────────
|
|
189
|
-
|
|
206
|
+
let anthropicTools = buildAnthropicTools(llmRequest);
|
|
190
207
|
if (wantsWebSearch(llmRequest)) {
|
|
191
|
-
|
|
208
|
+
if (nativeSearchOn('anthropic', endpoint.platform)) {
|
|
209
|
+
setLlmSpanAttribute('llm.web_search.native', true);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
// Not sent off Anthropic's own API (lib/models/endpoints.ts); the
|
|
213
|
+
// doctor and the capability matrix state this before any request.
|
|
214
|
+
anthropicTools = anthropicTools.filter((t) => t.type !== 'web_search_20250305');
|
|
215
|
+
setLlmSpanAttribute('llm.web_search.omitted', true);
|
|
216
|
+
setLlmSpanAttribute('llm.capability.dropped', 'web_search');
|
|
217
|
+
if (!this.searchDropWarned) {
|
|
218
|
+
this.searchDropWarned = true;
|
|
219
|
+
console.warn(`⚠ web_search is not sent to Claude on ${endpoint.platform}; the agent answers without it (use web_extract).`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
192
222
|
}
|
|
193
223
|
// ── Extended thinking (Gemini thinkingConfig → Anthropic thinking) ───────
|
|
194
224
|
const cfg = llmRequest.config ?? {};
|
|
@@ -219,7 +249,7 @@ export class ClaudeLlm extends BaseLlm {
|
|
|
219
249
|
: undefined;
|
|
220
250
|
const allTools = structuredTool ? [...anthropicTools, structuredTool] : anthropicTools;
|
|
221
251
|
const requestBase = {
|
|
222
|
-
model: this.model,
|
|
252
|
+
model: platformModel(endpoint, this.model),
|
|
223
253
|
max_tokens: maxTokens,
|
|
224
254
|
system: systemParts.join('\n\n') || undefined,
|
|
225
255
|
messages,
|
|
@@ -231,7 +261,7 @@ export class ClaudeLlm extends BaseLlm {
|
|
|
231
261
|
try {
|
|
232
262
|
if (stream) {
|
|
233
263
|
// Streaming path
|
|
234
|
-
const streamResponse = await client.messages.stream(requestBase);
|
|
264
|
+
const streamResponse = await client.messages.stream(requestBase, providerRequestOptions());
|
|
235
265
|
for await (const chunk of streamResponse) {
|
|
236
266
|
if (chunk.type === 'content_block_delta') {
|
|
237
267
|
if (chunk.delta.type === 'text_delta') {
|
|
@@ -266,7 +296,7 @@ export class ClaudeLlm extends BaseLlm {
|
|
|
266
296
|
}
|
|
267
297
|
else {
|
|
268
298
|
// Non-streaming path
|
|
269
|
-
const response = await client.messages.create(requestBase);
|
|
299
|
+
const response = await client.messages.create(requestBase, providerRequestOptions());
|
|
270
300
|
// Thinking first, as a display-only partial.
|
|
271
301
|
const thinkingText = (response.content ?? [])
|
|
272
302
|
.filter((b) => b.type === 'thinking')
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/models/endpoints.ts — where each provider's requests go and how they
|
|
3
|
+
* authenticate (ADR 0023).
|
|
4
|
+
*
|
|
5
|
+
* The model id still picks the provider (lib/models/providerMap.ts). This
|
|
6
|
+
* module picks the provider's PLATFORM: its own public API, or the cloud an
|
|
7
|
+
* enterprise reaches it through, plus a base URL for an internal proxy and a
|
|
8
|
+
* map from the YAML id to the id (or deployment) that platform knows.
|
|
9
|
+
*
|
|
10
|
+
* provider platforms credential on a cloud platform
|
|
11
|
+
* gemini direct | vertex Google Application Default Credentials
|
|
12
|
+
* anthropic direct | bedrock | vertex AWS credential chain / Google ADC
|
|
13
|
+
* openai direct | azure AZURE_OPENAI_API_KEY, else Entra ID
|
|
14
|
+
* xai, ollama direct only
|
|
15
|
+
*
|
|
16
|
+
* Configuration comes from the environment (`endpointFromEnv`) or, per
|
|
17
|
+
* request, from the server's `credentials` plug point, which may return an
|
|
18
|
+
* API key or a partial endpoint merged over the environment's.
|
|
19
|
+
*
|
|
20
|
+
* The Vertex AI, Bedrock and Azure paths are built on each vendor SDK's own
|
|
21
|
+
* client for that platform and are tested against mocks; they have not been
|
|
22
|
+
* run against the live clouds from this repository. The doctor says so.
|
|
23
|
+
*/
|
|
24
|
+
import type { ProviderId } from './providerMap.ts';
|
|
25
|
+
export type Platform = 'direct' | 'vertex' | 'bedrock' | 'azure';
|
|
26
|
+
export declare const PLATFORMS_FOR: Record<ProviderId, readonly Platform[]>;
|
|
27
|
+
export interface ProviderEndpoint {
|
|
28
|
+
platform: Platform;
|
|
29
|
+
/** direct: an OpenAI- or Anthropic-compatible proxy in front of the vendor API. */
|
|
30
|
+
baseURL?: string;
|
|
31
|
+
/** A static key: the environment's, a caller's, or one a secret manager returned. */
|
|
32
|
+
apiKey?: string;
|
|
33
|
+
/** A bearer-token source called per client (Entra ID, a secret manager). openai/azure only. */
|
|
34
|
+
token?: () => Promise<string>;
|
|
35
|
+
/** vertex: the Google Cloud project and location (region, or `global`). */
|
|
36
|
+
project?: string;
|
|
37
|
+
location?: string;
|
|
38
|
+
/** bedrock: the AWS region. */
|
|
39
|
+
region?: string;
|
|
40
|
+
/** YAML model id → the id or deployment name this platform uses. Unlisted ids pass through. */
|
|
41
|
+
models?: Record<string, string>;
|
|
42
|
+
}
|
|
43
|
+
/** The platform the environment selects for a provider (default direct). */
|
|
44
|
+
export declare function platformFromEnv(provider: ProviderId, env?: NodeJS.ProcessEnv): Platform;
|
|
45
|
+
/** A provider's endpoint as the environment configures it. */
|
|
46
|
+
export declare function endpointFromEnv(provider: ProviderId, env?: NodeJS.ProcessEnv): ProviderEndpoint;
|
|
47
|
+
/** Azure OpenAI's v1 API, which the plain OpenAI client speaks. */
|
|
48
|
+
export declare function azureBaseURL(endpoint: string): string;
|
|
49
|
+
/** The id to send: the platform's name for a YAML model id. */
|
|
50
|
+
export declare function platformModel(endpoint: ProviderEndpoint | undefined, model: string): string;
|
|
51
|
+
/** What is missing for an endpoint to be usable; empty when complete. */
|
|
52
|
+
export declare function endpointProblems(provider: ProviderId, e: ProviderEndpoint): string[];
|
|
53
|
+
/**
|
|
54
|
+
* True when a provider can be called: its key is present on the direct
|
|
55
|
+
* platform, or its cloud platform is fully configured (the cloud's own
|
|
56
|
+
* credential chain is then trusted to authenticate; the doctor says it was
|
|
57
|
+
* not checked).
|
|
58
|
+
*/
|
|
59
|
+
export declare function providerReady(provider: ProviderId): boolean;
|
|
60
|
+
/** Merge a per-request endpoint (the credentials plug point) over the environment's. */
|
|
61
|
+
export declare function mergeEndpoint(provider: ProviderId, override: Partial<ProviderEndpoint> | undefined): ProviderEndpoint;
|
|
62
|
+
/** The label for logs and the doctor: "Claude on Bedrock (us-east-1)". */
|
|
63
|
+
export declare function endpointLabel(provider: ProviderId, e: ProviderEndpoint): string;
|
|
64
|
+
/** How a cloud platform authenticates, for the doctor. */
|
|
65
|
+
export declare function credentialSource(provider: ProviderId, e: ProviderEndpoint): string;
|
|
66
|
+
/** The vendor SDK package a platform needs, beyond the direct one. */
|
|
67
|
+
export declare const PLATFORM_SDK: Partial<Record<`${ProviderId}/${Platform}`, string>>;
|
|
68
|
+
/** Which SDK class to construct, with what options. */
|
|
69
|
+
export interface ClientSpec {
|
|
70
|
+
module: string;
|
|
71
|
+
/** Export names tried in order (default export first for the direct SDKs). */
|
|
72
|
+
exportNames: string[];
|
|
73
|
+
options: Record<string, unknown>;
|
|
74
|
+
}
|
|
75
|
+
export type SdkImporter = (module: string) => Promise<any>;
|
|
76
|
+
/**
|
|
77
|
+
* Replace how vendor SDKs are imported: for tests (a mock Bedrock client)
|
|
78
|
+
* and for bundlers that need static imports. Undefined restores the default.
|
|
79
|
+
*/
|
|
80
|
+
export declare function setSdkImporter(importer: SdkImporter | undefined): void;
|
|
81
|
+
/** Import a spec's module and construct its client. Throws SdkMissingError when absent. */
|
|
82
|
+
export declare function instantiateClient(spec: ClientSpec): Promise<any>;
|
|
83
|
+
export declare class SdkMissingError extends Error {
|
|
84
|
+
readonly module: string;
|
|
85
|
+
constructor(module: string);
|
|
86
|
+
}
|
|
87
|
+
/** The Anthropic client for an endpoint, or why it cannot be built. */
|
|
88
|
+
export declare function claudeClientSpec(e: ProviderEndpoint, apiKey: string | undefined): ClientSpec | {
|
|
89
|
+
error: string;
|
|
90
|
+
};
|
|
91
|
+
/** The scope Azure OpenAI tokens are issued for. */
|
|
92
|
+
export declare const AZURE_COGNITIVE_SCOPE = "https://cognitiveservices.azure.com/.default";
|
|
93
|
+
/**
|
|
94
|
+
* A bearer-token source from Entra ID (DefaultAzureCredential: managed
|
|
95
|
+
* identity, workload identity, the Azure CLI...), shared by every client in
|
|
96
|
+
* the process so tokens are cached and refreshed once.
|
|
97
|
+
*/
|
|
98
|
+
export declare function entraTokenSource(): () => Promise<string>;
|
|
99
|
+
/** Platforms whose adapter does not send the provider's native web search. */
|
|
100
|
+
export declare function nativeSearchOn(provider: ProviderId, platform: Platform): boolean;
|