feat: persist blocked executor jobs
This commit is contained in:
@@ -67,12 +67,49 @@ function validateNode(state) {
|
||||
};
|
||||
}
|
||||
|
||||
function planNode(state) {
|
||||
async function planNode(state, executorGateway) {
|
||||
const taskType = String(state.spec.input?.taskType ?? '').trim() || 'code-change';
|
||||
const instruction = String(state.spec.input?.instruction ?? '');
|
||||
const executorJob = await executorGateway.createJob({
|
||||
jobId: `${state.spec.runId}:executor-preview`,
|
||||
idempotencyKey: `${state.spec.runId}:build_plan:v1`,
|
||||
executor: 'goosed',
|
||||
task: {
|
||||
type: taskType,
|
||||
instruction,
|
||||
workspaceRef: state.spec.input?.workspaceRef ?? null,
|
||||
inputRefs: state.spec.input?.inputRefs ?? [],
|
||||
},
|
||||
subject: state.spec.subject,
|
||||
authorization: {
|
||||
executionAllowed: false,
|
||||
actorId: state.spec.subject?.userId ?? null,
|
||||
},
|
||||
policy: {
|
||||
sideEffectsAllowed: false,
|
||||
networkAllowed: false,
|
||||
},
|
||||
controls: {
|
||||
timeoutMs: state.spec.limits?.timeoutMs,
|
||||
cancellationAllowed: true,
|
||||
fallbackExecutor: 'aider',
|
||||
},
|
||||
metadata: {
|
||||
source: 'langgraph-shadow-plan',
|
||||
workflow: state.spec.workflow,
|
||||
},
|
||||
});
|
||||
const plan = {
|
||||
taskType,
|
||||
executorAdapter: 'native-agent-run',
|
||||
executorJob: {
|
||||
kind: 'executor-job',
|
||||
id: executorJob.job.jobId,
|
||||
executor: executorJob.job.executor,
|
||||
status: executorJob.job.status,
|
||||
reason: executorJob.job.reason,
|
||||
durable: executorGateway.status().store.durable,
|
||||
},
|
||||
instructionCharacters: instruction.length,
|
||||
steps: [
|
||||
'accept_control_plane_run',
|
||||
@@ -86,6 +123,7 @@ function planNode(state) {
|
||||
events: [eventFor(state, 'workflow_planned', {
|
||||
taskType,
|
||||
executorAdapter: plan.executorAdapter,
|
||||
executorJob: plan.executorJob,
|
||||
stepCount: plan.steps.length,
|
||||
})],
|
||||
};
|
||||
@@ -106,11 +144,14 @@ function finalizeNode(state) {
|
||||
};
|
||||
}
|
||||
|
||||
export function createCodeRunShadowGraph({ checkpointer } = {}) {
|
||||
export function createCodeRunShadowGraph({ checkpointer, executorGateway } = {}) {
|
||||
if (!checkpointer) throw new Error('Code run shadow graph requires a checkpointer');
|
||||
if (!executorGateway?.createJob) {
|
||||
throw new Error('Code run shadow graph requires an Executor Gateway');
|
||||
}
|
||||
return new StateGraph(ShadowState)
|
||||
.addNode('validate_run', validateNode)
|
||||
.addNode('build_plan', planNode)
|
||||
.addNode('build_plan', (state) => planNode(state, executorGateway))
|
||||
.addNode('finalize_run', finalizeNode)
|
||||
.addEdge(START, 'validate_run')
|
||||
.addEdge('validate_run', 'build_plan')
|
||||
|
||||
Reference in New Issue
Block a user