@agentstep/agent-sdk 0.4.30 → 0.4.32

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 (182) hide show
  1. package/dist/auth/middleware.js +8 -8
  2. package/dist/backends/claude/args.js +6 -6
  3. package/dist/backends/claude/index.js +7 -7
  4. package/dist/backends/codex/auth.js +6 -6
  5. package/dist/backends/codex/index.js +10 -10
  6. package/dist/backends/factory/auth.js +6 -6
  7. package/dist/backends/factory/index.js +7 -7
  8. package/dist/backends/gemini/auth.js +6 -6
  9. package/dist/backends/gemini/index.js +10 -10
  10. package/dist/backends/opencode/auth.js +6 -6
  11. package/dist/backends/opencode/index.js +10 -10
  12. package/dist/backends/pi/auth.js +6 -6
  13. package/dist/backends/pi/index.js +7 -7
  14. package/dist/backends/registry.js +24 -24
  15. package/dist/{chunk-QWGJS6V6.js → chunk-2CPZFRJJ.js} +13 -9
  16. package/dist/{chunk-NZATVUV2.js → chunk-2GIX4HAT.js} +1 -1
  17. package/dist/{chunk-67D4I5AE.js → chunk-2I35VGHX.js} +4 -4
  18. package/dist/{chunk-XQEMI2MI.js → chunk-2PPB644A.js} +1 -1
  19. package/dist/{chunk-LR4TA74O.js → chunk-2VED3F37.js} +21 -17
  20. package/dist/{chunk-HFBC2TOG.js → chunk-3HL62Y77.js} +2 -2
  21. package/dist/{chunk-YTC6ST5T.js → chunk-3HTE2CIM.js} +5 -5
  22. package/dist/{chunk-LOAFGJWC.js → chunk-3K4KIYEZ.js} +2 -2
  23. package/dist/{chunk-65XR7JU6.js → chunk-3NQH2EUI.js} +4 -4
  24. package/dist/{chunk-DL2BACWC.js → chunk-45JXGYJK.js} +9 -8
  25. package/dist/{chunk-BQOFXJSK.js → chunk-47XDZFF4.js} +3 -3
  26. package/dist/chunk-4XXQAVKE.js +34 -0
  27. package/dist/{chunk-4PVPM2WC.js → chunk-5EKQBD2H.js} +7 -7
  28. package/dist/{chunk-HA5FIXGQ.js → chunk-5EQJOUWM.js} +1 -1
  29. package/dist/{chunk-IFXD4DH5.js → chunk-5IGBMS2U.js} +1 -1
  30. package/dist/{chunk-SXTHM67U.js → chunk-6GP5IKXE.js} +1 -1
  31. package/dist/{chunk-HEDK5J34.js → chunk-6IYCBW4J.js} +1 -1
  32. package/dist/{chunk-4C7XJI2V.js → chunk-6POQAFEC.js} +1 -1
  33. package/dist/{chunk-6VENJOPG.js → chunk-7CD4QT5R.js} +2 -2
  34. package/dist/{chunk-5QTDZQ2H.js → chunk-7VVH435L.js} +4 -4
  35. package/dist/{chunk-SW75SNDB.js → chunk-A3KHFT7I.js} +7 -7
  36. package/dist/{chunk-BBYQMNGK.js → chunk-AR2TM7CR.js} +1 -1
  37. package/dist/{chunk-BKBC43KV.js → chunk-C46UG6GQ.js} +1 -1
  38. package/dist/{chunk-KA33M67F.js → chunk-C6AXM3M7.js} +2 -2
  39. package/dist/{chunk-XTTHH5MF.js → chunk-CREPPDHX.js} +1 -1
  40. package/dist/{chunk-F3BVYYRX.js → chunk-DYK2WTYW.js} +5 -5
  41. package/dist/{chunk-NT2AI5IE.js → chunk-E7DD7F7J.js} +6 -6
  42. package/dist/{chunk-BJK4SGWG.js → chunk-EA4JOLDI.js} +2 -2
  43. package/dist/{chunk-4B7PQTTS.js → chunk-EUIR2ADY.js} +8 -8
  44. package/dist/{chunk-REGPK5NG.js → chunk-FXLUSECC.js} +1 -1
  45. package/dist/chunk-G7KUVNDY.js +80 -0
  46. package/dist/{chunk-H62LRJJP.js → chunk-GUXT2F26.js} +42 -12
  47. package/dist/{chunk-YGTC5UP5.js → chunk-H7UKW666.js} +1 -1
  48. package/dist/{chunk-TRGHIMCR.js → chunk-IDIOFF35.js} +33 -4
  49. package/dist/{chunk-L43UD7PK.js → chunk-JCW3ZRES.js} +1 -1
  50. package/dist/{chunk-VMILIALE.js → chunk-JVNWYWAT.js} +15 -15
  51. package/dist/{chunk-6EQZSMIZ.js → chunk-JZL4L54R.js} +4 -4
  52. package/dist/{chunk-2JKOYBUO.js → chunk-K7NOZ7LV.js} +1 -1
  53. package/dist/{chunk-NC4FHDIP.js → chunk-KLN6HPYM.js} +1 -1
  54. package/dist/{chunk-YIOKUA23.js → chunk-L2RX552S.js} +7 -7
  55. package/dist/{chunk-JSKZXF5J.js → chunk-L5RW66H5.js} +1 -1
  56. package/dist/{chunk-AXISFTHX.js → chunk-MPTQYBVB.js} +2 -2
  57. package/dist/{chunk-FIJTBRZ5.js → chunk-MQQ44IGX.js} +4 -4
  58. package/dist/{chunk-ULQOJ3WO.js → chunk-N3QIXC2B.js} +2 -2
  59. package/dist/{chunk-VC25NYHW.js → chunk-OGJUSGF7.js} +1 -1
  60. package/dist/{chunk-AP2N4R6D.js → chunk-P26WOAA3.js} +1 -1
  61. package/dist/{chunk-H3O7QBOQ.js → chunk-P3PHXVMA.js} +1 -1
  62. package/dist/{chunk-BSVZAXLI.js → chunk-PKYFFSLU.js} +6 -6
  63. package/dist/{chunk-ULJVEN67.js → chunk-QBMPITYC.js} +3 -3
  64. package/dist/{chunk-DNV6JZLZ.js → chunk-QEIG7FXY.js} +1 -1
  65. package/dist/{chunk-TRQX5AIZ.js → chunk-QHBXWPSO.js} +4 -4
  66. package/dist/{chunk-JYUJQHPR.js → chunk-QO2C2PBW.js} +3 -3
  67. package/dist/{chunk-SLAOS6JN.js → chunk-R5T4LJSK.js} +2 -2
  68. package/dist/{chunk-46XURNM7.js → chunk-R6V363NP.js} +4 -4
  69. package/dist/{chunk-X2EEOO6Q.js → chunk-RRASSOJX.js} +5 -5
  70. package/dist/{chunk-2DRBKIGQ.js → chunk-RVR6C22M.js} +1 -1
  71. package/dist/{chunk-CL3DUJRJ.js → chunk-S7HHYBY3.js} +2 -2
  72. package/dist/{chunk-EIR2TG5I.js → chunk-S7W3KJYH.js} +1 -1
  73. package/dist/{chunk-7V277COF.js → chunk-SUGSHXND.js} +7 -7
  74. package/dist/{chunk-5NBZZZKH.js → chunk-TH7WJLZC.js} +8 -8
  75. package/dist/{chunk-7DSZOBSQ.js → chunk-TIHUJDA6.js} +2 -2
  76. package/dist/{chunk-HF6HORZZ.js → chunk-TPPLYCJF.js} +2 -2
  77. package/dist/{chunk-PFWTQ43U.js → chunk-TQYD3NYI.js} +1 -1
  78. package/dist/{chunk-VUADJZRV.js → chunk-UJAD2NQ7.js} +3 -3
  79. package/dist/{chunk-WHV4YUQB.js → chunk-USYY3L7G.js} +6 -6
  80. package/dist/{chunk-M36DF445.js → chunk-V2R7RWVY.js} +1 -1
  81. package/dist/{chunk-EFDAVLKN.js → chunk-V7MTIMPB.js} +9 -7
  82. package/dist/{chunk-XUNTHJIE.js → chunk-WCDWL6ED.js} +7 -0
  83. package/dist/{chunk-QV5WI73T.js → chunk-WCNGMBIE.js} +3 -3
  84. package/dist/{chunk-FGQFNIRI.js → chunk-WQARLGBG.js} +3 -3
  85. package/dist/{chunk-EN3ICYTL.js → chunk-WQHRP3JL.js} +181 -15
  86. package/dist/{chunk-S5HVHCAK.js → chunk-X6IQ57SC.js} +8 -8
  87. package/dist/{chunk-WP5EWNGJ.js → chunk-X7VVDJ6T.js} +4 -4
  88. package/dist/{chunk-UF3NB27E.js → chunk-XMTKYR64.js} +8 -8
  89. package/dist/{chunk-7UJ2PIXJ.js → chunk-YD3T4PBA.js} +2 -2
  90. package/dist/{chunk-EFCCO74P.js → chunk-YDZ7PCQO.js} +3 -3
  91. package/dist/{chunk-JN3G4Y4L.js → chunk-YNOONYPO.js} +4 -4
  92. package/dist/{chunk-H7Z4BWRI.js → chunk-YVHFSCAX.js} +2 -2
  93. package/dist/{chunk-3KLJGU75.js → chunk-YYEDFQJY.js} +18 -12
  94. package/dist/{chunk-LHHBOQUR.js → chunk-ZMJ4EP4C.js} +2 -0
  95. package/dist/{chunk-TXUUUO5R.js → chunk-ZTH5JRZG.js} +8 -8
  96. package/dist/{chunk-TZZMVXFM.js → chunk-ZUDHZG7B.js} +4 -4
  97. package/dist/{chunk-7GNSB22P.js → chunk-ZVXIZ2JD.js} +8 -8
  98. package/dist/config/index.js +5 -5
  99. package/dist/containers/client.js +6 -6
  100. package/dist/containers/exec.js +6 -6
  101. package/dist/containers/lifecycle.js +42 -37
  102. package/dist/containers/setup.js +8 -8
  103. package/dist/containers/warm-pool.js +21 -0
  104. package/dist/db/agents.js +6 -6
  105. package/dist/db/api_keys.js +5 -5
  106. package/dist/db/audit.js +3 -3
  107. package/dist/db/batch.js +10 -10
  108. package/dist/db/client.js +2 -2
  109. package/dist/db/credentials.js +3 -3
  110. package/dist/db/drizzle.js +4 -4
  111. package/dist/db/environments.js +6 -6
  112. package/dist/db/events.js +5 -5
  113. package/dist/db/files.js +5 -5
  114. package/dist/db/memory.js +5 -5
  115. package/dist/db/migrations.js +1 -1
  116. package/dist/db/proxy.js +5 -5
  117. package/dist/db/schema.js +1 -1
  118. package/dist/db/session-resources.js +5 -5
  119. package/dist/db/sessions.js +7 -7
  120. package/dist/db/sync.js +5 -5
  121. package/dist/db/tenants.js +3 -3
  122. package/dist/db/traces.js +5 -5
  123. package/dist/db/upstream_keys.js +3 -3
  124. package/dist/db/vaults.js +6 -6
  125. package/dist/handlers/agents.js +53 -52
  126. package/dist/handlers/api_keys.js +54 -53
  127. package/dist/handlers/audit.js +54 -53
  128. package/dist/handlers/batch.js +54 -53
  129. package/dist/handlers/credentials.js +54 -53
  130. package/dist/handlers/environments.js +54 -53
  131. package/dist/handlers/events.js +57 -56
  132. package/dist/handlers/files.js +54 -53
  133. package/dist/handlers/index.js +103 -102
  134. package/dist/handlers/license.js +53 -52
  135. package/dist/handlers/memory.js +54 -53
  136. package/dist/handlers/metrics.js +53 -52
  137. package/dist/handlers/models.js +54 -53
  138. package/dist/handlers/providers.js +53 -52
  139. package/dist/handlers/resources.js +53 -52
  140. package/dist/handlers/sessions.js +56 -55
  141. package/dist/handlers/settings.js +53 -52
  142. package/dist/handlers/skills-write.js +53 -52
  143. package/dist/handlers/skills.js +54 -53
  144. package/dist/handlers/stream.js +53 -52
  145. package/dist/handlers/tenants.js +54 -53
  146. package/dist/handlers/threads.js +53 -52
  147. package/dist/handlers/traces.js +54 -53
  148. package/dist/handlers/upstream_keys.js +56 -55
  149. package/dist/handlers/vaults.js +53 -52
  150. package/dist/handlers/whoami.js +53 -52
  151. package/dist/http.js +52 -51
  152. package/dist/index.js +66 -65
  153. package/dist/init.js +49 -48
  154. package/dist/lib/model-registry.js +6 -6
  155. package/dist/lib/skills-cache.js +6 -6
  156. package/dist/observability/otlp.js +12 -12
  157. package/dist/observability/redactor.js +8 -8
  158. package/dist/providers/apple-container.js +2 -2
  159. package/dist/providers/docker.js +1 -1
  160. package/dist/providers/fly.js +5 -5
  161. package/dist/providers/modal.js +5 -5
  162. package/dist/providers/podman.js +24 -21
  163. package/dist/providers/registry.js +1 -1
  164. package/dist/providers/resolve-secrets.js +7 -7
  165. package/dist/providers/sprites.js +8 -7
  166. package/dist/providers/upstream-keys.js +11 -11
  167. package/dist/providers/vercel.js +5 -5
  168. package/dist/proxy/forward.js +6 -6
  169. package/dist/queue/index.js +6 -6
  170. package/dist/sessions/bus.js +10 -10
  171. package/dist/sessions/driver.js +42 -41
  172. package/dist/sessions/grader.js +5 -5
  173. package/dist/sessions/secrets.js +8 -8
  174. package/dist/sessions/sweeper.js +39 -38
  175. package/dist/sessions/threads.js +42 -41
  176. package/dist/shutdown.js +40 -39
  177. package/dist/sync/anthropic.js +10 -10
  178. package/dist/sync/container-file-sync.js +6 -6
  179. package/dist/sync/file-sync.js +17 -17
  180. package/package.json +1 -1
  181. package/dist/chunk-RMZRSYIJ.js +0 -31
  182. /package/dist/{chunk-C6JEPQ7T.js → chunk-WPK4ZPMG.js} +0 -0
