feat(agent): 运行时内部错误上报到日志(onReport)
- PiAgentRuntimeOptions.onReport:本次运行扩展的系统提示 section、能力工具、beforeTool / beforeRequest 钩子抛错 先上报(runId + 位置 + 脱敏信息)再原样抛出;pi-durable 的 Harness onReport 也接进来(source=harness) - server runner / 视觉子流程用 runtimeReporter 写 warn 日志 - 测试:钩子抛错时上报带 runId 与位置、信息已脱敏,调用照常被 block Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
003815591c
commit
7c5215663d
5 files changed
+184
-62
No files matched your search
@@ -24,7 +24,7 @@ import { BrowserServiceError, type ChallengeVision, registerChallengeVision } fr
|
||||
import { resolveRunUpstream } from "../pi/index.ts";
|
||||
import type { ServerContext } from "../types.ts";
|
||||
import { parseFakeScripts } from "./fake-scripts.ts";
|
||||
import { type AgentEnv, agentSettings, eventSink, publishStatus, sessionDirOf } from "./runner.ts";
|
||||
import { type AgentEnv, agentSettings, eventSink, publishStatus, runtimeReporter, sessionDirOf } from "./runner.ts";
|
||||
|
||||
// VIS-1 browser.solve_challenge:有界的视觉子流程(REQ §4.4、§10)。
|
||||
// - 服务端起一个受限的子 agent_run(父会话 = 调用它的 Agent 运行;白名单只有截图 / 坐标点击 / 输入 / 滚动 / 等待 / 读页面),
|
||||
@@ -305,6 +305,7 @@ async function runChild(
|
||||
const onEvent = eventSink(env);
|
||||
const onEventError = (err: unknown) =>
|
||||
ctx.logger.warn({ runId: child.id, err: { message: (err as Error).message } }, "视觉子流程事件落库失败");
|
||||
const onReport = runtimeReporter(ctx);
|
||||
let scripts: FakeScript[] = [FALLBACK_SCRIPT];
|
||||
if (fake) {
|
||||
try {
|
||||
@@ -315,11 +316,12 @@ async function runChild(
|
||||
}
|
||||
}
|
||||
const runtime = fake
|
||||
? createFakeRuntime({ registry, scripts, onEvent, onEventError, fake: { vision: true } }).runtime
|
||||
? createFakeRuntime({ registry, scripts, onEvent, onEventError, onReport, fake: { vision: true } }).runtime
|
||||
: new PiAgentRuntime({
|
||||
registry,
|
||||
onEvent,
|
||||
onEventError,
|
||||
onReport,
|
||||
upstream: { spec: upstream.spec, credentials: upstream.credentials },
|
||||
});
|
||||
const systemPrompt = buildSystemPrompt({
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
type FakeScript,
|
||||
PiAgentRuntime,
|
||||
type RunOutcome,
|
||||
type RuntimeReport,
|
||||
type SessionKind,
|
||||
type SkillDoc,
|
||||
selectSkills,
|
||||
@@ -399,6 +400,15 @@ export async function buildRunPrompt(
|
||||
return { systemPrompt, kind, skills, available };
|
||||
}
|
||||
|
||||
/**
|
||||
* 运行时内部错误(本次运行扩展的系统提示 / 能力工具 / 白名单与预算钩子抛错,pi-durable 的 onReport)→ warn 日志。
|
||||
* message 已由运行时脱敏;只记位置与信息,不记原始错误对象。
|
||||
*/
|
||||
export function runtimeReporter(ctx: ServerContext): (r: RuntimeReport) => void {
|
||||
return (r) =>
|
||||
ctx.logger.warn({ runId: r.runId, source: r.source, err: { message: r.message } }, "agent 运行时内部错误");
|
||||
}
|
||||
|
||||
/** 读 agent_run_event 里最后一轮的结束事件(崩溃发生在"模型已结束、业务状态未写"之间时复用) */
|
||||
async function lastOutcomeEvent(env: AgentEnv, runId: string) {
|
||||
const r = await env.ctx.db
|
||||
@@ -460,6 +470,7 @@ export async function drive(
|
||||
const onEvent = eventSink(env);
|
||||
const onEventError = (err: unknown, e: AgentRunEvent) =>
|
||||
ctx.logger.warn({ runId, seq: e.seq, err: { message: (err as Error).message } }, "agent 事件落库失败");
|
||||
const onReport = runtimeReporter(ctx);
|
||||
let scripts: FakeScript[] = DEMO_SCRIPTS;
|
||||
if (fake) {
|
||||
try {
|
||||
@@ -475,11 +486,12 @@ export async function drive(
|
||||
}
|
||||
}
|
||||
const runtime = fake
|
||||
? createFakeRuntime({ registry, scripts, onEvent, onEventError, fake: { vision: true } }).runtime
|
||||
? createFakeRuntime({ registry, scripts, onEvent, onEventError, onReport, fake: { vision: true } }).runtime
|
||||
: new PiAgentRuntime({
|
||||
registry,
|
||||
onEvent,
|
||||
onEventError,
|
||||
onReport,
|
||||
...(upstream ? { upstream: { spec: upstream.spec, credentials: upstream.credentials } } : {}),
|
||||
});
|
||||
const maxSeq = await ctx.db
|
||||
|
||||
Reference in new issue
Block a user