@deepstrike/wasm 0.2.52 → 0.2.60

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.
Files changed (54) hide show
  1. package/README.md +15 -14
  2. package/dist/agent-ir.d.ts +81 -0
  3. package/dist/agent-ir.js +115 -0
  4. package/dist/agent.d.ts +140 -0
  5. package/dist/agent.js +34 -0
  6. package/dist/governance.d.ts +0 -25
  7. package/dist/governance.js +1 -53
  8. package/dist/index.d.ts +23 -8
  9. package/dist/index.js +11 -4
  10. package/dist/memory/durable.d.ts +13 -0
  11. package/dist/memory/durable.js +42 -0
  12. package/dist/memory/in-memory-store.d.ts +8 -6
  13. package/dist/memory/in-memory-store.js +8 -2
  14. package/dist/memory/index.d.ts +18 -2
  15. package/dist/providers/anthropic.d.ts +9 -0
  16. package/dist/providers/anthropic.js +12 -33
  17. package/dist/providers/content-policy.d.ts +16 -0
  18. package/dist/providers/content-policy.js +39 -0
  19. package/dist/providers/openai.d.ts +36 -17
  20. package/dist/providers/openai.js +86 -46
  21. package/dist/providers/provider-error.d.ts +22 -0
  22. package/dist/providers/provider-error.js +90 -0
  23. package/dist/providers/request-plan.d.ts +87 -0
  24. package/dist/providers/request-plan.js +153 -0
  25. package/dist/providers/stop-reason.d.ts +5 -0
  26. package/dist/providers/stop-reason.js +24 -0
  27. package/dist/runtime/canonical-kernel-step.d.ts +2 -5
  28. package/dist/runtime/canonical-kernel-step.js +40 -58
  29. package/dist/runtime/context-policy.d.ts +10 -12
  30. package/dist/runtime/context-policy.js +6 -8
  31. package/dist/runtime/durable-content.d.ts +44 -0
  32. package/dist/runtime/durable-content.js +119 -0
  33. package/dist/runtime/execution-plane.d.ts +2 -2
  34. package/dist/runtime/execution-plane.js +2 -2
  35. package/dist/runtime/kernel-event-log.js +0 -1
  36. package/dist/runtime/kernel-step.d.ts +1 -2
  37. package/dist/runtime/kernel-step.js +1 -1
  38. package/dist/runtime/provider-replay.d.ts +1 -1
  39. package/dist/runtime/provider-replay.js +12 -20
  40. package/dist/runtime/runner.d.ts +22 -18
  41. package/dist/runtime/runner.js +115 -55
  42. package/dist/runtime/session-log.d.ts +8 -1
  43. package/dist/runtime/session-repair.d.ts +1 -1
  44. package/dist/runtime/session-repair.js +1 -1
  45. package/dist/runtime/sha256.d.ts +2 -0
  46. package/dist/runtime/sha256.js +38 -0
  47. package/dist/runtime/sub-agent-orchestrator.d.ts +1 -1
  48. package/dist/runtime/sub-agent-orchestrator.js +3 -3
  49. package/dist/runtime/types/agent.d.ts +17 -7
  50. package/dist/runtime/types/agent.js +30 -4
  51. package/dist/runtime/workflow-control-flow.d.ts +0 -4
  52. package/dist/runtime/workflow-control-flow.js +0 -16
  53. package/dist/types.d.ts +58 -5
  54. package/package.json +2 -2