@@ -2,17 +2,17 @@ import {
2
2
  init_ids,
3
3
  newId
4
4
  } from "./chunk-F4WUVOLE.js";
5
+ import {
6
+ init_clock,
7
+ nowMs
8
+ } from "./chunk-HFDLUBWN.js";
5
9
  import {
6
10
  getDrizzle,
7
11
  init_drizzle
8
- } from "./chunk-SLAOS6JN.js";
12
+ } from "./chunk-R5T4LJSK.js";
9
13
  import {
10
14
  schema_exports
11
- } from "./chunk-LHHBOQUR.js";
12
- import {
13
- init_clock,
14
- nowMs
15
- } from "./chunk-HFDLUBWN.js";
15
+ } from "./chunk-ZMJ4EP4C.js";
16
16
 
17
17
  // src/db/api_keys.ts
18
18
  init_drizzle();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getConfig
3
- } from "./chunk-EFDAVLKN.js";
3
+ } from "./chunk-V7MTIMPB.js";
4
4
 
5
5
  // src/backends/gemini/auth.ts
6
6
  function buildGeminiAuthEnv() {
@@ -1,14 +1,14 @@
1
+ import {
2
+ init_clock,
3
+ nowMs
4
+ } from "./chunk-HFDLUBWN.js";
1
5
  import {
2
6
  getDrizzle,
3
7
  init_drizzle
4
- } from "./chunk-SLAOS6JN.js";
8
+ } from "./chunk-R5T4LJSK.js";
5
9
  import {
6
10
  schema_exports
7
- } from "./chunk-LHHBOQUR.js";
8
- import {
9
- init_clock,
10
- nowMs
11
- } from "./chunk-HFDLUBWN.js";
11
+ } from "./chunk-ZMJ4EP4C.js";
12
12
 
