@yanlinglabs/winter-agent-sdk 0.0.16 → 0.0.20
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/README.md +38 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +93 -9
- package/dist/options.d.ts +55 -2
- package/dist/protocol/config.d.ts +149 -0
- package/dist/protocol/frames.d.ts +48 -1
- package/dist/query.d.ts +8 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -84,6 +84,7 @@ build (`BrandProfile.envPrefix`); a rebranded host reads the identical suffix un
|
|
|
84
84
|
| `WINTER_DISABLE_EXPLORE_INHERIT_CAP` | off | Truthy opts a first-party Anthropic session out of the Explore built-in's own model cap (which otherwise caps a Fable-tier session's Explore spawn down to Opus). |
|
|
85
85
|
| `WINTER_FORK_SUBAGENT` | off | Truthy enables `subagent_type: "fork"` for the session (mirrors `CLAUDE_CODE_FORK_SUBAGENT`). `Options.forkSubagent` (below) wins over this variable in either direction. |
|
|
86
86
|
| `WINTER_WEB_FETCH_AGENT` | off | Truthy makes the `web-fetch` built-in agent type available (off by default, like claude's own). |
|
|
87
|
+
| `WINTER_MAX_WEB_SEARCHES_PER_SESSION` | `200` | How many `WebSearch` calls one session may make, counted before each search and shared with every descendant subagent (the analogue of `CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION`). Past it, a call answers with a plain refusal result rather than an error. |
|
|
87
88
|
| `WINTER_AGENT_SDK_DISABLE_BUILTIN_AGENTS` | off | Truthy withholds every built-in `subagent_type` (gated or not) for the session. |
|
|
88
89
|
| `WINTER_DISABLE_EXPLORE_PLAN_AGENTS` | off | Truthy withholds the `Explore` and `Plan` built-ins together. |
|
|
89
90
|
| `WINTER_DISABLE_AGENT_VIEW` | off | Truthy withholds the `claude` catch-all built-in (mirrors `CLAUDE_CODE_DISABLE_AGENT_VIEW`). |
|
|
@@ -107,6 +108,43 @@ never the full universe of types its parent session could otherwise reach. Absen
|
|
|
107
108
|
session, and any child whose parent definition named no `Agent(...)` restriction) means
|
|
108
109
|
unrestricted, the behavior every session had before this field existed.
|
|
109
110
|
|
|
111
|
+
### The built-in web tools (since 0.0.17)
|
|
112
|
+
|
|
113
|
+
`WebFetch` and `WebSearch` ship in every default `init.tools`, as copies of the pinned `claude`
|
|
114
|
+
runtime's own — same descriptions, same input schemas, same inner-call prompts, same output assembly.
|
|
115
|
+
|
|
116
|
+
- **`WebFetch`** takes `{url, prompt}`, fetches the page from this machine (`http` is upgraded to
|
|
117
|
+
`https` unconditionally, and a hostname with fewer than two dot-separated labels is refused — so
|
|
118
|
+
`localhost` and IPv6 literals are not fetchable, exactly as in claude), converts HTML to markdown,
|
|
119
|
+
and answers `prompt` over it with a small fast model. Responses are cached for 15 minutes per
|
|
120
|
+
session. Rules are `WebFetch(domain:<host>)`; an allow rule naming an exact host is standing consent
|
|
121
|
+
for that host wherever it resolves.
|
|
122
|
+
- **`WebSearch`** takes `{query, allowed_domains?, blocked_domains?}` and runs one inner pass over the
|
|
123
|
+
search backend, returning titles and urls only. The budget is 200 calls per session
|
|
124
|
+
(`WINTER_MAX_WEB_SEARCHES_PER_SESSION`), shared with every descendant. Its only rule form is the
|
|
125
|
+
bare `WebSearch`; a scoped `WebSearch(...)` in `Options.allowedTools`/`disallowedTools` throws at
|
|
126
|
+
startup (a settings file drops it and warns).
|
|
127
|
+
|
|
128
|
+
Withdraw either with `disallowedTools`. `WebSearch` can also be switched off at the backend with
|
|
129
|
+
`web.search.enabled: false`.
|
|
130
|
+
|
|
131
|
+
- **`Options.web`** — `search.enabled`, `search.authRef` (the backend key, used only once the
|
|
132
|
+
anonymous tier is exhausted), `search.maxSearchesPerCall` / `search.anonymousMaxSearchesPerCall`,
|
|
133
|
+
`fetch.digestModel` / `fetch.authRef` (the page-digest model and its own credential),
|
|
134
|
+
`fetch.privateAddressPolicy` (`"ask"` by default, `"deny"` / `"allow"`), and one `blockedDomains`
|
|
135
|
+
floor both tools honour (suffix match on a label boundary: `example.com` covers
|
|
136
|
+
`docs.example.com`). Every field is optional; `resolveWebToolsConfig` + `WEB_TOOLS_DEFAULTS` are
|
|
137
|
+
exported for a host that wants the resolved shape. **An unattended host should set
|
|
138
|
+
`fetch.privateAddressPolicy: "deny"`** — under the default a private or loopback target raises a real
|
|
139
|
+
permission prompt, and a session that cannot prompt refuses the call.
|
|
140
|
+
- **`Options.autoMemory`** — `enabled` and `directory` for the auto-memory section, for a host that
|
|
141
|
+
runs with `settingSources: []` and therefore cannot reach `autoMemoryEnabled` /
|
|
142
|
+
`autoMemoryDirectory` in a settings file. Precedence per field: this option, then the settings key,
|
|
143
|
+
then the computed default (`<home>/projects/<memory-key>/memory`, enabled). A relocated directory
|
|
144
|
+
under the home's own `projects/` tree stays write-denied.
|
|
145
|
+
|
|
146
|
+
Subagents inherit both.
|
|
147
|
+
|
|
110
148
|
### The 0.0.16 background-default change
|
|
111
149
|
|
|
112
150
|
Before 0.0.16, an Agent tool call with no `run_in_background` ran in the **foreground** (this call
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,9 @@ export type { QueryInternal, ControlRequestHandler, ControlRequestHandlerResult
|
|
|
4
4
|
export type { Options } from "./options.js";
|
|
5
5
|
export { SYSTEM_PROMPT_DYNAMIC_BOUNDARY, DEFAULT_CONTEXT_WINDOW_TOKENS, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_PLANS_DIRECTORY, DEFAULT_OUTPUT_STYLE } from "./options.js";
|
|
6
6
|
export { DEFAULT_PROVIDER_STALL_TIMEOUT_MS, DEFAULT_KEYCHAIN_SERVICE } from "./options.js";
|
|
7
|
+
export { WEB_TOOLS_DEFAULTS, resolveWebToolsConfig } from "./options.js";
|
|
8
|
+
export type { ResolvedWebToolsConfig } from "./options.js";
|
|
9
|
+
export type { WebToolsConfig, WebSearchConfig, WebFetchConfig, WebPrivateAddressPolicy, AutoMemoryConfig } from "./protocol/config.js";
|
|
7
10
|
export type { ProviderSelection, ProviderConnectionConfig, CredentialRef, ThinkingConfig, EffortLevel, AutoClassifierConfig, AdvisorConfig, ModelInfo, AgentInfo, AccountInfo } from "./protocol/config.js";
|
|
8
11
|
export type { SlotView, ActiveSlotSet, ModelFamilyListing, ModelSlotSetting, ModelRowServable } from "./protocol/config.js";
|
|
9
12
|
export type { SdkPluginConfig, SystemPromptOption, SystemPromptPreset, OutputFormat, JsonSchemaOutputFormat, SkillsOption, RewindFilesResult, RewindFilesRequest, InitPluginInfo } from "./protocol/config.js";
|
|
@@ -24,7 +27,7 @@ export { SDK_VERSION } from "./version.js";
|
|
|
24
27
|
export { MESSAGING_CONTROL_SUBTYPES, MESSAGING_CONTROL_SUBTYPE_LIST, MESSAGING_HOST_REQUEST_SUBTYPES, MESSAGING_RUNTIME_REQUEST_SUBTYPES, resolveFacetTarget } from "./protocol/messaging.js";
|
|
25
28
|
export { isRuntimeAddress, isGlobalAgentMessage, isDeliveryOutcome, isListedRuntimeObjectArray, isPermissionClassLabel, isMessagingDeliverRequest, isMessagingChildRequest, isMessagingSubscribeIdleRequest, isMessagingReadNotificationsRequest, isMessagingNotificationsPage, isMessagingIdleNoticePayload, isNotificationRecord, } from "./protocol/messaging.js";
|
|
26
29
|
export type { MessagingControlSubtype, MessagingDeliverRequest, MessagingChildRequest, MessagingSubscribeIdleRequest, MessagingSenderClassResponse, MessagingReadNotificationsRequest, MessagingNotificationsPage, MessagingIdleNoticePayload, } from "./protocol/messaging.js";
|
|
27
|
-
export type { ProtocolVersion, WinterFrame, SdkMessage as ProtocolSdkMessage, InitFrame, UserFrame, DataFrame, ControlRequestFrame, ControlResponseFrame, UnknownFrame, SDKHookStartedMessage, SDKHookProgressMessage, SDKHookResponseMessage, SDKPermissionDeniedMessage, SDKPermissionDenial, SDKTaskStartedMessage, SDKTaskNotificationMessage, SDKTaskUpdatedMessage, SDKTaskProgressMessage, SDKBackgroundTasksChangedMessage, SDKLocalCommandOutputMessage, BackgroundTaskMessage, SDKCompactBoundaryMessage, SDKSessionStateChangedMessage, WireContentBlock, WireStreamEvent, WireStreamEventDelta, SDKPartialAssistantMessage, SDKAssistantMessageError, SDKAPIRetryMessage, SDKRateLimitEvent, SDKRateLimitInfo, SDKAuthStatusMessage, SDKThinkingTokensMessage, SDKModelRefusalFallbackMessage, SDKModelRefusalNoFallbackMessage, SDKReasoningSummaryMessage, SDKModelSwitchMessage, SDKContinuityWarningMessage, } from "./protocol/frames.js";
|
|
30
|
+
export type { ProtocolVersion, WinterFrame, SdkMessage as ProtocolSdkMessage, InitFrame, UserFrame, DataFrame, ControlRequestFrame, ControlResponseFrame, ControlCancelRequestFrame, WireResultUsage, UnknownFrame, SDKHookStartedMessage, SDKHookProgressMessage, SDKHookResponseMessage, SDKPermissionDeniedMessage, SDKPermissionDenial, SDKTaskStartedMessage, SDKTaskNotificationMessage, SDKTaskUpdatedMessage, SDKTaskProgressMessage, SDKBackgroundTasksChangedMessage, SDKLocalCommandOutputMessage, BackgroundTaskMessage, SDKCompactBoundaryMessage, SDKSessionStateChangedMessage, WireContentBlock, WireStreamEvent, WireStreamEventDelta, SDKPartialAssistantMessage, SDKAssistantMessageError, SDKAPIRetryMessage, SDKRateLimitEvent, SDKRateLimitInfo, SDKAuthStatusMessage, SDKThinkingTokensMessage, SDKModelRefusalFallbackMessage, SDKModelRefusalNoFallbackMessage, SDKReasoningSummaryMessage, SDKModelSwitchMessage, SDKContinuityWarningMessage, } from "./protocol/frames.js";
|
|
28
31
|
export { resolveWinterHome, resolveKeychainServiceForProfile, isUnset } from "./paths/home.js";
|
|
29
32
|
export { transcriptProjectKey, TRANSCRIPT_PROJECT_KEY_MAX_LENGTH, isVendorCompliantProjectKey } from "./paths/project-key.js";
|
|
30
33
|
export { compatibilityKeys } from "./paths/keys.js";
|
package/dist/index.js
CHANGED
|
@@ -66,6 +66,38 @@ var DEFAULT_PLANS_DIRECTORY = `${WINTER_BRAND2.projectDirName}/plans`;
|
|
|
66
66
|
var DEFAULT_OUTPUT_STYLE = "default";
|
|
67
67
|
var DEFAULT_PROVIDER_STALL_TIMEOUT_MS = 120000;
|
|
68
68
|
var DEFAULT_KEYCHAIN_SERVICE = WINTER_BRAND2.keychainService;
|
|
69
|
+
var WEB_TOOLS_DEFAULTS = {
|
|
70
|
+
searchEnabled: true,
|
|
71
|
+
maxSearchesPerCall: 8,
|
|
72
|
+
anonymousMaxSearchesPerCall: 3,
|
|
73
|
+
privateAddressPolicy: "ask"
|
|
74
|
+
};
|
|
75
|
+
function positiveIntegerOr(value, fallback) {
|
|
76
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : fallback;
|
|
77
|
+
}
|
|
78
|
+
var PRIVATE_ADDRESS_POLICIES = ["allow", "ask", "deny"];
|
|
79
|
+
function resolveWebToolsConfig(web) {
|
|
80
|
+
const rawDigest = web?.fetch?.digestModel;
|
|
81
|
+
const digestModel = typeof rawDigest === "string" ? rawDigest.trim() : undefined;
|
|
82
|
+
const rawPolicy = web?.fetch?.privateAddressPolicy;
|
|
83
|
+
const privateAddressPolicy = PRIVATE_ADDRESS_POLICIES.find((policy) => policy === rawPolicy) ?? WEB_TOOLS_DEFAULTS.privateAddressPolicy;
|
|
84
|
+
const rawEnabled = web?.search?.enabled;
|
|
85
|
+
const rawBlocked = web?.blockedDomains;
|
|
86
|
+
return {
|
|
87
|
+
search: {
|
|
88
|
+
enabled: rawEnabled === undefined ? WEB_TOOLS_DEFAULTS.searchEnabled : rawEnabled === true,
|
|
89
|
+
...web?.search?.authRef !== undefined ? { authRef: web.search.authRef } : {},
|
|
90
|
+
maxSearchesPerCall: positiveIntegerOr(web?.search?.maxSearchesPerCall, WEB_TOOLS_DEFAULTS.maxSearchesPerCall),
|
|
91
|
+
anonymousMaxSearchesPerCall: positiveIntegerOr(web?.search?.anonymousMaxSearchesPerCall, WEB_TOOLS_DEFAULTS.anonymousMaxSearchesPerCall)
|
|
92
|
+
},
|
|
93
|
+
fetch: {
|
|
94
|
+
...digestModel !== undefined && digestModel.length > 0 ? { digestModel } : {},
|
|
95
|
+
...web?.fetch?.authRef !== undefined ? { authRef: web.fetch.authRef } : {},
|
|
96
|
+
privateAddressPolicy
|
|
97
|
+
},
|
|
98
|
+
blockedDomains: (Array.isArray(rawBlocked) ? rawBlocked : []).filter((d) => typeof d === "string" && d.trim().length > 0)
|
|
99
|
+
};
|
|
100
|
+
}
|
|
69
101
|
function isWinterMcpServerInstance(value) {
|
|
70
102
|
if (typeof value !== "object" || value === null)
|
|
71
103
|
return false;
|
|
@@ -601,6 +633,8 @@ function query(args) {
|
|
|
601
633
|
...brand.keychainService !== WINTER_BRAND2.keychainService || options.keychainService !== undefined ? { keychainService: brand.keychainService } : {},
|
|
602
634
|
...options.autoClassifier !== undefined ? { autoClassifier: options.autoClassifier } : {},
|
|
603
635
|
...options.advisor !== undefined ? { advisor: options.advisor } : {},
|
|
636
|
+
...options.web !== undefined ? { web: options.web } : {},
|
|
637
|
+
...options.autoMemory !== undefined ? { autoMemory: options.autoMemory } : {},
|
|
604
638
|
brand
|
|
605
639
|
};
|
|
606
640
|
const command = options.spawnClaudeCodeProcess ? options.pathToClaudeCodeExecutable ?? "winter" : resolveRuntimeExecutable(options);
|
|
@@ -632,6 +666,7 @@ function query(args) {
|
|
|
632
666
|
proc.stdin.write(encodeFrame(frame));
|
|
633
667
|
}
|
|
634
668
|
const controlRequestHandlers = new Map;
|
|
669
|
+
const incomingRequestAborts = new Map;
|
|
635
670
|
async function handleIncomingControlRequest(cf) {
|
|
636
671
|
try {
|
|
637
672
|
const handler = controlRequestHandlers.get(cf.subtype);
|
|
@@ -644,8 +679,12 @@ function query(args) {
|
|
|
644
679
|
});
|
|
645
680
|
return;
|
|
646
681
|
}
|
|
682
|
+
const cancel = new AbortController;
|
|
683
|
+
incomingRequestAborts.set(cf.requestId, cancel);
|
|
647
684
|
try {
|
|
648
|
-
const result = await handler(cf.payload);
|
|
685
|
+
const result = await handler(cf.payload, { signal: cancel.signal });
|
|
686
|
+
if (cancel.signal.aborted)
|
|
687
|
+
return;
|
|
649
688
|
if (result.ok) {
|
|
650
689
|
writeControlResponse({
|
|
651
690
|
type: "control_response",
|
|
@@ -657,19 +696,27 @@ function query(args) {
|
|
|
657
696
|
writeControlResponse({ type: "control_response", requestId: cf.requestId, ok: false, error: result.error });
|
|
658
697
|
}
|
|
659
698
|
} catch (err) {
|
|
699
|
+
if (cancel.signal.aborted)
|
|
700
|
+
return;
|
|
660
701
|
const message = err instanceof Error ? err.message : String(err);
|
|
661
702
|
writeControlResponse({ type: "control_response", requestId: cf.requestId, ok: false, error: { code: "handler_threw", message } });
|
|
703
|
+
} finally {
|
|
704
|
+
incomingRequestAborts.delete(cf.requestId);
|
|
662
705
|
}
|
|
663
706
|
} catch {}
|
|
664
707
|
}
|
|
665
708
|
function makePermissionHandler(canUseTool) {
|
|
666
|
-
return async (payload) => {
|
|
709
|
+
return async (payload, handlerCtx) => {
|
|
667
710
|
const req = payload;
|
|
668
711
|
const controller = new AbortController;
|
|
669
712
|
if (options.abortController?.signal.aborted)
|
|
670
713
|
controller.abort();
|
|
671
714
|
else
|
|
672
715
|
options.abortController?.signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
716
|
+
if (handlerCtx?.signal.aborted === true)
|
|
717
|
+
controller.abort();
|
|
718
|
+
else
|
|
719
|
+
handlerCtx?.signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
673
720
|
let result;
|
|
674
721
|
try {
|
|
675
722
|
result = await canUseTool(req.toolName, req.input, {
|
|
@@ -794,6 +841,13 @@ function query(args) {
|
|
|
794
841
|
}
|
|
795
842
|
continue;
|
|
796
843
|
}
|
|
844
|
+
if (frame.type === "control_cancel_request") {
|
|
845
|
+
const cancelledId = frame.requestId ?? "";
|
|
846
|
+
const cancelled = incomingRequestAborts.get(cancelledId);
|
|
847
|
+
incomingRequestAborts.delete(cancelledId);
|
|
848
|
+
cancelled?.abort();
|
|
849
|
+
continue;
|
|
850
|
+
}
|
|
797
851
|
if (frame.type === "control_request") {
|
|
798
852
|
handleIncomingControlRequest(frame);
|
|
799
853
|
continue;
|
|
@@ -967,7 +1021,7 @@ function query(args) {
|
|
|
967
1021
|
return gen;
|
|
968
1022
|
}
|
|
969
1023
|
// src/version.ts
|
|
970
|
-
var SDK_VERSION = "0.0.
|
|
1024
|
+
var SDK_VERSION = "0.0.20";
|
|
971
1025
|
// src/paths/project-key.ts
|
|
972
1026
|
var TRANSCRIPT_PROJECT_KEY_MAX_LENGTH = 64;
|
|
973
1027
|
var VENDOR_PROJECT_KEY_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
@@ -1010,13 +1064,41 @@ function resolveCanonical(raw) {
|
|
|
1010
1064
|
}
|
|
1011
1065
|
}
|
|
1012
1066
|
function gitCommonRoot(resolvedCwd) {
|
|
1067
|
+
let commonDir;
|
|
1068
|
+
try {
|
|
1069
|
+
const raw = runGit(["-C", resolvedCwd, "rev-parse", "--git-common-dir"]);
|
|
1070
|
+
commonDir = platformNormalize(realpathSync(isAbsolute(raw) ? raw : resolvePath(resolvedCwd, raw)));
|
|
1071
|
+
} catch {
|
|
1072
|
+
return null;
|
|
1073
|
+
}
|
|
1074
|
+
const candidate = dirname2(commonDir);
|
|
1075
|
+
if (isWithin(resolvedCwd, candidate))
|
|
1076
|
+
return candidate;
|
|
1077
|
+
if (registeredWorktrees(commonDir).some((worktree) => isWithin(resolvedCwd, worktree)))
|
|
1078
|
+
return candidate;
|
|
1079
|
+
const configured = configuredWorktree(commonDir);
|
|
1080
|
+
if (configured !== null && isWithin(resolvedCwd, configured))
|
|
1081
|
+
return configured;
|
|
1082
|
+
return null;
|
|
1083
|
+
}
|
|
1084
|
+
function runGit(args) {
|
|
1085
|
+
return execFileSync("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
1086
|
+
}
|
|
1087
|
+
function isWithin(path, dir) {
|
|
1088
|
+
return path === dir || path.startsWith(dir.endsWith("/") ? dir : `${dir}/`);
|
|
1089
|
+
}
|
|
1090
|
+
function registeredWorktrees(commonDir) {
|
|
1091
|
+
try {
|
|
1092
|
+
return runGit(["--git-dir", commonDir, "worktree", "list", "--porcelain"]).split(`
|
|
1093
|
+
`).filter((line) => line.startsWith("worktree ")).map((line) => resolveCanonical(line.slice("worktree ".length)));
|
|
1094
|
+
} catch {
|
|
1095
|
+
return [];
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
function configuredWorktree(commonDir) {
|
|
1013
1099
|
try {
|
|
1014
|
-
const raw =
|
|
1015
|
-
|
|
1016
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
1017
|
-
}).trim();
|
|
1018
|
-
const commonDir = isAbsolute(raw) ? raw : resolvePath(resolvedCwd, raw);
|
|
1019
|
-
return platformNormalize(dirname2(realpathSync(commonDir)));
|
|
1100
|
+
const raw = runGit(["--git-dir", commonDir, "config", "--get", "core.worktree"]);
|
|
1101
|
+
return raw.length > 0 ? resolveCanonical(isAbsolute(raw) ? raw : resolvePath(commonDir, raw)) : null;
|
|
1020
1102
|
} catch {
|
|
1021
1103
|
return null;
|
|
1022
1104
|
}
|
|
@@ -1690,6 +1772,7 @@ export {
|
|
|
1690
1772
|
SYSTEM_PROMPT_DYNAMIC_BOUNDARY,
|
|
1691
1773
|
SessionNotFoundError,
|
|
1692
1774
|
TRANSCRIPT_PROJECT_KEY_MAX_LENGTH,
|
|
1775
|
+
WEB_TOOLS_DEFAULTS,
|
|
1693
1776
|
WINTER_BRAND2 as WINTER_BRAND,
|
|
1694
1777
|
WinterCompatibilitySessionStore2 as WinterCompatibilitySessionStore,
|
|
1695
1778
|
WinterRpcError,
|
|
@@ -1738,6 +1821,7 @@ export {
|
|
|
1738
1821
|
resolveRuntimeExecutable,
|
|
1739
1822
|
resolveSettings,
|
|
1740
1823
|
resolveSettingsDetailed,
|
|
1824
|
+
resolveWebToolsConfig,
|
|
1741
1825
|
resolveWinterHome2 as resolveWinterHome,
|
|
1742
1826
|
settingsPathFor,
|
|
1743
1827
|
splitFrames,
|
package/dist/options.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { SpawnClaudeCodeProcess } from "./transport.js";
|
|
2
2
|
import type { PermissionMode, CanUseTool, HookEvent, HookCallbackMatcher } from "./permissions/types.js";
|
|
3
|
-
import type { SandboxSettingsConfig, McpServerToolPolicy, McpStdioServerConfig, McpHttpServerConfig, McpSSEServerConfig, McpSdkServerConfig, RuntimeAgentDefinition, SdkPluginConfig, SystemPromptOption, OutputFormat, SkillsOption, ProviderSelection, ThinkingConfig, EffortLevel, AutoClassifierConfig, AdvisorConfig } from "./protocol/config.js";
|
|
3
|
+
import type { SandboxSettingsConfig, McpServerToolPolicy, McpStdioServerConfig, McpHttpServerConfig, McpSSEServerConfig, McpSdkServerConfig, RuntimeAgentDefinition, SdkPluginConfig, SystemPromptOption, OutputFormat, SkillsOption, ProviderSelection, ThinkingConfig, EffortLevel, AutoClassifierConfig, AdvisorConfig, WebToolsConfig, WebPrivateAddressPolicy, AutoMemoryConfig, CredentialRef } from "./protocol/config.js";
|
|
4
4
|
import type { SettingSource } from "./settings/types.js";
|
|
5
5
|
import type { SessionStore } from "./store/session-store.js";
|
|
6
6
|
import { type BrandProfile } from "./brand.js";
|
|
7
7
|
export type { BrandProfile, BrandValidation } from "./brand.js";
|
|
8
8
|
export type { SdkPluginConfig, SystemPromptOption, OutputFormat, JsonSchemaOutputFormat, SkillsOption } from "./protocol/config.js";
|
|
9
9
|
export type { ProviderSelection, ProviderConnectionConfig, CredentialRef, ThinkingConfig, EffortLevel, AutoClassifierConfig, AdvisorConfig } from "./protocol/config.js";
|
|
10
|
+
export type { WebToolsConfig, WebSearchConfig, WebFetchConfig, WebPrivateAddressPolicy, AutoMemoryConfig } from "./protocol/config.js";
|
|
10
11
|
export declare const SYSTEM_PROMPT_DYNAMIC_BOUNDARY = "__SYSTEM_PROMPT_DYNAMIC_BOUNDARY__";
|
|
11
12
|
export declare const DEFAULT_CONTEXT_WINDOW_TOKENS = 200000;
|
|
12
13
|
export declare const DEFAULT_COMPACTION_THRESHOLD = 0.92;
|
|
@@ -14,6 +15,42 @@ export declare const DEFAULT_PLANS_DIRECTORY: string;
|
|
|
14
15
|
export declare const DEFAULT_OUTPUT_STYLE = "default";
|
|
15
16
|
export declare const DEFAULT_PROVIDER_STALL_TIMEOUT_MS = 120000;
|
|
16
17
|
export declare const DEFAULT_KEYCHAIN_SERVICE: string;
|
|
18
|
+
/**
|
|
19
|
+
* Every web-tool default, spelled ONCE. A reader function resolves an absent field against this --
|
|
20
|
+
* no consumer writes a literal of its own.
|
|
21
|
+
*
|
|
22
|
+
* `maxSearchesPerCall: 8` is the pinned tool's own per-call bound. `anonymousMaxSearchesPerCall: 3`
|
|
23
|
+
* is Winter's: see `WebSearchConfig.anonymousMaxSearchesPerCall`. `privateAddressPolicy: "ask"` is
|
|
24
|
+
* the conservative interactive posture; a host that can never ask sets `"deny"`.
|
|
25
|
+
*/
|
|
26
|
+
export declare const WEB_TOOLS_DEFAULTS: {
|
|
27
|
+
readonly searchEnabled: true;
|
|
28
|
+
readonly maxSearchesPerCall: 8;
|
|
29
|
+
readonly anonymousMaxSearchesPerCall: 3;
|
|
30
|
+
readonly privateAddressPolicy: "ask";
|
|
31
|
+
};
|
|
32
|
+
/** `WebToolsConfig` with every default applied -- what a consumer reads instead of the raw option. */
|
|
33
|
+
export interface ResolvedWebToolsConfig {
|
|
34
|
+
search: {
|
|
35
|
+
enabled: boolean;
|
|
36
|
+
authRef?: CredentialRef;
|
|
37
|
+
maxSearchesPerCall: number;
|
|
38
|
+
anonymousMaxSearchesPerCall: number;
|
|
39
|
+
};
|
|
40
|
+
fetch: {
|
|
41
|
+
digestModel?: string;
|
|
42
|
+
authRef?: CredentialRef;
|
|
43
|
+
privateAddressPolicy: WebPrivateAddressPolicy;
|
|
44
|
+
};
|
|
45
|
+
blockedDomains: string[];
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* THE one reader of `WebToolsConfig`. Pure, dependency-free and total: an absent block, an absent
|
|
49
|
+
* field, a non-positive or non-finite bound and a whitespace-only `digestModel` all resolve to the
|
|
50
|
+
* default rather than to a value no consumer can act on (a bound of `0` would make a tool that is
|
|
51
|
+
* advertised and can never search; disabling search is `search.enabled: false`).
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveWebToolsConfig(web: WebToolsConfig | undefined): ResolvedWebToolsConfig;
|
|
17
54
|
export interface McpSdkServerConfigWithInstance extends McpSdkServerConfig {
|
|
18
55
|
instance: unknown;
|
|
19
56
|
}
|
|
@@ -238,7 +275,9 @@ export interface Options {
|
|
|
238
275
|
autoClassifier?: AutoClassifierConfig;
|
|
239
276
|
/**
|
|
240
277
|
* DISCLOSED WINTER option (P2 carry, wired in T10): the advisor/reviewer backend's model, same
|
|
241
|
-
* selection path
|
|
278
|
+
* selection path -- a provider-qualified tag (`<providerId>/<model>`) names its own provider, so a
|
|
279
|
+
* reviewer on another provider than the session's is just that tag plus that provider's credential
|
|
280
|
+
* (the `web.fetch.digestModel` shape). Its optional `authRef` (fix wave, Ruling E-1) is the advisor's OWN credential:
|
|
242
281
|
* a target on another provider than the session's never inherits the session's -- it uses the
|
|
243
282
|
* route's ref, else the target provider's own keychain record (`<providerId>:default`), else a
|
|
244
283
|
* typed `no-credential-for-provider` refusal at its first generation.
|
|
@@ -246,6 +285,20 @@ export interface Options {
|
|
|
246
285
|
* The MODEL may also come from `settings.advisor.model` (D30, hot); `Options.advisor.model` wins.
|
|
247
286
|
*/
|
|
248
287
|
advisor?: AdvisorConfig;
|
|
288
|
+
/**
|
|
289
|
+
* DISCLOSED WINTER option: the `WebSearch` / `WebFetch` tools' configuration -- the search
|
|
290
|
+
* backend's fallback key and per-call bounds, the page-digest model and its credential, the
|
|
291
|
+
* private-address policy, and the ONE `blockedDomains` floor both tools honour. Every field is
|
|
292
|
+
* optional; `resolveWebToolsConfig` applies `WEB_TOOLS_DEFAULTS`. See `WebToolsConfig`.
|
|
293
|
+
*/
|
|
294
|
+
web?: WebToolsConfig;
|
|
295
|
+
/**
|
|
296
|
+
* DISCLOSED WINTER option: the host's say over the auto-memory section -- whether it is on, and
|
|
297
|
+
* which directory it names. Wins over the settings keys, which win over the computed default; it
|
|
298
|
+
* is how a host that disables settings files (`settingSources: []`) still makes the session agree
|
|
299
|
+
* with it about where memory lives. See `AutoMemoryConfig`.
|
|
300
|
+
*/
|
|
301
|
+
autoMemory?: AutoMemoryConfig;
|
|
249
302
|
/**
|
|
250
303
|
* DISCLOSED WINTER option (P7a, D19): THE BRAND PROFILE — every Winter-owned name this session
|
|
251
304
|
* runs under, as a partial that folds onto Winter's own defaults (brand.ts's `WINTER_BRAND`).
|
|
@@ -322,6 +322,10 @@ export interface RuntimeConfig {
|
|
|
322
322
|
keychainService?: string;
|
|
323
323
|
autoClassifier?: AutoClassifierConfig;
|
|
324
324
|
advisor?: AdvisorConfig;
|
|
325
|
+
/** The wire twin of `Options.web` -- see `WebToolsConfig`. Pure passthrough; absent means every default in `WEB_TOOLS_DEFAULTS`. */
|
|
326
|
+
web?: WebToolsConfig;
|
|
327
|
+
/** The wire twin of `Options.autoMemory` -- see `AutoMemoryConfig`. Pure passthrough; absent means "settings, then the computed default". */
|
|
328
|
+
autoMemory?: AutoMemoryConfig;
|
|
325
329
|
/**
|
|
326
330
|
* P7a (D19): the RESOLVED brand profile — every Winter-owned name this session runs under.
|
|
327
331
|
*
|
|
@@ -469,9 +473,154 @@ export interface AutoClassifierConfig {
|
|
|
469
473
|
* advisor's provider, the advisor's provider refuses with a typed `no-credential-for-provider`.
|
|
470
474
|
*/
|
|
471
475
|
export interface AdvisorConfig {
|
|
476
|
+
/**
|
|
477
|
+
* The reviewer's model: a PROVIDER-QUALIFIED TAG (`<providerId>/<model>`, e.g.
|
|
478
|
+
* `codex-oauth/gpt-5.6-sol`) or a slot name, resolved through the SAME selection path as the
|
|
479
|
+
* session model -- exactly as `WebFetchConfig.digestModel` is.
|
|
480
|
+
*
|
|
481
|
+
* THE TAG IS THE PROVIDER IDENTITY; there is deliberately no second field for it. A qualified tag
|
|
482
|
+
* resolves under ITS OWN provider, never under the session's (`Options.provider`), so an advisor on
|
|
483
|
+
* another provider than the session's needs nothing but that tag and, in `authRef`, that provider's
|
|
484
|
+
* own credential. A host that splits the tag down to a bare model id before passing it has thrown
|
|
485
|
+
* the provider away: a bare id is read as a slot name or canonical id and resolved by the session's
|
|
486
|
+
* slot rules, which is a different question.
|
|
487
|
+
*/
|
|
472
488
|
model: string;
|
|
473
489
|
authRef?: CredentialRef;
|
|
474
490
|
}
|
|
491
|
+
/**
|
|
492
|
+
* What to do when `WebFetch` is pointed at a loopback, private-range or link-local address.
|
|
493
|
+
*
|
|
494
|
+
* `"ask"` raise the ordinary permission prompt for that host before anything is fetched;
|
|
495
|
+
* `"deny"` refuse with a typed tool result and fetch nothing;
|
|
496
|
+
* `"allow"` fetch it like any public host.
|
|
497
|
+
*
|
|
498
|
+
* WHY THIS IS A HOST DECISION AND NOT A CONSTANT. A sandboxed shell has no network, so `WebFetch` is
|
|
499
|
+
* the only door from a session to the services on the user's own machine and LAN -- an admin page, a
|
|
500
|
+
* metadata endpoint. Whether that door opens silently depends on whether the session can ask a human
|
|
501
|
+
* at all: an interactive host can, an unattended one cannot and must refuse.
|
|
502
|
+
*
|
|
503
|
+
* WHAT `"allow"` AND AN APPROVAL CAN AND CANNOT REACH. `WebFetch` upgrades `http` to `https`
|
|
504
|
+
* unconditionally and refuses any hostname with fewer than two dot-separated labels -- both are the
|
|
505
|
+
* reference runtime's own rules, kept. So this policy governs an `https` service at an IPv4 literal
|
|
506
|
+
* (`https://127.0.0.1:8443/`) or at a name the URL parser leaves with two or more labels
|
|
507
|
+
* (`printer.local`, `api.localhost`). A plain-`http` port and every IPv6 literal (`[::1]` is one
|
|
508
|
+
* label) are unfetchable whatever this says -- a session pointed at one gets `Invalid URL` from the
|
|
509
|
+
* tool, and no approval is raised for it, because no answer could make it work.
|
|
510
|
+
*/
|
|
511
|
+
export type WebPrivateAddressPolicy = "allow" | "ask" | "deny";
|
|
512
|
+
/** `WebSearch`'s own configuration. Every field is optional; see `WEB_TOOLS_DEFAULTS` (options.ts) for what absent means. */
|
|
513
|
+
export interface WebSearchConfig {
|
|
514
|
+
/**
|
|
515
|
+
* The host's explicit OFF switch for the search BACKEND. Absent means enabled.
|
|
516
|
+
*
|
|
517
|
+
* The backend's anonymous tier needs no credential, so "is a search backend usable" is `true` for
|
|
518
|
+
* every session by default -- which would make the tool's capability gate a constant. This is the
|
|
519
|
+
* one fact that can make it `false`: a host that must not let a session reach the backend at all
|
|
520
|
+
* (an offline deployment, a policy that forbids the third-party endpoint). With `false` the tool is
|
|
521
|
+
* not advertised, and a call that reaches it anyway answers with a typed refusal.
|
|
522
|
+
*
|
|
523
|
+
* NOT a substitute for `disallowedTools`, which hides a tool the runtime has; this says the
|
|
524
|
+
* backend behind it is not there.
|
|
525
|
+
*/
|
|
526
|
+
enabled?: boolean;
|
|
527
|
+
/**
|
|
528
|
+
* A reference to the search backend's API key -- the FALLBACK, used only once the anonymous tier
|
|
529
|
+
* is exhausted or rate-limited. A locator, never the key: the runtime resolves it at the last
|
|
530
|
+
* responsible moment and accepts EITHER JSON credential material (`{"kind":"api-key","key":...}`)
|
|
531
|
+
* OR a bare non-empty string, because a host that shares this keychain slot with another client
|
|
532
|
+
* cannot change what is stored in it. Absent means anonymous-only: an exhausted quota is then a
|
|
533
|
+
* typed "add a key" result, never an error that ends the turn.
|
|
534
|
+
*/
|
|
535
|
+
authRef?: CredentialRef;
|
|
536
|
+
/**
|
|
537
|
+
* The most backend searches ONE `WebSearch` call may run while a key is in use (the inner model
|
|
538
|
+
* decides how many it needs, up to this). Absent means `WEB_TOOLS_DEFAULTS.maxSearchesPerCall`.
|
|
539
|
+
*/
|
|
540
|
+
maxSearchesPerCall?: number;
|
|
541
|
+
/**
|
|
542
|
+
* The same bound while the call is riding the ANONYMOUS tier. Separate, and lower by default,
|
|
543
|
+
* because the anonymous tier is a small shared daily allowance: eight searches per call would
|
|
544
|
+
* spend it in a handful of calls and push every later one onto the key (or onto the "quota
|
|
545
|
+
* exhausted" result when there is no key). Absent means
|
|
546
|
+
* `WEB_TOOLS_DEFAULTS.anonymousMaxSearchesPerCall`.
|
|
547
|
+
*/
|
|
548
|
+
anonymousMaxSearchesPerCall?: number;
|
|
549
|
+
}
|
|
550
|
+
/** `WebFetch`'s own configuration. Every field is optional; see `WEB_TOOLS_DEFAULTS` (options.ts) for what absent means. */
|
|
551
|
+
export interface WebFetchConfig {
|
|
552
|
+
/**
|
|
553
|
+
* The model that digests a fetched page against the caller's prompt -- a provider-qualified tag
|
|
554
|
+
* (`<providerId>/<model>`) or a slot name, resolved through the SAME selection path as the session
|
|
555
|
+
* model.
|
|
556
|
+
*
|
|
557
|
+
* THE DEFAULT, stated plainly: when the host names none, the digest runs on the SESSION'S OWN
|
|
558
|
+
* MODEL. That is the one choice that is always resolvable and needs no second credential. There is
|
|
559
|
+
* deliberately no "cheapest slot" heuristic -- a family's slots are not reliably ranked
|
|
560
|
+
* strongest-to-weakest, so picking one by position would be a guess presented as a rule.
|
|
561
|
+
*
|
|
562
|
+
* A STATED model that cannot be resolved (unknown tag, disabled provider, no credential) is a
|
|
563
|
+
* typed refusal surfaced as the tool's RESULT. It is never a silent fallback onto the session's
|
|
564
|
+
* model: a host that named a small model did so to bound cost, and quietly spending the session
|
|
565
|
+
* model's price instead is the failure this field exists to prevent.
|
|
566
|
+
*/
|
|
567
|
+
digestModel?: string;
|
|
568
|
+
/**
|
|
569
|
+
* The digest model's OWN credential, for a digest model on another provider than the session's
|
|
570
|
+
* (the cross-provider credential rule every auxiliary route follows: the route's own ref, else the
|
|
571
|
+
* session's material only when the provider is the same, else the target provider's
|
|
572
|
+
* `<providerId>:default` keychain record, else a typed `no-credential-for-provider`). The session's
|
|
573
|
+
* key is never sent to another provider. Ignored when `digestModel` is absent.
|
|
574
|
+
*/
|
|
575
|
+
authRef?: CredentialRef;
|
|
576
|
+
/** See `WebPrivateAddressPolicy`. Absent means `WEB_TOOLS_DEFAULTS.privateAddressPolicy`. */
|
|
577
|
+
privateAddressPolicy?: WebPrivateAddressPolicy;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* DISCLOSED WINTER option: the two web tools' configuration.
|
|
581
|
+
*
|
|
582
|
+
* `blockedDomains` sits at THIS level, not under either tool, because it is ONE list with ONE
|
|
583
|
+
* meaning -- the host's domain floor -- and both tools must honour it: `WebFetch` refuses a listed
|
|
584
|
+
* host outright, and `WebSearch` sends the list as the backend's exclusion filter on EVERY inner
|
|
585
|
+
* search, so a blocked domain can neither be fetched nor be surfaced as a link to fetch. Two lists
|
|
586
|
+
* would be two chances to update one and forget the other.
|
|
587
|
+
*
|
|
588
|
+
* MATCHING IS BY SUFFIX ON A LABEL BOUNDARY: listing `example.com` blocks `example.com` and every
|
|
589
|
+
* subdomain of it (`docs.example.com`), and does not block `notexample.com`. Entries are compared
|
|
590
|
+
* case-insensitively; a leading `*.` or `.` and a trailing `.` are ignored.
|
|
591
|
+
*/
|
|
592
|
+
export interface WebToolsConfig {
|
|
593
|
+
search?: WebSearchConfig;
|
|
594
|
+
fetch?: WebFetchConfig;
|
|
595
|
+
blockedDomains?: string[];
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* DISCLOSED WINTER option: the host's say over the auto-memory section.
|
|
599
|
+
*
|
|
600
|
+
* WHY IT EXISTS. The runtime computes the memory directory itself and reads `autoMemoryEnabled` /
|
|
601
|
+
* `autoMemoryDirectory` from SETTINGS FILES only. A host that turns settings files off
|
|
602
|
+
* (`settingSources: []`) therefore had no way to make the session agree with it about where memory
|
|
603
|
+
* lives, or to turn the section off -- the two sides could only agree by computing the same path by
|
|
604
|
+
* coincidence.
|
|
605
|
+
*
|
|
606
|
+
* PRECEDENCE, per field: this option, then the settings key, then the computed default
|
|
607
|
+
* (`<home>/projects/<memory-key>/memory`, enabled).
|
|
608
|
+
*
|
|
609
|
+
* `enabled: false` the auto-memory section and its index are omitted entirely, whatever settings
|
|
610
|
+
* say; `enabled: true` turns it on even over a settings `false`.
|
|
611
|
+
* `directory` REPLACES the computed path outright, with no per-project nesting beneath it
|
|
612
|
+
* (`~` and a cwd-relative path are expanded exactly as the settings key's are).
|
|
613
|
+
* Whitespace-only counts as absent.
|
|
614
|
+
*
|
|
615
|
+
* NOTE FOR A HOST RELOCATING THE DIRECTORY: the write-permission carve-out for memory files is keyed
|
|
616
|
+
* to the DEFAULT `projects/<key>/memory` shape under the home. A directory elsewhere under the
|
|
617
|
+
* home's `projects/` tree is still write-denied; one outside the home meets no floor at all and
|
|
618
|
+
* follows the session's ordinary write rules.
|
|
619
|
+
*/
|
|
620
|
+
export interface AutoMemoryConfig {
|
|
621
|
+
enabled?: boolean;
|
|
622
|
+
directory?: string;
|
|
623
|
+
}
|
|
475
624
|
/**
|
|
476
625
|
* The pinned `ModelInfo` (`sdk.d.ts:1261-1300`): three required fields, six optional.
|
|
477
626
|
*
|
|
@@ -42,11 +42,56 @@ export interface ControlResponseFrame {
|
|
|
42
42
|
message: string;
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Runtime -> host: "I stopped waiting for control_request `requestId`" (lane C, C2 -- claude parity:
|
|
47
|
+
* claude's structuredIO writes `control_cancel_request` when a pending request's signal aborts, e.g.
|
|
48
|
+
* a turn interrupted while a permission prompt is open). The host aborts the callback it is running
|
|
49
|
+
* for that request (`canUseTool`'s `signal`) and owes no response; one sent anyway is dropped.
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* `result.usage`: claude's `NonNullableUsage` (every `BetaUsage` field, none null), carrying THIS
|
|
53
|
+
* turn's main-loop generations -- claude builds a fresh QueryEngine per prompt in SDK mode, so its
|
|
54
|
+
* `totalUsage` starts at EMPTY_USAGE each turn. The four token counts are real; the rest is filled the
|
|
55
|
+
* way the pinned binary's own EMPTY_USAGE fills a value it has no data for, and says so:
|
|
56
|
+
* - `cache_creation`: every cache write Winter marks is the default 5-minute ephemeral one (the
|
|
57
|
+
* adapters send `{type: "ephemeral"}` with no ttl), so `ephemeral_5m_input_tokens` equals
|
|
58
|
+
* `cache_creation_input_tokens` and `ephemeral_1h_input_tokens` is 0;
|
|
59
|
+
* - `server_tool_use`: Winter's WebSearch/WebFetch run client-side, never as billed server tools: 0/0;
|
|
60
|
+
* - `output_tokens_details.thinking_tokens`: 0 -- providers' reasoning-token counts are not threaded
|
|
61
|
+
* through Winter's usage yet (they are included in `output_tokens`);
|
|
62
|
+
* - `service_tier: "standard"`, `inference_geo: ""`, `iterations: []`, `speed: "standard"`: the
|
|
63
|
+
* pinned EMPTY_USAGE's own values.
|
|
64
|
+
*/
|
|
65
|
+
export interface WireResultUsage {
|
|
66
|
+
output_tokens_details: {
|
|
67
|
+
thinking_tokens: number;
|
|
68
|
+
};
|
|
69
|
+
input_tokens: number;
|
|
70
|
+
cache_creation_input_tokens: number;
|
|
71
|
+
cache_read_input_tokens: number;
|
|
72
|
+
output_tokens: number;
|
|
73
|
+
server_tool_use: {
|
|
74
|
+
web_search_requests: number;
|
|
75
|
+
web_fetch_requests: number;
|
|
76
|
+
};
|
|
77
|
+
service_tier: "standard" | "priority" | "batch";
|
|
78
|
+
cache_creation: {
|
|
79
|
+
ephemeral_1h_input_tokens: number;
|
|
80
|
+
ephemeral_5m_input_tokens: number;
|
|
81
|
+
};
|
|
82
|
+
inference_geo: string;
|
|
83
|
+
iterations: unknown[];
|
|
84
|
+
speed: "standard" | "fast";
|
|
85
|
+
}
|
|
86
|
+
export interface ControlCancelRequestFrame {
|
|
87
|
+
type: "control_cancel_request";
|
|
88
|
+
requestId: string;
|
|
89
|
+
}
|
|
45
90
|
export interface UnknownFrame {
|
|
46
91
|
type: string;
|
|
47
92
|
[k: string]: unknown;
|
|
48
93
|
}
|
|
49
|
-
export type WinterFrame = InitFrame | UserFrame | DataFrame | ControlRequestFrame | ControlResponseFrame | UnknownFrame;
|
|
94
|
+
export type WinterFrame = InitFrame | UserFrame | DataFrame | ControlRequestFrame | ControlResponseFrame | ControlCancelRequestFrame | UnknownFrame;
|
|
50
95
|
export interface SDKHookStartedMessage {
|
|
51
96
|
type: "system";
|
|
52
97
|
subtype: "hook_started";
|
|
@@ -618,6 +663,8 @@ export type SdkMessage = {
|
|
|
618
663
|
structured_output?: unknown;
|
|
619
664
|
terminal_reason?: "structured_output_retry_exhausted" | "api_error" | string;
|
|
620
665
|
api_error_status?: number | null;
|
|
666
|
+
/** THIS turn's main-loop usage -- claude's `result.usage` (dist-session fixes C1); see `WireResultUsage`. */
|
|
667
|
+
usage?: WireResultUsage;
|
|
621
668
|
permission_denials: SDKPermissionDenial[];
|
|
622
669
|
[k: string]: unknown;
|
|
623
670
|
} | {
|
package/dist/query.d.ts
CHANGED
|
@@ -21,7 +21,14 @@ export type ControlRequestHandlerResult = {
|
|
|
21
21
|
message: string;
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* A handler for one runtime-originated control_request subtype. `ctx.signal` aborts when the runtime
|
|
26
|
+
* CANCELS the request (`control_cancel_request` -- lane C, C2, claude parity): the handler should stop
|
|
27
|
+
* waiting, and whatever it returns afterwards is not sent (the runtime already stopped waiting).
|
|
28
|
+
*/
|
|
29
|
+
export type ControlRequestHandler = (payload: unknown, ctx?: {
|
|
30
|
+
signal: AbortSignal;
|
|
31
|
+
}) => Promise<ControlRequestHandlerResult>;
|
|
25
32
|
export interface QueryInternal {
|
|
26
33
|
registerControlRequestHandler(subtype: string, handler: ControlRequestHandler): void;
|
|
27
34
|
respondPermission(requestId: string, result: PermissionResult): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yanlinglabs/winter-agent-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -45,15 +45,15 @@
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@yanlinglabs/winter-provider-catalog": "0.0.
|
|
48
|
+
"@yanlinglabs/winter-provider-catalog": "0.0.20"
|
|
49
49
|
},
|
|
50
50
|
"optionalDependencies": {
|
|
51
|
-
"@yanlinglabs/winter-agent-sdk-darwin-arm64": "0.0.
|
|
51
|
+
"@yanlinglabs/winter-agent-sdk-darwin-arm64": "0.0.20"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^26.4.0",
|
|
55
|
-
"winter-
|
|
56
|
-
"
|
|
55
|
+
"@yanlinglabs/winter-conformance": "0.0.20",
|
|
56
|
+
"winter-agent-runtime": "0.0.20"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {}
|
|
59
59
|
}
|