-
Notifications
You must be signed in to change notification settings - Fork 552
fix(agent): propagate messages session ids to runner traces #4767
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 |
|---|---|---|
|
|
@@ -41,6 +41,7 @@ import { | |
| type HarnessCapabilities, | ||
| type ResolvedToolSpec, | ||
| type ToolCallbackContext, | ||
| resolveRunSessionId, | ||
| resolvePromptText, | ||
| } from "../protocol.ts"; | ||
| import { EMPTY_OBJECT_SCHEMA } from "../tools/callback.ts"; | ||
|
|
@@ -299,7 +300,8 @@ export async function runPi( | |
| })); | ||
|
|
||
| // Hand the session id + model to the extension so spans carry them. | ||
| otel.config.sessionId = session.sessionId; | ||
| const sessionId = resolveRunSessionId(request, session.sessionId); | ||
|
Member
Author
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. The previous code stamped |
||
| otel.config.sessionId = sessionId; | ||
| otel.config.provider = model.provider; | ||
| otel.config.requestModel = model.id; | ||
|
|
||
|
|
@@ -329,7 +331,6 @@ export async function runPi( | |
| await session.prompt(prompt); | ||
|
|
||
| const output = streamed.trim() || extractAssistantText(session.messages); | ||
| const sessionId = session.sessionId; | ||
| const stopReason = lastStopReason(session.messages); | ||
| const usage = otel.usage(); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -65,6 +65,7 @@ import { | |
| type ToolCallbackContext, | ||
| messageText, | ||
| resolvePromptText, | ||
| resolveRunSessionId, | ||
| } from "../protocol.ts"; | ||
|
|
||
| const require = createRequire(import.meta.url); | ||
|
|
@@ -817,6 +818,7 @@ export async function runRivet( | |
| cwd, | ||
| sessionInit: { cwd, mcpServers }, | ||
| }); | ||
| const sessionId = resolveRunSessionId(request, session.id); | ||
|
|
||
| // Resolve the model first: when the harness rejects the requested id and keeps its | ||
| // own default (e.g. Claude ignores "gpt-5.5"), `model` is undefined and the chat span | ||
|
|
@@ -838,7 +840,7 @@ export async function runRivet( | |
|
|
||
| run.start({ | ||
| prompt, | ||
| sessionId: session.id, | ||
| sessionId, | ||
| messages: [...priorMessages(request), { role: "user", content: prompt }], | ||
| }); | ||
|
|
||
|
|
@@ -922,7 +924,7 @@ export async function runRivet( | |
| // `streamingDeltas` advertises end-to-end live deltas, which is only true when a live | ||
|
Member
Author
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. Confirm both replaced |
||
| // sink is wired. The one-shot path reports false even when the harness produces deltas. | ||
| capabilities: { ...capabilities, streamingDeltas: !!emit && capabilities.streamingDeltas }, | ||
| sessionId: session.id, | ||
| sessionId, | ||
| model: model ?? request.model, | ||
| traceId: run.traceId(), | ||
| }; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -189,7 +189,7 @@ export interface AgentRunRequest { | |
| harness?: string; | ||
| /** Sandbox for the rivet backend ("local" / "daytona"). */ | ||
| sandbox?: string; | ||
| /** Continue a prior run by replaying its history. */ | ||
| /** External conversation id. The cold runtime still receives history in `messages`. */ | ||
| sessionId?: string; | ||
| /** Provider API keys as env vars ({OPENAI_API_KEY,...}), resolved from the vault. */ | ||
| secrets?: Record<string, string>; | ||
|
|
@@ -288,3 +288,8 @@ export function resolvePromptText(request: AgentRunRequest): string { | |
| } | ||
| return ""; | ||
| } | ||
|
|
||
| /** Prefer the platform conversation id, falling back to the harness's ephemeral id. */ | ||
| export function resolveRunSessionId(request: AgentRunRequest, fallback: string): string { | ||
| return request.sessionId && request.sessionId.trim() ? request.sessionId : fallback; | ||
|
Member
Author
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. The empty-string guard matters: |
||
| } | ||
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.
This sits before the
VAR_KEYWORDbranch, so a handler that declares an explicitsession_idargument gets the envelope value, while a**kwargshandler does not receive it. That asymmetry is intentional and pinned by the two new normalizer tests.