13
13
  // src/config/index.ts
14
14
  init_drizzle();
@@ -53,7 +53,9 @@ function loadConfig() {
53
53
  ollamaUrl: process.env.OLLAMA_URL || readSetting("ollama_url") || "http://localhost:11434",
54
54
  anthropicPassthroughEnabled: parseBool(
55
55
  process.env.ANTHROPIC_PASSTHROUGH_ENABLED ?? readSetting("anthropic_passthrough_enabled")
56
- )
56
+ ),
57
+ warmPoolSize: num(process.env.WARM_POOL_SIZE, 0),
58
+ warmPoolTtlMs: num(process.env.WARM_POOL_TTL_MS, 3e5)
57
59
  };
58
60
  }
59
61
  function parseBool(v) {
@@ -459,6 +459,13 @@ function runMigrations(db) {
459
459
  if (envCols3.some((c) => c.name === "template_sprite")) {
460
460
  db.exec(`ALTER TABLE environments RENAME COLUMN template_sprite TO template_sandbox`);
461
461
  }
462
+ const sessColsQuota = db.prepare(`PRAGMA table_info(sessions)`).all();
463
+ if (!sessColsQuota.some((c) => c.name === "max_tokens")) {
464
+ db.exec(`ALTER TABLE sessions ADD COLUMN max_tokens INTEGER DEFAULT NULL`);
465
+ }
466
+ if (!sessColsQuota.some((c) => c.name === "max_wall_duration_ms")) {
467
+ db.exec(`ALTER TABLE sessions ADD COLUMN max_wall_duration_ms INTEGER DEFAULT NULL`);
468
+ }
462
469
  }
463
470
  var init_migrations = __esm({
464
471
  "src/db/migrations.ts"() {
@@ -12,15 +12,15 @@ import {
12
12
  listMemories,
13
13
  listMemoryStores,
14
14
  updateMemory
15
- } from "./chunk-7V277COF.js";
15
+ } from "./chunk-SUGSHXND.js";
16
16
  import {
17
17
  jsonOk,
18
18
  routeWrap
19
- } from "./chunk-LOAFGJWC.js";
19
+ } from "./chunk-3K4KIYEZ.js";
20
20
  import {
21
21
  getDb,
22
22
  init_client
23
- } from "./chunk-4C7XJI2V.js";
23
+ } from "./chunk-6POQAFEC.js";
24
24
  import {
25
25
  badRequest,
26
26
  conflict,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  forwardToAnthropic
3
- } from "./chunk-L43UD7PK.js";
3
+ } from "./chunk-JCW3ZRES.js";
4
4
  import {
5
5
  isAnthropicApiKey,
6
6
  isPassthroughAllowedPath
@@ -8,10 +8,10 @@ import {
8
8
  import {
9
9
  findByRawKey,
10
10
  hydratePermissions
11
- } from "./chunk-WHV4YUQB.js";
11
+ } from "./chunk-USYY3L7G.js";
12
12
  import {
13
13
  getConfig
14
- } from "./chunk-EFDAVLKN.js";
14
+ } from "./chunk-V7MTIMPB.js";
15
15
  import {
16
16
  unauthorized
17
17
  } from "./chunk-EZYKRG4W.js";
