인터페이스: RunStore
정의 위치: packages/ai/src/activities/chat/middleware/run-store.ts:179
실행 수명 주기 레코드를 위한 영속성 저장소입니다.
필수: createOrResume, update, get, findActiveRun. 모든 백엔드는
네 가지를 모두 구현해야 합니다. 영속성 미들웨어가 이를
무조건 호출하기 때문입니다. findActiveRun는 기능 감지를 수행하는 대신 필수입니다
구현하지 않은 백엔드는 다음 중 하나와 구분할 수 없기 때문입니다.
응답이 정상적으로 null인 경우와 구분할 수 없으므로, 재연결이 아무 작업도 하지 않고 조용히 종료됩니다.
빌드 시점에 실패하는 대신입니다. 정확히 한 릴리스
주기 동안 선택 사항이었으며, 그 대가를 정확히 치렀습니다.
선택 사항: listByThread, listReclaimable. 각각 하나의 상위 수준
기능(스레드 기록, 회수 리핑)을 제공하며 호출자는 이를 기능 감지하고,
백엔드가 이를 생략하면 정상적으로 성능을 저하하면서 처리합니다.
속성
createOrResume
createOrResume: (input) => Promise<RunRecord>;
정의 위치: packages/ai/src/activities/chat/middleware/run-store.ts:188
실행 기록을 생성하거나, runId이
이미 있으면 기존 기록을 변경하지 않고 반환합니다.
불변 조건(idempotency): 기존 기록은 변경하지 않고 반환되며,
전달된 threadId/startedAt/status은 무시됩니다. 이로 인해
실행을 안전하게 재개할 수 있습니다. 처음 생성할 때 status은 'running'으로
기본 설정됩니다.
매개변수
input
Pick<RunRecord, "threadId" | "runId" | "startedAt"> & object
반환값
Promise<RunRecord>
findActiveRun
findActiveRun: (threadId) => Promise<RunRecord | null>;
정의 위치: packages/ai/src/activities/chat/middleware/run-store.ts:255
가장 최근의 'running' 실행(대상: threadId) 또는 활성 상태인 것이 없으면 null입니다.
필수입니다. 이는 클라이언트를 다시 연결할 때(새로 고침하거나 다른 기기에서 동일한 스레드를 여는 경우) 영속적인 기반이 되는 안정적인 스레드 ID에서 "이 스레드에 연결할 활성 실행이 있는가?"를 확인합니다. 이는 단일 턴에서 여러 개가 생성될 수 있는 임시 실행 ID와는 무관합니다. 둘 이상의 실행이 'running'인 경우, startedAt 값이 가장 큰 실행이 선택됩니다.
이를 null로 스텁 처리하는 백엔드는 재연결을 조용히 끕니다. null도 유휴 스레드에 대한 올바른 답이기 때문입니다. 실행 수명 주기가 전혀 없는 백엔드는 대신 전체 runs 스토어를 생략해야 합니다. 기능 단계는 메서드 수준이 아니라 스토어 수준에 속합니다.
매개변수
threadId
string
반환값
Promise<RunRecord | null>
get
get: (runId) => Promise<RunRecord | null>;
정의 위치: packages/ai/src/activities/chat/middleware/run-store.ts:216
현재 레코드이며, 알 수 없는 경우 null입니다.
매개변수
runId
string
반환값
Promise<RunRecord | null>
listByThread?
optional listByThread?: (threadId) => Promise<RunRecord[]>;
정의 위치: packages/ai/src/activities/chat/middleware/run-store.ts:221
대화의 모든 run을 startedAt 기준 오름차순으로 반환합니다. 선택 사항: thread의 과거 에이전트 활동을 렌더링하는 데만 필요합니다. 소비자는 기능을 감지합니다.
매개변수
threadId
string
반환값
Promise<RunRecord[]>
listReclaimable?
optional listReclaimable?: (opts) => Promise<RunRecord[]>;
정의 위치: packages/ai/src/activities/chat/middleware/run-store.ts:237
다시 회수할 수 있는 실행: status === 'running'의 세 가지가 모두 충족되고,
detachedSince이 설정되며, detachedSince <= now - ttlMs인 경우입니다. 기준 시점은
포함됩니다 — 정확히 now - ttlMs에 분리된 실행은 다시 회수할 수 있습니다.
선택 사항: reaper에만 필요합니다. 소비자는 기능을 감지합니다.
detachedSince은(는) withSandbox의 분리 경로에서 채워집니다(다음을 참조하세요:
RunRecord.detachedSince). 이 표면에 노출된 후보를 대상으로 하는
스윕은 @tanstack/ai-sandbox의 reapDetachedRuns입니다. 이 작업은 이미 에이전트가 완료한 실행을
최종 처리하고, TTL을 초과한 항목을 만료시키며, 샌드박스를
다시 회수합니다. 이는 스케줄러가 아니라 함수이므로 애플리케이션이
(cron, queue, alarm(), waitUntil) 호출해야 하며, 이 메서드를 생략한
백엔드는 전혀 정리할 수 없습니다.
매개변수
opts
now
number
ttlMs
number
반환값
Promise<RunRecord[]>
update
update: (runId, patch) => Promise<void>;
정의 위치: packages/ai/src/activities/chat/middleware/run-store.ts:199
레코드의 변경 가능한 필드를 패치합니다.
불변 조건: 알 수 없는 runId을 업데이트하는 작업은 아무 동작도 하지 않습니다 — 예외를 발생시켜서는 안 되며
레코드를 생성해서도 안 됩니다.
매개변수
runId
string
patch
Partial<Pick<RunRecord,
| "status"
| "finishedAt"
| "error"
| "usage"
| "sandboxKey"
| "detachedSince"
| "cancelRequested"
| "driverEpoch">>
반환값
Promise<void>