evolve-sdk 0.0.55.dev1239__tar.gz → 0.0.55.dev1246__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/PKG-INFO +1 -1
  2. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/bridge/dist/bridge.bundle.cjs +1 -1
  3. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/__init__.py +9 -1
  4. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/hosted.py +159 -0
  5. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve_sdk.egg-info/PKG-INFO +1 -1
  6. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/pyproject.toml +1 -1
  7. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/LICENSE +0 -0
  8. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/MANIFEST.in +0 -0
  9. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/README.md +0 -0
  10. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/bridge/__init__.py +0 -0
  11. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/_http.py +0 -0
  12. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/agent.py +0 -0
  13. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/bridge.py +0 -0
  14. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/browser_credentials.py +0 -0
  15. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/browser_profiles.py +0 -0
  16. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/config.py +0 -0
  17. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/integrations.py +0 -0
  18. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/managed_secrets.py +0 -0
  19. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/pipeline/__init__.py +0 -0
  20. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/pipeline/pipeline.py +0 -0
  21. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/pipeline/types.py +0 -0
  22. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/prompts/__init__.py +0 -0
  23. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/prompts/agent_md/judge.md +0 -0
  24. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/prompts/agent_md/reduce.md +0 -0
  25. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/prompts/agent_md/verify.md +0 -0
  26. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/prompts/user/judge.md +0 -0
  27. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/prompts/user/retry_feedback.md +0 -0
  28. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/prompts/user/verify.md +0 -0
  29. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/py.typed +0 -0
  30. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/results.py +0 -0
  31. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/retry.py +0 -0
  32. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/schema.py +0 -0
  33. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/sessions_client.py +0 -0
  34. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/storage_client.py +0 -0
  35. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/swarm/__init__.py +0 -0
  36. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/swarm/results.py +0 -0
  37. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/swarm/swarm.py +0 -0
  38. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/swarm/types.py +0 -0
  39. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve/utils.py +0 -0
  40. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve_sdk.egg-info/SOURCES.txt +0 -0
  41. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve_sdk.egg-info/dependency_links.txt +0 -0
  42. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve_sdk.egg-info/requires.txt +0 -0
  43. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/evolve_sdk.egg-info/top_level.txt +0 -0
  44. {evolve_sdk-0.0.55.dev1239 → evolve_sdk-0.0.55.dev1246}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: evolve-sdk
3
- Version: 0.0.55.dev1239
3
+ Version: 0.0.55.dev1246
4
4
  Summary: Pythonic SDK for multi-agent orchestration in E2B sandboxes
5
5
  Author-email: "Swarmlink, Inc." <brandomagnani@evolvingmachines.ai>
6
6
  License: Apache-2.0