@@ -1,21 +1,21 @@
1
- import {
2
- resolveVaultSecrets
3
- } from "./chunk-IFXD4DH5.js";
4
1
  import {
5
2
  dockerProvider
6
- } from "./chunk-RMZRSYIJ.js";
3
+ } from "./chunk-4XXQAVKE.js";
4
+ import {
5
+ resolveVaultSecrets
6
+ } from "./chunk-5IGBMS2U.js";
7
7
  import {
8
8
  appendEvent
9
- } from "./chunk-TRQX5AIZ.js";
9
+ } from "./chunk-QHBXWPSO.js";
10
10
  import {
11
11
  getSession,
12
12
  getSessionRow,
13
13
  setSessionSandbox
14
- } from "./chunk-QWGJS6V6.js";
14
+ } from "./chunk-2CPZFRJJ.js";
15
15
  import {
16
16
  deleteSprite,
17
17
  listSprites
18
- } from "./chunk-REGPK5NG.js";
18
+ } from "./chunk-FXLUSECC.js";
19
19
  import {
20
20
  allSessionSandboxes,
21
21
  countInEnv,
@@ -24,20 +24,29 @@ import {
24
24
  } from "./chunk-EFOIR7R3.js";
25
25
  import {
26
26
  resolveContainerProvider
27
- } from "./chunk-C6JEPQ7T.js";
27
+ } from "./chunk-WPK4ZPMG.js";
28
28
  import {
29
29
  getEnvironment,
30
- getEnvironmentRow
31
- } from "./chunk-S5HVHCAK.js";
30
+ getEnvironmentRow,
31
+ listEnvironments
32
+ } from "./chunk-X6IQ57SC.js";
33
+ import {
34
+ addWarm,
35
+ claimWarm,
36
+ countInflight,
37
+ countWarm,
38
+ decrementInflight,
39
+ incrementInflight
40
+ } from "./chunk-G7KUVNDY.js";
32
41
  import {
33
42
  getAgent
34
- } from "./chunk-TXUUUO5R.js";
43
+ } from "./chunk-ZTH5JRZG.js";
35
44
  import {
36
45
  resolveBackend
37
- } from "./chunk-4B7PQTTS.js";
46
+ } from "./chunk-EUIR2ADY.js";
38
47
  import {
39
48
  getConfig
40
- } from "./chunk-EFDAVLKN.js";
49
+ } from "./chunk-V7MTIMPB.js";
41
50
  import {
42
51
  init_clock,
43
52
  nowMs
@@ -48,6 +57,7 @@ import {
48
57
 
49
58
  // src/containers/lifecycle.ts
50
59
  init_clock();
60
+ import { ulid } from "ulid";
51
61
  var lcLog = (...args) => {
52
62
  if (process.env.DEBUG_LIFECYCLE === "1") console.log(...args);
53
63
  };
@@ -94,7 +104,8 @@ async function installSkills(sandboxName, provider, skills, engine) {
94
104
  }
95
105
  }
96
106
  function deriveSandboxName(sessionId) {
97
- return `${SANDBOX_NAME_PREFIX}${sessionId.replace(/^sess_/, "").toLowerCase()}`;
107
+ const tail = sessionId.replace(/^[a-z]+_/, "").toLowerCase();
108
+ return `${SANDBOX_NAME_PREFIX}${tail}`;
98
109
  }
99
110
  async function acquireForFirstTurn(sessionId) {
100
111
  const row = getSessionRow(sessionId);
@@ -109,7 +120,8 @@ async function acquireForFirstTurn(sessionId) {
109
120
  `environment is not ready (state=${env.state})`
110
121
  );
111
122
  }
112
- if (countInEnv(env.id) >= getConfig().maxSandboxesPerEnv) {
123
+ const config = getConfig();
124
+ if (countInEnv(env.id) + countWarm(env.id) >= config.maxSandboxesPerEnv) {
113
125
  throw new ApiError(503, "server_busy", "env sandbox pool exhausted");
114
126
  }
115
127
  const agent = getAgent(row.agent_id, row.agent_version);
@@ -128,6 +140,84 @@ async function acquireForFirstTurn(sessionId) {
128
140
  }
129
141
  }
130
142
  const sp = wrapProviderWithSecrets(provider, secrets);
143
+ const warm = claimWarm(env.id, backend.name, provider.name);
144
+ if (warm) {
145
+ lcLog(`[lifecycle] ${sessionId} claimed warm container: ${warm.sandboxName}`);
146
+ const name2 = warm.sandboxName;
147
+ try {
148
+ if (agent.engine === "claude") {
149
+ const customTools = agent.tools.filter(
150
+ (t) => t.type === "custom"
151
+ );
152
+ const allBridgeTools = [...customTools];
153
+ if (agent.threads_enabled) {
154
+ allBridgeTools.push({
155
+ type: "custom",
156
+ name: "spawn_agent",
157
+ description: "Spawn a sub-agent to handle a task. Returns the sub-agent's response.",
158
+ input_schema: {
159
+ type: "object",
160
+ properties: {
161
+ agent_id: { type: "string", description: "ID of the agent to spawn" },
162
+ prompt: { type: "string", description: "Task for the sub-agent" }
163
+ },
164
+ required: ["agent_id", "prompt"]
165
+ }
166
+ });
167
+ }
168
+ if (allBridgeTools.length > 0) {
169
+ const { installToolBridge } = await import("./backends/claude/index.js");
170
+ await installToolBridge(name2, allBridgeTools, sp);
171
+ }
172
+ if (agent.confirmation_mode) {
173
+ const { installPermissionHook } = await import("./backends/claude/index.js");
174
+ await installPermissionHook(name2, sp);
175
+ }
176
+ }
177
+ if (agent.skills && agent.skills.length > 0) {
178
+ lcLog(`[lifecycle] ${sessionId} installing ${agent.skills.length} skill(s) on warm container...`);
179
+ await installSkills(name2, sp, agent.skills, agent.engine);
180
+ }
181
+ } catch (err) {
182
+ await sp.delete(name2).catch(() => {
183
+ });
184
+ throw err;
185
+ }
186
+ const { listResources: listSessionResources2 } = await import("./db/session-resources.js");
187
+ const tableResources2 = listSessionResources2(sessionId);
188
+ if (tableResources2.length > 0) {
189
+ const mapped = tableResources2.map((r) => {
190
+ if (r.type === "file") return { type: "file", file_id: r.file_id, mount_path: r.mount_path };
191
+ if (r.type === "github_repository") {
192
+ const checkout = r.checkout;
193
+ return {
194
+ type: "github_repository",
195
+ repository_url: r.url,
196
+ mount_path: r.mount_path,
197
+ branch: checkout?.type === "branch" ? checkout.name : void 0,
198
+ commit: checkout?.type === "commit" ? checkout.name : void 0
199
+ };
200
+ }
201
+ return { type: "uri", uri: r.url, mount_path: r.mount_path };
202
+ });
203
+ await provisionResources(name2, mapped, sp);
204
+ } else {
205
+ const session = getSession(sessionId);
206
+ if (session?.resources && session.resources.length > 0) {
207
+ await provisionResources(name2, session.resources, sp);
208
+ }
209
+ }
210
+ register({
211
+ sandboxName: name2,
212
+ envId: env.id,
213
+ sessionId,
214
+ createdAt: nowMs(),
215
+ vaultSecrets: Object.keys(secrets).length > 0 ? secrets : void 0
216
+ });
217
+ setSessionSandbox(sessionId, name2);
218
+ void replenishWarmPool(env.id, backend.name, provider, secrets);
219
+ return name2;
220
+ }
131
221
  const name = deriveSandboxName(sessionId);
132
222
  lcLog(`[lifecycle] ${sessionId} creating container via ${sp.name}...`);
133
223
  try {
@@ -234,6 +324,80 @@ async function acquireForFirstTurn(sessionId) {
234
324
  setSessionSandbox(sessionId, name);
235
325
  return name;
236
326
  }
327
+ function effectiveWarmPoolSize(envId) {
328
+ const cfg = getConfig();
329
+ const envObj = getEnvironment(envId);
330
+ return envObj?.config?.warm_pool_size ?? cfg.warmPoolSize;
331
+ }
332
+ async function replenishWarmPool(envId, engine, provider, secrets) {
333
+ if (!provider.supportsWarmPool) return;
334
+ const target = effectiveWarmPoolSize(envId);
335
+ if (target <= 0) return;
336
+ if (countWarm(envId) + countInflight(envId) >= target) return;
337
+ const cfg = getConfig();
338
+ if (countInEnv(envId) + countWarm(envId) + countInflight(envId) >= cfg.maxSandboxesPerEnv) return;
339
+ incrementInflight(envId);
340
+ try {
341
+ const sp = wrapProviderWithSecrets(provider, secrets);
342
+ const name = `ca-warm-${ulid().toLowerCase()}`;
343
+ lcLog(`[warm-pool] creating warm container for env=${envId} engine=${engine}: ${name}`);
344
+ await sp.create({ name });
345
+ const backend = resolveBackend(engine);
346
+ await backend.prepareOnSandbox(name, sp);
347
+ const cfg2 = getConfig();
348
+ addWarm({
349
+ sandboxName: name,
350
+ envId,
351
+ engine,
352
+ provider: provider.name,
353
+ createdAt: nowMs(),
354
+ expiresAt: nowMs() + cfg2.warmPoolTtlMs,
355
+ vaultSecrets: Object.keys(secrets).length > 0 ? secrets : void 0
356
+ });
357
+ lcLog(`[warm-pool] warm container ready: ${name} (env=${envId})`);
358
+ } catch (err) {
359
+ console.warn(`[warm-pool] replenish failed for env=${envId} engine=${engine}:`, err);
360
+ } finally {
361
+ decrementInflight(envId);
362
+ }
363
+ }
364
+ async function fillWarmPools() {
365
+ const cfg = getConfig();
366
+ if (cfg.warmPoolSize <= 0) return;
367
+ const envs = listEnvironments({ includeArchived: false, limit: 100 });
368
+ const readyEnvs = envs.filter((e) => e.state === "ready");
369
+ if (readyEnvs.length === 0) return;
370
+ const CONCURRENCY = 3;
371
+ let active = 0;
372
+ let idx = 0;
373
+ async function processNext() {
374
+ while (idx < readyEnvs.length) {
375
+ if (active >= CONCURRENCY) {
376
+ await new Promise((r) => setTimeout(r, 0));
377
+ continue;
378
+ }
379
+ const env = readyEnvs[idx++];
380
+ active++;
381
+ void fillOneEnv(env).finally(() => active--);
382
+ }
383
+ }
384
+ void processNext();
385
+ }
386
+ async function fillOneEnv(env) {
387
+ const target = effectiveWarmPoolSize(env.id);
388
+ if (target <= 0) return;
389
+ try {
390
+ const provider = await resolveContainerProvider(env.config?.provider);
391
+ if (!provider.supportsWarmPool) return;
392
+ const backend = resolveBackend("claude");
393
+ const needed = target - countWarm(env.id) - countInflight(env.id);
394
+ for (let i = 0; i < needed; i++) {
395
+ void replenishWarmPool(env.id, backend.name, provider, {});
396
+ }
397
+ } catch (err) {
398
+ console.warn(`[warm-pool] fillOneEnv failed for env=${env.id}:`, err);
399
+ }
400
+ }
237
401
  async function provisionResources(sandboxName, resources, provider) {
238
402
  await provider.exec(sandboxName, ["mkdir", "-p", "/mnt/session/resources", "/mnt/session/uploads", "/mnt/session/outputs"]);
239
403
  const MAX_RESOURCE_BYTES = 50 * 1024 * 1024;
@@ -405,6 +569,8 @@ export {
405
569
  wrapProviderWithSecrets,
406
570
  installSkills,
407
571
  acquireForFirstTurn,
572
+ replenishWarmPool,
573
+ fillWarmPools,
408
574
  provisionResources,
409
575
  releaseSession,
410
576
  reconcileOrphanSandboxes,
@@ -1,22 +1,22 @@
1
1
  import {
2
2
  DEFAULT_TENANT_ID
3
- } from "./chunk-BBYQMNGK.js";
3
+ } from "./chunk-AR2TM7CR.js";
4
4
  import {
5
5
  init_ids,
6
6
  newId
7
7
  } from "./chunk-F4WUVOLE.js";
8
- import {
9
- getDrizzle,
10
- init_drizzle
11
- } from "./chunk-SLAOS6JN.js";
12
- import {
13
- schema_exports
14
- } from "./chunk-LHHBOQUR.js";
15
8
  import {
16
9
  init_clock,
17
10
  nowMs,
18
11
  toIso
19
12
  } from "./chunk-HFDLUBWN.js";
13
+ import {
14
+ getDrizzle,
15
+ init_drizzle
16
+ } from "./chunk-R5T4LJSK.js";
17
+ import {
18
+ schema_exports
19
+ } from "./chunk-ZMJ4EP4C.js";
20
20
 
21
21
  // src/db/environments.ts
22
22
  init_drizzle();
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  listTraces
3
- } from "./chunk-SXTHM67U.js";
3
+ } from "./chunk-6GP5IKXE.js";
4
4
  import {
5
5
  jsonOk,
6
6
  routeWrap
7
- } from "./chunk-LOAFGJWC.js";
7
+ } from "./chunk-3K4KIYEZ.js";
8
8
  import {
9
9
  exportTrace
10
- } from "./chunk-F3BVYYRX.js";
10
+ } from "./chunk-DYK2WTYW.js";
11
11
  import {
12
12
  listEventsByTrace,
13
13
  rowToManagedEvent
14
- } from "./chunk-5NBZZZKH.js";
14
+ } from "./chunk-TH7WJLZC.js";
15
15
  import {
16
16
  badRequest,
17
17
  notFound
@@ -1,32 +1,32 @@
1
1
  import {
2
2
  resolveRemoteSessionId
3
- } from "./chunk-YIOKUA23.js";
3
+ } from "./chunk-L2RX552S.js";
4
4
  import {
5
5
  assertResourceTenant
6
6
  } from "./chunk-23UKWXJH.js";
