Q128: every model call of a run is recorded with its purpose and listed in the run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1f484df894
commit
6afd7bef2a
25 files changed
+189
-22
No files matched your search
@@ -172,6 +172,13 @@ export const zh: Record<string, string> = {
|
||||
"Check": "检查",
|
||||
"Choose": "选择",
|
||||
"No findings": "未发现问题",
|
||||
"Model calls ({count})": "模型调用({count})",
|
||||
"This run made no model call.": "本次运行没有调用模型。",
|
||||
"Turn": "轮次",
|
||||
"Goal audit": "目标审查",
|
||||
"Model check": "模型检查",
|
||||
"Manual": "手动",
|
||||
"Earlier call": "早期调用",
|
||||
"Partly scanned": "部分扫描",
|
||||
"Scanned before whole-file checks existed: only its first MiB was checked.": "在全文件检查之前扫描:只检查了前 1 MiB。",
|
||||
"Contents not inspected": "内容未检查",
|
||||
@@ -395,7 +402,6 @@ export const zh: Record<string, string> = {
|
||||
"Replaced by an edit": "已因编辑被替换",
|
||||
"Changed since approval": "批准后已改动",
|
||||
"Removed since approval": "批准后已删除",
|
||||
"Goal audit": "目标审查",
|
||||
"CEO: hires officers, grants connectors and skills, and closes goals. This rank cannot be changed.": "CEO:招聘高管、授予连接器和技能、关闭目标。此职级不可更改。",
|
||||
"An independent model checks every goal before it closes. Pick one your agents do not use, ideally from another provider.": "每个目标关闭前都由一个独立模型检查。请选择 Agent 不使用的模型,最好来自另一家服务商。",
|
||||
"No auditor is set, so goals cannot be closed yet.": "尚未设置审查模型,目标暂时无法关闭。",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { RunRequestList } from "./runs/RunRequestList";
|
||||
import { useMemo, useState } from "react";
|
||||
import { Avatar, Button, Pill, Segmented } from "../shared/ui";
|
||||
import type { AgentRecord, ProviderRecord, TaskRecord, TaskRunRecord } from "../../../shared/domain";
|
||||
@@ -147,6 +148,8 @@ function RunDetail({ run, tasks, agents, providers, providerRequests, actions }:
|
||||
<MetaLabel>{t("Context")}</MetaLabel><div className="mono" style={{ fontSize: 12, overflow: "hidden", textOverflow: "ellipsis" }}>{run.executionContextId}</div>
|
||||
</div>
|
||||
|
||||
<RunRequestList orgId={run.orgId} runId={run.id} state={run.state} />
|
||||
|
||||
{run.state === "superseded" && run.errorMessage && (
|
||||
<div className="card" style={{ padding: 16, marginBottom: 16 }}>
|
||||
<div className="section-label" style={{ marginBottom: 8 }}>{t("Why it did not run")}</div>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import type { RunRequestRecord } from "../../../../shared/provider-runtime-domain";
|
||||
import { Pill } from "../../shared/ui";
|
||||
import { t } from "../../i18n/i18n";
|
||||
|
||||
function purposeLabel(purpose: string): string {
|
||||
if (purpose === "agent_turn") return t("Turn");
|
||||
if (purpose === "goal_audit") return t("Goal audit");
|
||||
if (purpose === "model_check") return t("Model check");
|
||||
if (purpose === "manual") return t("Manual");
|
||||
return t("Earlier call");
|
||||
}
|
||||
|
||||
/** Every model call the run made, in order, so a turn or an audit can be found by its task. */
|
||||
export function RunRequestList({ orgId, runId, state }: { orgId: string; runId: string; state: string }) {
|
||||
// Fetched calls are kept with the run they belong to, so switching runs never shows another run's chain.
|
||||
const [loaded, setLoaded] = useState<{ runId: string; requests: RunRequestRecord[] } | { runId: string; error: string } | null>(null);
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
window.agentCompany.runRequests({ orgId, runId })
|
||||
.then((result) => {
|
||||
if (cancelled) return;
|
||||
setLoaded(result.ok ? { runId, requests: result.data } : { runId, error: result.error.message });
|
||||
})
|
||||
.catch((reason: unknown) => {
|
||||
if (!cancelled) setLoaded({ runId, error: reason instanceof Error ? reason.message : String(reason) });
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [orgId, runId, state]);
|
||||
|
||||
if (!loaded || loaded.runId !== runId) return null;
|
||||
if ("error" in loaded) return <div className="form-error" role="alert">{loaded.error}</div>;
|
||||
const { requests } = loaded;
|
||||
return (
|
||||
<div style={{ marginBottom: 20 }}>
|
||||
<div className="section-label" style={{ marginBottom: 8 }}>{t("Model calls ({count})", { count: String(requests.length) })}</div>
|
||||
{requests.length === 0 && <div style={{ fontSize: 13, color: "var(--text-3)" }}>{t("This run made no model call.")}</div>}
|
||||
{requests.map((request, index) => (
|
||||
<div key={request.id} className="row" style={{ gap: 10, fontSize: 13, padding: "6px 0", borderBottom: "1px solid var(--border-soft)" }}>
|
||||
<span className="mono" style={{ color: "var(--text-3)", width: 24 }}>{index + 1}</span>
|
||||
<span style={{ width: 96 }}>{purposeLabel(request.purpose)}</span>
|
||||
<span className="mono" style={{ flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis" }}>{request.model}</span>
|
||||
<Pill tone={request.state === "failed" ? "red" : request.state === "succeeded" ? "green" : "amber"}>{request.state}</Pill>
|
||||
<span className="mono" style={{ color: "var(--text-3)", width: 120, textAlign: "right" }}>
|
||||
{request.inputTokens ?? "—"} / {request.outputTokens ?? "—"}
|
||||
</span>
|
||||
{request.errorMessage && <span style={{ color: "var(--red)", flexBasis: "100%", whiteSpace: "pre-wrap" }}>{request.errorMessage}</span>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user