@@ -899,7 +899,7 @@ PY`,{timeoutMs:1e4})).exitCode!==0)throw new Error("Managed secret egress proxy
899
899
  `);f=T.pop()??"";for(let k of T){if(!k.trim())continue;let O=p(k);if(this.captureDroidSession(k,O),this.sessionLogger?.writeEventParsed(k,O),t?.onStdout?.(k+`
900
900
  `),O&&t?.onContent)for(let R of O)t.onContent(R)}},y=I=>{t?.onStderr?.(I)},b=await c.commands.spawn(l,{cwd:this.workingDir,timeoutMs:r,envs:d,onStdout:m,onStderr:y}),v=this.beginOperation("run",b,t,"run_start");if(this.hasRun=!0,a)return this.watchBackgroundOperation(v,"run",b,t,c),{sandboxId:c.sandboxId,sessionId:this.managedBrowserSession?.sessionId,browser:this.browserResponseInfo(),runId:u,exitCode:0,stdout:`Background process started with ID ${b.processId}`,stderr:""};let S;try{S=await b.wait()}catch(I){throw this.interruptedOperations.delete(v),this.finalizeOperation(v,t,"run_failed","error"),I}if(this.interruptedOperations.delete(v)||S.exitCode===130?this.finalizeOperation(v,t,"run_interrupted","interrupted"):S.exitCode===0?this.finalizeOperation(v,t,"run_complete","idle"):this.finalizeOperation(v,t,"run_failed","error"),f.trim()){let I=p(f);if(this.captureDroidSession(f,I),this.sessionLogger?.writeEventParsed(f,I),t?.onStdout?.(f+`
901
901
  `),I&&t?.onContent)for(let T of I)t.onContent(T)}await this.writeDroidSessionState(c),this.sessionLogger&&!a&&await this.flushSessionLoggerWithTimeout();let w;if(this.storage&&!a&&S.exitCode===0)try{w=await uXe(c,this.storage,this.agentConfig.type,this.workingDir,{tag:this.sessionTag,model:this.agentConfig.model||this.registry.defaultModel,workspaceMode:this.options.workspaceMode||"knowledge",comment:i,parentId:this.lastCheckpointId}),this.lastCheckpointId=w.id}catch(I){console.warn(`[Evolve] Auto-checkpoint failed: ${I.message}`)}return{sandboxId:c.sandboxId,sessionId:this.managedBrowserSession?.sessionId,browser:this.browserResponseInfo(),runId:u,exitCode:S.exitCode,stdout:S.stdout,stderr:S.stderr,checkpoint:w}}async executeCommand(e,t={},n){let{timeoutMs:r=LO,background:a=!1}=t;if(this.activeCommand)throw new Error("Agent is already running. Call interrupt(), wait for the active/background command to finish, or create a new Evolve instance.");let i=await this.getSandbox(n);this.credentialsSealed||await this.ensureProviderRuntimeToken(),this.lastRunTimestamp=Date.now(),this.requiresPreRunDashboardIngest()&&(this.ensureSessionLogger(i),this.sessionLogger?.writePrompt(e),await this.flushSessionLoggerWithTimeout());let s="",o="",c=m=>{s+=m,n?.onStdout?.(m)},l=m=>{o+=m,n?.onStderr?.(m)},u=this.credentialsSealed?{}:this.buildProviderRuntimeProcessEnvs(),d=await i.commands.spawn(e,{cwd:this.workingDir,timeoutMs:r,envs:Object.keys(u).length>0?u:void 0,onStdout:c,onStderr:l}),f=this.beginOperation("command",d,n,"command_start");if(a)return this.watchBackgroundOperation(f,"command",d,n),{sandboxId:i.sandboxId,sessionId:this.managedBrowserSession?.sessionId,browser:this.browserResponseInfo(),exitCode:0,stdout:`Background process started with ID ${d.processId}`,stderr:""};let p;try{p=await d.wait()}catch(m){throw this.interruptedOperations.delete(f),this.finalizeOperation(f,n,"command_failed","error"),m}return this.interruptedOperations.delete(f)||p.exitCode===130?this.finalizeOperation(f,n,"command_interrupted","interrupted"):p.exitCode===0?this.finalizeOperation(f,n,"command_complete","idle"):this.finalizeOperation(f,n,"command_failed","error"),{sandboxId:i.sandboxId,sessionId:this.managedBrowserSession?.sessionId,browser:this.browserResponseInfo(),exitCode:p.exitCode,stdout:s||p.stdout||"",stderr:o||p.stderr||""}}async sealCredentials(){if(!this.credentialsSealed){if(!this.sandbox)throw new Error("No active sandbox. Call run() or executeCommand() first.");if(this.activeCommand)throw new Error("Cannot seal credentials while a process is running.");if(this.agentConfig.isDirectMode&&!this.agentConfig.externalGateway)throw new Error("Credential sealing requires gateway mode; direct provider credentials cannot be revoked by Evolve");if([this.options.secrets&&Object.keys(this.options.secrets).length>0,this.options.sandboxCreateOptions?.envs&&Object.keys(this.options.sandboxCreateOptions.envs).length>0,this.options.managedSecrets,this.options.integrations,this.options.mcpServers&&Object.keys(this.options.mcpServers).length>0,this.options.managedBrowser,this.options.browserCredentials].some(Boolean))throw new Error("Credential sealing requires a credential-minimal sandbox: omit secrets, managed secrets, integrations, MCP servers, and browser credentials");if(this.agentConfig.externalGateway){await this.agentConfig.externalGateway.revoke(),this.credentialsSealed=!0;return}if(!this.providerRuntimeToken||!this.options.providerRouting)throw new Error("Cannot seal credentials: no active provider runtime token to revoke. Without a gateway-issued runtime token the sandbox may hold credentials Evolve cannot revoke, so sealing would be a false guarantee.");await this.closeProviderRuntimeToken(!0),this.credentialsSealed=!0}}isSealed(){return this.credentialsSealed}async collectArtifacts(e){if(!this.credentialsSealed)throw new Error("Call sealCredentials() before collecting artifacts.");if(!this.sandbox)throw new Error("No active sandbox.");if(this.activeCommand)throw new Error("Cannot collect artifacts while a process is running.");return h9t(this.sandbox,this.workingDir,e)}async uploadContext(e){let t=await this.getSandbox();await this.uploadContextFiles(t,e)}async uploadFiles(e){let t=await this.getSandbox();await this.uploadWorkspaceFiles(t,e)}async uploadFileFromPath(e,t){let n=await this.getSandbox(),r=e.startsWith("/")?e:`${this.workingDir}/${e}`,a=r.substring(0,r.lastIndexOf("/"));if(a&&await n.commands.run(`mkdir -p ${a}`,{timeoutMs:3e4}),n.files.writeFromPath){await n.files.writeFromPath(r,t);return}let{readFile:i}=await import("fs/promises");await n.files.write(r,await i(t))}async getOutputFiles(e=!1){let t=await this.getSandbox(),n=`${this.workingDir}/output`,r=e?"":"-maxdepth 1",a=(await t.commands.run(`find ${n} ${r} -type f -exec stat -c '%n|%Z' {} \\; 2>/dev/null || true`,{timeoutMs:3e4})).stdout.split(`
902
- `).filter(Boolean),i=this.lastRunTimestamp?Math.floor(this.lastRunTimestamp/1e3)-2:0,s=[],o=`${n}/`;for(let f of a){let[p,m]=f.split("|");if(!p||!m)continue;let y=parseInt(m,10);i>0&&y<i||s.push(p)}let c={},l=await Promise.all(s.map(async f=>{try{let p=await t.files.read(f);return{relativePath:f.startsWith(o)?f.slice(o.length):f.split("/").pop()||f,content:p}}catch{return null}}));for(let f of l)f&&(c[f.relativePath]=f.content);if(!this.zodSchema&&!this.jsonSchema)return{files:c,data:null};let u=c["result.json"];if(!u)return{files:c,data:null,error:"Schema provided but agent did not create output/result.json"};let d=typeof u=="string"?u:new TextDecoder().decode(u);try{let f=JSON.parse(d);if(this.zodSchema){let p=this.zodSchema.safeParse(f);return p.success?{files:c,data:p.data}:{files:c,data:null,error:`Schema validation failed: ${p.error.message}`,rawData:d}}if(this.compiledValidator){if(this.compiledValidator(f))return{files:c,data:f};{let p=this.compiledValidator.errors?.map(m=>`${m.instancePath} ${m.message}`).join(", ")||"Unknown validation error";return{files:c,data:null,error:`Schema validation failed: ${p}`,rawData:d}}}return{files:c,data:null}}catch(f){return{files:c,data:null,error:`Failed to parse result.json: ${f.message}`,rawData:d}}}async checkpoint(e){if(!this.storage)throw new Error("Storage not configured. Call .withStorage().");if(!this.sandbox)throw new Error("No active sandbox. Call run() first.");let t=await uXe(this.sandbox,this.storage,this.agentConfig.type,this.workingDir,{tag:this.sessionTag,model:this.agentConfig.model||this.registry.defaultModel,workspaceMode:this.options.workspaceMode||"knowledge",comment:e?.comment,parentId:this.lastCheckpointId});return this.lastCheckpointId=t.id,t}getSession(){return this.sandbox?.sandboxId||this.options.sandboxId||null}async setSession(e){if(this.credentialsSealed)throw new Error("Agent credentials are sealed and this Evolve instance cannot switch sandboxes");if(this.options.managedSecrets)throw new Error("setSession() cannot be used with managed secrets; managed secret grants are sandbox-scoped.");if(this.options.sandboxCreateOptions?.user)throw new Error("setSession() cannot be used with a configured sandbox user; the user cannot be enforced on an existing sandbox.");if(this.activeCommand&&!await this.interrupt())throw new Error("Cannot switch session while an active process is running and could not be interrupted.");await this.rotateSession(),await this.closeProviderRuntimeToken(),await this.closeManagedSecretRuntimeToken(),await this.closeManagedBrowserSession(),this.options.sandboxId=e,this.sandbox=void 0,this.interruptedOperations.clear(),this.invalidateActiveOperation(),this.sandboxState="ready",this.agentState="idle",this.hasRun=!0,this.lastCheckpointId=void 0}async pause(e){this.sandbox&&(this.activeCommand&&await this.interrupt(e),await this.sandbox.pause(),this.sandboxState="paused",this.agentState="idle",this.emitLifecycle(e,"sandbox_pause"))}async resume(e){this.sandbox&&this.options.sandboxProvider&&(this.sandbox=await this.options.sandboxProvider.connect(this.sandbox.sandboxId),this.sandboxState="ready",this.agentState="idle",this.emitLifecycle(e,"sandbox_resume"))}async interrupt(e){if(!this.activeCommand&&!this.activeProcessId)return!1;let t=this.activeOperationId,n=this.activeOperationKind,r=!1;try{this.activeCommand?r=await this.activeCommand.kill():this.sandbox&&this.activeProcessId&&(r=await this.sandbox.commands.kill(this.activeProcessId))}catch{r=!1}if(!r)return this.sandboxState="running",this.agentState="running",!1;t!==null&&this.interruptedOperations.add(t),this.invalidateActiveOperation(),this.sandboxState="ready",this.agentState="interrupted";let a=n==="run"?"run_interrupted":"command_interrupted";return this.emitLifecycle(e,a),r}status(){let e=this.browserRuntimeInfo();return{sandboxId:this.getSession(),sandbox:this.sandboxState,agent:this.agentState,activeProcessId:this.activeProcessId,hasRun:this.hasRun,timestamp:new Date().toISOString(),...e?{browser:e}:{}}}async kill(e){await this.rotateSession();let t;try{this.activeCommand&&await this.interrupt(e),this.sandbox&&(await this.sandbox.kill(),this.sandbox=void 0)}catch(n){t=n}finally{await this.closeProviderRuntimeToken(),await this.closeManagedSecretRuntimeToken(),await this.closeManagedBrowserSession()}if(t)throw t;this.options.sandboxId=void 0,this.interruptedOperations.clear(),this.invalidateActiveOperation(),this.sandboxState="stopped",this.agentState="idle",this.hasRun=!1,this.lastCheckpointId=void 0,this.emitLifecycle(e,"sandbox_killed")}async getHost(e){return(await this.getSandbox()).getHost(e)}getAgentType(){return this.agentConfig.type}getSessionTag(){return!this.sandbox&&!this.sessionLogger?null:this.sessionTag}getSessionTimestamp(){return this.sessionLogger?.getTimestamp()||null}async flushObservability(){await this.sessionLogger?.flush()}async rotateSession(){let e=!!this.sessionLogger;this.sessionLogger&&(await this.sessionLogger.close(),this.sessionLogger=void 0),e&&(this.previousSessionTag=this.sessionTag),this.sessionTag=wXe(this.options.sessionTagPrefix||"evolve")}async fetchSpend(e){if(this.agentConfig.isDirectMode)throw new Error("Cost tracking requires gateway mode (set EVOLVE_API_KEY).");let t=this.agentConfig.apiKey;if(!t)throw new Error("Cost tracking requires an API key.");let n=process.env.EVOLVE_DASHBOARD_URL||ia,r=await fetch(`${n}/api/sessions/spend?${e}`,{headers:{Authorization:`Bearer ${t}`},signal:AbortSignal.timeout(1e4)});if(!r.ok){let a=await r.text().catch(()=>"");throw new Error(`Spend query failed (${r.status}): ${a}`)}return r}resolveSpendTag(){if(this.sandbox||this.sessionLogger)return this.sessionTag;if(this.previousSessionTag)return this.previousSessionTag;throw new Error("No session to query. Call run() first.")}normalizeRunCost(e,t){return{...e,asOf:e.asOf??t.asOf,isComplete:e.isComplete??t.isComplete,truncated:e.truncated??t.truncated}}normalizeSessionCost(e){let t={asOf:e.asOf,isComplete:e.isComplete,truncated:e.truncated};return{...e,runs:e.runs.map(n=>this.normalizeRunCost(n,t))}}async getSessionCost(){let e=this.resolveSpendTag(),t=new URLSearchParams({tag:e}),n=await(await this.fetchSpend(t)).json();return this.normalizeSessionCost(n)}async getRunCost(e){let t=this.resolveSpendTag();if("runId"in e){let i=new URLSearchParams({tag:t,runId:e.runId}),s=await(await this.fetchSpend(i)).json();return this.normalizeRunCost(s,{asOf:new Date().toISOString(),isComplete:!1,truncated:!1})}let n=await this.getSessionCost(),r=e.index>0?e.index-1:n.runs.length+e.index,a=n.runs[r];if(!a)throw new Error(`Run index ${e.index} out of range. Session has ${n.runs.length} run(s).`);return a}};function S9t(e){return(e||process.env.EVOLVE_DASHBOARD_URL||ia).replace(/\/$/,"")}function _9t(e){let t=e||process.env.EVOLVE_API_KEY;if(!t)throw new Error("Browser profiles require EVOLVE_API_KEY or an explicit apiKey");return t}async function w9t(e){return await e.text().catch(()=>"")}async function xXe(e,t,n={}){let r=await fetch(`${S9t(e?.dashboardUrl)}${t}`,{...n,headers:{Authorization:`Bearer ${_9t(e?.apiKey)}`,accept:"application/json",...n.body?{"content-type":"application/json"}:{},...n.headers||{}}});if(!r.ok)throw new Error(`Browser profiles request failed (${r.status}): ${await w9t(r)}`);return r.status===204?{}:await r.json()}var I9t=class{constructor(e={}){this.config=e}toMetadata(e){return{id:e.id,profile:e.profile,createdAt:e.createdAt||e.created_at||"",updatedAt:e.updatedAt||e.updated_at||"",lastUsedAt:e.lastUsedAt??e.last_used_at??null}}async list(){return{profiles:(await xXe(this.config,"/api/browser-profiles")).profiles.map(e=>this.toMetadata(e))}}async delete(e){return await xXe(this.config,"/api/browser-profiles",{method:"DELETE",body:JSON.stringify(e)})}};function x9t(e={}){return new I9t(e)}var Ov=class extends TXe.EventEmitter{config={};agent;fallbackSandboxState="stopped";fallbackAgentState="idle";fallbackHasRun=!1;constructor(){super()}on(e,t){return super.on(e,t)}off(e,t){return super.off(e,t)}emit(e,...t){return super.emit(e,...t)}withAgent(e){return e&&($Xe(e),WXe(e),this.config.agent=e,this._cachedGatewayOverrides=null),this}withSandbox(e){return this.config.sandbox=e,this}withSandboxCreateOptions(e){return this.config.sandboxCreateOptions={...e,envs:e.envs?{...e.envs}:void 0,metadata:e.metadata?{...e.metadata}:void 0},this}withWorkingDirectory(e){return this.config.workingDirectory=e,this}withWorkspaceMode(e){return this.config.workspaceMode=e,this}withSecrets(e){return this.config.secrets={...this.config.secrets,...e},this}withManagedSecrets(e){return this.config.managedSecrets=e,this}withSession(e){return this.config.sandboxId=e,this.agent||(this.fallbackSandboxState="ready",this.fallbackAgentState="idle",this.fallbackHasRun=!0),this}withSystemPrompt(e){return this.config.systemPrompt=e,this}withContext(e){return this.config.context={...this.config.context,...e},this}withFiles(e){return this.config.files={...this.config.files,...e},this}withMcpServers(e){return this.config.mcpServers={...this.config.mcpServers,...e},this}withBrowser(e={provider:"agent-browser",remote:!0}){return e===!1?delete this.config.browser:this.config.browser=e,this}withBrowserCredentials(e={}){return this.config.browserCredentials=e,this}withPlugins(e){let t=Array.isArray(e)?e:[e];return this.config.plugins=[...this.config.plugins??[],...t],this}withSkills(e){return this.config.skills=e,this}withSchema(e,t){return this.config.schema=e,t&&(vB(e)?console.warn("[Evolve] schemaOptions ignored for Zod schemas - use .passthrough(), .strip(), z.coerce instead"):this.config.schemaOptions=t),this}withSessionTagPrefix(e){return this.config.sessionTagPrefix=e,this}withObservability(e){return this.config.observability={...this.config.observability,...e},this}withIntegrations(e){return this.config.integrations=e,this}withStorage(e){return this.config.storage=e||{},this}static integrations=EYt;static browserCredentials=r9t;static browserProfiles=x9t;static managedSecrets=CB;async initializeAgent(){let e=rXe(this.config.agent),t=Tv(e.type);if(this.config.integrations&&e.isDirectMode)throw new Error("withIntegrations() is available only in gateway mode with EVOLVE_API_KEY");if(this.config.managedSecrets&&e.isDirectMode)throw new Error("withManagedSecrets() is available only in gateway mode with EVOLVE_API_KEY");if(this.config.managedSecrets&&this.config.sandboxId)throw new Error("withManagedSecrets() cannot be used with withSession(); managed secret grants are sandbox-scoped.");let n=RQ(this.config.managedSecrets,t);if(n&&this.config.sandbox&&!DZ(this.config.sandbox))throw new Error("withManagedSecrets() requires an Evolve-managed sandbox; remove withSandbox() or pass a managed sandbox provider.");let r=this.config.sandbox??(n?await qZ(e.apiKey):await Gjt()),a={},i,s,o=this.config.skills,c;if(this.config.browser){let d=WYt(this.config.browser);if(c=d,d.provider==="browser-use"){if(e.isDirectMode)throw new Error('withBrowser("browser-use") requires gateway mode. Use apiKey/EVOLVE_API_KEY instead of providerApiKey/direct mode.');a=bQ(e.apiKey)}if((d.provider==="actionbook"||d.provider==="agent-browser")&&d.managed){if(e.isDirectMode)throw new Error(`Managed browser provider "${d.provider}" requires gateway mode. Use apiKey/EVOLVE_API_KEY instead of providerApiKey/direct mode.`);i=d.provider==="actionbook"?lYt:uYt,s={provider:d.provider,apiKey:e.apiKey,dashboardUrl:process.env.EVOLVE_DASHBOARD_URL||ia,...d.profile?{profile:d.profile}:{}}}if(d.profile&&!d.managed)throw new Error('withBrowser({ profile }) requires managed remote browser mode. Use .withBrowser({ profile }) or .withBrowser({ provider: "agent-browser", remote: true, profile }).')}if(this.config.browserCredentials!==void 0){if(this.config.sandboxId)throw new Error("withBrowserCredentials() cannot be used with withSession(); browser login tokens are run-scoped.");if(e.isDirectMode)throw new Error("withBrowserCredentials() requires gateway mode. Use apiKey/EVOLVE_API_KEY instead of providerApiKey/direct mode.");if(!c||c.provider!=="agent-browser"||!c.managed)throw new Error('withBrowserCredentials() requires .withBrowser() or .withBrowser({ provider: "agent-browser", remote: true }).');if(this.config.mcpServers?.["browser-login"])throw new Error('withBrowserCredentials() reserves the "browser-login" MCP server name.')}let l=this.config.storage!==void 0?KXe(this.config.storage,!e.isDirectMode,ia,e.isDirectMode?void 0:e.apiKey):void 0,u={sandboxProvider:r,sandboxCreateOptions:this.config.sandboxCreateOptions,secrets:this.config.secrets,managedSecrets:n?{secrets:n,apiKey:e.apiKey,dashboardUrl:process.env.EVOLVE_DASHBOARD_URL||ia}:void 0,sandboxId:this.config.sandboxId,workingDirectory:this.config.workingDirectory,workspaceMode:this.config.workspaceMode,systemPrompt:this.config.systemPrompt,context:this.config.context,files:this.config.files,mcpServers:{...a,...this.config.mcpServers},browserPrompt:i,managedBrowser:s,browserCredentials:this.config.browserCredentials!==void 0?{apiKey:e.apiKey,dashboardUrl:process.env.EVOLVE_DASHBOARD_URL||ia,config:this.config.browserCredentials}:void 0,plugins:this.config.plugins,skills:o,schema:this.config.schema,schemaOptions:this.config.schemaOptions,sessionTagPrefix:this.config.sessionTagPrefix,observability:this.config.observability,integrations:this.config.integrations?{...this.config.integrations,apiKey:e.apiKey,dashboardUrl:process.env.EVOLVE_DASHBOARD_URL||ia}:void 0,providerRouting:e.isDirectMode?void 0:{apiKey:e.apiKey,dashboardUrl:process.env.EVOLVE_DASHBOARD_URL||ia},storage:l};this.agent=new b9t(e,u)}createStreamCallbacks(){let e=this.listenerCount("stdout")>0,t=this.listenerCount("stderr")>0,n=this.listenerCount("content")>0,r=this.listenerCount("lifecycle")>0;return{onStdout:e?a=>this.emit("stdout",a):void 0,onStderr:t?a=>this.emit("stderr",a):void 0,onContent:n?a=>this.emit("content",a):void 0,onLifecycle:r?a=>this.emit("lifecycle",a):void 0}}emitLifecycleFromStatus(e){if(this.listenerCount("lifecycle")===0)return;let t=this.status();this.emit("lifecycle",{sandboxId:t.sandboxId,sandbox:t.sandbox,agent:t.agent,timestamp:new Date().toISOString(),reason:e,...t.browser?{browser:t.browser}:{}})}async run({prompt:e,timeoutMs:t,background:n,from:r,checkpointComment:a,resume:i}){if(r&&this.config.sandboxId)throw new Error("Cannot use 'from' with 'withSession()' \u2014 restore requires a fresh sandbox.");this.agent||await this.initializeAgent();let s=this.createStreamCallbacks();return this.agent.run({prompt:e,timeoutMs:t,background:n,from:r,checkpointComment:a,resume:i},s)}async executeCommand(e,t={}){this.agent||await this.initializeAgent();let n=this.createStreamCallbacks();return this.agent.executeCommand(e,t,n)}async prepareSandbox(){this.agent||await this.initializeAgent();let e=this.createStreamCallbacks();return(await this.agent.getSandbox(e)).sandboxId}async updateNetwork(e){if(!this.agent)throw new Error("No sandbox yet. Call prepareSandbox(), run() or executeCommand() before updateNetwork().");let t=await this.agent.getSandbox(this.createStreamCallbacks());if(typeof t.updateNetwork!="function")throw new Error(`The ${this.config.sandbox?.providerType??"configured"} sandbox provider cannot change network policy after start. Create the sandbox with the policy it needs for its whole lifetime, or use a provider that supports runtime changes.`);await t.updateNetwork(e)}async sealCredentials(){if(!this.agent)throw new Error("Agent not initialized. Call run() or executeCommand() first.");await this.agent.sealCredentials()}isSealed(){return this.agent?.isSealed()??!1}resolvedSkills(){return this.agent?.resolvedSkills()??[]}async collectArtifacts(e){if(!this.agent)throw new Error("Agent not initialized. Call run() or executeCommand() first.");return this.agent.collectArtifacts(e)}async interrupt(){if(!this.agent)return!1;let e=this.createStreamCallbacks();return this.agent.interrupt(e)}async uploadContext(e){return this.agent||await this.initializeAgent(),this.agent.uploadContext(e)}async uploadFiles(e){return this.agent||await this.initializeAgent(),this.agent.uploadFiles(e)}async uploadFileFromPath(e,t){return this.agent||await this.initializeAgent(),this.agent.uploadFileFromPath(e,t)}async getOutputFiles(e=!1){if(!this.agent)throw new Error("Agent not initialized. Call run() first.");return this.agent.getOutputFiles(e)}async checkpoint(e){if(!this.agent)throw new Error("Agent not initialized. Call run() first.");return this.agent.checkpoint(e)}_cachedGatewayOverrides=null;resolveGatewayOverrides(){if(this._cachedGatewayOverrides!==null)return this._cachedGatewayOverrides||void 0;try{let e=rXe(this.config.agent);if(!e.isDirectMode)return this._cachedGatewayOverrides={gatewayUrl:ia,gatewayApiKey:e.apiKey},this._cachedGatewayOverrides}catch{}this._cachedGatewayOverrides=void 0}async listCheckpoints(e){if(this.config.storage===void 0)throw new Error("Storage not configured. Call .withStorage().");return gXe(this.config.storage,this.resolveGatewayOverrides()||{}).listCheckpoints(e)}storage(){if(this.config.storage===void 0)throw new Error("Storage not configured. Call .withStorage().");return gXe(this.config.storage,this.resolveGatewayOverrides()||{})}getSession(){return this.agent?this.agent.getSession():this.config.sandboxId??null}async setSession(e){if(this.config.managedSecrets)throw new Error("setSession() cannot be used with withManagedSecrets(); managed secret grants are sandbox-scoped.");this.agent?await this.agent.setSession(e):(this.fallbackSandboxState="ready",this.fallbackAgentState="idle",this.fallbackHasRun=!0),this.config.sandboxId=e}status(){return this.agent?this.agent.status():{sandboxId:this.config.sandboxId??null,sandbox:this.fallbackSandboxState,agent:this.fallbackAgentState,activeProcessId:null,hasRun:this.fallbackHasRun,timestamp:new Date().toISOString()}}async pause(){if(this.agent){let e=this.createStreamCallbacks();await this.agent.pause(e);return}this.config.sandboxId&&this.config.sandbox&&(await(await this.config.sandbox.connect(this.config.sandboxId)).pause(),this.fallbackSandboxState="paused",this.fallbackAgentState="idle",this.emitLifecycleFromStatus("sandbox_pause"))}async resume(){if(this.agent){let e=this.createStreamCallbacks();await this.agent.resume(e);return}this.config.sandboxId&&this.config.sandbox&&(await this.config.sandbox.connect(this.config.sandboxId),this.fallbackSandboxState="ready",this.fallbackAgentState="idle",this.emitLifecycleFromStatus("sandbox_resume"))}async kill(){if(this.agent){let e=this.createStreamCallbacks();await this.agent.kill(e),this.config.sandboxId=void 0,this.fallbackSandboxState="stopped",this.fallbackAgentState="idle",this.fallbackHasRun=!1;return}this.config.sandboxId&&this.config.sandbox&&(await(await this.config.sandbox.connect(this.config.sandboxId)).kill(),this.fallbackSandboxState="stopped",this.fallbackAgentState="idle",this.fallbackHasRun=!1,this.emitLifecycleFromStatus("sandbox_killed"),this.config.sandboxId=void 0)}async getHost(e){return this.agent||await this.initializeAgent(),this.agent.getHost(e)}getSessionTag(){return this.agent?.getSessionTag()||null}getSessionTimestamp(){return this.agent?.getSessionTimestamp()||null}async flushObservability(){await this.agent?.flushObservability()}async getSessionCost(){if(!this.agent)throw new Error("No agent initialized. Call run() first.");return this.agent.getSessionCost()}async getRunCost(e){if(!this.agent)throw new Error("No agent initialized. Call run() first.");return this.agent.getRunCost(e)}},E9t=class{permits;queue=[];constructor(e){if(e<1)throw new Error("Semaphore max must be >= 1");this.permits=e}async use(e){await this.acquire();try{return await e()}finally{this.release()}}acquire(){return this.permits>0?(this.permits--,Promise.resolve()):new Promise(e=>this.queue.push(e))}release(){this.queue.length>0?this.queue.shift()():this.permits++}},wO=Symbol.for("evolve.SwarmResult"),EXe=class gZe extends Array{get success(){return this.filter(t=>t.status==="success")}get filtered(){return this.filter(t=>t.status==="filtered")}get error(){return this.filter(t=>t.status==="error")}static from(t){let n=new gZe;return n.push(...t),n}},ROn=class fB{config;semaphore;constructor(t={}){let n=t.concurrency??SQ;if(n>AB)throw new Error(`concurrency=${n} exceeds max ${AB}. For higher parallelism, scale horizontally with multiple processes.`);this.config={agent:t.agent,sandbox:t.sandbox,tag:t.tag??"swarm",concurrency:n,timeoutMs:t.timeoutMs??LO,workspaceMode:t.workspaceMode??"knowledge",retry:t.retry,mcpServers:t.mcpServers,skills:t.skills,integrations:t.integrations},this.semaphore=new E9t(this.config.concurrency)}async map(t){let{items:n,prompt:r,bestOf:a,verify:i}=t,s=t.retry??this.config.retry,o=this.generateOperationId(),c=t.timeoutMs??this.config.timeoutMs;if(a&&i)throw new Error("map() cannot use both bestOf and verify options simultaneously");let l=await Promise.all(n.map((u,d)=>a?this.executeMapItemWithBestOf(u,r,d,o,t,c,s):i?this.executeMapItemWithVerify(u,r,d,o,t,c,s):s?Dp(f=>this.executeMapItem(u,r,d,o,t,c,f),s,d):this.executeMapItem(u,r,d,o,t,c)));return EXe.from(l)}async filter(t){let{items:n,prompt:r,condition:a,verify:i}=t,s=t.retry??this.config.retry,o=this.generateOperationId(),c=t.timeoutMs??this.config.timeoutMs,l=await Promise.all(n.map((d,f)=>i?this.executeFilterItemWithVerify(d,r,f,o,t,c,s):s?Dp(p=>this.executeFilterItem(d,r,f,o,t,c,p),s,f):this.executeFilterItem(d,r,f,o,t,c))),u=[];for(let d of l)if(d.status==="error")u.push(d);else if(d.data!==null)try{a(d.data)?u.push(d):u.push({...d,status:"filtered"})}catch(f){u.push({...d,status:"error",data:null,error:`Condition function threw: ${f.message}`})}return EXe.from(u)}async reduce(t){let{items:n,prompt:r,verify:a}=t,i=t.retry??this.config.retry,s=this.generateOperationId(),o=t.timeoutMs??this.config.timeoutMs,c=[],l=[];n.forEach((I,T)=>{c.push(this.getFiles(I)),l.push(this.getIndex(I,T))});let u={};c.forEach((I,T)=>{Object.entries(I).forEach(([k,O])=>{u[`item_${l[T]}/${k}`]=O})});let d=wZ(u),f=Ev(mYt,{fileTree:d}),p=t.systemPrompt?`${f}
902
+ `).filter(Boolean),i=this.lastRunTimestamp?Math.floor(this.lastRunTimestamp/1e3)-2:0,s=[],o=`${n}/`;for(let f of a){let[p,m]=f.split("|");if(!p||!m)continue;let y=parseInt(m,10);i>0&&y<i||s.push(p)}let c={},l=await Promise.all(s.map(async f=>{try{let p=await t.files.read(f);return{relativePath:f.startsWith(o)?f.slice(o.length):f.split("/").pop()||f,content:p}}catch{return null}}));for(let f of l)f&&(c[f.relativePath]=f.content);if(!this.zodSchema&&!this.jsonSchema)return{files:c,data:null};let u=c["result.json"];if(!u)return{files:c,data:null,error:"Schema provided but agent did not create output/result.json"};let d=typeof u=="string"?u:new TextDecoder().decode(u);try{let f=JSON.parse(d);if(this.zodSchema){let p=this.zodSchema.safeParse(f);return p.success?{files:c,data:p.data}:{files:c,data:null,error:`Schema validation failed: ${p.error.message}`,rawData:d}}if(this.compiledValidator){if(this.compiledValidator(f))return{files:c,data:f};{let p=this.compiledValidator.errors?.map(m=>`${m.instancePath} ${m.message}`).join(", ")||"Unknown validation error";return{files:c,data:null,error:`Schema validation failed: ${p}`,rawData:d}}}return{files:c,data:null}}catch(f){return{files:c,data:null,error:`Failed to parse result.json: ${f.message}`,rawData:d}}}async checkpoint(e){if(!this.storage)throw new Error("Storage not configured. Call .withStorage().");if(!this.sandbox)throw new Error("No active sandbox. Call run() first.");let t=await uXe(this.sandbox,this.storage,this.agentConfig.type,this.workingDir,{tag:this.sessionTag,model:this.agentConfig.model||this.registry.defaultModel,workspaceMode:this.options.workspaceMode||"knowledge",comment:e?.comment,parentId:this.lastCheckpointId});return this.lastCheckpointId=t.id,t}getSession(){return this.sandbox?.sandboxId||this.options.sandboxId||null}async setSession(e){if(this.credentialsSealed)throw new Error("Agent credentials are sealed and this Evolve instance cannot switch sandboxes");if(this.options.managedSecrets)throw new Error("setSession() cannot be used with managed secrets; managed secret grants are sandbox-scoped.");if(this.options.sandboxCreateOptions?.user)throw new Error("setSession() cannot be used with a configured sandbox user; the user cannot be enforced on an existing sandbox.");if(this.activeCommand&&!await this.interrupt())throw new Error("Cannot switch session while an active process is running and could not be interrupted.");await this.rotateSession(),await this.closeProviderRuntimeToken(),await this.closeManagedSecretRuntimeToken(),await this.closeManagedBrowserSession(),this.options.sandboxId=e,this.sandbox=void 0,this.interruptedOperations.clear(),this.invalidateActiveOperation(),this.sandboxState="ready",this.agentState="idle",this.hasRun=!0,this.lastCheckpointId=void 0}async pause(e){this.sandbox&&(this.activeCommand&&await this.interrupt(e),await this.sandbox.pause(),this.sandboxState="paused",this.agentState="idle",this.emitLifecycle(e,"sandbox_pause"))}async resume(e){this.sandbox&&this.options.sandboxProvider&&(this.sandbox=await this.options.sandboxProvider.connect(this.sandbox.sandboxId),this.sandboxState="ready",this.agentState="idle",this.emitLifecycle(e,"sandbox_resume"))}async interrupt(e){if(!this.activeCommand&&!this.activeProcessId)return!1;let t=this.activeOperationId,n=this.activeOperationKind,r=!1;try{this.activeCommand?r=await this.activeCommand.kill():this.sandbox&&this.activeProcessId&&(r=await this.sandbox.commands.kill(this.activeProcessId))}catch{r=!1}if(!r)return this.sandboxState="running",this.agentState="running",!1;t!==null&&this.interruptedOperations.add(t),this.invalidateActiveOperation(),this.sandboxState="ready",this.agentState="interrupted";let a=n==="run"?"run_interrupted":"command_interrupted";return this.emitLifecycle(e,a),r}status(){let e=this.browserRuntimeInfo();return{sandboxId:this.getSession(),sandbox:this.sandboxState,agent:this.agentState,activeProcessId:this.activeProcessId,hasRun:this.hasRun,timestamp:new Date().toISOString(),...e?{browser:e}:{}}}async kill(e){await this.rotateSession();let t;try{this.activeCommand&&await this.interrupt(e),this.sandbox&&(await this.sandbox.kill(),this.sandbox=void 0)}catch(n){t=n}finally{await this.closeProviderRuntimeToken(),await this.closeManagedSecretRuntimeToken(),await this.closeManagedBrowserSession()}if(t)throw t;this.options.sandboxId=void 0,this.interruptedOperations.clear(),this.invalidateActiveOperation(),this.sandboxState="stopped",this.agentState="idle",this.hasRun=!1,this.lastCheckpointId=void 0,this.emitLifecycle(e,"sandbox_killed")}async getHost(e){return(await this.getSandbox()).getHost(e)}getAgentType(){return this.agentConfig.type}getSessionTag(){return!this.sandbox&&!this.sessionLogger?null:this.sessionTag}getSessionTimestamp(){return this.sessionLogger?.getTimestamp()||null}async flushObservability(){await this.sessionLogger?.flush()}async rotateSession(){let e=!!this.sessionLogger;this.sessionLogger&&(await this.sessionLogger.close(),this.sessionLogger=void 0),e&&(this.previousSessionTag=this.sessionTag),this.sessionTag=wXe(this.options.sessionTagPrefix||"evolve")}async fetchSpend(e){if(this.agentConfig.isDirectMode)throw new Error("Cost tracking requires gateway mode (set EVOLVE_API_KEY).");let t=this.agentConfig.apiKey;if(!t)throw new Error("Cost tracking requires an API key.");let n=process.env.EVOLVE_DASHBOARD_URL||ia,r=await fetch(`${n}/api/sessions/spend?${e}`,{headers:{Authorization:`Bearer ${t}`},signal:AbortSignal.timeout(1e4)});if(!r.ok){let a=await r.text().catch(()=>"");throw new Error(`Spend query failed (${r.status}): ${a}`)}return r}resolveSpendTag(){if(this.sandbox||this.sessionLogger)return this.sessionTag;if(this.previousSessionTag)return this.previousSessionTag;throw new Error("No session to query. Call run() first.")}normalizeRunCost(e,t){return{...e,asOf:e.asOf??t.asOf,isComplete:e.isComplete??t.isComplete,truncated:e.truncated??t.truncated}}normalizeSessionCost(e){let t={asOf:e.asOf,isComplete:e.isComplete,truncated:e.truncated};return{...e,runs:e.runs.map(n=>this.normalizeRunCost(n,t))}}async getSessionCost(){let e=this.resolveSpendTag(),t=new URLSearchParams({tag:e}),n=await(await this.fetchSpend(t)).json();return this.normalizeSessionCost(n)}async getRunCost(e){let t=this.resolveSpendTag();if("runId"in e){let i=new URLSearchParams({tag:t,runId:e.runId}),s=await(await this.fetchSpend(i)).json();return this.normalizeRunCost(s,{asOf:new Date().toISOString(),isComplete:!1,truncated:!1})}let n=await this.getSessionCost(),r=e.index>0?e.index-1:n.runs.length+e.index,a=n.runs[r];if(!a)throw new Error(`Run index ${e.index} out of range. Session has ${n.runs.length} run(s).`);return a}};function S9t(e){return(e||process.env.EVOLVE_DASHBOARD_URL||ia).replace(/\/$/,"")}function _9t(e){let t=e||process.env.EVOLVE_API_KEY;if(!t)throw new Error("Browser profiles require EVOLVE_API_KEY or an explicit apiKey");return t}async function w9t(e){return await e.text().catch(()=>"")}async function xXe(e,t,n={}){let r=await fetch(`${S9t(e?.dashboardUrl)}${t}`,{...n,headers:{Authorization:`Bearer ${_9t(e?.apiKey)}`,accept:"application/json",...n.body?{"content-type":"application/json"}:{},...n.headers||{}}});if(!r.ok)throw new Error(`Browser profiles request failed (${r.status}): ${await w9t(r)}`);return r.status===204?{}:await r.json()}var I9t=class{constructor(e={}){this.config=e}toMetadata(e){return{id:e.id,profile:e.profile,createdAt:e.createdAt||e.created_at||"",updatedAt:e.updatedAt||e.updated_at||"",lastUsedAt:e.lastUsedAt??e.last_used_at??null}}async list(){return{profiles:(await xXe(this.config,"/api/browser-profiles")).profiles.map(e=>this.toMetadata(e))}}async delete(e){return await xXe(this.config,"/api/browser-profiles",{method:"DELETE",body:JSON.stringify(e)})}};function x9t(e={}){return new I9t(e)}var Ov=class extends TXe.EventEmitter{config={};agent;fallbackSandboxState="stopped";fallbackAgentState="idle";fallbackHasRun=!1;constructor(){super()}on(e,t){return super.on(e,t)}off(e,t){return super.off(e,t)}emit(e,...t){return super.emit(e,...t)}withAgent(e){return e&&($Xe(e),WXe(e),this.config.agent=e,this._cachedGatewayOverrides=null),this}withSandbox(e){return this.config.sandbox=e,this}withSandboxCreateOptions(e){return this.config.sandboxCreateOptions={...e,envs:e.envs?{...e.envs}:void 0,metadata:e.metadata?{...e.metadata}:void 0},this}withWorkingDirectory(e){return this.config.workingDirectory=e,this}withWorkspaceMode(e){return this.config.workspaceMode=e,this}withSecrets(e){return this.config.secrets={...this.config.secrets,...e},this}withManagedSecrets(e){return this.config.managedSecrets=e,this}withSession(e){return this.config.sandboxId=e,this.agent||(this.fallbackSandboxState="ready",this.fallbackAgentState="idle",this.fallbackHasRun=!0),this}withSystemPrompt(e){return this.config.systemPrompt=e,this}withContext(e){return this.config.context={...this.config.context,...e},this}withFiles(e){return this.config.files={...this.config.files,...e},this}withMcpServers(e){return this.config.mcpServers={...this.config.mcpServers,...e},this}withBrowser(e={provider:"agent-browser",remote:!0}){return e===!1?delete this.config.browser:this.config.browser=e,this}withBrowserCredentials(e={}){return this.config.browserCredentials=e,this}withPlugins(e){let t=Array.isArray(e)?e:[e];return this.config.plugins=[...this.config.plugins??[],...t],this}withSkills(e){return this.config.skills=e,this}withSchema(e,t){return this.config.schema=e,t&&(vB(e)?console.warn("[Evolve] schemaOptions ignored for Zod schemas - use .passthrough(), .strip(), z.coerce instead"):this.config.schemaOptions=t),this}withSessionTagPrefix(e){return this.config.sessionTagPrefix=e,this}withObservability(e){return this.config.observability={...this.config.observability,...e},this}withIntegrations(e){return this.config.integrations=e,this}withStorage(e){return this.config.storage=e||{},this}static integrations=EYt;static browserCredentials=r9t;static browserProfiles=x9t;static managedSecrets=CB;async initializeAgent(){let e=rXe(this.config.agent),t=Tv(e.type);if(this.config.integrations&&e.isDirectMode)throw new Error("withIntegrations() is available only in gateway mode with EVOLVE_API_KEY");if(this.config.managedSecrets&&e.isDirectMode)throw new Error("withManagedSecrets() is available only in gateway mode with EVOLVE_API_KEY");if(this.config.managedSecrets&&this.config.sandboxId)throw new Error("withManagedSecrets() cannot be used with withSession(); managed secret grants are sandbox-scoped.");let n=RQ(this.config.managedSecrets,t);if(n&&this.config.sandbox&&!DZ(this.config.sandbox))throw new Error("withManagedSecrets() requires an Evolve-managed sandbox; remove withSandbox() or pass a managed sandbox provider.");let r=this.config.sandbox??(n?await qZ(e.apiKey):await Gjt()),a={},i,s,o=this.config.skills,c;if(this.config.browser){let d=WYt(this.config.browser);if(c=d,d.provider==="browser-use"){if(e.isDirectMode)throw new Error('withBrowser("browser-use") requires gateway mode. Use apiKey/EVOLVE_API_KEY instead of providerApiKey/direct mode.');a=bQ(e.apiKey)}if((d.provider==="actionbook"||d.provider==="agent-browser")&&d.managed){if(e.isDirectMode)throw new Error(`Managed browser provider "${d.provider}" requires gateway mode. Use apiKey/EVOLVE_API_KEY instead of providerApiKey/direct mode.`);i=d.provider==="actionbook"?lYt:uYt,s={provider:d.provider,apiKey:e.apiKey,dashboardUrl:process.env.EVOLVE_DASHBOARD_URL||ia,...d.profile?{profile:d.profile}:{}}}if(d.profile&&!d.managed)throw new Error('withBrowser({ profile }) requires managed remote browser mode. Use .withBrowser({ profile }) or .withBrowser({ provider: "agent-browser", remote: true, profile }).')}if(this.config.browserCredentials!==void 0){if(this.config.sandboxId)throw new Error("withBrowserCredentials() cannot be used with withSession(); browser login tokens are run-scoped.");if(e.isDirectMode)throw new Error("withBrowserCredentials() requires gateway mode. Use apiKey/EVOLVE_API_KEY instead of providerApiKey/direct mode.");if(!c||c.provider!=="agent-browser"||!c.managed)throw new Error('withBrowserCredentials() requires .withBrowser() or .withBrowser({ provider: "agent-browser", remote: true }).');if(this.config.mcpServers?.["browser-login"])throw new Error('withBrowserCredentials() reserves the "browser-login" MCP server name.')}let l=this.config.storage!==void 0?KXe(this.config.storage,!e.isDirectMode,ia,e.isDirectMode?void 0:e.apiKey):void 0,u={sandboxProvider:r,sandboxCreateOptions:this.config.sandboxCreateOptions,secrets:this.config.secrets,managedSecrets:n?{secrets:n,apiKey:e.apiKey,dashboardUrl:process.env.EVOLVE_DASHBOARD_URL||ia}:void 0,sandboxId:this.config.sandboxId,workingDirectory:this.config.workingDirectory,workspaceMode:this.config.workspaceMode,systemPrompt:this.config.systemPrompt,context:this.config.context,files:this.config.files,mcpServers:{...a,...this.config.mcpServers},browserPrompt:i,managedBrowser:s,browserCredentials:this.config.browserCredentials!==void 0?{apiKey:e.apiKey,dashboardUrl:process.env.EVOLVE_DASHBOARD_URL||ia,config:this.config.browserCredentials}:void 0,plugins:this.config.plugins,skills:o,schema:this.config.schema,schemaOptions:this.config.schemaOptions,sessionTagPrefix:this.config.sessionTagPrefix,observability:this.config.observability,integrations:this.config.integrations?{...this.config.integrations,apiKey:e.apiKey,dashboardUrl:process.env.EVOLVE_DASHBOARD_URL||ia}:void 0,providerRouting:e.isDirectMode?void 0:{apiKey:e.apiKey,dashboardUrl:process.env.EVOLVE_DASHBOARD_URL||ia},storage:l};this.agent=new b9t(e,u)}createStreamCallbacks(){let e=this.listenerCount("stdout")>0,t=this.listenerCount("stderr")>0,n=this.listenerCount("content")>0,r=this.listenerCount("lifecycle")>0;return{onStdout:e?a=>this.emit("stdout",a):void 0,onStderr:t?a=>this.emit("stderr",a):void 0,onContent:n?a=>this.emit("content",a):void 0,onLifecycle:r?a=>this.emit("lifecycle",a):void 0}}emitLifecycleFromStatus(e){if(this.listenerCount("lifecycle")===0)return;let t=this.status();this.emit("lifecycle",{sandboxId:t.sandboxId,sandbox:t.sandbox,agent:t.agent,timestamp:new Date().toISOString(),reason:e,...t.browser?{browser:t.browser}:{}})}async run({prompt:e,timeoutMs:t,background:n,from:r,checkpointComment:a,resume:i}){if(r&&this.config.sandboxId)throw new Error("Cannot use 'from' with 'withSession()' \u2014 restore requires a fresh sandbox.");this.agent||await this.initializeAgent();let s=this.createStreamCallbacks();return this.agent.run({prompt:e,timeoutMs:t,background:n,from:r,checkpointComment:a,resume:i},s)}async executeCommand(e,t={}){this.agent||await this.initializeAgent();let n=this.createStreamCallbacks();return this.agent.executeCommand(e,t,n)}async prepareSandbox(){this.agent||await this.initializeAgent();let e=this.createStreamCallbacks();return(await this.agent.getSandbox(e)).sandboxId}async updateNetwork(e){if(!this.agent)throw new Error("No sandbox yet. Call prepareSandbox(), run() or executeCommand() before updateNetwork().");let t=await this.agent.getSandbox(this.createStreamCallbacks());if(typeof t.updateNetwork!="function")throw new Error(`The ${this.config.sandbox?.providerType??"configured"} sandbox provider cannot change network policy after start. Create the sandbox with the policy it needs for its whole lifetime, or use a provider that supports runtime changes.`);await t.updateNetwork(e)}async sealCredentials(){if(!this.agent)throw new Error("Agent not initialized. Call run() or executeCommand() first.");await this.agent.sealCredentials()}isSealed(){return this.agent?.isSealed()??!1}resolvedSkills(){return this.agent?.resolvedSkills()??[]}async collectArtifacts(e){if(!this.agent)throw new Error("Agent not initialized. Call run() or executeCommand() first.");return this.agent.collectArtifacts(e)}async interrupt(){if(!this.agent)return!1;let e=this.createStreamCallbacks();return this.agent.interrupt(e)}async uploadContext(e){return this.agent||await this.initializeAgent(),this.agent.uploadContext(e)}async uploadFiles(e){return this.agent||await this.initializeAgent(),this.agent.uploadFiles(e)}async uploadFileFromPath(e,t){return this.agent||await this.initializeAgent(),this.agent.uploadFileFromPath(e,t)}async getOutputFiles(e=!1){if(!this.agent)throw new Error("Agent not initialized. Call run() first.");return this.agent.getOutputFiles(e)}async checkpoint(e){if(!this.agent)throw new Error("Agent not initialized. Call run() first.");return this.agent.checkpoint(e)}_cachedGatewayOverrides=null;resolveGatewayOverrides(){if(this._cachedGatewayOverrides!==null)return this._cachedGatewayOverrides||void 0;try{let e=rXe(this.config.agent);if(!e.isDirectMode)return this._cachedGatewayOverrides={gatewayUrl:ia,gatewayApiKey:e.apiKey},this._cachedGatewayOverrides}catch{}this._cachedGatewayOverrides=void 0}async listCheckpoints(e){if(this.config.storage===void 0)throw new Error("Storage not configured. Call .withStorage().");return gXe(this.config.storage,this.resolveGatewayOverrides()||{}).listCheckpoints(e)}storage(){if(this.config.storage===void 0)throw new Error("Storage not configured. Call .withStorage().");return gXe(this.config.storage,this.resolveGatewayOverrides()||{})}getSession(){return this.agent?this.agent.getSession():this.config.sandboxId??null}async setSession(e){if(this.config.managedSecrets)throw new Error("setSession() cannot be used with withManagedSecrets(); managed secret grants are sandbox-scoped.");this.agent?await this.agent.setSession(e):(this.fallbackSandboxState="ready",this.fallbackAgentState="idle",this.fallbackHasRun=!0),this.config.sandboxId=e}status(){return this.agent?this.agent.status():{sandboxId:this.config.sandboxId??null,sandbox:this.fallbackSandboxState,agent:this.fallbackAgentState,activeProcessId:null,hasRun:this.fallbackHasRun,timestamp:new Date().toISOString()}}async pause(){if(this.agent){let e=this.createStreamCallbacks();await this.agent.pause(e);return}this.config.sandboxId&&this.config.sandbox&&(await(await this.config.sandbox.connect(this.config.sandboxId)).pause(),this.fallbackSandboxState="paused",this.fallbackAgentState="idle",this.emitLifecycleFromStatus("sandbox_pause"))}async resume(){if(this.agent){let e=this.createStreamCallbacks();await this.agent.resume(e);return}this.config.sandboxId&&this.config.sandbox&&(await this.config.sandbox.connect(this.config.sandboxId),this.fallbackSandboxState="ready",this.fallbackAgentState="idle",this.emitLifecycleFromStatus("sandbox_resume"))}async kill(){if(this.agent){let e=this.createStreamCallbacks();await this.agent.kill(e),this.config.sandboxId=void 0,this.fallbackSandboxState="stopped",this.fallbackAgentState="idle",this.fallbackHasRun=!1;return}this.config.sandboxId&&this.config.sandbox&&(await(await this.config.sandbox.connect(this.config.sandboxId)).kill(),this.fallbackSandboxState="stopped",this.fallbackAgentState="idle",this.fallbackHasRun=!1,this.emitLifecycleFromStatus("sandbox_killed"),this.config.sandboxId=void 0)}async getHost(e){return this.agent||await this.initializeAgent(),this.agent.getHost(e)}getSessionTag(){return this.agent?.getSessionTag()||null}getSessionTimestamp(){return this.agent?.getSessionTimestamp()||null}async flushObservability(){await this.agent?.flushObservability()}async getSessionCost(){if(!this.agent)throw new Error("No agent initialized. Call run() first.");return this.agent.getSessionCost()}async getRunCost(e){if(!this.agent)throw new Error("No agent initialized. Call run() first.");return this.agent.getRunCost(e)}},E9t=class{permits;queue=[];constructor(e){if(e<1)throw new Error("Semaphore max must be >= 1");this.permits=e}async use(e){await this.acquire();try{return await e()}finally{this.release()}}acquire(){return this.permits>0?(this.permits--,Promise.resolve()):new Promise(e=>this.queue.push(e))}release(){this.queue.length>0?this.queue.shift()():this.permits++}},wO=Symbol.for("evolve.SwarmResult"),EXe=class gZe extends Array{get success(){return this.filter(t=>t.status==="success")}get filtered(){return this.filter(t=>t.status==="filtered")}get error(){return this.filter(t=>t.status==="error")}static from(t){let n=new gZe;return n.push(...t),n}},NOn=class fB{config;semaphore;constructor(t={}){let n=t.concurrency??SQ;if(n>AB)throw new Error(`concurrency=${n} exceeds max ${AB}. For higher parallelism, scale horizontally with multiple processes.`);this.config={agent:t.agent,sandbox:t.sandbox,tag:t.tag??"swarm",concurrency:n,timeoutMs:t.timeoutMs??LO,workspaceMode:t.workspaceMode??"knowledge",retry:t.retry,mcpServers:t.mcpServers,skills:t.skills,integrations:t.integrations},this.semaphore=new E9t(this.config.concurrency)}async map(t){let{items:n,prompt:r,bestOf:a,verify:i}=t,s=t.retry??this.config.retry,o=this.generateOperationId(),c=t.timeoutMs??this.config.timeoutMs;if(a&&i)throw new Error("map() cannot use both bestOf and verify options simultaneously");let l=await Promise.all(n.map((u,d)=>a?this.executeMapItemWithBestOf(u,r,d,o,t,c,s):i?this.executeMapItemWithVerify(u,r,d,o,t,c,s):s?Dp(f=>this.executeMapItem(u,r,d,o,t,c,f),s,d):this.executeMapItem(u,r,d,o,t,c)));return EXe.from(l)}async filter(t){let{items:n,prompt:r,condition:a,verify:i}=t,s=t.retry??this.config.retry,o=this.generateOperationId(),c=t.timeoutMs??this.config.timeoutMs,l=await Promise.all(n.map((d,f)=>i?this.executeFilterItemWithVerify(d,r,f,o,t,c,s):s?Dp(p=>this.executeFilterItem(d,r,f,o,t,c,p),s,f):this.executeFilterItem(d,r,f,o,t,c))),u=[];for(let d of l)if(d.status==="error")u.push(d);else if(d.data!==null)try{a(d.data)?u.push(d):u.push({...d,status:"filtered"})}catch(f){u.push({...d,status:"error",data:null,error:`Condition function threw: ${f.message}`})}return EXe.from(u)}async reduce(t){let{items:n,prompt:r,verify:a}=t,i=t.retry??this.config.retry,s=this.generateOperationId(),o=t.timeoutMs??this.config.timeoutMs,c=[],l=[];n.forEach((I,T)=>{c.push(this.getFiles(I)),l.push(this.getIndex(I,T))});let u={};c.forEach((I,T)=>{Object.entries(I).forEach(([k,O])=>{u[`item_${l[T]}/${k}`]=O})});let d=wZ(u),f=Ev(mYt,{fileTree:d}),p=t.systemPrompt?`${f}
903
903
 
904
904
  ${t.systemPrompt}`:f,m=(I,T,k)=>({operationId:s,operation:"reduce",tag:I.tag,sandboxId:I.sandboxId,swarmName:this.config.tag,operationName:t.name,inputCount:n.length,inputIndices:l,errorRetry:T,verifyRetry:k,...this.pipelineContextToMeta(t._pipelineContext)}),y=t.mcpServers??this.config.mcpServers,b=t.skills??this.config.skills,v=t.integrations??this.config.integrations,S=async(I,T,k,O)=>{let R=await this.semaphore.use(()=>this.execute(u,I,{systemPrompt:p,schema:t.schema,schemaOptions:t.schemaOptions,agent:t.agent,mcpServers:y,skills:b,integrations:v,tagPrefix:T,timeoutMs:o,observability:{swarmName:this.config.tag,operationName:t.name,operationId:s,operation:"reduce",role:"worker",errorRetry:k,verifyRetry:O&&O>1?O-1:void 0,...this.pipelineContextToObservability(t._pipelineContext)}})),B=m(R,k,O&&O>1?O-1:void 0);return R.error?{status:"error",data:null,files:R.files,meta:B,error:R.error,rawData:R.rawData}:{status:"success",data:R.data,files:R.files,meta:B}},w=`${this.config.tag}-reduce`;return a?this.runWithVerification((I,T,k)=>S(I,T,void 0,k),{originalPrompt:r,inputFiles:u,verifyConfig:a,timeoutMs:o,systemPrompt:p,schema:t.schema,mcpServers:y,skills:b,integrations:v,operationId:s,baseTag:w,retry:i,operation:"reduce",_pipelineContext:t._pipelineContext}):i?Dp(I=>{let T=I>1?I-1:void 0,k=T?`${w}-er${T}`:w;return S(r,k,T)},i):S(r,w)}async bestOf(t){let{item:n,prompt:r,config:a}=t,i=t.retry??this.config.retry,s=a.n??a.taskAgents?.length;if(s===void 0)throw new Error("bestOf requires n or taskAgents");if(s<2)throw new Error("bestOf requires n >= 2");let o=this.generateOperationId(),c=t.timeoutMs??this.config.timeoutMs,l=this.getFiles(n),u=a.mcpServers??this.config.mcpServers,d=a.judgeMcpServers??a.mcpServers??this.config.mcpServers,f=a.skills??this.config.skills,p=a.judgeSkills??a.skills??this.config.skills,m=a.integrations??this.config.integrations,y=a.judgeIntegrations??a.integrations??this.config.integrations,b=await Promise.all(Array.from({length:s},async(T,k)=>{let O=i?await Dp(R=>this.executeBestOfCandidate({inputFiles:l,prompt:r,candidateIndex:k,operationId:o,config:a,systemPrompt:t.systemPrompt,schema:t.schema,schemaOptions:t.schemaOptions,mcpServers:u,skills:f,integrations:m,timeoutMs:c,attempt:R}),i,k):await this.executeBestOfCandidate({inputFiles:l,prompt:r,candidateIndex:k,operationId:o,config:a,systemPrompt:t.systemPrompt,schema:t.schema,schemaOptions:t.schemaOptions,mcpServers:u,skills:f,integrations:m,timeoutMs:c});return a.onCandidateComplete?.(0,k,O.status==="success"?"success":"error"),O})),v=i?await Dp(T=>this.executeBestOfJudge({inputFiles:l,taskPrompt:r,candidates:b,config:a,timeoutMs:c,operationId:o,systemPrompt:t.systemPrompt,schema:t.schema,schemaOptions:t.schemaOptions,mcpServers:d,skills:p,integrations:y,attempt:T}),{...i,retryOn:void 0},0):await this.executeBestOfJudge({inputFiles:l,taskPrompt:r,candidates:b,config:a,timeoutMs:c,operationId:o,systemPrompt:t.systemPrompt,schema:t.schema,schemaOptions:t.schemaOptions,mcpServers:d,skills:p,integrations:y}),S=b.findIndex(T=>T.status==="success"),w=v.decision?.winner??(S>=0?S:0);a.onJudgeComplete?.(0,w,v.decision?.reasoning??"Judge failed to provide reasoning");let I={operationId:o,operation:"bestof-judge",tag:v.tag,sandboxId:v.sandboxId,swarmName:this.config.tag,operationName:t.name,candidateCount:s};return{winner:b[w]??b[0],winnerIndex:w,judgeReasoning:v.decision?.reasoning??"Judge failed to provide reasoning",judgeMeta:I,candidates:b}}async execute(t,n,r){let a=null,i="",s=r.tagPrefix,o={},c=null,l,u,d={...this.config.agent,...r.agent};try{a=new Ov().withAgent(d).withSandbox(this.config.sandbox).withWorkspaceMode(this.config.workspaceMode).withSessionTagPrefix(r.tagPrefix),r.schema&&a.withSchema(r.schema,r.schemaOptions),r.systemPrompt&&a.withSystemPrompt(r.systemPrompt),r.mcpServers&&a.withMcpServers(r.mcpServers),r.skills?.length&&a.withSkills(r.skills),r.integrations&&a.withIntegrations(r.integrations),r.observability&&a.withObservability(r.observability),Object.keys(t).length>0&&a.withContext(t);let f=await a.run({prompt:n,timeoutMs:r.timeoutMs});i=f.sandboxId,s=a.getSessionTag()??r.tagPrefix;let p=null;try{p=await a.getOutputFiles(!0),o=p.files}catch{}f.exitCode!==0?l=`Agent exited with code ${f.exitCode}`:r.schema?p?(c=p.data,p.error&&(l=p.error),p.rawData&&(u=p.rawData)):l="Failed to read output files from sandbox":c=o}catch(f){if(l=f.message,a){s=a.getSessionTag()??r.tagPrefix;try{o=(await a.getOutputFiles(!0)).files}catch{}}}finally{a&&await a.kill().catch(()=>{})}return{files:o,data:c,tag:s,sandboxId:i,error:l,rawData:u}}async executeMapItem(t,n,r,a,i,s,o=1){let c=this.getFiles(t),l=o>1?`${this.config.tag}-map-${r}-er${o-1}`:`${this.config.tag}-map-${r}`,u=this.evaluatePrompt(n,c,r);if(u instanceof Error)return this.buildErrorResult(`Prompt function threw: ${u.message}`,{operationId:a,operation:"map",tag:l,sandboxId:"",itemIndex:r});let d=i.mcpServers??this.config.mcpServers,f=i.skills??this.config.skills,p=i.integrations??this.config.integrations,m=await this.semaphore.use(()=>this.execute(c,u,{systemPrompt:i.systemPrompt,schema:i.schema,schemaOptions:i.schemaOptions,agent:i.agent,mcpServers:d,skills:f,integrations:p,tagPrefix:l,timeoutMs:s,observability:{swarmName:this.config.tag,operationName:i.name,operationId:a,operation:"map",itemIndex:r,role:"worker",errorRetry:o>1?o-1:void 0,...this.pipelineContextToObservability(i._pipelineContext)}})),y={operationId:a,operation:"map",tag:m.tag,sandboxId:m.sandboxId,swarmName:this.config.tag,operationName:i.name,itemIndex:r,errorRetry:o>1?o-1:void 0,...this.pipelineContextToMeta(i._pipelineContext)};return this.buildResult(m,y)}async executeMapItemWithVerify(t,n,r,a,i,s,o){let c=this.getFiles(t),l=`${this.config.tag}-map-${r}`,u=i.verify,d=i.mcpServers??this.config.mcpServers,f=i.skills??this.config.skills,p=i.integrations??this.config.integrations,m=this.evaluatePrompt(n,c,r);if(m instanceof Error)return this.buildErrorResult(`Prompt function threw: ${m.message}`,{operationId:a,operation:"map",tag:l,sandboxId:"",itemIndex:r});let y=async(b,v,S)=>{let w=await this.semaphore.use(()=>this.execute(c,b,{systemPrompt:i.systemPrompt,schema:i.schema,schemaOptions:i.schemaOptions,agent:i.agent,mcpServers:d,skills:f,integrations:p,tagPrefix:v,timeoutMs:s,observability:{swarmName:this.config.tag,operationName:i.name,operationId:a,operation:"map",itemIndex:r,role:"worker",verifyRetry:S&&S>1?S-1:void 0,...this.pipelineContextToObservability(i._pipelineContext)}})),I={operationId:a,operation:"map",tag:w.tag,sandboxId:w.sandboxId,swarmName:this.config.tag,operationName:i.name,itemIndex:r,verifyRetry:S&&S>1?S-1:void 0,...this.pipelineContextToMeta(i._pipelineContext)};return this.buildResult(w,I)};return this.runWithVerification(y,{originalPrompt:m,inputFiles:c,verifyConfig:u,timeoutMs:s,systemPrompt:i.systemPrompt,schema:i.schema,mcpServers:d,skills:f,integrations:p,operationId:a,baseTag:l,retry:o,itemIndex:r,operation:"map",_pipelineContext:i._pipelineContext})}async executeMapItemWithBestOf(t,n,r,a,i,s,o){let c=this.getFiles(t),l=`${this.config.tag}-map-${r}`,u=this.evaluatePrompt(n,c,r);if(u instanceof Error)return this.buildErrorResult(`Prompt function threw: ${u.message}`,{operationId:a,operation:"map",tag:l,sandboxId:"",itemIndex:r});let d=i.bestOf,f=d.n??d.taskAgents?.length;if(f===void 0||f<2)return this.buildErrorResult("bestOf requires n >= 2 or taskAgents with at least 2 elements",{operationId:a,operation:"map",tag:l,sandboxId:"",itemIndex:r});let p=i.mcpServers??this.config.mcpServers,m=d.mcpServers??p,y=d.judgeMcpServers??d.mcpServers??p,b=i.skills??this.config.skills,v=d.skills??b,S=d.judgeSkills??d.skills??b,w=i.integrations??this.config.integrations,I=d.integrations??w,T=d.judgeIntegrations??d.integrations??w,k=await Promise.all(Array.from({length:f},async(Pe,ee)=>{let E=o?await Dp(G=>this.executeBestOfCandidate({inputFiles:c,prompt:u,candidateIndex:ee,operationId:a,config:d,systemPrompt:i.systemPrompt,schema:i.schema,schemaOptions:i.schemaOptions,mcpServers:m,skills:v,integrations:I,timeoutMs:s,parentIndex:r,attempt:G,_pipelineContext:i._pipelineContext}),o,ee):await this.executeBestOfCandidate({inputFiles:c,prompt:u,candidateIndex:ee,operationId:a,config:d,systemPrompt:i.systemPrompt,schema:i.schema,schemaOptions:i.schemaOptions,mcpServers:m,skills:v,integrations:I,timeoutMs:s,parentIndex:r,_pipelineContext:i._pipelineContext});return d.onCandidateComplete?.(r,ee,E.status==="success"?"success":"error"),E})),O=o?await Dp(Pe=>this.executeBestOfJudge({inputFiles:c,taskPrompt:u,candidates:k,config:d,timeoutMs:s,operationId:a,systemPrompt:i.systemPrompt,schema:i.schema,schemaOptions:i.schemaOptions,mcpServers:y,skills:S,integrations:T,parentIndex:r,attempt:Pe,_pipelineContext:i._pipelineContext}),{...o,retryOn:void 0},0):await this.executeBestOfJudge({inputFiles:c,taskPrompt:u,candidates:k,config:d,timeoutMs:s,operationId:a,systemPrompt:i.systemPrompt,schema:i.schema,schemaOptions:i.schemaOptions,mcpServers:y,skills:S,integrations:T,parentIndex:r,_pipelineContext:i._pipelineContext}),R=k.findIndex(Pe=>Pe.status==="success"),B=O.decision?.winner??(R>=0?R:0),V=k[B]??k[0];d.onJudgeComplete?.(r,B,O.decision?.reasoning??"Judge failed to provide reasoning");let L={operationId:a,operation:"bestof-judge",tag:O.tag,sandboxId:O.sandboxId,swarmName:this.config.tag,operationName:i.name,candidateCount:f,...this.pipelineContextToMeta(i._pipelineContext)};return{...V,meta:{...V.meta,operation:"map",swarmName:this.config.tag,operationName:i.name,itemIndex:r,...this.pipelineContextToMeta(i._pipelineContext)},bestOf:{winnerIndex:B,judgeReasoning:O.decision?.reasoning??"Judge failed to provide reasoning",judgeMeta:L,candidates:k}}}async executeFilterItem(t,n,r,a,i,s,o=1){let c=this.getFiles(t),l=o>1?`${this.config.tag}-filter-${r}-er${o-1}`:`${this.config.tag}-filter-${r}`,u=i.mcpServers??this.config.mcpServers,d=i.skills??this.config.skills,f=i.integrations??this.config.integrations,p=await this.semaphore.use(()=>this.execute(c,n,{systemPrompt:i.systemPrompt,schema:i.schema,schemaOptions:i.schemaOptions,agent:i.agent,mcpServers:u,skills:d,integrations:f,tagPrefix:l,timeoutMs:s,observability:{swarmName:this.config.tag,operationName:i.name,operationId:a,operation:"filter",itemIndex:r,role:"worker",errorRetry:o>1?o-1:void 0,...this.pipelineContextToObservability(i._pipelineContext)}})),m={operationId:a,operation:"filter",tag:p.tag,sandboxId:p.sandboxId,swarmName:this.config.tag,operationName:i.name,itemIndex:r,errorRetry:o>1?o-1:void 0,...this.pipelineContextToMeta(i._pipelineContext)};return this.buildResult(p,m,c)}async executeFilterItemWithVerify(t,n,r,a,i,s,o){let c=this.getFiles(t),l=`${this.config.tag}-filter-${r}`,u=i.verify,d=i.mcpServers??this.config.mcpServers,f=i.skills??this.config.skills,p=i.integrations??this.config.integrations,m=async(y,b,v)=>{let S=await this.semaphore.use(()=>this.execute(c,y,{systemPrompt:i.systemPrompt,schema:i.schema,schemaOptions:i.schemaOptions,agent:i.agent,mcpServers:d,skills:f,integrations:p,tagPrefix:b,timeoutMs:s,observability:{swarmName:this.config.tag,operationName:i.name,operationId:a,operation:"filter",itemIndex:r,role:"worker",verifyRetry:v&&v>1?v-1:void 0,...this.pipelineContextToObservability(i._pipelineContext)}})),w={operationId:a,operation:"filter",tag:S.tag,sandboxId:S.sandboxId,swarmName:this.config.tag,operationName:i.name,itemIndex:r,verifyRetry:v&&v>1?v-1:void 0,...this.pipelineContextToMeta(i._pipelineContext)};return this.buildResult(S,w,c)};return this.runWithVerification(m,{originalPrompt:n,inputFiles:c,verifyConfig:u,timeoutMs:s,systemPrompt:i.systemPrompt,schema:i.schema,mcpServers:d,skills:f,integrations:p,operationId:a,baseTag:l,retry:o,itemIndex:r,operation:"filter",_pipelineContext:i._pipelineContext})}async executeBestOfCandidate(t){let{inputFiles:n,prompt:r,candidateIndex:a,operationId:i,config:s,timeoutMs:o,parentIndex:c,attempt:l=1,_pipelineContext:u}=t,d=c!==void 0?`${this.config.tag}-map-${c}-bestof-cand-${a}`:`${this.config.tag}-bestof-cand-${a}`,f=l>1?`${d}-er${l-1}`:d,p=await this.semaphore.use(()=>this.execute(n,r,{systemPrompt:t.systemPrompt,schema:t.schema,schemaOptions:t.schemaOptions,agent:s.taskAgents?.[a],mcpServers:t.mcpServers,skills:t.skills,integrations:t.integrations,tagPrefix:f,timeoutMs:o,observability:{swarmName:this.config.tag,operationId:i,operation:"map",itemIndex:c,role:"candidate",candidateIndex:a,errorRetry:l>1?l-1:void 0,...this.pipelineContextToObservability(u)}})),m={operationId:i,operation:"bestof-cand",tag:p.tag,sandboxId:p.sandboxId,swarmName:this.config.tag,itemIndex:a,errorRetry:l>1?l-1:void 0,candidateIndex:a,...this.pipelineContextToMeta(u)};return this.buildResult(p,m)}buildJudgeContext(t){let n=this.buildEvaluatorContext({inputFiles:t.inputFiles,taskPrompt:t.taskPrompt,systemPrompt:t.systemPrompt,schema:t.schema});return t.candidates.forEach((r,a)=>{r.status==="error"&&(n[`candidate_${a}/_failed.txt`]=`STATUS: FAILED
905
905
 
@@ -91,6 +91,10 @@ from .hosted import (
91
91
  JobImportProgress,
92
92
  JobImportSkippedTrial,
93
93
  JobImportSource,
94
+ JobTaskLink,
95
+ TrialTaskLink,
96
+ TASK_LINKED_BY,
97
+ TASK_LINK_REASONS,
94
98
  DatasetPage,
95
99
  DatasetPreflight,
96
100
  PreflightDeferredCheck,
@@ -493,7 +497,7 @@ async def list_checkpoints(
493
497
  await store.close()
494
498
 
495
499
 
496
- __version__ = '0.0.55.dev1239'
500
+ __version__ = '0.0.55.dev1246'
497
501
 
498
502
  __all__ = [
499
503
  # Main classes
@@ -696,6 +700,10 @@ __all__ = [
696
700
  'JobImportProgress',
697
701
  'JobImportSkippedTrial',
698
702
  'JobImportSource',
703
+ 'JobTaskLink',
704
+ 'TrialTaskLink',
705
+ 'TASK_LINKED_BY',
706
+ 'TASK_LINK_REASONS',
699
707
  'ApiKey',
700
708
  'AuthStatus',
701
709
  'Organization',
@@ -51,6 +51,7 @@ from typing import (
51
51
  Literal,
52
52
  NoReturn,
53
53
  Optional,
54
+ Tuple,
54
55
  TypedDict,
55
56
  Union,
56
57
  get_args,
@@ -1285,6 +1286,32 @@ class UploadProvenance:
1285
1286
  #: The aggregated REPORTED figures, or None on jobs ingested before the
1286
1287
  #: field existed.
1287
1288
  reported_totals: Optional[ReportedTotals]
1289
+ #: One row per task of the uploaded job, in archive order
1290
+ #: (:class:`JobTaskLink`): how many of its trials linked to a stored
1291
+ #: task — and so analyze with the task folder — and why the rest did
1292
+ #: not. None only on jobs ingested before the link law existed.
1293
+ task_links: Optional[List['JobTaskLink']] = None
1294
+
1295
+
1296
+ @dataclass
1297
+ class JobTaskLink:
1298
+ """One task of an uploaded job, rolled up (spec ``JobTaskLink``): its
1299
+ trial count, how many linked to a stored task (``n_linked`` analyze with
1300
+ the task folder, ``n_unlinked`` without), the rule that linked them
1301
+ (:class:`TrialTaskLink` ``linked_by``, or ``'none'`` when no trial of
1302
+ the task linked), the ``name@version`` refs they linked to (sorted;
1303
+ normally one), the unlinked trials per reason, and the refs an
1304
+ ambiguous hash matched."""
1305
+ #: The platform task key (the leaf of a registry-qualified name).
1306
+ task_name: str
1307
+ n_trials: int
1308
+ n_linked: int
1309
+ n_unlinked: int
1310
+ linked_by: str
1311
+ datasets: List[str] = field(default_factory=list)
1312
+ #: Unlinked trials per reason (``TrialTaskLink.link_reason`` words → counts).
1313
+ link_reasons: Dict[str, int] = field(default_factory=dict)
1314
+ candidates: List[str] = field(default_factory=list)
1288
1315
 
1289
1316
 
1290
1317
  @dataclass
@@ -2266,6 +2293,37 @@ class TrialUploadProvenance:
2266
2293
  original_task_name: str
2267
2294
  #: The uploaded figures, or None when the archive carried none.
2268
2295
  reported_agent_result: Optional[ReportedAgentResult]
2296
+ #: How this trial linked to a stored task, or why not. None only on
2297
+ #: trials ingested before the link law existed (never guessed).
2298
+ link: Optional['TrialTaskLink'] = None
2299
+
2300
+
2301
+ @dataclass
2302
+ class TrialTaskLink:
2303
+ """How THIS uploaded trial linked to a stored task, or why not (spec
2304
+ ``TrialTaskLink``). ``linked_by`` is the ONE rule the ingest ran for the
2305
+ job: ``'dataset_flag'`` (the ``dataset`` hint, by task name — the
2306
+ override), ``'job_dataset_record'`` (the job's own config.json named a
2307
+ dataset the caller can see; linked by Harbor's task hash inside it),
2308
+ ``'task_hash'`` (nothing named; exactly one visible dataset carries the
2309
+ hash), or ``'none'`` — and then ``link_reason`` says why:
2310
+ ``'hash_mismatch'``, ``'task_not_in_dataset'``, ``'no_dataset_named'``,
2311
+ ``'dataset_ambiguous'`` (``candidates`` names the datasets; the hint
2312
+ decides), ``'no_hash_match'``, ``'no_task_digest'``. A linked trial
2313
+ analyzes with the task folder in ``/app/task``; an unlinked one
2314
+ without it."""
2315
+ linked_by: str
2316
+ #: Set exactly when ``linked_by`` is ``'none'``.
2317
+ link_reason: Optional[str]
2318
+ #: The linked dataset's name; None when not linked.
2319
+ dataset: Optional[str]
2320
+ #: The linked dataset version's label; None when not linked.
2321
+ version: Optional[str]
2322
+ #: The trial's lock.json ``task.digest`` (``sha256:<hex>``), or None
2323
+ #: when the archive carried none.
2324
+ task_digest: Optional[str]
2325
+ #: The ``name@version`` refs an ambiguous hash matched; [] otherwise.
2326
+ candidates: List[str] = field(default_factory=list)
2269
2327
 
2270
2328
 
2271
2329
  @dataclass
@@ -3145,6 +3203,13 @@ class JobImport:
3145
3203
  #: One entry per skipped trial, in archive order, from COMPLETED on
3146
3204
  #: ([] when none). None until COMPLETED.
3147
3205
  skipped_trials: Optional[List[JobImportSkippedTrial]] = None
3206
+ #: The ingested job's per-task task-linkage roll-up — the same rows the
3207
+ #: job serves as ``upload.task_links``, so a watcher learns from the
3208
+ #: import alone which tasks will analyze with their task folder and why
3209
+ #: the rest will not. None until COMPLETED, None again when the job is
3210
+ #: gone (like ``job_id``), and None on a job ingested before the link
3211
+ #: law existed.
3212
+ task_links: Optional[List[JobTaskLink]] = None
3148
3213
  failure: Optional[JobImportFailure] = None
3149
3214
  #: None until the worker's first report (a QUEUED import).
3150
3215
  progress: Optional[JobImportProgress] = None
@@ -3710,6 +3775,98 @@ def _map_upload_provenance(data: Any) -> Optional[UploadProvenance]:
3710
3775
  original_job_name=original_name if isinstance(original_name, str) else None,
3711
3776
  uploaded_at=uploaded_at,
3712
3777
  reported_totals=reported_totals,
3778
+ task_links=_map_task_links(data.get('task_links')),
3779
+ )
3780
+
3781
+
3782
+ #: The contract's ``TaskLinkedBy`` enum (spec/openapi.yaml), in its order.
3783
+ TASK_LINKED_BY: Tuple[str, ...] = ('dataset_flag', 'job_dataset_record', 'task_hash', 'none')
3784
+ #: The contract's ``TaskLinkReason`` enum (spec/openapi.yaml), in its order.
3785
+ TASK_LINK_REASONS: Tuple[str, ...] = (
3786
+ 'hash_mismatch',
3787
+ 'task_not_in_dataset',
3788
+ 'no_dataset_named',
3789
+ 'dataset_ambiguous',
3790
+ 'no_hash_match',
3791
+ 'no_task_digest',
3792
+ )
3793
+
3794
+
3795
+ def _string_list(value: Any) -> Optional[List[str]]:
3796
+ if not isinstance(value, list) or not all(isinstance(member, str) for member in value):
3797
+ return None
3798
+ return list(value)
3799
+
3800
+
3801
+ def _genuine_int(value: Any) -> bool:
3802
+ return isinstance(value, int) and not isinstance(value, bool)
3803
+
3804
+
3805
+ def _map_task_links(raw: Any) -> Optional[List[JobTaskLink]]:
3806
+ """The per-task link roll-up (spec ``JobTaskLink[]``), defensively:
3807
+ absent (a pre-feature upload, or an older server) and malformed both
3808
+ read None — and one malformed row nulls the WHOLE list, because a
3809
+ shorter list would be a false count of the job's tasks. The counts
3810
+ must be genuine integers, the rule a member of the contract's enum,
3811
+ every reason key a member too."""
3812
+ if not isinstance(raw, list):
3813
+ return None
3814
+ out: List[JobTaskLink] = []
3815
+ for entry in raw:
3816
+ if not isinstance(entry, dict):
3817
+ return None
3818
+ task_name = entry.get('task_name')
3819
+ linked_by = entry.get('linked_by')
3820
+ counts = (entry.get('n_trials'), entry.get('n_linked'), entry.get('n_unlinked'))
3821
+ if not isinstance(task_name, str) or linked_by not in TASK_LINKED_BY:
3822
+ return None
3823
+ if not all(_genuine_int(count) and count >= 0 for count in counts):
3824
+ return None
3825
+ datasets = _string_list(entry.get('datasets'))
3826
+ candidates = _string_list(entry.get('candidates'))
3827
+ reasons_raw = entry.get('link_reasons')
3828
+ if datasets is None or candidates is None or not isinstance(reasons_raw, dict):
3829
+ return None
3830
+ reasons: Dict[str, int] = {}
3831
+ for reason, count in reasons_raw.items():
3832
+ if reason not in TASK_LINK_REASONS or not _genuine_int(count):
3833
+ return None
3834
+ reasons[reason] = count
3835
+ out.append(JobTaskLink(
3836
+ task_name=task_name,
3837
+ n_trials=counts[0],
3838
+ n_linked=counts[1],
3839
+ n_unlinked=counts[2],
3840
+ linked_by=linked_by,
3841
+ datasets=datasets,
3842
+ link_reasons=reasons,
3843
+ candidates=candidates,
3844
+ ))
3845
+ return out
3846
+
3847
+
3848
+ def _map_trial_task_link(raw: Any) -> Optional[TrialTaskLink]:
3849
+ """One trial's link fact (spec ``TrialTaskLink``), defensively: absent
3850
+ (a pre-feature trial, or an older server) and malformed both read None
3851
+ — never a fabricated link."""
3852
+ if not isinstance(raw, dict):
3853
+ return None
3854
+ linked_by = raw.get('linked_by')
3855
+ reason = raw.get('link_reason')
3856
+ if linked_by not in TASK_LINKED_BY:
3857
+ return None
3858
+ if reason is not None and reason not in TASK_LINK_REASONS:
3859
+ return None
3860
+ candidates = _string_list(raw.get('candidates')) if 'candidates' in raw else []
3861
+ if candidates is None:
3862
+ return None
3863
+ return TrialTaskLink(
3864
+ linked_by=linked_by,
3865
+ link_reason=reason,
3866
+ dataset=raw.get('dataset') if isinstance(raw.get('dataset'), str) else None,
3867
+ version=raw.get('version') if isinstance(raw.get('version'), str) else None,
3868
+ task_digest=raw.get('task_digest') if isinstance(raw.get('task_digest'), str) else None,
3869
+ candidates=candidates,
3713
3870
  )
3714
3871
 
3715
3872
 
@@ -4150,6 +4307,7 @@ def _map_trial_upload_provenance(data: Any) -> Optional[TrialUploadProvenance]:
4150
4307
  if isinstance(reported, dict)
4151
4308
  else None
4152
4309
  ),
4310
+ link=_map_trial_task_link(data.get('link')),
4153
4311
  )
4154
4312
 
4155
4313
 
@@ -4439,6 +4597,7 @@ def _map_job_import(data: Dict[str, Any]) -> JobImport:
4439
4597
  if isinstance(data.get('n_trials_skipped'), int) else None
4440
4598
  ),
4441
4599
  skipped_trials=_map_job_import_skipped_trials(data.get('skipped_trials')),
4600
+ task_links=_map_task_links(data.get('task_links')),
4442
4601
  failure=failure,
4443
4602
  progress=_map_job_import_progress(data.get('progress')),
4444
4603
  created_at=data.get('created_at') if isinstance(data.get('created_at'), str) else None,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: evolve-sdk
3
- Version: 0.0.55.dev1239
3
+ Version: 0.0.55.dev1246
4
4
  Summary: Pythonic SDK for multi-agent orchestration in E2B sandboxes
5
5
  Author-email: "Swarmlink, Inc." <brandomagnani@evolvingmachines.ai>
6
6
  License: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "evolve-sdk"
7
- version = "0.0.55.dev1239"
7
+ version = "0.0.55.dev1246"
8
8
  description = "Pythonic SDK for multi-agent orchestration in E2B sandboxes"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"