7
7
  import {
8
8
  authenticateAndIntercept
9
- } from "./chunk-FGQFNIRI.js";
9
+ } from "./chunk-WQARLGBG.js";
10
10
  import {
11
11
  forwardToAnthropic
12
- } from "./chunk-L43UD7PK.js";
12
+ } from "./chunk-JCW3ZRES.js";
13
13
  import {
14
14
  ensureInitialized
15
- } from "./chunk-LR4TA74O.js";
15
+ } from "./chunk-2VED3F37.js";
16
16
  import {
17
17
  getProxiedTenantId,
18
18
  isProxied
19
- } from "./chunk-NT2AI5IE.js";
19
+ } from "./chunk-E7DD7F7J.js";
20
20
  import {
21
21
  subscribe
22
- } from "./chunk-TRQX5AIZ.js";
22
+ } from "./chunk-QHBXWPSO.js";
23
23
  import {
24
24
  getSession
25
- } from "./chunk-QWGJS6V6.js";
25
+ } from "./chunk-2CPZFRJJ.js";
26
26
  import {
27
27
  getDb,
28
28
  init_client
29
- } from "./chunk-4C7XJI2V.js";
29
+ } from "./chunk-6POQAFEC.js";
30
30
  import {
31
31
  notFound,
32
32
  toResponse
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  jsonOk,
3
3
  routeWrap
4
- } from "./chunk-LOAFGJWC.js";
4
+ } from "./chunk-3K4KIYEZ.js";
5
5
  import {
6
6
  readSetting,
7
7
  writeSetting
8
- } from "./chunk-EFDAVLKN.js";
8
+ } from "./chunk-V7MTIMPB.js";
9
9
  import {
10
10
  badRequest
11
11
  } from "./chunk-EZYKRG4W.js";
