@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,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 92 literals exactly as they appear in `c7t`'s source order (duplicate `learn.microsoft.com`
|
|
3
|
+
* included) -- kept verbatim so a future re-extraction diffs cleanly against this array.
|
|
4
|
+
*/
|
|
5
|
+
export declare const PREAPPROVED_HOST_ENTRIES: readonly string[];
|
|
6
|
+
/**
|
|
7
|
+
* `wX(hostname, pathname)`, verbatim: an EXACT hostname match (no subdomains) against the
|
|
8
|
+
* hostname-only half, OR a hostname with a registered path prefix whose pathname is that prefix or a
|
|
9
|
+
* `/`-bounded child of it -- rejected outright when the raw pathname contains an encoded slash,
|
|
10
|
+
* backslash or dot (`%2f`, `%5c`, `%2e`, doubly-encoded or not), which is exactly the traversal class
|
|
11
|
+
* that would otherwise let `/docs%2f..%2fadmin` read as a legitimate child of `/docs`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isPreapprovedHost(hostname: string, pathname: string): boolean;
|
|
14
|
+
/** `isPreapprovedHost`, taking the URL directly. A URL that fails to parse is never preapproved. */
|
|
15
|
+
export declare function isPreapprovedUrl(url: URL): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* The registered entry that matched `url`, if any -- distinguishes a bare hostname match from a
|
|
18
|
+
* path-scoped one, and names the scope's prefix, so the redirect walk can ask "does the hop's own
|
|
19
|
+
* path still fall under the SAME scope" rather than only "is this host preapproved at all."
|
|
20
|
+
*/
|
|
21
|
+
export interface PreapprovedMatch {
|
|
22
|
+
host: string;
|
|
23
|
+
/** `undefined` for a hostname-only entry; the exact `/`-prefixed scope for a path-scoped one. */
|
|
24
|
+
pathPrefix?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Security review round 2, minor: this was EXACT-hostname-only, while `staysWithinScope` (below)
|
|
28
|
+
* already applied the three-way `[host, stripped, "www."+stripped]` match -- half of one fix. The
|
|
29
|
+
* gap is not cosmetic: a redirect chain `claude.com/docs/a` -> `www.claude.com/docs/a` (eligible,
|
|
30
|
+
* `staysWithinScope` says so) -> `www.claude.com/other` recomputes THIS function fresh at the top of
|
|
31
|
+
* the SECOND hop, on hostname `www.claude.com` -- which `PATH_PREFIXES` only ever keys by
|
|
32
|
+
* `claude.com`, so the old exact match returned `undefined` for it. An `undefined` scope makes
|
|
33
|
+
* `isEligibleAutoFollow`'s own `scope !== undefined && ...` check SHORT-CIRCUIT to "no restriction
|
|
34
|
+
* at all," so the THIRD hop (genuinely outside `/docs`) was auto-followed, not refused -- and because
|
|
35
|
+
* `claude.com/docs/a` (the ORIGINAL input URL) is still preapproved, that off-scope content got
|
|
36
|
+
* permissive guidelines and was eligible for the verbatim markdown passthrough. Matching hosts the
|
|
37
|
+
* same three-way way `staysWithinScope` does closes it: hop 2 now still resolves a scope (matched via
|
|
38
|
+
* the `claude.com` entry), and `staysWithinScope` correctly refuses hop 3's `/other` path.
|
|
39
|
+
*/
|
|
40
|
+
export declare function preapprovedScopeOf(url: URL): PreapprovedMatch | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Whether `url` still falls under the SAME preapproved scope `from` matched -- used by the redirect
|
|
43
|
+
* walk's "not leaving a preapproved path scope" gate.
|
|
44
|
+
*
|
|
45
|
+
* HOST comparison is the same three-way test claude's own code runs (security review corrections
|
|
46
|
+
* §4.8, measured): `[host, stripped, "www."+stripped]`, i.e. the scope's own host, that host with a
|
|
47
|
+
* leading `www.` stripped, and that stripped form with `www.` re-added -- so a scope matched on
|
|
48
|
+
* `claude.com/docs` still covers a redirect to `www.claude.com/docs/x`, and one matched on
|
|
49
|
+
* `www.example.com/docs` still covers a redirect to `example.com/docs/x`. An EXACT match only (this
|
|
50
|
+
* lane's earlier version) refused a same-site www-variant redirect claude itself follows.
|
|
51
|
+
*/
|
|
52
|
+
export declare function staysWithinScope(from: PreapprovedMatch, url: URL): boolean;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type AddressVerdict = "public" | "private";
|
|
2
|
+
/** One classified fact about a hop's target -- WHERE it came from is what a caller's message names. */
|
|
3
|
+
export interface PrivateAddressFinding {
|
|
4
|
+
class: AddressVerdict;
|
|
5
|
+
/** The shared classifier's own class name, or a reserved-name label -- safe to show the model. */
|
|
6
|
+
reason?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Strips a `[...]` IPv6 literal's brackets; a non-bracketed host is returned unchanged. */
|
|
9
|
+
export declare function stripIpv6Brackets(hostname: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Classifies a literal IP address -- family auto-detected via `net.isIP` (0 = not a literal IP at
|
|
12
|
+
* all, in which case this returns `undefined` rather than guessing). Delegates the actual range
|
|
13
|
+
* logic to the shared classifier, which already handles IPv4-mapped IPv6 in both its dotted-quad
|
|
14
|
+
* (`::ffff:127.0.0.1`) and hex-group (`::ffff:7f00:1`) forms.
|
|
15
|
+
*/
|
|
16
|
+
export declare function classifyIpLiteral(address: string): PrivateAddressFinding | undefined;
|
|
17
|
+
/** Reserved names RFC 6761 (`localhost`) and mDNS (`.local`) carve out -- private by NAME, whatever they resolve to. A single trailing dot (the DNS root, `localhost.`/`a.localhost.`/`foo.local.`) is stripped first so it cannot defeat the check. */
|
|
18
|
+
export declare function classifyReservedName(hostname: string): PrivateAddressFinding | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* The LEXICAL verdict for `hostname` as written in the URL: an IP literal classified by range, or a
|
|
21
|
+
* reserved name. `undefined` means "not lexically decidable" -- an ordinary DNS name, which is only
|
|
22
|
+
* classifiable by its RESOLVED address (see `classifyHostname` below).
|
|
23
|
+
*/
|
|
24
|
+
export declare function classifyHostnameLexically(hostname: string): PrivateAddressFinding | undefined;
|
|
25
|
+
/** The verdict for one resolved connection address (whatever DNS returned for an ordinary name). */
|
|
26
|
+
export declare function classifyResolvedAddress(address: string): PrivateAddressFinding;
|
|
27
|
+
/**
|
|
28
|
+
* The full verdict for `hostname`: lexical first (an IP literal or reserved name never needs a
|
|
29
|
+
* lookup), else every address `resolve` returns for it -- ANY private address among them makes the
|
|
30
|
+
* whole hostname private, because a caller reaches whichever address the OS connects to, not
|
|
31
|
+
* necessarily the first one.
|
|
32
|
+
*
|
|
33
|
+
* NOT the function that guards the actual connection any more (security review finding M6):
|
|
34
|
+
* `_web-fetch-net.ts`'s own `resolveTarget` now does its own single resolution and PINS the fetch
|
|
35
|
+
* to the exact address it classified (`Host` + `tls.serverName` carrying the logical name), closing
|
|
36
|
+
* the rebinding TOCTOU this function's own resolve-then-classify shape cannot by itself (a second,
|
|
37
|
+
* independent `fetch()`-internal resolution could still answer differently). This function remains
|
|
38
|
+
* the upfront, pre-cache gate in `web-fetch.ts` -- a decision, not a connection -- where that gap
|
|
39
|
+
* does not apply the same way (nothing here opens a socket).
|
|
40
|
+
*
|
|
41
|
+
* FAILS CLOSED on a resolution failure (security review finding M6): an EARLIER version of this
|
|
42
|
+
* function answered `PUBLIC` when `resolve` threw or answered nothing, on the reasoning that "the
|
|
43
|
+
* fetch step reports the real failure" -- but a caller that only asks THIS function before deciding
|
|
44
|
+
* whether to proceed (as `web-fetch.ts`'s own upfront gate does, ahead of a cache-hit) would treat an
|
|
45
|
+
* unresolvable name as safe to serve. There is no address to pin a decision to, so the honest answer
|
|
46
|
+
* is `private` (refuse), never `public` (silently proceed).
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* Item 2: the ONE spelling of "resolution failed" -- shared so a caller that needs to tell "actually
|
|
50
|
+
* private" apart from "unknown, because DNS didn't answer" (`web-fetch.ts`'s own cache-hit refusal,
|
|
51
|
+
* which used to say "it is a private/loopback address" for BOTH) compares against this constant,
|
|
52
|
+
* never a re-typed literal that could drift from the one below.
|
|
53
|
+
*/
|
|
54
|
+
export declare const UNRESOLVABLE_HOST_REASON = "could not resolve any address for this host";
|
|
55
|
+
export declare function classifyHostname(hostname: string, resolve: (hostname: string) => Promise<readonly string[]>): Promise<PrivateAddressFinding>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { CredentialRef, ResolvedWebToolsConfig } from "@yanlinglabs/winter-agent-sdk";
|
|
2
|
+
import type { MessageOrigin } from "@yanlinglabs/winter-provider-runtime";
|
|
3
|
+
import type { Provider, ProviderUsage } from "../engine.js";
|
|
4
|
+
import type { AuxiliaryModelResolution } from "../provider/session-provider.js";
|
|
5
|
+
import type { ToolSecretResolver } from "../provider/tool-secret.js";
|
|
6
|
+
/** The model a run is generating with RIGHT NOW -- live across `set_model` and a fallback. */
|
|
7
|
+
export interface SessionModelHandle {
|
|
8
|
+
provider: Provider;
|
|
9
|
+
/**
|
|
10
|
+
* The session's live model string -- BOTH what an inner request carries as `model` (exactly what
|
|
11
|
+
* the main loop sends, so the adapter translates it identically) AND the key its usage is
|
|
12
|
+
* accounted under (so an inner generation lands on the SAME `modelUsage` row as the main loop's).
|
|
13
|
+
* `undefined` only for a scripted double started with no model string.
|
|
14
|
+
*/
|
|
15
|
+
model: string | undefined;
|
|
16
|
+
/** Stamped onto the inner transcript's assistant messages so a real adapter replays them in-domain. */
|
|
17
|
+
origin?: MessageOrigin;
|
|
18
|
+
}
|
|
19
|
+
export interface WebSessionRuntime {
|
|
20
|
+
/** `RuntimeConfig.web` with every default applied (`resolveWebToolsConfig`). */
|
|
21
|
+
readonly web: ResolvedWebToolsConfig;
|
|
22
|
+
/**
|
|
23
|
+
* THE SESSION'S OWN MODEL, live. The default for every inner pass: always resolvable (the session
|
|
24
|
+
* is already generating on it) and needing no second credential. Read at CALL time, never cached
|
|
25
|
+
* by a consumer -- a `set_model` between two tool calls must move the inner pass with it.
|
|
26
|
+
*/
|
|
27
|
+
sessionModel(): SessionModelHandle;
|
|
28
|
+
/**
|
|
29
|
+
* A STATED inner model (`web.fetch.digestModel`), by tag, under the cross-provider credential
|
|
30
|
+
* rule. ABSENT when the session has no catalog identity to resolve against (a scripted double, a
|
|
31
|
+
* session whose own model was refused): a stated tag is then unresolvable, and the consumer says
|
|
32
|
+
* so rather than falling back.
|
|
33
|
+
*/
|
|
34
|
+
resolveAuxiliaryModel?: (tag: string, opts?: {
|
|
35
|
+
authRef?: CredentialRef;
|
|
36
|
+
}) => AuxiliaryModelResolution;
|
|
37
|
+
/**
|
|
38
|
+
* Folds ONE inner generation's usage into this run's accounting, exactly as far as a main-loop
|
|
39
|
+
* generation's goes and no further: it is SPEND (cumulative tokens, the cost ledger, and therefore
|
|
40
|
+
* `maxBudgetUsd`), and it is NOT context -- the inner prompt is never part of the session's next
|
|
41
|
+
* request, so it must not move the context reading compaction triggers on.
|
|
42
|
+
*/
|
|
43
|
+
accountUsage(modelKey: string | undefined, usage: ProviderUsage): void;
|
|
44
|
+
/**
|
|
45
|
+
* Has this run crossed `maxBudgetUsd`? The main loop asks this only before ITS OWN requests, so an
|
|
46
|
+
* inner pass asks it before each of its generations -- otherwise a bounded inner loop is the one
|
|
47
|
+
* place a session could keep spending past its ceiling. OPTIONAL and additive: absent (a hand-built
|
|
48
|
+
* runtime, a run with no budget) reads as "no".
|
|
49
|
+
*/
|
|
50
|
+
budgetExceeded?(): boolean;
|
|
51
|
+
/** Resolves a tool's secret from a ref. ABSENT for an engine run with no provider wiring (a bare `runEngine` over a double). */
|
|
52
|
+
resolveToolSecret?: ToolSecretResolver;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Registers `runtime` under `key` (`config.agentId ?? config.sessionId` -- a child shares its
|
|
56
|
+
* parent's session id, so the agent id is what tells them apart). Returns an IDENTITY-CHECKED
|
|
57
|
+
* disposer: a late teardown of a previous generation never removes the live one's registration.
|
|
58
|
+
*/
|
|
59
|
+
export declare function registerWebSessionRuntime(key: string, runtime: WebSessionRuntime): () => void;
|
|
60
|
+
export declare function getWebSessionRuntime(key: string): WebSessionRuntime | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* The runtime for the engine run EXECUTING this tool call: the child's own when the call is a
|
|
63
|
+
* child's, else the session's. Falls back to the owning session's for a child whose own
|
|
64
|
+
* registration is missing, so a wiring gap degrades to "the parent's model" rather than to a tool
|
|
65
|
+
* that cannot run.
|
|
66
|
+
*/
|
|
67
|
+
export declare function webSessionRuntimeFor(ctx: {
|
|
68
|
+
sessionId: string;
|
|
69
|
+
agentId?: string;
|
|
70
|
+
}): WebSessionRuntime | undefined;
|
|
71
|
+
/** The three SESSION-level facts a child run inherits from the root's registration (see the header). */
|
|
72
|
+
export declare function inheritedWebSessionFacts(sessionId: string): Pick<WebSessionRuntime, "web" | "resolveAuxiliaryModel" | "resolveToolSecret"> | undefined;
|
|
73
|
+
/** Test hygiene only: the registry is a process-wide singleton and `bun test` shares one module graph. */
|
|
74
|
+
export declare function resetWebSessionRuntimesForTest(): void;
|
|
75
|
+
/** `winter.search-backend`'s session fact: the host has not switched the backend off. */
|
|
76
|
+
export declare function searchBackendUsable(runtime: Pick<WebSessionRuntime, "web">): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* `winter.fetch-extractor`'s session fact: a digest model resolves.
|
|
79
|
+
*
|
|
80
|
+
* With no `digestModel` stated the digest runs on the session's own model, which resolves by
|
|
81
|
+
* construction. A STATED one must actually resolve -- it is never quietly replaced -- so an
|
|
82
|
+
* unresolvable tag withdraws the tool rather than advertising one that can only refuse. (Whether a
|
|
83
|
+
* CREDENTIAL exists for a cross-provider digest model is not knowable synchronously; that arrives as
|
|
84
|
+
* a typed refusal in the tool's result at the first generation.)
|
|
85
|
+
*/
|
|
86
|
+
export declare function digestModelResolves(runtime: Pick<WebSessionRuntime, "web" | "resolveAuxiliaryModel">): boolean;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { AgentOpts } from "./types.js";
|
|
2
|
+
import type { BudgetSnapshot } from "./budget.js";
|
|
3
|
+
/** Worker -> parent. */
|
|
4
|
+
export type BridgeRequest = {
|
|
5
|
+
op: "agent";
|
|
6
|
+
callId: number;
|
|
7
|
+
prompt: string;
|
|
8
|
+
opts?: AgentOpts;
|
|
9
|
+
} | {
|
|
10
|
+
op: "workflow";
|
|
11
|
+
callId: number;
|
|
12
|
+
ref: WorkflowRef;
|
|
13
|
+
args?: unknown;
|
|
14
|
+
} | {
|
|
15
|
+
op: "log";
|
|
16
|
+
message: string;
|
|
17
|
+
} | {
|
|
18
|
+
op: "resumed";
|
|
19
|
+
cachedPrefix: number;
|
|
20
|
+
} | {
|
|
21
|
+
op: "phase";
|
|
22
|
+
title: string;
|
|
23
|
+
} | {
|
|
24
|
+
op: "done";
|
|
25
|
+
result: unknown;
|
|
26
|
+
} | {
|
|
27
|
+
op: "error";
|
|
28
|
+
message: string;
|
|
29
|
+
};
|
|
30
|
+
/** WS-11 §1.6's `workflow(nameOrRef, args?)`: "a saved name or `{scriptPath}`". */
|
|
31
|
+
export type WorkflowRef = {
|
|
32
|
+
name: string;
|
|
33
|
+
} | {
|
|
34
|
+
scriptPath: string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Parent -> worker: the reply to an `agent`/`workflow` request.
|
|
38
|
+
*
|
|
39
|
+
* `ok: true, value: null` is a MEANINGFUL, non-error outcome for `agent` -- WS-11 §1.6: "Resolves
|
|
40
|
+
* `null` when the user skips the agent or it dies on a terminal error -- callers filter with
|
|
41
|
+
* `.filter(Boolean)`." `ok: false` is reserved for the conditions that must THROW inside the script
|
|
42
|
+
* (the total-agent cap, the budget ceiling, an unresolvable nested workflow), because those are
|
|
43
|
+
* conditions a `.filter(Boolean)` must not be able to swallow.
|
|
44
|
+
*/
|
|
45
|
+
export type BridgeResponse = {
|
|
46
|
+
callId: number;
|
|
47
|
+
ok: true;
|
|
48
|
+
value: unknown;
|
|
49
|
+
budget?: BudgetSnapshot;
|
|
50
|
+
} | {
|
|
51
|
+
callId: number;
|
|
52
|
+
ok: false;
|
|
53
|
+
error: string;
|
|
54
|
+
budget?: BudgetSnapshot;
|
|
55
|
+
};
|
|
56
|
+
/** The single init line the parent writes on spawn, before anything else. */
|
|
57
|
+
export interface WorkerInit {
|
|
58
|
+
runId: string;
|
|
59
|
+
source: string;
|
|
60
|
+
args: unknown;
|
|
61
|
+
/** `min(16, CPUs - 2)`, resolved parent-side (semaphore.ts). */
|
|
62
|
+
concurrency: number;
|
|
63
|
+
/** WS-11 §1.6: 1000 total agents per run. Mirrored so the worker can fail fast; enforced parent-side regardless. */
|
|
64
|
+
totalAgentCap: number;
|
|
65
|
+
/** WS-11 §1.6: 4096 items max per `parallel`/`pipeline` call -- an EXPLICIT error, entirely in-worker (the parent never sees the array). */
|
|
66
|
+
maxItemsPerCall: number;
|
|
67
|
+
budget: BudgetSnapshot;
|
|
68
|
+
/** WS-11 §1.5: the prior run's ordered agent() results. Absent/empty for a fresh run. */
|
|
69
|
+
resumeJournal?: Array<{
|
|
70
|
+
promptKey: string;
|
|
71
|
+
value: unknown;
|
|
72
|
+
}>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The framing both ends share. Deliberately a FUNCTION over a string buffer rather than a class:
|
|
76
|
+
* the worker and the runtime both need it, the worker's copy is bundled into the compiled binary,
|
|
77
|
+
* and a shared pure function has no lifecycle to get wrong on either side.
|
|
78
|
+
*
|
|
79
|
+
* Returns the complete lines found and the unconsumed remainder, which the caller carries forward --
|
|
80
|
+
* a `data` chunk may split a line in half or coalesce ten of them.
|
|
81
|
+
*/
|
|
82
|
+
export declare function splitNdjson(buffer: string): {
|
|
83
|
+
lines: string[];
|
|
84
|
+
rest: string;
|
|
85
|
+
};
|
|
86
|
+
/** One NDJSON frame, terminator included. One place, so the two ends cannot disagree about the newline. */
|
|
87
|
+
export declare function encodeNdjson(value: unknown): string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** What crosses the bridge so the worker's own `budget` object can answer without a round trip. */
|
|
2
|
+
export interface BudgetSnapshot {
|
|
3
|
+
total: number | null;
|
|
4
|
+
spent: number;
|
|
5
|
+
}
|
|
6
|
+
export interface WorkflowBudget {
|
|
7
|
+
/** `null` = no ceiling. THE DEFAULT (WS-11 §1.6 as amended by the task brief). */
|
|
8
|
+
readonly total: number | null;
|
|
9
|
+
spent(): number;
|
|
10
|
+
remaining(): number;
|
|
11
|
+
/** True once `spent() >= total`. Always false when `total` is null. */
|
|
12
|
+
exceeded(): boolean;
|
|
13
|
+
snapshot(): BudgetSnapshot;
|
|
14
|
+
}
|
|
15
|
+
export interface BudgetDeps {
|
|
16
|
+
/**
|
|
17
|
+
* The session's CUMULATIVE token spend (RULING P5-J). Absent = 0, never `contextTokens()` -- see
|
|
18
|
+
* this module's header for why substituting that quantity is worse than reporting nothing.
|
|
19
|
+
*/
|
|
20
|
+
spentTokens?: () => number;
|
|
21
|
+
/** Omitted (or null) = no ceiling. */
|
|
22
|
+
total?: number | null;
|
|
23
|
+
}
|
|
24
|
+
export declare function createBudget(deps: BudgetDeps): WorkflowBudget;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type { BrandProfile, SettingSource } from "@yanlinglabs/winter-agent-sdk";
|
|
2
|
+
import type { RuntimeAgentDefinition } from "@yanlinglabs/winter-agent-sdk";
|
|
3
|
+
import type { ContextAccountant } from "../engine.js";
|
|
4
|
+
import type { StructuredOutputSeam } from "../structured/seam.js";
|
|
5
|
+
export interface WorkflowSessionRuntime {
|
|
6
|
+
/**
|
|
7
|
+
* THE REGISTRATION KEY (fix wave, whole-branch I5). The engine's own `config.sessionId`.
|
|
8
|
+
*
|
|
9
|
+
* OPTIONAL ONLY FOR COMPILE COMPATIBILITY, and the omission is not the intended shape: an
|
|
10
|
+
* unkeyed registration lands in the single legacy slot below, which is exactly the
|
|
11
|
+
* one-live-session-per-process assumption I5 is about. `engine.ts` (the sole production
|
|
12
|
+
* registrant) is another lane's file in this wave and still omits it -- see this module's own
|
|
13
|
+
* "PRODUCTION WIRING" note.
|
|
14
|
+
*
|
|
15
|
+
* A CHILD engine reaches the registration site with its PARENT's `config.sessionId`, which is why
|
|
16
|
+
* registration is FIRST-WINS: see `registerWorkflowSession`.
|
|
17
|
+
*/
|
|
18
|
+
sessionId?: string;
|
|
19
|
+
/** The winter root this session persists under -- `resolveWinterHome()`'s value, whose `projects/` child holds the session area. */
|
|
20
|
+
winterHome: string;
|
|
21
|
+
/**
|
|
22
|
+
* SV-5 fix round 3: the DISCOVERY root a nested `workflow(name)` call's project/user tier
|
|
23
|
+
* resolution reads (`resolveWorkflowByName`'s `winterHome` -- the user tier's
|
|
24
|
+
* `<winterHome>/workflows`) -- DELIBERATELY DISTINCT from `winterHome` above, which is the
|
|
25
|
+
* DURABLE persist root (`storeHome ?? winterHome`) capture (3)'s script path is built from.
|
|
26
|
+
* Conflating the two would read the user tier from the wrong root whenever a router-linked run
|
|
27
|
+
* has a `storeHome` that differs from its per-run `winterHome` -- exactly the SV-1/SV-2 bug class
|
|
28
|
+
* this field exists to not repeat. Absent means the nested resolver's user tier stays inert,
|
|
29
|
+
* matching every pre-fix-round-3 caller.
|
|
30
|
+
*/
|
|
31
|
+
discoveryWinterHome?: string;
|
|
32
|
+
/** P7a (D19): the session's brand -- the project dot-dir a `workflow(name)` resolves under, and the worker seatbelt's fences. */
|
|
33
|
+
brand?: BrandProfile;
|
|
34
|
+
/** SV-5 fix round 3 (I-4): threaded to `resolveWorkflowByName` so a nested call's project/user tier resolution is source-gated exactly like the top-level Workflow tool. */
|
|
35
|
+
settingSources?: readonly SettingSource[];
|
|
36
|
+
/**
|
|
37
|
+
* WS-21 §6.3 item 1 (batch-2 fix round): the session's ENABLED plugins that ship a `workflows/`
|
|
38
|
+
* directory -- threaded to `defaultNestedResolver` (workflows/runtime.ts) so a nested
|
|
39
|
+
* `workflow("plugin:name")` call resolves a plugin workflow exactly like the top-level Workflow
|
|
40
|
+
* tool does (tools/impl/workflow.ts). Absent means a qualified name never resolves here either,
|
|
41
|
+
* matching every pre-fix caller.
|
|
42
|
+
*
|
|
43
|
+
* Fix round 4 (minors, M-3's last bullet): also carries `workflowsPaths` -- see
|
|
44
|
+
* `engine.ts`'s `EngineOptions.pluginWorkflows` for why every hop widened rather than gaining a
|
|
45
|
+
* new field.
|
|
46
|
+
*/
|
|
47
|
+
pluginWorkflows?: readonly {
|
|
48
|
+
name: string;
|
|
49
|
+
workflowsPath?: string;
|
|
50
|
+
workflowsPaths?: readonly string[];
|
|
51
|
+
}[];
|
|
52
|
+
/** `compatibilityKeys(cwd).transcriptProjectKey`, after `resolveProjectDirName` -- the SAME key the transcript store uses, never a second derivation. */
|
|
53
|
+
projectKey: string;
|
|
54
|
+
/** The session's own temp directory (paths/temp.ts) -- where per-run journals live (store.ts's `workflowRunsDir`). */
|
|
55
|
+
sessionTempDir: string;
|
|
56
|
+
/** Borrowed from Lane K through the seam (R5-12's named W->K coupling) -- never a second validator. */
|
|
57
|
+
structured: StructuredOutputSeam;
|
|
58
|
+
/** The session's live context accounting. Passed straight to `WorkflowRunHost.accountant`. */
|
|
59
|
+
accountant: ContextAccountant;
|
|
60
|
+
/**
|
|
61
|
+
* The session's CUMULATIVE token spend, for `budget.spent()` -- RULING P5-J (spine, fix wave).
|
|
62
|
+
*
|
|
63
|
+
* Deliberately NOT `accountant.contextTokens()`, which is the last provider call's context SIZE:
|
|
64
|
+
* an overwrite rather than an accumulation, non-monotonic, and blind to a workflow's own agents
|
|
65
|
+
* (each child builds its own accountant). Absent = `spent()` reports 0 and a ceiling never trips,
|
|
66
|
+
* which is honest; substituting the wrong quantity would look plausible and bound nothing.
|
|
67
|
+
*
|
|
68
|
+
* P5-J is expected to add the counter to `ContextAccountant` and route child usage into the
|
|
69
|
+
* parent's; when it lands, T8 wires that accessor here.
|
|
70
|
+
*/
|
|
71
|
+
spentTokens?: () => number;
|
|
72
|
+
/**
|
|
73
|
+
* The workflow budget ceiling, if the host set one. `null`/absent is the DEFAULT and means no
|
|
74
|
+
* ceiling (WS-11 §1.6 as amended by the task brief). No `WorkflowInput` field carries this -- it is
|
|
75
|
+
* a host/session-level setting, which is why it arrives here rather than through the tool call.
|
|
76
|
+
*/
|
|
77
|
+
budgetTotal?: number | null;
|
|
78
|
+
/**
|
|
79
|
+
* Resolves `agent({ agentType })` against the SAME registry the Agent tool uses (WS-11 §1.6:
|
|
80
|
+
* "a custom subagent type resolved from the same registry as the Agent tool"). Injected rather
|
|
81
|
+
* than called directly so this module keeps no dependency on `subagents/definitions.ts`, and so a
|
|
82
|
+
* host that has already loaded its definitions does not make the runtime re-read the filesystem
|
|
83
|
+
* once per `agent()` call.
|
|
84
|
+
*
|
|
85
|
+
* Absent = no custom types resolve; `agent({agentType})` then spawns a child whose definition
|
|
86
|
+
* records the unresolved name (runtime.ts's `resolveChildDefinition`), never a silent generic one.
|
|
87
|
+
*/
|
|
88
|
+
resolveAgentType?(agentType: string, ctx: {
|
|
89
|
+
cwd: string;
|
|
90
|
+
trustedWorkspace: boolean;
|
|
91
|
+
}): RuntimeAgentDefinition | undefined;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Register this session's runtime and return an IDENTITY-CHECKED disposer (the shape
|
|
95
|
+
* `registerSessionMcpLifecycle` already uses): the disposer withdraws the registration only while it
|
|
96
|
+
* is still the one this call made, so a stopped-and-immediately-restarted run's late teardown cannot
|
|
97
|
+
* remove the live generation's runtime.
|
|
98
|
+
*
|
|
99
|
+
* FIRST-WINS PER SESSION ID, deliberately. A CHILD engine reaches the production registration site
|
|
100
|
+
* (`engine.ts`) with `config.sessionId` -- which for a child IS the parent's id -- because the child
|
|
101
|
+
* is given the parent's structured-output seam, the condition that site gates on. Last-wins would
|
|
102
|
+
* therefore let a child replace its parent's registration mid-run (different `sessionTempDir`,
|
|
103
|
+
* different `projectKey`) and withdraw it at the child's teardown: the daemon defect, reachable
|
|
104
|
+
* inside one session. First-wins makes the child's register/dispose pair a no-op, which is also the
|
|
105
|
+
* "children resolve against the parent's registration" reading the seam already documents.
|
|
106
|
+
*
|
|
107
|
+
* PRODUCTION WIRING IS **NEEDS_CONTEXT** (this wave's lane split): `engine.ts` is another lane's
|
|
108
|
+
* file, so its two call sites still pass no `sessionId` and still call `clearWorkflowSession()` with
|
|
109
|
+
* no argument -- which is why the legacy slot below exists and why production behaviour is BYTE
|
|
110
|
+
* IDENTICAL to the pre-fix build until those two lines change to
|
|
111
|
+
* `registerWorkflowSession({ sessionId: config.sessionId, ... })` and `disposeWorkflowSession?.()`.
|
|
112
|
+
*/
|
|
113
|
+
export declare function registerWorkflowSession(runtime: WorkflowSessionRuntime): () => void;
|
|
114
|
+
/**
|
|
115
|
+
* The runtime registered for `sessionId`, or the legacy unkeyed one when no keyed registration
|
|
116
|
+
* exists for it (the pre-I5 production path, unchanged). `undefined` when nothing is registered at
|
|
117
|
+
* all -- the Workflow tool answers a typed tool error rather than crashing.
|
|
118
|
+
*/
|
|
119
|
+
export declare function getWorkflowSession(sessionId?: string): WorkflowSessionRuntime | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* Withdraw one session's registration. PRODUCTION teardown calls this (engine.ts, at the end of
|
|
122
|
+
* every run) for the reason the registration shape makes concrete: a run that left its registration
|
|
123
|
+
* standing would let a LATER session's Workflow call persist its script under the finished session's
|
|
124
|
+
* `projects/<key>/<uuid>/` directory.
|
|
125
|
+
*
|
|
126
|
+
* With no argument it clears the LEGACY slot only -- never the whole map. Clearing every session
|
|
127
|
+
* would reinstate I5 in the other direction: one run's teardown disabling every other live session's
|
|
128
|
+
* workflows.
|
|
129
|
+
*
|
|
130
|
+
* AT ENGINE TEARDOWN, USE THE DISPOSER `registerWorkflowSession` RETURNS -- never
|
|
131
|
+
* `clearWorkflowSession(config.sessionId)`. First-wins protects REGISTRATION from a child engine
|
|
132
|
+
* (which arrives with its parent's `config.sessionId`); only the identity-checked disposer protects
|
|
133
|
+
* WITHDRAWAL from the same child, whose teardown would otherwise delete its still-running parent's
|
|
134
|
+
* entry by key. This by-key form is for a host that is genuinely ending that session.
|
|
135
|
+
*/
|
|
136
|
+
export declare function clearWorkflowSession(sessionId?: string): void;
|
|
137
|
+
/**
|
|
138
|
+
* Test-only: clears EVERY registration, keyed and legacy. Same rationale as every sibling singleton
|
|
139
|
+
* in this codebase: bun's test runner shares ONE module instance across every file in a run, so one
|
|
140
|
+
* file's registration would otherwise leak into another's assertions.
|
|
141
|
+
*/
|
|
142
|
+
export declare function resetWorkflowSessionForTest(): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AgentOpts } from "./types.js";
|
|
2
|
+
export interface JournalEntry {
|
|
3
|
+
promptKey: string;
|
|
4
|
+
value: unknown;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The positional cache key: `(prompt, opts)` serialized. WS-11 §1.5's "a per-run journal keyed by
|
|
8
|
+
* call order + prompt/opts key" -- the ORDER is the array index, this is the identity check at that
|
|
9
|
+
* index. `undefined` opts normalize to `null` so `agent("go")` and `agent("go", undefined)` are the
|
|
10
|
+
* same call, which they are.
|
|
11
|
+
*/
|
|
12
|
+
export declare function promptKey(prompt: string, opts?: AgentOpts): string;
|
|
13
|
+
export declare class RunJournal {
|
|
14
|
+
private readonly path;
|
|
15
|
+
constructor(dir: string, runId: string);
|
|
16
|
+
append(promptKeyValue: string, value: unknown): void;
|
|
17
|
+
/** Escape hatch for the corrupt-line test -- a real caller always uses `append`. */
|
|
18
|
+
appendRaw(line: string): void;
|
|
19
|
+
/**
|
|
20
|
+
* The journal's readable prefix. A missing file is an empty array (a fresh run has no journal),
|
|
21
|
+
* and a CORRUPT line is skipped rather than fatal: a run killed mid-append leaves a partial last
|
|
22
|
+
* line, and refusing to resume at all because of it would be strictly worse than resuming the
|
|
23
|
+
* complete entries that precede it. The positional replay in script-api.ts diverges at the first
|
|
24
|
+
* key mismatch anyway, so a skipped line can only ever shorten the cached prefix, never
|
|
25
|
+
* misalign it -- a dropped middle entry shifts the entries after it, and the very next key
|
|
26
|
+
* comparison fails and latches `diverged`, sending everything from there on live.
|
|
27
|
+
*/
|
|
28
|
+
load(): JournalEntry[];
|
|
29
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** A declared phase (WS-11 §1.2). `title` is matched against `phase()` calls EXACTLY. */
|
|
2
|
+
export interface WorkflowMetaPhase {
|
|
3
|
+
title: string;
|
|
4
|
+
detail?: string;
|
|
5
|
+
model?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface WorkflowMeta {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
whenToUse?: string;
|
|
11
|
+
phases?: WorkflowMetaPhase[];
|
|
12
|
+
/** Any further literal keys the author wrote. Preserved, never interpreted -- this parser validates the SHAPE it is specified to validate and does not silently drop what it does not know. */
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}
|
|
15
|
+
export type ParsedWorkflowMeta = {
|
|
16
|
+
ok: true;
|
|
17
|
+
meta: WorkflowMeta;
|
|
18
|
+
} | {
|
|
19
|
+
ok: false;
|
|
20
|
+
error: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Parses and validates a script's `meta` block.
|
|
24
|
+
*
|
|
25
|
+
* Never throws and never evaluates: every failure -- absent block, non-literal value, missing
|
|
26
|
+
* required key, malformed `phases` -- comes back as `{ ok: false, error }`. The Workflow tool turns
|
|
27
|
+
* that into a `WorkflowOutput` carrying `error` (derived-shapes-p5 item (g): a script that fails the
|
|
28
|
+
* syntax check still RETURNS a WorkflowOutput, it does not throw).
|
|
29
|
+
*/
|
|
30
|
+
export declare function parseWorkflowMeta(source: string): ParsedWorkflowMeta;
|
|
31
|
+
/** The resolution of one `phase(title)` call against the declared phases. */
|
|
32
|
+
export interface PhaseGroup extends WorkflowMetaPhase {
|
|
33
|
+
/** true when `title` matched a declared `meta.phases` entry EXACTLY. */
|
|
34
|
+
declared: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* WS-11 §1.2's own rule, at the one point it actually applies -- when a `phase()` call arrives over
|
|
38
|
+
* the bridge, not at parse time: "phase titles match `phase()` calls exactly; an unmatched `phase()`
|
|
39
|
+
* call gets its own progress group."
|
|
40
|
+
*
|
|
41
|
+
* A near-miss is deliberately NOT fuzzy-matched to a declared phase: a script that mistypes a phase
|
|
42
|
+
* title gets a visible extra group, which is a diagnosable outcome, rather than silently landing in
|
|
43
|
+
* the wrong one.
|
|
44
|
+
*/
|
|
45
|
+
export declare function matchPhaseGroup(declared: readonly WorkflowMetaPhase[] | undefined, title: string): PhaseGroup;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { WorkflowCounts, WorkflowRunView } from "./types.js";
|
|
2
|
+
export declare class WorkflowRegistry {
|
|
3
|
+
private readonly runs;
|
|
4
|
+
register(entry: {
|
|
5
|
+
runId: string;
|
|
6
|
+
sessionId: string;
|
|
7
|
+
taskId: string;
|
|
8
|
+
name: string;
|
|
9
|
+
abort: AbortController;
|
|
10
|
+
startedAt?: number;
|
|
11
|
+
}): void;
|
|
12
|
+
setPhase(runId: string, phase: string): void;
|
|
13
|
+
setCounts(runId: string, counts: WorkflowCounts): void;
|
|
14
|
+
/** `running -> completed | failed`. No-op if unknown or already terminal. */
|
|
15
|
+
complete(runId: string, outcome: {
|
|
16
|
+
ok: boolean;
|
|
17
|
+
result: string;
|
|
18
|
+
}): void;
|
|
19
|
+
fail(runId: string, error: string): void;
|
|
20
|
+
/** `running -> stopped`, firing the run's abort. Returns false if unknown or already terminal. */
|
|
21
|
+
stop(runId: string): boolean;
|
|
22
|
+
get(runId: string): WorkflowRunView | undefined;
|
|
23
|
+
list(sessionId: string): WorkflowRunView[];
|
|
24
|
+
}
|