Skip to content

Commit 8b59ae5

Browse files
committed
Use runId for sandbox id
1 parent 0a1b093 commit 8b59ae5

File tree

3 files changed

+37
-29
lines changed

3 files changed

+37
-29
lines changed

backend/src/run-programmatic-step.ts

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ import type { WebSocket } from 'ws'
2828
const sandboxManager = new SandboxManager()
2929

3030
// Maintains generator state for all agents. Generator state can't be serialized, so we store it in memory.
31-
const agentIdToGenerator: Record<string, StepGenerator | undefined> = {}
32-
export const agentIdToStepAll: Set<string> = new Set()
31+
const runIdToGenerator: Record<string, StepGenerator | undefined> = {}
32+
export const runIdToStepAll: Set<string> = new Set()
3333

3434
// Function to clear the generator cache for testing purposes
3535
export function clearAgentGeneratorCache() {
36-
for (const key in agentIdToGenerator) {
37-
delete agentIdToGenerator[key]
36+
for (const key in runIdToGenerator) {
37+
delete runIdToGenerator[key]
3838
}
39-
agentIdToStepAll.clear()
39+
runIdToStepAll.clear()
4040
// Clean up QuickJS sandboxes
4141
sandboxManager.dispose()
4242
}
@@ -78,16 +78,20 @@ export async function runProgrammaticStep(
7878
throw new Error('No step handler found for agent template ' + template.id)
7979
}
8080

81+
if (!agentState.runId) {
82+
throw new Error('Agent state has no run ID')
83+
}
84+
8185
// Run with either a generator or a sandbox.
82-
let generator = agentIdToGenerator[agentState.agentId]
83-
let sandbox = sandboxManager.getSandbox(agentState.agentId)
86+
let generator = runIdToGenerator[agentState.runId]
87+
let sandbox = sandboxManager.getSandbox(agentState.runId)
8488

8589
// Check if we need to initialize a generator (either native or QuickJS-based)
8690
if (!generator && !sandbox) {
8791
if (typeof template.handleSteps === 'string') {
8892
// Initialize QuickJS sandbox for string-based generator
8993
sandbox = await sandboxManager.getOrCreateSandbox(
90-
agentState.agentId,
94+
agentState.runId,
9195
template.handleSteps,
9296
{
9397
agentState,
@@ -102,15 +106,15 @@ export async function runProgrammaticStep(
102106
prompt,
103107
params,
104108
})
105-
agentIdToGenerator[agentState.agentId] = generator
109+
runIdToGenerator[agentState.runId] = generator
106110
}
107111
}
108112

109113
// Check if we're in STEP_ALL mode
110-
if (agentIdToStepAll.has(agentState.agentId)) {
114+
if (runIdToStepAll.has(agentState.runId)) {
111115
if (stepsComplete) {
112116
// Clear the STEP_ALL mode. Stepping can continue if handleSteps doesn't return.
113-
agentIdToStepAll.delete(agentState.agentId)
117+
runIdToStepAll.delete(agentState.runId)
114118
} else {
115119
return { agentState, endTurn: false, stepNumber }
116120
}
@@ -143,7 +147,9 @@ export async function runProgrammaticStep(
143147
...data,
144148
})
145149
},
146-
agentState: cloneDeep(agentState),
150+
agentState: cloneDeep(
151+
agentState as AgentState & Required<Pick<AgentState, 'runId'>>,
152+
),
147153
agentContext: cloneDeep(agentState.agentContext),
148154
messages: cloneDeep(agentState.messageHistory),
149155
}
@@ -182,7 +188,7 @@ export async function runProgrammaticStep(
182188
break
183189
}
184190
if (result.value === 'STEP_ALL') {
185-
agentIdToStepAll.add(state.agentState.agentId)
191+
runIdToStepAll.add(state.agentState.agentId)
186192
break
187193
}
188194

@@ -322,20 +328,21 @@ export async function runProgrammaticStep(
322328
if (endTurn) {
323329
if (sandbox) {
324330
// Clean up QuickJS sandbox if execution is complete
325-
sandboxManager.removeSandbox(agentState.agentId)
331+
sandboxManager.removeSandbox(agentState.runId)
326332
}
327-
delete agentIdToGenerator[agentState.agentId]
328-
agentIdToStepAll.delete(agentState.agentId)
333+
delete runIdToGenerator[agentState.runId]
334+
runIdToStepAll.delete(agentState.runId)
329335
}
330336
}
331337
}
332338