@@ -5,15 +5,15 @@ import {
5
5
  import {
6
6
  jsonOk,
7
7
  routeWrap
8
- } from "./chunk-LOAFGJWC.js";
8
+ } from "./chunk-3K4KIYEZ.js";
9
9
  import {
10
10
  getSession,
11
11
  listSessions
12
- } from "./chunk-QWGJS6V6.js";
12
+ } from "./chunk-2CPZFRJJ.js";
13
13
  import {
14
14
  getDb,
15
15
  init_client
16
- } from "./chunk-4C7XJI2V.js";
16
+ } from "./chunk-6POQAFEC.js";
17
17
  import {
18
18
  notFound
19
19
  } from "./chunk-EZYKRG4W.js";
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  disableUpstreamKey,
3
3
  selectNextUpstreamKey
4
- } from "./chunk-YGTC5UP5.js";
4
+ } from "./chunk-H7UKW666.js";
5
5
  import {
6
6
  listEntries
7
- } from "./chunk-7GNSB22P.js";
7
+ } from "./chunk-ZVXIZ2JD.js";
8
8
  import {
9
9
  getSession
10
- } from "./chunk-QWGJS6V6.js";
10
+ } from "./chunk-2CPZFRJJ.js";
11
11
  import {
12
12
  getConfig
13
- } from "./chunk-EFDAVLKN.js";
13
+ } from "./chunk-V7MTIMPB.js";
14
14
 
