@evolvingmachines/sdk 0.0.51 → 0.0.52-project-sable.20260729.8632c49

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.cts CHANGED
@@ -1,9 +1,11 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import * as zod from 'zod';
3
- import { z } from 'zod';
3
+ import { ZodType, z } from 'zod';
4
4
  export { E2BConfig, E2BProvider, createE2BProvider } from '@evolvingmachines/e2b';
5
5
  export { DaytonaConfig, DaytonaProvider, createDaytonaProvider } from '@evolvingmachines/daytona';
6
6
  export { ModalConfig, ModalProvider, createModalProvider } from '@evolvingmachines/modal';
7
+ import { H as HostedClientConfig, B as BenchmarksClient, C as CustomHarnessesClient, J as JobsClient, a as CapabilityDocument, b as HostedErrorCode } from './types-BnWkwyuA.cjs';
8
+ export { k as ActiveBenchmark, A as Awaitable, j as Benchmark, Y as BenchmarkImport, a0 as BenchmarkImportFailure, Z as BenchmarkImportInput, f as BenchmarkImportList, g as BenchmarkImportPage, _ as BenchmarkImportSource, $ as BenchmarkImportStatus, l as BenchmarkVersion, m as BenchmarkVersionState, D as ComparisonAggregate, F as ComparisonCell, G as ComparisonCoverage, I as ComparisonTaskRow, a1 as CustomHarness, a2 as CustomHarnessInput, a3 as CustomHarnessSource, h as CustomHarnessUpsertInput, E as EvalSandboxProvider, af as ExportJobOptions, c as HOSTED_ERROR_CODES, d as HarnessCapability, e as HarnessModel, q as Job, o as JobAgent, K as JobComparison, y as JobEvent, p as JobInput, a6 as JobList, a5 as JobPage, r as JobStatus, z as JobWatch, L as ListImportsOptions, aa as ListJobsOptions, ab as ListTrialsOptions, M as ModelUsage, P as ProviderCapability, W as RegradeFilter, R as RegradeJob, Q as RegradeJobStatus, X as RegradeOptions, N as RegradeResult, O as RegradeStatus, a9 as RunJobOptions, a4 as SpendSource, S as StatusVocabulary, T as Task, n as TaskProviderVerdict, s as Trial, v as TrialCounts, t as TrialDetail, a8 as TrialList, a7 as TrialPage, u as TrialStatus, w as TrialTraceEvent, ac as TrialTraceOptions, x as TrialTracePage, U as UpstreamStatus, V as VerifierMode, ae as WatchImportOptions, ad as WatchJobOptions, i as isHostedErrorCode } from './types-BnWkwyuA.cjs';
7
9
 
8
10
  /**
9
11
  * ACP-inspired output types for unified agent event streaming.
@@ -141,7 +143,40 @@ interface PlanEntry {
141
143
  * All possible session update types.
142
144
  * Discriminated union on `sessionUpdate` field.
143
145
  */
144
- type SessionUpdate = AgentMessageChunk | AgentThoughtChunk | UserMessageChunk | ToolCall | ToolCallUpdate | Plan;
146
+ type SessionUpdate = AgentMessageChunk | AgentThoughtChunk | UserMessageChunk | ToolCall | ToolCallUpdate | Plan | AgentError;
147
+ /**
148
+ * A failure the HARNESS itself reported — not model output, not work.
149
+ *
150
+ * WHY THIS IS ITS OWN VARIANT AND NOT AN agent_message_chunk. Harnesses stream
151
+ * their failures on the same channel as their output: codex writes
152
+ * {"type":"error"} and {"type":"turn.failed"} to stdout as JSONL while its
153
+ * stderr says only "Reading prompt from stdin...". Dropping those left a run
154
+ * that could not reach the model looking identical to a run that produced
155
+ * nothing at all, which cost a full night of blind diagnosis. Folding them into
156
+ * agent_message_chunk would be worse than dropping them: a consumer counting
157
+ * "did the agent do any work" would count the error as work.
158
+ *
159
+ * So the transcript records the failure, and the discriminant says plainly that
160
+ * it is a failure. Anything deciding whether a harness RAN must exclude this
161
+ * variant — see isAgentWorkUpdate() below, and the eval runner's
162
+ * harnessNeverRan law, which must keep firing for an error-only run so an
163
+ * infrastructure failure is never scored as a zero.
164
+ */
165
+ interface AgentError {
166
+ sessionUpdate: "error";
167
+ /** The harness's own message, verbatim. */
168
+ message: string;
169
+ /** True when the harness treated it as terminal for the turn. */
170
+ fatal: boolean;
171
+ }
172
+ /**
173
+ * Is this update evidence the harness did WORK, as opposed to reporting a
174
+ * failure? The one predicate every "did it run" check should use, so the answer
175
+ * cannot drift between callers.
176
+ */
177
+ declare function isAgentWorkUpdate(update: {
178
+ sessionUpdate?: unknown;
179
+ } | null | undefined): boolean;
145
180
  /**
146
181
  * Streaming text/image from agent.
147
182
  * May arrive in multiple chunks - concatenate text.
@@ -285,6 +320,239 @@ interface OutputEvent {
285
320
  update: SessionUpdate;
286
321
  }
287
322
 
323
+ /**
324
+ * Agent Registry
325
+ *
326
+ * Single source of truth for agent-specific behavior.
327
+ * All differences between agents are data, not code.
328
+ */
329
+
330
+ /** Model configuration */
331
+ interface ModelInfo {
332
+ /** Model alias (short name used with --model) */
333
+ alias: string;
334
+ /** Full model ID */
335
+ modelId: string;
336
+ /** What this model is best for */
337
+ description: string;
338
+ }
339
+ /** MCP configuration for an agent */
340
+ interface McpConfigInfo {
341
+ /** Settings directory (e.g., "~/.claude") */
342
+ settingsDir: string;
343
+ /** Config filename (e.g., "settings.json" or "config.toml") */
344
+ filename: string;
345
+ /** Config format */
346
+ format: "json" | "toml";
347
+ /** Whether to use workingDir for project-level config (Claude only) */
348
+ projectConfig?: boolean;
349
+ }
350
+ /** Options for building agent commands */
351
+ interface BuildCommandOptions {
352
+ prompt: string;
353
+ model: string;
354
+ isResume: boolean;
355
+ sessionId?: string;
356
+ reasoningEffort?: string;
357
+ isDirectMode?: boolean;
358
+ /**
359
+ * External gateway mode (caller-minted credential + base URL). Direct-mode
360
+ * env injection applies, but CLIs that route via generated config (OpenCode
361
+ * inline config, Droid settings file) must use their GATEWAY command shape
362
+ * pointed at the caller's gateway — with the model passed VERBATIM (route
363
+ * names belong to the caller's gateway, never to Evolve's alias maps).
364
+ */
365
+ isExternalGateway?: boolean;
366
+ /** Skills enabled for this run */
367
+ skills?: string[];
368
+ /** Sandbox home directory (default: "/home/user") */
369
+ homeDir?: string;
370
+ }
371
+ interface AgentRegistryEntry {
372
+ /** Sandbox image/template identifier (provider maps to its own concept) */
373
+ image: string;
374
+ /** Environment variable name for API key */
375
+ apiKeyEnv: string;
376
+ /** Environment variable name for OAuth (file path or token depending on agent) */
377
+ oauthEnv?: string;
378
+ /** OAuth credentials filename (e.g., "auth.json" for Codex, "oauth_creds.json" for Gemini) */
379
+ oauthFileName?: string;
380
+ /** Environment variable to set when OAuth is active (e.g., GOOGLE_GENAI_USE_GCA=true for Gemini) */
381
+ oauthActivationEnv?: {
382
+ key: string;
383
+ value: string;
384
+ };
385
+ /** Environment variable name for base URL, if this CLI supports one */
386
+ baseUrlEnv?: string;
387
+ /** Default model alias */
388
+ defaultModel: string;
389
+ /** Available models for this agent */
390
+ models: ModelInfo[];
391
+ /** System prompt filename (e.g., "CLAUDE.md") */
392
+ systemPromptFile: string;
393
+ /** MCP configuration */
394
+ mcpConfig: McpConfigInfo;
395
+ /** Build the CLI command for this agent */
396
+ buildCommand: (opts: BuildCommandOptions) => string;
397
+ /** Extra setup step (e.g., codex login) */
398
+ setupCommand?: string;
399
+ /** Gateway path prefix for CLIs that use a provider-native passthrough endpoint */
400
+ gatewayPath?: string;
401
+ /** Default base URL for direct mode (only needed if provider requires specific endpoint, e.g., Qwen → Dashscope) */
402
+ defaultBaseUrl?: string;
403
+ /** Available beta headers for this agent (for reference) */
404
+ availableBetas?: Record<string, string>;
405
+ /** Skills configuration for this agent */
406
+ skillsConfig: SkillsConfig;
407
+ /** Multi-provider env mapping: model prefix → keyEnv (for CLIs like OpenCode that resolve provider from model string) */
408
+ providerEnvMap?: Record<string, {
409
+ keyEnv: string;
410
+ }>;
411
+ /** Env var for inline config (e.g., OPENCODE_CONFIG_CONTENT) — used in gateway mode to set provider base URLs */
412
+ gatewayConfigEnv?: string;
413
+ /** Gateway-only model aliases for CLIs whose native model IDs differ from the Evolve gateway's route names */
414
+ gatewayModelAliases?: Record<string, string>;
415
+ /** Direct-mode model aliases for CLIs whose public model names differ from CLI-native model IDs */
416
+ directModelAliases?: Record<string, string>;
417
+ /** Do not set provider API key env in gateway mode (used when routing via generated settings instead) */
418
+ skipApiKeyEnvInGateway?: boolean;
419
+ /** Dedicated Droid settings file for Evolve gateway custom model routing */
420
+ droidGatewaySettings?: {
421
+ settingsPath: string;
422
+ displayName: string;
423
+ provider: "generic-chat-completion-api" | "openai" | "anthropic";
424
+ maxOutputTokens?: number;
425
+ };
426
+ /** Environment variable that CLI reads for custom outbound HTTP headers */
427
+ customHeadersEnv?: string;
428
+ /** Format for custom headers env var: "newline" (Claude) or "comma" (Gemini). Default: "newline" */
429
+ customHeadersFormat?: "newline" | "comma";
430
+ /**
431
+ * Per-env-var spend tracking for CLIs that support env_http_headers in config
432
+ * (e.g., Codex TOML). Maps Evolve gateway header names to env var names that the CLI
433
+ * reads at request time. Alternative to customHeadersEnv for agents without a
434
+ * single custom-headers env var.
435
+ */
436
+ spendTrackingEnvs?: {
437
+ /** Env var name for x-litellm-customer-id value */
438
+ sessionTagEnv: string;
439
+ /** Env var name for x-litellm-tags value */
440
+ runTagEnv: string;
441
+ };
442
+ /**
443
+ * Config-file-based spend tracking for CLIs that read custom headers from a
444
+ * JSON settings file (e.g., Qwen settings.json → model.generationConfig.customHeaders).
445
+ * The SDK writes headers to this file before each run.
446
+ * Source-verified: Qwen reads customHeaders from settings.json, not env vars.
447
+ */
448
+ spendTrackingJsonConfig?: {
449
+ /** JSON path to the customHeaders object (dot-separated) */
450
+ headersPath: string;
451
+ };
452
+ /**
453
+ * TOML provider-based spend tracking for CLIs that read custom_headers from a
454
+ * provider entry in config.toml (e.g., Kimi Code).
455
+ * The SDK writes a provider+model entry with custom_headers before each run.
456
+ * Source-verified: Kimi Code reads custom_headers from
457
+ * providers[name].custom_headers in ~/.kimi-code/config.toml.
458
+ */
459
+ spendTrackingTomlProvider?: {
460
+ /** Config file path (e.g., "~/.kimi-code/config.toml") */
461
+ configPath: string;
462
+ /** Provider name in config (e.g., "evolve-gateway") */
463
+ providerName: string;
464
+ /** Model entry name (e.g., "evolve-default") */
465
+ modelName: string;
466
+ /** Max context size for the model entry */
467
+ maxContextSize: number;
468
+ };
469
+ /** Additional directories to include in checkpoint tar (beyond mcpConfig.settingsDir).
470
+ * Used for agents like OpenCode that spread state across XDG directories. */
471
+ checkpointDirs?: string[];
472
+ /** Additional relative paths to exclude from checkpoint tar. */
473
+ checkpointExcludes?: string[];
474
+ }
475
+ /**
476
+ * Registry of all supported agents.
477
+ *
478
+ * Each agent defines a buildCommand function that constructs the CLI command.
479
+ * This is type-safe and handles conditional logic cleanly.
480
+ */
481
+ declare const AGENT_REGISTRY: Record<AgentType, AgentRegistryEntry>;
482
+ /**
483
+ * Get registry entry for an agent type
484
+ */
485
+ declare function getAgentConfig(agentType: AgentType): AgentRegistryEntry;
486
+ /**
487
+ * Check if an agent type is valid
488
+ */
489
+ declare function isValidAgentType(type: string): type is AgentType;
490
+ /**
491
+ * Expand path with ~ to the sandbox home directory (default: /home/user)
492
+ */
493
+ declare function expandPath(path: string, homeDir?: string): string;
494
+ /**
495
+ * Get MCP settings path for an agent
496
+ */
497
+ declare function getMcpSettingsPath(agentType: AgentType, homeDir?: string): string;
498
+ /**
499
+ * Get MCP settings directory for an agent
500
+ */
501
+ declare function getMcpSettingsDir(agentType: AgentType, homeDir?: string): string;
502
+
503
+ interface ManagedSecretRef {
504
+ name: string;
505
+ as?: string;
506
+ }
507
+ interface ManagedSecretMetadata {
508
+ id: string;
509
+ name: string;
510
+ allowedHosts: string[];
511
+ allowedPathPrefixes: string[];
512
+ allowedMethods: string[];
513
+ createdAt: string;
514
+ updatedAt: string;
515
+ lastUsedAt: string | null;
516
+ }
517
+ interface ManagedSecretsClientConfig {
518
+ apiKey?: string;
519
+ dashboardUrl?: string;
520
+ }
521
+ interface ManagedSecretsClient {
522
+ list(): Promise<ManagedSecretMetadata[]>;
523
+ }
524
+ declare function managedSecrets(config?: ManagedSecretsClientConfig): ManagedSecretsClient;
525
+
526
+ interface EvolveEvents {
527
+ stdout: (chunk: string) => void;
528
+ stderr: (chunk: string) => void;
529
+ content: (event: OutputEvent) => void;
530
+ lifecycle: (event: LifecycleEvent) => void;
531
+ }
532
+ interface EvolveConfig {
533
+ agent?: AgentConfig;
534
+ sandbox?: SandboxProvider;
535
+ sandboxCreateOptions?: SandboxCreateOptions;
536
+ workingDirectory?: string;
537
+ workspaceMode?: WorkspaceMode;
538
+ secrets?: Record<string, string>;
539
+ managedSecrets?: ManagedSecretRef[];
540
+ sandboxId?: string;
541
+ systemPrompt?: string;
542
+ context?: FileMap;
543
+ files?: FileMap;
544
+ mcpServers?: Record<string, McpServerConfig>;
545
+ browser?: BrowserConfig;
546
+ browserCredentials?: BrowserCredentialsConfig;
547
+ plugins?: AgentPluginConfig[];
548
+ skills?: SkillName[];
549
+ schema?: ZodType<unknown> | JsonSchema;
550
+ schemaOptions?: SchemaValidationOptions;
551
+ sessionTagPrefix?: string;
552
+ observability?: Record<string, unknown>;
553
+ integrations?: IntegrationsSetup;
554
+ storage?: StorageConfig;
555
+ }
288
556
  /** Result of a completed sandbox command */