333339
export const getPublicAgentState = (
334-
agentState: AgentState,
340+
agentState: AgentState & Required<Pick<AgentState, 'runId'>>,
335341
): PublicAgentState => {
336-
const { agentId, parentId, messageHistory, output } = agentState
342+
const { agentId, runId, parentId, messageHistory, output } = agentState
337343
return {
338344
agentId,
345+
runId,
339346
parentId,
340347
messageHistory: messageHistory as any as PublicAgentState['messageHistory'],
341348
output,

backend/src/util/quickjs-sandbox.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,12 @@ export class SandboxManager {
209209
* Create or get a sandbox for the given agent ID
210210
*/
211211
async getOrCreateSandbox(
212-
agentId: string,
212+
runId: string,
213213
generatorCode: string,
214214
initialInput: any,
215215
config?: SandboxConfig,
216216
): Promise<QuickJSSandbox> {
217-
const existing = this.sandboxes.get(agentId)
217+
const existing = this.sandboxes.get(runId)
218218
if (existing && existing.isInitialized()) {
219219
return existing
220220
}
@@ -230,38 +230,38 @@ export class SandboxManager {
230230
initialInput,
231231
config,
232232
)
233-
this.sandboxes.set(agentId, sandbox)
233+
this.sandboxes.set(runId, sandbox)
234234
return sandbox
235235
}
236236

237237
/**
238238
* Get an existing sandbox
239239
*/
240-
getSandbox(agentId: string): QuickJSSandbox | undefined {
241-
return this.sandboxes.get(agentId)
240+
getSandbox(runId: string): QuickJSSandbox | undefined {
241+
return this.sandboxes.get(runId)
242242
}
243243

244244
/**
245245
* Remove and dispose a sandbox
246246
*/
247-
removeSandbox(agentId: string): void {
248-
const sandbox = this.sandboxes.get(agentId)
247+
removeSandbox(runId: string): void {
248+
const sandbox = this.sandboxes.get(runId)
249249
if (sandbox) {
250250
sandbox.dispose()
251-
this.sandboxes.delete(agentId)
251+
this.sandboxes.delete(runId)
252252
}
253253
}
254254

255255
/**
256256
* Clean up all sandboxes
257257
*/
258258
dispose(): void {
259-
for (const [agentId, sandbox] of this.sandboxes) {
259+
for (const [runId, sandbox] of this.sandboxes) {
260260
try {
261261
sandbox.dispose()
262262
} catch (error) {
263263
logger.warn(
264-
{ error, agentId },
264+
{ error, runId },
265265
'Failed to dispose sandbox during cleanup',
266266
)
267267
}

common/src/templates/initial-agents-dir/types/agent-definition.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
* export default definition
1515
*/
1616

17-
import type { Message, ToolResultOutput, JsonObjectSchema } from './util-types'
1817
import type * as Tools from './tools'
18+
import type { Message, ToolResultOutput, JsonObjectSchema } from './util-types'
1919
type ToolName = Tools.ToolName
2020

2121
// ============================================================================
@@ -196,6 +196,7 @@ export interface AgentDefinition {
196196

197197
export interface AgentState {
198198
agentId: string
199+
runId: string
199200
parentId: string | undefined
200201

201202
/** The agent's conversation history: messages from the user and the assistant. */

0 commit comments

Comments
 (0)