15
15
  // src/providers/upstream-keys.ts
16
16
  var CONSECUTIVE_FAIL_THRESHOLD = 3;
@@ -4,11 +4,11 @@ import {
4
4
  getSources,
5
5
  getStats,
6
6
  searchSkills
7
- } from "./chunk-H3O7QBOQ.js";
7
+ } from "./chunk-P3PHXVMA.js";
8
8
  import {
9
9
  jsonOk,
10
10
  routeWrap
11
- } from "./chunk-LOAFGJWC.js";
11
+ } from "./chunk-3K4KIYEZ.js";
12
12
 
13
13
  // src/handlers/skills.ts
14
14
  async function handleGetSkillsCatalog(request) {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  syncAndCreateSession
3
- } from "./chunk-46XURNM7.js";
3
+ } from "./chunk-R6V363NP.js";
4
4
  import {
5
5
  resolveRemoteSessionId,
6
6
  upsertSync
7
- } from "./chunk-YIOKUA23.js";
7
+ } from "./chunk-L2RX552S.js";
8
8
  import {
9
9
  assertResourceTenant,
10
10
  tenantFilter
@@ -14,14 +14,14 @@ import {
14
14
  } from "./chunk-DC2UMEQH.js";
15
15
  import {
16
16
  kickoffEnvironmentSetup
17
- } from "./chunk-KA33M67F.js";
17
+ } from "./chunk-C6AXM3M7.js";
18
18
  import {
19
19
  jsonOk,
20
20
  routeWrap
21
- } from "./chunk-LOAFGJWC.js";
21
+ } from "./chunk-3K4KIYEZ.js";
22
22
  import {
23
23
  forwardToAnthropic
24
- } from "./chunk-L43UD7PK.js";
24
+ } from "./chunk-JCW3ZRES.js";
25
25
  import {
26
26
  errors_exports,
27
27
  init_errors
@@ -31,18 +31,18 @@ import {
31
31
  isProxied,
32
32
  markProxied,
33
33
  unmarkProxied
34
- } from "./chunk-NT2AI5IE.js";
34
+ } from "./chunk-E7DD7F7J.js";
35
35
  import {
36
36
  dropActor,
37
37
  getActor
38
38
  } from "./chunk-LAWTTG2E.js";
