Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/perstack/src/lib/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Checkpoint, PerstackConfig, ProviderConfig, ProviderName } from "@
import { getEnv } from "./get-env.js"
import { getPerstackConfig } from "./perstack-toml.js"
import { getProviderConfig } from "./provider-config.js"
import { getCheckpointById, getMostRecentCheckpoint, getMostRecentRunInJob } from "./run-manager.js"
import { findCheckpointInJob, getMostRecentCheckpoint, getMostRecentRunInJob } from "./run-manager.js"

const defaultProvider: ProviderName = "anthropic"
const defaultModel = "claude-sonnet-4-5"
Expand Down Expand Up @@ -37,8 +37,7 @@ export async function resolveRunContext(input: ResolveRunContextInput): Promise<
throw new Error("--resume-from requires --continue or --continue-job")
}
const jobId = input.continueJob ?? (await getMostRecentCheckpoint()).jobId
const run = await getMostRecentRunInJob(jobId)
checkpoint = await getCheckpointById(jobId, run.runId, input.resumeFrom)
checkpoint = await findCheckpointInJob(jobId, input.resumeFrom)
} else if (input.continueJob) {
const run = await getMostRecentRunInJob(input.continueJob)
checkpoint = await getMostRecentCheckpoint(run.jobId, run.runId)
Expand Down
20 changes: 20 additions & 0 deletions packages/perstack/src/lib/run-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,26 @@ export async function getCheckpointById(
const checkpoint = await readFile(checkpointPath, "utf-8")
return checkpointSchema.parse(JSON.parse(checkpoint))
}

export async function findCheckpointInJob(jobId: string, checkpointId: string): Promise<Checkpoint> {
const runs = await getRunsByJobId(jobId)
for (const run of runs) {
const runDir = getRunDir(jobId, run.runId)
if (!existsSync(runDir)) {
continue
}
const files = await readdir(runDir)
const checkpointFile = files.find(
(file) => file.startsWith("checkpoint-") && file.includes(`-${checkpointId}.`),
)
if (checkpointFile) {
const checkpointPath = path.resolve(runDir, checkpointFile)
const checkpoint = await readFile(checkpointPath, "utf-8")
return checkpointSchema.parse(JSON.parse(checkpoint))
}
}
throw new Error(`Checkpoint ${checkpointId} not found in job ${jobId}`)
}
export async function getCheckpointsWithDetails(
jobId: string,
runId: string,
Expand Down