-
Notifications
You must be signed in to change notification settings - Fork 45
feat(agent-runtime): add getLatestRunId to resolve a thread's latest run #451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -230,6 +230,62 @@ describe('test/OSSAgentStore.test.ts', () => { | |
| }); | ||
| }); | ||
|
|
||
| describe('recent run id', () => { | ||
| it('should record latestRunId on the thread when createRun has a threadId', async () => { | ||
| const thread = await store.createThread(); | ||
| const run = await store.createRun([{ role: 'user', content: 'Hello' }], thread.id); | ||
| // latestRunId is written in the background; drain before asserting. | ||
| await store.awaitPendingWrites(); | ||
| assert.equal(await store.getLatestRunId(thread.id), run.id); | ||
| }); | ||
|
|
||
| it('should point getLatestRunId at the most recent run', async () => { | ||
| const thread = await store.createThread(); | ||
| await store.createRun([{ role: 'user', content: 'first' }], thread.id); | ||
| const second = await store.createRun([{ role: 'user', content: 'second' }], thread.id); | ||
| await store.awaitPendingWrites(); | ||
| assert.equal(await store.getLatestRunId(thread.id), second.id); | ||
| }); | ||
|
|
||
| it('should preserve existing thread metadata when recording latestRunId', async () => { | ||
| const thread = await store.createThread({ origin: 'audit', agentName: 'foo' }); | ||
| const run = await store.createRun([{ role: 'user', content: 'Hello' }], thread.id); | ||
| await store.awaitPendingWrites(); | ||
| const fetched = await store.getThread(thread.id); | ||
| assert.deepEqual(fetched.metadata, { origin: 'audit', agentName: 'foo' }); | ||
| assert.equal(await store.getLatestRunId(thread.id), run.id); | ||
| }); | ||
|
|
||
| it('should return null for a thread that exists but has no run (historical data)', async () => { | ||
| const thread = await store.createThread(); | ||
| assert.equal(await store.getLatestRunId(thread.id), null); | ||
| }); | ||
|
|
||
| it('should not record latestRunId when createRun has no threadId', async () => { | ||
| const run = await store.createRun([{ role: 'user', content: 'Hello' }]); | ||
| assert(run.id.startsWith('run_')); | ||
| // No thread to query; the run simply has no latest-run pointer anywhere. | ||
| }); | ||
|
Comment on lines
+264
to
+268
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a real assertion in this test case. Line 264’s test name claims pointer behavior, but Lines 265-268 only assert run id format. It won’t fail if pointer logic regresses. Please assert an observable invariant (for example, create a thread first, run without 🤖 Prompt for AI Agents |
||
|
|
||
| it('should not fail run creation when the threadId does not exist', async () => { | ||
| // Best-effort pointer write: a missing thread meta is swallowed. | ||
| const run = await store.createRun([{ role: 'user', content: 'Hello' }], 'thread_missing'); | ||
| assert(run.id.startsWith('run_')); | ||
| }); | ||
|
|
||
| it('should throw AgentNotFoundError from getLatestRunId for a non-existent thread', async () => { | ||
| await assert.rejects( | ||
| () => store.getLatestRunId('thread_non_existent'), | ||
| (err: unknown) => { | ||
| assert(err instanceof AgentNotFoundError); | ||
| assert.equal(err.status, 404); | ||
| assert.match(err.message, /Thread thread_non_existent not found/); | ||
| return true; | ||
| }, | ||
| ); | ||
| }); | ||
| }); | ||
|
|
||
| describe('init / destroy', () => { | ||
| it('should call client init when present', async () => { | ||
| let initCalled = false; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awaiting
recordLastRunIdsynchronously blocks the run creation process, adding two extra network roundtrips (one GET and one PUT to the object storage) to the critical path ofcreateRun. Since the client already receives therunIdin the response of the run creation call (or via therun_createdevent in streaming), they do not need to immediately querygetRecentRunIdto find it.\n\nWe can make this write non-blocking (running in the background) and track it using the existingpendingIndexWritesset so thatdestroy()still safely awaits it before shutdown. This significantly improves the latency of starting a run.