mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-07-21 02:05:45 +00:00
* feat(subagents): show runtime metadata on task cards * fix(subagents): stop task-card render loop and dedupe model fetches Address code review on the runtime-metadata cards: - P1 render loop: the terminal ToolMessage is re-parsed on every MessageList render and always carries modelName/usage, so the presence-based setTasks condition fired a fresh state object each render -> "Maximum update depth exceeded". computeNextSubtask now returns a value-compared `changed` flag and a pure subtaskNotification() routes terminal transitions through the deferred after-render path while skipping no-op re-parses. - Per-card useModels refetch: add staleTime: Infinity to the ["models"] query so every subtask card shares one /api/models fetch instead of refetching on each mount. * make format * refactor(subagents): dedupe token-usage validators + tidy event narrowing Address PR review follow-ups: - DRY: extract one shared token-usage validator per side. Backend status_contract.normalize_token_usage() now backs both the terminal ToolMessage metadata and the subagent.step/.end run events (step_events.py), and frontend messages/usage.normalizeTokenUsage() backs both the live task_running event (lifecycle.ts) and the terminal ToolMessage metadata (subtask-result.ts). Prevents the input/output/ total_tokens validation from drifting across the four former copies. - Nit: onCustomEvent narrows event.type once instead of re-checking the object shape per branch; the redundant task_started early-return (already validated by taskEventToSubtaskUpdate) is dropped.
37 lines
976 B
TypeScript
37 lines
976 B
TypeScript
import { describe, expect, it } from "@rstest/core";
|
|
|
|
import {
|
|
formatSubtaskTokenUsage,
|
|
resolveSubtaskModelLabel,
|
|
} from "@/core/tasks/presentation";
|
|
|
|
describe("resolveSubtaskModelLabel", () => {
|
|
it("prefers the configured display name and falls back to the model identifier", () => {
|
|
expect(
|
|
resolveSubtaskModelLabel("claude-3-7-sonnet", [
|
|
{
|
|
id: "model-1",
|
|
name: "claude-3-7-sonnet",
|
|
model: "claude-3-7-sonnet@20250219",
|
|
display_name: "Claude 3.7 Sonnet",
|
|
},
|
|
]),
|
|
).toBe("Claude 3.7 Sonnet");
|
|
|
|
expect(resolveSubtaskModelLabel("unlisted-model", [])).toBe(
|
|
"unlisted-model",
|
|
);
|
|
});
|
|
|
|
it("formats only reported cumulative token usage", () => {
|
|
expect(formatSubtaskTokenUsage(undefined)).toBeUndefined();
|
|
expect(
|
|
formatSubtaskTokenUsage({
|
|
inputTokens: 10_000,
|
|
outputTokens: 2_345,
|
|
totalTokens: 12_345,
|
|
}),
|
|
).toBe("12.3K");
|
|
});
|
|
});
|