feat(status): Include model name in intermittent 'Sending query' status

This commit is contained in:
USO Status 2026-01-27 08:36:31 +01:00
parent f3e4890bb7
commit 8cddf01257
3 changed files with 25 additions and 29 deletions

View File

@ -300,6 +300,11 @@ export async function runEmbeddedPiAgent(
const prompt = const prompt =
provider === "anthropic" ? scrubAnthropicRefusalMagic(params.prompt) : params.prompt; provider === "anthropic" ? scrubAnthropicRefusalMagic(params.prompt) : params.prompt;
params.onAgentEvent?.({
stream: "lifecycle",
data: { phase: "model_call_start", provider, model: modelId },
});
const attempt = await runEmbeddedAttempt({ const attempt = await runEmbeddedAttempt({
sessionId: params.sessionId, sessionId: params.sessionId,
sessionKey: params.sessionKey, sessionKey: params.sessionKey,

View File

@ -87,6 +87,7 @@ export function mapAgentEventToPhase(event: {
const phase = typeof data.phase === "string" ? data.phase : ""; const phase = typeof data.phase === "string" ? data.phase : "";
if (stream === "lifecycle") { if (stream === "lifecycle") {
if (phase === "model_call_start") return "sending_query_model_resolved";
if (phase === "start") return "sending_query"; if (phase === "start") return "sending_query";
if (phase === "end") return "complete"; if (phase === "end") return "complete";
} }
@ -162,7 +163,7 @@ export async function handleAgentEventForStatus(
if (phase && phase !== ctx.currentPhase) { if (phase && phase !== ctx.currentPhase) {
log.debug(`Status phase change: ${ctx.currentPhase} -> ${phase}`); log.debug(`Status phase change: ${ctx.currentPhase} -> ${phase}`);
ctx.currentPhase = phase; ctx.currentPhase = phase;
await ctx.controller.setPhase(phase); await ctx.controller.setPhase(phase, event.data);
} }
} }

View File

@ -17,6 +17,7 @@ const log = createSubsystemLogger("status-updates");
export type StatusPhase = export type StatusPhase =
| "sending_query" | "sending_query"
| "sending_query_model_resolved"
| "receiving_reasoning" | "receiving_reasoning"
| "processing_tools" | "processing_tools"
| "generating_response" | "generating_response"
@ -59,6 +60,8 @@ export type StatusUpdateState = {
lastUpdateAt: number; lastUpdateAt: number;
elapsedSeconds: number; elapsedSeconds: number;
isComplete: boolean; isComplete: boolean;
providerUsed?: string;
modelUsed?: string;
}; };
const DEFAULT_CONFIG: Required<StatusUpdateConfig> = { const DEFAULT_CONFIG: Required<StatusUpdateConfig> = {
@ -73,6 +76,7 @@ const DEFAULT_CONFIG: Required<StatusUpdateConfig> = {
const PHASE_MESSAGES: Record<StatusPhase, string> = { const PHASE_MESSAGES: Record<StatusPhase, string> = {
sending_query: "Sending query to AI model", sending_query: "Sending query to AI model",
sending_query_model_resolved: "Sending query to AI model",
receiving_reasoning: "Processing reasoning data", receiving_reasoning: "Processing reasoning data",
processing_tools: "Executing tools", processing_tools: "Executing tools",
generating_response: "Generating response", generating_response: "Generating response",
@ -81,6 +85,7 @@ const PHASE_MESSAGES: Record<StatusPhase, string> = {
const PHASE_EMOJI: Record<StatusPhase, string> = { const PHASE_EMOJI: Record<StatusPhase, string> = {
sending_query: "⏳", sending_query: "⏳",
sending_query_model_resolved: "⏳",
receiving_reasoning: "🧠", receiving_reasoning: "🧠",
processing_tools: "🔧", processing_tools: "🔧",
generating_response: "✍️", generating_response: "✍️",
@ -104,15 +109,21 @@ function formatElapsedTime(seconds: number): string {
} }
function formatStatusMessage( function formatStatusMessage(
phase: StatusPhase, state: StatusUpdateState,
elapsedSeconds: number,
config: Required<StatusUpdateConfig>, config: Required<StatusUpdateConfig>,
): string { ): string {
const parts: string[] = []; const parts: string[] = [];
const phase = state.phase;
const elapsedSeconds = state.elapsedSeconds;
if (config.showPhases) { if (config.showPhases) {
const emoji = PHASE_EMOJI[phase]; const emoji = PHASE_EMOJI[phase];
const message = PHASE_MESSAGES[phase]; let message = PHASE_MESSAGES[phase];
if (phase === "sending_query_model_resolved" && state.providerUsed && state.modelUsed) {
message = `Sending request to ${state.providerUsed}/${state.modelUsed}`;
}
parts.push(`${emoji} ${message}`); parts.push(`${emoji} ${message}`);
} }
@ -174,13 +185,15 @@ export class StatusUpdateController {
} }
} }
async setPhase(phase: StatusPhase): Promise<void> { async setPhase(phase: StatusPhase, data?: { provider?: string; model?: string }): Promise<void> {
if (!this.isEnabled() || this.stopped || this.state.isComplete) return; if (!this.isEnabled() || this.stopped || this.state.isComplete) return;
if (phase === this.state.phase) return; if (phase === this.state.phase) return;
log.debug(`Status phase: ${this.state.phase} -> ${phase}`); log.debug(`Status phase: ${this.state.phase} -> ${phase}`);
this.state.phase = phase; this.state.phase = phase;
if (data?.provider) this.state.providerUsed = data.provider;
if (data?.model) this.state.modelUsed = data.model;
if (phase === "complete") { if (phase === "complete") {
this.state.isComplete = true; this.state.isComplete = true;
@ -191,29 +204,6 @@ export class StatusUpdateController {
await this.sendUpdate(); await this.sendUpdate();
} }
async complete(finalText?: string): Promise<string | undefined> {
if (this.stopped) return undefined;
this.state.isComplete = true;
this.stopUpdateTimer();
this.stopped = true;
if (!this.isEnabled()) return finalText;
// The final message is returned, relying on message deletion/cleanup.
// Clean up status message if it exists and we're not editing
if (this.state.statusMessageId && this.callbacks.deleteStatus) {
try {
await this.callbacks.deleteStatus(this.state.statusMessageId);
} catch (err) {
log.debug(`Failed to delete status message: ${String(err)}`);
}
}
return finalText;
}
async cleanup(): Promise<void> { async cleanup(): Promise<void> {
this.stopUpdateTimer(); this.stopUpdateTimer();
this.stopped = true; this.stopped = true;
@ -235,7 +225,7 @@ export class StatusUpdateController {
this.state.elapsedSeconds = Math.floor((now - this.state.startedAt) / 1000); this.state.elapsedSeconds = Math.floor((now - this.state.startedAt) / 1000);
this.state.lastUpdateAt = now; this.state.lastUpdateAt = now;
const text = formatStatusMessage(this.state.phase, this.state.elapsedSeconds, this.config); const text = formatStatusMessage(this.state, this.config);
try { try {
if (this.config.mode === "edit" && this.supportsEdit() && this.state.statusMessageId) { if (this.config.mode === "edit" && this.supportsEdit() && this.state.statusMessageId) {