feat(runtime): add checkpoint artifact id contract

This commit is contained in:
Saravana Achu Mac 2026-04-04 14:27:26 -07:00
parent 2d86c9801a
commit 59ae0e1943
4 changed files with 19 additions and 4 deletions

View File

@ -144,8 +144,9 @@ describe('agent runtime contract baseline', () => {
createdAt: '2026-04-04T12:00:00.000Z', createdAt: '2026-04-04T12:00:00.000Z',
statusAtCapture: 'waiting-approval', statusAtCapture: 'waiting-approval',
currentTaskId: 'task_cowork_1', currentTaskId: 'task_cowork_1',
checkpointArtifactId: 'artifact://notelett/note-1',
todoIds: ['todo_cowork_1'], todoIds: ['todo_cowork_1'],
artifactRefs: [], artifactRefs: ['artifact://notelett/note-1'],
memoryRefs: [], memoryRefs: [],
approvalRefs: ['approval_1'], approvalRefs: ['approval_1'],
dispatchContext: { dispatchContext: {
@ -164,5 +165,6 @@ describe('agent runtime contract baseline', () => {
expect(checkpoint.statusAtCapture).toBe('waiting-approval'); expect(checkpoint.statusAtCapture).toBe('waiting-approval');
expect(checkpoint.resumeToken).toBe('task_cowork_1'); expect(checkpoint.resumeToken).toBe('task_cowork_1');
expect(checkpoint.checkpointArtifactId).toBe('artifact://notelett/note-1');
}); });
}); });

View File

@ -81,6 +81,7 @@ export const AgentCheckpointSchema = z.object({
createdAt: z.string().datetime(), createdAt: z.string().datetime(),
statusAtCapture: AgentCheckpointStatusSchema, statusAtCapture: AgentCheckpointStatusSchema,
currentTaskId: z.string().min(1).nullable().optional(), currentTaskId: z.string().min(1).nullable().optional(),
checkpointArtifactId: z.string().min(1).nullable().optional(),
todoIds: z.array(z.string().min(1)), todoIds: z.array(z.string().min(1)),
artifactRefs: z.array(z.string().min(1)), artifactRefs: z.array(z.string().min(1)),
memoryRefs: z.array(z.string().min(1)), memoryRefs: z.array(z.string().min(1)),

View File

@ -89,6 +89,7 @@ describe('agent runtime routes', () => {
updatedAt: '2026-04-04T08:10:00.000Z', updatedAt: '2026-04-04T08:10:00.000Z',
sessionId: 'sess-1', sessionId: 'sess-1',
eventId: 'evt_cowork_task_task-1', eventId: 'evt_cowork_task_task-1',
checkpointArtifactId: 'artifact://notelett/note-1',
}, },
], ],
}, },
@ -102,6 +103,7 @@ describe('agent runtime routes', () => {
sessionId: 'sess-1', sessionId: 'sess-1',
productId: 'clawcowork', productId: 'clawcowork',
status: 'running', status: 'running',
checkpointArtifactId: 'artifact://notelett/note-1',
correlationId: 'evt_cowork_task_task-1', correlationId: 'evt_cowork_task_task-1',
}); });
}); });
@ -232,6 +234,7 @@ describe('agent runtime routes', () => {
completed: false, completed: false,
cancelled: false, cancelled: false,
completed_tool_calls: 2, completed_tool_calls: 2,
checkpoint_artifact_id: 'artifact://notelett/note-1',
artifact_refs: ['artifact://notelett/note-1'], artifact_refs: ['artifact://notelett/note-1'],
memory_refs: ['memory://mindlyst/memory-1'], memory_refs: ['memory://mindlyst/memory-1'],
approval_refs: ['approval://cowork/ap-1'], approval_refs: ['approval://cowork/ap-1'],
@ -251,6 +254,7 @@ describe('agent runtime routes', () => {
userId: 'demo-user', userId: 'demo-user',
statusAtCapture: 'queued', statusAtCapture: 'queued',
resumeToken: 'task-1', resumeToken: 'task-1',
checkpointArtifactId: 'artifact://notelett/note-1',
artifactRefs: ['artifact://notelett/note-1'], artifactRefs: ['artifact://notelett/note-1'],
memoryRefs: ['memory://mindlyst/memory-1'], memoryRefs: ['memory://mindlyst/memory-1'],
approvalRefs: ['approval://cowork/ap-1'], approvalRefs: ['approval://cowork/ap-1'],

View File

@ -279,6 +279,15 @@ function toAgentCheckpoint(
: 'checkpoint available for resume', : 'checkpoint available for resume',
].join('; '); ].join('; ');
const artifactRefs = Array.isArray(checkpoint.artifact_refs)
? checkpoint.artifact_refs.filter((value): value is string => typeof value === 'string')
: [];
const checkpointArtifactId =
typeof checkpoint.checkpoint_artifact_id === 'string' &&
checkpoint.checkpoint_artifact_id.length > 0
? checkpoint.checkpoint_artifact_id
: (artifactRefs[0] ?? null);
return AgentCheckpointSchema.parse({ return AgentCheckpointSchema.parse({
checkpointId: `ckpt_${taskId}`, checkpointId: `ckpt_${taskId}`,
sessionId: sessionId:
@ -292,10 +301,9 @@ function toAgentCheckpoint(
createdAt, createdAt,
statusAtCapture: mapCheckpointStatus(task, checkpoint), statusAtCapture: mapCheckpointStatus(task, checkpoint),
currentTaskId: taskId, currentTaskId: taskId,
checkpointArtifactId,
todoIds: [`todo_${taskId}`], todoIds: [`todo_${taskId}`],
artifactRefs: Array.isArray(checkpoint.artifact_refs) artifactRefs,
? checkpoint.artifact_refs.filter((value): value is string => typeof value === 'string')
: [],
memoryRefs: Array.isArray(checkpoint.memory_refs) memoryRefs: Array.isArray(checkpoint.memory_refs)
? checkpoint.memory_refs.filter((value): value is string => typeof value === 'string') ? checkpoint.memory_refs.filter((value): value is string => typeof value === 'string')
: [], : [],