289
557
  interface SandboxCommandResult {
290
558
  exitCode: number;
@@ -318,6 +586,13 @@ interface SandboxRunOptions {
318
586
  interface SandboxSpawnOptions extends SandboxRunOptions {
319
587
  stdin?: boolean;
320
588
  }
589
+ /** Provider-neutral outbound network policy applied when the sandbox boots. */
590
+ interface SandboxNetworkPolicy {
591
+ /** Allow all outbound traffic, or deny it except for allowedDestinations. */
592
+ outbound: "open" | "blocked";
593
+ /** Hostnames, IP addresses, or CIDR ranges that remain reachable when blocked. */
594
+ allowedDestinations?: string[];
595
+ }
321
596
  /** Options for creating a sandbox */
322
597
  interface SandboxCreateOptions {
323
598
  /** Sandbox image/template ID. Provider uses its default if not specified. */
@@ -325,7 +600,108 @@ interface SandboxCreateOptions {
325
600
  envs?: Record<string, string>;
326
601
  metadata?: Record<string, string>;
327
602
  timeoutMs?: number;
603
+ /**
604
+ * Terminate the sandbox after this long with nothing running in it. This is
605
+ * an INACTIVITY bound, not a lifetime: `timeoutMs` caps how long the box may
606
+ * live at all, this caps how long it may sit doing nothing — which is what
607
+ * reclaims a box whose client died between commands, long before the lifetime
608
+ * would.
609
+ *
610
+ * Providers must reject it if they cannot enforce it, never silently ignore
611
+ * it. Only modal has a true idle timer alongside an absolute lifetime; e2b has
612
+ * no idle concept, and daytona's only clock IS an inactivity one, which
613
+ * `timeoutMs` already drives there.
614
+ *
615
+ * WHAT COUNTS AS ACTIVITY IS THE PROVIDER'S DEFINITION, and it is narrower
616
+ * than "the client is doing something" — Modal counts a running exec, a stdin
617
+ * write, and an open tunnel connection, and says nothing about filesystem
618
+ * calls. Size this above the longest gap between commands the caller expects,
619
+ * not above the longest gap between API calls.
620
+ */
621
+ idleTimeoutMs?: number;
328
622
  workingDirectory?: string;
623
+ /**
624
+ * Per-sandbox compute sizing: cpu in cores, memory and disk in GiB.
625
+ * Providers must reject entries they cannot enforce at create time, never
626
+ * silently ignore them (modal sizes cpu/memory at create but cannot size
627
+ * disk; e2b sizes at template build only; daytona sizes at snapshot build,
628
+ * so an existing snapshot cannot be resized at create).
629
+ */
630
+ resources?: {
631
+ cpu?: number;
632
+ memory?: number;
633
+ disk?: number;
634
+ };
635
+ /** Providers must reject policies they cannot enforce; never silently ignore them. */
636
+ network?: SandboxNetworkPolicy;
637
+ /**
638
+ * Run all commands and file operations as this user.
639
+ * Providers must reject it if they cannot enforce it, never silently ignore it.
640
+ */
641
+ user?: string;
642
+ /**
643
+ * Home directory used for agent config paths inside the sandbox.
644
+ * Default: "/root" when user is "root", "/home/<user>" for other users,
645
+ * "/home/user" when no user is given.
646
+ */
647
+ homeDir?: string;
648
+ }
649
+ /** Options for listing sandboxes (capability: SandboxProvider.list). */
650
+ interface SandboxListOptions {
651
+ /**
652
+ * Provider-neutral states. Providers map them onto their own vocabulary and
653
+ * must not invent matches for a state they do not have (Modal has no paused
654
+ * state, so a filter excluding "running" matches nothing there).
655
+ */
656
+ state?: ("running" | "paused")[];
657
+ metadata?: Record<string, string>;
658
+ limit?: number;
659
+ }
660
+ /** File or directory entry (capability: SandboxFiles.list). */
661
+ interface FileInfo {
662
+ name: string;
663
+ path: string;
664
+ type: "file" | "dir";
665
+ }
666
+ /**
667
+ * A COMPLETE (or admittedly incomplete) enumeration of a provider's fleet.
668
+ *
669
+ * `complete` is the load-bearing field, not a nicety. The callers that need a
670
+ * whole fleet — orphan sweeps, lifecycle reconciliation — read a sandbox's
671
+ * ABSENCE from the list as evidence it is gone, so a truncated page and a small
672
+ * fleet must never be the same answer. Returning a short array with no signal
673
+ * makes them identical, and the caller that acts on that difference is the one
674
+ * deleting machines.
675
+ *
676
+ * A caller that sees `complete: false` has to leave every row alone, exactly as
677
+ * if it had never asked.
678
+ */
679
+ interface SandboxListPage {
680
+ sandboxes: SandboxInfo[];
681
+ /**
682
+ * False means THIS IS NOT THE WHOLE FLEET — for any reason, including a
683
+ * `limit` the caller set. A caller-imposed limit that stopped the walk while
684
+ * more sandboxes existed is still a truncated answer, and reporting it as
685
+ * complete is what made this flag useless at its only real consumer: a sweep
686
+ * that always passes a limit could never learn it had been truncated.
687
+ * Complete means the provider ran out, not that we stopped asking.
688
+ */
689
+ complete: boolean;
690
+ /** Provider requests made. Diagnostic — a fleet that suddenly costs 40 pages. */
691
+ pagesFetched: number;
692
+ /** Why it could not be finished, when it could not. */
693
+ error?: string;
694
+ }
695
+ /** Sandbox metadata and lifecycle info (capability: SandboxProvider.list, SandboxInstance.getInfo). */
696
+ interface SandboxInfo {
697
+ sandboxId: string;
698
+ /** The provider-neutral image/template the sandbox booted from. */
699
+ image: string;
700
+ name?: string;
701
+ metadata: Record<string, string>;
702
+ startedAt: string;
703
+ /** End time (undefined for running sandboxes). */
704
+ endAt?: string;
329
705
  }
330
706
  /** Command execution capabilities */
331
707
  interface SandboxCommands {
@@ -343,6 +719,27 @@ interface SandboxFiles {
343
719
  data: string | Buffer | ArrayBuffer | Uint8Array;
344
720
  }>): Promise<void>;
345
721
  makeDir(path: string): Promise<void>;
722
+ /**
723
+ * Upload a LOCAL file by path, without loading it into the process heap.
724
+ *
725
+ * write()/writeBatch() take the bytes as a value, so uploading a large
726
+ * artifact costs one full-size Buffer per concurrent upload — a caller doing
727
+ * many uploads at once pays that in RSS. This takes the path instead and lets
728
+ * the provider move the bytes its own cheapest way (a request body streamed
729
+ * off disk, or the vendor SDK's own path upload).
730
+ *
731
+ * OPTIONAL: a provider that has no cheaper path than "read it and send it"
732
+ * omits this, and uploadFileFromPath() falls back to write().
733
+ */
734
+ writeFromPath?(sandboxPath: string, localPath: string): Promise<void>;
735
+ /** Check whether a file or directory exists. */
736
+ exists?(path: string): Promise<boolean>;
737
+ /** List directory contents. */
738
+ list?(path: string): Promise<FileInfo[]>;
739
+ /** Delete a file or directory. */
740
+ remove?(path: string): Promise<void>;
741
+ /** Rename or move a file or directory. */
742
+ rename?(oldPath: string, newPath: string): Promise<void>;
346
743
  }
347
744
  /** Sandbox instance */
348
745
  interface SandboxInstance {
@@ -353,15 +750,62 @@ interface SandboxInstance {
353
750
  getHost(port: number): Promise<string>;
354
751
  kill(): Promise<void>;
355
752
  pause(): Promise<void>;
753
+ /** Whether the sandbox is currently running. */
754
+ isRunning?(): Promise<boolean>;
755
+ /** Sandbox metadata and timing. */
756
+ getInfo?(): Promise<SandboxInfo>;
356
757
  }
357
758
  /** Sandbox lifecycle management - providers implement this */
358
759
  interface SandboxProvider {
359
760
  /** Provider type identifier (e.g., "e2b") */
360
761
  readonly providerType: string;
361
- /** Human-readable provider name for logging */
762
+ /** Human-readable provider name for logging (e.g., "E2B") */
362
763
  readonly name?: string;
363
764
  create(options: SandboxCreateOptions): Promise<SandboxInstance>;
364
765
  connect(sandboxId: string, timeoutMs?: number): Promise<SandboxInstance>;
766
+ /**
767
+ * List sandboxes, paginating to exhaustion.
768
+ *
769
+ * `limit` bounds the number of items RETURNED, so a caller that wants one
770
+ * cheap page still asks for one; without it the answer is the whole fleet.
771
+ * It used to be first-page-only regardless, which silently truncated any
772
+ * account past a provider's page size.
773
+ *
774
+ * Errors throw. A caller that cannot treat a failed enumeration as an
775
+ * exception — because it reads absence as termination — wants `listAll`.
776
+ *
777
+ * OPTIONAL: all three first-party providers implement it, but the SDK never
778
+ * calls it, so requiring it would break third-party providers passed to
779
+ * .withSandbox() for no gain. Declared here so every provider that offers it
780
+ * offers the SAME signature.
781
+ */
782
+ list?(options?: SandboxListOptions): Promise<SandboxInfo[]>;
783
+ /**
784
+ * The fleet-bookkeeping counterpart to `list()`: paginates to exhaustion and
785
+ * NEVER throws.
786
+ *
787
+ * The difference is not error style, it is what a failure MEANS to the
788
+ * caller. Anything that reads a sandbox's absence as "terminated" cannot
789
+ * distinguish a provider that answered "nothing" from one that could not
790
+ * finish answering — and acting on that confusion mass-kills a live fleet. So
791
+ * a failure comes back as `complete: false` rather than as an exception the
792
+ * caller might catch and treat as an empty list.
793
+ *
794
+ * REQUIRED, unlike `list`. It was optional in the first cut, and that is
795
+ * precisely what let one provider keep silently truncating while this
796
+ * interface promised exhaustive listing — a provider that cannot answer "is
797
+ * this the whole fleet?" cannot be used for fleet bookkeeping at all, so the
798
+ * type refuses to let a fourth one ship without saying so.
799
+ *
800
+ * PARTIAL RESULTS ARE RETURNED, not discarded: `complete: false` with a
801
+ * non-empty `sandboxes` means "at least these, and there are more". Modal's
802
+ * own `listSandboxIds` takes the stricter line and returns an empty set on
803
+ * failure, on the grounds that partial results are worse than none for a
804
+ * terminal-state decision. Both are safe because `complete` is what callers
805
+ * branch on; the divergence is deliberate and noted here so nobody "fixes"
806
+ * one to match the other without deciding which rule they want.
807
+ */
808
+ listAll(options?: SandboxListOptions): Promise<SandboxListPage>;
365
809
  }
366
810
  /** Supported agent types (headless CLI agents only, no ACP) */
367
811
  type AgentType = "claude" | "codex" | "gemini" | "qwen" | "kimi" | "opencode" | "droid";
@@ -376,7 +820,7 @@ declare const AGENT_TYPES: {
376
820
  readonly DROID: "droid";
377
821
  };
378
822
  /** Workspace mode determines folder structure and system prompt */
379
- type WorkspaceMode = "knowledge" | "swe";
823
+ type WorkspaceMode = "knowledge" | "swe" | "task";
380
824
  /** Available skills that can be enabled */
381
825
  type SkillName = "pdf" | "dev-browser" | (string & {});
382
826
  /** Browser automation providers that can be enabled explicitly */
@@ -520,7 +964,22 @@ interface SchemaValidationOptions {
520
964
  * Validation mode preset definitions
521
965
  */
522
966
  declare const VALIDATION_PRESETS: Record<ValidationMode, Required<Omit<SchemaValidationOptions, "mode">>>;
523
- /** Configuration passed to withAgent() */
967
+ /**
968
+ * Caller-minted gateway credential for external gateway mode.
969
+ *
970
+ * For callers that mint their own spend-capped key on an OpenAI-compatible
971
+ * gateway. The credential is injected like direct mode and sealCredentials()
972
+ * calls revoke() — sealing fails if revocation fails.
973
+ */
974
+ interface ExternalGatewayConfig {
975
+ /** Spend-capped gateway API key minted by the caller */
976
+ apiKey: string;
977
+ /** OpenAI-compatible gateway base URL */
978
+ baseUrl: string;
979
+ /** Revoke the minted credential. Called by sealCredentials(); seal fails if this throws. */
980
+ revoke: () => Promise<void>;
981
+ }
982
+ /** Configuration passed to withAgent() */
524
983
  interface AgentConfig {
525
984
  /** Agent type (default: "claude") */
526
985
  type?: AgentType;
@@ -532,10 +991,27 @@ interface AgentConfig {
532
991
  oauthToken?: string;
533
992
  /** Provider base URL for direct mode (default: provider env var or registry default) */
534
993
  providerBaseUrl?: string;
994
+ /**
995
+ * Caller-minted revocable gateway credential. Mutually exclusive with
996
+ * apiKey (gateway mode) and providerApiKey/providerBaseUrl (direct mode).
997
+ */
998
+ externalGateway?: ExternalGatewayConfig;
535
999
  /** Model to use (optional, uses agent's default if omitted) */
536
1000
  model?: string;
537
1001
  /** Reasoning effort for models that support it */
538
1002
  reasoningEffort?: ReasoningEffort;
1003
+ /**
1004
+ * Context/completion ceiling for CLIs that must be told one (Kimi Code reads
1005
+ * it as `max_context_size` and sends it as the request's `max_tokens`).
1006
+ *
1007
+ * Set it to the model's real ceiling when driving a harness against a model
1008
+ * from another family — e.g. Kimi Code against `gpt-5.5` through an
1009
+ * OpenAI-compatible gateway, where an oversized `max_tokens` is rejected with
1010
+ * a 400. When set it is used verbatim. When omitted, the harness's own models
1011
+ * keep their registry value and any other model falls back to a conservative
1012
+ * 128000. Harnesses that never send a ceiling ignore it.
1013
+ */
1014
+ maxContextSize?: number;
539
1015
  }
540
1016
  /** Resolved agent config (output of resolution, not an extension of input) */
541
1017
  interface ResolvedAgentConfig {
@@ -546,15 +1022,29 @@ interface ResolvedAgentConfig {
546
1022
  isOAuth?: boolean;
547
1023
  /** File content for file-based OAuth (Codex) */
548
1024
  oauthFileContent?: string;
1025
+ /** External gateway mode: caller-minted revocable credential */
1026
+ externalGateway?: {
1027
+ revoke: () => Promise<void>;
1028
+ };
549
1029
  model?: string;
550
1030
  reasoningEffort?: ReasoningEffort;
1031
+ /** Caller-pinned context/completion ceiling; used verbatim when present */
1032
+ maxContextSize?: number;
551
1033
  }
552
1034
  /** Options for Agent constructor */
553
1035
  interface AgentOptions {
554
1036
  /** Sandbox provider (e.g., E2B) */
555
1037
  sandboxProvider?: SandboxProvider;
1038
+ /** Provider-neutral sandbox creation options forwarded on fresh creates. */
1039
+ sandboxCreateOptions?: SandboxCreateOptions;
556
1040
  /** Additional environment secrets */
557
1041
  secrets?: Record<string, string>;
1042
+ /** Dashboard-stored managed secrets exposed through opaque env vars. */
1043
+ managedSecrets?: {
1044
+ secrets: ManagedSecretRef[];
1045
+ apiKey: string;
1046
+ dashboardUrl?: string;
1047
+ };
558
1048
  /** Existing sandbox ID to connect to */
559
1049
  sandboxId?: string;
560
1050
  /** Working directory path */
@@ -706,7 +1196,7 @@ interface RunCost {
706
1196
  runId: string;
707
1197
  /** 1-based chronological position in session */
708
1198
  index: number;
709
- /** Total cost in USD (includes platform margin) */
1199
+ /** Total cost in USD as billed to your Evolve account */
710
1200
  cost: number;
711
1201
  /** Token counts */
712
1202
  tokens: {
@@ -986,8 +1476,6 @@ interface IntegrationAccountDeleteResult {
986
1476
  *
987
1477
  * Single Agent class that uses registry lookup for agent-specific behavior.
988
1478
  * All agent differences are data (in registry), not code.
989
- *
990
- * Evidence: sdk-rewrite-v3.md Design Decisions section
991
1479
  */
992
1480
 
993
1481
  /**
@@ -1002,9 +1490,10 @@ declare class Agent {
1002
1490
  private sandbox?;
1003
1491
  private hasRun;
1004
1492
  private readonly workingDir;
1493
+ private readonly homeDir;
1005
1494
  private lastRunTimestamp?;
1006
1495
  private readonly registry;
1007
- /** Unified session ID — used for both observability (SessionLogger) and spend tracking (LiteLLM customer-id) */
1496
+ /** Unified session ID — used for both observability (SessionLogger) and spend tracking (gateway customer-id) */
1008
1497
  private sessionTag;
1009
1498
  /** Previous session tag — preserved across kill()/setSession() so cost queries still work */
1010
1499
  private previousSessionTag?;
@@ -1020,6 +1509,9 @@ declare class Agent {
1020
1509
  private droidSessionId?;
1021
1510
  private managedBrowserSession?;
1022
1511
  private providerRuntimeToken?;
1512
+ private managedSecretRuntimeToken?;
1513
+ private managedSecretProxy?;
1514
+ private credentialsSealed;
1023
1515
  private readonly skills?;
1024
1516
  private readonly storage?;
1025
1517
  private lastCheckpointId?;
@@ -1043,10 +1535,33 @@ declare class Agent {
1043
1535
  * Get or create sandbox instance
1044
1536
  */
1045
1537
  getSandbox(callbacks?: StreamCallbacks): Promise<SandboxInstance>;
1538
+ /**
1539
+ * The `max_context_size` Kimi Code is told, which it sends as the request's
1540
+ * `max_tokens`. Three cases, in order:
1541
+ *
1542
+ * 1. `maxContextSize` on the agent config wins verbatim — the caller knows
1543
+ * the model's real ceiling.
1544
+ * 2. A model the kimi registry entry itself declares keeps that entry's
1545
+ * value (262144).
1546
+ * 3. Any other model — e.g. driving Kimi Code against `gpt-5.5` through an
1547
+ * OpenAI-compatible gateway — gets the conservative constant, because
1548
+ * 262144 is above that model's ceiling and the gateway answers 400.
1549
+ *
1550
+ * Both kimi wiring paths (KIMI_MODEL_MAX_CONTEXT_SIZE and the config.toml
1551
+ * `max_context_size`) resolve it here, so they can never disagree.
1552
+ */
1553
+ private resolveKimiMaxContextSize;
1554
+ /**
1555
+ * Kimi Code model envs for direct-style credential injection (direct mode
1556
+ * and externalGateway mode). Kimi Code reads KIMI_MODEL_* — the registry's
1557
+ * KIMI_API_KEY/KIMI_BASE_URL are SDK-facing inputs the CLI never reads.
1558
+ */
1559
+ private buildKimiDirectModelEnvs;
1046
1560
  /**
1047
1561
  * Build environment variables for sandbox
1048
1562
  */
1049
1563
  private buildEnvironmentVariables;
1564
+ private buildSandboxCreateOptions;
1050
1565
  private validatedUserSecretsForEnvironment;
1051
1566
  private ensureManagedBrowserSession;
1052
1567
  private ensureProviderRuntimeToken;
@@ -1054,6 +1569,10 @@ declare class Agent {
1054
1569
  private setupManagedBrowser;
1055
1570
  private closeManagedBrowserSession;
1056
1571
  private closeProviderRuntimeToken;
1572
+ private ensureManagedSecretRuntimeToken;
1573
+ private bindManagedSecretRuntimeToken;
1574
+ private setupManagedSecretEgress;
1575
+ private closeManagedSecretRuntimeToken;
1057
1576
  /**
1058
1577
  * Build the inline gateway config JSON for agents using gatewayConfigEnv
1059
1578
  * (e.g., OpenCode OPENCODE_CONFIG_CONTENT). Centralizes the provider config
@@ -1067,9 +1586,12 @@ declare class Agent {
1067
1586
  */
1068
1587
  private buildGatewayConfigJson;
1069
1588
  private activeProviderRuntimeToken;
1589
+ private requireActiveProviderRuntimeToken;
1070
1590
  private ensureSessionLogger;
1071
1591
  private flushSessionLoggerWithTimeout;
1592
+ private requiresPreRunDashboardIngest;
1072
1593
  private providerRuntimeHeaderUpdates;
1594
+ private shouldExposeProviderRuntimeTokenEnv;
1073
1595
  private buildProviderRuntimeProcessEnvs;
1074
1596
  /**
1075
1597
  * Build per-run env overrides for spend tracking.
@@ -1082,6 +1604,7 @@ declare class Agent {
1082
1604
  private captureDroidSession;
1083
1605
  private extractDroidSessionId;
1084
1606
  private findDroidSessionId;
1607
+ private droidSessionStatePath;
1085
1608
  private loadDroidSessionState;
1086
1609
  private writeDroidSessionState;
1087
1610
  private resolveGatewayModel;
@@ -1090,6 +1613,7 @@ declare class Agent {
1090
1613
  * Agent-specific authentication setup
1091
1614
  */
1092
1615
  private setupAgentAuth;
1616
+ private writeGeminiGatewayAuthSettings;
1093
1617
  private setupAgentPlugins;
1094
1618
  private assertProviderRuntimeDoesNotExposeGatewayKey;
1095
1619
  /**
@@ -1128,6 +1652,16 @@ declare class Agent {
1128
1652
  * Execute arbitrary command in sandbox
1129
1653
  */
1130
1654
  executeCommand(command: string, options?: ExecuteCommandOptions, callbacks?: StreamCallbacks): Promise<AgentResponse>;
1655
+ /**
1656
+ * Permanently revoke the model capability attached to this sandbox.
1657
+ * This is intentionally fail-closed: configurations that may have placed
1658
+ * other credentials in the sandbox cannot claim to be sealed.
1659
+ */
1660
+ sealCredentials(): Promise<void>;
1661
+ /** Whether sealCredentials() has completed — the sandbox holds no revocable model credential. */
1662
+ isSealed(): boolean;
1663
+ /** Collect caller-declared files or directories after the credential boundary. */
1664
+ collectArtifacts(paths: string[]): Promise<FileMap>;
1131
1665
  /**
1132
1666
  * Upload context files (to context/ folder)
1133
1667
  */
@@ -1136,6 +1670,24 @@ declare class Agent {
1136
1670
  * Upload files to working directory
1137
1671
  */
1138
1672
  uploadFiles(files: FileMap): Promise<void>;
1673
+ /**
1674
+ * Upload one LOCAL file into the sandbox by path, without holding its bytes
1675
+ * in the process heap.
1676
+ *
1677
+ * uploadFiles() takes a FileMap — the bytes as a value — so a caller
1678
+ * uploading a large artifact pays one full-size Buffer per concurrent
1679
+ * upload. This takes the local path instead: the provider streams it off
1680
+ * disk (or hands its own SDK the path), so peak memory is a chunk rather
1681
+ * than the file. Use it for anything big enough that N concurrent uploads
1682
+ * would matter; uploadFiles() stays the right call for small content.
1683
+ *
1684
+ * `sandboxPath` follows the uploadFiles() convention: absolute paths are
1685
+ * used as-is, relative paths resolve under the working directory.
1686
+ *
1687
+ * Providers that expose no cheaper path than a plain write fall back to
1688
+ * reading the file — correct everywhere, cheap where the provider helps.
1689
+ */
1690
+ uploadFileFromPath(sandboxPath: string, localPath: string): Promise<void>;
1139
1691
  /**
1140
1692
  * Get output files from output/ folder with optional schema validation
1141
1693
  *
@@ -1198,7 +1750,7 @@ declare class Agent {
1198
1750
  /**
1199
1751
  * Get current session tag.
1200
1752
  * Returns null if no active session (before sandbox creation or after kill()).
1201
- * Used for both observability (dashboard traces) and spend tracking (LiteLLM customer-id).
1753
+ * Used for both observability (dashboard traces) and spend tracking (gateway customer-id).
1202
1754
  */
1203
1755
  getSessionTag(): string | null;
1204
1756
  /**
@@ -1243,8 +1795,7 @@ declare class Agent {
1243
1795
  /**
1244
1796
  * Get cost breakdown for the current session (all runs).
1245
1797
  *
1246
- * Queries the dashboard API which proxies to LiteLLM spend logs.
1247
- * Cost data has ~60s latency due to gateway batch writes.
1798
+ * Cost data can lag live usage by about a minute.
1248
1799
  * Also works after kill() for the most recent session only.
1249
1800
  *
1250
1801
  * Requires gateway mode (EVOLVE_API_KEY).
@@ -1265,149 +1816,6 @@ declare class Agent {
1265
1816
  }): Promise<RunCost>;
1266
1817
  }
1267
1818
 
1268
- /**
1269
- * Claude JSONL → ACP-style events parser.
1270
- *
1271
- * Native schema source (@anthropic-ai/claude-agent-sdk):
1272
- * MANUS-API/KNOWLEDGE/claude-agent-sdk/cc_sdk_typescript.md
1273
- * (SDKMessage, SDKAssistantMessage, SDKPartialAssistantMessage, Tool Input/Output types)
1274
- *
1275
- * Conversion logic reference:
1276
- * MANUS-API/KNOWLEDGE/claude-code-acp/src/tools.ts
1277
- * (toolInfoFromToolUse, toolUpdateFromToolResult)
1278
- *
1279
- * ACP output schema:
1280
- * MANUS-API/KNOWLEDGE/acp-typescript-sdk/src/schema/types.gen.ts
1281
- */
1282
-
1283
- /**
1284
- * Create a Claude parser instance with its own isolated cache.
1285
- * Each Evolve instance should create its own parser for proper isolation.
1286
- */
1287
- declare function createClaudeParser(): (jsonLine: string) => OutputEvent[] | null;
1288
-
1289
- /**
1290
- * Codex JSONL → ACP-style events parser.
1291
- *
1292
- * Native schema: codex-rs/exec/src/exec_events.rs
1293
- * - ThreadEvent: thread.started, turn.started, turn.completed, item.started, item.updated, item.completed
1294
- * - ThreadItemDetails: AgentMessage, Reasoning, CommandExecution, FileChange, McpToolCall, WebSearch, TodoList, Error
1295
- *
1296
- * ACP output: acp-typescript-sdk/src/schema/types.gen.ts
1297
- * - SessionUpdate: agent_message_chunk, agent_thought_chunk, tool_call, tool_call_update, plan
1298
- *
1299
- * Event mapping:
1300
- * reasoning → agent_thought_chunk (exec_events.rs:134 ReasoningItem { text })
1301
- * agent_message → agent_message_chunk (exec_events.rs:129 AgentMessageItem { text })
1302
- * mcp_tool_call → tool_call/update (exec_events.rs:215 McpToolCallItem)
1303
- * command_execution → tool_call/update (exec_events.rs:151 CommandExecutionItem)
1304
- * file_change → tool_call (exec_events.rs:176 FileChangeItem)
1305
- * todo_list → plan (exec_events.rs:245 TodoListItem { items: TodoItem[] })
1306
- * web_search → tool_call (exec_events.rs:227 WebSearchItem { query })
1307
- */
1308
-
1309
- /**
1310
- * Create a Codex parser instance.
1311
- */
1312
- declare function createCodexParser(): (jsonLine: string) => OutputEvent[] | null;
1313
-
1314
- /**
1315
- * Droid exec parser.
1316
- *
1317
- * Supports the documented headless `--output-format stream-json` lines and the
1318
- * raw `stream-jsonrpc` notification envelope used by Droid's low-level SDK.
1319
- */
1320
-
1321
- declare function createDroidParser(): (jsonLine: string) => OutputEvent[] | null;
1322
-
1323
- /**
1324
- * Gemini JSONL → ACP-style events parser.
1325
- *
1326
- * Native schema (gemini --output-format stream-json):
1327
- * gemini-cli/packages/core/src/output/types.ts
1328
- *
1329
- * Gemini events (types.ts:29-36 JsonStreamEventType):
1330
- * - "init" → types.ts:43-47 InitEvent { session_id, model }
1331
- * - "message" → types.ts:49-54 MessageEvent { role, content, delta? }
1332
- * - "tool_use" → types.ts:56-61 ToolUseEvent { tool_name, tool_id, parameters }
1333
- * - "tool_result" → types.ts:63-72 ToolResultEvent { tool_id, status, output?, error? }
1334
- * - "error" → types.ts:74-78 ErrorEvent { severity, message }
1335
- * - "result" → types.ts:91-99 ResultEvent { status, error?, stats? }
1336
- *
1337
- * ACP output: acp-typescript-sdk/src/schema/types.gen.ts:2449-2464
1338
- */
1339
-
1340
- /**
1341
- * Create a Gemini parser instance.
1342
- */
1343
- declare function createGeminiParser(): (jsonLine: string) => OutputEvent[] | null;
1344
-
1345
- /**
1346
- * Qwen NDJSON → ACP-style events parser.
1347
- *
1348
- * Native schema: KNOWLEDGE/qwen-code/packages/sdk-typescript/src/types/protocol.ts
1349
- * ACP schema: KNOWLEDGE/acp-typescript-sdk/src/schema/types.gen.ts
1350
- *
1351
- * Qwen NDJSON message types (protocol.ts:428-433):
1352
- * - type: "assistant" → SDKAssistantMessage (protocol.ts:102-108)
1353
- * - type: "stream_event" → SDKPartialAssistantMessage (protocol.ts:225-231)
1354
- * - type: "user" → SDKUserMessage (protocol.ts:93-100)
1355
- * - type: "system" → SDKSystemMessage (skipped)
1356
- * - type: "result" → SDKResultMessage (skipped)
1357
- *
1358
- * ContentBlock types (protocol.ts:72-76):
1359
- * - TextBlock (protocol.ts:43-48): { type: 'text', text: string }
1360
- * - ThinkingBlock (protocol.ts:49-54): { type: 'thinking', thinking: string }
1361
- * - ToolUseBlock (protocol.ts:56-62): { type: 'tool_use', id, name, input }
1362
- * - ToolResultBlock (protocol.ts:64-70): { type: 'tool_result', tool_use_id, content?, is_error? }
1363
- *
1364
- * StreamEvent types (protocol.ts:218-223):
1365
- * - message_start, content_block_start, content_block_delta, content_block_stop, message_stop
1366
- */
1367
-
1368
- /**
1369
- * Stateless parser function (creates new parser per call).
1370
- * Use createQwenParser() for stateful streaming parsing.
1371
- *
1372
- * @param line - Single line of NDJSON from qwen CLI
1373
- * @returns Array of OutputEvent objects, or null if line couldn't be parsed
1374
- */
1375
- declare function parseQwenOutput(line: string): OutputEvent[] | null;
1376
-
1377
- /**
1378
- * Unified Parser Entry Point
1379
- *
1380
- * Routes NDJSON lines to the appropriate agent-specific parser.
1381
- * Simple line-based parsing - no buffering needed since CLIs output complete JSON per line.
1382
- */
1383
-
1384
- /** Parser function type */
1385
- type AgentParser = (jsonLine: string) => OutputEvent[] | null;
1386
- /**
1387
- * Create a parser instance for the given agent type.
1388
- * Each Evolve instance should create its own parser for proper isolation.
1389
- *
1390
- * @param agentType - The agent type to create a parser for
1391
- * @returns Parser function that takes NDJSON lines and returns OutputEvents
1392
- */
1393
- declare function createAgentParser(agentType: AgentType): AgentParser;
1394
- /**
1395
- * Parse a single NDJSON line from any agent (creates new parser per call - use createAgentParser for efficiency)
1396
- *
1397
- * @param agentType - The agent type to parse for
1398
- * @param line - Single line of NDJSON output
1399
- * @returns Array of OutputEvent objects, or null if line couldn't be parsed
1400
- */
1401
- declare function parseNdjsonLine(agentType: AgentType, line: string): OutputEvent[] | null;
1402
- /**
1403
- * Parse multiple NDJSON lines (convenience wrapper)
1404
- *
1405
- * @param agentType - The agent type to parse for
1406
- * @param output - Multi-line NDJSON output
1407
- * @returns Array of all parsed OutputEvent objects
1408
- */
1409
- declare function parseNdjsonOutput(agentType: AgentType, output: string): OutputEvent[];
1410
-
1411
1819
  declare const BROWSER_LOGIN_MCP_SERVER_NAME = "browser-login";
1412
1820
  interface BrowserCredentialMetadata {
1413
1821
  id: string;
@@ -1489,52 +1897,6 @@ declare class BrowserProfilesClient {
1489
1897
  }
1490
1898
  declare function browserProfiles(config?: BrowserProfilesClientConfig): BrowserProfilesClient;
1491
1899
 
1492
- /**
1493
- * Evolve events
1494
- *
1495
- * Runtime streams:
1496
- * - stdout: Raw NDJSON lines
1497
- * - stderr: Process stderr
1498
- * - content: Parsed OutputEvent
1499
- * - lifecycle: Sandbox/agent lifecycle transitions
1500
- */
1501
- interface EvolveEvents {
1502
- stdout: (chunk: string) => void;
1503
- stderr: (chunk: string) => void;
1504
- content: (event: OutputEvent) => void;
1505
- lifecycle: (event: LifecycleEvent) => void;
1506
- }
1507
- interface EvolveConfig {
1508
- agent?: AgentConfig;
1509
- sandbox?: SandboxProvider;
1510
- workingDirectory?: string;
1511
- workspaceMode?: WorkspaceMode;
1512
- secrets?: Record<string, string>;
1513
- sandboxId?: string;
1514
- systemPrompt?: string;
1515
- context?: FileMap;
1516
- files?: FileMap;
1517
- mcpServers?: Record<string, McpServerConfig>;
1518
- /** Browser automation provider to enable explicitly */
1519
- browser?: BrowserConfig;
1520
- /** Browser login MCP setup for managed remote agent-browser runs */
1521
- browserCredentials?: BrowserCredentialsConfig;
1522
- /** Agent plugins/extensions to install before first run */
1523
- plugins?: AgentPluginConfig[];
1524
- /** Skills to enable (e.g., ["pdf", "dev-browser"]) */
1525
- skills?: SkillName[];
1526
- /** Schema for structured output (Zod or JSON Schema, auto-detected) */
1527
- schema?: z.ZodType<unknown> | JsonSchema;
1528
- /** Validation options for JSON Schema (ignored for Zod) */
1529
- schemaOptions?: SchemaValidationOptions;
1530
- sessionTagPrefix?: string;
1531
- /** Observability metadata for trace grouping (generic key-value, domain-agnostic) */
1532
- observability?: Record<string, unknown>;
1533
- /** Managed integrations config */
1534
- integrations?: IntegrationsSetup;
1535
- /** Storage configuration for checkpointing */
1536
- storage?: StorageConfig;
1537
- }
1538
1900
  /**
1539
1901
  * Evolve orchestrator with builder pattern
1540
1902
  *
@@ -1568,6 +1930,11 @@ declare class Evolve extends EventEmitter {
1568
1930
  * Configure sandbox provider
1569
1931
  */
1570
1932
  withSandbox(provider?: SandboxProvider): this;
1933
+ /**
1934
+ * Configure provider-neutral options used whenever Evolve creates a sandbox.
1935
+ * Evolve-owned runtime variables override conflicting env entries.
1936
+ */
1937
+ withSandboxCreateOptions(options: SandboxCreateOptions): this;
1571
1938
  /**
1572
1939
  * Set working directory path
1573
1940
  */
@@ -1576,12 +1943,19 @@ declare class Evolve extends EventEmitter {
1576
1943
  * Set workspace mode
1577
1944
  * - "knowledge": Creates context/, scripts/, temp/, output/ folders
1578
1945
  * - "swe": Same as knowledge + repo/ folder for code repositories
1946
+ * - "task": Leaves the task-owned working directory untouched
1579
1947
  */
1580
1948
  withWorkspaceMode(mode: WorkspaceMode): this;
1581
1949
  /**
1582
1950
  * Add environment secrets
1583
1951
  */
1584
1952
  withSecrets(secrets: Record<string, string>): this;
1953
+ /**
1954
+ * Attach Dashboard-stored managed secrets to the sandbox.
1955
+ *
1956
+ * The sandbox receives opaque env var values; raw secret values stay server-side.
1957
+ */
1958
+ withManagedSecrets(secrets: ManagedSecretRef[]): this;
1585
1959
  /**
1586
1960
  * Connect to existing session
1587
1961
  */
@@ -1710,6 +2084,8 @@ declare class Evolve extends EventEmitter {
1710
2084
  static browserCredentials: typeof browserCredentials;
1711
2085
  /** Static browser profile client for listing and deleting reusable browser profiles. */
1712
2086
  static browserProfiles: typeof browserProfiles;
2087
+ /** Static managed secrets client for listing Dashboard-stored secret metadata. */
2088
+ static managedSecrets: typeof managedSecrets;
1713
2089
  /**
1714
2090
  * Initialize agent on first use
1715
2091
  */
@@ -1738,6 +2114,21 @@ declare class Evolve extends EventEmitter {
1738
2114
  timeoutMs?: number;
1739
2115
  background?: boolean;
1740
2116
  }): Promise<AgentResponse>;
2117
+ /**
2118
+ * Create and fully initialize the configured sandbox without starting an
2119
+ * agent command. Durable orchestrators use this to persist the sandbox ID
2120
+ * before handing execution to the agent.
2121
+ */
2122
+ prepareSandbox(): Promise<string>;
2123
+ /**
2124
+ * Irreversibly revoke Evolve-managed runtime credentials for this sandbox.
2125
+ * Agent runs are disabled afterward; credential-free commands remain available.
2126
+ */
2127
+ sealCredentials(): Promise<void>;
2128
+ /** Whether sealCredentials() has completed for the active sandbox. */
2129
+ isSealed(): boolean;
2130
+ /** Collect files or directories from the working directory after credentials are sealed. */
2131
+ collectArtifacts(paths: string[]): Promise<FileMap>;
1741
2132
  /**
1742
2133
  * Interrupt active process without killing sandbox.
1743
2134
  */
@@ -1750,6 +2141,15 @@ declare class Evolve extends EventEmitter {
1750
2141
  * Upload files to workspace (runtime - immediate upload)
1751
2142
  */
1752
2143
  uploadFiles(files: FileMap): Promise<void>;
2144
+ /**
2145
+ * Upload one LOCAL file into the sandbox by path, streaming rather than
2146
+ * buffering it (runtime - immediate upload).
2147
+ *
2148
+ * The memory-bounded counterpart to uploadFiles(): use it when the file is
2149
+ * large enough that holding it in the heap — once per concurrent upload —
2150
+ * would matter.
2151
+ */
2152
+ uploadFileFromPath(sandboxPath: string, localPath: string): Promise<void>;
1753
2153
  /**
1754
2154
  * Get output files from output/ folder with optional schema validation
1755
2155
  *
@@ -1941,7 +2341,7 @@ interface SwarmConfig {
1941
2341
  /** Per-worker timeout in ms (default: 1 hour) */
1942
2342
  timeoutMs?: number;
1943
2343
  /** Workspace mode (default: SDK default 'knowledge') */
1944
- workspaceMode?: WorkspaceMode;
2344
+ workspaceMode?: Exclude<WorkspaceMode, "task">;
1945
2345
  /** Default retry configuration for all operations (per-operation config takes precedence) */
1946
2346
  retry?: RetryConfig;
1947
2347
  /** Default MCP servers for all operations (per-operation config takes precedence) */
@@ -2685,176 +3085,179 @@ declare class TerminalPipeline<T> extends Pipeline<T> {
2685
3085
  }
2686
3086
 
2687
3087
  /**
2688
- * Agent Registry
3088
+ * Sandbox providers the Dashboard runs on the customer's behalf.
2689
3089
  *
2690
- * Single source of truth for agent-specific behavior.
2691
- * All differences between agents are data, not code.
3090
+ * Managed mode means the customer holds one Evolve API key and no provider
3091
+ * credential at all: the Dashboard authenticates the key, records ownership,
3092
+ * and makes the provider call with platform credentials. Each provider has its
3093
+ * own door under /api/managed/<provider>.
3094
+ */
3095
+ declare const MANAGED_SANDBOX_PROVIDERS: readonly ["e2b", "daytona", "modal"];
3096
+ type ManagedSandboxProviderName = (typeof MANAGED_SANDBOX_PROVIDERS)[number];
3097
+
3098
+ /**
3099
+ * Sandbox Provider Resolution
2692
3100
  *
2693
- * Evidence: sdk-rewrite-v3.md Agent Registry section
3101
+ * Resolves default sandbox provider from environment.
3102
+ * Supports E2B, Daytona, and Modal providers.
2694
3103
  */
2695
3104
 
2696
- /** Model configuration */
2697
- interface ModelInfo {
2698
- /** Model alias (short name used with --model) */
2699
- alias: string;
2700
- /** Full model ID */
2701
- modelId: string;
2702
- /** What this model is best for */
2703
- description: string;
2704
- }
2705
- /** MCP configuration for an agent */
2706
- interface McpConfigInfo {
2707
- /** Settings directory (e.g., "~/.claude") */
2708
- settingsDir: string;
2709
- /** Config filename (e.g., "settings.json" or "config.toml") */
2710
- filename: string;
2711
- /** Config format */
2712
- format: "json" | "toml";
2713
- /** Whether to use workingDir for project-level config (Claude only) */
2714
- projectConfig?: boolean;
2715
- }
2716
- /** Options for building agent commands */
2717
- interface BuildCommandOptions {
2718
- prompt: string;
2719
- model: string;
2720
- isResume: boolean;
2721
- sessionId?: string;
2722
- reasoningEffort?: string;
2723
- isDirectMode?: boolean;
2724
- /** Skills enabled for this run */
2725
- skills?: string[];
2726
- }
2727
- interface AgentRegistryEntry {
2728
- /** Sandbox image/template identifier (provider maps to its own concept) */
2729
- image: string;
2730
- /** Environment variable name for API key */
2731
- apiKeyEnv: string;
2732
- /** Environment variable name for OAuth (file path or token depending on agent) */
2733
- oauthEnv?: string;
2734
- /** OAuth credentials filename (e.g., "auth.json" for Codex, "oauth_creds.json" for Gemini) */
2735
- oauthFileName?: string;
2736
- /** Environment variable to set when OAuth is active (e.g., GOOGLE_GENAI_USE_GCA=true for Gemini) */
2737
- oauthActivationEnv?: {
2738
- key: string;
2739
- value: string;
2740
- };
2741
- /** Environment variable name for base URL, if this CLI supports one */
2742
- baseUrlEnv?: string;
2743
- /** Default model alias */
2744
- defaultModel: string;
2745
- /** Available models for this agent */
2746
- models: ModelInfo[];
2747
- /** System prompt filename (e.g., "CLAUDE.md") */
2748
- systemPromptFile: string;
2749
- /** MCP configuration */
2750
- mcpConfig: McpConfigInfo;
2751
- /** Build the CLI command for this agent */
2752
- buildCommand: (opts: BuildCommandOptions) => string;
2753
- /** Extra setup step (e.g., codex login) */
2754
- setupCommand?: string;
2755
- /** Gateway path prefix for CLIs that use a provider-native passthrough endpoint */
2756
- gatewayPath?: string;
2757
- /** Default base URL for direct mode (only needed if provider requires specific endpoint, e.g., Qwen → Dashscope) */
2758
- defaultBaseUrl?: string;
2759
- /** Available beta headers for this agent (for reference) */
2760
- availableBetas?: Record<string, string>;
2761
- /** Skills configuration for this agent */
2762
- skillsConfig: SkillsConfig;
2763
- /** Multi-provider env mapping: model prefix → keyEnv (for CLIs like OpenCode that resolve provider from model string) */
2764
- providerEnvMap?: Record<string, {
2765
- keyEnv: string;
2766
- }>;
2767
- /** Env var for inline config (e.g., OPENCODE_CONFIG_CONTENT) — used in gateway mode to set provider base URLs */
2768
- gatewayConfigEnv?: string;
2769
- /** Gateway-only model aliases for CLIs whose native model IDs differ from LiteLLM route names */
2770
- gatewayModelAliases?: Record<string, string>;
2771
- /** Direct-mode model aliases for CLIs whose public model names differ from CLI-native model IDs */
2772
- directModelAliases?: Record<string, string>;
2773
- /** Do not set provider API key env in gateway mode (used when routing via generated settings instead) */
2774
- skipApiKeyEnvInGateway?: boolean;
2775
- /** Dedicated Droid settings file for Evolve gateway custom model routing */
2776
- droidGatewaySettings?: {
2777
- settingsPath: string;
2778
- displayName: string;
2779
- provider: "generic-chat-completion-api" | "openai" | "anthropic";
2780
- maxOutputTokens?: number;
2781
- };
2782
- /** Environment variable that CLI reads for custom outbound HTTP headers */
2783
- customHeadersEnv?: string;
2784
- /** Format for custom headers env var: "newline" (Claude) or "comma" (Gemini). Default: "newline" */
2785
- customHeadersFormat?: "newline" | "comma";
2786
- /**
2787
- * Per-env-var spend tracking for CLIs that support env_http_headers in config
2788
- * (e.g., Codex TOML). Maps LiteLLM header names to env var names that the CLI
2789
- * reads at request time. Alternative to customHeadersEnv for agents without a
2790
- * single custom-headers env var.
2791
- */
2792
- spendTrackingEnvs?: {
2793
- /** Env var name for x-litellm-customer-id value */
2794
- sessionTagEnv: string;
2795
- /** Env var name for x-litellm-tags value */
2796
- runTagEnv: string;
2797
- };
2798
- /**
2799
- * Config-file-based spend tracking for CLIs that read custom headers from a
2800
- * JSON settings file (e.g., Qwen settings.json → model.generationConfig.customHeaders).
2801
- * The SDK writes headers to this file before each run.
2802
- * Source-verified: Qwen reads customHeaders from settings.json, not env vars.
2803
- */
2804
- spendTrackingJsonConfig?: {
2805
- /** JSON path to the customHeaders object (dot-separated) */
2806
- headersPath: string;
2807
- };
2808
- /**
2809
- * TOML provider-based spend tracking for CLIs that read custom_headers from a
2810
- * provider entry in config.toml (e.g., Kimi Code).
2811
- * The SDK writes a provider+model entry with custom_headers before each run.
2812
- * Source-verified: Kimi Code reads custom_headers from
2813
- * providers[name].custom_headers in ~/.kimi-code/config.toml.
2814
- */
2815
- spendTrackingTomlProvider?: {
2816
- /** Config file path (e.g., "~/.kimi-code/config.toml") */
2817
- configPath: string;
2818
- /** Provider name in config (e.g., "evolve-gateway") */
2819
- providerName: string;
2820
- /** Model entry name (e.g., "evolve-default") */
2821
- modelName: string;
2822
- /** Max context size for the model entry */
2823
- maxContextSize: number;
2824
- };
2825
- /** Additional directories to include in checkpoint tar (beyond mcpConfig.settingsDir).
2826
- * Used for agents like OpenCode that spread state across XDG directories. */
2827
- checkpointDirs?: string[];
2828
- /** Additional relative paths to exclude from checkpoint tar. */
2829
- checkpointExcludes?: string[];
2830
- }
2831
3105
  /**
2832
- * Registry of all supported agents.
3106
+ * A sandbox the platform runs for you.
2833
3107
  *
2834
- * Each agent defines a buildCommand function that constructs the CLI command.
2835
- * This is type-safe and handles conditional logic cleanly.
3108
+ * ```ts
3109
+ * const kit = new Evolve()
3110
+ * .withAgent({ agentType: "claude" })
3111
+ * .withSandbox(await managedSandbox("daytona"));
3112
+ * ```
3113
+ *
3114
+ * Requires an Evolve API key and no provider credential of any kind. Omit the
3115
+ * provider to take the platform default (E2B).
2836
3116
  */
2837
- declare const AGENT_REGISTRY: Record<AgentType, AgentRegistryEntry>;
3117
+ declare function managedSandbox(provider?: ManagedSandboxProviderName, evolveKey?: string): Promise<SandboxProvider>;
3118
+
2838
3119
  /**
2839
- * Get registry entry for an agent type
3120
+ * Claude JSONL → ACP-style events parser.
3121
+ *
3122
+ * Native schema source (@anthropic-ai/claude-agent-sdk):
3123
+ * MANUS-API/KNOWLEDGE/claude-agent-sdk/cc_sdk_typescript.md
3124
+ * (SDKMessage, SDKAssistantMessage, SDKPartialAssistantMessage, Tool Input/Output types)
3125
+ *
3126
+ * Conversion logic reference:
3127
+ * MANUS-API/KNOWLEDGE/claude-code-acp/src/tools.ts
3128
+ * (toolInfoFromToolUse, toolUpdateFromToolResult)
3129
+ *
3130
+ * ACP output schema:
3131
+ * MANUS-API/KNOWLEDGE/acp-typescript-sdk/src/schema/types.gen.ts
2840
3132
  */
2841
- declare function getAgentConfig(agentType: AgentType): AgentRegistryEntry;
3133
+
2842
3134
  /**
2843
- * Check if an agent type is valid
3135
+ * Create a Claude parser instance with its own isolated cache.
3136
+ * Each Evolve instance should create its own parser for proper isolation.
2844
3137
  */
2845
- declare function isValidAgentType(type: string): type is AgentType;
3138
+ declare function createClaudeParser(): (jsonLine: string) => OutputEvent[] | null;
3139
+
2846
3140
  /**
2847
- * Expand path with ~ to /home/user
3141
+ * Codex JSONL → ACP-style events parser.
3142
+ *
3143
+ * Native schema: codex-rs/exec/src/exec_events.rs
3144
+ * - ThreadEvent: thread.started, turn.started, turn.completed, item.started, item.updated, item.completed
3145
+ * - ThreadItemDetails: AgentMessage, Reasoning, CommandExecution, FileChange, McpToolCall, WebSearch, TodoList, Error
3146
+ *
3147
+ * ACP output: acp-typescript-sdk/src/schema/types.gen.ts
3148
+ * - SessionUpdate: agent_message_chunk, agent_thought_chunk, tool_call, tool_call_update, plan
3149
+ *
3150
+ * Event mapping:
3151
+ * reasoning → agent_thought_chunk (exec_events.rs:134 ReasoningItem { text })
3152
+ * agent_message → agent_message_chunk (exec_events.rs:129 AgentMessageItem { text })
3153
+ * mcp_tool_call → tool_call/update (exec_events.rs:215 McpToolCallItem)
3154
+ * command_execution → tool_call/update (exec_events.rs:151 CommandExecutionItem)
3155
+ * file_change → tool_call (exec_events.rs:176 FileChangeItem)
3156
+ * todo_list → plan (exec_events.rs:245 TodoListItem { items: TodoItem[] })
3157
+ * web_search → tool_call (exec_events.rs:227 WebSearchItem { query })
2848
3158
  */
2849
- declare function expandPath(path: string): string;
3159
+
2850
3160
  /**
2851
- * Get MCP settings path for an agent
3161
+ * Create a Codex parser instance.
2852
3162
  */
2853
- declare function getMcpSettingsPath(agentType: AgentType): string;
3163
+ declare function createCodexParser(): (jsonLine: string) => OutputEvent[] | null;
3164
+
2854
3165
  /**
2855
- * Get MCP settings directory for an agent
3166
+ * Droid exec parser.
3167
+ *
3168
+ * Supports the documented headless `--output-format stream-json` lines and the
3169
+ * raw `stream-jsonrpc` notification envelope used by Droid's low-level SDK.
3170
+ */
3171
+
3172
+ declare function createDroidParser(): (jsonLine: string) => OutputEvent[] | null;
3173
+
3174
+ /**
3175
+ * Gemini JSONL → ACP-style events parser.
3176
+ *
3177
+ * Native schema (gemini --output-format stream-json):
3178
+ * gemini-cli/packages/core/src/output/types.ts
3179
+ *
3180
+ * Gemini events (types.ts:29-36 JsonStreamEventType):
3181
+ * - "init" → types.ts:43-47 InitEvent { session_id, model }
3182
+ * - "message" → types.ts:49-54 MessageEvent { role, content, delta? }
3183
+ * - "tool_use" → types.ts:56-61 ToolUseEvent { tool_name, tool_id, parameters }
3184
+ * - "tool_result" → types.ts:63-72 ToolResultEvent { tool_id, status, output?, error? }
3185
+ * - "error" → types.ts:74-78 ErrorEvent { severity, message }
3186
+ * - "result" → types.ts:91-99 ResultEvent { status, error?, stats? }
3187
+ *
3188
+ * ACP output: acp-typescript-sdk/src/schema/types.gen.ts:2449-2464
3189
+ */
3190
+
3191
+ /**
3192
+ * Create a Gemini parser instance.
3193
+ */
3194
+ declare function createGeminiParser(): (jsonLine: string) => OutputEvent[] | null;
3195
+
3196
+ /**
3197
+ * Qwen NDJSON → ACP-style events parser.
3198
+ *
3199
+ * Native schema: KNOWLEDGE/qwen-code/packages/sdk-typescript/src/types/protocol.ts
3200
+ * ACP schema: KNOWLEDGE/acp-typescript-sdk/src/schema/types.gen.ts
3201
+ *
3202
+ * Qwen NDJSON message types (protocol.ts:428-433):
3203
+ * - type: "assistant" → SDKAssistantMessage (protocol.ts:102-108)
3204
+ * - type: "stream_event" → SDKPartialAssistantMessage (protocol.ts:225-231)
3205
+ * - type: "user" → SDKUserMessage (protocol.ts:93-100)
3206
+ * - type: "system" → SDKSystemMessage (skipped)
3207
+ * - type: "result" → SDKResultMessage (skipped)
3208
+ *
3209
+ * ContentBlock types (protocol.ts:72-76):
3210
+ * - TextBlock (protocol.ts:43-48): { type: 'text', text: string }
3211
+ * - ThinkingBlock (protocol.ts:49-54): { type: 'thinking', thinking: string }
3212
+ * - ToolUseBlock (protocol.ts:56-62): { type: 'tool_use', id, name, input }
3213
+ * - ToolResultBlock (protocol.ts:64-70): { type: 'tool_result', tool_use_id, content?, is_error? }
3214
+ *
3215
+ * StreamEvent types (protocol.ts:218-223):
3216
+ * - message_start, content_block_start, content_block_delta, content_block_stop, message_stop
2856
3217
  */
2857
- declare function getMcpSettingsDir(agentType: AgentType): string;
3218
+
3219
+ /**
3220
+ * Stateless parser function (creates new parser per call).
3221
+ * Use createQwenParser() for stateful streaming parsing.
3222
+ *
3223
+ * @param line - Single line of NDJSON from qwen CLI
3224
+ * @returns Array of OutputEvent objects, or null if line couldn't be parsed
3225
+ */
3226
+ declare function parseQwenOutput(line: string): OutputEvent[] | null;
3227
+
3228
+ /**
3229
+ * Unified Parser Entry Point
3230
+ *
3231
+ * Routes NDJSON lines to the appropriate agent-specific parser.
3232
+ * Simple line-based parsing - no buffering needed since CLIs output complete JSON per line.
3233
+ */
3234
+
3235
+ /** Parser function type */
3236
+ type AgentParser = (jsonLine: string) => OutputEvent[] | null;
3237
+ /**
3238
+ * Create a parser instance for the given agent type.
3239
+ * Each Evolve instance should create its own parser for proper isolation.
3240
+ *
3241
+ * @param agentType - The agent type to create a parser for
3242
+ * @returns Parser function that takes NDJSON lines and returns OutputEvents
3243
+ */
3244
+ declare function createAgentParser(agentType: AgentType): AgentParser;
3245
+ /**
3246
+ * Parse a single NDJSON line from any agent (creates new parser per call - use createAgentParser for efficiency)
3247
+ *
3248
+ * @param agentType - The agent type to parse for
3249
+ * @param line - Single line of NDJSON output
3250
+ * @returns Array of OutputEvent objects, or null if line couldn't be parsed
3251
+ */
3252
+ declare function parseNdjsonLine(agentType: AgentType, line: string): OutputEvent[] | null;
3253
+ /**
3254
+ * Parse multiple NDJSON lines (convenience wrapper)
3255
+ *
3256
+ * @param agentType - The agent type to parse for
3257
+ * @param output - Multi-line NDJSON output
3258
+ * @returns Array of all parsed OutputEvent objects
3259
+ */
3260
+ declare function parseNdjsonOutput(agentType: AgentType, output: string): OutputEvent[];
2858
3261
 
2859
3262
  /**
2860
3263
  * MCP JSON Configuration Writer
@@ -2876,11 +3279,11 @@ declare function getMcpSettingsDir(agentType: AgentType): string;
2876
3279
  * 1. ${workingDir}/.mcp.json - project-level MCP servers
2877
3280
  * 2. ~/.claude/settings.json - enable project MCP servers
2878
3281
  */
2879
- declare function writeClaudeMcpConfig(sandbox: SandboxInstance, workingDir: string, servers: Record<string, McpServerConfig>): Promise<void>;
3282
+ declare function writeClaudeMcpConfig(sandbox: SandboxInstance, workingDir: string, servers: Record<string, McpServerConfig>, homeDir?: string): Promise<void>;
2880
3283
  /** Write MCP config for Gemini agent */
2881
- declare function writeGeminiMcpConfig(sandbox: SandboxInstance, servers: Record<string, McpServerConfig>): Promise<void>;
3284
+ declare function writeGeminiMcpConfig(sandbox: SandboxInstance, servers: Record<string, McpServerConfig>, homeDir?: string): Promise<void>;
2882
3285
  /** Write MCP config for Qwen agent */
2883
- declare function writeQwenMcpConfig(sandbox: SandboxInstance, servers: Record<string, McpServerConfig>): Promise<void>;
3286
+ declare function writeQwenMcpConfig(sandbox: SandboxInstance, servers: Record<string, McpServerConfig>, homeDir?: string): Promise<void>;
2884
3287
  /**
2885
3288
  * Write MCP config for Droid agent
2886
3289
  *
@@ -2903,7 +3306,7 @@ interface DroidGatewaySettingsConfig {
2903
3306
  * The command passes this file with `droid --settings`, so it does not alter the
2904
3307
  * user's normal ~/.factory/settings.json inside the sandbox.
2905
3308
  */
2906
- declare function writeDroidGatewaySettings(sandbox: SandboxInstance, config: DroidGatewaySettingsConfig, headers: Record<string, string>): Promise<void>;
3309
+ declare function writeDroidGatewaySettings(sandbox: SandboxInstance, config: DroidGatewaySettingsConfig, headers: Record<string, string>, homeDir?: string): Promise<void>;
2907
3310
 
2908
3311
  /**
2909
3312
  * MCP TOML Configuration Writer
@@ -2918,7 +3321,7 @@ declare function writeDroidGatewaySettings(sandbox: SandboxInstance, config: Dro
2918
3321
  * Codex stores MCP config in ~/.codex/config.toml using TOML format.
2919
3322
  * Format: [mcp_servers.server_name] sections
2920
3323
  */
2921
- declare function writeCodexMcpConfig(sandbox: SandboxInstance, servers: Record<string, McpServerConfig>): Promise<void>;
3324
+ declare function writeCodexMcpConfig(sandbox: SandboxInstance, servers: Record<string, McpServerConfig>, homeDir?: string): Promise<void>;
2922
3325
 
2923
3326
  /**
2924
3327
  * MCP Configuration Module
@@ -2938,7 +3341,7 @@ declare function writeCodexMcpConfig(sandbox: SandboxInstance, servers: Record<s
2938
3341
  * - Droid: JSON to ${workingDir}/.factory/mcp.json
2939
3342
  * - OpenCode: JSON to ${workingDir}/opencode.json (mcp key)
2940
3343
  */
2941
- declare function writeMcpConfig(agentType: AgentType, sandbox: SandboxInstance, workingDir: string, servers: Record<string, McpServerConfig>): Promise<void>;
3344
+ declare function writeMcpConfig(agentType: AgentType, sandbox: SandboxInstance, workingDir: string, servers: Record<string, McpServerConfig>, homeDir?: string): Promise<void>;
2942
3345
 
2943
3346
  /**
2944
3347
  * Prompt Templates
@@ -3086,8 +3489,6 @@ declare function saveLocalDir(localPath: string, files: FileMap): void;
3086
3489
  *
3087
3490
  * Provides durable persistence for agent workspaces beyond sandbox lifetime.
3088
3491
  * Supports BYOK (user's S3 bucket) and Gateway (Evolve-managed) modes.
3089
- *
3090
- * Evidence: storage-checkpointing plan v2.2
3091
3492
  */
3092
3493
 
3093
3494
  /**
@@ -3206,4 +3607,225 @@ interface SessionsClient {
3206
3607
  */
3207
3608
  declare function sessions(config?: SessionsConfig): SessionsClient;
3208
3609
 
3209
- export { AGENT_REGISTRY, AGENT_TYPES, type ActionbookBrowserConfig, Agent, type AgentBrowserConfig, type AgentConfig, type AgentOptions, type AgentOverride, type AgentParser, type AgentPluginConfig, type AgentRegistryEntry, type AgentResponse, type AgentRuntimeState, type AgentType, BROWSER_ACTIONBOOK_PROMPT, BROWSER_LOGIN_MCP_SERVER_NAME, type BaseMeta, type BestOfConfig, type BestOfParams, type BestOfResult, type BrowserConfig, type BrowserCredentialCreateInput, type BrowserCredentialDeleteInput, type BrowserCredentialListOptions, type BrowserCredentialMetadata, type BrowserCredentialScopeEntry, BrowserCredentialsClient, type BrowserCredentialsClientConfig, type BrowserCredentialsConfig, type BrowserProfileDeleteInput, type BrowserProfileMetadata, BrowserProfilesClient, type BrowserProfilesClientConfig, type BrowserProvider, type BrowserReplay, type BrowserReplayOptions, type BrowserRuntimeInfo, type CandidateCompleteEvent, type CheckpointInfo, type CodexAgentPluginConfig, type DefaultBrowserConfig, type DownloadCheckpointOptions, type DownloadFilesOptions, type DownloadSessionOptions, type EmitOption, type EventHandler, type EventName, Evolve, type EvolveConfig, type EvolveEvents, type ExecuteCommandOptions, type FileMap, type FilterConfig, type FilterParams, type GeminiAgentPluginConfig, type GetEventsOptions, type IndexedMeta, type IntegrationAccount, type IntegrationAccountDeleteParams, type IntegrationAccountDeleteResult, type IntegrationAccountListParams, type IntegrationAccountUpdateParams, type IntegrationAccountUpdateResult, type IntegrationAuthParams, type IntegrationAuthResult, type IntegrationToolsFilter, type IntegrationsConfig, type IntegrationsSetup, type ItemInput, type ItemRetryEvent, JUDGE_PROMPT, type JsonSchema, type JudgeCompleteEvent, type JudgeDecision, type JudgeMeta, type LifecycleEvent, type LifecycleReason, type ListSessionsOptions, type ManagedBrowserProvider, type MapConfig, type MapParams, type MarketplaceAgentPluginConfig, type McpConfigInfo, type McpServerConfig, type ModelInfo, type OnCandidateCompleteCallback, type OnItemRetryCallback, type OnJudgeCompleteCallback, type OnVerifierCompleteCallback, type OnWorkerCompleteCallback, type OperationType, type OutputEvent, type OutputResult, Pipeline, type PipelineContext, type PipelineEventMap, type PipelineEvents, type PipelineResult, type ProcessInfo, type Prompt, type PromptFn, RETRY_FEEDBACK_PROMPT, type ReasoningEffort, type ReduceConfig, type ReduceMeta, type ReduceParams, type ReduceResult, type ResolvedStorageConfig, type RetryConfig, type RunCost, type RunOptions, SCHEMA_PROMPT, SWARM_RESULT_BRAND, SYSTEM_PROMPT, type SandboxCommandHandle, type SandboxCommandResult, type SandboxCommands, type SandboxCreateOptions, type SandboxFiles, type SandboxInstance, type SandboxLifecycleState, type SandboxProvider, type SandboxRunOptions, type SandboxSpawnOptions, type SchemaValidationOptions, Semaphore, type SessionCost, type SessionEvent, type SessionInfo, type SessionPage, type SessionStatus, type SessionsClient, type SessionsConfig, type SkillName, type SkillsConfig, type StepCompleteEvent, type StepErrorEvent, type StepEvent, type StepResult, type StepStartEvent, type StorageClient, type StorageConfig, type StreamCallbacks, Swarm, type SwarmConfig, type SwarmResult, SwarmResultList, TerminalPipeline, VALIDATION_PRESETS, VERIFY_PROMPT, type ValidationMode, type VerifierCompleteEvent, type VerifyConfig, type VerifyDecision, type VerifyInfo, type VerifyMeta, WORKSPACE_PROMPT, WORKSPACE_SWE_PROMPT, type WorkerCompleteEvent, type WorkspaceMode, applyTemplate, browserCredentials, browserProfiles, buildWorkerSystemPrompt, createAgentParser, createClaudeParser, createCodexParser, createDroidParser, createGeminiParser, executeWithRetry, expandPath, getAgentConfig, getMcpSettingsDir, getMcpSettingsPath, isValidAgentType, isZodSchema, jsonSchemaToString, parseNdjsonLine, parseNdjsonOutput, parseQwenOutput, readLocalDir, resolveStorageConfig, saveLocalDir, sessions, storage, writeClaudeMcpConfig, writeCodexMcpConfig, writeDroidGatewaySettings, writeDroidMcpConfig, writeGeminiMcpConfig, writeMcpConfig, writeQwenMcpConfig, zodSchemaToJson };
3610
+ /**
3611
+ * A typed failure from the hosted evals API.
3612
+ *
3613
+ * `message` is the server's own product sentence and `code` is the stable
3614
+ * machine-readable identifier, so callers branch on codes and never on English.
3615
+ * `code` is typed as the closed HostedErrorCode union (widened to string for
3616
+ * forward compatibility with a newer server), which is what makes a typo like
3617
+ * `insufficient_creidts` a compile error instead of a branch that never runs.
3618
+ *
3619
+ * `param` and `details` are the machine-readable half of the refusal:
3620
+ *
3621
+ * catch (err) {
3622
+ * if (err instanceof EvolveApiError && err.code === "provider_unsupported") {
3623
+ * // every refused task WITH its reason — not a sentence to regex
3624
+ * const refused = err.details?.refusedTasks as { taskKey: string }[];
3625
+ * }
3626
+ * }
3627
+ *
3628
+ * The server truncates the MESSAGE when a list is long and never truncates
3629
+ * `details`, so the data is always complete even when the sentence says
3630
+ * "and 8 more".
3631
+ */
3632
+ declare class EvolveApiError extends Error {
3633
+ /** HTTP status of the failed response */
3634
+ readonly status: number;
3635
+ /** Stable snake_case error code from the API ("unknown_error" when absent) */
3636
+ readonly code: HostedErrorCode | "unknown_error" | (string & {});
3637
+ /**
3638
+ * The input field this refusal is about — a body path ("agents[0].harness"),
3639
+ * a query parameter ("limit"), or a multipart part name ("runCommand").
3640
+ * Undefined when the failure is not about a particular field.
3641
+ */
3642
+ readonly param?: string;
3643
+ /** The complete machine-readable data behind the message. Never truncated. */
3644
+ readonly details?: Record<string, unknown>;
3645
+ /**
3646
+ * Seconds to wait before retrying (429/503). Read from the body first and the
3647
+ * Retry-After header second, because a browser fetch cannot always see the
3648
+ * header on a cross-origin response.
3649
+ */
3650
+ readonly retryAfterSec?: number;
3651
+ /** Server-side id for this failure; the string to quote in a support thread. */
3652
+ readonly requestId?: string;
3653
+ constructor(status: number, code: string, message: string, extra?: {
3654
+ param?: string;
3655
+ details?: Record<string, unknown>;
3656
+ retryAfterSec?: number;
3657
+ requestId?: string;
3658
+ });
3659
+ /** True when this code is one this SDK version knows about. */
3660
+ isKnownCode(): boolean;
3661
+ }
3662
+ /**
3663
+ * Thrown by benchmarks().getActive() when the named benchmark exists but has no
3664
+ * active version, so there is no runnable version to resolve. Use get() to
3665
+ * inspect a benchmark that may not have an active version yet.
3666
+ */
3667
+ declare class NoActiveVersionError extends Error {
3668
+ /** The benchmark name that had no active version */
3669
+ readonly benchmark: string;
3670
+ constructor(benchmark: string);
3671
+ }
3672
+ /**
3673
+ * Downloaded bytes did not match the digest the server stated for them.
3674
+ *
3675
+ * NOT an EvolveApiError: the request succeeded, so it gets its own type rather
3676
+ * than an invented error code.
3677
+ */
3678
+ declare class EvolveDigestMismatchError extends Error {
3679
+ readonly expected: string;
3680
+ readonly actual: string;
3681
+ readonly name = "EvolveDigestMismatchError";
3682
+ constructor(expected: string, actual: string);
3683
+ }
3684
+ /**
3685
+ * A download ended early: fewer bytes arrived than Content-Length promised.
3686
+ *
3687
+ * Its own type because a truncated body is not a wrong body — the distinction
3688
+ * tells a caller whether to retry (yes) or to stop trusting the stored object
3689
+ * (that is the digest error).
3690
+ */
3691
+ declare class EvolveIncompleteDownloadError extends Error {
3692
+ readonly expectedBytes: number;
3693
+ readonly receivedBytes: number;
3694
+ readonly name = "EvolveIncompleteDownloadError";
3695
+ constructor(expectedBytes: number, receivedBytes: number);
3696
+ }
3697
+ /**
3698
+ * Create a BenchmarksClient for the shared benchmark catalog.
3699
+ *
3700
+ * Requires EVOLVE_API_KEY (or { apiKey } in config).
3701
+ *
3702
+ * @example
3703
+ * ```ts
3704
+ * import { benchmarks } from "@evolvingmachines/sdk";
3705
+ *
3706
+ * const b = benchmarks();
3707
+ * const catalog = await b.list();
3708
+ * const deepSwe = await b.get("deep-swe@1.1");
3709
+ * ```
3710
+ */
3711
+ declare function benchmarks(config?: HostedClientConfig): BenchmarksClient;
3712
+ /**
3713
+ * Create a CustomHarnessesClient for the caller's own private harnesses.
3714
+ *
3715
+ * Register a harness once, then name it in `agents[].harness` exactly
3716
+ * like a built-in. Requires EVOLVE_API_KEY (or { apiKey } in config).
3717
+ *
3718
+ * @example
3719
+ * ```ts
3720
+ * import { customHarnesses, jobs } from "@evolvingmachines/sdk";
3721
+ *
3722
+ * const harnesses = customHarnesses();
3723
+ * await harnesses.create({
3724
+ * name: "acme-cli",
3725
+ * installScript: "curl -fsSL https://acme.dev/install.sh | sh",
3726
+ * runCommand: "acme-cli --headless",
3727
+ * });
3728
+ *
3729
+ * await jobs().run({
3730
+ * benchmark: "deep-swe",
3731
+ * agents: [{ harness: "acme-cli", model: "gpt-5.5" }],
3732
+ * maxTrialSpendUsd: 25,
3733
+ * });
3734
+ * ```
3735
+ */
3736
+ declare function customHarnesses(config?: HostedClientConfig): CustomHarnessesClient;
3737
+ /**
3738
+ * Create a JobsClient for hosted jobs.
3739
+ *
3740
+ * Requires EVOLVE_API_KEY (or { apiKey } in config).
3741
+ *
3742
+ * @example
3743
+ * ```ts
3744
+ * import { jobs } from "@evolvingmachines/sdk";
3745
+ *
3746
+ * const client = jobs();
3747
+ * // benchmark: bare name = active version; "name@version" pins a version
3748
+ * const job = await client.run({
3749
+ * benchmark: "deep-swe",
3750
+ * agents: [{ harness: "codex", model: "gpt-5.5" }],
3751
+ * runsPerTask: 1,
3752
+ * concurrency: 4,
3753
+ * maxTrialSpendUsd: 25,
3754
+ * });
3755
+ * const final = await client.watch(job.id, {
3756
+ * onEvent: (event) => console.log(event.type, event.data),
3757
+ * });
3758
+ * ```
3759
+ */
3760
+ declare function jobs(config?: HostedClientConfig): JobsClient;
3761
+ /**
3762
+ * The hosted surface, configured once.
3763
+ *
3764
+ * The three factories are the right decomposition — a benchmark catalog, your
3765
+ * own harness registrations, and jobs are three genuinely different lifetimes —
3766
+ * but they made you say the same thing three times:
3767
+ *
3768
+ * const b = benchmarks({ apiKey, baseUrl });
3769
+ * const h = customHarnesses({ apiKey, baseUrl }); // again
3770
+ * const j = jobs({ apiKey, baseUrl }); // and again
3771
+ *
3772
+ * and any one of those going out of sync with the others is a bug that looks
3773
+ * like a permissions problem. One door, one config:
3774
+ *
3775
+ * const evolve = hosted({ apiKey });
3776
+ * const catalog = await evolve.benchmarks.list();
3777
+ * const job = await evolve.jobs.run({ ... });
3778
+ *
3779
+ * The three clients are built LAZILY, on first access. That matters because
3780
+ * they throw when no API key is present, and `meta()` needs no key at all — so
3781
+ * `hosted().meta()` works on a signed-out page, while `hosted().jobs` still
3782
+ * fails loudly and immediately the moment you reach for something that does
3783
+ * need credentials.
3784
+ */
3785
+ interface HostedEvolve {
3786
+ /** The benchmark catalog: list, get, import, delete. */
3787
+ readonly benchmarks: BenchmarksClient;
3788
+ /** Your own bring-your-own harness registrations. */
3789
+ readonly customHarnesses: CustomHarnessesClient;
3790
+ /** Jobs: run, watch, compare, regrade, export. */
3791
+ readonly jobs: JobsClient;
3792
+ /**
3793
+ * The capability document — every harness, provider, status, limit, and
3794
+ * error code the platform supports. Public: no API key required.
3795
+ *
3796
+ * Fetch it once and stop hardcoding. It is what tells you the legal harness
3797
+ * names without having to send a bad one and read the 400.
3798
+ */
3799
+ meta(): Promise<CapabilityDocument>;
3800
+ }
3801
+ /**
3802
+ * Open the hosted surface with one configuration.
3803
+ *
3804
+ * Named `hosted()` rather than `evolve()` deliberately: `Evolve` is already the
3805
+ * local-sandbox SDK class in this same package, and two exports one shift key
3806
+ * apart that do completely different things is a trap. `hosted()` says which
3807
+ * half of the SDK you are reaching for.
3808
+ *
3809
+ * @example
3810
+ * ```ts
3811
+ * import { hosted } from "@evolvingmachines/sdk";
3812
+ *
3813
+ * const evolve = hosted(); // EVOLVE_API_KEY from env
3814
+ * const { harnesses } = await evolve.meta(); // no key needed for this one
3815
+ * const job = await evolve.jobs.run({
3816
+ * benchmark: "deep-swe",
3817
+ * agents: [{ harness: "claude", model: harnesses[0].defaultModel! }],
3818
+ * });
3819
+ * ```
3820
+ */
3821
+ declare function hosted(config?: HostedClientConfig): HostedEvolve;
3822
+ /**
3823
+ * Fetch the capability document.
3824
+ *
3825
+ * NO API KEY. The document is the same information the docs publish, and
3826
+ * requiring credentials would mean a signed-out page could not populate its own
3827
+ * harness picker — so this is the one hosted call that takes only a base URL.
3828
+ */
3829
+ declare function meta(config?: HostedClientConfig): Promise<CapabilityDocument>;
3830
+
3831
+ export { AGENT_REGISTRY, AGENT_TYPES, type ActionbookBrowserConfig, Agent, type AgentBrowserConfig, type AgentConfig, type AgentError, type AgentOptions, type AgentOverride, type AgentParser, type AgentPluginConfig, type AgentRegistryEntry, type AgentResponse, type AgentRuntimeState, type AgentType, BROWSER_ACTIONBOOK_PROMPT, BROWSER_LOGIN_MCP_SERVER_NAME, type BaseMeta, BenchmarksClient, type BestOfConfig, type BestOfParams, type BestOfResult, type BrowserConfig, type BrowserCredentialCreateInput, type BrowserCredentialDeleteInput, type BrowserCredentialListOptions, type BrowserCredentialMetadata, type BrowserCredentialScopeEntry, BrowserCredentialsClient, type BrowserCredentialsClientConfig, type BrowserCredentialsConfig, type BrowserProfileDeleteInput, type BrowserProfileMetadata, BrowserProfilesClient, type BrowserProfilesClientConfig, type BrowserProvider, type BrowserReplay, type BrowserReplayOptions, type BrowserRuntimeInfo, type CandidateCompleteEvent, CapabilityDocument, type CheckpointInfo, type CodexAgentPluginConfig, CustomHarnessesClient, type DefaultBrowserConfig, type DownloadCheckpointOptions, type DownloadFilesOptions, type DownloadSessionOptions, type EmitOption, type EventHandler, type EventName, Evolve, EvolveApiError, type EvolveConfig, EvolveDigestMismatchError, type EvolveEvents, EvolveIncompleteDownloadError, type ExecuteCommandOptions, type ExternalGatewayConfig, type FileMap, type FilterConfig, type FilterParams, type GeminiAgentPluginConfig, type GetEventsOptions, HostedClientConfig, HostedErrorCode, type HostedEvolve, type IndexedMeta, type IntegrationAccount, type IntegrationAccountDeleteParams, type IntegrationAccountDeleteResult, type IntegrationAccountListParams, type IntegrationAccountUpdateParams, type IntegrationAccountUpdateResult, type IntegrationAuthParams, type IntegrationAuthResult, type IntegrationToolsFilter, type IntegrationsConfig, type IntegrationsSetup, type ItemInput, type ItemRetryEvent, JUDGE_PROMPT, JobsClient, type JsonSchema, type JudgeCompleteEvent, type JudgeDecision, type JudgeMeta, type LifecycleEvent, type LifecycleReason, type ListSessionsOptions, MANAGED_SANDBOX_PROVIDERS, type ManagedBrowserProvider, type ManagedSandboxProviderName, type ManagedSecretMetadata, type ManagedSecretRef, type ManagedSecretsClient, type ManagedSecretsClientConfig, type MapConfig, type MapParams, type MarketplaceAgentPluginConfig, type McpConfigInfo, type McpServerConfig, type ModelInfo, NoActiveVersionError, type OnCandidateCompleteCallback, type OnItemRetryCallback, type OnJudgeCompleteCallback, type OnVerifierCompleteCallback, type OnWorkerCompleteCallback, type OperationType, type OutputEvent, type OutputResult, Pipeline, type PipelineContext, type PipelineEventMap, type PipelineEvents, type PipelineResult, type ProcessInfo, type Prompt, type PromptFn, RETRY_FEEDBACK_PROMPT, type ReasoningEffort, type ReduceConfig, type ReduceMeta, type ReduceParams, type ReduceResult, type ResolvedStorageConfig, type RetryConfig, type RunCost, type RunOptions, SCHEMA_PROMPT, SWARM_RESULT_BRAND, SYSTEM_PROMPT, type SandboxCommandHandle, type SandboxCommandResult, type SandboxCommands, type SandboxCreateOptions, type SandboxFiles, type SandboxInstance, type SandboxLifecycleState, type SandboxNetworkPolicy, type SandboxProvider, type SandboxRunOptions, type SandboxSpawnOptions, type SchemaValidationOptions, Semaphore, type SessionCost, type SessionEvent, type SessionInfo, type SessionPage, type SessionStatus, type SessionUpdate, type SessionsClient, type SessionsConfig, type SkillName, type SkillsConfig, type StepCompleteEvent, type StepErrorEvent, type StepEvent, type StepResult, type StepStartEvent, type StorageClient, type StorageConfig, type StreamCallbacks, Swarm, type SwarmConfig, type SwarmResult, SwarmResultList, TerminalPipeline, VALIDATION_PRESETS, VERIFY_PROMPT, type ValidationMode, type VerifierCompleteEvent, type VerifyConfig, type VerifyDecision, type VerifyInfo, type VerifyMeta, WORKSPACE_PROMPT, WORKSPACE_SWE_PROMPT, type WorkerCompleteEvent, type WorkspaceMode, applyTemplate, benchmarks, browserCredentials, browserProfiles, buildWorkerSystemPrompt, createAgentParser, createClaudeParser, createCodexParser, createDroidParser, createGeminiParser, customHarnesses, executeWithRetry, expandPath, getAgentConfig, getMcpSettingsDir, getMcpSettingsPath, hosted, isAgentWorkUpdate, isValidAgentType, isZodSchema, jobs, jsonSchemaToString, managedSandbox, managedSecrets, meta, parseNdjsonLine, parseNdjsonOutput, parseQwenOutput, readLocalDir, resolveStorageConfig, saveLocalDir, sessions, storage, writeClaudeMcpConfig, writeCodexMcpConfig, writeDroidGatewaySettings, writeDroidMcpConfig, writeGeminiMcpConfig, writeMcpConfig, writeQwenMcpConfig, zodSchemaToJson };