@yanlinglabs/winter-agent-runtime 0.0.27
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/LICENSE +21 -0
- package/NOTICE +41 -0
- package/README.md +64 -0
- package/dist/checkpoint/file-history.d.ts +81 -0
- package/dist/checkpoint/rewind.d.ts +55 -0
- package/dist/checkpoint/seam.d.ts +47 -0
- package/dist/checkpoint/sink.d.ts +66 -0
- package/dist/commands/builtins-listing.d.ts +40 -0
- package/dist/commands/resolver.d.ts +103 -0
- package/dist/commands/seam.d.ts +53 -0
- package/dist/compaction/controller.d.ts +23 -0
- package/dist/compaction/retention.d.ts +35 -0
- package/dist/compaction/seam.d.ts +115 -0
- package/dist/compaction/summarizer.d.ts +79 -0
- package/dist/context/agent-listing.d.ts +39 -0
- package/dist/context/assembler.d.ts +46 -0
- package/dist/context/attachments.d.ts +104 -0
- package/dist/context/dynamic-sections.d.ts +31 -0
- package/dist/context/git-fixture.d.ts +18 -0
- package/dist/context/git-status.d.ts +16 -0
- package/dist/context/imports.d.ts +22 -0
- package/dist/context/injection.d.ts +53 -0
- package/dist/context/memory-key.d.ts +46 -0
- package/dist/context/memory.d.ts +28 -0
- package/dist/context/minimal-prompt.d.ts +5 -0
- package/dist/context/output-styles.d.ts +68 -0
- package/dist/context/plan-mode.d.ts +29 -0
- package/dist/context/request-layout.d.ts +138 -0
- package/dist/context/rules.d.ts +63 -0
- package/dist/context/seam.d.ts +136 -0
- package/dist/context/tool-epoch.d.ts +118 -0
- package/dist/context/winter-code-preset.d.ts +39 -0
- package/dist/context/winter-md.d.ts +81 -0
- package/dist/embedded-host.d.ts +48 -0
- package/dist/embedded-host.js +155 -0
- package/dist/embedded-protocol.d.ts +44 -0
- package/dist/embedded-worker.d.ts +1 -0
- package/dist/embedded-worker.js +74 -0
- package/dist/embedded.d.ts +34 -0
- package/dist/embedded.js +9 -0
- package/dist/engine.d.ts +1298 -0
- package/dist/hooks/additional-context.d.ts +21 -0
- package/dist/hooks/bounds.d.ts +6 -0
- package/dist/hooks/bridge-invoker.d.ts +3 -0
- package/dist/hooks/command-invoker.d.ts +52 -0
- package/dist/hooks/from-config.d.ts +31 -0
- package/dist/hooks/hook-stage.d.ts +25 -0
- package/dist/hooks/input-validator.d.ts +6 -0
- package/dist/hooks/reducer.d.ts +74 -0
- package/dist/hooks/registry.d.ts +33 -0
- package/dist/hooks/runner.d.ts +105 -0
- package/dist/index-584yahed.js +6037 -0
- package/dist/index-97t2rmtf.js +42 -0
- package/dist/index-9qgkpv56.js +27183 -0
- package/dist/index-bef62z3r.js +437 -0
- package/dist/index-rkhh0457.js +187 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +353 -0
- package/dist/main.d.ts +1 -0
- package/dist/mcp/client.d.ts +105 -0
- package/dist/mcp/control-seam.d.ts +25 -0
- package/dist/mcp/control.d.ts +5 -0
- package/dist/mcp/elicitation.d.ts +35 -0
- package/dist/mcp/env.d.ts +12 -0
- package/dist/mcp/lifecycle.d.ts +142 -0
- package/dist/mcp/output-cap.d.ts +15 -0
- package/dist/mcp/state.d.ts +24 -0
- package/dist/mcp/test-fixtures.d.ts +88 -0
- package/dist/mcp/transports/__fixtures__/stdio-server.d.ts +1 -0
- package/dist/mcp/transports/http.d.ts +5 -0
- package/dist/mcp/transports/sdk.d.ts +5 -0
- package/dist/mcp/transports/sse.d.ts +3 -0
- package/dist/mcp/transports/stdio.d.ts +35 -0
- package/dist/mcp/winter-server.d.ts +2 -0
- package/dist/messaging/reference-adapter.d.ts +88 -0
- package/dist/messaging/router.d.ts +8 -0
- package/dist/paths/project-dir-name.d.ts +2 -0
- package/dist/paths/temp.d.ts +25 -0
- package/dist/permissions/approvals.d.ts +107 -0
- package/dist/permissions/auto/caches.d.ts +53 -0
- package/dist/permissions/auto/config.d.ts +37 -0
- package/dist/permissions/auto/engine.d.ts +74 -0
- package/dist/permissions/auto/envelope.d.ts +45 -0
- package/dist/permissions/auto/inheritance.d.ts +27 -0
- package/dist/permissions/edit-recognition.d.ts +30 -0
- package/dist/permissions/evaluator.d.ts +284 -0
- package/dist/permissions/file-rules.d.ts +384 -0
- package/dist/permissions/grammar.d.ts +113 -0
- package/dist/permissions/paths.d.ts +32 -0
- package/dist/permissions/policy-state.d.ts +64 -0
- package/dist/permissions/prompt-stage.d.ts +3 -0
- package/dist/permissions/protected.d.ts +54 -0
- package/dist/permissions/ruleset.d.ts +134 -0
- package/dist/permissions/shell-structure.d.ts +41 -0
- package/dist/plugins/bundle.d.ts +100 -0
- package/dist/plugins/installed.d.ts +30 -0
- package/dist/plugins/loader.d.ts +56 -0
- package/dist/plugins/manifest.d.ts +115 -0
- package/dist/production-wiring.d.ts +340 -0
- package/dist/protocol/channel.d.ts +22 -0
- package/dist/provider/advisor-route.d.ts +47 -0
- package/dist/provider/bridge.d.ts +124 -0
- package/dist/provider/classifier/model-classifier.d.ts +82 -0
- package/dist/provider/classifier/prompt.d.ts +62 -0
- package/dist/provider/classifier/verdict-schema.d.ts +83 -0
- package/dist/provider/credential-api.d.ts +160 -0
- package/dist/provider/family-listing.d.ts +27 -0
- package/dist/provider/first-party.d.ts +4 -0
- package/dist/provider/keychain-store.d.ts +59 -0
- package/dist/provider/lean-prompt.d.ts +7 -0
- package/dist/provider/mock.d.ts +55 -0
- package/dist/provider/scenario-fake.d.ts +96 -0
- package/dist/provider/selection.d.ts +115 -0
- package/dist/provider/session-provider.d.ts +426 -0
- package/dist/provider/slots.d.ts +120 -0
- package/dist/provider/stream-frames.d.ts +25 -0
- package/dist/provider/tool-secret.d.ts +57 -0
- package/dist/rpc/bridge.d.ts +14 -0
- package/dist/rpc/mcp-control.d.ts +26 -0
- package/dist/runtime.d.ts +14 -0
- package/dist/sandbox/profile.d.ts +249 -0
- package/dist/sandbox/spawn.d.ts +139 -0
- package/dist/settings/env-filter.d.ts +52 -0
- package/dist/settings/loaders/hooks.d.ts +44 -0
- package/dist/settings/loaders/mcp-config.d.ts +83 -0
- package/dist/settings/loaders/plugin-mcp.d.ts +3 -0
- package/dist/settings/loaders/strict-plugin-only.d.ts +13 -0
- package/dist/settings/resolve.d.ts +2 -0
- package/dist/settings/sources.d.ts +2 -0
- package/dist/settings/trust.d.ts +36 -0
- package/dist/skills/attachment.d.ts +25 -0
- package/dist/skills/frontmatter.d.ts +64 -0
- package/dist/skills/index.d.ts +16 -0
- package/dist/skills/listing.d.ts +89 -0
- package/dist/skills/loader.d.ts +104 -0
- package/dist/skills/option.d.ts +68 -0
- package/dist/skills/permission-rules.d.ts +21 -0
- package/dist/skills/runtime.d.ts +21 -0
- package/dist/skills/store.d.ts +163 -0
- package/dist/store/continuation-attach.d.ts +44 -0
- package/dist/store/dialect.d.ts +526 -0
- package/dist/store/provider-state.d.ts +188 -0
- package/dist/store/resume.d.ts +92 -0
- package/dist/structured/ajv-seam.d.ts +7 -0
- package/dist/structured/descriptor.d.ts +9 -0
- package/dist/structured/seam.d.ts +51 -0
- package/dist/structured/validator.d.ts +22 -0
- package/dist/subagents/activity.d.ts +13 -0
- package/dist/subagents/availability.d.ts +30 -0
- package/dist/subagents/builtin-agents.d.ts +37 -0
- package/dist/subagents/child-engine.d.ts +198 -0
- package/dist/subagents/child-handle.d.ts +344 -0
- package/dist/subagents/definitions.d.ts +189 -0
- package/dist/subagents/fork.d.ts +55 -0
- package/dist/subagents/git-root.d.ts +1 -0
- package/dist/subagents/limits.d.ts +28 -0
- package/dist/subagents/notification-queue.d.ts +233 -0
- package/dist/subagents/plugin-agents.d.ts +5 -0
- package/dist/subagents/policy.d.ts +46 -0
- package/dist/subagents/register-default-factory.d.ts +66 -0
- package/dist/subagents/resolution.d.ts +56 -0
- package/dist/subagents/restore.d.ts +9 -0
- package/dist/subagents/roster.d.ts +17 -0
- package/dist/subagents/test-fakes.d.ts +12 -0
- package/dist/subagents/tool-pools.d.ts +69 -0
- package/dist/subagents/watchdog.d.ts +13 -0
- package/dist/subagents/workspace.d.ts +27 -0
- package/dist/testing.d.ts +5 -0
- package/dist/testing.js +194 -0
- package/dist/tools/background-tasks.d.ts +10 -0
- package/dist/tools/descriptors/_shared.d.ts +34 -0
- package/dist/tools/descriptors/advisor.d.ts +1 -0
- package/dist/tools/descriptors/agent.d.ts +47 -0
- package/dist/tools/descriptors/artifact.d.ts +1 -0
- package/dist/tools/descriptors/ask-user-question.d.ts +1 -0
- package/dist/tools/descriptors/bash.d.ts +20 -0
- package/dist/tools/descriptors/claude-design.d.ts +1 -0
- package/dist/tools/descriptors/cron-create.d.ts +1 -0
- package/dist/tools/descriptors/cron-delete.d.ts +1 -0
- package/dist/tools/descriptors/cron-list.d.ts +1 -0
- package/dist/tools/descriptors/edit.d.ts +1 -0
- package/dist/tools/descriptors/end-conversation.d.ts +1 -0
- package/dist/tools/descriptors/enter-plan-mode.d.ts +1 -0
- package/dist/tools/descriptors/enter-worktree.d.ts +1 -0
- package/dist/tools/descriptors/exit-plan-mode.d.ts +1 -0
- package/dist/tools/descriptors/exit-worktree.d.ts +1 -0
- package/dist/tools/descriptors/glob.d.ts +1 -0
- package/dist/tools/descriptors/grep.d.ts +1 -0
- package/dist/tools/descriptors/index.d.ts +59 -0
- package/dist/tools/descriptors/list-agents.d.ts +1 -0
- package/dist/tools/descriptors/list-mcp-resources-tool.d.ts +1 -0
- package/dist/tools/descriptors/lsp.d.ts +1 -0
- package/dist/tools/descriptors/monitor.d.ts +1 -0
- package/dist/tools/descriptors/notebook-edit.d.ts +1 -0
- package/dist/tools/descriptors/powershell.d.ts +1 -0
- package/dist/tools/descriptors/projects.d.ts +1 -0
- package/dist/tools/descriptors/propose-goal.d.ts +1 -0
- package/dist/tools/descriptors/propose-skills.d.ts +1 -0
- package/dist/tools/descriptors/push-notification.d.ts +1 -0
- package/dist/tools/descriptors/read-mcp-resource-dir-tool.d.ts +1 -0
- package/dist/tools/descriptors/read-mcp-resource-tool.d.ts +1 -0
- package/dist/tools/descriptors/read-notifications.d.ts +1 -0
- package/dist/tools/descriptors/read.d.ts +1 -0
- package/dist/tools/descriptors/refresh-mcp-tools.d.ts +1 -0
- package/dist/tools/descriptors/remote-trigger.d.ts +1 -0
- package/dist/tools/descriptors/repl.d.ts +1 -0
- package/dist/tools/descriptors/report-findings.d.ts +1 -0
- package/dist/tools/descriptors/schedule-wakeup.d.ts +1 -0
- package/dist/tools/descriptors/send-feedback.d.ts +1 -0
- package/dist/tools/descriptors/send-message.d.ts +1 -0
- package/dist/tools/descriptors/send-user-file.d.ts +1 -0
- package/dist/tools/descriptors/share-onboarding-guide.d.ts +1 -0
- package/dist/tools/descriptors/show-onboarding-role-picker.d.ts +1 -0
- package/dist/tools/descriptors/skill.d.ts +1 -0
- package/dist/tools/descriptors/structured-output.d.ts +1 -0
- package/dist/tools/descriptors/task-create.d.ts +1 -0
- package/dist/tools/descriptors/task-get.d.ts +1 -0
- package/dist/tools/descriptors/task-list.d.ts +1 -0
- package/dist/tools/descriptors/task-output.d.ts +1 -0
- package/dist/tools/descriptors/task-stop.d.ts +1 -0
- package/dist/tools/descriptors/task-update.d.ts +1 -0
- package/dist/tools/descriptors/todo-write.d.ts +1 -0
- package/dist/tools/descriptors/tool-search.d.ts +1 -0
- package/dist/tools/descriptors/wait-for-mcp-servers.d.ts +1 -0
- package/dist/tools/descriptors/web-fetch.d.ts +8 -0
- package/dist/tools/descriptors/web-search.d.ts +15 -0
- package/dist/tools/descriptors/winter-list-agents.d.ts +1 -0
- package/dist/tools/descriptors/winter-send-message.d.ts +1 -0
- package/dist/tools/descriptors/workflow.d.ts +1 -0
- package/dist/tools/descriptors/write.d.ts +1 -0
- package/dist/tools/impl/_caller.d.ts +14 -0
- package/dist/tools/impl/_domains.d.ts +25 -0
- package/dist/tools/impl/_exa-client.d.ts +122 -0
- package/dist/tools/impl/_exa-session-client.d.ts +23 -0
- package/dist/tools/impl/_inner-model.d.ts +135 -0
- package/dist/tools/impl/_search-budget.d.ts +36 -0
- package/dist/tools/impl/_web-fetch-cache.d.ts +37 -0
- package/dist/tools/impl/_web-fetch-html.d.ts +26 -0
- package/dist/tools/impl/_web-fetch-net.d.ts +99 -0
- package/dist/tools/impl/_web-search-assembler.d.ts +57 -0
- package/dist/tools/impl/advisor.d.ts +37 -0
- package/dist/tools/impl/agent.d.ts +10 -0
- package/dist/tools/impl/ask-user-question.d.ts +5 -0
- package/dist/tools/impl/background-task-runtime.d.ts +272 -0
- package/dist/tools/impl/bash.d.ts +78 -0
- package/dist/tools/impl/cron.d.ts +11 -0
- package/dist/tools/impl/edit.d.ts +1 -0
- package/dist/tools/impl/enter-plan-mode.d.ts +4 -0
- package/dist/tools/impl/enter-worktree.d.ts +25 -0
- package/dist/tools/impl/exit-plan-mode.d.ts +4 -0
- package/dist/tools/impl/exit-worktree.d.ts +4 -0
- package/dist/tools/impl/glob.d.ts +1 -0
- package/dist/tools/impl/grep.d.ts +19 -0
- package/dist/tools/impl/index.d.ts +37 -0
- package/dist/tools/impl/list-agents.d.ts +7 -0
- package/dist/tools/impl/list-mcp-resources-tool.d.ts +9 -0
- package/dist/tools/impl/monitor.d.ts +66 -0
- package/dist/tools/impl/notebook-edit.d.ts +1 -0
- package/dist/tools/impl/push-notification.d.ts +4 -0
- package/dist/tools/impl/read-ladder.d.ts +25 -0
- package/dist/tools/impl/read-mcp-resource-dir-tool.d.ts +9 -0
- package/dist/tools/impl/read-mcp-resource-tool.d.ts +9 -0
- package/dist/tools/impl/read-notifications.d.ts +5 -0
- package/dist/tools/impl/read.d.ts +44 -0
- package/dist/tools/impl/refresh-mcp-tools.d.ts +8 -0
- package/dist/tools/impl/report-findings.d.ts +1 -0
- package/dist/tools/impl/schedule-wakeup.d.ts +2 -0
- package/dist/tools/impl/send-message.d.ts +7 -0
- package/dist/tools/impl/skill.d.ts +5 -0
- package/dist/tools/impl/task-graph.d.ts +1 -0
- package/dist/tools/impl/task-output.d.ts +16 -0
- package/dist/tools/impl/task-stop.d.ts +11 -0
- package/dist/tools/impl/todo-write.d.ts +8 -0
- package/dist/tools/impl/tool-search.d.ts +4 -0
- package/dist/tools/impl/wait-for-mcp-servers.d.ts +29 -0
- package/dist/tools/impl/web-fetch.d.ts +36 -0
- package/dist/tools/impl/web-search.d.ts +30 -0
- package/dist/tools/impl/workflow.d.ts +5 -0
- package/dist/tools/impl/write.d.ts +8 -0
- package/dist/tools/paths-seam.d.ts +6 -0
- package/dist/tools/read-state.d.ts +12 -0
- package/dist/tools/registry.d.ts +423 -0
- package/dist/tools/task-graph-store.d.ts +61 -0
- package/dist/toolsearch/aliases.d.ts +26 -0
- package/dist/toolsearch/exposure.d.ts +30 -0
- package/dist/toolsearch/ranking.d.ts +6 -0
- package/dist/toolsearch/search.d.ts +45 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +5 -0
- package/dist/web/fetchable-url.d.ts +28 -0
- package/dist/web/preapproved-hosts.d.ts +52 -0
- package/dist/web/private-address.d.ts +55 -0
- package/dist/web/session-runtime.d.ts +86 -0
- package/dist/workflows/bridge.d.ts +87 -0
- package/dist/workflows/budget.d.ts +24 -0
- package/dist/workflows/host-registry.d.ts +142 -0
- package/dist/workflows/journal.d.ts +29 -0
- package/dist/workflows/meta.d.ts +45 -0
- package/dist/workflows/registry.d.ts +24 -0
- package/dist/workflows/runtime.d.ts +254 -0
- package/dist/workflows/sandbox.d.ts +49 -0
- package/dist/workflows/script-api.d.ts +58 -0
- package/dist/workflows/seam.d.ts +92 -0
- package/dist/workflows/semaphore.d.ts +16 -0
- package/dist/workflows/store.d.ts +177 -0
- package/dist/workflows/subprocess-entry.d.ts +38 -0
- package/dist/workflows/subprocess-entry.js +14 -0
- package/dist/workflows/transcript.d.ts +56 -0
- package/dist/workflows/types.d.ts +84 -0
- package/dist/workflows/worker-harness.d.ts +45 -0
- package/package.json +76 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { WinterCatalog } from "@yanlinglabs/winter-provider-catalog";
|
|
2
|
+
import type { CredentialStore, ProviderContext, ProviderRegistry, ResolvedModel } from "@yanlinglabs/winter-provider-runtime";
|
|
3
|
+
import { type CredentialRef, type RuntimeConfig } from "@yanlinglabs/winter-agent-sdk";
|
|
4
|
+
import type { Provider } from "../engine.js";
|
|
5
|
+
/**
|
|
6
|
+
* The reserved namespace that reaches the in-process scripted double (R6-13).
|
|
7
|
+
*
|
|
8
|
+
* A NAMESPACE rather than an env var, and the ruling is worth restating because it inverts a P1
|
|
9
|
+
* carry: "remove `WINTER_TEST_PROVIDER` affordances" is NOT taken as written, because `main.ts` also
|
|
10
|
+
* uses that name to register in-process test TOOLS in the spawned runtime -- something no loopback
|
|
11
|
+
* server can do. So production selection is catalog-first, the double is reachable only through this
|
|
12
|
+
* namespace, and the env var survives ONLY as the harness's alias for it.
|
|
13
|
+
*/
|
|
14
|
+
export declare const WINTER_TEST_NAMESPACE = "winter-test";
|
|
15
|
+
/** R6-9: the resolved identity that rides `system/init`'s Winter-only `winter_provider` extension and the dialect record. */
|
|
16
|
+
export interface WinterProviderIdentity {
|
|
17
|
+
providerId: string;
|
|
18
|
+
modelKey: string;
|
|
19
|
+
adapterId: string;
|
|
20
|
+
adapterVersion: string;
|
|
21
|
+
catalogVersion: string;
|
|
22
|
+
continuationDomain?: string;
|
|
23
|
+
authRefKind: CredentialRef["kind"];
|
|
24
|
+
}
|
|
25
|
+
/** What a session gets back. The `testProvider` arm is the reserved namespace's -- a scripted double has no catalog identity to report, and pretending otherwise would put a fake row in the init frame. */
|
|
26
|
+
export type SessionProviderSelection = {
|
|
27
|
+
provider: Provider;
|
|
28
|
+
identity: WinterProviderIdentity;
|
|
29
|
+
resolved: ResolvedModel;
|
|
30
|
+
contextWindow?: number;
|
|
31
|
+
supportsToolSearch: boolean;
|
|
32
|
+
familyMetadata: {
|
|
33
|
+
taskNative?: boolean;
|
|
34
|
+
};
|
|
35
|
+
/** R6-9: the fallback candidates, already domain-checked. Empty when none was configured. */
|
|
36
|
+
fallbackModels: ResolvedModel[];
|
|
37
|
+
} | {
|
|
38
|
+
testProvider: Provider;
|
|
39
|
+
};
|
|
40
|
+
export interface SelectionDeps {
|
|
41
|
+
registry: ProviderRegistry;
|
|
42
|
+
credentials: CredentialStore;
|
|
43
|
+
env: Record<string, string | undefined>;
|
|
44
|
+
/** R6-13: the in-process scripted double, resolved by name. Absent -> a `winter-test/<name>` model is a typed refusal rather than a silent miss. */
|
|
45
|
+
testProviders?: (name: string) => Provider | undefined;
|
|
46
|
+
/** How a resolved model becomes a `Provider`. Injected so this module never imports the bridge's own construction path in a test. */
|
|
47
|
+
buildProvider?: (resolved: ResolvedModel) => Provider;
|
|
48
|
+
/**
|
|
49
|
+
* WS-13b R6b-7: the resolved `settings.providers` map, as a GETTER.
|
|
50
|
+
*
|
|
51
|
+
* A getter and not a value, and that is the whole hot-reload seam. WS-11 §5's "no setting may
|
|
52
|
+
* require a restart" is a product rule above the SDK boundary -- this package starts no watchers
|
|
53
|
+
* (production-wiring's own header says so) -- so what it owes instead is a read that happens AT
|
|
54
|
+
* RESOLUTION TIME rather than a snapshot taken when the deps object was built. A host that
|
|
55
|
+
* re-resolves its settings sees the new value at the session's next resolution and at every
|
|
56
|
+
* `set_model`, with nothing rebuilt.
|
|
57
|
+
*
|
|
58
|
+
* Absent, or an id absent from the map, means ENABLED. Silence is never a disablement.
|
|
59
|
+
*/
|
|
60
|
+
providerSettings?: () => Record<string, {
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
}> | undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolves the session's provider and model.
|
|
66
|
+
*
|
|
67
|
+
* Order, and each step exists because the one before it cannot answer:
|
|
68
|
+
* 1. the reserved `winter-test/<name>` namespace -- checked FIRST so a test double can never be
|
|
69
|
+
* shadowed by a catalog row, and so the check is independent of every credential question;
|
|
70
|
+
* 2. a QUALIFIED `<providerId>/<model>` key -> the catalog, verbatim;
|
|
71
|
+
* 3. a pinned Anthropic ALIAS -> the `anthropic` provider, but only with a credential ref for it;
|
|
72
|
+
* 4. a BARE id -> `config.provider.providerId`;
|
|
73
|
+
* 5. no model and no provider -> a typed refusal.
|
|
74
|
+
*/
|
|
75
|
+
export declare function resolveSessionProvider(config: RuntimeConfig, deps: SelectionDeps): SessionProviderSelection;
|
|
76
|
+
/**
|
|
77
|
+
* Redacts a `CredentialRef` for a frame, a log line or an error message.
|
|
78
|
+
*
|
|
79
|
+
* `inline` is the case this exists for: R6-10 makes it a HOST responsibility that the SDK never
|
|
80
|
+
* persists, and its value is a live secret sitting in the session's own config -- so anything that
|
|
81
|
+
* renders a ref renders it through here. The others carry only locators, and those are reproduced
|
|
82
|
+
* because a locator is what makes a credential problem diagnosable.
|
|
83
|
+
*/
|
|
84
|
+
export declare function redactCredentialRef(ref: CredentialRef): string;
|
|
85
|
+
/**
|
|
86
|
+
* R6-6: how the session's stall timeout reaches an adapter.
|
|
87
|
+
*
|
|
88
|
+
* THROUGH `ProviderContext`, not `ProviderRequest`, and the placement is the design. A stall watchdog
|
|
89
|
+
* is a property of the CONNECTION -- an adapter arms it around its own `boundedFetch`/`parseSse`,
|
|
90
|
+
* once, for every call it makes -- not of one turn's payload. Putting it on the request would invite
|
|
91
|
+
* a per-turn override that no ruling asks for and that an adapter would have to re-arm mid-stream.
|
|
92
|
+
*
|
|
93
|
+
* One resolution site, so the disclosed default cannot be applied differently by two callers.
|
|
94
|
+
*/
|
|
95
|
+
export declare function resolveStallTimeoutMs(config: RuntimeConfig): number;
|
|
96
|
+
/**
|
|
97
|
+
* Assembles the `ProviderContext` an adapter runs under.
|
|
98
|
+
*
|
|
99
|
+
* THE PRODUCTION CALLER OF `resolveStallTimeoutMs`, and the reason this function exists rather than
|
|
100
|
+
* leaving five separate decisions to whoever wires a session (review round 1, M1). The stall timeout
|
|
101
|
+
* is the one that shows why: `sse.ts` reads `ctx.stallTimeoutMs` on every chunk, so a caller that
|
|
102
|
+
* assembled a context without it would silently disable R6-6's watchdog on every stream — a disclosed
|
|
103
|
+
* option that quietly did nothing.
|
|
104
|
+
*
|
|
105
|
+
* `log` defaults to a NO-OP rather than to a console writer: `ProviderContext.log`'s own contract is
|
|
106
|
+
* provider/model identifiers and byte COUNTS only, and a default that wrote anywhere would be a
|
|
107
|
+
* default that a careless adapter could turn into a content leak.
|
|
108
|
+
*/
|
|
109
|
+
export declare function createProviderContext(config: RuntimeConfig, deps: {
|
|
110
|
+
providerId: string;
|
|
111
|
+
credentials: CredentialStore;
|
|
112
|
+
log?: ProviderContext["log"];
|
|
113
|
+
}): ProviderContext;
|
|
114
|
+
/** Convenience for a caller that has a catalog rather than a registry. One construction site, so a registry is never built twice for one session. */
|
|
115
|
+
export declare function createSelectionRegistry(catalog: WinterCatalog): ProviderRegistry;
|
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
import type { WinterCatalog, WinterProviderDescriptor } from "@yanlinglabs/winter-provider-catalog";
|
|
2
|
+
import type { CredentialRef, ProviderConnectionConfig, RuntimeConfig } from "@yanlinglabs/winter-agent-sdk";
|
|
3
|
+
import type { CredentialStore, ModelInfo, ProviderContext, ProviderRegistry, ResolvedModel } from "@yanlinglabs/winter-provider-runtime";
|
|
4
|
+
import { WinterProviderResolutionError, DECORATION_CHAR_BUDGET, MAX_DECORATION_CHARS } from "@yanlinglabs/winter-provider-runtime";
|
|
5
|
+
import { type KeychainSecretReader } from "./keychain-store.js";
|
|
6
|
+
import { type ToolSecretResolver } from "./tool-secret.js";
|
|
7
|
+
import { type WinterProviderIdentity } from "./selection.js";
|
|
8
|
+
import { type ClassifierRoute } from "./classifier/model-classifier.js";
|
|
9
|
+
import type { ClassifierInterface } from "../permissions/auto/engine.js";
|
|
10
|
+
import { type ContinuationChain, type ProviderStateRecord, type ProviderStateRecordInput } from "../store/provider-state.js";
|
|
11
|
+
import type { PricedUsage, Provider, ProviderUsage, ResolveModelSwitch, UsageRowFacts } from "../engine.js";
|
|
12
|
+
import { type SlotProviderResolution } from "./slots.js";
|
|
13
|
+
/**
|
|
14
|
+
* The pinned `ApiKeySource` vocabulary (`sdk.d.ts:127`), of which the JSDoc marks five members
|
|
15
|
+
* legacy — the live set is these four.
|
|
16
|
+
*
|
|
17
|
+
* WINTER'S MAPPING, and it is a DISCLOSED gap-fill rather than a translation. The union has exactly
|
|
18
|
+
* one spelling for "an API key", and it names an environment variable: `'ANTHROPIC_API_KEY'`. It has
|
|
19
|
+
* no spelling for "a key from the Keychain", "a key from a file" or "a key the host passed inline" —
|
|
20
|
+
* every credential shape R6-10 adds. So Winter reports `'ANTHROPIC_API_KEY'` for exactly that env
|
|
21
|
+
* name and `'none'` for everything else, on the pin's own gloss that `'none'` means "not via an API
|
|
22
|
+
* key" and is what the pinned runtime itself reports for OAuth, bearer and third-party-cloud auth.
|
|
23
|
+
*
|
|
24
|
+
* The REAL fact is never lost: it rides `winter_provider.authRefKind` on the same frame, which is
|
|
25
|
+
* where a consumer that cares about Winter's credential model is supposed to look. Inventing a fifth
|
|
26
|
+
* member of a closed pinned union would be the divergence; reporting the pin's own catch-all is not.
|
|
27
|
+
*/
|
|
28
|
+
export type ApiKeySource = "ANTHROPIC_API_KEY" | "apiKeyHelper" | "/login managed key" | "none";
|
|
29
|
+
export declare function apiKeySourceFor(ref: CredentialRef | undefined): ApiKeySource;
|
|
30
|
+
/** The `AccountInfo` shape the pin declares (`sdk.d.ts:23-33`) — every field optional, an empty object valid. */
|
|
31
|
+
export interface AccountInfo {
|
|
32
|
+
email?: string;
|
|
33
|
+
organization?: string;
|
|
34
|
+
subscriptionType?: string;
|
|
35
|
+
tokenSource?: string;
|
|
36
|
+
apiKeySource?: string;
|
|
37
|
+
apiProvider?: "firstParty" | "bedrock" | "vertex" | "foundry" | "anthropicAws" | "anthropicGoogleCloud" | "mantle" | "gateway";
|
|
38
|
+
}
|
|
39
|
+
/** The one read of the table above (exported for its own unit test, exactly as `apiKeySourceFor` is). `undefined` = this provider has no member of its own and reports nothing. */
|
|
40
|
+
export declare function apiProviderFor(providerId: string | undefined): AccountInfo["apiProvider"] | undefined;
|
|
41
|
+
export interface SessionProviderOptions {
|
|
42
|
+
/** The session's EFFECTIVE config. */
|
|
43
|
+
config: RuntimeConfig;
|
|
44
|
+
/** The environment governing R6-13's harness alias and the `env` credential store. Explicit at every entrypoint. */
|
|
45
|
+
env: Record<string, string | undefined>;
|
|
46
|
+
/** Injected in tests so a fixture owns its own rows. Production: the catalog compiled into this build. */
|
|
47
|
+
catalog?: WinterCatalog;
|
|
48
|
+
/** Injected in tests (an in-memory store). Production: keychain + env + file + inline, composed below. */
|
|
49
|
+
credentials?: CredentialStore;
|
|
50
|
+
/**
|
|
51
|
+
* R6-13: the reserved `winter-test/<name>` namespace's in-process double.
|
|
52
|
+
*
|
|
53
|
+
* DEFAULTS TO `testProviderForNamespace` (`provider/mock.ts`) — the namespace is a DISCLOSED test
|
|
54
|
+
* affordance that exists in production by ruling, not an injection point a caller has to remember,
|
|
55
|
+
* and a default that refused it would make the namespace work on one leg and not another. A caller
|
|
56
|
+
* overrides it only to supply something the shared table cannot: `main.ts` wraps it to register the
|
|
57
|
+
* `bgtask` fixture's paired TOOL, and `testing.ts` replaces it with the live JS provider its caller
|
|
58
|
+
* handed the leg — the one thing a spawned process can never be given.
|
|
59
|
+
*/
|
|
60
|
+
testProviders?: (name: string) => Provider | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* R6-7: the resumed continuation chain, as a GETTER.
|
|
63
|
+
*
|
|
64
|
+
* A getter rather than a value because the chain is re-attached asynchronously at the start of the
|
|
65
|
+
* run (`attachContinuationChain`), after this wiring is built — a captured snapshot would always
|
|
66
|
+
* be the empty one.
|
|
67
|
+
*/
|
|
68
|
+
chain?: () => ContinuationChain;
|
|
69
|
+
/**
|
|
70
|
+
* Review r1, M-1: where the renderer's sticky decoration decisions persist (the session's own
|
|
71
|
+
* provider-state sidecar, `SessionPersistence.recordProviderState`). Absent: they hold for this run only.
|
|
72
|
+
*/
|
|
73
|
+
recordProviderState?: (record: ProviderStateRecordInput) => void | Promise<void>;
|
|
74
|
+
/** `ProviderContext.log` — provider/model identifiers and BYTE COUNTS only, never content. Defaults to a no-op. */
|
|
75
|
+
log?: ProviderContext["log"];
|
|
76
|
+
/**
|
|
77
|
+
* The OS home the `file` credential store resolves `~/.aws/credentials` under.
|
|
78
|
+
*
|
|
79
|
+
* Explicit at every entrypoint and NEVER defaulted to `os.homedir()` here: a default would make
|
|
80
|
+
* every test that forgot to set it read the developer's real credentials file, which is precisely
|
|
81
|
+
* the hazard the Global Constraints forbid. `env.HOME` is the caller's usual answer.
|
|
82
|
+
*/
|
|
83
|
+
home?: string;
|
|
84
|
+
/**
|
|
85
|
+
* WS-13b R6b-7: the resolved `settings.providers` map, as a GETTER (see `SelectionDeps`' own
|
|
86
|
+
* field for why a getter is the hot-reload seam).
|
|
87
|
+
*
|
|
88
|
+
* Threaded into selection AND read again at the `set_model` seam: R6-K put resolution under the
|
|
89
|
+
* session provider precisely so a switch cannot walk around a rule the session start applied, and
|
|
90
|
+
* a disable that held only at start would be exactly such a walk-around.
|
|
91
|
+
*/
|
|
92
|
+
providerSettings?: () => Record<string, {
|
|
93
|
+
enabled: boolean;
|
|
94
|
+
}> | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* WS-13c §4 step 6 (P6.6): the slot resolver, so `set_model` accepts a SLOT NAME.
|
|
97
|
+
*
|
|
98
|
+
* Consulted only for a BARE name — a qualified `<providerId>/<model>` key is already an
|
|
99
|
+
* unambiguous statement and goes straight to R6-K's own rules, unchanged. A refusal is returned as
|
|
100
|
+
* the seam's typed refusal and becomes the control response, exactly like `provider-mismatch`:
|
|
101
|
+
* never a parked switch, never a substitution.
|
|
102
|
+
*
|
|
103
|
+
* ABSENT -> `set_model` keeps its pre-P6.6 shape verbatim (every scripted double, every pre-P6.6
|
|
104
|
+
* fixture, and the reserved `winter-test/<name>` namespace, for which the wiring withholds it).
|
|
105
|
+
*/
|
|
106
|
+
resolveSlot?: (requested: string, currentModelKey: string | undefined) => SlotProviderResolution;
|
|
107
|
+
/**
|
|
108
|
+
* P7a LANE B (D30): `settings.advisor.model`, as a GETTER over the same live settings view
|
|
109
|
+
* `providerSettings` reads.
|
|
110
|
+
*
|
|
111
|
+
* A GETTER for the reason every other settings seam in this file is one: the value is HOT (a
|
|
112
|
+
* Global Constraint of this phase -- "takes effect at the next quiescent boundary through the live
|
|
113
|
+
* settings getter, no restart"), and a string captured at construction could only ever be the
|
|
114
|
+
* value the session started with.
|
|
115
|
+
*
|
|
116
|
+
* ABSENT -> no setting is in play and the precedence falls to `Options.advisor.model` and then to
|
|
117
|
+
* D30's per-family default, which is exactly what a host that resolves no settings should get.
|
|
118
|
+
*/
|
|
119
|
+
advisorModelSetting?: () => string | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* P7a LANE B, fix r1 (review M-1): a monotonic number the wiring bumps whenever it LEARNS something
|
|
122
|
+
* about a provider's credential, so a memo taken on a cold view cannot outlive that view.
|
|
123
|
+
*
|
|
124
|
+
* WHY IT HAS TO EXIST. `production-wiring.ts`'s `credentialPresent` is a synchronous answer over an
|
|
125
|
+
* asynchronous fact: the session's own provider is `"present"` by construction, every other
|
|
126
|
+
* provider is `"unknown"` until a background probe lands, and nothing awaits those probes. The very
|
|
127
|
+
* first consumer is `reviewerResolves()` computing `init.tools`, which is what FIRES the prewarm --
|
|
128
|
+
* so the advisor's first resolution is necessarily cold, and a memo without this term pins that
|
|
129
|
+
* cold answer for the session's whole life.
|
|
130
|
+
*
|
|
131
|
+
* A VERSION rather than the credential view itself, for the same reason `settingsVersion` is a
|
|
132
|
+
* number: the memo compares it, and comparing a view by value would mean re-deriving the whole
|
|
133
|
+
* presence map on every capability check.
|
|
134
|
+
*
|
|
135
|
+
* ABSENT -> `0`, i.e. "nothing here ever learns anything", which is the truth for a caller that
|
|
136
|
+
* builds a wiring directly with a fixed credential store.
|
|
137
|
+
*/
|
|
138
|
+
credentialEpoch?: () => number;
|
|
139
|
+
/**
|
|
140
|
+
* The keychain's RAW reader, for `resolveToolSecret` (a tool's key may be a bare string, which the
|
|
141
|
+
* credential store rightly refuses -- see `tool-secret.ts`).
|
|
142
|
+
*
|
|
143
|
+
* DEFAULTS TO THE REAL ONE ONLY WHEN `credentials` IS ALSO DEFAULTED. A caller that injects a
|
|
144
|
+
* credential store (every test) has said "this is the only source", and quietly reading the real
|
|
145
|
+
* keychain beside it would be exactly the test-touches-the-login-keychain hazard the store's own
|
|
146
|
+
* injection exists to prevent. Such a caller passes a reader over a fake backend, or none at all.
|
|
147
|
+
*/
|
|
148
|
+
readKeychainSecret?: KeychainSecretReader;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* What `resolveAuxiliaryModel` answers: a BUILT, non-streaming provider for the tag, or a typed
|
|
152
|
+
* refusal. A VALUE in both arms -- the consumer is a tool executor, which must never throw.
|
|
153
|
+
*/
|
|
154
|
+
export type AuxiliaryModelResolution = {
|
|
155
|
+
ok: true;
|
|
156
|
+
provider: Provider;
|
|
157
|
+
modelKey: string;
|
|
158
|
+
} | {
|
|
159
|
+
ok: false;
|
|
160
|
+
code: string;
|
|
161
|
+
message: string;
|
|
162
|
+
};
|
|
163
|
+
export interface SessionProviderWiring {
|
|
164
|
+
/** What `runEngine` is handed. Either the catalog-resolved adapter chain or the reserved namespace's scripted double. */
|
|
165
|
+
provider: Provider;
|
|
166
|
+
registry: ProviderRegistry;
|
|
167
|
+
credentials: CredentialStore;
|
|
168
|
+
catalog: WinterCatalog;
|
|
169
|
+
/** ABSENT for a `winter-test/<name>` session: a scripted double has no catalog identity, and putting a fake row in the init frame would be worse than omitting it. */
|
|
170
|
+
identity?: WinterProviderIdentity;
|
|
171
|
+
resolved?: ResolvedModel;
|
|
172
|
+
/**
|
|
173
|
+
* PRESENT when selection REFUSED, in which case this wiring's `provider` is the one that rethrows
|
|
174
|
+
* the refusal on its first generation (see `buildSessionProvider`'s own header for the ruling).
|
|
175
|
+
*
|
|
176
|
+
* Exposed rather than swallowed so an entrypoint can also report the reason on stderr: the frame
|
|
177
|
+
* stream is the host's channel, stderr is the operator's, and a refusal deserves both.
|
|
178
|
+
*/
|
|
179
|
+
resolutionError?: WinterProviderResolutionError;
|
|
180
|
+
/** R6-9: the pinned `system/init.apiKeySource`. Always present — the pin makes the field REQUIRED. */
|
|
181
|
+
apiKeySource: ApiKeySource;
|
|
182
|
+
/** P4 carry: `toolCalling === "native"`, from the descriptor's own evidence. Absent when nothing is known. */
|
|
183
|
+
providerSupportsToolSearch?: boolean;
|
|
184
|
+
/** The descriptor's context window, unless the host set `contextWindowTokens` explicitly. */
|
|
185
|
+
contextWindowTokens?: number;
|
|
186
|
+
/** R6-14: which classifier this session got, and why. Recorded so `fallback_state` can name the reason. */
|
|
187
|
+
classifierRoute: ClassifierRoute;
|
|
188
|
+
/** ABSENT unless the route produced a real one — `createAutoEngine`'s own default (always `no_verdict`) is what a manual fallback means. */
|
|
189
|
+
classifier?: ClassifierInterface;
|
|
190
|
+
/**
|
|
191
|
+
* P7a LANE B (D29/D30) — THE ADVISOR'S REVIEWER, resolved on demand.
|
|
192
|
+
*
|
|
193
|
+
* REPLACES the P2-carry `advisorProvider`, which was a single provider built once from
|
|
194
|
+
* `config.advisor.model` and nothing else. Three things forced a function:
|
|
195
|
+
*
|
|
196
|
+
* - the reviewer's model can come from `settings.advisor.model`, which is HOT (a Global
|
|
197
|
+
* Constraint of this phase): a value captured at session start could never see an edit;
|
|
198
|
+
* - its DEFAULT depends on the session's family (D30), and the session's family changes with
|
|
199
|
+
* `set_model` -- so the answer depends on the LIVE model key, which is the argument;
|
|
200
|
+
* - the advisor tool's own contract is "a reviewer is resolvable RIGHT NOW" (its
|
|
201
|
+
* `winter.reviewer-model` capability gate), which is a question, not a stored object.
|
|
202
|
+
*
|
|
203
|
+
* PINNED AT FIRST USE (WS-13 R6-G): the built provider is memoised on the inputs that chose it
|
|
204
|
+
* (the option, the live setting, the session's model key), so repeated calls within one settings
|
|
205
|
+
* version return the SAME provider instance -- and a settings edit re-pins at the next call, which
|
|
206
|
+
* is the next quiescent boundary. No cache is shared with the classifier (R6-G's own rule); this
|
|
207
|
+
* memo holds one entry and its key is the route's own inputs.
|
|
208
|
+
*
|
|
209
|
+
* ABSENT for a session with no catalog identity (the reserved `winter-test/<name>` namespace and a
|
|
210
|
+
* session whose own model failed to resolve): there is no family to default from and no row to
|
|
211
|
+
* resolve against, and a fabricated answer would be worse than the honest "no reviewer".
|
|
212
|
+
*/
|
|
213
|
+
resolveReviewer?: (currentModelKey?: string) => {
|
|
214
|
+
provider: Provider;
|
|
215
|
+
model: string;
|
|
216
|
+
} | undefined;
|
|
217
|
+
/**
|
|
218
|
+
* A TOOL'S OWN INNER MODEL, by tag -- `WebFetch`'s page-digest model is the first consumer.
|
|
219
|
+
*
|
|
220
|
+
* `tag` is a provider-qualified key or a slot name and goes through the SAME slot resolver
|
|
221
|
+
* `set_model`, a child spawn and the advisor use, then `registry.resolve`, then `buildProvider`
|
|
222
|
+
* under Ruling E-1: `opts.authRef` is the ROUTE's own credential (step 1); without it a target on
|
|
223
|
+
* the session's provider uses the session's material and a target on ANOTHER provider gets its own
|
|
224
|
+
* `<providerId>:default` record, verified at its first generation with a typed
|
|
225
|
+
* `no-credential-for-provider`. The session's key is never sent to another provider.
|
|
226
|
+
*
|
|
227
|
+
* The provider is wrapped `withoutStreaming` (R6-G: an auxiliary generation emits no
|
|
228
|
+
* `stream_event`s) and MEMOISED per `(tag, authRef, session model key, credential epoch)`, so the
|
|
229
|
+
* capability check that asks "does the digest model resolve" on every tool-list read costs one
|
|
230
|
+
* resolution per credential/settings view, and a repeated call reuses one provider object.
|
|
231
|
+
*
|
|
232
|
+
* It answers with a REFUSAL VALUE, unlike `resolveReviewer` (whose throw is a documented
|
|
233
|
+
* workaround for a pinned return type). "The session's own model" is NOT a tag and never comes
|
|
234
|
+
* here: the engine already holds that provider, live, and re-resolving it would be a second
|
|
235
|
+
* opinion about a decision `set_model` and the fallback already made.
|
|
236
|
+
*
|
|
237
|
+
* ABSENT on the two arms with no catalog identity (the reserved test namespace, a refused
|
|
238
|
+
* session): a stated tag is then simply unresolvable, and the consumer says so.
|
|
239
|
+
*/
|
|
240
|
+
resolveAuxiliaryModel?: (tag: string, opts?: {
|
|
241
|
+
authRef?: CredentialRef;
|
|
242
|
+
currentModelKey?: string;
|
|
243
|
+
}) => AuxiliaryModelResolution;
|
|
244
|
+
/**
|
|
245
|
+
* Resolves a TOOL's secret from an arbitrary ref -- see `tool-secret.ts`. Present on EVERY arm: it
|
|
246
|
+
* depends on the credential store, not on the session having a model.
|
|
247
|
+
*/
|
|
248
|
+
resolveToolSecret: ToolSecretResolver;
|
|
249
|
+
/**
|
|
250
|
+
* Builds a `Provider` for any resolved model against THAT TARGET's material (Ruling E-1), the
|
|
251
|
+
* session's renderer and the session's chain.
|
|
252
|
+
*
|
|
253
|
+
* Exposed because R6-17's per-child provider needs the identical construction — a child built
|
|
254
|
+
* through a second construction path would get a different context (and, per
|
|
255
|
+
* `createProviderContext`'s own header, could silently lose the stall watchdog).
|
|
256
|
+
*/
|
|
257
|
+
buildProvider(resolved: ResolvedModel, opts?: BuildProviderOptions): Provider;
|
|
258
|
+
/** Ruling E-1: WHICH credential and connection `buildProvider` would use for this target, and why. Pure -- no store is consulted. */
|
|
259
|
+
describeTargetMaterial(resolved: ResolvedModel, opts?: BuildProviderOptions): TargetMaterial;
|
|
260
|
+
/** The provider this session is configured for (`config.provider.providerId`, else the resolved model's). Undefined only for a session with neither. */
|
|
261
|
+
sessionProviderId(): string | undefined;
|
|
262
|
+
/**
|
|
263
|
+
* P6 fix wave (Ruling E-2): THE SWITCH SEAM -- `EngineOptions.resolveModelSwitch`. R6-K resolution
|
|
264
|
+
* under the session provider, `buildProvider` under Ruling E-1, the resolved identity, and the two
|
|
265
|
+
* continuity endpoints `classifySwitch` compares. Present on every arm: a session that started
|
|
266
|
+
* unresolvable can be handed a model that resolves and recover.
|
|
267
|
+
*/
|
|
268
|
+
resolveModelSwitch: ResolveModelSwitch;
|
|
269
|
+
/** P6 fix wave (Ruling E-3): `fallbackModel`'s candidates as catalog keys, in order, domain-checked at init. Empty for the reserved namespace and for a refused session. */
|
|
270
|
+
fallbackModelKeys: string[];
|
|
271
|
+
/** P6 fix wave (Ruling E-4, R6-H): prices one generation for the model it ran on, from the catalog's `pricing` evidence. `undefined` for an unpriced row. */
|
|
272
|
+
priceUsage(modelKey: string, usage: ProviderUsage): PricedUsage | undefined;
|
|
273
|
+
/** The catalog facts for a `modelUsage` row of ANY resolvable model, priced or not (dist-session fixes C1). `undefined` for a key the catalog cannot resolve. */
|
|
274
|
+
usageRowFacts(modelKey: string): UsageRowFacts | undefined;
|
|
275
|
+
/** P6 fix wave (Ruling E-5, R6-14): the resolved classifier model's key, for the session pin. Present exactly when `classifier` is. */
|
|
276
|
+
classifierIdentity?: {
|
|
277
|
+
modelKey: string;
|
|
278
|
+
};
|
|
279
|
+
/** R6-I: the `supportedModels()` rows for this session. */
|
|
280
|
+
supportedModels(): ModelInfo[];
|
|
281
|
+
/** R6-I / capture (d): the initialize-response account surface. Never `system/init` — the pin has no account field there. */
|
|
282
|
+
accountInfo(): AccountInfo;
|
|
283
|
+
}
|
|
284
|
+
/** What a caller may pass to `buildProvider`. `authRef` is the target ROUTE's own credential (a classifier's `autoClassifier.authRef`, an advisor's `advisor.authRef`). */
|
|
285
|
+
export interface BuildProviderOptions {
|
|
286
|
+
authRef?: CredentialRef;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Ruling E-1: the credential and connection a provider built for `resolved` is given.
|
|
290
|
+
*
|
|
291
|
+
* `source` records which step of the rule answered:
|
|
292
|
+
* - `route` an explicit `authRef` on the target's own route;
|
|
293
|
+
* - `session` the target IS the session's provider, so the session's own material;
|
|
294
|
+
* - `provider-record` the target provider's OWN keychain record (`<providerId>:default`, R6-10's
|
|
295
|
+
* one-record-per-provider/account), whose existence the built provider
|
|
296
|
+
* verifies on its first generation and refuses (typed) when absent.
|
|
297
|
+
*
|
|
298
|
+
* `crossProvider` is the fact every consumer keys on: a cross-provider target's `connection` is its
|
|
299
|
+
* own generated endpoint -- never the session's user `baseUrl`/headers.
|
|
300
|
+
*/
|
|
301
|
+
export interface TargetMaterial {
|
|
302
|
+
authRef: CredentialRef;
|
|
303
|
+
connection?: ProviderConnectionConfig;
|
|
304
|
+
source: "route" | "session" | "provider-record";
|
|
305
|
+
crossProvider: boolean;
|
|
306
|
+
}
|
|
307
|
+
/** The account id a target provider's OWN keychain record is looked up under when a route names no ref (Ruling E-1 step 2). Disclosed in WS-13 §6. */
|
|
308
|
+
export declare const DEFAULT_PROVIDER_ACCOUNT_ID = "default";
|
|
309
|
+
/**
|
|
310
|
+
* The production credential store: Keychain, then env, then file, then inline.
|
|
311
|
+
*
|
|
312
|
+
* COMPOSED, not chosen: a `CredentialRef` names its own kind, every member answers `null` (or a
|
|
313
|
+
* typed `unsupported` the composite skips) for a ref it does not own, so the order is about which
|
|
314
|
+
* member gets asked first and not about precedence between competing answers.
|
|
315
|
+
*
|
|
316
|
+
* The Keychain member is FIRST and is constructed unconditionally, which is safe because
|
|
317
|
+
* `keychain-store.ts` resolves `Bun.secrets` LAZILY — a session with no keychain ref never touches
|
|
318
|
+
* it, and a runtime without it reports a typed failure at the point of use rather than at import.
|
|
319
|
+
*/
|
|
320
|
+
export declare function createProductionCredentialStore(config: RuntimeConfig, env: Record<string, string | undefined>, home: string): CredentialStore;
|
|
321
|
+
/**
|
|
322
|
+
* The connection profile for one resolved provider.
|
|
323
|
+
*
|
|
324
|
+
* THE RULE, and the fixture `production-wiring.test.ts` pins it in both directions:
|
|
325
|
+
*
|
|
326
|
+
* - The operator's own `connection.baseUrl` always wins, verbatim, and is a USER endpoint.
|
|
327
|
+
* - Otherwise the catalog's `defaultEndpoints.api` is copied in ONLY when the adapter has no
|
|
328
|
+
* vendor default of its own to fall back to — which is exactly the adapters that serve MORE THAN
|
|
329
|
+
* ONE provider (`winter.local-openai`'s twelve local runners, `winter.openai-chat-completions`'s
|
|
330
|
+
* deepseek and openrouter). One adapter, many vendors, no single default.
|
|
331
|
+
* - Otherwise nothing is set, so the adapter uses its own reviewed endpoint and
|
|
332
|
+
* `applyPrivilegedHeaders` still has something to gate.
|
|
333
|
+
*
|
|
334
|
+
* "Serves more than one provider" is deliberately computed from the catalog rather than hard-coded,
|
|
335
|
+
* and the fixture asserts BOTH directions (`google`/`bedrock` get no baseUrl; `deepseek` and a
|
|
336
|
+
* local runner do). `anthropic` (P6.5) and `openai` (WS-23, when `xai` joined it on
|
|
337
|
+
* `winter.openai-responses`) each crossed from the first group to the second, and the fixture failed
|
|
338
|
+
* loudly both times; since P7a the copy is stamped `"reviewed"`, so crossing no longer demotes the
|
|
339
|
+
* endpoint (it pins that too).
|
|
340
|
+
*
|
|
341
|
+
* P7a (WS-13b §10, closing the M-1 partial): every profile this function returns with a `baseUrl`
|
|
342
|
+
* now says WHERE that URL came from. The copy is `"reviewed"`; anything the operator supplied is
|
|
343
|
+
* `"user"`. Until the marker existed, the two were byte-identical strings and every adapter had to
|
|
344
|
+
* read the copy as a user endpoint — which silently took 156 rows off the privileged-header path
|
|
345
|
+
* in production while adapter fixtures, passing a generated base URL directly, kept passing.
|
|
346
|
+
*/
|
|
347
|
+
export declare function connectionForProvider(config: RuntimeConfig, catalog: WinterCatalog, provider: WinterProviderDescriptor): ProviderConnectionConfig | undefined;
|
|
348
|
+
/**
|
|
349
|
+
* Ruling E-1: a CROSS-PROVIDER target's connection. The session's user `connection` is NOT consulted
|
|
350
|
+
* -- a user `baseUrl` and its headers belong to the session's own provider -- so the target reaches
|
|
351
|
+
* its own generated endpoint (copied into the profile for a multi-provider adapter, per the rule
|
|
352
|
+
* above; left to the adapter's reviewed default otherwise).
|
|
353
|
+
*
|
|
354
|
+
* P7a: for a `requiresUserEndpoint` provider this ALWAYS refuses. Such a target has no endpoint of
|
|
355
|
+
* its own and, by this function's own rule, may not borrow the session's -- so there is nothing to
|
|
356
|
+
* reach and the refusal is the honest answer, not an omission. A classifier, advisor or R6-17 child
|
|
357
|
+
* on `azure-ai` is exactly that shape.
|
|
358
|
+
*/
|
|
359
|
+
export declare function generatedConnectionForProvider(catalog: WinterCatalog, provider: WinterProviderDescriptor): ProviderConnectionConfig | undefined;
|
|
360
|
+
/**
|
|
361
|
+
* Builds the session's provider, identity, classifier and account surface.
|
|
362
|
+
*
|
|
363
|
+
* NEVER THROWS for an unresolvable session model (R6-9, as reversed in review round 1): the refusal
|
|
364
|
+
* is DEFERRED -- this returns a wiring whose `provider.generate()` rethrows the typed
|
|
365
|
+
* `WinterProviderResolutionError`, so the session still starts, `system/init` is emitted (with no
|
|
366
|
+
* `winter_provider`), and the first generation lands on R6-F's pinned result shape before `query()`
|
|
367
|
+
* throws. `resolutionError` carries the reason so an entrypoint can also report it on stderr.
|
|
368
|
+
*/
|
|
369
|
+
/**
|
|
370
|
+
* P7a (D19 / R-7a-8) -- THE KEYCHAIN BLOCK'S SINGLE SOURCE.
|
|
371
|
+
*
|
|
372
|
+
* A FUNCTION, and exported, because the answer is needed in two places -- the credential store this
|
|
373
|
+
* session opens (`buildCredentialStore`) and the `service` a cross-provider record's `authRef`
|
|
374
|
+
* carries (`describeTargetMaterial`) -- and the two naming different services would write a
|
|
375
|
+
* credential where nothing will look for it.
|
|
376
|
+
*
|
|
377
|
+
* `brand.keychainService` is the source. `config.keychainService` is the DEPRECATED standalone
|
|
378
|
+
* alias, and the wrapper emits it only when the session actually chose a service (branded, or the
|
|
379
|
+
* option set) -- so a branded host that set `brand.keychainService` and nothing else leaves the
|
|
380
|
+
* top-level key ABSENT, and a reader of that key alone silently opened WINTER's own service for a
|
|
381
|
+
* reuser whose whole profile said otherwise. The two surfaces AGREE by construction whenever both
|
|
382
|
+
* are present (`query()` folds the deprecated option INTO the profile before resolving), so
|
|
383
|
+
* preferring the profile can never contradict a host that used the old field.
|
|
384
|
+
*
|
|
385
|
+
* `undefined` means "the session chose none" -- `createKeychainCredentialStore`'s own default
|
|
386
|
+
* applies, and the `authRef` carries no `service` key at all (which is what keeps an unbranded
|
|
387
|
+
* session's `authRef` byte-identical to before P7a).
|
|
388
|
+
*/
|
|
389
|
+
export declare function resolveSessionKeychainService(config: RuntimeConfig): string | undefined;
|
|
390
|
+
/** WS-23 (reasoning-state): the cross-family decoration caps -- declared beside the fit estimate that accounts for them (provider-runtime `continuity/fit.ts`, where the rationale is). */
|
|
391
|
+
export { DECORATION_CHAR_BUDGET, MAX_DECORATION_CHARS };
|
|
392
|
+
export declare function buildSessionProvider(opts: SessionProviderOptions): SessionProviderWiring;
|
|
393
|
+
/**
|
|
394
|
+
* R6-7 / Lane C wiring item 2: the RESUMED continuation chain, loaded once before the run starts.
|
|
395
|
+
*
|
|
396
|
+
* WHY IT IS LOADED HERE AND NOT INSIDE THE ENGINE. `attachContinuationChain` (engine.ts) folds each
|
|
397
|
+
* record's `origin` onto the in-memory message it belongs to, which is what the domain check reads —
|
|
398
|
+
* but the renderer's OTHER input is the chain itself, and that is where the `summary` records live.
|
|
399
|
+
* R6-8 forbids a foreign summary from ever entering `assistant.message.content`, so the sidecar is
|
|
400
|
+
* its only home; a renderer handed an empty chain therefore renders a resumed cross-family history
|
|
401
|
+
* with no decoration at all, which is indistinguishable from a session that had nothing to carry.
|
|
402
|
+
*
|
|
403
|
+
* `entryUuids` is the set of assistant entries that ACTUALLY EXIST in the rebuilt history —
|
|
404
|
+
* `buildContinuationChain`'s own rule is that a record without its entry is ignored (and
|
|
405
|
+
* garbage-collectable), so passing the record's own anchors back in would defeat the check.
|
|
406
|
+
*
|
|
407
|
+
* An unreadable sidecar yields an EMPTY chain rather than a throw: `attachContinuationChain` already
|
|
408
|
+
* emits the `sidecar_unreadable` continuity warning for exactly this case, and a session must not
|
|
409
|
+
* fail to start because its optional continuation state could not be read.
|
|
410
|
+
*/
|
|
411
|
+
export declare function loadResumedChain(store: {
|
|
412
|
+
loadProviderState?(): Promise<ProviderStateRecord[]>;
|
|
413
|
+
} | undefined, messages: ReadonlyArray<{
|
|
414
|
+
uuid?: string;
|
|
415
|
+
}>): Promise<ContinuationChain>;
|
|
416
|
+
/**
|
|
417
|
+
* A `Provider` that never streams, for the auxiliary generations R6-G names.
|
|
418
|
+
*
|
|
419
|
+
* `ProviderRequest.sink` is what makes a generation's `stream_event`s reach the host, and capture (F)
|
|
420
|
+
* found the pinned runtime forwarding events for only the FORWARDED generations — the compaction
|
|
421
|
+
* summariser, the classifier, the advisor and `countTokens` are all suppressed. The engine already
|
|
422
|
+
* builds those requests without a sink; this wrapper is the belt-and-braces half for a provider
|
|
423
|
+
* handed to one of them directly (the advisor backend below), so a future caller that copies a
|
|
424
|
+
* request wholesale cannot accidentally re-enable streaming for an auxiliary call.
|
|
425
|
+
*/
|
|
426
|
+
export declare function withoutStreaming(provider: Provider): Provider;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { WinterCatalog } from "@yanlinglabs/winter-provider-catalog";
|
|
2
|
+
import type { ActiveSlotSet, ModelSlotSetting } from "@yanlinglabs/winter-agent-sdk";
|
|
3
|
+
/**
|
|
4
|
+
* The marker the Agent descriptor's static description carries, and the block it lives in.
|
|
5
|
+
*
|
|
6
|
+
* DECLARED HERE rather than in `tools/descriptors/agent.ts` on purpose: the engine has to strip the
|
|
7
|
+
* block when no active slot set is wired, and importing the descriptor module for a string would
|
|
8
|
+
* run its `stub(...)` registration as a side effect of loading the engine. This module has no side
|
|
9
|
+
* effects at all, so both ends can name the same constant.
|
|
10
|
+
*/
|
|
11
|
+
export declare const AGENT_MODEL_SLOTS_MARKER = "{{MODEL_SLOTS}}";
|
|
12
|
+
export declare const AGENT_MODEL_SLOTS_BLOCK = "\n\nModel options for this session:\n{{MODEL_SLOTS}}";
|
|
13
|
+
/**
|
|
14
|
+
* The WS-06 canonical name of the one tool whose schema is rendered per family.
|
|
15
|
+
*
|
|
16
|
+
* Declared beside the marker for the same reason: the engine needs to recognise the descriptor and
|
|
17
|
+
* cannot import the descriptor (or the executor) module for a string without taking its
|
|
18
|
+
* registration side effects. `descriptors/agent.ts` and `tools/impl/agent.ts` both read it from
|
|
19
|
+
* here, so the name has one producer rather than three spellings that could drift.
|
|
20
|
+
*/
|
|
21
|
+
export declare const AGENT_TOOL_CANONICAL_NAME = "Agent";
|
|
22
|
+
export interface ActiveSlotSetInput {
|
|
23
|
+
catalog: WinterCatalog;
|
|
24
|
+
currentModelKey: string | undefined;
|
|
25
|
+
customSlots: readonly ModelSlotSetting[] | undefined;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The slots this session offers (WS-13c §3).
|
|
29
|
+
*
|
|
30
|
+
* TOTAL BY CONSTRUCTION — it never throws. It is called on every turn to render the Agent tool, and
|
|
31
|
+
* a session whose model failed to resolve (or one running a scripted double, or one on an
|
|
32
|
+
* `allowUnlisted` pass-through with no catalog row) still renders tools. An exception here would
|
|
33
|
+
* take down the tool advertisement itself, which is a strictly worse answer than an honest
|
|
34
|
+
* `own-model` set naming the model the session is actually on.
|
|
35
|
+
*/
|
|
36
|
+
export declare function computeActiveSlotSet(input: ActiveSlotSetInput): ActiveSlotSet;
|
|
37
|
+
/**
|
|
38
|
+
* The two things the Agent tool renders from the active set (WS-13c §3): the `model` property's
|
|
39
|
+
* `enum` (slot names in order) and one description line per slot, appended to the tool description
|
|
40
|
+
* as `<name> — <canonicalModelId>: <description> (<reason>)`.
|
|
41
|
+
*
|
|
42
|
+
* The tool SHAPE never changes — only these two.
|
|
43
|
+
*/
|
|
44
|
+
export declare function renderAgentModelSchema(active: ActiveSlotSet): {
|
|
45
|
+
enum: string[];
|
|
46
|
+
descriptionLines: string[];
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* WS-13c §4 step 2, as three states rather than two (R-6c-27).
|
|
50
|
+
*
|
|
51
|
+
* `CredentialStore.get` is asynchronous (a Keychain read) while this whole resolver is synchronous,
|
|
52
|
+
* so a caller genuinely cannot always answer. Collapsing that to `true` made a COLD subscription row
|
|
53
|
+
* win §4 step 3-i over a WARM token row the user actually has — an openai-API-key-only session's
|
|
54
|
+
* first `Agent(model: "astra")` chose `codex-oauth`, and `set_model` reported success and only failed
|
|
55
|
+
* at the next generation. Collapsing it to `false` is worse: it writes "no credential configured"
|
|
56
|
+
* into a `wouldServe` line about a provider that may well be configured, which is a false statement
|
|
57
|
+
* about the user's setup rather than a missing one.
|
|
58
|
+
*
|
|
59
|
+
* So: `absent` filters the row out and names the reason; `unknown` keeps it, but orders it AFTER
|
|
60
|
+
* every `present` row in the same §4 tier.
|
|
61
|
+
*/
|
|
62
|
+
export type CredentialPresence = "present" | "absent" | "unknown";
|
|
63
|
+
export interface SlotProviderResolutionInput {
|
|
64
|
+
catalog: WinterCatalog;
|
|
65
|
+
active: ActiveSlotSet;
|
|
66
|
+
requested: string;
|
|
67
|
+
hasCredential: (providerId: string) => CredentialPresence;
|
|
68
|
+
providerEnabled: (providerId: string) => boolean;
|
|
69
|
+
preferredProviders: readonly string[];
|
|
70
|
+
/**
|
|
71
|
+
* LANE A ADDITION to the spine's pinned input (optional, so every pinned call site still compiles).
|
|
72
|
+
*
|
|
73
|
+
* `ActiveSlotSet`/`SlotView` are the PUBLIC, host-facing shapes and carry no `provider` field, so a
|
|
74
|
+
* custom slot's pin (`modelSlots[].provider`, WS-13c §4 step 4) has nowhere to ride into this
|
|
75
|
+
* function. Without it a pinned slot would resolve to whatever step 3 ordered first — a silent
|
|
76
|
+
* substitution of one provider for another, which is the single thing §4 step 4 exists to prevent.
|
|
77
|
+
* Matched BY NAME (a validated set has unique names), never by index.
|
|
78
|
+
*/
|
|
79
|
+
customSlots?: readonly ModelSlotSetting[];
|
|
80
|
+
}
|
|
81
|
+
export type SlotProviderResolution = {
|
|
82
|
+
ok: true;
|
|
83
|
+
modelKey: string;
|
|
84
|
+
providerId: string;
|
|
85
|
+
canonicalModelId: string;
|
|
86
|
+
slot: {
|
|
87
|
+
family: string;
|
|
88
|
+
name: string;
|
|
89
|
+
source: ActiveSlotSet["source"];
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* LANE A ADDITION: TRUE when `requested` was a slot NAME.
|
|
93
|
+
*
|
|
94
|
+
* A full catalog key or a canonical id passes through (§3: "`AgentInput.model` is slot names
|
|
95
|
+
* only" governs what the MODEL is offered; a host-side `AgentDefinition.model`,
|
|
96
|
+
* `WINTER_SUBAGENT_MODEL` and the inherited `config.model` are full identifiers and reach the
|
|
97
|
+
* same resolver). `slot` still carries the active family/source so the pinned shape stays
|
|
98
|
+
* total, so a consumer that RECORDS the slot on a child must gate on this flag — otherwise
|
|
99
|
+
* every pre-P6.6 spawn, whose model is the parent's own `config.model`, grows a `slot` record
|
|
100
|
+
* naming a slot nobody asked for (WS-13c §3: "the slot the request named, IF it named one").
|
|
101
|
+
*/
|
|
102
|
+
viaSlotName: boolean;
|
|
103
|
+
} | {
|
|
104
|
+
ok: false;
|
|
105
|
+
code: "slot-unservable" | "ambiguous-slot-name" | "unknown-slot";
|
|
106
|
+
message: string;
|
|
107
|
+
wouldServe: Array<{
|
|
108
|
+
key: string;
|
|
109
|
+
providerId: string;
|
|
110
|
+
why: string;
|
|
111
|
+
}>;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Slot name -> provider + model key (WS-13c §4).
|
|
115
|
+
*
|
|
116
|
+
* NEVER A SUBSTITUTION (WS-13 §9): a failure is typed and carries `wouldServe` — the rows that would
|
|
117
|
+
* have served it and why each did not (no credential / disabled / pinned provider absent) — because
|
|
118
|
+
* "it did not work" and "you have no OpenAI key" are different problems for the user.
|
|
119
|
+
*/
|
|
120
|
+
export declare function resolveSlotToProvider(input: SlotProviderResolutionInput): SlotProviderResolution;
|