@yanlinglabs/winter-agent-sdk 0.0.17 → 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/dist/index.d.ts +1 -1
- package/dist/index.js +57 -9
- package/dist/options.d.ts +3 -1
- package/dist/protocol/config.d.ts +12 -0
- package/dist/protocol/frames.d.ts +48 -1
- package/dist/query.d.ts +8 -1
- package/package.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export { SDK_VERSION } from "./version.js";
|
|
|
27
27
|
export { MESSAGING_CONTROL_SUBTYPES, MESSAGING_CONTROL_SUBTYPE_LIST, MESSAGING_HOST_REQUEST_SUBTYPES, MESSAGING_RUNTIME_REQUEST_SUBTYPES, resolveFacetTarget } from "./protocol/messaging.js";
|
|
28
28
|
export { isRuntimeAddress, isGlobalAgentMessage, isDeliveryOutcome, isListedRuntimeObjectArray, isPermissionClassLabel, isMessagingDeliverRequest, isMessagingChildRequest, isMessagingSubscribeIdleRequest, isMessagingReadNotificationsRequest, isMessagingNotificationsPage, isMessagingIdleNoticePayload, isNotificationRecord, } from "./protocol/messaging.js";
|
|
29
29
|
export type { MessagingControlSubtype, MessagingDeliverRequest, MessagingChildRequest, MessagingSubscribeIdleRequest, MessagingSenderClassResponse, MessagingReadNotificationsRequest, MessagingNotificationsPage, MessagingIdleNoticePayload, } from "./protocol/messaging.js";
|
|
30
|
-
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";
|
|
31
31
|
export { resolveWinterHome, resolveKeychainServiceForProfile, isUnset } from "./paths/home.js";
|
|
32
32
|
export { transcriptProjectKey, TRANSCRIPT_PROJECT_KEY_MAX_LENGTH, isVendorCompliantProjectKey } from "./paths/project-key.js";
|
|
33
33
|
export { compatibilityKeys } from "./paths/keys.js";
|
package/dist/index.js
CHANGED
|
@@ -666,6 +666,7 @@ function query(args) {
|
|
|
666
666
|
proc.stdin.write(encodeFrame(frame));
|
|
667
667
|
}
|
|
668
668
|
const controlRequestHandlers = new Map;
|
|
669
|
+
const incomingRequestAborts = new Map;
|
|
669
670
|
async function handleIncomingControlRequest(cf) {
|
|
670
671
|
try {
|
|
671
672
|
const handler = controlRequestHandlers.get(cf.subtype);
|
|
@@ -678,8 +679,12 @@ function query(args) {
|
|
|
678
679
|
});
|
|
679
680
|
return;
|
|
680
681
|
}
|
|
682
|
+
const cancel = new AbortController;
|
|
683
|
+
incomingRequestAborts.set(cf.requestId, cancel);
|
|
681
684
|
try {
|
|
682
|
-
const result = await handler(cf.payload);
|
|
685
|
+
const result = await handler(cf.payload, { signal: cancel.signal });
|
|
686
|
+
if (cancel.signal.aborted)
|
|
687
|
+
return;
|
|
683
688
|
if (result.ok) {
|
|
684
689
|
writeControlResponse({
|
|
685
690
|
type: "control_response",
|
|
@@ -691,19 +696,27 @@ function query(args) {
|
|
|
691
696
|
writeControlResponse({ type: "control_response", requestId: cf.requestId, ok: false, error: result.error });
|
|
692
697
|
}
|
|
693
698
|
} catch (err) {
|
|
699
|
+
if (cancel.signal.aborted)
|
|
700
|
+
return;
|
|
694
701
|
const message = err instanceof Error ? err.message : String(err);
|
|
695
702
|
writeControlResponse({ type: "control_response", requestId: cf.requestId, ok: false, error: { code: "handler_threw", message } });
|
|
703
|
+
} finally {
|
|
704
|
+
incomingRequestAborts.delete(cf.requestId);
|
|
696
705
|
}
|
|
697
706
|
} catch {}
|
|
698
707
|
}
|
|
699
708
|
function makePermissionHandler(canUseTool) {
|
|
700
|
-
return async (payload) => {
|
|
709
|
+
return async (payload, handlerCtx) => {
|
|
701
710
|
const req = payload;
|
|
702
711
|
const controller = new AbortController;
|
|
703
712
|
if (options.abortController?.signal.aborted)
|
|
704
713
|
controller.abort();
|
|
705
714
|
else
|
|
706
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 });
|
|
707
720
|
let result;
|
|
708
721
|
try {
|
|
709
722
|
result = await canUseTool(req.toolName, req.input, {
|
|
@@ -828,6 +841,13 @@ function query(args) {
|
|
|
828
841
|
}
|
|
829
842
|
continue;
|
|
830
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
|
+
}
|
|
831
851
|
if (frame.type === "control_request") {
|
|
832
852
|
handleIncomingControlRequest(frame);
|
|
833
853
|
continue;
|
|
@@ -1001,7 +1021,7 @@ function query(args) {
|
|
|
1001
1021
|
return gen;
|
|
1002
1022
|
}
|
|
1003
1023
|
// src/version.ts
|
|
1004
|
-
var SDK_VERSION = "0.0.
|
|
1024
|
+
var SDK_VERSION = "0.0.20";
|
|
1005
1025
|
// src/paths/project-key.ts
|
|
1006
1026
|
var TRANSCRIPT_PROJECT_KEY_MAX_LENGTH = 64;
|
|
1007
1027
|
var VENDOR_PROJECT_KEY_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
@@ -1044,13 +1064,41 @@ function resolveCanonical(raw) {
|
|
|
1044
1064
|
}
|
|
1045
1065
|
}
|
|
1046
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) {
|
|
1047
1099
|
try {
|
|
1048
|
-
const raw =
|
|
1049
|
-
|
|
1050
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
1051
|
-
}).trim();
|
|
1052
|
-
const commonDir = isAbsolute(raw) ? raw : resolvePath(resolvedCwd, raw);
|
|
1053
|
-
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;
|
|
1054
1102
|
} catch {
|
|
1055
1103
|
return null;
|
|
1056
1104
|
}
|
package/dist/options.d.ts
CHANGED
|
@@ -275,7 +275,9 @@ export interface Options {
|
|
|
275
275
|
autoClassifier?: AutoClassifierConfig;
|
|
276
276
|
/**
|
|
277
277
|
* DISCLOSED WINTER option (P2 carry, wired in T10): the advisor/reviewer backend's model, same
|
|
278
|
-
* 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:
|
|
279
281
|
* a target on another provider than the session's never inherits the session's -- it uses the
|
|
280
282
|
* route's ref, else the target provider's own keychain record (`<providerId>:default`), else a
|
|
281
283
|
* typed `no-credential-for-provider` refusal at its first generation.
|
|
@@ -473,6 +473,18 @@ export interface AutoClassifierConfig {
|
|
|
473
473
|
* advisor's provider, the advisor's provider refuses with a typed `no-credential-for-provider`.
|
|
474
474
|
*/
|
|
475
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
|
+
*/
|
|
476
488
|
model: string;
|
|
477
489
|
authRef?: CredentialRef;
|
|
478
490
|
}
|
|
@@ -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
|
}
|