@@ -0,0 +1,87 @@
1
+ import type { RenderedContext, ToolSchema } from "../types.js";
2
+ export interface ProviderRequestEndpoint {
3
+ id: string;
4
+ protocol: string;
5
+ baseURL: string;
6
+ }
7
+ export interface ProviderRequestPlan {
8
+ providerId: string;
9
+ modelId: string;
10
+ endpoint: ProviderRequestEndpoint;
11
+ context: RenderedContext;
12
+ tools: ToolSchema[];
13
+ options: Record<string, unknown>;
14
+ fingerprint: string;
15
+ }
16
+ /** Stable, provider-independent fallback used when no native token meter is available. */
17
+ export declare function estimateProviderPromptTokens(context: RenderedContext, tools: ToolSchema[]): number;
18
+ export interface RecordedPromptMeasurement {
19
+ requestFingerprint: string;
20
+ inputTokens: number;
21
+ source: {
22
+ kind: "native";
23
+ provider: string;
24
+ } | {
25
+ kind: "local_exact";
26
+ tokenizer: string;
27
+ } | {
28
+ kind: "heuristic";
29
+ };
30
+ confidence: "exact" | "high_confidence" | "low_confidence";
31
+ }
32
+ export interface ProviderUsage {
33
+ inputTokens: number;
34
+ outputTokens: number;
35
+ cacheReadInputTokens?: number;
36
+ cacheCreationInputTokens?: number;
37
+ reasoningTokens?: number;
38
+ }
39
+ export interface NormalizedProviderUsage extends ProviderUsage {
40
+ uncachedInputTokens: number;
41
+ }
42
+ export interface PricingSnapshot {
43
+ version: string;
44
+ currency: string;
45
+ region: string;
46
+ effectiveFrom: string;
47
+ expiresAt?: string;
48
+ ratesPerMillion: {
49
+ input: number;
50
+ output: number;
51
+ cacheRead?: number;
52
+ cacheCreation?: number;
53
+ reasoning?: number;
54
+ };
55
+ }
56
+ export type CostObservation = {
57
+ source: "snapshot";
58
+ currency: string;
59
+ amount: number;
60
+ pricingVersion: string;
61
+ } | {
62
+ source: "unpriced";
63
+ reason: "pricing_snapshot_not_effective" | "pricing_snapshot_expired" | "invalid_pricing_snapshot";
64
+ };
65
+ export declare function createProviderRequestPlan(input: Omit<ProviderRequestPlan, "fingerprint" | "options"> & {
66
+ options?: Record<string, unknown>;
67
+ }): ProviderRequestPlan;
68
+ export declare function createProviderRequestPlanForProvider(provider: {
69
+ descriptor?(): {
70
+ provider: string;
71
+ protocol: string;
72
+ model: string;
73
+ };
74
+ requestPlanIdentity?(): {
75
+ providerId?: string;
76
+ modelId?: string;
77
+ endpoint?: {
78
+ id?: string;
79
+ protocol?: string;
80
+ baseURL?: string;
81
+ };
82
+ };
83
+ }, context: RenderedContext, tools: ToolSchema[], options?: Record<string, unknown>): ProviderRequestPlan;
84
+ export declare function recordPromptMeasurement(plan: Pick<ProviderRequestPlan, "fingerprint">, measurement: Omit<RecordedPromptMeasurement, "requestFingerprint">): RecordedPromptMeasurement;
85
+ export declare function measurementForPlan(plan: Pick<ProviderRequestPlan, "fingerprint">, record: RecordedPromptMeasurement | undefined): RecordedPromptMeasurement | undefined;
86
+ export declare function normalizeProviderUsage(usage: ProviderUsage): NormalizedProviderUsage;
87
+ export declare function priceProviderUsage(usage: NormalizedProviderUsage, snapshot: PricingSnapshot, observedAt?: string | Date): CostObservation;
@@ -0,0 +1,153 @@
1
+ import { sha256Hex } from "../runtime/sha256.js";
2
+ /** Stable, provider-independent fallback used when no native token meter is available. */
3
+ export function estimateProviderPromptTokens(context, tools) {
4
+ const bytes = new TextEncoder().encode(stableJson({ context, tools })).byteLength;
5
+ return Math.max(1, Math.ceil(bytes / 4));
6
+ }
7
+ const EXCLUDED = new Set(["apiKey", "api_key", "bearerToken", "bearer_token", "authorization", "credential", "credentials", "retry", "maxRetries", "baseDelay", "timeout", "signal"]);
8
+ export function createProviderRequestPlan(input) {
9
+ const value = {
10
+ providerId: input.providerId, modelId: input.modelId, endpoint: sanitizeEndpoint(input.endpoint),
11
+ context: clone(input.context), tools: clone(input.tools), options: materialOptions(input.options ?? {}),
12
+ };
13
+ return { ...value, fingerprint: sha256Hex(stableJson(value)) };
14
+ }
15
+ export function createProviderRequestPlanForProvider(provider, context, tools, options) {
16
+ const descriptor = provider.descriptor?.() ?? { provider: "unknown", protocol: "unknown", model: "unknown" };
17
+ const identity = provider.requestPlanIdentity?.();
18
+ return createProviderRequestPlan({
19
+ providerId: identity?.providerId ?? descriptor.provider,
20
+ modelId: identity?.modelId ?? descriptor.model,
21
+ endpoint: {
22
+ id: identity?.endpoint?.id ?? `${descriptor.provider}.${descriptor.protocol}`,
23
+ protocol: identity?.endpoint?.protocol ?? descriptor.protocol,
24
+ baseURL: identity?.endpoint?.baseURL ?? "",
25
+ },
26
+ context, tools, options,
27
+ });
28
+ }
29
+ export function recordPromptMeasurement(plan, measurement) {
30
+ if (!Number.isSafeInteger(measurement.inputTokens) || measurement.inputTokens < 0)
31
+ throw new RangeError("inputTokens must be a non-negative safe integer");
32
+ return { requestFingerprint: plan.fingerprint, inputTokens: measurement.inputTokens, source: clone(measurement.source), confidence: measurement.confidence };
33
+ }
34
+ export function measurementForPlan(plan, record) {
35
+ if (!record || record.requestFingerprint !== plan.fingerprint)
36
+ return undefined;
37
+ if (!Number.isSafeInteger(record.inputTokens) || record.inputTokens < 0)
38
+ return undefined;
39
+ if (record.confidence !== "exact" && record.confidence !== "high_confidence" && record.confidence !== "low_confidence")
40
+ return undefined;
41
+ if (!record.source || typeof record.source !== "object")
42
+ return undefined;
43
+ if (record.source.kind === "native" && typeof record.source.provider === "string" && record.source.provider.length > 0)
44
+ return clone(record);
45
+ if (record.source.kind === "local_exact" && typeof record.source.tokenizer === "string" && record.source.tokenizer.length > 0)
46
+ return clone(record);
47
+ if (record.source.kind === "heuristic")
48
+ return clone(record);
49
+ return undefined;
50
+ }
51
+ export function normalizeProviderUsage(usage) {
52
+ const inputTokens = nonNegativeInteger(usage.inputTokens, "inputTokens");
53
+ const outputTokens = nonNegativeInteger(usage.outputTokens, "outputTokens");
54
+ const cacheReadInputTokens = optionalNonNegativeInteger(usage.cacheReadInputTokens, "cacheReadInputTokens");
55
+ const cacheCreationInputTokens = optionalNonNegativeInteger(usage.cacheCreationInputTokens, "cacheCreationInputTokens");
56
+ const reasoningTokens = optionalNonNegativeInteger(usage.reasoningTokens, "reasoningTokens");
57
+ const cached = (cacheReadInputTokens ?? 0) + (cacheCreationInputTokens ?? 0);
58
+ if (cached > inputTokens)
59
+ throw new RangeError("cache token subsets cannot exceed inputTokens");
60
+ if (reasoningTokens !== undefined && reasoningTokens > outputTokens)
61
+ throw new RangeError("reasoningTokens must be a subset of outputTokens");
62
+ return {
63
+ inputTokens,
64
+ uncachedInputTokens: inputTokens - cached,
65
+ outputTokens,
66
+ ...(cacheReadInputTokens !== undefined ? { cacheReadInputTokens } : {}),
67
+ ...(cacheCreationInputTokens !== undefined ? { cacheCreationInputTokens } : {}),
68
+ ...(reasoningTokens !== undefined ? { reasoningTokens } : {}),
69
+ };
70
+ }
71
+ export function priceProviderUsage(usage, snapshot, observedAt = new Date()) {
72
+ const at = typeof observedAt === "string" ? new Date(observedAt) : observedAt;
73
+ const from = new Date(snapshot.effectiveFrom);
74
+ const expires = snapshot.expiresAt ? new Date(snapshot.expiresAt) : undefined;
75
+ const rates = snapshot.ratesPerMillion;
76
+ const requiredRates = [rates.input, rates.output];
77
+ if (!snapshot.version || !snapshot.currency || Number.isNaN(at.valueOf()) || Number.isNaN(from.valueOf())
78
+ || requiredRates.some(rate => typeof rate !== "number" || !Number.isFinite(rate) || rate < 0)
79
+ || Object.values(rates).some(rate => typeof rate !== "number" || !Number.isFinite(rate) || rate < 0)) {
80
+ return { source: "unpriced", reason: "invalid_pricing_snapshot" };
81
+ }
82
+ if (at < from)
83
+ return { source: "unpriced", reason: "pricing_snapshot_not_effective" };
84
+ if (expires && (Number.isNaN(expires.valueOf()) || at >= expires))
85
+ return { source: "unpriced", reason: "pricing_snapshot_expired" };
86
+ const amount = (usage.uncachedInputTokens * rates.input
87
+ + usage.outputTokens * rates.output
88
+ + (usage.cacheReadInputTokens ?? 0) * (rates.cacheRead ?? rates.input)
89
+ + (usage.cacheCreationInputTokens ?? 0) * (rates.cacheCreation ?? rates.input)
90
+ + (usage.reasoningTokens ?? 0) * (rates.reasoning ?? 0)) / 1_000_000;
91
+ return { source: "snapshot", currency: snapshot.currency, amount, pricingVersion: snapshot.version };
92
+ }
93
+ function materialOptions(options) {
94
+ return sanitizeMaterialValue(options);
95
+ }
96
+ function sanitizeEndpoint(endpoint) {
97
+ try {
98
+ const url = new URL(endpoint.baseURL);
99
+ url.username = "";
100
+ url.password = "";
101
+ url.search = "";
102
+ url.hash = "";
103
+ return { ...clone(endpoint), baseURL: url.toString().replace(/\/$/, "") };
104
+ }
105
+ catch {
106
+ return { ...clone(endpoint), baseURL: "" };
107
+ }
108
+ }
109
+ function sanitizeMaterialValue(value) {
110
+ if (value === undefined || typeof value === "function")
111
+ return undefined;
112
+ if (Array.isArray(value))
113
+ return value.map(sanitizeMaterialValue).filter(item => item !== undefined);
114
+ if (value !== null && typeof value === "object") {
115
+ return Object.fromEntries(Object.keys(value).sort().flatMap(key => {
116
+ if (EXCLUDED.has(key) || isTransportOnlyKey(key))
117
+ return [];
118
+ const sanitized = sanitizeMaterialValue(value[key]);
119
+ return sanitized === undefined ? [] : [[key, sanitized]];
120
+ }));
121
+ }
122
+ return value;
123
+ }
124
+ function isTransportOnlyKey(key) {
125
+ const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
126
+ return normalized.includes("authorization") || normalized.includes("credential")
127
+ || normalized.includes("accesstoken") || normalized.includes("refreshtoken")
128
+ || normalized.includes("apikey") || normalized === "bearer" || normalized === "token"
129
+ || normalized === "secret" || normalized === "xapikey";
130
+ }
131
+ function stableJson(value) {
132
+ if (value === null || typeof value !== "object")
133
+ return JSON.stringify(value);
134
+ if (Array.isArray(value))
135
+ return `[${value.map(stableJson).join(",")}]`;
136
+ const object = value;
137
+ return `{${Object.keys(object).sort().map(key => `${JSON.stringify(key)}:${stableJson(object[key])}`).join(",")}}`;
138
+ }
139
+ function clone(value) {
140
+ if (value === undefined || value === null || typeof value !== "object")
141
+ return value;
142
+ if (Array.isArray(value))
143
+ return value.map(clone);
144
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, clone(item)]));
145
+ }
146
+ function nonNegativeInteger(value, name) {
147
+ if (!Number.isSafeInteger(value) || value < 0)
148
+ throw new RangeError(`${name} must be a non-negative safe integer`);
149
+ return value;
150
+ }
151
+ function optionalNonNegativeInteger(value, name) {
152
+ return value === undefined ? undefined : nonNegativeInteger(value, name);
153
+ }
@@ -0,0 +1,5 @@
1
+ export type CanonicalStopReason = "end_turn" | "tool_use" | "max_tokens" | "stop_sequence" | "content_filter" | "other";
2
+ /** Validates the closed, provider-normalized stop-reason contract. */
3
+ export declare function decodeCanonicalStopReason(value: unknown): CanonicalStopReason;
4
+ /** Normalize an open-ended provider value into the closed runtime contract. */
5
+ export declare function normalizeProviderStopReason(value: unknown): CanonicalStopReason;
@@ -0,0 +1,24 @@
1
+ const KNOWN = new Set([
2
+ "end_turn",
3
+ "tool_use",
4
+ "max_tokens",
5
+ "stop_sequence",
6
+ "content_filter",
7
+ "other",
8
+ ]);
9
+ /** Validates the closed, provider-normalized stop-reason contract. */
10
+ export function decodeCanonicalStopReason(value) {
11
+ if (typeof value !== "string" || !KNOWN.has(value)) {
12
+ throw new RangeError(`unknown canonical stop reason: ${String(value)}`);
13
+ }
14
+ return value;
15
+ }
16
+ /** Normalize an open-ended provider value into the closed runtime contract. */
17
+ export function normalizeProviderStopReason(value) {
18
+ if (typeof value !== "string" || value.length === 0) {
19
+ throw new RangeError(`invalid provider stop reason: ${String(value)}`);
20
+ }
21
+ return KNOWN.has(value)
22
+ ? value
23
+ : "other";
24
+ }
@@ -94,13 +94,9 @@ export interface CanonicalRunnerRuntimeOptions {
94
94
  }>;