39
39
  import {
40
40
  releaseSession
41
- } from "./chunk-EN3ICYTL.js";
41
+ } from "./chunk-WQHRP3JL.js";
42
42
  import {
43
43
  appendEvent,
44
44
  dropEmitter
45
- } from "./chunk-TRQX5AIZ.js";
45
+ } from "./chunk-QHBXWPSO.js";
46
46
  import {
47
47
  archiveSession,
48
48
  createSession,
@@ -50,13 +50,13 @@ import {
50
50
  listSessions,
51
51
  updateSessionMutable,
52
52
  updateSessionStatus
53
- } from "./chunk-QWGJS6V6.js";
53
+ } from "./chunk-2CPZFRJJ.js";
54
54
  import {
55
55
  getEnvironment
56
- } from "./chunk-S5HVHCAK.js";
56
+ } from "./chunk-X6IQ57SC.js";
57
57
  import {
58
58
  getAgent
59
- } from "./chunk-TXUUUO5R.js";
59
+ } from "./chunk-ZTH5JRZG.js";
60
60
  import {
61
61
  init_clock,
62
62
  nowMs
@@ -64,7 +64,7 @@ import {
64
64
  import {
65
65
  getDb,
66
66
  init_client
67
- } from "./chunk-4C7XJI2V.js";
67
+ } from "./chunk-6POQAFEC.js";
68
68
  import {
69
69
  badRequest,
70
70
  notFound
@@ -137,6 +137,8 @@ var CreateSchema = z.object({
137
137
  title: z.string().nullish(),
138
138
  metadata: z.record(z.unknown()).optional(),
139
139
  max_budget_usd: z.number().positive().optional(),
140
+ max_tokens: z.number().int().positive().optional(),
141
+ max_wall_duration_ms: z.number().int().positive().optional(),
140
142
  resources: z.array(ResourceSchema).optional(),
141
143
  vault_ids: z.array(z.string()).optional()
142
144
  });
@@ -267,6 +269,8 @@ function handleCreateSession(request) {
267
269
  title: data.title ?? null,
268
270
  metadata: data.metadata ?? {},
269
271
  max_budget_usd: data.max_budget_usd ?? null,
272
+ max_tokens: data.max_tokens ?? null,
273
+ max_wall_duration_ms: data.max_wall_duration_ms ?? null,
270
274
  resources: data.resources?.length ? data.resources : null,
271
275
  vault_ids: data.vault_ids?.length ? data.vault_ids : null,
272
276
  api_key_id: auth.keyId,
@@ -326,6 +330,8 @@ function handleCreateSession(request) {
326
330
  title: data.title ?? null,
327
331
  metadata: data.metadata ?? {},
328
332
  max_budget_usd: data.max_budget_usd ?? null,
333
+ max_tokens: data.max_tokens ?? null,
334
+ max_wall_duration_ms: data.max_wall_duration_ms ?? null,
329
335
  resources: data.resources?.length ? data.resources : null,
330
336
  vault_ids: data.vault_ids?.length ? data.vault_ids : null,
331
337
  api_key_id: auth.keyId,
@@ -126,6 +126,8 @@ var init_schema = __esm({
126
126
  parked_checkpoint_id: text("parked_checkpoint_id"),
127
127
  provider_name: text("provider_name").notNull().default("sprites"),
128
128
  max_budget_usd: real("max_budget_usd"),
129
+ max_tokens: integer("max_tokens"),
130
+ max_wall_duration_ms: integer("max_wall_duration_ms"),
129
131
  outcome_criteria_json: text("outcome_criteria_json"),
130
132
  resources_json: text("resources_json"),
131
133
  vault_ids_json: text("vault_ids_json"),