feat: initial release v0.3.0

This commit is contained in:
saturn
2026-03-08 03:15:27 +08:00
commit 881ed44996
1311 changed files with 225407 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import {
executePipelineGraph,
GraphCancellationError,
type GraphExecutorState,
} from '@/lib/run-runtime/graph-executor'
const { createCheckpointMock, getRunByIdMock } = vi.hoisted(() => ({
createCheckpointMock: vi.fn(),
getRunByIdMock: vi.fn(),
}))
vi.mock('@/lib/run-runtime/service', () => ({
buildLeanState: vi.fn((value: unknown) => value),
createCheckpoint: createCheckpointMock,
getRunById: getRunByIdMock,
}))
describe('graph executor', () => {
beforeEach(() => {
vi.clearAllMocks()
getRunByIdMock.mockResolvedValue({
id: 'run_1',
userId: 'user_1',
status: 'running',
})
})
it('retries retryable node error and writes checkpoint once success', async () => {
const state: GraphExecutorState = {
refs: {},
meta: {},
}
const runMock = vi
.fn()
.mockRejectedValueOnce(new TypeError('fetch failed sending request'))
.mockResolvedValueOnce({
output: { ok: true },
})
await executePipelineGraph({
runId: 'run_1',
projectId: 'project_1',
userId: 'user_1',
state,
nodes: [
{
key: 'node_a',
title: 'Node A',
maxAttempts: 2,
run: runMock,
},
],
})
expect(runMock).toHaveBeenCalledTimes(2)
expect(createCheckpointMock).toHaveBeenCalledTimes(1)
expect(createCheckpointMock).toHaveBeenCalledWith(expect.objectContaining({
runId: 'run_1',
nodeKey: 'node_a',
version: 2,
}))
})
it('throws cancellation error when run status is canceling', async () => {
getRunByIdMock.mockResolvedValue({
id: 'run_1',
userId: 'user_1',
status: 'canceling',
})
await expect(
executePipelineGraph({
runId: 'run_1',
projectId: 'project_1',
userId: 'user_1',
state: {
refs: {},
meta: {},
},
nodes: [
{
key: 'node_a',
title: 'Node A',
run: async () => ({ output: { ok: true } }),
},
],
}),
).rejects.toBeInstanceOf(GraphCancellationError)
})
it('merges refs into state and persists lean checkpoint', async () => {
const state: GraphExecutorState = {
refs: {
scriptId: 'script_1',
},
meta: {
tag: 'v1',
},
}
await executePipelineGraph({
runId: 'run_1',
projectId: 'project_1',
userId: 'user_1',
state,
nodes: [
{
key: 'node_b',
title: 'Node B',
run: async () => ({
checkpointRefs: {
storyboardId: 'storyboard_1',
},
checkpointMeta: {
done: true,
},
}),
},
],
})
expect(state.refs).toEqual({
scriptId: 'script_1',
storyboardId: 'storyboard_1',
voiceLineBatchId: undefined,
versionHash: undefined,
cursor: undefined,
})
expect(createCheckpointMock).toHaveBeenCalledWith(expect.objectContaining({
state: expect.objectContaining({
refs: expect.objectContaining({
scriptId: 'script_1',
storyboardId: 'storyboard_1',
}),
}),
}))
})
})