nanocodex 0.6.6 → 0.6.7
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 +297 -6
- package/THIRD-PARTY-LICENSES +23 -0
- package/browser/Agent.d.mts +5 -4
- package/browser/Agent.mjs +4 -0
- package/browser/Claude.d.mts +4 -0
- package/browser/Claude.mjs +11 -0
- package/browser/InlineAgent.mjs +19 -1
- package/browser/host.d.mts +54 -1
- package/browser/host.mjs +65 -16
- package/browser/hostManagedWebSocket.mjs +11 -2
- package/browser/index.d.mts +3 -10
- package/browser/index.mjs +2 -5
- package/browser/socket-observations.mjs +203 -0
- package/cloud/Decorator.d.mts +2 -2
- package/cloud/Decorator.mjs +1 -0
- package/cloud/Dialog.d.mts +13 -0
- package/cloud/Dialog.mjs +52 -6
- package/cloud/Transport.d.mts +0 -11
- package/cloud/Transport.mjs +1 -386
- package/cloud/actions/account.d.mts +12 -0
- package/cloud/actions/account.mjs +11 -0
- package/cloud/actions/agent.mjs +3 -0
- package/cloud/actions/connection.d.mts +3 -1
- package/cloud/actions/connection.mjs +19 -4
- package/cloud/index.d.mts +1 -1
- package/cloud/index.mjs +1 -1
- package/cloud/internal.mjs +19 -4
- package/cloud/mercator.mjs +1 -1
- package/cloud/mock.d.mts +17 -0
- package/cloud/mock.mjs +392 -0
- package/cloud/types.d.mts +3 -1
- package/cloudflare/Agent.d.mts +2 -0
- package/cloudflare/Agent.mjs +88 -2
- package/cloudflare/agent-settings.d.mts +1 -1
- package/cloudflare/agent-settings.mjs +9 -0
- package/cloudflare/egress.mjs +9 -6
- package/cloudflare/gateway-responses.d.mts +1 -0
- package/cloudflare/gateway-responses.mjs +2 -2
- package/cloudflare/managed-auth.d.mts +4 -4
- package/cloudflare/managed-auth.mjs +14 -2
- package/cloudflare/managed-live.d.mts +6 -0
- package/cloudflare/managed-live.mjs +56 -1
- package/cloudflare/workers-ai-responses.d.mts +2 -1
- package/cloudflare/workers-ai-responses.mjs +80 -6
- package/host/Agent.d.mts +6 -2
- package/host/Claude.d.mts +3 -0
- package/host/Claude.mjs +2 -0
- package/host/index.d.mts +6 -10
- package/host/index.mjs +2 -5
- package/index.d.mts +11 -10
- package/index.mjs +0 -5
- package/internal.mjs +28 -3
- package/managed/Agent.d.mts +6 -2
- package/managed/Agent.mjs +39 -5
- package/managed/ManagedError.d.mts +3 -0
- package/node/Agent.d.mts +6 -2
- package/node/Agent.mjs +14 -1
- package/node/Claude.d.mts +4 -0
- package/node/Claude.mjs +24 -0
- package/node/host.mjs +18 -9
- package/node/index.d.mts +6 -10
- package/node/index.mjs +2 -5
- package/package.json +41 -9
- package/pkg-node/nanocodex.d.ts +109 -0
- package/pkg-node/nanocodex.js +818 -51
- package/pkg-node/nanocodex_bg.wasm.d.ts +47 -3
- package/pkg-web/.nanocodex-bindgen-stamp +3 -3
- package/pkg-web/nanocodex-build.json +1 -1
- package/pkg-web/nanocodex.d.ts +156 -3
- package/pkg-web/nanocodex.js +813 -51
- package/pkg-web/nanocodex_bg.js +813 -51
- package/pkg-web/nanocodex_bg.wasm +0 -0
- package/pkg-web/nanocodex_bg.wasm.d.ts +47 -3
- package/pkg-web/nanocodex_worker.js +1 -1
- package/runtime/claude-host.mjs +308 -0
- package/runtime/claude-subscription.mjs +79 -0
- package/runtime/claude.d.mts +112 -0
- package/runtime/claude.mjs +221 -0
- package/runtime/code-effect-identity.mjs +123 -0
- package/runtime/harnesses.mjs +51 -0
- package/runtime/mcp-payment.mjs +8 -0
- package/runtime/mcp-runtime.d.mts +10 -0
- package/runtime/mcp-runtime.mjs +242 -57
- package/runtime/mercator.mjs +2 -0
- package/runtime/quickjs-evaluator.mjs +23 -11
- package/runtime/response-controls.mjs +1 -6
- package/runtime/responses-http.mjs +4 -2
- package/runtime/retry-after.d.mts +10 -0
- package/runtime/retry-after.mjs +86 -0
- package/runtime/steer-receipt.mjs +8 -1
- package/runtime/subagent-routing.d.mts +4 -2
- package/runtime/subagent-routing.mjs +7 -2
- package/runtime/subagents.d.mts +8 -3
- package/services/account.d.mts +76 -0
- package/services/account.mjs +151 -0
- package/services/hosted.mjs +72 -0
- package/services/index.d.mts +95 -0
- package/services/index.mjs +192 -0
- package/services/scope.mjs +36 -0
- package/{runtime/tempo-provider.d.mts → tempo/index.d.mts} +20 -1
- package/{runtime/tempo-provider.mjs → tempo/index.mjs} +39 -3
- package/tools/browser/browserShell.mjs +18 -8
- package/tools/browser/python.worker.mjs +17 -1
- package/tools/browser/threadGit.mjs +12 -2
- package/tools/environment.d.mts +8 -0
- package/tools/environment.mjs +10 -0
- package/tools/index.d.mts +6 -3
- package/types.d.mts +104 -4
- package/worker/Claude.d.mts +4 -0
- package/worker/Claude.mjs +11 -0
- package/worker/ClaudeSubscription.d.mts +24 -0
- package/worker/ClaudeSubscription.mjs +9 -0
- package/worker/index.d.mts +9 -0
- package/worker/index.mjs +4 -0
package/host/index.mjs
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
export * as Actions from "../actions/index.mjs";
|
|
2
2
|
export { createQuickJsEvaluator } from "../runtime/quickjs-evaluator.mjs";
|
|
3
|
-
export {
|
|
4
|
-
createTempoProvider,
|
|
5
|
-
createTempoProviderFromAccounts,
|
|
6
|
-
DEFAULT_MERCATOR_MCP_URL,
|
|
7
|
-
} from "../runtime/tempo-provider.mjs";
|
|
8
3
|
export * as Agent from "./Agent.mjs";
|
|
9
4
|
export * as Subagents from "../runtime/subagents.mjs";
|
|
10
5
|
export * as Transport from "../browser/Transport.mjs";
|
|
6
|
+
|
|
7
|
+
export * as Claude from "./Claude.mjs";
|
package/index.d.mts
CHANGED
|
@@ -8,16 +8,6 @@ export { createTools } from "./tools/Tools.mjs";
|
|
|
8
8
|
export type { Tools, AttachmentClient, AttachmentTarget, AttachmentTransport } from "./tools/Tools.mjs";
|
|
9
9
|
export type { HostedMachine } from "./tools/hostedCatalog.mjs";
|
|
10
10
|
export type { AsyncQuickJsModule, QuickJsEvaluatorOptions } from "./runtime/quickjs-evaluator.mjs";
|
|
11
|
-
export {
|
|
12
|
-
createTempoProvider,
|
|
13
|
-
createTempoProviderFromAccounts,
|
|
14
|
-
DEFAULT_MERCATOR_MCP_URL,
|
|
15
|
-
} from "./runtime/tempo-provider.mjs";
|
|
16
|
-
export type {
|
|
17
|
-
AccountsTempoProviderOptions,
|
|
18
|
-
AccountsWallet,
|
|
19
|
-
TempoProvider,
|
|
20
|
-
} from "./runtime/tempo-provider.mjs";
|
|
21
11
|
export type {
|
|
22
12
|
Agent,
|
|
23
13
|
AgentActions,
|
|
@@ -35,6 +25,9 @@ export type {
|
|
|
35
25
|
ChatGptSubscriptionStore,
|
|
36
26
|
CostStatus,
|
|
37
27
|
CodeEvaluator,
|
|
28
|
+
CodeEffectContext,
|
|
29
|
+
CodeEffectReceipt,
|
|
30
|
+
CodeEffectJournal,
|
|
38
31
|
CodeEvaluatorEnvironment,
|
|
39
32
|
DefaultAgent,
|
|
40
33
|
EventWatcher,
|
|
@@ -43,6 +36,8 @@ export type {
|
|
|
43
36
|
ForkOptions,
|
|
44
37
|
McpClient,
|
|
45
38
|
McpPayment,
|
|
39
|
+
PaidMcpPayment,
|
|
40
|
+
McpPrivateResultPolicy,
|
|
46
41
|
McpServer,
|
|
47
42
|
McpServers,
|
|
48
43
|
McpTool,
|
|
@@ -70,3 +65,9 @@ export type {
|
|
|
70
65
|
TurnUsage,
|
|
71
66
|
WatchEventsOptions,
|
|
72
67
|
} from "./types.mjs";
|
|
68
|
+
|
|
69
|
+
export type {
|
|
70
|
+
Options as ClaudeSubscriptionOptions,
|
|
71
|
+
Subscription as ClaudeSubscriptionHandle,
|
|
72
|
+
Status as ClaudeSubscriptionStatus,
|
|
73
|
+
} from "./worker/ClaudeSubscription.mjs";
|
package/index.mjs
CHANGED
|
@@ -5,8 +5,3 @@ export {
|
|
|
5
5
|
} from "./runtime/subscription-store.mjs";
|
|
6
6
|
export { createQuickJsEvaluator } from "./runtime/quickjs-evaluator.mjs";
|
|
7
7
|
export { createTools } from "./tools/Tools.mjs";
|
|
8
|
-
export {
|
|
9
|
-
createTempoProvider,
|
|
10
|
-
createTempoProviderFromAccounts,
|
|
11
|
-
DEFAULT_MERCATOR_MCP_URL,
|
|
12
|
-
} from "./runtime/tempo-provider.mjs";
|
package/internal.mjs
CHANGED
|
@@ -110,6 +110,14 @@ export async function routePrompt(agent, options) {
|
|
|
110
110
|
return raw === undefined ? undefined : createTurn(raw, agent);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
/** Internal host lifecycle identity; accepted() retains its public durable-only contract. */
|
|
114
|
+
export function getTurnHostId(turn) {
|
|
115
|
+
const state = turnState(turn);
|
|
116
|
+
return typeof state.raw.hostTurnId === "function"
|
|
117
|
+
? Promise.resolve(state.raw.hostTurnId())
|
|
118
|
+
: awaitTurnAcceptance(turn);
|
|
119
|
+
}
|
|
120
|
+
|
|
113
121
|
export function getTurnResult(turn) {
|
|
114
122
|
const state = turnState(turn);
|
|
115
123
|
if (!state.result) {
|
|
@@ -321,6 +329,7 @@ export function toWasmConfig(options = {}) {
|
|
|
321
329
|
copy(config, "thinking", options.thinking);
|
|
322
330
|
copy(config, "reasoning_mode", options.reasoningMode);
|
|
323
331
|
copy(config, "fast_mode", options.fastMode);
|
|
332
|
+
copy(config, "instant_tool_steering", options.instantToolSteering);
|
|
324
333
|
copy(config, "stateless_http", options.stateless);
|
|
325
334
|
copy(config, "subagent_routing", options.subagentRouting);
|
|
326
335
|
copy(config, "websocket_warmup", options.websocketWarmup);
|
|
@@ -330,6 +339,7 @@ export function toWasmConfig(options = {}) {
|
|
|
330
339
|
copy(config, "instructions", options.instructions);
|
|
331
340
|
copy(config, "additional_instructions", options.additionalInstructions);
|
|
332
341
|
copy(config, "session_id", options.sessionId);
|
|
342
|
+
copy(config, "prompt_cache_key", options.promptCacheKey);
|
|
333
343
|
copy(config, "workspace", options.workspace);
|
|
334
344
|
if (options.executionEnvironment !== undefined) {
|
|
335
345
|
const environment = options.executionEnvironment;
|
|
@@ -351,6 +361,7 @@ export function toWasmConfig(options = {}) {
|
|
|
351
361
|
copy(config, "durability_host_id", options.durabilityHostId);
|
|
352
362
|
copy(config, "terminal_receipt_retention", options.terminalReceiptRetention);
|
|
353
363
|
copy(config, "subagents", options.subagents);
|
|
364
|
+
copy(config, "claude_harness", options.claudeHarness);
|
|
354
365
|
copy(config, "host_definition_id", options.hostDefinitionId);
|
|
355
366
|
copy(config, "before_compaction", options.beforeCompaction);
|
|
356
367
|
return config;
|
|
@@ -463,6 +474,12 @@ export function releaseDefinitionHost(id) {
|
|
|
463
474
|
}
|
|
464
475
|
|
|
465
476
|
const hostBridge = Object.freeze({
|
|
477
|
+
claudeAuth(hostDefinitionId) {
|
|
478
|
+
return requiredDefinitionHost(hostDefinitionId).claudeAuthHeaders();
|
|
479
|
+
},
|
|
480
|
+
executeClaudeTool(hostDefinitionId, name, input, sessionId, callId, model, turnId, localDefinitions, executeLocalTool) {
|
|
481
|
+
return requiredDefinitionHost(hostDefinitionId).executeClaudeTool(name, input, sessionId, callId, model, turnId, localDefinitions, executeLocalTool);
|
|
482
|
+
},
|
|
466
483
|
httpOpen(endpoint, apiKey, accountId, fedramp, sessionId, threadId, turnState, body) {
|
|
467
484
|
const host = requiredSessionHost(threadId);
|
|
468
485
|
if (typeof host.httpOpen !== "function") {
|
|
@@ -592,8 +609,8 @@ const hostBridge = Object.freeze({
|
|
|
592
609
|
host.releaseSession(sessionId);
|
|
593
610
|
releaseHostSession(host, sessionId);
|
|
594
611
|
},
|
|
595
|
-
executeCode(source, sessionId, callId, model, turnId) {
|
|
596
|
-
return requiredSessionHost(sessionId).executeCode(source, sessionId, callId, model, turnId);
|
|
612
|
+
executeCode(source, sessionId, callId, model, turnId, localDefinitions, executeLocalTool) {
|
|
613
|
+
return requiredSessionHost(sessionId).executeCode(source, sessionId, callId, model, turnId, localDefinitions, executeLocalTool);
|
|
597
614
|
},
|
|
598
615
|
waitCode(input, sessionId, callId) {
|
|
599
616
|
return requiredSessionHost(sessionId).waitCode(input, sessionId, callId);
|
|
@@ -604,6 +621,12 @@ const hostBridge = Object.freeze({
|
|
|
604
621
|
executeTool(name, input, sessionId, callId, model, turnId) {
|
|
605
622
|
return requiredSessionHost(sessionId).executeTool(name, input, sessionId, callId, model, turnId);
|
|
606
623
|
},
|
|
624
|
+
preemptCode(sessionId, callId) {
|
|
625
|
+
return hostSessions.get(sessionId)?.preemptCode?.(sessionId, callId) ?? false;
|
|
626
|
+
},
|
|
627
|
+
preemptCodeTurn(sessionId) {
|
|
628
|
+
return hostSessions.get(sessionId)?.preemptCodeTurn?.(sessionId) ?? 0;
|
|
629
|
+
},
|
|
607
630
|
beginCodeTurn(sessionId) {
|
|
608
631
|
hostSessions.get(sessionId)?.beginCodeTurn?.(sessionId);
|
|
609
632
|
},
|
|
@@ -1021,7 +1044,9 @@ function connectFailure(error) {
|
|
|
1021
1044
|
kind: "handshake_rejected",
|
|
1022
1045
|
status,
|
|
1023
1046
|
body: typeof error?.body === "string" ? error.body : errorDetail(error),
|
|
1024
|
-
...(Number.isFinite(retryAfter) && retryAfter >= 0 ? { retry_after: retryAfter } : {}),
|
|
1047
|
+
...(error?.retryAfter !== undefined && Number.isFinite(retryAfter) && retryAfter >= 0 ? { retry_after: retryAfter } : {}),
|
|
1048
|
+
...(Number.isSafeInteger(error?.retry_after_deadline_ms) && error.retry_after_deadline_ms >= 0
|
|
1049
|
+
? { retry_after_deadline_ms: error.retry_after_deadline_ms } : {}),
|
|
1025
1050
|
};
|
|
1026
1051
|
}
|
|
1027
1052
|
return {
|
package/managed/Agent.d.mts
CHANGED
|
@@ -73,7 +73,7 @@ export type Options = Readonly<{
|
|
|
73
73
|
}>;
|
|
74
74
|
|
|
75
75
|
export type CreateSettings = Readonly<{
|
|
76
|
-
model: Model;
|
|
76
|
+
model: Model | "claude-sonnet-4-6" | "claude-opus-4-6" | "claude-sonnet-5-5" | "claude-opus-5-5";
|
|
77
77
|
thinking: Thinking;
|
|
78
78
|
reasoningMode: ReasoningMode;
|
|
79
79
|
fastMode: boolean;
|
|
@@ -89,6 +89,8 @@ export type Environment = Readonly<{
|
|
|
89
89
|
network?: NetworkPolicy;
|
|
90
90
|
}>;
|
|
91
91
|
export type Configuration = Readonly<{
|
|
92
|
+
/** Yield active exec/wait observers on accepted steering; default false. */
|
|
93
|
+
instant_tool_steering?: boolean;
|
|
92
94
|
/** Pin this session to one connected ChatGPT account; disables automatic account failover. */
|
|
93
95
|
chatgpt_account_id?: string;
|
|
94
96
|
settings?: Readonly<{ model: CreateSettings["model"]; thinking: CreateSettings["thinking"]; reasoning_mode: "standard" | "pro"; fast_mode: boolean }>;
|
|
@@ -163,7 +165,7 @@ export type State = Readonly<{
|
|
|
163
165
|
latest_event_cursor: string;
|
|
164
166
|
stream_error: string | null;
|
|
165
167
|
settings: Readonly<{
|
|
166
|
-
model: Model;
|
|
168
|
+
model: Model | "claude-sonnet-4-6" | "claude-opus-4-6" | "claude-sonnet-5-5" | "claude-opus-5-5";
|
|
167
169
|
thinking: Thinking;
|
|
168
170
|
reasoning_mode: ReasoningMode;
|
|
169
171
|
fast_mode: boolean;
|
|
@@ -357,6 +359,8 @@ export type CronTrigger = Readonly<{
|
|
|
357
359
|
export type Agent = Readonly<{
|
|
358
360
|
/** Start bounded background runtime/socket preparation for an active conversation.
|
|
359
361
|
* Resolves on acceptance, not provider readiness. Never required before prompt(). */
|
|
362
|
+
/** Idle manual compaction; uncertain failures are never automatically retried. */
|
|
363
|
+
compact(options?: Readonly<{ signal?: AbortSignal }>): Promise<void>;
|
|
360
364
|
prepare(options?: Readonly<{ signal?: AbortSignal }>): Promise<void>;
|
|
361
365
|
requiredActions: Readonly<{
|
|
362
366
|
list(): Promise<{ data: readonly Readonly<{ call_id: string; session_id: string; source_call_id: string; name: string; input: unknown; deadline_at: number }>[] }>;
|
package/managed/Agent.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { attachRetryAfterAdvice, retryAfterAdvice, retryAfterRemaining } from "../runtime/retry-after.mjs";
|
|
1
2
|
import { steerInputKey } from "../runtime/steer-receipt.mjs";
|
|
2
3
|
import { requestOriginContext } from "../tools/environment.mjs";
|
|
3
4
|
import { ManagedError } from "./ManagedError.mjs";
|
|
@@ -17,6 +18,14 @@ const TERMINAL_TYPES = new Set([
|
|
|
17
18
|
"turn_cancelled",
|
|
18
19
|
"turn_failed",
|
|
19
20
|
]);
|
|
21
|
+
// Typed terminal failures override an otherwise retryable HTTP status.
|
|
22
|
+
const TERMINAL_RETRY_CODES = new Set([
|
|
23
|
+
"context_length_exceeded", "insufficient_quota", "usage_not_included",
|
|
24
|
+
"cyber_policy", "misalignment_policy_violation", "invalid_prompt", "bio_policy",
|
|
25
|
+
]);
|
|
26
|
+
// Private event-reconnect veto; does not alter public code precedence or the
|
|
27
|
+
// independent creation/mutation retry policy.
|
|
28
|
+
const terminalResponseErrors = new WeakSet();
|
|
20
29
|
const TERMINAL_CACHE_CAPACITY = 256;
|
|
21
30
|
const TERMINAL_CACHE_BYTES = 8 * 1024 * 1024;
|
|
22
31
|
const SUBSCRIBER_QUEUE_CAPACITY = 4_096;
|
|
@@ -29,7 +38,7 @@ const TURN_STATE_READ_TIMEOUT_MS = 2_000;
|
|
|
29
38
|
const ALLOWED_OPTIONS = new Set(["apiKey", "baseUrl", "fetch", "toolsTransport", "requestOrigin"]);
|
|
30
39
|
const CREATE_SETTINGS = new Set(["model", "thinking", "reasoningMode", "fastMode"]);
|
|
31
40
|
const SETTINGS_PATCH = CREATE_SETTINGS;
|
|
32
|
-
const MODELS = new Set(["gpt-6.1-sol", "gpt-6-luna", "gpt-6-astra", "@cf/zai-org/glm-5.3", "kimi-k3", "mimo-v2.6-pro"]);
|
|
41
|
+
const MODELS = new Set(["gpt-6.1-sol", "gpt-6-luna", "gpt-6-astra", "@cf/zai-org/glm-5.3", "kimi-k3", "mimo-v2.6-pro", "claude-sonnet-4-6", "claude-opus-4-6", "claude-sonnet-5-5", "claude-opus-5-5"]);
|
|
33
42
|
const THINKING = new Set(["none", "low", "medium", "high", "xhigh", "max"]);
|
|
34
43
|
const REASONING_MODES = new Set(["standard", "pro"]);
|
|
35
44
|
const eventEncoder = new TextEncoder();
|
|
@@ -159,6 +168,7 @@ function managedCreateOptions(options) {
|
|
|
159
168
|
if (settings.model === "gpt-6-astra" && settings.reasoningMode === "pro") {
|
|
160
169
|
throw new TypeError("GPT-6 Astra does not support pro reasoning mode");
|
|
161
170
|
}
|
|
171
|
+
if (settings.model.startsWith("claude-") && (!["low", "medium", "high"].includes(settings.thinking) || settings.reasoningMode !== "standard" || settings.fastMode)) throw new TypeError("unsupported Claude settings");
|
|
162
172
|
return {
|
|
163
173
|
clientOptions,
|
|
164
174
|
creationKey,
|
|
@@ -302,6 +312,9 @@ function agentHandle(client, id, summary, retainedEventStream) {
|
|
|
302
312
|
return agentHandle(client, childId);
|
|
303
313
|
},
|
|
304
314
|
// Activation is explicit: passive event/history readers never warm a model.
|
|
315
|
+
compact: (options = {}) => client.json(`${agentPath(id)}/compact`, {
|
|
316
|
+
method: "POST", signal: options.signal,
|
|
317
|
+
}).then(() => undefined),
|
|
305
318
|
prepare: (options = {}) => client.json(`${agentPath(id)}/prepare`, {
|
|
306
319
|
method: "POST", ...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
307
320
|
}).then(() => undefined),
|
|
@@ -452,6 +465,7 @@ function managedSettings(value) {
|
|
|
452
465
|
|| !REASONING_MODES.has(value.reasoning_mode) || typeof value.fast_mode !== "boolean"
|
|
453
466
|
|| (["@cf/zai-org/glm-5.3", "kimi-k3", "mimo-v2.6-pro"].includes(value.model) && (!(value.model === "kimi-k3" ? ["low", "high"] : ["low", "medium", "high"]).includes(value.thinking) || value.reasoning_mode === "pro"))
|
|
454
467
|
|| (["gpt-6-astra", "gpt-6.1-sol"].includes(value.model) && value.thinking === "none")
|
|
468
|
+
|| (value.model.startsWith("claude-") && (!["low", "medium", "high"].includes(value.thinking) || value.reasoning_mode !== "standard" || value.fast_mode))
|
|
455
469
|
|| (value.model === "gpt-6-astra" && value.reasoning_mode === "pro")
|
|
456
470
|
) {
|
|
457
471
|
throw new ManagedError("invalid_response", "managed agent settings are malformed");
|
|
@@ -1323,8 +1337,8 @@ async function* readEvents(client, agentId, initialCursor, signal, onControlCurs
|
|
|
1323
1337
|
}
|
|
1324
1338
|
if (!response.ok) {
|
|
1325
1339
|
const error = await responseError(response);
|
|
1326
|
-
if (response.status !== 429 && response.status < 500) throw error;
|
|
1327
|
-
await
|
|
1340
|
+
if ((terminalResponseErrors.has(error) || TERMINAL_RETRY_CODES.has(error.code)) || (response.status !== 429 && response.status < 500)) throw error;
|
|
1341
|
+
await waitForRetryAdvice(error, reconnectDelay, signal);
|
|
1328
1342
|
continue;
|
|
1329
1343
|
}
|
|
1330
1344
|
if (!response.body) throw new ManagedError("invalid_response", "managed event stream has no body");
|
|
@@ -1376,6 +1390,16 @@ async function* readEvents(client, agentId, initialCursor, signal, onControlCurs
|
|
|
1376
1390
|
}
|
|
1377
1391
|
}
|
|
1378
1392
|
|
|
1393
|
+
async function waitForRetryAdvice(advice, fallback, signal) {
|
|
1394
|
+
let remaining = retryAfterRemaining(advice);
|
|
1395
|
+
if (remaining === undefined) return delay(fallback, signal);
|
|
1396
|
+
while (remaining > 0) {
|
|
1397
|
+
// Timers coerce larger delays to ~1ms; chunking preserves the original deadline.
|
|
1398
|
+
await delay(Math.min(remaining, 2_147_483_647), signal);
|
|
1399
|
+
remaining = retryAfterRemaining(advice);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1379
1403
|
function encodedBytes(value) {
|
|
1380
1404
|
const encoded = typeof value === "string" ? value : JSON.stringify(value);
|
|
1381
1405
|
return eventEncoder.encode(encoded).byteLength;
|
|
@@ -1569,11 +1593,21 @@ function managedClient(options) {
|
|
|
1569
1593
|
}
|
|
1570
1594
|
|
|
1571
1595
|
async function responseError(response) {
|
|
1596
|
+
const advice = retryAfterAdvice(response.headers.get("retry-after"));
|
|
1572
1597
|
let body;
|
|
1573
1598
|
try { body = await response.json(); } catch { body = undefined; }
|
|
1574
|
-
const code = typeof body?.error === "string" ? body.error
|
|
1599
|
+
const code = typeof body?.error === "string" ? body.error
|
|
1600
|
+
: typeof body?.error?.code === "string" ? body.error.code
|
|
1601
|
+
: typeof body?.code === "string" ? body.code
|
|
1602
|
+
: typeof body?.error?.type === "string" ? body.error.type : `http_${response.status}`;
|
|
1575
1603
|
const message = typeof body?.message === "string" ? body.message : `managed request failed (${response.status})`;
|
|
1576
|
-
|
|
1604
|
+
const error = attachRetryAfterAdvice(new ManagedError(code, message, { status: response.status }), advice);
|
|
1605
|
+
const discriminators = [body?.error, body?.code, body?.type,
|
|
1606
|
+
body?.error?.code, body?.error?.type, body?.response?.error?.code, body?.response?.error?.type];
|
|
1607
|
+
if (discriminators.some((value) => typeof value === "string" && TERMINAL_RETRY_CODES.has(value))) {
|
|
1608
|
+
terminalResponseErrors.add(error);
|
|
1609
|
+
}
|
|
1610
|
+
return error;
|
|
1577
1611
|
}
|
|
1578
1612
|
|
|
1579
1613
|
function validateOptions(options) {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export declare class ManagedError extends Error {
|
|
2
2
|
readonly code: string;
|
|
3
3
|
readonly status: number | undefined;
|
|
4
|
+
/** Server advice captured before consuming a rejected response body. */
|
|
5
|
+
readonly retry_after?: number;
|
|
6
|
+
readonly retry_after_deadline_ms?: number;
|
|
4
7
|
constructor(
|
|
5
8
|
code: string,
|
|
6
9
|
message: string,
|
package/node/Agent.d.mts
CHANGED
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
AgentLifecycle,
|
|
3
3
|
AgentOptions,
|
|
4
4
|
CodeEvaluator,
|
|
5
|
+
CodeEffectJournal,
|
|
5
6
|
DefaultAgent,
|
|
6
7
|
DurabilityStore,
|
|
7
8
|
McpServers,
|
|
@@ -14,10 +15,11 @@ import type { Tools } from "../tools/Tools.mjs";
|
|
|
14
15
|
|
|
15
16
|
export type Agent = DefaultAgent;
|
|
16
17
|
type ToolExposureOptions =
|
|
17
|
-
| { mcp?: false | undefined; toolMode?: "code" | "direct" | undefined }
|
|
18
|
-
| { mcp: McpServers; toolMode?: "code" | undefined };
|
|
18
|
+
| { mcp?: false | undefined; toolMode?: "code" | "code-only" | "direct" | undefined }
|
|
19
|
+
| { mcp: McpServers; toolMode?: "code" | "code-only" | undefined };
|
|
19
20
|
|
|
20
21
|
/** Creates a Node-hosted Rust/WASM Agent. */
|
|
22
|
+
export function create(options: import('../runtime/claude.mjs').Options & { harness: 'claude' }): Promise<import('../runtime/claude.mjs').Agent>;
|
|
21
23
|
export function create(options: create.ManagedOptions): Promise<AgentLifecycle>;
|
|
22
24
|
export function create(options: create.Options): Promise<create.ReturnType>;
|
|
23
25
|
export declare namespace create {
|
|
@@ -27,6 +29,8 @@ export declare namespace create {
|
|
|
27
29
|
}>;
|
|
28
30
|
type Options = AgentOptions & ToolExposureOptions & {
|
|
29
31
|
codeEvaluator?: CodeEvaluator | undefined;
|
|
32
|
+
/** Opt-in durable direct-tool and nested Code Mode receipts for safe cold recovery. */
|
|
33
|
+
codeEffectJournal?: CodeEffectJournal | undefined;
|
|
30
34
|
/** Caller-owned rooted filesystem mounted through standard workspace tools. */
|
|
31
35
|
filesystem?: Workspace | undefined;
|
|
32
36
|
module?: unknown;
|
package/node/Agent.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { prepareHarnesses } from '../runtime/harnesses.mjs';
|
|
2
|
+
import { create as createClaude } from './Claude.mjs';
|
|
1
3
|
import { createRequire } from "node:module";
|
|
2
4
|
import initWeb, { Nanocodex as WebNanocodex } from "../pkg-web/nanocodex.js";
|
|
3
5
|
|
|
@@ -29,12 +31,15 @@ let initializedWeb;
|
|
|
29
31
|
let NodeNanocodex;
|
|
30
32
|
|
|
31
33
|
export function create(options = {}) {
|
|
34
|
+
if (options.harness === 'claude') return createClaude(options);
|
|
35
|
+
if (options.harness !== undefined && options.harness !== 'codex') throw new TypeError('unsupported harness family');
|
|
32
36
|
if (managedTransportOptions(options?.transport)) return createManagedAgent(options);
|
|
33
37
|
const {
|
|
34
38
|
model,
|
|
35
39
|
thinking,
|
|
36
40
|
reasoningMode,
|
|
37
41
|
fastMode,
|
|
42
|
+
instantToolSteering,
|
|
38
43
|
rawApiEvents,
|
|
39
44
|
instructions,
|
|
40
45
|
additionalInstructions,
|
|
@@ -51,6 +56,7 @@ export function create(options = {}) {
|
|
|
51
56
|
toolMode,
|
|
52
57
|
mcp,
|
|
53
58
|
codeEvaluator,
|
|
59
|
+
codeEffectJournal,
|
|
54
60
|
} = options;
|
|
55
61
|
const stableSessionId = sessionId ?? createSessionId();
|
|
56
62
|
const {
|
|
@@ -63,6 +69,8 @@ export function create(options = {}) {
|
|
|
63
69
|
} = resolveResponsesTransport(transport);
|
|
64
70
|
const { tools: hostTools, subagents: subagentConfig } = resolveTools(tools);
|
|
65
71
|
const events = createEventChannel();
|
|
72
|
+
// Host lifecycle observers need terminal events even without a public watcher.
|
|
73
|
+
events.subscribe(() => {});
|
|
66
74
|
if (filesystem && workspace !== undefined && workspace !== filesystem.root) {
|
|
67
75
|
throw new TypeError("workspace must match filesystem.root when both are provided");
|
|
68
76
|
}
|
|
@@ -80,8 +88,10 @@ export function create(options = {}) {
|
|
|
80
88
|
toolMode,
|
|
81
89
|
workspace: workspace ?? filesystem?.root ?? resume?.workspace,
|
|
82
90
|
codeEvaluator,
|
|
83
|
-
|
|
91
|
+
codeEffectJournal,
|
|
92
|
+
onDispose: () => { releaseDefinitionHost(hostDefinitionId); void harnesses?.close(); },
|
|
84
93
|
});
|
|
94
|
+
let harnesses;
|
|
85
95
|
let durabilityOwner;
|
|
86
96
|
let creationStarted = false;
|
|
87
97
|
hostDefinitionId = registerDefinitionHost(host);
|
|
@@ -100,6 +110,7 @@ export function create(options = {}) {
|
|
|
100
110
|
durabilityId,
|
|
101
111
|
);
|
|
102
112
|
}
|
|
113
|
+
harnesses = await prepareHarnesses(options.harnesses, events.emit);
|
|
103
114
|
activateHost(host);
|
|
104
115
|
await host.ready();
|
|
105
116
|
const Nanocodex = module === undefined
|
|
@@ -116,6 +127,7 @@ export function create(options = {}) {
|
|
|
116
127
|
apiBaseUrl,
|
|
117
128
|
websocketWarmup,
|
|
118
129
|
subagents: subagentConfig,
|
|
130
|
+
claudeHarness: harnesses?.claude,
|
|
119
131
|
hostDefinitionId,
|
|
120
132
|
beforeCompaction: beforeCompaction !== undefined,
|
|
121
133
|
...config,
|
|
@@ -162,6 +174,7 @@ export function create(options = {}) {
|
|
|
162
174
|
thinking,
|
|
163
175
|
reasoningMode,
|
|
164
176
|
fastMode,
|
|
177
|
+
instantToolSteering,
|
|
165
178
|
rawApiEvents,
|
|
166
179
|
instructions,
|
|
167
180
|
additionalInstructions,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Agent, Options } from '../runtime/claude.mjs';
|
|
2
|
+
export type { Agent, Auth, Options, NativeToolResult, Result, Tool, ToolContent, ToolResult, Turn } from '../runtime/claude.mjs';
|
|
3
|
+
/** Creates the actual Claude Rust/WASM backend with explicit host-owned authentication and tools. */
|
|
4
|
+
export function create(options: Options): Promise<Agent>;
|
package/node/Claude.mjs
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { createClaude } from '../runtime/claude.mjs';
|
|
3
|
+
import { createNodeHost } from './host.mjs';
|
|
4
|
+
import { createBrowserHost } from '../browser/host.mjs';
|
|
5
|
+
|
|
6
|
+
function createCodexHost(options) {
|
|
7
|
+
// Function-backed Web API transports retain their own callbacks and evaluator.
|
|
8
|
+
if (options.hostAuth || options.createResponse || options.createWebSocket || options.WebSocketImpl) {
|
|
9
|
+
if ((options.toolMode === 'code' || options.toolMode === 'code-only') && typeof globalThis.Worker !== 'function' && options.codeEvaluator === undefined) throw new TypeError('host-managed Codex Code Mode requires an explicit codeEvaluator');
|
|
10
|
+
return createBrowserHost(options);
|
|
11
|
+
}
|
|
12
|
+
return createNodeHost(options);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Explicit Claude Messages runtime; no authentication or tools are inferred. */
|
|
16
|
+
export function create(options) {
|
|
17
|
+
return createClaude(options, async (module) => {
|
|
18
|
+
if (module === undefined) return createRequire(import.meta.url)('../pkg-node/nanocodex.js').Nanoclaude;
|
|
19
|
+
const wasm = await import('../pkg-web/nanocodex.js');
|
|
20
|
+
const { initializeBrowserEngine } = await import('../browser/engine.mjs');
|
|
21
|
+
await initializeBrowserEngine({ module });
|
|
22
|
+
return wasm.Nanoclaude;
|
|
23
|
+
}, 'node', { createCodexHost });
|
|
24
|
+
}
|
package/node/host.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { retryAfterAdvice } from "../runtime/retry-after.mjs";
|
|
2
|
+
|
|
3
|
+
import { createCodeEffectIdentity } from "../runtime/code-effect-identity.mjs";
|
|
1
4
|
import { createBeforeCompaction } from "../runtime/before-compaction.mjs";
|
|
2
5
|
import { createResponsesHttp, responsesHttpHeaders } from "../runtime/responses-http.mjs";
|
|
3
6
|
import { Console } from "node:console";
|
|
@@ -26,8 +29,8 @@ const MPP_CLIENT_PROTOCOL_ERROR_CLOSE_CODE = 3008;
|
|
|
26
29
|
export function createNodeHost(options = {}) {
|
|
27
30
|
const preservation = createBeforeCompaction(options.beforeCompaction);
|
|
28
31
|
const toolMode = options.toolMode ?? "code";
|
|
29
|
-
if (toolMode !== "code" && toolMode !== "direct") {
|
|
30
|
-
throw new TypeError("toolMode must be code or direct");
|
|
32
|
+
if (toolMode !== "code" && toolMode !== "code-only" && toolMode !== "direct") {
|
|
33
|
+
throw new TypeError("toolMode must be code, code-only or direct");
|
|
31
34
|
}
|
|
32
35
|
const toolsRouter = options.tools?.[toolRouterBrand]
|
|
33
36
|
? options.tools[toolRouterRuntime]
|
|
@@ -39,7 +42,7 @@ export function createNodeHost(options = {}) {
|
|
|
39
42
|
if (toolsMcp && options.mcpServers) {
|
|
40
43
|
throw new TypeError("MCP is already configured in Tools");
|
|
41
44
|
}
|
|
42
|
-
if ((toolsMcp || options.mcpServers) && toolMode
|
|
45
|
+
if ((toolsMcp || options.mcpServers) && toolMode === "direct") {
|
|
43
46
|
throw new TypeError("remote MCP requires Code Mode");
|
|
44
47
|
}
|
|
45
48
|
const toolsLifecycle = options.tools?.[toolRuntimeLifecycle];
|
|
@@ -51,10 +54,13 @@ export function createNodeHost(options = {}) {
|
|
|
51
54
|
body, signal, redirect: "error" });
|
|
52
55
|
});
|
|
53
56
|
const connections = new Map();
|
|
57
|
+
const effectIdentity = createCodeEffectIdentity(options.codeEffectJournal);
|
|
54
58
|
const code = createCodeRuntime(options.tools, {
|
|
55
59
|
require: createRequire(resolve(options.workspace ?? process.cwd(), ".nanocodex-code-mode.cjs")),
|
|
56
60
|
console: new Console({ stdout: process.stderr, stderr: process.stderr }),
|
|
57
61
|
evaluate: options.codeEvaluator,
|
|
62
|
+
effectJournal: options.codeEffectJournal,
|
|
63
|
+
effectIdentity: options.codeEffectJournal ? effectIdentity.resolve : undefined,
|
|
58
64
|
});
|
|
59
65
|
const filesystem = options.filesystem
|
|
60
66
|
? import("../runtime/workspace.mjs")
|
|
@@ -118,6 +124,7 @@ export function createNodeHost(options = {}) {
|
|
|
118
124
|
socket.on("unexpected-response", (_request, response) => {
|
|
119
125
|
if (settled) return;
|
|
120
126
|
settled = true;
|
|
127
|
+
const advice = retryAfterAdvice(header(response.headers, "retry-after"));
|
|
121
128
|
response.setEncoding("utf8");
|
|
122
129
|
const chunks = [];
|
|
123
130
|
response.on("data", (chunk) => chunks.push(chunk));
|
|
@@ -125,8 +132,8 @@ export function createNodeHost(options = {}) {
|
|
|
125
132
|
const error = new Error(`WebSocket handshake was rejected with HTTP ${response.statusCode}`);
|
|
126
133
|
error.status = response.statusCode;
|
|
127
134
|
error.body = chunks.length ? chunks.join("") : "empty response body";
|
|
128
|
-
|
|
129
|
-
if (
|
|
135
|
+
Object.assign(error, advice);
|
|
136
|
+
if (advice.retry_after !== undefined) error.retryAfter = advice.retry_after;
|
|
130
137
|
reject(error);
|
|
131
138
|
});
|
|
132
139
|
});
|
|
@@ -301,7 +308,7 @@ export function createNodeHost(options = {}) {
|
|
|
301
308
|
http.dispose();
|
|
302
309
|
disposal = Promise.resolve().then(() => settleCleanup([
|
|
303
310
|
...[...connections.keys()].map((handle) => () => close(handle)),
|
|
304
|
-
() => code.reset(),
|
|
311
|
+
() => { effectIdentity.reset(); return code.reset(); },
|
|
305
312
|
() => mcpInstalled,
|
|
306
313
|
() => toolsLifecycle?.close(),
|
|
307
314
|
() => options.onDispose?.(),
|
|
@@ -335,15 +342,17 @@ export function createNodeHost(options = {}) {
|
|
|
335
342
|
waitCode: code.waitCodeObserved,
|
|
336
343
|
beginCodeTurn: code.beginTurn,
|
|
337
344
|
cancelCodeTurn: code.cancelTurn,
|
|
345
|
+
preemptCode: code.preempt,
|
|
346
|
+
preemptCodeTurn: code.preemptTurn,
|
|
338
347
|
nextCodeUpdate: code.nextCodeUpdate,
|
|
339
348
|
executeTool: code.executeTool,
|
|
340
349
|
bindSubagentSession: code.bindSubagentSession,
|
|
341
350
|
cancelCode: code.cancel,
|
|
342
351
|
toolMode: () => toolMode,
|
|
343
352
|
toolDefinitions: code.toolDefinitions,
|
|
344
|
-
releaseSession: code.releaseSession,
|
|
345
|
-
emitEvent: onEvent,
|
|
346
|
-
reset: code.reset,
|
|
353
|
+
releaseSession: (sessionId) => { effectIdentity.release(sessionId); return code.releaseSession(sessionId); },
|
|
354
|
+
emitEvent: (event, ...args) => { code.observeEvent(event); effectIdentity.observe(event); return onEvent(event, ...args); },
|
|
355
|
+
reset: () => { effectIdentity.reset(); return code.reset(); },
|
|
347
356
|
dispose,
|
|
348
357
|
});
|
|
349
358
|
}
|
package/node/index.d.mts
CHANGED
|
@@ -4,16 +4,6 @@ export {
|
|
|
4
4
|
subscriptionRevision,
|
|
5
5
|
} from "../runtime/subscription-store.mjs";
|
|
6
6
|
export { createQuickJsEvaluator } from "../runtime/quickjs-evaluator.mjs";
|
|
7
|
-
export {
|
|
8
|
-
createTempoProvider,
|
|
9
|
-
createTempoProviderFromAccounts,
|
|
10
|
-
DEFAULT_MERCATOR_MCP_URL,
|
|
11
|
-
} from "../runtime/tempo-provider.mjs";
|
|
12
|
-
export type {
|
|
13
|
-
AccountsTempoProviderOptions,
|
|
14
|
-
AccountsWallet,
|
|
15
|
-
TempoProvider,
|
|
16
|
-
} from "../runtime/tempo-provider.mjs";
|
|
17
7
|
export type {
|
|
18
8
|
AgentEvent,
|
|
19
9
|
AgentLifecycle,
|
|
@@ -27,6 +17,9 @@ export type {
|
|
|
27
17
|
CostStatus,
|
|
28
18
|
CodeEvaluator,
|
|
29
19
|
CodeEvaluatorEnvironment,
|
|
20
|
+
CodeEffectContext,
|
|
21
|
+
CodeEffectReceipt,
|
|
22
|
+
CodeEffectJournal,
|
|
30
23
|
EstimatedUsdCost,
|
|
31
24
|
PromptInput,
|
|
32
25
|
PromptItem,
|
|
@@ -45,6 +38,7 @@ export type {
|
|
|
45
38
|
TurnResult,
|
|
46
39
|
TurnUsage,
|
|
47
40
|
McpPayment,
|
|
41
|
+
PaidMcpPayment,
|
|
48
42
|
McpServer,
|
|
49
43
|
McpServers,
|
|
50
44
|
MemoryChatGptSubscriptionStore,
|
|
@@ -60,3 +54,5 @@ export * as Subagents from "../runtime/subagents.mjs";
|
|
|
60
54
|
export * as Transport from "./Transport.mjs";
|
|
61
55
|
export * as Workspace from "./workspace.mjs";
|
|
62
56
|
export * as Tools from "../tools/index.mjs";
|
|
57
|
+
|
|
58
|
+
export * as Claude from "./Claude.mjs";
|
package/node/index.mjs
CHANGED
|
@@ -4,14 +4,11 @@ export {
|
|
|
4
4
|
subscriptionRevision,
|
|
5
5
|
} from "../runtime/subscription-store.mjs";
|
|
6
6
|
export { createQuickJsEvaluator } from "../runtime/quickjs-evaluator.mjs";
|
|
7
|
-
export {
|
|
8
|
-
createTempoProvider,
|
|
9
|
-
createTempoProviderFromAccounts,
|
|
10
|
-
DEFAULT_MERCATOR_MCP_URL,
|
|
11
|
-
} from "../runtime/tempo-provider.mjs";
|
|
12
7
|
export * as Agent from "./Agent.mjs";
|
|
13
8
|
export * as ChatGptSubscription from "./ChatGptSubscription.mjs";
|
|
14
9
|
export * as Subagents from "../runtime/subagents.mjs";
|
|
15
10
|
export * as Transport from "./Transport.mjs";
|
|
16
11
|
export * as Workspace from "./workspace.mjs";
|
|
17
12
|
export * as Tools from "../tools/index.mjs";
|
|
13
|
+
|
|
14
|
+
export * as Claude from "./Claude.mjs";
|