95
95
  }
96
96
  export declare function sha256(value: string): string;
97
- /** Small synchronous SHA-256 for Worker/browser hosts (no node:crypto). */
98
- declare function syncSha256(value: string): string;
99
- export { syncSha256 as sha256Hex };
100
97
  /**
101
98
  * Canonical operation runtime used by the WASM host.
102
- * Every durable transition below is one of the canonical ABI's five input classes; no legacy
103
- * envelope or synthesized host transaction reaches core or storage.
99
+ * Every durable transition below is one of the canonical contract's five input classes.
104
100
  */
105
101
  export declare class CanonicalRunnerRuntime {
106
102
  private readonly options;
@@ -153,3 +149,4 @@ export declare function canonicalKernelAction(runtime: CanonicalRunnerRuntime, p
153
149
  export declare function canonicalStartAgent(runtime: CanonicalRunnerRuntime, pending: KernelObservationLike[], task: Record<string, unknown>, runSpec?: Record<string, unknown>): Promise<KernelRunnerAction>;
154
150
  export declare function canonicalStartWorkflow(runtime: CanonicalRunnerRuntime, pending: KernelObservationLike[], spec: Record<string, unknown>): Promise<KernelRunnerAction | null>;
155
151
  type KernelObservationLike = KernelObservation;
152
+ export {};
@@ -1,4 +1,5 @@
1
- import { kernelAbiVersion } from "@deepstrike/wasm-kernel";
1
+ import { normalizeProviderStopReason } from "../providers/stop-reason.js";
2
+ import { sha256Hex } from "./sha256.js";
2
3
  import { JournalCasConflictError, MAX_CHAIN_POSITION as JOURNAL_MAX_CHAIN_POSITION, } from "./kernel-journal.js";
3
4
  import { encodeCanonicalContentParts, kernelMessageToSdk, renderedContextToSdk, } from "./kernel-step.js";
4
5
  export const MAX_CHAIN_POSITION = JOURNAL_MAX_CHAIN_POSITION;
@@ -343,7 +344,6 @@ export class CanonicalKernelHost {
343
344
  }
344
345
  async transition(input, options = {}) {
345
346
  const inputJson = JSON.stringify({
346
- abi_version: kernelAbiVersion(),
347
347
  operation_id: this.operationId,
348
348
  input_id: options.inputId ?? `wasm-input-${crypto.randomUUID()}`,
349
349
  observed_at_ms: options.observedAtMs ?? String(Date.now()),
@@ -591,7 +591,7 @@ function logicalRunSpec(raw, goal) {
591
591
  ...(raw.metadata && typeof raw.metadata === "object" ? { metadata: raw.metadata } : {}),
592
592
  };
593
593
  }
594
- function canonicalWorkflowSpec(raw) {
594
+ function canonicalWorkflowSpec(raw, allowHostSchedulingFactors = false) {
595
595
  const nodes = Array.isArray(raw.nodes) ? raw.nodes.map(asObject) : [];
596
596
  const nodeIds = nodes.map((_node, index) => `wf-node${index}`);
597
597
  return {
@@ -614,6 +614,9 @@ function canonicalWorkflowSpec(raw) {
614
614
  unsupported.push("max_turns");
615
615
  if (node.max_wall_ms !== undefined || node.maxWallMs !== undefined)
616
616
  unsupported.push("max_wall_ms");
617
+ const schedulingFactors = node.scheduling_factors ?? node.schedulingFactors;
618
+ if (schedulingFactors !== undefined && !allowHostSchedulingFactors)
619
+ unsupported.push("scheduling_factors");
617
620
  const inheritance = node.context_inheritance ?? node.contextInheritance;
618
621
  if (unsupported.length > 0) {
619
622
  throw new CanonicalKernelRejectedError(JSON.stringify({
@@ -634,16 +637,20 @@ function canonicalWorkflowSpec(raw) {
634
637
  : [];
635
638
  const modelHint = node.model_hint ?? node.modelHint;
636
639
  const outputSchema = node.output_schema ?? node.outputSchema;
640
+ const canonicalSchedulingFactors = schedulingFactors === undefined
641
+ ? undefined
642
+ : canonicalSchedulingFactorsForHost(schedulingFactors);
637
643
  const runSpec = logicalRunSpec({
638
644
  goal,
639
645
  ...(node.role ? { role: node.role } : {}),
640
646
  ...(node.isolation ? { isolation: node.isolation } : {}),
641
647
  ...(inheritance ? { context_inheritance: inheritance } : {}),
642
- ...((modelHint !== undefined || outputSchema !== undefined)
648
+ ...((modelHint !== undefined || outputSchema !== undefined || canonicalSchedulingFactors !== undefined)
643
649
  ? {
644
650
  metadata: {
645
651
  ...(modelHint !== undefined ? { model_hint: modelHint } : {}),
646
652
  ...(outputSchema !== undefined ? { output_schema: outputSchema } : {}),
653
+ ...(canonicalSchedulingFactors !== undefined ? { scheduling_factors: canonicalSchedulingFactors } : {}),
647
654
  },
648
655
  }
649
656
  : {}),
@@ -661,62 +668,35 @@ function canonicalWorkflowSpec(raw) {
661
668
  }),
662
669
  };
663
670
  }
664
- export function sha256(value) {
665
- return syncSha256(value);
666
- }
667
- /** Small synchronous SHA-256 for Worker/browser hosts (no node:crypto). */
668
- function syncSha256(value) {
669
- const encoder = new TextEncoder();
670
- const input = encoder.encode(value);
671
- const bitLength = input.length * 8;
672
- const length = ((input.length + 9 + 63) >> 6) << 6;
673
- const data = new Uint8Array(length);
674
- data.set(input);
675
- data[input.length] = 0x80;
676
- new DataView(data.buffer).setUint32(length - 4, bitLength >>> 0, false);
677
- const h = new Uint32Array([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]);
678
- const k = [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
679
- const ror = (x, n) => (x >>> n) | (x << (32 - n));
680
- for (let offset = 0; offset < data.length; offset += 64) {
681
- const w = new Uint32Array(64);
682
- const view = new DataView(data.buffer, offset, 64);
683
- for (let i = 0; i < 16; i++)
684
- w[i] = view.getUint32(i * 4, false);
685
- for (let i = 16; i < 64; i++) {
686
- w[i] = (w[i - 16] + (ror(w[i - 15], 7) ^ ror(w[i - 15], 18) ^ (w[i - 15] >>> 3)) + w[i - 7] + (ror(w[i - 2], 17) ^ ror(w[i - 2], 19) ^ (w[i - 2] >>> 10))) >>> 0;
671
+ function canonicalSchedulingFactorsForHost(value) {
672
+ const raw = asObject(value);
673
+ const allowed = new Set(["deadline_urgency", "process_priority", "resource_pressure", "budget_pressure"]);
674
+ const unknown = Object.keys(raw).filter(key => !allowed.has(key));
675
+ if (unknown.length > 0)
676
+ throw new TypeError(`unknown scheduling factor(s): ${unknown.join(", ")}`);
677
+ const factors = {};
678
+ for (const key of allowed) {
679
+ const factor = raw[key];
680
+ if (factor === undefined)
681
+ continue;
682
+ if (!Number.isSafeInteger(factor) || factor < 0) {
683
+ throw new RangeError(`scheduling_factors.${key} must be a non-negative safe integer`);
687
684
  }
688
- let [a, b, c, d, e, f, g, hh] = h;
689
- for (let i = 0; i < 64; i++) {
690
- const t1 = (hh + (ror(e, 6) ^ ror(e, 11) ^ ror(e, 25)) + ((e & f) ^ ((~e) & g)) + k[i] + w[i]) >>> 0;
691
- const t2 = ((ror(a, 2) ^ ror(a, 13) ^ ror(a, 22)) + ((a & b) ^ (a & c) ^ (b & c))) >>> 0;
692
- hh = g;
693
- g = f;
694
- f = e;
695
- e = (d + t1) >>> 0;
696
- d = c;
697
- c = b;
698
- b = a;
699
- a = (t1 + t2) >>> 0;
700
- }
701
- for (let i = 0; i < 8; i++)
702
- h[i] = (h[i] + [a, b, c, d, e, f, g, hh][i]) >>> 0;
685
+ factors[key] = factor;
703
686
  }
704
- return `sha256:${Array.from(h, word => word.toString(16).padStart(8, "0")).join("")}`;
687
+ return factors;
688
+ }
689
+ export function sha256(value) {
690
+ return sha256Hex(value);
705
691
  }
706
- export { syncSha256 as sha256Hex };
707
692
  function providerStopReason(value) {
708
- if (typeof value !== "string" || value.length === 0)
693
+ if (value === undefined || value === null || value === "")
709
694
  return undefined;
710
- const normalized = value.toLowerCase();
711
- if (["end_turn", "tool_use", "max_tokens", "stop_sequence", "content_filter"].includes(normalized)) {
712
- return normalized;
713
- }
714
- return "other";
695
+ return normalizeProviderStopReason(value);
715
696
  }
716
697
  /**
717
698
  * Canonical operation runtime used by the WASM host.
718
- * Every durable transition below is one of the canonical ABI's five input classes; no legacy
719
- * envelope or synthesized host transaction reaches core or storage.
699
+ * Every durable transition below is one of the canonical contract's five input classes.
720
700
  */
721
701
  export class CanonicalRunnerRuntime {
722
702
  options;
@@ -842,7 +822,7 @@ export class CanonicalRunnerRuntime {
842
822
  kind: "start_operation",
843
823
  entry: {
844
824
  kind: "workflow",
845
- spec: canonicalWorkflowSpec(specValue),
825
+ spec: canonicalWorkflowSpec(specValue, true),
846
826
  },
847
827
  initial_context: this.initialContext,
848
828
  });
@@ -896,7 +876,8 @@ export class CanonicalRunnerRuntime {
896
876
  }
897
877
  case "provider_error": {
898
878
  const message = String(event.message ?? "");
899
- const contextOverflow = /context|token.*limit|too long/i.test(message);
879
+ const errorKind = typeof event.error_kind === "string" ? event.error_kind : "unknown";
880
+ const contextOverflow = errorKind === "context_overflow";
900
881
  input = contextOverflow
901
882
  ? {
902
883
  kind: "resolve_effect",
@@ -906,7 +887,11 @@ export class CanonicalRunnerRuntime {
906
887
  result: { kind: "provider", outcome: { kind: "context_overflow" } },
907
888
  },
908
889
  }
909
- : this.failedEffect(event, "transport_exhausted", message, true);
890
+ : this.failedEffect(event, ["transport", "rate_limit", "model_unavailable"].includes(errorKind)
891
+ ? "transport_exhausted"
892
+ : ["auth", "invalid_request", "modality", "protocol"].includes(errorKind)
893
+ ? "protocol_error"
894
+ : "unknown", message, typeof event.retryable === "boolean" ? event.retryable : false);
910
895
  break;
911
896
  }
912
897
  case "tool_results": {
@@ -1465,9 +1450,6 @@ export class CanonicalRunnerRuntime {
1465
1450
  delete asObject(execution.entropy_watch).threshold;
1466
1451
  delete asObject(execution.entropy_watch).hysteresis;
1467
1452
  }
1468
- if (config.tool_dispatch_gate !== undefined) {
1469
- this.featurePolicy().tool_dispatch_gate = config.tool_dispatch_gate;
1470
- }
1471
1453
  if (config.knowledge_budget_ratio !== undefined) {
1472
1454
  const context = asObject(this.config.context_policy);
1473
1455
  context.knowledge_budget_ppm = Math.round(Number(config.knowledge_budget_ratio) * 1_000_000);
@@ -1,35 +1,33 @@
1
- export declare const CONTEXT_POLICY_VERSION: 1;
2
1
  export declare const PPM_SCALE: 1000000;
3
- export interface ContextPressureThresholdsV1 {
2
+ export interface ContextPressureThresholds {
4
3
  snip: number;
5
4
  micro: number;
6
5
  collapse: number;
7
6
  auto: number;
8
7
  renewal: number;
9
8
  }
10
- export interface ContextPolicyV1 {
11
- pressureThresholds: ContextPressureThresholdsV1;
9
+ export interface ContextPolicy {
10
+ pressureThresholds: ContextPressureThresholds;
12
11
  targetAfterCompress: number;
13
12
  preserveRecentTurns: number;
14
13
  renewalCarryover: number;
15
14
  collapseOldAssistantNarration: boolean;
16
15
  idleMicroCompactMinutes: number;
17
16
  }
18
- export interface ContextPolicyWireV1 {
19
- version: typeof CONTEXT_POLICY_VERSION;
20
- pressure_thresholds_ppm: ContextPressureThresholdsV1;
17
+ export interface ContextPolicyWire {
18
+ pressure_thresholds_ppm: ContextPressureThresholds;
21
19
  target_after_compress_ppm: number;
22
20
  preserve_recent_turns: number;
23
21
  renewal_carryover_ppm: number;
24
22
  collapse_old_assistant_narration: boolean;
25
23
  idle_micro_compact_minutes: number;
26
24
  }
27
- export interface ContextPolicyOverridesV1 extends Partial<Omit<ContextPolicyV1, "pressureThresholds">> {
28
- pressureThresholds?: Partial<ContextPressureThresholdsV1>;
25
+ export interface ContextPolicyOverrides extends Partial<Omit<ContextPolicy, "pressureThresholds">> {
26
+ pressureThresholds?: Partial<ContextPressureThresholds>;
29
27
  }
30
- export declare const DEFAULT_CONTEXT_POLICY_V1: Readonly<ContextPolicyV1>;
28
+ export declare const DEFAULT_CONTEXT_POLICY: Readonly<ContextPolicy>;
31
29
  /** Resolve ergonomic partial SDK options into one complete, atomically validated policy. */
32
- export declare function contextPolicyV1(overrides?: ContextPolicyOverridesV1): ContextPolicyV1;
30
+ export declare function contextPolicy(overrides?: ContextPolicyOverrides): ContextPolicy;
33
31
  /** Convert the public ratio-based policy to the canonical integer-only ABI wire shape. */
34
- export declare function normalizeContextPolicyV1(policy: ContextPolicyV1): ContextPolicyWireV1;
32
+ export declare function normalizeContextPolicy(policy: ContextPolicy): ContextPolicyWire;
35
33
  export declare function ratioToPpm(value: number, field?: string): number;
@@ -1,6 +1,5 @@
1
- export const CONTEXT_POLICY_VERSION = 1;
2
1
  export const PPM_SCALE = 1_000_000;
3
- export const DEFAULT_CONTEXT_POLICY_V1 = Object.freeze({
2
+ export const DEFAULT_CONTEXT_POLICY = Object.freeze({
4
3
  pressureThresholds: Object.freeze({ snip: 0.70, micro: 0.80, collapse: 0.90, auto: 0.95, renewal: 0.98 }),
5
4
  targetAfterCompress: 0.65,
6
5
  preserveRecentTurns: 2,
@@ -9,20 +8,20 @@ export const DEFAULT_CONTEXT_POLICY_V1 = Object.freeze({
9
8
  idleMicroCompactMinutes: 60,
10
9
  });
11
10
  /** Resolve ergonomic partial SDK options into one complete, atomically validated policy. */
12
- export function contextPolicyV1(overrides = {}) {
11
+ export function contextPolicy(overrides = {}) {
13
12
  const policy = {
14
- ...DEFAULT_CONTEXT_POLICY_V1,
13
+ ...DEFAULT_CONTEXT_POLICY,
15
14
  ...overrides,
16
15
  pressureThresholds: {
17
- ...DEFAULT_CONTEXT_POLICY_V1.pressureThresholds,
16
+ ...DEFAULT_CONTEXT_POLICY.pressureThresholds,
18
17
  ...overrides.pressureThresholds,
19
18
  },
20
19
  };
21
- normalizeContextPolicyV1(policy);
20
+ normalizeContextPolicy(policy);
22
21
  return policy;
23
22
  }
24
23
  /** Convert the public ratio-based policy to the canonical integer-only ABI wire shape. */
25
- export function normalizeContextPolicyV1(policy) {
24
+ export function normalizeContextPolicy(policy) {
26
25
  const pressure_thresholds_ppm = {
27
26
  snip: ratioToPpm(policy.pressureThresholds.snip, "pressureThresholds.snip"),
28
27
  micro: ratioToPpm(policy.pressureThresholds.micro, "pressureThresholds.micro"),
@@ -44,7 +43,6 @@ export function normalizeContextPolicyV1(policy) {
44
43
  throw new TypeError("collapseOldAssistantNarration must be boolean");
45
44
  }
46
45
  return {
47
- version: CONTEXT_POLICY_VERSION,
48
46
  pressure_thresholds_ppm,
49
47
  target_after_compress_ppm,
50
48
  preserve_recent_turns: policy.preserveRecentTurns,
@@ -0,0 +1,44 @@
1
+ export declare class DurableContentError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export type DurableSource = {
5
+ kind: "url";
6
+ url: string;
7
+ } | {
8
+ kind: "base64";
9
+ data: string;
10
+ } | {
11
+ kind: "file_id";
12
+ id: string;
13
+ affinity: {
14
+ provider_id: string;
15
+ endpoint_id: string;
16
+ };
17
+ } | {
18
+ kind: "object";
19
+ handle: string;
20
+ owner: string;
21
+ payload_ref: string;
22
+ };
23
+ export type DurableContentBlock = {
24
+ type: "text";
25
+ text: string;
26
+ } | {
27
+ type: "image" | "audio" | "video" | "file";
28
+ source: DurableSource;
29
+ media_type?: string;
30
+ provider_options?: Record<string, unknown>;
31
+ };
32
+ export interface DurableContent {
33
+ blocks: DurableContentBlock[];
34
+ }
35
+ export interface DurableToolResult extends DurableContent {
36
+ call_id: string;
37
+ is_error: boolean;
38
+ }
39
+ export declare function decodeDurableContent(value: unknown): DurableContent;
40
+ export declare function decodeDurableToolResult(value: unknown): DurableToolResult;
41
+ export declare function encodeDurableContent(content: DurableContent): Record<string, unknown>;
42
+ export declare function encodeDurableToolResult(result: DurableToolResult): Record<string, unknown>;
43
+ export declare function toolOutputBlocksToDurable(blocks: readonly import("../types.js").ToolOutputBlock[]): DurableContentBlock[];
44
+ export declare function durableBlocksToToolOutput(blocks: readonly DurableContentBlock[]): import("../types.js").ToolOutputBlock[];