niceeval 0.1.2 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +21 -7
- package/src/agents/ai-sdk-otel.test.ts +22 -0
- package/src/agents/ai-sdk-otel.ts +0 -0
- package/src/agents/ai-sdk.test.ts +88 -3
- package/src/agents/ai-sdk.ts +52 -54
- package/src/agents/index.ts +5 -0
- package/src/agents/ui-message-stream.test.ts +4 -12
- package/src/agents/ui-message-stream.ts +14 -18
- package/src/scoring/scoped.ts +66 -18
- package/src/view/app/components/CodeView.tsx +7 -14
- package/src/view/app/lib/transcript-data.tsx +20 -4
- package/src/view/app/types.ts +3 -1
- package/src/view/client-dist/app.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "niceeval",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Agent-native eval tool — eval agents, services, functions, and coding-agent fixtures",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,6 +28,10 @@
|
|
|
28
28
|
"types": "./src/agents/index.ts",
|
|
29
29
|
"import": "./src/agents/index.ts"
|
|
30
30
|
},
|
|
31
|
+
"./adapter/otel": {
|
|
32
|
+
"types": "./src/agents/ai-sdk-otel.ts",
|
|
33
|
+
"import": "./src/agents/ai-sdk-otel.ts"
|
|
34
|
+
},
|
|
31
35
|
"./expect": {
|
|
32
36
|
"types": "./src/expect/index.ts",
|
|
33
37
|
"import": "./src/expect/index.ts"
|
|
@@ -52,13 +56,11 @@
|
|
|
52
56
|
"tar-stream": "^3.1.7",
|
|
53
57
|
"tsx": "^4.19.2"
|
|
54
58
|
},
|
|
55
|
-
"optionalDependencies": {
|
|
56
|
-
"@vercel/sandbox": "^2.2.1",
|
|
57
|
-
"dockerode": "^4.0.2",
|
|
58
|
-
"e2b": "^2.31.0"
|
|
59
|
-
},
|
|
60
59
|
"devDependencies": {
|
|
61
60
|
"@ai-sdk/otel": "^1.0.9",
|
|
61
|
+
"@vercel/sandbox": "^2.2.1",
|
|
62
|
+
"dockerode": "^4.0.2",
|
|
63
|
+
"e2b": "^2.31.0",
|
|
62
64
|
"@opentelemetry/exporter-trace-otlp-http": "^0.219.0",
|
|
63
65
|
"@opentelemetry/sdk-trace-node": "^2.8.0",
|
|
64
66
|
"@radix-ui/react-collapsible": "^1.1.14",
|
|
@@ -91,12 +93,18 @@
|
|
|
91
93
|
"@ai-sdk/otel": ">=1.0.0",
|
|
92
94
|
"@opentelemetry/exporter-trace-otlp-http": ">=0.200.0",
|
|
93
95
|
"@opentelemetry/sdk-trace-node": ">=2.0.0",
|
|
94
|
-
"
|
|
96
|
+
"@vercel/sandbox": ">=2.0.0",
|
|
97
|
+
"ai": ">=5.0.0",
|
|
98
|
+
"dockerode": ">=4.0.0",
|
|
99
|
+
"e2b": ">=2.0.0"
|
|
95
100
|
},
|
|
96
101
|
"peerDependenciesMeta": {
|
|
97
102
|
"@ai-sdk/otel": {
|
|
98
103
|
"optional": true
|
|
99
104
|
},
|
|
105
|
+
"@vercel/sandbox": {
|
|
106
|
+
"optional": true
|
|
107
|
+
},
|
|
100
108
|
"ai": {
|
|
101
109
|
"optional": true
|
|
102
110
|
},
|
|
@@ -105,6 +113,12 @@
|
|
|
105
113
|
},
|
|
106
114
|
"@opentelemetry/sdk-trace-node": {
|
|
107
115
|
"optional": true
|
|
116
|
+
},
|
|
117
|
+
"dockerode": {
|
|
118
|
+
"optional": true
|
|
119
|
+
},
|
|
120
|
+
"e2b": {
|
|
121
|
+
"optional": true
|
|
108
122
|
}
|
|
109
123
|
},
|
|
110
124
|
"scripts": {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { aiSdkOtel } from "./ai-sdk-otel.ts";
|
|
4
|
+
|
|
5
|
+
describe("aiSdkOtel", () => {
|
|
6
|
+
it("为端点建出带一个 @ai-sdk/otel 集成的遥测件,flush 可用", async () => {
|
|
7
|
+
const pipeline = aiSdkOtel();
|
|
8
|
+
const turn = pipeline.telemetryForEndpoint("http://127.0.0.1:4318/v1/traces");
|
|
9
|
+
expect(turn.settings.integrations).toHaveLength(1);
|
|
10
|
+
await expect(turn.flush()).resolves.toBeUndefined(); // 没有 span 时 flush 不发网络请求
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("同端点复用 provider,不同端点各建一条(并行 attempt 的 span 不串流)", () => {
|
|
14
|
+
const pipeline = aiSdkOtel();
|
|
15
|
+
const a1 = pipeline.telemetryForEndpoint("http://127.0.0.1:4318/v1/traces");
|
|
16
|
+
const a2 = pipeline.telemetryForEndpoint("http://127.0.0.1:4318/v1/traces");
|
|
17
|
+
const b = pipeline.telemetryForEndpoint("http://127.0.0.1:4319/v1/traces");
|
|
18
|
+
const tracerOf = (t: typeof a1) => (t.settings.integrations[0] as { tracer?: unknown }).tracer;
|
|
19
|
+
expect(tracerOf(a1)).toBe(tracerOf(a2));
|
|
20
|
+
expect(tracerOf(a1)).not.toBe(tracerOf(b));
|
|
21
|
+
});
|
|
22
|
+
});
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
|
|
3
3
|
import { aiSdkAgent, fromAiSdk } from "./ai-sdk.ts";
|
|
4
|
-
import type { AiSdkGenerateContext, AiSdkResultLike } from "./ai-sdk.ts";
|
|
4
|
+
import type { AiSdkGenerateContext, AiSdkResultLike, AiSdkTracing } from "./ai-sdk.ts";
|
|
5
5
|
import type { AgentContext } from "../types.ts";
|
|
6
6
|
import { createAgentSession } from "../context/session.ts";
|
|
7
7
|
|
|
@@ -250,7 +250,7 @@ describe("fromAiSdk", () => {
|
|
|
250
250
|
expect(seen[2]).toEqual([{ role: "user", content: "新会话" }]);
|
|
251
251
|
});
|
|
252
252
|
|
|
253
|
-
it("aiSdkAgent:approval 停轮 → waiting
|
|
253
|
+
it("aiSdkAgent:approval 停轮 → waiting;下一轮 responses 翻译成 tool-approval-response", async () => {
|
|
254
254
|
const seen: unknown[][] = [];
|
|
255
255
|
let call = 0;
|
|
256
256
|
const agent = aiSdkAgent({
|
|
@@ -282,7 +282,10 @@ describe("fromAiSdk", () => {
|
|
|
282
282
|
expect(first.status).toBe("waiting");
|
|
283
283
|
expect(first.events.some((e) => e.type === "input.requested")).toBe(true);
|
|
284
284
|
|
|
285
|
-
const second = await agent.send(
|
|
285
|
+
const second = await agent.send(
|
|
286
|
+
{ text: "approve", responses: [{ requestId: "appr_1", optionId: "approve" }] },
|
|
287
|
+
fakeCtx({ id: ctx.session.id }),
|
|
288
|
+
);
|
|
286
289
|
expect(second.status).toBe("completed");
|
|
287
290
|
// 第二轮历史的最后一条是翻译好的裁决(tool 消息),不是用户文本
|
|
288
291
|
const last = (seen[1] as { role: string; content: unknown }[]).at(-1);
|
|
@@ -335,6 +338,88 @@ describe("fromAiSdk", () => {
|
|
|
335
338
|
});
|
|
336
339
|
});
|
|
337
340
|
|
|
341
|
+
it("aiSdkAgent:approval 停轮期间的 send 没带对位 responses → 直接报错(不从文本猜)", async () => {
|
|
342
|
+
const agent = aiSdkAgent({
|
|
343
|
+
generate: async () => ({
|
|
344
|
+
steps: [
|
|
345
|
+
{
|
|
346
|
+
content: [
|
|
347
|
+
{ type: "tool-call", toolCallId: "c1", toolName: "send_email", input: {} },
|
|
348
|
+
{ type: "tool-approval-request", approvalId: "appr_1", toolCall: { toolCallId: "c1", toolName: "send_email", input: {} } },
|
|
349
|
+
],
|
|
350
|
+
},
|
|
351
|
+
],
|
|
352
|
+
responseMessages: [{ role: "assistant", content: [] }],
|
|
353
|
+
} satisfies AiSdkResultLike),
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
const ctx = fakeCtx();
|
|
357
|
+
const first = await agent.send({ text: "发邮件" }, ctx);
|
|
358
|
+
expect(first.status).toBe("waiting");
|
|
359
|
+
await expect(agent.send({ text: "approve" }, fakeCtx({ id: ctx.session.id }))).rejects.toThrow(/t\.respond/);
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it("aiSdkAgent:tracing 管线——每轮拿 per-attempt 端点建集成经 ctx.telemetry 交给 generate,轮末 flush", async () => {
|
|
363
|
+
const endpoints: string[] = [];
|
|
364
|
+
const flushed: string[] = [];
|
|
365
|
+
const tracing: AiSdkTracing = {
|
|
366
|
+
telemetryForEndpoint(endpoint) {
|
|
367
|
+
endpoints.push(endpoint);
|
|
368
|
+
return {
|
|
369
|
+
settings: { integrations: ["fake-integration"] },
|
|
370
|
+
flush: async () => { flushed.push(endpoint); },
|
|
371
|
+
};
|
|
372
|
+
},
|
|
373
|
+
};
|
|
374
|
+
let seenTelemetry: unknown;
|
|
375
|
+
const agent = aiSdkAgent({
|
|
376
|
+
tracing,
|
|
377
|
+
generate: async ({ telemetry }) => {
|
|
378
|
+
seenTelemetry = telemetry;
|
|
379
|
+
return { text: "ok" };
|
|
380
|
+
},
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const turn = await agent.send(
|
|
384
|
+
{ text: "hi" },
|
|
385
|
+
{ ...fakeCtx(), telemetry: { endpoint: "http://127.0.0.1:4318/v1/traces" } },
|
|
386
|
+
);
|
|
387
|
+
expect(turn.status).toBe("completed");
|
|
388
|
+
expect(seenTelemetry).toEqual({ integrations: ["fake-integration"] });
|
|
389
|
+
expect(endpoints).toEqual(["http://127.0.0.1:4318/v1/traces"]);
|
|
390
|
+
expect(flushed).toEqual(["http://127.0.0.1:4318/v1/traces"]);
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
it("aiSdkAgent:generate 抛错也要 flush(本轮已产生的 span 不能丢)", async () => {
|
|
394
|
+
let flushes = 0;
|
|
395
|
+
const tracing: AiSdkTracing = {
|
|
396
|
+
telemetryForEndpoint: () => ({
|
|
397
|
+
settings: { integrations: [] },
|
|
398
|
+
flush: async () => { flushes++; },
|
|
399
|
+
}),
|
|
400
|
+
};
|
|
401
|
+
const agent = aiSdkAgent({
|
|
402
|
+
tracing,
|
|
403
|
+
generate: async () => { throw new Error("upstream timeout"); },
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
const turn = await agent.send({ text: "hi" }, { ...fakeCtx(), telemetry: { endpoint: "http://e/v1/traces" } });
|
|
407
|
+
expect(turn.status).toBe("failed");
|
|
408
|
+
expect(flushes).toBe(1);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it("aiSdkAgent:没配 tracing 时 generate 的 telemetry 恒为 undefined", async () => {
|
|
412
|
+
let seenTelemetry: unknown = "sentinel";
|
|
413
|
+
const agent = aiSdkAgent({
|
|
414
|
+
generate: async ({ telemetry }) => {
|
|
415
|
+
seenTelemetry = telemetry;
|
|
416
|
+
return { text: "ok" };
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
await agent.send({ text: "hi" }, fakeCtx());
|
|
420
|
+
expect(seenTelemetry).toBeUndefined();
|
|
421
|
+
});
|
|
422
|
+
|
|
338
423
|
it("aiSdkAgent:generate 抛错 / 空结果 → failed + error 事件", async () => {
|
|
339
424
|
const boom = aiSdkAgent({ generate: async () => { throw new Error("上游超时"); } });
|
|
340
425
|
const failed = await boom.send({ text: "hi" }, fakeCtx());
|
package/src/agents/ai-sdk.ts
CHANGED
|
@@ -367,8 +367,9 @@ export interface AiSdkGenerateContext<M = unknown> {
|
|
|
367
367
|
readonly signal: AbortSignal;
|
|
368
368
|
readonly flags: Readonly<Record<string, unknown>>;
|
|
369
369
|
/**
|
|
370
|
-
*
|
|
371
|
-
* 选项。OTel provider、per-attempt 端点绑定和轮末 flush
|
|
370
|
+
* 配了 `tracing`(如 `aiSdkOtel()`)才有:直接放进 generateText / streamText 的
|
|
371
|
+
* `telemetry` 选项。OTel provider、per-attempt 端点绑定和轮末 flush 都由工厂做,
|
|
372
|
+
* 应用侧原样透传即可。
|
|
372
373
|
*/
|
|
373
374
|
readonly telemetry?: AiSdkTelemetrySettings;
|
|
374
375
|
}
|
|
@@ -381,17 +382,40 @@ export interface AiSdkTelemetrySettings {
|
|
|
381
382
|
readonly integrations: any[];
|
|
382
383
|
}
|
|
383
384
|
|
|
385
|
+
/** tracing 管线为某一轮建好的遥测件(`AiSdkTracing.telemetryForEndpoint` 的返回值)。 */
|
|
386
|
+
export interface AiSdkTurnTelemetry {
|
|
387
|
+
/** 直接放进 generateText / streamText 的 `telemetry` 选项。 */
|
|
388
|
+
settings: AiSdkTelemetrySettings;
|
|
389
|
+
/** 每轮结束后由工厂调用:轮次归属靠时间窗口,span 必须立刻送到,不能等 batch。 */
|
|
390
|
+
flush(): Promise<void>;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* `aiSdkAgent` 的 tracing 管线契约。内置实现是 `niceeval/adapter/otel` 的 `aiSdkOtel()`——
|
|
395
|
+
* 独立子路径导出,OTel 三件套是可选 peer 依赖,只有 import 那个入口的项目才需要安装;
|
|
396
|
+
* 这里只放形状,`niceeval/adapter` 本身零 OTel 依赖。
|
|
397
|
+
*/
|
|
398
|
+
export interface AiSdkTracing {
|
|
399
|
+
/** 为本轮的 OTLP 接收端点建(或复用)一条导出管线。每个 attempt 端点不同,按端点缓存。 */
|
|
400
|
+
telemetryForEndpoint(endpoint: string): AiSdkTurnTelemetry;
|
|
401
|
+
}
|
|
402
|
+
|
|
384
403
|
export interface AiSdkAgentOptions<M = unknown> {
|
|
385
404
|
/** agent 名(报告 / 结果聚合的身份)。默认 "ai-sdk"。 */
|
|
386
405
|
name?: string;
|
|
387
406
|
/**
|
|
388
|
-
* 开 OTel 管线(拿 `niceeval view` 的瀑布图)
|
|
389
|
-
* per-attempt OTLP
|
|
390
|
-
*
|
|
391
|
-
* generateText / streamText 的 `telemetry`
|
|
392
|
-
*
|
|
407
|
+
* 开 OTel 管线(拿 `niceeval view` 的瀑布图):传 `niceeval/adapter/otel` 的
|
|
408
|
+
* `aiSdkOtel()`。设了运行器就为这个 agent 开 per-attempt OTLP 接收器,工厂每轮用
|
|
409
|
+
* 管线建好绑定接收端点的集成,经 `generate` 的 ctx.telemetry 交给应用,原样透传给
|
|
410
|
+
* generateText / streamText 的 `telemetry` 选项即可。省略则整个 OTel 管线不开,
|
|
411
|
+
* `generate` 拿到的 `telemetry` 恒为 undefined,应用侧零开销。
|
|
412
|
+
*
|
|
413
|
+
* ```typescript
|
|
414
|
+
* import { aiSdkOtel } from "niceeval/adapter/otel";
|
|
415
|
+
* aiSdkAgent({ tracing: aiSdkOtel(), generate });
|
|
416
|
+
* ```
|
|
393
417
|
*/
|
|
394
|
-
tracing?:
|
|
418
|
+
tracing?: AiSdkTracing;
|
|
395
419
|
/**
|
|
396
420
|
* 每轮一召:拿会话历史跑一次 generateText / streamText(await 完整结果)并原样返回。
|
|
397
421
|
* model / tools / system prompt / stopWhen 都在这里配 —— 那是应用的事,工厂不掺和。
|
|
@@ -399,11 +423,6 @@ export interface AiSdkAgentOptions<M = unknown> {
|
|
|
399
423
|
generate(ctx: AiSdkGenerateContext<M>): Promise<AiSdkResultLike>;
|
|
400
424
|
/** 本轮的结构化输出(Turn.data,喂 outputEquals / outputMatches)。省略则 data 为 undefined。 */
|
|
401
425
|
data?(result: AiSdkResultLike, turn: AiSdkTurn): unknown;
|
|
402
|
-
/**
|
|
403
|
-
* 可选双发:tracing 的 span 除发给 niceeval 的接收器外,同一批也发到你自己的 OTLP
|
|
404
|
-
* 后端(Langfuse / SigNoz / 生产 collector)。只在 `tracing: true` 时生效。
|
|
405
|
-
*/
|
|
406
|
-
otlpBackendUrl?: string;
|
|
407
426
|
}
|
|
408
427
|
|
|
409
428
|
/**
|
|
@@ -417,10 +436,10 @@ export interface AiSdkAgentOptions<M = unknown> {
|
|
|
417
436
|
* tool-approval-response(以 approve / yes / 同意 / 批准 开头 = 批准,其余一律拒绝)塞回
|
|
418
437
|
* messages 再召 `generate`,SDK 才会执行(或跳过)被拦的工具;
|
|
419
438
|
* · 失败兜底:`generate` 抛错或结果完全为空 → `status: "failed"` + error 事件;
|
|
420
|
-
* · tracing
|
|
421
|
-
* 接收端点的 `@ai-sdk/otel` 集成(经
|
|
422
|
-
* generateText 的 `telemetry` 即可)并在轮末
|
|
423
|
-
*
|
|
439
|
+
* · tracing:传 `tracing: aiSdkOtel()`(来自 `niceeval/adapter/otel`)后,工厂替应用
|
|
440
|
+
* 做完 OTel 管线——为每轮建好绑定 niceeval 接收端点的 `@ai-sdk/otel` 集成(经
|
|
441
|
+
* ctx.telemetry 交给 generate,原样透传给 generateText 的 `telemetry` 即可)并在轮末
|
|
442
|
+
* flush;`aiSdkOtel({ backendUrl })` 可选双发到你自己的观测后端。应用侧零埋点代码。
|
|
424
443
|
*
|
|
425
444
|
* ```typescript
|
|
426
445
|
* import { aiSdkAgent } from "niceeval/adapter";
|
|
@@ -435,20 +454,6 @@ export interface AiSdkAgentOptions<M = unknown> {
|
|
|
435
454
|
* });
|
|
436
455
|
* ```
|
|
437
456
|
*/
|
|
438
|
-
let otelModule: Promise<typeof import("./ai-sdk-otel.ts")> | undefined;
|
|
439
|
-
|
|
440
|
-
/** OTel 管线按需加载:三个 OTel 包是可选 peer,只有开了 tracing 的用户需要装。 */
|
|
441
|
-
function loadOtel(): Promise<typeof import("./ai-sdk-otel.ts")> {
|
|
442
|
-
otelModule ??= import("./ai-sdk-otel.ts").catch((error: unknown) => {
|
|
443
|
-
otelModule = undefined;
|
|
444
|
-
throw new Error(
|
|
445
|
-
"tracing: true 需要 OTel 依赖:请在被测项目里安装 @ai-sdk/otel、@opentelemetry/sdk-trace-node、@opentelemetry/exporter-trace-otlp-http(niceeval 的可选 peer 依赖)。",
|
|
446
|
-
{ cause: error },
|
|
447
|
-
);
|
|
448
|
-
});
|
|
449
|
-
return otelModule;
|
|
450
|
-
}
|
|
451
|
-
|
|
452
457
|
export function aiSdkAgent<M = unknown>(options: AiSdkAgentOptions<M>): Agent {
|
|
453
458
|
interface SessionState {
|
|
454
459
|
messages: M[];
|
|
@@ -474,15 +479,12 @@ export function aiSdkAgent<M = unknown>(options: AiSdkAgentOptions<M>): Agent {
|
|
|
474
479
|
}
|
|
475
480
|
|
|
476
481
|
if (state.pendingApprovals.length > 0) {
|
|
477
|
-
// HITL:t.respond 的回答到 adapter 就是一次普通的带
|
|
478
|
-
//
|
|
479
|
-
|
|
480
|
-
// (行数不够沿用最后一行)——内置件要防御式兼容,回退路径保留。
|
|
481
|
-
const lines = input.text.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
482
|
-
const content = state.pendingApprovals.map((approvalId, i) => ({
|
|
482
|
+
// HITL:t.respond 的回答到 adapter 就是一次普通的带 responses 的 send,按
|
|
483
|
+
// requestId(= approvalId)对位取裁决;没答到的请求直接报错,不从文本猜。
|
|
484
|
+
const content = state.pendingApprovals.map((approvalId) => ({
|
|
483
485
|
type: "tool-approval-response" as const,
|
|
484
486
|
approvalId,
|
|
485
|
-
approved:
|
|
487
|
+
approved: approvalDecision(input.responses, approvalId),
|
|
486
488
|
}));
|
|
487
489
|
state.pendingApprovals = [];
|
|
488
490
|
state.messages.push({ role: "tool", content } as M);
|
|
@@ -490,8 +492,9 @@ export function aiSdkAgent<M = unknown>(options: AiSdkAgentOptions<M>): Agent {
|
|
|
490
492
|
state.messages.push(userMessage(input.text, input.files) as M);
|
|
491
493
|
}
|
|
492
494
|
|
|
493
|
-
// tracing
|
|
494
|
-
|
|
495
|
+
// tracing 管线由调用方显式传入(niceeval/adapter/otel 的 aiSdkOtel()),工厂只管
|
|
496
|
+
// 每轮把 per-attempt 端点交给它、轮末 flush。
|
|
497
|
+
const otel = ctx.telemetry && options.tracing ? options.tracing.telemetryForEndpoint(ctx.telemetry.endpoint) : undefined;
|
|
495
498
|
|
|
496
499
|
let result: AiSdkResultLike;
|
|
497
500
|
try {
|
|
@@ -517,31 +520,26 @@ export function aiSdkAgent<M = unknown>(options: AiSdkAgentOptions<M>): Agent {
|
|
|
517
520
|
const turn = fromAiSdk(result);
|
|
518
521
|
// 上游偶尔退化返回完全空的结果;当正常回复会把故障伪装成通过,按失败处理。
|
|
519
522
|
if (turn.events.length === 0) {
|
|
520
|
-
return { status: "failed", events: [{ type: "error", message: "AI SDK
|
|
523
|
+
return { status: "failed", events: [{ type: "error", message: "AI SDK returned an empty result (no text, no tool calls)" }] };
|
|
521
524
|
}
|
|
522
525
|
return { ...turn, data: options.data?.(result, turn) };
|
|
523
526
|
},
|
|
524
527
|
});
|
|
525
528
|
}
|
|
526
529
|
|
|
530
|
+
/** 裁决词法(t.respond 的自由文本回答):approve / yes / 同意 / 批准 开头 = 批准,其余一律拒绝。 */
|
|
527
531
|
function isApproved(line: string): boolean {
|
|
528
532
|
return /^(approve|yes|同意|批准)/i.test(line);
|
|
529
533
|
}
|
|
530
534
|
|
|
531
|
-
/**
|
|
532
|
-
|
|
533
|
-
* 拿不到匹配的 responses 才退回从整行文本猜(见 isApproved)——防御式兼容旧 adapter 用法,
|
|
534
|
-
* 不删旧分支。
|
|
535
|
-
*/
|
|
536
|
-
function approvedFromResponse(
|
|
537
|
-
responses: readonly InputResponse[] | undefined,
|
|
538
|
-
requestId: string,
|
|
539
|
-
fallbackText: string,
|
|
540
|
-
): boolean {
|
|
535
|
+
/** 按 requestId(= approvalId)从 input.responses 对位取裁决;optionId 优先,自由文本走 isApproved。 */
|
|
536
|
+
function approvalDecision(responses: readonly InputResponse[] | undefined, requestId: string): boolean {
|
|
541
537
|
const matched = responses?.find((r) => r.requestId === requestId);
|
|
542
|
-
if (matched
|
|
543
|
-
|
|
544
|
-
|
|
538
|
+
if (!matched) {
|
|
539
|
+
throw new Error(`No response for pending approval "${requestId}". Answer approval requests with t.respond(...).`);
|
|
540
|
+
}
|
|
541
|
+
if (matched.optionId !== undefined) return matched.optionId === "approve";
|
|
542
|
+
return isApproved(matched.text?.trim() ?? "");
|
|
545
543
|
}
|
|
546
544
|
|
|
547
545
|
/** 待人批准的 approval 请求 id(非 automatic)。steps 优先,退回 v7 顶层聚合 content。 */
|
package/src/agents/index.ts
CHANGED
|
@@ -34,15 +34,20 @@ export type {
|
|
|
34
34
|
export { driveFrameStream, deltaStream } from "./streaming.ts";
|
|
35
35
|
export type { FrameReducer, FrameHook, DeltaOp, DeltaStreamSpec } from "./streaming.ts";
|
|
36
36
|
|
|
37
|
+
// tracing 管线的内置实现 aiSdkOtel() 在 `niceeval/adapter/otel`(独立子路径,不从这里
|
|
38
|
+
// re-export):OTel 三件套是可选 peer 依赖,只有 import 那个入口的项目才需要安装。
|
|
37
39
|
export { fromAiSdk, aiSdkAgent } from "./ai-sdk.ts";
|
|
38
40
|
export type {
|
|
39
41
|
AiSdkAgentOptions,
|
|
40
42
|
AiSdkGenerateContext,
|
|
41
43
|
AiSdkResultLike,
|
|
42
44
|
AiSdkStepLike,
|
|
45
|
+
AiSdkTelemetrySettings,
|
|
43
46
|
AiSdkToolCallLike,
|
|
44
47
|
AiSdkToolResultLike,
|
|
48
|
+
AiSdkTracing,
|
|
45
49
|
AiSdkTurn,
|
|
50
|
+
AiSdkTurnTelemetry,
|
|
46
51
|
AiSdkUsageLike,
|
|
47
52
|
} from "./ai-sdk.ts";
|
|
48
53
|
|
|
@@ -149,7 +149,7 @@ describe("uiMessageStreamAgent", () => {
|
|
|
149
149
|
fetchMock.mockResolvedValueOnce(
|
|
150
150
|
sse([{ type: "tool-output-available", toolCallId: "c1", output: 2 }, { type: "text-delta", delta: "= 2" }]),
|
|
151
151
|
);
|
|
152
|
-
const turn2 = await agent.send({ text: "approve" }, c);
|
|
152
|
+
const turn2 = await agent.send({ text: "approve", responses: [{ requestId: "ap1", optionId: "approve" }] }, c);
|
|
153
153
|
expect(turn2.status).toBe("completed");
|
|
154
154
|
expect(turn2.events).toEqual([
|
|
155
155
|
{ type: "action.called", callId: "c1", name: "calculate", input: { expr: "1+1" } },
|
|
@@ -177,7 +177,7 @@ describe("uiMessageStreamAgent", () => {
|
|
|
177
177
|
await agent.send({ text: "算" }, c);
|
|
178
178
|
|
|
179
179
|
fetchMock.mockResolvedValueOnce(sse([{ type: "text-delta", delta: "好的,不算了" }]));
|
|
180
|
-
const turn2 = await agent.send({ text: "deny" }, c);
|
|
180
|
+
const turn2 = await agent.send({ text: "deny", responses: [{ requestId: "ap1", optionId: "deny" }] }, c);
|
|
181
181
|
expect(turn2.status).toBe("completed");
|
|
182
182
|
expect(turn2.events).toEqual([
|
|
183
183
|
{ type: "action.called", callId: "c1", name: "calculate", input: { expr: "1+1" } },
|
|
@@ -211,7 +211,7 @@ describe("uiMessageStreamAgent", () => {
|
|
|
211
211
|
expect(mutated.approval).toMatchObject({ approved: false });
|
|
212
212
|
});
|
|
213
213
|
|
|
214
|
-
it("HITL
|
|
214
|
+
it("HITL:approval 停轮期间的 send 没带对位 responses → 直接报错(不从文本猜)", async () => {
|
|
215
215
|
const agent = uiMessageStreamAgent({ name: "t", url: "http://x/api/chat" });
|
|
216
216
|
fetchMock.mockResolvedValueOnce(
|
|
217
217
|
sse([
|
|
@@ -222,15 +222,7 @@ describe("uiMessageStreamAgent", () => {
|
|
|
222
222
|
const c = ctx();
|
|
223
223
|
await agent.send({ text: "算 1+1" }, c);
|
|
224
224
|
|
|
225
|
-
|
|
226
|
-
sse([{ type: "tool-output-available", toolCallId: "c1", output: 2 }, { type: "text-delta", delta: "= 2" }]),
|
|
227
|
-
);
|
|
228
|
-
const turn2 = await agent.send({ text: "approve" }, c); // 没有 responses 字段
|
|
229
|
-
expect(turn2.events).toEqual([
|
|
230
|
-
{ type: "action.called", callId: "c1", name: "calculate", input: { expr: "1+1" } },
|
|
231
|
-
{ type: "action.result", callId: "c1", output: 2, status: "completed" },
|
|
232
|
-
{ type: "message", role: "assistant", text: "= 2" },
|
|
233
|
-
]);
|
|
225
|
+
await expect(agent.send({ text: "approve" }, c)).rejects.toThrow(/t\.respond/);
|
|
234
226
|
});
|
|
235
227
|
|
|
236
228
|
it("error 帧 → failed + error 事件", async () => {
|
|
@@ -135,25 +135,19 @@ function isApprovalRequested(part: UIMessagePartLike): boolean {
|
|
|
135
135
|
return isToolPart(part) && part.state === "approval-requested";
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
/** 和 aiSdkAgent
|
|
138
|
+
/** 和 aiSdkAgent 同一词法(t.respond 的自由文本回答):approve / yes / 同意 / 批准 开头 = 批准。 */
|
|
139
139
|
function isApproved(text: string): boolean {
|
|
140
140
|
return /^(approve|yes|同意|批准)/i.test(text.trim());
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
/**
|
|
144
|
-
|
|
145
|
-
* 拿不到 responses(旧 adapter / 手写 send 未接结构化回答)才退回从 input.text 猜的路径,
|
|
146
|
-
* 防御式保留,不删旧分支。
|
|
147
|
-
*/
|
|
148
|
-
function approvedFromResponse(
|
|
149
|
-
responses: readonly InputResponse[] | undefined,
|
|
150
|
-
requestId: string | undefined,
|
|
151
|
-
fallbackText: string,
|
|
152
|
-
): boolean {
|
|
143
|
+
/** 按 requestId 从 input.responses 对位取裁决;optionId 优先,自由文本走 isApproved,没答到直接报错。 */
|
|
144
|
+
function approvalDecision(responses: readonly InputResponse[] | undefined, requestId: string | undefined): boolean {
|
|
153
145
|
const matched = responses?.find((r) => r.requestId === requestId);
|
|
154
|
-
if (matched
|
|
155
|
-
|
|
156
|
-
|
|
146
|
+
if (!matched) {
|
|
147
|
+
throw new Error(`No response for pending approval "${requestId ?? "unknown"}". Answer approval requests with t.respond(...).`);
|
|
148
|
+
}
|
|
149
|
+
if (matched.optionId !== undefined) return matched.optionId === "approve";
|
|
150
|
+
return isApproved(matched.text ?? "");
|
|
157
151
|
}
|
|
158
152
|
|
|
159
153
|
/** 已报告的进度:resume 续跑的是同一条 assistant 消息,跨轮去重靠它。 */
|
|
@@ -273,9 +267,9 @@ export function uiMessageStreamAgent(options: UiMessageStreamAgentOptions): Agen
|
|
|
273
267
|
if (pendingPart && lastMessage) {
|
|
274
268
|
// HITL 续跑:不追加新 user 消息 —— 把停在 approval-requested 的 part 原地改成
|
|
275
269
|
// approval-responded,原样重发,服务端续跑同一条被打断的 assistant 消息。
|
|
276
|
-
//
|
|
270
|
+
// 裁决按 requestId 从 input.responses 对位读取(t.respond 的结构化回答)。
|
|
277
271
|
const requestId = pendingPart.approval?.id ?? pendingPart.toolCallId;
|
|
278
|
-
const approved =
|
|
272
|
+
const approved = approvalDecision(input.responses, requestId);
|
|
279
273
|
const mutatedParts = lastMessage.parts.map((part) =>
|
|
280
274
|
isApprovalRequested(part) && part.approval?.id === pendingPart.approval?.id
|
|
281
275
|
? {
|
|
@@ -313,11 +307,13 @@ export function uiMessageStreamAgent(options: UiMessageStreamAgentOptions): Agen
|
|
|
313
307
|
} catch (err) {
|
|
314
308
|
if (ctx.signal.aborted) throw err;
|
|
315
309
|
const cause = err instanceof Error ? (err.cause instanceof Error ? err.cause.message : err.message) : String(err);
|
|
316
|
-
throw new Error(
|
|
310
|
+
throw new Error(
|
|
311
|
+
`Could not connect to ${url} (${cause}). Is the app under test running? Start it yourself first, or point url at a deployed instance via config.`,
|
|
312
|
+
);
|
|
317
313
|
}
|
|
318
314
|
if (!res.ok || !res.body) {
|
|
319
315
|
throw new Error(
|
|
320
|
-
`POST ${url}
|
|
316
|
+
`POST ${url} failed: ${res.status} ${await res.text().catch(() => "")}. Confirm the app is running and the endpoint speaks the UI Message Stream protocol (the backend useChat expects).`,
|
|
321
317
|
);
|
|
322
318
|
}
|
|
323
319
|
|
package/src/scoring/scoped.ts
CHANGED
|
@@ -49,8 +49,39 @@ function toolMatches(tc: ToolCall, name: string, match?: ToolMatch): boolean {
|
|
|
49
49
|
return true;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
// ── evidence:把调用的出入参带回断言结果,view 展开可见,不用翻原始事件流 ──
|
|
53
|
+
|
|
54
|
+
function briefJson(value: unknown, max = 800): string {
|
|
55
|
+
let s: string;
|
|
56
|
+
try {
|
|
57
|
+
s = JSON.stringify(value) ?? String(value);
|
|
58
|
+
} catch {
|
|
59
|
+
s = String(value);
|
|
60
|
+
}
|
|
61
|
+
return s.length > max ? s.slice(0, max) + "…" : s;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function describeCalls(calls: readonly ToolCall[]): string | undefined {
|
|
65
|
+
if (calls.length === 0) return undefined;
|
|
66
|
+
return calls
|
|
67
|
+
.map((tc) => {
|
|
68
|
+
const name = tc.originalName && tc.originalName !== tc.name ? tc.originalName : tc.name;
|
|
69
|
+
const lines = [`${name} [${tc.status}]`, ` input: ${briefJson(tc.input)}`];
|
|
70
|
+
if (tc.output !== undefined) lines.push(` output: ${briefJson(tc.output)}`);
|
|
71
|
+
return lines.join("\n");
|
|
72
|
+
})
|
|
73
|
+
.join("\n");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function describeSubagents(calls: readonly SubagentCall[]): string | undefined {
|
|
77
|
+
if (calls.length === 0) return undefined;
|
|
78
|
+
return calls
|
|
79
|
+
.map((s) => {
|
|
80
|
+
const lines = [`${s.name} [${s.status}]${s.remoteUrl ? ` ${s.remoteUrl}` : ""}`];
|
|
81
|
+
if (s.output !== undefined) lines.push(` output: ${briefJson(s.output)}`);
|
|
82
|
+
return lines.join("\n");
|
|
83
|
+
})
|
|
84
|
+
.join("\n");
|
|
54
85
|
}
|
|
55
86
|
|
|
56
87
|
function subagentMatches(call: SubagentCall, name: string, match?: SubagentMatch): boolean {
|
|
@@ -89,7 +120,8 @@ export function messageIncludes(token: string | RegExp): Spec {
|
|
|
89
120
|
.map((e) => e.text)
|
|
90
121
|
.join("\n");
|
|
91
122
|
const ok = token instanceof RegExp ? token.test(text) : text.includes(token);
|
|
92
|
-
|
|
123
|
+
// 失败时把实际被扫的助手文本带回来(和 t.check 的口径一致);命中时行色已说明一切。
|
|
124
|
+
return ok ? 1 : { score: 0, evidence: text ? (text.length > 4000 ? text.slice(0, 4000) + "…" : text) : undefined };
|
|
93
125
|
},
|
|
94
126
|
};
|
|
95
127
|
}
|
|
@@ -99,9 +131,13 @@ export function calledTool(name: string, match?: ToolMatch): Spec {
|
|
|
99
131
|
name: `calledTool(${name})`,
|
|
100
132
|
severity: "gate",
|
|
101
133
|
evaluate: (ctx) => {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
134
|
+
const matched = ctx.facts.toolCalls.filter((tc) => toolMatches(tc, name, match));
|
|
135
|
+
const n = matched.length;
|
|
136
|
+
const score = match?.count !== undefined ? (n === match.count ? 1 : 0) : n >= 1 ? 1 : 0;
|
|
137
|
+
// 命中给命中调用的出入参;没命中给同名调用(条件不满足的近失);再没有就列出实际调过的工具。
|
|
138
|
+
const sameName = ctx.facts.toolCalls.filter((tc) => tc.name === name || tc.originalName === name);
|
|
139
|
+
const shown = matched.length ? matched : sameName.length ? sameName : ctx.facts.toolCalls;
|
|
140
|
+
return { score, evidence: describeCalls(shown) };
|
|
105
141
|
},
|
|
106
142
|
};
|
|
107
143
|
}
|
|
@@ -110,7 +146,10 @@ export function notCalledTool(name: string, match?: ToolMatch): Spec {
|
|
|
110
146
|
return {
|
|
111
147
|
name: `notCalledTool(${name})`,
|
|
112
148
|
severity: "gate",
|
|
113
|
-
evaluate: (ctx) =>
|
|
149
|
+
evaluate: (ctx) => {
|
|
150
|
+
const matched = ctx.facts.toolCalls.filter((tc) => toolMatches(tc, name, match));
|
|
151
|
+
return { score: matched.length === 0 ? 1 : 0, evidence: describeCalls(matched) };
|
|
152
|
+
},
|
|
114
153
|
};
|
|
115
154
|
}
|
|
116
155
|
|
|
@@ -123,7 +162,8 @@ export function toolOrder(names: string[]): Spec {
|
|
|
123
162
|
for (const tc of ctx.facts.toolCalls) {
|
|
124
163
|
if (i < names.length && (tc.name === names[i] || tc.originalName === names[i])) i++;
|
|
125
164
|
}
|
|
126
|
-
|
|
165
|
+
const actual = ctx.facts.toolCalls.map((tc) => tc.originalName ?? tc.name).join(" → ");
|
|
166
|
+
return { score: i === names.length ? 1 : 0, evidence: actual || undefined };
|
|
127
167
|
},
|
|
128
168
|
};
|
|
129
169
|
}
|
|
@@ -132,7 +172,10 @@ export function usedNoTools(): Spec {
|
|
|
132
172
|
return {
|
|
133
173
|
name: "usedNoTools",
|
|
134
174
|
severity: "gate",
|
|
135
|
-
evaluate: (ctx) => (
|
|
175
|
+
evaluate: (ctx) => ({
|
|
176
|
+
score: ctx.facts.toolCalls.length === 0 ? 1 : 0,
|
|
177
|
+
evidence: describeCalls(ctx.facts.toolCalls),
|
|
178
|
+
}),
|
|
136
179
|
};
|
|
137
180
|
}
|
|
138
181
|
|
|
@@ -140,7 +183,10 @@ export function maxToolCalls(max: number): Spec {
|
|
|
140
183
|
return {
|
|
141
184
|
name: `maxToolCalls(${max})`,
|
|
142
185
|
severity: "gate",
|
|
143
|
-
evaluate: (ctx) => (
|
|
186
|
+
evaluate: (ctx) => ({
|
|
187
|
+
score: ctx.facts.toolCalls.length <= max ? 1 : 0,
|
|
188
|
+
evidence: describeCalls(ctx.facts.toolCalls),
|
|
189
|
+
}),
|
|
144
190
|
};
|
|
145
191
|
}
|
|
146
192
|
|
|
@@ -153,9 +199,10 @@ export function noFailedActions(): Spec {
|
|
|
153
199
|
name: "noFailedActions",
|
|
154
200
|
severity: "gate",
|
|
155
201
|
evaluate: (ctx) => {
|
|
156
|
-
const
|
|
157
|
-
const
|
|
158
|
-
|
|
202
|
+
const failedTools = ctx.facts.toolCalls.filter((tc) => tc.status === "failed");
|
|
203
|
+
const failedSubs = ctx.facts.subagentCalls.filter((s) => s.status === "failed");
|
|
204
|
+
const evidence = [describeCalls(failedTools), describeSubagents(failedSubs)].filter(Boolean).join("\n") || undefined;
|
|
205
|
+
return { score: failedTools.length || failedSubs.length ? 0 : 1, evidence };
|
|
159
206
|
},
|
|
160
207
|
};
|
|
161
208
|
}
|
|
@@ -165,9 +212,10 @@ export function calledSubagent(name: string, match?: SubagentMatch): Spec {
|
|
|
165
212
|
name: `calledSubagent(${name})`,
|
|
166
213
|
severity: "gate",
|
|
167
214
|
evaluate: (ctx) => {
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
215
|
+
const matched = ctx.facts.subagentCalls.filter((call) => subagentMatches(call, name, match));
|
|
216
|
+
const n = matched.length;
|
|
217
|
+
const score = match?.count !== undefined ? (n === match.count ? 1 : 0) : n >= 1 ? 1 : 0;
|
|
218
|
+
return { score, evidence: describeSubagents(matched.length ? matched : ctx.facts.subagentCalls) };
|
|
171
219
|
},
|
|
172
220
|
};
|
|
173
221
|
}
|
|
@@ -258,8 +306,8 @@ export function noFailedShellCommands(): Spec {
|
|
|
258
306
|
name: "noFailedShellCommands",
|
|
259
307
|
severity: "gate",
|
|
260
308
|
evaluate: (ctx) => {
|
|
261
|
-
const failed = ctx.facts.toolCalls.
|
|
262
|
-
return failed ? 0 : 1;
|
|
309
|
+
const failed = ctx.facts.toolCalls.filter((tc) => tc.name === "shell" && tc.status === "failed");
|
|
310
|
+
return { score: failed.length ? 0 : 1, evidence: describeCalls(failed) };
|
|
263
311
|
},
|
|
264
312
|
};
|
|
265
313
|
}
|
|
@@ -2,9 +2,9 @@ import { useCallback, useMemo, useState } from "react";
|
|
|
2
2
|
import { AlertCircle, CheckCircle2, ChevronRight, MessageCircle, XCircle } from "lucide-react";
|
|
3
3
|
import type { T } from "../shared.ts";
|
|
4
4
|
import type { Assertion, CodeSource, SourceTurn, TranscriptEvent } from "../types.ts";
|
|
5
|
-
import {
|
|
6
|
-
import { formatScore
|
|
7
|
-
import { Transcript } from "./Transcript.tsx";
|
|
5
|
+
import { highlightTs, indexAsserts, indexTurns, locKey } from "../lib/transcript-data.tsx";
|
|
6
|
+
import { formatScore } from "../lib/format.ts";
|
|
7
|
+
import { InputBlock, ToolBlock, Transcript } from "./Transcript.tsx";
|
|
8
8
|
|
|
9
9
|
/** soft 断言没过阈值不影响 outcome,颜色上跟 gate 失败(红)区分开,用 warn(黄)。 */
|
|
10
10
|
function assertTone(a: Assertion): "good" | "warn" | "bad" {
|
|
@@ -205,17 +205,10 @@ export function ReplyPanel({ turn, t }: { turn: SourceTurn; t: T }) {
|
|
|
205
205
|
);
|
|
206
206
|
if (r.kind === "error")
|
|
207
207
|
return <div key={j} className="reply-err">! {r.text}</div>;
|
|
208
|
-
if (r.kind === "tool")
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return (
|
|
213
|
-
<div key={j} className="reply-tool">
|
|
214
|
-
<span className="reply-tool-name">{arg ? `${verb}(${truncate(arg, 80)})` : verb}</span>
|
|
215
|
-
{out ? <span className="reply-tool-out">→ {truncate(previewText(out), 100)}</span> : null}
|
|
216
|
-
</div>
|
|
217
|
-
);
|
|
218
|
-
}
|
|
208
|
+
if (r.kind === "tool")
|
|
209
|
+
// 和 Transcript 同一个组件:摘要行显示工具名(入参)→ 出参预览,展开看完整出入参。
|
|
210
|
+
return <ToolBlock key={j} call={r.ev} result={r.result} t={t} />;
|
|
211
|
+
if (r.kind === "input") return <InputBlock key={j} event={{ type: "input.requested", request: r.ev.request }} t={t} />;
|
|
219
212
|
return null;
|
|
220
213
|
})}
|
|
221
214
|
</div>
|
|
@@ -16,6 +16,9 @@ export function locKey(file: string, line: number): string {
|
|
|
16
16
|
export function indexTurns(events: TranscriptEvent[]): IndexedTurns {
|
|
17
17
|
const byKey = new Map<string, SourceTurn>();
|
|
18
18
|
const noloc: SourceTurn[] = [];
|
|
19
|
+
// callId → tool 回复,跨轮共享:HITL(审批门)下 action.called 在 send 轮、
|
|
20
|
+
// action.result 在 respond 轮才到,只在当轮找会把结果丢掉。
|
|
21
|
+
const toolByCallId = new Map<string, Extract<SourceTurn["replies"][number], { kind: "tool" }>>();
|
|
19
22
|
let cur: SourceTurn | null = null;
|
|
20
23
|
for (const ev of events || []) {
|
|
21
24
|
if (ev.type === "message" && ev.role === "user") {
|
|
@@ -29,12 +32,14 @@ export function indexTurns(events: TranscriptEvent[]): IndexedTurns {
|
|
|
29
32
|
} else if (ev.type === "thinking") {
|
|
30
33
|
cur.replies.push({ kind: "thinking", text: ev.text || "" });
|
|
31
34
|
} else if (ev.type === "action.called") {
|
|
32
|
-
|
|
35
|
+
const reply = { kind: "tool" as const, ev };
|
|
36
|
+
toolByCallId.set(ev.callId, reply);
|
|
37
|
+
cur.replies.push(reply);
|
|
33
38
|
} else if (ev.type === "action.result") {
|
|
34
|
-
const tool =
|
|
35
|
-
(r): r is Extract<SourceTurn["replies"][number], { kind: "tool" }> => r.kind === "tool" && r.ev.callId === ev.callId,
|
|
36
|
-
);
|
|
39
|
+
const tool = toolByCallId.get(ev.callId);
|
|
37
40
|
if (tool) tool.result = ev;
|
|
41
|
+
} else if (ev.type === "input.requested") {
|
|
42
|
+
cur.replies.push({ kind: "input", ev });
|
|
38
43
|
} else if (ev.type === "error") {
|
|
39
44
|
cur.replies.push({ kind: "error", text: ev.message || "error" });
|
|
40
45
|
}
|
|
@@ -105,6 +110,17 @@ export function toolPrimaryArg(call: ToolBlockCall): string {
|
|
|
105
110
|
const value = input[key];
|
|
106
111
|
if (typeof value === "string" && value) return value;
|
|
107
112
|
}
|
|
113
|
+
// 领域工具(get_weather / calculate…)的入参 key 不在上面的通用名单里,
|
|
114
|
+
// 兜底给紧凑 JSON——入参是断言的一等材料,不能因为 key 认不出就不显示。
|
|
115
|
+
const keys = Object.keys(input);
|
|
116
|
+
if (keys.length > 0) {
|
|
117
|
+
try {
|
|
118
|
+
const compact = JSON.stringify(input);
|
|
119
|
+
return compact.length > 200 ? compact.slice(0, 200) + "…" : compact;
|
|
120
|
+
} catch {
|
|
121
|
+
return "";
|
|
122
|
+
}
|
|
123
|
+
}
|
|
108
124
|
return "";
|
|
109
125
|
}
|
|
110
126
|
|
package/src/view/app/types.ts
CHANGED
|
@@ -42,9 +42,11 @@ export type Reply =
|
|
|
42
42
|
| { kind: "text"; text: string }
|
|
43
43
|
| { kind: "thinking"; text: string }
|
|
44
44
|
| { kind: "error"; text: string }
|
|
45
|
-
| { kind: "tool"; ev: ActionCalledEvent; result?: ActionResultEvent }
|
|
45
|
+
| { kind: "tool"; ev: ActionCalledEvent; result?: ActionResultEvent }
|
|
46
|
+
| { kind: "input"; ev: InputRequestedEvent };
|
|
46
47
|
|
|
47
48
|
export type ActionCalledEvent = Extract<StreamEvent, { type: "action.called" }>;
|
|
49
|
+
export type InputRequestedEvent = Extract<StreamEvent, { type: "input.requested" }>;
|
|
48
50
|
export type ActionResultEvent = Extract<StreamEvent, { type: "action.result" }>;
|
|
49
51
|
export type SubagentCalledEvent = Extract<StreamEvent, { type: "subagent.called" }>;
|
|
50
52
|
export type SubagentCompletedEvent = Extract<StreamEvent, { type: "subagent.completed" }>;
|
|
@@ -10,10 +10,10 @@ Error generating stack: `+e.message+`
|
|
|
10
10
|
`).find(e=>e.trim())||``}function oe(e,t){let n=String(e);return n.length>t?n.slice(0,t)+` ... [+`+(n.length-t)+` chars]`:n}function se(e){return e===null?`null`:typeof e==`string`||typeof e==`number`||typeof e==`boolean`?String(e):JSON.stringify(e)}function ce(e){return(e?.inputTokens||0)+(e?.outputTokens||0)+(e?.cacheReadTokens||0)+(e?.cacheWriteTokens||0)}function D(e){return typeof e!=`number`||!Number.isFinite(e)?`0`:String(Number(e.toFixed(2)))}function O(e){return!Number.isFinite(e)||e<=0?`0`:e>=1e6?(e/1e6).toFixed(2)+`M`:e>=1e3?(e/1e3).toFixed(1)+`k`:String(Math.round(e))}function le(e,t){if(!e)return`-`;let n=new Date(e);return Number.isNaN(n.getTime())?`-`:n.toLocaleString(t??[],{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`})}function ue(e){if(!e)return``;let t=new Date(e);return Number.isNaN(t.getTime())?``:t.toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`,second:`2-digit`})}function de(e){let t=new URLSearchParams(location.search),n=t.get(`modal`);if(!n)return null;let r=t.get(`exp`),i=parseInt(t.get(`a`)??`0`,10);for(let t of e)for(let e of t.results??[])if(e.id===n&&(!r||e.experimentId===r)&&e.attempt===i)return e;return null}function k(e){let t=new Map;for(let n of e)n.group&&(t.has(n.group)||t.set(n.group,[]),t.get(n.group)?.push(n));return t}function A(e,t,n){let r=j(e,n),i=j(t,n);return typeof r==`string`||typeof i==`string`?String(r).localeCompare(String(i)):Number(r)-Number(i)}function j(e,t){return t===`experiment`?e.label:t===`model`?e.model||``:t===`agent`?e.agent:t===`cost`?e.estimatedCostUSD||0:t===`tokens`?ce(e.usage):e[t]||0}function fe(e,t){let n=e.experiment||{},r=n.flags&&Object.keys(n.flags).length?Object.entries(n.flags).map(([e,t])=>e+`=`+se(t)).join(`, `):t(`config.flagsNone`);return[[t(`config.experiment`),e.experimentId||e.label],[t(`table.model`),e.model||t(`config.default`)],[`agent`,e.agent],[`runs`,n.runs??e.runs],[`earlyExit`,n.earlyExit===void 0?t(`config.notApplicable`):String(n.earlyExit)],[`sandbox`,n.sandbox||t(`config.default`)],[`budget`,n.budget===void 0?t(`config.none`):`$`+n.budget],[`flags`,r]]}var M=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),N=o(((e,t)=>{t.exports=M()}))();function pe({label:e,value:t}){return(0,N.jsxs)(`div`,{className:`metric`,children:[(0,N.jsx)(`div`,{className:`label`,children:e}),(0,N.jsx)(`div`,{className:`value`,children:t})]})}function me({name:e,sortKey:t,sort:n,onSort:r}){return(0,N.jsx)(`th`,{children:(0,N.jsx)(`button`,{"data-sorted":n.key===t?n.dir===1?`asc`:`desc`:void 0,onClick:()=>r(t),children:e})})}function he({label:e,value:t,className:n=``,title:r}){return(0,N.jsxs)(`div`,{className:`detail-kpi`,children:[(0,N.jsx)(`span`,{children:e}),(0,N.jsx)(`b`,{className:n,title:r,children:t})]})}function ge(e){let t=e.map(e=>e.outcome);return t.some(e=>e===`passed`)?`passed`:t.some(e=>e===`failed`)?`failed`:t.some(e=>e===`errored`)?`errored`:`skipped`}function _e(e){let t=new Map;for(let n of e){let e=`${n.experimentId??``}|||${n.id}`;t.set(e,[...t.get(e)??[],n])}return[...t.values()].map(e=>{let t=[...e].sort((e,t)=>e.attempt-t.attempt);return{id:t[0].id,experimentId:t[0].experimentId,outcome:ge(t),attempts:t,passedAttempts:t.filter(e=>e.outcome===`passed`).length}})}function ve(e){let t=_e(e).filter(e=>e.outcome!==`skipped`);return t.length?t.filter(e=>e.outcome===`passed`).length/t.length:0}function ye(e){return e===`passed`?`good`:e===`errored`?`infra-err`:e===`failed`?`bad`:`warn`}function be(e,t){return e===`passed`?t(`status.pass`):e===`failed`?t(`status.fail`):e===`errored`?t(`status.error`):e===`skipped`?t(`status.skipped`):e||`—`}function xe(e){return(e.assertions||[]).filter(e=>!e.passed&&e.severity===`gate`)}function Se(e,t){return e.error?e.error:e.skipReason?e.skipReason:t.map(e=>e.detail?`${e.name}: ${e.detail}`:e.name).join(`, `)}function Ce(e){let t=(e||[]).filter(e=>e.score!==void 0&&e.score!==null);return t.length?t.map(e=>{let t=D(e.score);return e.threshold===void 0?`${e.name} ${t}`:`${e.name} ${t}/${D(e.threshold)}`}).join(` · `):``}function we(e,t){let n=[`${(e.passed||0)+(e.scored||0)} ${t(`outcome.passed`)}`,`${e.failed} ${t(`outcome.failed`)}`];return e.errored&&n.push(`${e.errored} ${t(`outcome.errored`)}`),e.skipped&&n.push(`${e.skipped} ${t(`outcome.skipped`)}`),n.join(` / `)}function Te({groupMap:e,selectedGroup:t,onSelect:n,t:r}){return e.size?(0,N.jsx)(`div`,{id:`group-selector`,className:`group-selector`,children:[...e.keys()].sort().map(i=>{let a=e.get(i)??[],o=a.flatMap(e=>e.results??[]),s=_e(o),c=s.filter(e=>e.outcome===`failed`).length,l=s.filter(e=>e.outcome===`errored`).length,u=ve(o),d=u>=.8?`good`:u>=.5?`warn`:`bad`,f=a.reduce((e,t)=>e+(t.estimatedCostUSD||0),0),p=a.map(e=>e.lastRunAt).filter(e=>!!e).sort().at(-1);return(0,N.jsxs)(`div`,{className:`group-card${t===i?` is-selected`:``}`,tabIndex:0,role:`button`,onClick:()=>n(i),onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),n(i))},children:[(0,N.jsx)(`div`,{className:`group-card-name`,children:i}),(0,N.jsx)(`div`,{className:`group-card-rate ${d}`,children:E(u)}),(0,N.jsxs)(`div`,{className:`group-card-meta`,children:[a.length,` `,a.length===1?r(`detail.evalResult`):r(`detail.evalResults`),` · `,c,` `,r(`outcome.failed`),l?` · ${l} ${r(`outcome.errored`)}`:``,` · `,re(f)]}),p?(0,N.jsx)(`div`,{className:`group-card-time`,children:le(p)}):null]},i)})}):(0,N.jsx)(`div`,{id:`group-selector`,className:`group-selector`})}var Ee=(...e)=>e.filter((e,t,n)=>!!e&&e.trim()!==``&&n.indexOf(e)===t).join(` `).trim(),De=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),Oe=e=>e.replace(/^([A-Z])|[\s-_]+(\w)/g,(e,t,n)=>n?n.toUpperCase():t.toLowerCase()),ke=e=>{let t=Oe(e);return t.charAt(0).toUpperCase()+t.slice(1)},Ae={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},je=e=>{for(let t in e)if(t.startsWith(`aria-`)||t===`role`||t===`title`)return!0;return!1},Me=(0,_.createContext)({}),Ne=()=>(0,_.useContext)(Me),Pe=(0,_.forwardRef)(({color:e,size:t,strokeWidth:n,absoluteStrokeWidth:r,className:i=``,children:a,iconNode:o,...s},c)=>{let{size:l=24,strokeWidth:u=2,absoluteStrokeWidth:d=!1,color:f=`currentColor`,className:p=``}=Ne()??{},m=r??d?Number(n??u)*24/Number(t??l):n??u;return(0,_.createElement)(`svg`,{ref:c,...Ae,width:t??l??Ae.width,height:t??l??Ae.height,stroke:e??f,strokeWidth:m,className:Ee(`lucide`,p,i),...!a&&!je(s)&&{"aria-hidden":`true`},...s},[...o.map(([e,t])=>(0,_.createElement)(e,t)),...Array.isArray(a)?a:[a]])}),Fe=(e,t)=>{let n=(0,_.forwardRef)(({className:n,...r},i)=>(0,_.createElement)(Pe,{ref:i,iconNode:t,className:Ee(`lucide-${De(ke(e))}`,`lucide-${e}`,n),...r}));return n.displayName=ke(e),n},Ie=Fe(`circle-alert`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`12`,x2:`12`,y1:`8`,y2:`12`,key:`1pkeuh`}],[`line`,{x1:`12`,x2:`12.01`,y1:`16`,y2:`16`,key:`4dfq90`}]]),Le=Fe(`circle-check`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),Re=Fe(`circle-x`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`m15 9-6 6`,key:`1uzhvr`}],[`path`,{d:`m9 9 6 6`,key:`z0biqf`}]]),ze=Fe(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]),Be=Fe(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),Ve=Fe(`copy`,[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]),He=Fe(`message-circle`,[[`path`,{d:`M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719`,key:`1sd12s`}]]);function Ue({rows:e,sort:t,setSortKey:n,openRows:r,toggleRow:i,openModal:a,t:o}){return(0,N.jsx)(`div`,{className:`table-wrap`,children:(0,N.jsxs)(`table`,{children:[(0,N.jsx)(`thead`,{children:(0,N.jsxs)(`tr`,{children:[(0,N.jsx)(me,{name:o(`table.experiment`),sortKey:`experiment`,sort:t,onSort:n}),(0,N.jsx)(me,{name:o(`table.model`),sortKey:`model`,sort:t,onSort:n}),(0,N.jsx)(me,{name:o(`table.agent`),sortKey:`agent`,sort:t,onSort:n}),(0,N.jsx)(me,{name:o(`table.avgDuration`),sortKey:`avgDurationMs`,sort:t,onSort:n}),(0,N.jsx)(me,{name:o(`table.successRate`),sortKey:`passRate`,sort:t,onSort:n}),(0,N.jsx)(me,{name:o(`table.tokens`),sortKey:`tokens`,sort:t,onSort:n}),(0,N.jsx)(me,{name:o(`table.estCost`),sortKey:`cost`,sort:t,onSort:n}),(0,N.jsx)(`th`,{children:o(`table.outcomes`)})]})}),(0,N.jsx)(`tbody`,{children:e.map(e=>(0,N.jsxs)(_.Fragment,{children:[(0,N.jsx)(We,{row:e,open:r.has(e.key),onToggle:()=>i(e.key),t:o}),r.has(e.key)?(0,N.jsx)(Ge,{row:e,openModal:a,t:o}):null]},e.key))})]})})}function We({row:e,open:t,onToggle:n,t:r}){let i=e.passRate>=.8?`good`:e.passRate>=.5?`warn`:`bad`;return(0,N.jsxs)(`tr`,{className:`main-row${t?` is-open`:``}`,tabIndex:0,onClick:n,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),n())},children:[(0,N.jsxs)(`td`,{children:[(0,N.jsx)(Be,{className:`chev-icon`,"aria-hidden":`true`}),(0,N.jsx)(`span`,{className:`name`,children:e.label}),(0,N.jsxs)(`div`,{className:`sub`,children:[e.evals,` `,e.evals===1?r(`detail.evalResult`):r(`detail.evalResults`),e.runs>e.evals?` · ${e.runs} ${r(`detail.runsUnit`)}`:``,e.lastRunAt?` · ${le(e.lastRunAt)}`:``]})]}),(0,N.jsx)(`td`,{children:e.model||r(`config.default`)}),(0,N.jsx)(`td`,{children:e.agent}),(0,N.jsx)(`td`,{className:`num`,children:ne(e.avgDurationMs)}),(0,N.jsx)(`td`,{className:`num ${i}`,children:E(e.passRate)}),(0,N.jsx)(`td`,{className:`num`,children:O(ce(e.usage))}),(0,N.jsx)(`td`,{className:`num`,children:re(e.estimatedCostUSD)}),(0,N.jsx)(`td`,{children:(0,N.jsx)(`span`,{className:`pill`,children:we(e,r)})})]})}function Ge({row:e,openModal:t,t:n}){let r=(e.results??[]).reduce((e,t)=>e+(t.durationMs||0),0),i=e.results?.find(e=>e.outcome===`errored`)||e.results?.find(e=>e.outcome===`failed`)||e.results?.[0]||{},a=_e(e.results??[]).sort((e,t)=>e.id.localeCompare(t.id));return(0,N.jsx)(`tr`,{className:`detail-row`,children:(0,N.jsx)(`td`,{className:`detail-cell`,colSpan:8,children:(0,N.jsxs)(`div`,{className:`detail`,children:[(0,N.jsx)(`div`,{className:`config-strip`,children:fe(e,n).map(([e,t])=>(0,N.jsxs)(`span`,{className:`config-chip`,children:[(0,N.jsx)(`span`,{children:e}),(0,N.jsx)(`b`,{children:t})]},e))}),(0,N.jsxs)(`div`,{className:`detail-kpis`,children:[(0,N.jsx)(he,{label:n(`detail.evals`),value:e.evals}),(0,N.jsx)(he,{label:n(`detail.passed`),value:e.passed,className:`good`}),(0,N.jsx)(he,{label:n(`detail.failed`),value:e.failed,className:e.failed?`bad`:``}),(0,N.jsx)(he,{label:n(`detail.errored`),value:e.errored,className:e.errored?`infra-err`:``}),e.runs>e.evals?(0,N.jsx)(he,{label:n(`detail.runs`),value:e.runs}):null,(0,N.jsx)(he,{label:n(`detail.totalTime`),value:ne(r)}),(0,N.jsx)(he,{label:n(`detail.totalCost`),value:re(e.estimatedCostUSD)}),(0,N.jsx)(he,{label:n(`detail.ran`),value:le(e.lastRunAt),title:e.lastRunAt||``})]}),(0,N.jsx)(`h3`,{children:n(`detail.evaluationAttempts`)}),(0,N.jsxs)(`div`,{className:`eval-list`,children:[(0,N.jsxs)(`div`,{className:`eval-grid-head`,children:[(0,N.jsx)(`span`,{children:n(`detail.status`)}),(0,N.jsx)(`span`,{children:n(`detail.eval`)}),(0,N.jsx)(`span`,{children:n(`detail.reason`)}),(0,N.jsx)(`span`,{children:n(`detail.time`)}),(0,N.jsx)(`span`,{children:n(`table.tokens`)}),(0,N.jsx)(`span`,{children:n(`table.estCost`)}),(0,N.jsx)(`span`,{children:n(`detail.run`)})]}),a.map(e=>(0,N.jsx)(Ke,{group:e,openModal:t,t:n},`${e.experimentId??``}-${e.id}`))]}),(0,N.jsxs)(`details`,{className:`raw-details`,children:[(0,N.jsxs)(`summary`,{children:[n(`detail.rawSample`),` `,(0,N.jsx)(`span`,{className:`raw-note`,children:n(`detail.rawNote`)})]}),(0,N.jsx)(`pre`,{children:JSON.stringify(i,null,2)})]})]})})})}function Ke({group:e,openModal:t,t:n}){let[r,i]=(0,_.useState)(!1),a=e.attempts.length;if(a===1)return(0,N.jsx)(qe,{result:e.attempts[0],totalRuns:1,openModal:t,t:n});let o=e.attempts.find(t=>t.outcome===e.outcome)??e.attempts[0],s=Se(o,xe(o))||(e.outcome===`passed`?Ce(o.assertions||[]):``),c=e.attempts.reduce((e,t)=>e+(t.durationMs||0),0),l=e.attempts.reduce((e,t)=>e+ce(t.usage),0),u=e.attempts.reduce((e,t)=>e+(t.estimatedCostUSD||0),0),d=()=>i(e=>!e);return(0,N.jsxs)(N.Fragment,{children:[(0,N.jsxs)(`div`,{className:`eval-item eval-item-clickable eval-group${r?` is-open`:``}`,role:`button`,tabIndex:0,"aria-expanded":r,onClick:d,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),d())},children:[(0,N.jsx)(`span`,{className:`attempt-status`,children:(0,N.jsx)(`span`,{className:ye(e.outcome),children:be(e.outcome,n)})}),(0,N.jsxs)(`span`,{className:`eval-id`,children:[(0,N.jsx)(Be,{className:`chev-icon`,"aria-hidden":`true`}),e.id]}),(0,N.jsx)(`div`,{className:`assertions-cell`,children:(0,N.jsx)(`span`,{className:`assertions`,title:s||void 0,children:s||(0,N.jsx)(`span`,{className:`reason-empty`,children:`—`})})}),(0,N.jsx)(`span`,{className:`num`,children:ne(c)}),(0,N.jsx)(`span`,{className:`num`,children:O(l)}),(0,N.jsx)(`span`,{className:`num`,children:re(u)}),(0,N.jsxs)(`span`,{className:`num run-ratio`,title:`${e.passedAttempts}/${a} ${n(`detail.passed`)}`,children:[e.passedAttempts,`/`,a]})]}),r?(0,N.jsx)(`div`,{className:`eval-attempts`,children:e.attempts.map(e=>(0,N.jsx)(qe,{result:e,totalRuns:a,openModal:t,t:n},`${e.id}-${e.attempt}`))}):null]})}function qe({result:e,totalRuns:t,openModal:n,t:r}){let i=e.outcome,a=Se(e,xe(e)),o=e.assertions||[],s=o.some(e=>e.score!==void 0&&e.score!==null),c=e.hasEvents||e.hasTrace||s,l=!a&&i===`passed`?Ce(o):``,u=a||l,d=()=>n(e),f=(0,N.jsxs)(N.Fragment,{children:[(0,N.jsx)(`span`,{className:`attempt-status`,children:(0,N.jsx)(`span`,{className:ye(i),children:be(i,r)})}),(0,N.jsx)(`span`,{className:`eval-id`,children:e.id}),(0,N.jsx)(`div`,{className:`assertions-cell`,children:(0,N.jsx)(`span`,{className:`assertions${c?` assertions-link`:``}`,title:u||void 0,onClick:c?e=>{e.stopPropagation(),d()}:void 0,children:u||(0,N.jsx)(`span`,{className:`reason-empty`,children:`—`})})}),(0,N.jsxs)(`span`,{className:`num`,children:[ne(e.durationMs),e.startedAt?(0,N.jsx)(`small`,{className:`ran-at`,children:ue(e.startedAt)}):null]}),(0,N.jsx)(`span`,{className:`num`,children:O(ce(e.usage))}),(0,N.jsx)(`span`,{className:`num`,children:re(e.estimatedCostUSD)}),(0,N.jsxs)(`span`,{className:`num`,title:`attempt ${e.attempt+1} of ${t}`,children:[`#`,e.attempt+1]})]});return c?(0,N.jsx)(`div`,{className:`eval-item eval-item-clickable`,role:`button`,tabIndex:0,onClick:d,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),d())},children:f}):(0,N.jsx)(`div`,{className:`eval-item`,children:f})}function Je({rows:e,t}){let[n,r]=(0,_.useState)(!1),i=e.flatMap(e=>(e.results??[]).filter(e=>e.outcome===`failed`||e.outcome===`errored`).map(t=>{let n=Se(t,xe(t)),r=t.artifactBase,i=t.hasTrace&&r?`${r}/trace.json`:null;return{experimentName:e.label,evalId:t.id,reason:n,tracePath:i}}));return i.length?(0,N.jsxs)(`button`,{className:`copy-all-errors${n?` is-copied`:``}`,onClick:async e=>{e.stopPropagation();let t=i.map(({experimentName:e,evalId:t,reason:n,tracePath:r})=>[`实验: ${e} Eval: ${t}`,n?`错误: ${n}`:null,r?`Trace: ${r}`:null].filter(Boolean).join(`
|
|
11
11
|
`)).join(`
|
|
12
12
|
|
|
13
|
-
`);try{await Ye(t),r(!0),setTimeout(()=>r(!1),1500)}catch{r(!1)}},title:t(`action.copyErrors`),children:[n?(0,N.jsx)(ze,{"aria-hidden":`true`}):(0,N.jsx)(Ve,{"aria-hidden":`true`}),(0,N.jsx)(`span`,{children:n?t(`action.copied`):`${t(`action.copyErrors`)} (${i.length})`})]}):null}async function Ye(e){if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(e);return}let t=document.createElement(`textarea`);t.value=e,t.style.position=`fixed`,t.style.opacity=`0`,document.body.appendChild(t),t.select(),document.execCommand(`copy`),t.remove()}function Xe(e){return Array.isArray(e)&&e.every(Ze)?e:null}function Ze(e){return nt(e)&&typeof e.path==`string`&&typeof e.content==`string`}function Qe(e){return Array.isArray(e)&&e.every(et)?e:null}function $e(e){return Array.isArray(e)&&e.every(tt)?e:null}function et(e){if(!nt(e)||typeof e.type!=`string`)return!1;switch(e.type){case`message`:return(e.role===`assistant`||e.role===`user`)&&typeof e.text==`string`;case`action.called`:return typeof e.callId==`string`&&typeof e.name==`string`;case`action.result`:return typeof e.callId==`string`;case`subagent.called`:return typeof e.callId==`string`&&typeof e.name==`string`;case`subagent.completed`:return typeof e.callId==`string`;case`input.requested`:return nt(e.request);case`thinking`:return typeof e.text==`string`;case`compaction`:return!0;case`error`:return typeof e.message==`string`;default:return!1}}function tt(e){return nt(e)&&typeof e.traceId==`string`&&typeof e.spanId==`string`&&typeof e.name==`string`&&typeof e.startMs==`number`&&typeof e.endMs==`number`}function nt(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function rt(e,t){return`${e}:${t}`}function it(e){let t=new Map,n=[],r=null;for(let
|
|
13
|
+
`);try{await Ye(t),r(!0),setTimeout(()=>r(!1),1500)}catch{r(!1)}},title:t(`action.copyErrors`),children:[n?(0,N.jsx)(ze,{"aria-hidden":`true`}):(0,N.jsx)(Ve,{"aria-hidden":`true`}),(0,N.jsx)(`span`,{children:n?t(`action.copied`):`${t(`action.copyErrors`)} (${i.length})`})]}):null}async function Ye(e){if(navigator.clipboard?.writeText){await navigator.clipboard.writeText(e);return}let t=document.createElement(`textarea`);t.value=e,t.style.position=`fixed`,t.style.opacity=`0`,document.body.appendChild(t),t.select(),document.execCommand(`copy`),t.remove()}function Xe(e){return Array.isArray(e)&&e.every(Ze)?e:null}function Ze(e){return nt(e)&&typeof e.path==`string`&&typeof e.content==`string`}function Qe(e){return Array.isArray(e)&&e.every(et)?e:null}function $e(e){return Array.isArray(e)&&e.every(tt)?e:null}function et(e){if(!nt(e)||typeof e.type!=`string`)return!1;switch(e.type){case`message`:return(e.role===`assistant`||e.role===`user`)&&typeof e.text==`string`;case`action.called`:return typeof e.callId==`string`&&typeof e.name==`string`;case`action.result`:return typeof e.callId==`string`;case`subagent.called`:return typeof e.callId==`string`&&typeof e.name==`string`;case`subagent.completed`:return typeof e.callId==`string`;case`input.requested`:return nt(e.request);case`thinking`:return typeof e.text==`string`;case`compaction`:return!0;case`error`:return typeof e.message==`string`;default:return!1}}function tt(e){return nt(e)&&typeof e.traceId==`string`&&typeof e.spanId==`string`&&typeof e.name==`string`&&typeof e.startMs==`number`&&typeof e.endMs==`number`}function nt(e){return!!e&&typeof e==`object`&&!Array.isArray(e)}function rt(e,t){return`${e}:${t}`}function it(e){let t=new Map,n=[],r=new Map,i=null;for(let a of e||[])if(a.type===`message`&&a.role===`user`)i={loc:a.loc,sent:a.text||``,replies:[]},a.loc?t.set(rt(a.loc.file,a.loc.line),i):n.push(i);else if(!i)continue;else if(a.type===`message`&&a.role===`assistant`)i.replies.push({kind:`text`,text:a.text||``});else if(a.type===`thinking`)i.replies.push({kind:`thinking`,text:a.text||``});else if(a.type===`action.called`){let e={kind:`tool`,ev:a};r.set(a.callId,e),i.replies.push(e)}else if(a.type===`action.result`){let e=r.get(a.callId);e&&(e.result=a)}else a.type===`input.requested`?i.replies.push({kind:`input`,ev:a}):a.type===`error`&&i.replies.push({kind:`error`,text:a.message||`error`});return{byKey:t,noloc:n}}function at(e){let t=new Map,n=[];for(let r of e||[])if(r.loc){let e=rt(r.loc.file,r.loc.line);t.has(e)||t.set(e,[]),t.get(e)?.push(r)}else n.push(r);return{byKey:t,noloc:n}}var ot=/(\/\/[^\n]*)|(\/\*[^]*?\*\/)|(`(?:\\.|[^`\\])*`|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*')|\b(import|from|export|default|const|let|var|async|await|function|return|if|else|for|of|in|new|class|extends|typeof|void|true|false|null|undefined)\b|\b(\d[\d_.]*)\b|([A-Za-z_$][\w$]*)(?=\s*\()/g;function st(e){let t=[],n=0,r=0,i;for(ot.lastIndex=0;i=ot.exec(e);){i.index>n&&t.push(e.slice(n,i.index));let a=i[1]||i[2]?`tok-comment`:i[3]?`tok-str`:i[4]?`tok-kw`:i[5]?`tok-num`:i[6]?`tok-fn`:null;t.push(a?(0,N.jsx)(`span`,{className:a,children:i[0]},r++):i[0]),n=i.index+i[0].length,i[0].length===0&&ot.lastIndex++}return n<e.length&&t.push(e.slice(n)),t}var ct={file_read:`Read`,file_write:`Write`,file_edit:`Edit`,shell:`Bash`,web_fetch:`Fetch`,web_search:`Search`,glob:`Glob`,grep:`Grep`,list_dir:`List`,agent_task:`Task`};function lt(e){let t=e.input;if(typeof t==`string`)return t;if(!nt(t))return``;if(e.tool===`shell`){let e=t.command??t.cmd;if(typeof e==`string`)return e;if(Array.isArray(e))return e.filter(e=>typeof e==`string`).join(` `)}for(let e of[`path`,`file`,`file_path`,`filename`,`pattern`,`query`,`url`,`uri`,`prompt`,`description`,`command`,`remoteUrl`]){let n=t[e];if(typeof n==`string`&&n)return n}if(Object.keys(t).length>0)try{let e=JSON.stringify(t);return e.length>200?e.slice(0,200)+`…`:e}catch{return``}return``}function ut(e){if(e==null)return``;if(typeof e==`string`)return e;if(nt(e))for(let t of[`output`,`stdout`,`content`,`text`,`result`,`body`]){let n=e[t];if(typeof n==`string`)return n}return ie(e)}function dt({events:e,t}){if(!Array.isArray(e)||!e.length)return(0,N.jsx)(`div`,{className:`trace-span-meta`,children:t(`transcript.noEvents`)});let n=new Map;for(let t of e)(t.type===`action.result`||t.type===`subagent.completed`)&&n.set(t.callId,t);let r=new Set;return(0,N.jsx)(`div`,{className:`transcript`,children:e.map((e,i)=>{switch(e.type){case`message`:return(0,N.jsx)(ft,{event:e,t},i);case`thinking`:return(0,N.jsx)(pt,{event:e,t},i);case`action.called`:{let a=n.get(e.callId);return a&&r.add(e.callId),(0,N.jsx)(ht,{call:e,result:a,t},i)}case`subagent.called`:{let a=n.get(e.callId);return a&&r.add(e.callId),(0,N.jsx)(ht,{call:{tool:`agent_task`,name:e.name,input:{description:e.name,...e.remoteUrl?{remoteUrl:e.remoteUrl}:{}}},result:a,t},i)}case`action.result`:case`subagent.completed`:return r.has(e.callId)?null:(0,N.jsx)(ht,{call:{tool:`unknown`,name:`result`,input:null},result:e,t},i);case`input.requested`:return(0,N.jsx)(mt,{event:e,t},i);case`compaction`:return(0,N.jsxs)(`div`,{className:`ts-compaction`,children:[t(`transcript.contextCompacted`),e.reason?` · `+e.reason:``]},i);case`error`:return(0,N.jsxs)(`div`,{className:`ts-error`,children:[`! `,e.message||`error`]},i);default:return null}})})}function ft({event:e,t}){let n=e.role===`assistant`?`assistant`:`user`;return(0,N.jsxs)(`div`,{className:`ts-msg ts-${n}`,children:[(0,N.jsx)(`span`,{className:`ts-role`,children:t(n===`assistant`?`transcript.assistant`:`transcript.user`)}),(0,N.jsx)(`div`,{className:`ts-text`,children:e.text||``})]})}function pt({event:e,t}){return(0,N.jsxs)(`details`,{className:`ts-think`,children:[(0,N.jsx)(`summary`,{children:t(`transcript.thinking`)}),(0,N.jsx)(`div`,{className:`ts-think-text`,children:e.text||``})]})}function mt({event:e,t}){let n=e.request||{},r=(n.options||[]).map(e=>e.label||e.id).filter(Boolean).join(` / `),i=(n.prompt||t(`transcript.awaitingInput`))+(r?`
|
|
14
14
|
[ `+r+` ]`:``);return(0,N.jsxs)(`div`,{className:`ts-msg ts-input`,children:[(0,N.jsx)(`span`,{className:`ts-role`,children:t(`transcript.inputRequested`)}),(0,N.jsx)(`div`,{className:`ts-text`,children:i})]})}function ht({call:e,result:t,t:n}){let r=(e.tool?ct[e.tool]:void 0)||e.name||e.tool||`tool`,i=lt(e),a=i?`${r}(${i})`:r,o=t?t.status:`pending`,s=o===`failed`?`bad`:o===`rejected`?`warn`:o===`pending`?`pending`:`good`,c=e.input==null?``:ie(e.input),l=t?ut(t.output):``,u=t?ae(l):n(`transcript.running`);return(0,N.jsxs)(`details`,{className:`ts-tool-d`,children:[(0,N.jsxs)(`summary`,{className:`ts-row`,children:[(0,N.jsx)(`span`,{className:`ts-dot ${s}`}),(0,N.jsx)(`span`,{className:`ts-tool`,title:a,children:a}),(0,N.jsx)(`span`,{className:`ts-preview`,children:oe(u,140)})]}),(0,N.jsxs)(`div`,{className:`ts-body`,children:[c?(0,N.jsxs)(`div`,{className:`ts-field`,children:[(0,N.jsx)(`span`,{className:`ts-k`,children:n(`transcript.input`)}),(0,N.jsx)(`pre`,{className:`attr-pre`,children:oe(c,4e3)})]}):null,t?(0,N.jsxs)(`div`,{className:`ts-field`,children:[(0,N.jsxs)(`span`,{className:`ts-k`,children:[n(`transcript.output`),t.status&&t.status!==`completed`?` · `+t.status:``]}),(0,N.jsx)(`pre`,{className:`attr-pre`,children:l?oe(l,8e3):(0,N.jsx)(`span`,{className:`reason-empty`,children:n(`transcript.empty`)})})]}):null]})]})}function gt(e){return e.passed?`good`:e.severity===`soft`?`warn`:`bad`}function _t({sources:e,events:t,assertions:n,t:r}){let i=(0,_.useMemo)(()=>it(t),[t]),a=(0,_.useMemo)(()=>at(n),[n]),[o,s]=(0,_.useState)(()=>new Set),c=(0,_.useCallback)(e=>{s(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),l=new Set;for(let t of e){let e=t.content.split(`
|
|
15
15
|
`).length;for(let n=1;n<=e;n++)l.add(rt(t.path,n))}let u=[...a.byKey.entries()].filter(([e])=>!l.has(e)).flatMap(([,e])=>e).concat(a.noloc);return(0,N.jsxs)(`div`,{className:`codeview`,children:[e.map(e=>(0,N.jsx)(vt,{file:e,turns:i.byKey,asserts:a.byKey,open:o,toggle:c,t:r},e.path)),u.length?(0,N.jsxs)(`div`,{className:`code-orphans`,children:[(0,N.jsx)(`div`,{className:`code-orphans-head`,children:r(`code.otherAssertions`)}),(0,N.jsx)(St,{asserts:u,t:r})]}):null]})}function vt({file:e,turns:t,asserts:n,open:r,toggle:i,t:a}){let o=e.content.replace(/\n$/,``).split(`
|
|
16
|
-
`);return(0,N.jsxs)(`div`,{className:`code-file`,children:[(0,N.jsx)(`div`,{className:`code-file-head`,children:e.path}),(0,N.jsx)(`div`,{className:`code-lines`,children:o.map((o,s)=>{let c=s+1,l=rt(e.path,c);return(0,N.jsx)(yt,{n:c,text:o,turn:t.get(l),asserts:n.get(l),isOpen:r.has(l),onToggle:()=>i(l),t:a},c)})})]})}function yt({n:e,text:t,turn:n,asserts:r,isOpen:i,onToggle:a,t:o}){let s=!!n,c=!!(r&&r.length),l=c?r?.every(e=>e.passed)?`pass`:r?.some(e=>!e.passed&&e.severity===`gate`)?`fail`:`warn`:null,u=s||c;return(0,N.jsxs)(N.Fragment,{children:[(0,N.jsxs)(`div`,{className:`code-line`+(l?` line-${l}`:``)+(s&&!l?` line-send`:``)+(u?` line-clickable`:``)+(i?` is-open`:``),onClick:u?a:void 0,role:u?`button`:void 0,tabIndex:u?0:void 0,onKeyDown:u?e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),a())}:void 0,children:[(0,N.jsx)(`span`,{className:`ln`,children:e}),(0,N.jsx)(`span`,{className:`gmark`,children:c?l===`pass`?(0,N.jsx)(Le,{className:`gstat good`,"aria-hidden":`true`}):l===`warn`?(0,N.jsx)(Ie,{className:`gstat warn`,"aria-hidden":`true`}):(0,N.jsx)(Re,{className:`gstat bad`,"aria-hidden":`true`}):s?(0,N.jsx)(He,{className:`gsend`,"aria-hidden":`true`}):null}),(0,N.jsx)(`code`,{className:`ctext`,children:st(t)}),(0,N.jsxs)(`span`,{className:`lbadges`,children:[c?r?.map((e,t)=>(0,N.jsx)(bt,{a:e},t)):null,s?(0,N.jsx)(`span`,{className:`reply-hint`,children:o(i?`code.hide`:`code.reply`)}):u?(0,N.jsx)(Be,{className:`line-chev${i?` is-open`:``}`,"aria-hidden":`true`}):null]})]}),i&&s&&n?(0,N.jsx)(xt,{turn:n,t:o}):null,i&&c&&r?(0,N.jsx)(St,{asserts:r,t:o}):null]})}function bt({a:e}){return e.threshold!==void 0||e.score>0&&e.score<1?(0,N.jsxs)(`span`,{className:`abadge ${gt(e)}`,children:[D(e.score),e.threshold===void 0?null:(0,N.jsxs)(`span`,{className:`abadge-th`,children:[`/`,D(e.threshold)]})]}):null}function xt({turn:e,t}){return e.replies.length?(0,N.jsx)(`div`,{className:`line-detail reply-panel`,children:e.replies.map((e,n)=>{if(e.kind===`text`)return(0,N.jsxs)(`div`,{className:`reply-assistant`,children:[(0,N.jsx)(`span`,{className:`reply-role`,children:t(`transcript.assistant`)}),(0,N.jsx)(`div`,{className:`reply-text`,children:e.text})]},n);if(e.kind===`thinking`)return(0,N.jsxs)(`details`,{className:`reply-think`,children:[(0,N.jsx)(`summary`,{children:t(`transcript.thinking`)}),(0,N.jsx)(`div`,{className:`reply-think-text`,children:e.text})]},n);if(e.kind===`error`)return(0,N.jsxs)(`div`,{className:`reply-err`,children:[`! `,e.text]},n);if(e.kind===`tool`){let t=(e.ev.tool?ct[e.ev.tool]:void 0)||e.ev.name||e.ev.tool||`tool`,r=lt(e.ev),i=e.result?ut(e.result.output):``;return(0,N.jsxs)(`div`,{className:`reply-tool`,children:[(0,N.jsx)(`span`,{className:`reply-tool-name`,children:r?`${t}(${oe(r,80)})`:t}),i?(0,N.jsxs)(`span`,{className:`reply-tool-out`,children:[`→ `,oe(ae(i),100)]}):null]},n)}return null})}):(0,N.jsx)(`div`,{className:`line-detail reply-empty`,children:t(`code.noReply`)})}function St({asserts:e,t}){return(0,N.jsx)(`div`,{className:`line-detail assert-detail`,children:e.map((e,n)=>(0,N.jsxs)(`div`,{className:`assert-row`,children:[(0,N.jsx)(`span`,{className:`abadge ${gt(e)}`,children:e.passed?t(`assert.pass`):t(`assert.fail`)}),(0,N.jsx)(`span`,{className:`assert-name`,children:e.name}),e.severity===`soft`?(0,N.jsx)(`span`,{className:`assert-sev`,children:t(`assert.soft`)}):null,e.threshold===void 0?null:(0,N.jsxs)(`span`,{className:`assert-score`,children:[D(e.score),` / `,D(e.threshold)]}),e.detail?(0,N.jsx)(`div`,{className:`assert-reason`,children:e.detail}):null,e.evidence?(0,N.jsxs)(`details`,{className:`assert-evidence`,children:[(0,N.jsx)(`summary`,{children:t(`assert.evidence`)}),(0,N.jsx)(`pre`,{className:`assert-evidence-pre`,children:e.evidence})]}):null]},n))})}function Ct({assertions:e,events:t,t:n}){let r=e||[];return(0,N.jsxs)(`div`,{className:`nosource`,children:[(0,N.jsx)(`div`,{className:`nosource-note`,children:n(`code.noSource`)}),r.length?(0,N.jsxs)(`div`,{className:`nosource-block`,children:[(0,N.jsx)(`div`,{className:`nosource-head`,children:n(`code.checks`)}),(0,N.jsx)(St,{asserts:r,t:n})]}):null,t?.length?(0,N.jsxs)(`div`,{className:`nosource-block`,children:[(0,N.jsx)(`div`,{className:`nosource-head`,children:n(`code.conversation`)}),(0,N.jsx)(dt,{events:t,t:n})]}):null]})}function wt({spans:e,t}){if(!e?.length)return(0,N.jsx)(`div`,{className:`trace-span-meta`,children:t(`trace.noSpans`)});let n=Math.min(...e.map(e=>e.startMs)),r=Math.max(...e.map(e=>e.endMs)),i=Math.max(1,r-n),a=new Map(e.map(e=>[e.spanId,e])),o=e=>{let t=0,n=e,r=new Set;for(;n&&n.parentSpanId&&a.has(n.parentSpanId)&&!r.has(n.spanId);){r.add(n.spanId);let e=a.get(n.parentSpanId);if(!e||(n=e,t++,t>40))break}return t},s=[...e].sort((e,t)=>e.startMs-t.startMs||o(e)-o(t));return(0,N.jsxs)(`div`,{className:`trace`,children:[(0,N.jsxs)(`div`,{className:`trace-span-meta`,children:[t(`trace.total`),` `,ne(i),` · `,e.length,` `,t(`trace.spans`),` · `,t(`trace.clickDetails`)]}),s.map(e=>{let t=(e.startMs-n)/i*100,r=Math.max(.6,(e.endMs-e.startMs)/i*100),a=e.kind||`other`,s=e.status===`error`?`bad`:`k-`+a,c=Tt(e.attributes),l=(0,N.jsxs)(`summary`,{className:`trace-row`,children:[(0,N.jsxs)(`div`,{className:`trace-label`,style:{paddingLeft:o(e)*12},title:e.name,children:[a===`other`?null:(0,N.jsx)(`span`,{className:`kind-chip k-${a}`,children:a}),e.name]}),(0,N.jsx)(`div`,{className:`trace-track`,children:(0,N.jsx)(`div`,{className:`trace-bar ${s}`,style:{left:`${t}%`,width:`${r}%`}})}),(0,N.jsx)(`div`,{className:`trace-dur num`,children:ne(e.endMs-e.startMs)})]});return c?(0,N.jsxs)(`details`,{className:`span-d`,children:[l,c]},e.spanId):(0,N.jsx)(`div`,{className:`span-d`,children:l},e.spanId)})]})}function Tt(e){if(!e)return null;let t=/^(code\.|thread\.|target$|busy_ns$|idle_ns$|rpc\.|app_server\.)/,n=Object.keys(e).filter(e=>!t.test(e));if(!n.length)return null;let r=n.filter(e=>e.startsWith(`io.`)),i=n.filter(e=>!e.startsWith(`io.`)).sort();return(0,N.jsxs)(`div`,{className:`span-attrs`,children:[r.map(t=>{let n=t.replace(/^io\./,``),r=String(e[t]);return n===`input`||n===`output`?(0,N.jsxs)(`div`,{className:`attr-io`,children:[(0,N.jsx)(`span`,{className:`attr-k`,children:n}),(0,N.jsx)(`pre`,{className:`attr-pre`,children:r})]},t):(0,N.jsx)(Et,{label:n,value:r},t)}),i.map(t=>(0,N.jsx)(Et,{label:t,value:typeof e[t]==`object`?JSON.stringify(e[t]):String(e[t])},t))]})}function Et({label:e,value:t}){return(0,N.jsxs)(`div`,{className:`attr-row`,children:[(0,N.jsx)(`span`,{className:`attr-k`,children:e}),(0,N.jsx)(`span`,{className:`attr-v`,children:t})]})}function Dt({type:e,src:t,autoLoad:n=!1,t:r}){let[i,a]=(0,_.useState)(n),[o,s]=(0,_.useState)(!1),[c,l]=(0,_.useState)(null),[u,d]=(0,_.useState)(``),f=async()=>{if(!o){s(!0);try{let e=await fetch(`/artifact?p=`+encodeURIComponent(t));if(!e.ok)throw Error(`HTTP `+e.status);l(await e.json()),d(``)}catch(e){s(!1),d(`${r(`trace.loadFailed`)} ${String(e)}`)}}};return(0,_.useEffect)(()=>{n&&f()},[]),(0,N.jsxs)(`details`,{className:`trace-details`,open:i,onToggle:e=>{let t=e.currentTarget.open;a(t),t&&f()},children:[(0,N.jsx)(`summary`,{children:r(e===`transcript`?`trace.transcript`:`trace.timing`)}),(0,N.jsxs)(`div`,{className:`trace-slot`,children:[u?(0,N.jsx)(`div`,{className:`trace-span-meta`,children:u}):c?null:(0,N.jsx)(`div`,{className:`trace-span-meta`,children:r(`trace.loading`)}),c&&e===`transcript`?(0,N.jsx)(dt,{events:Qe(c)??[],t:r}):null,c&&e===`trace`?(0,N.jsx)(wt,{spans:$e(c)??[],t:r}):null]})]})}typeof window<`u`&&window.document&&window.document.createElement;function P(e,t,{checkForDefaultPrevented:n=!0}={}){return function(r){if(e?.(r),n===!1||!r.defaultPrevented)return t?.(r)}}function Ot(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}function kt(...e){return t=>{let n=!1,r=e.map(e=>{let r=Ot(e,t);return!n&&typeof r==`function`&&(n=!0),r});if(n)return()=>{for(let t=0;t<r.length;t++){let n=r[t];typeof n==`function`?n():Ot(e[t],null)}}}}function At(...e){return _.useCallback(kt(...e),e)}function jt(e,t=[]){let n=[];function r(t,r){let i=_.createContext(r);i.displayName=t+`Context`;let a=n.length;n=[...n,r];let o=t=>{let{scope:n,children:r,...o}=t,s=n?.[e]?.[a]||i,c=_.useMemo(()=>o,Object.values(o));return(0,N.jsx)(s.Provider,{value:c,children:r})};o.displayName=t+`Provider`;function s(n,o){let s=o?.[e]?.[a]||i,c=_.useContext(s);if(c)return c;if(r!==void 0)return r;throw Error(`\`${n}\` must be used within \`${t}\``)}return[o,s]}let i=()=>{let t=n.map(e=>_.createContext(e));return function(n){let r=n?.[e]||t;return _.useMemo(()=>({[`__scope${e}`]:{...n,[e]:r}}),[n,r])}};return i.scopeName=e,[r,Mt(i,...t)]}function Mt(...e){let t=e[0];if(e.length===1)return t;let n=()=>{let n=e.map(e=>({useScope:e(),scopeName:e.scopeName}));return function(e){let r=n.reduce((t,{useScope:n,scopeName:r})=>{let i=n(e)[`__scope${r}`];return{...t,...i}},{});return _.useMemo(()=>({[`__scope${t.scopeName}`]:r}),[r])}};return n.scopeName=t.scopeName,n}var Nt=globalThis?.document?_.useLayoutEffect:()=>{},Pt=_.useId||(()=>void 0),Ft=0;function It(e){let[t,n]=_.useState(Pt());return Nt(()=>{e||n(e=>e??String(Ft++))},[e]),e||(t?`radix-${t}`:``)}var Lt=_.useInsertionEffect||Nt;function Rt({prop:e,defaultProp:t,onChange:n=()=>{},caller:r}){let[i,a,o]=zt({defaultProp:t,onChange:n}),s=e!==void 0,c=s?e:i;{let t=_.useRef(e!==void 0);_.useEffect(()=>{let e=t.current;e!==s&&console.warn(`${r} is changing from ${e?`controlled`:`uncontrolled`} to ${s?`controlled`:`uncontrolled`}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),t.current=s},[s,r])}return[c,_.useCallback(t=>{if(s){let n=Bt(t)?t(e):t;n!==e&&o.current?.(n)}else a(t)},[s,e,a,o])]}function zt({defaultProp:e,onChange:t}){let[n,r]=_.useState(e),i=_.useRef(n),a=_.useRef(t);return Lt(()=>{a.current=t},[t]),_.useEffect(()=>{i.current!==n&&(a.current?.(n),i.current=n)},[n,i]),[n,r,a]}function Bt(e){return typeof e==`function`}var Vt=c(m(),1);function Ht(e){let t=_.forwardRef((t,n)=>{let{children:r,...i}=t,a=null,o=!1,s=[];Yt(r)&&typeof $t==`function`&&(r=$t(r._payload)),_.Children.forEach(r,e=>{if(qt(e)){o=!0;let t=e,n=`child`in t.props?t.props.child:t.props.children;Yt(n)&&typeof $t==`function`&&(n=$t(n._payload)),a=Wt(t,n),s.push(a?.props?.children)}else s.push(e)}),a?a=_.cloneElement(a,void 0,s):!o&&_.Children.count(r)===1&&_.isValidElement(r)&&(a=r);let c=a?Kt(a):void 0,l=At(n,c);if(!a){if(r||r===0)throw Error(o?Qt(e):Zt(e));return r}let u=Gt(i,a.props??{});return a.type!==_.Fragment&&(u.ref=n?l:c),_.cloneElement(a,u)});return t.displayName=`${e}.Slot`,t}var Ut=Symbol.for(`radix.slottable`),Wt=(e,t)=>{if(`child`in e.props){let t=e.props.child;return _.isValidElement(t)?_.cloneElement(t,void 0,e.props.children(t.props.children)):null}return _.isValidElement(t)?t:null};function Gt(e,t){let n={...t};for(let r in t){let i=e[r],a=t[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...e)=>{let t=a(...e);return i(...e),t}:i&&(n[r]=i):r===`style`?n[r]={...i,...a}:r===`className`&&(n[r]=[i,a].filter(Boolean).join(` `))}return{...e,...n}}function Kt(e){let t=Object.getOwnPropertyDescriptor(e.props,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function qt(e){return _.isValidElement(e)&&typeof e.type==`function`&&`__radixId`in e.type&&e.type.__radixId===Ut}var Jt=Symbol.for(`react.lazy`);function Yt(e){return typeof e==`object`&&!!e&&`$$typeof`in e&&e.$$typeof===Jt&&`_payload`in e&&Xt(e._payload)}function Xt(e){return typeof e==`object`&&!!e&&`then`in e}var Zt=e=>`${e} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,Qt=e=>`${e} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,$t=_.use,en=[`a`,`button`,`div`,`form`,`h2`,`h3`,`img`,`input`,`label`,`li`,`nav`,`ol`,`p`,`select`,`span`,`svg`,`ul`].reduce((e,t)=>{let n=Ht(`Primitive.${t}`),r=_.forwardRef((e,r)=>{let{asChild:i,...a}=e,o=i?n:t;return typeof window<`u`&&(window[Symbol.for(`radix-ui`)]=!0),(0,N.jsx)(o,{...a,ref:r})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{});function tn(e,t){e&&Vt.flushSync(()=>e.dispatchEvent(t))}function nn(e){let t=_.useRef(e);return _.useEffect(()=>{t.current=e}),_.useMemo(()=>((...e)=>t.current?.(...e)),[])}function rn(e,t=globalThis?.document){let n=nn(e);_.useEffect(()=>{let e=e=>{e.key===`Escape`&&n(e)};return t.addEventListener(`keydown`,e,{capture:!0}),()=>t.removeEventListener(`keydown`,e,{capture:!0})},[n,t])}var an=`DismissableLayer`,on=`dismissableLayer.update`,sn=`dismissableLayer.pointerDownOutside`,cn=`dismissableLayer.focusOutside`,ln,un=_.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set,dismissableSurfaces:new Set}),dn=_.forwardRef((e,t)=>{let{disableOutsidePointerEvents:n=!1,deferPointerDownOutside:r=!1,onEscapeKeyDown:i,onPointerDownOutside:a,onFocusOutside:o,onInteractOutside:s,onDismiss:c,...l}=e,u=_.useContext(un),[d,f]=_.useState(null),p=d?.ownerDocument??globalThis?.document,[,m]=_.useState({}),h=At(t,e=>f(e)),g=Array.from(u.layers),[v]=[...u.layersWithOutsidePointerEventsDisabled].slice(-1),y=g.indexOf(v),b=d?g.indexOf(d):-1,x=u.layersWithOutsidePointerEventsDisabled.size>0,S=b>=y,C=_.useRef(!1),w=hn(e=>{let t=e.target;if(!(t instanceof Node))return;let n=[...u.branches].some(e=>e.contains(t));!S||n||(a?.(e),s?.(e),e.defaultPrevented||c?.())},{ownerDocument:p,deferPointerDownOutside:r,isDeferredPointerDownOutsideRef:C,dismissableSurfaces:u.dismissableSurfaces}),T=gn(e=>{if(r&&C.current)return;let t=e.target;[...u.branches].some(e=>e.contains(t))||(o?.(e),s?.(e),e.defaultPrevented||c?.())},p);return rn(e=>{b===u.layers.size-1&&(i?.(e),!e.defaultPrevented&&c&&(e.preventDefault(),c()))},p),_.useEffect(()=>{if(d)return n&&(u.layersWithOutsidePointerEventsDisabled.size===0&&(ln=p.body.style.pointerEvents,p.body.style.pointerEvents=`none`),u.layersWithOutsidePointerEventsDisabled.add(d)),u.layers.add(d),_n(),()=>{n&&(u.layersWithOutsidePointerEventsDisabled.delete(d),u.layersWithOutsidePointerEventsDisabled.size===0&&(p.body.style.pointerEvents=ln))}},[d,p,n,u]),_.useEffect(()=>()=>{d&&(u.layers.delete(d),u.layersWithOutsidePointerEventsDisabled.delete(d),_n())},[d,u]),_.useEffect(()=>{let e=()=>m({});return document.addEventListener(on,e),()=>document.removeEventListener(on,e)},[]),(0,N.jsx)(en.div,{...l,ref:h,style:{pointerEvents:x?S?`auto`:`none`:void 0,...e.style},onFocusCapture:P(e.onFocusCapture,T.onFocusCapture),onBlurCapture:P(e.onBlurCapture,T.onBlurCapture),onPointerDownCapture:P(e.onPointerDownCapture,w.onPointerDownCapture)})});dn.displayName=an;var fn=`DismissableLayerBranch`,pn=_.forwardRef((e,t)=>{let n=_.useContext(un),r=_.useRef(null),i=At(t,r);return _.useEffect(()=>{let e=r.current;if(e)return n.branches.add(e),()=>{n.branches.delete(e)}},[n.branches]),(0,N.jsx)(en.div,{...e,ref:i})});pn.displayName=fn;function mn(){let e=_.useContext(un),[t,n]=_.useState(null);return _.useEffect(()=>{if(t)return e.dismissableSurfaces.add(t),()=>{e.dismissableSurfaces.delete(t)}},[t,e.dismissableSurfaces]),n}function hn(e,t){let{ownerDocument:n=globalThis?.document,deferPointerDownOutside:r=!1,isDeferredPointerDownOutsideRef:i,dismissableSurfaces:a}=t,o=nn(e),s=_.useRef(!1),c=_.useRef(!1),l=_.useRef(new Map),u=_.useRef(()=>{});return _.useEffect(()=>{function e(){c.current=!1,i.current=!1,l.current.clear()}function t(){return Array.from(l.current.values()).some(Boolean)}function d(e){if(!c.current)return;let t=e.target;t instanceof Node&&[...a].some(e=>e.contains(t))||l.current.set(e.type,!0),e.type===`click`&&window.setTimeout(()=>{c.current&&u.current()},0)}function f(e){c.current&&l.current.set(e.type,!1)}let p=a=>{if(a.target&&!s.current){let s=function(){n.removeEventListener(`click`,u.current);let r=t();e(),r||vn(sn,o,d,{discrete:!0})},d={originalEvent:a};c.current=!0,i.current=r&&a.button===0,l.current.clear(),!r||a.button!==0?s():(n.removeEventListener(`click`,u.current),u.current=s,n.addEventListener(`click`,u.current,{once:!0}))}else n.removeEventListener(`click`,u.current),e();s.current=!1},m=[`pointerup`,`mousedown`,`mouseup`,`touchstart`,`touchend`,`click`];for(let e of m)n.addEventListener(e,d,!0),n.addEventListener(e,f);let h=window.setTimeout(()=>{n.addEventListener(`pointerdown`,p)},0);return()=>{window.clearTimeout(h),n.removeEventListener(`pointerdown`,p),n.removeEventListener(`click`,u.current);for(let e of m)n.removeEventListener(e,d,!0),n.removeEventListener(e,f)}},[n,o,r,i,a]),{onPointerDownCapture:()=>s.current=!0}}function gn(e,t=globalThis?.document){let n=nn(e),r=_.useRef(!1);return _.useEffect(()=>{let e=e=>{e.target&&!r.current&&vn(cn,n,{originalEvent:e},{discrete:!1})};return t.addEventListener(`focusin`,e),()=>t.removeEventListener(`focusin`,e)},[t,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function _n(){let e=new CustomEvent(on);document.dispatchEvent(e)}function vn(e,t,n,{discrete:r}){let i=n.originalEvent.target,a=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&i.addEventListener(e,t,{once:!0}),r?tn(i,a):i.dispatchEvent(a)}var yn=`focusScope.autoFocusOnMount`,bn=`focusScope.autoFocusOnUnmount`,xn={bubbles:!1,cancelable:!0},Sn=`FocusScope`,Cn=_.forwardRef((e,t)=>{let{loop:n=!1,trapped:r=!1,onMountAutoFocus:i,onUnmountAutoFocus:a,...o}=e,[s,c]=_.useState(null),l=nn(i),u=nn(a),d=_.useRef(null),f=At(t,e=>c(e)),p=_.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;_.useEffect(()=>{if(r){let e=function(e){if(p.paused||!s)return;let t=e.target;s.contains(t)?d.current=t:An(d.current,{select:!0})},t=function(e){if(p.paused||!s)return;let t=e.relatedTarget;t!==null&&(s.contains(t)||An(d.current,{select:!0}))},n=function(e){if(document.activeElement===document.body)for(let t of e)t.removedNodes.length>0&&An(s)};document.addEventListener(`focusin`,e),document.addEventListener(`focusout`,t);let r=new MutationObserver(n);return s&&r.observe(s,{childList:!0,subtree:!0}),()=>{document.removeEventListener(`focusin`,e),document.removeEventListener(`focusout`,t),r.disconnect()}}},[r,s,p.paused]),_.useEffect(()=>{if(s){jn.add(p);let e=document.activeElement;if(!s.contains(e)){let t=new CustomEvent(yn,xn);s.addEventListener(yn,l),s.dispatchEvent(t),t.defaultPrevented||(wn(Pn(En(s)),{select:!0}),document.activeElement===e&&An(s))}return()=>{s.removeEventListener(yn,l),setTimeout(()=>{let t=new CustomEvent(bn,xn);s.addEventListener(bn,u),s.dispatchEvent(t),t.defaultPrevented||An(e??document.body,{select:!0}),s.removeEventListener(bn,u),jn.remove(p)},0)}}},[s,l,u,p]);let m=_.useCallback(e=>{if(!n&&!r||p.paused)return;let t=e.key===`Tab`&&!e.altKey&&!e.ctrlKey&&!e.metaKey,i=document.activeElement;if(t&&i){let t=e.currentTarget,[r,a]=Tn(t);r&&a?!e.shiftKey&&i===a?(e.preventDefault(),n&&An(r,{select:!0})):e.shiftKey&&i===r&&(e.preventDefault(),n&&An(a,{select:!0})):i===t&&e.preventDefault()}},[n,r,p.paused]);return(0,N.jsx)(en.div,{tabIndex:-1,...o,ref:f,onKeyDown:m})});Cn.displayName=Sn;function wn(e,{select:t=!1}={}){let n=document.activeElement;for(let r of e)if(An(r,{select:t}),document.activeElement!==n)return}function Tn(e){let t=En(e);return[Dn(t,e),Dn(t.reverse(),e)]}function En(e){let t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:e=>{let t=e.tagName===`INPUT`&&e.type===`hidden`;return e.disabled||e.hidden||t?NodeFilter.FILTER_SKIP:e.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function Dn(e,t){for(let n of e)if(!On(n,{upTo:t}))return n}function On(e,{upTo:t}){if(getComputedStyle(e).visibility===`hidden`)return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display===`none`)return!0;e=e.parentElement}return!1}function kn(e){return e instanceof HTMLInputElement&&`select`in e}function An(e,{select:t=!1}={}){if(e&&e.focus){let n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&kn(e)&&t&&e.select()}}var jn=Mn();function Mn(){let e=[];return{add(t){let n=e[0];t!==n&&n?.pause(),e=Nn(e,t),e.unshift(t)},remove(t){e=Nn(e,t),e[0]?.resume()}}}function Nn(e,t){let n=[...e],r=n.indexOf(t);return r!==-1&&n.splice(r,1),n}function Pn(e){return e.filter(e=>e.tagName!==`A`)}var Fn=`Portal`,In=_.forwardRef((e,t)=>{let{container:n,...r}=e,[i,a]=_.useState(!1);Nt(()=>a(!0),[]);let o=n||i&&globalThis?.document?.body;return o?Vt.createPortal((0,N.jsx)(en.div,{...r,ref:t}),o):null});In.displayName=Fn;function Ln(e,t){return _.useReducer((e,n)=>t[e][n]??e,e)}var Rn=e=>{let{present:t,children:n}=e,r=zn(t),i=typeof n==`function`?n({present:r.isPresent}):_.Children.only(n),a=Vn(r.ref,Un(i));return typeof n==`function`||r.isPresent?_.cloneElement(i,{ref:a}):null};Rn.displayName=`Presence`;function zn(e){let[t,n]=_.useState(),r=_.useRef(null),i=_.useRef(e),a=_.useRef(`none`),[o,s]=Ln(e?`mounted`:`unmounted`,{mounted:{UNMOUNT:`unmounted`,ANIMATION_OUT:`unmountSuspended`},unmountSuspended:{MOUNT:`mounted`,ANIMATION_END:`unmounted`},unmounted:{MOUNT:`mounted`}});return _.useEffect(()=>{let e=Hn(r.current);a.current=o===`mounted`?e:`none`},[o]),Nt(()=>{let t=r.current,n=i.current;if(n!==e){let r=a.current,o=Hn(t);e?s(`MOUNT`):o===`none`||t?.display===`none`?s(`UNMOUNT`):s(n&&r!==o?`ANIMATION_OUT`:`UNMOUNT`),i.current=e}},[e,s]),Nt(()=>{if(t){let e,n=t.ownerDocument.defaultView??window,o=a=>{let o=Hn(r.current).includes(CSS.escape(a.animationName));if(a.target===t&&o&&(s(`ANIMATION_END`),!i.current)){let r=t.style.animationFillMode;t.style.animationFillMode=`forwards`,e=n.setTimeout(()=>{t.style.animationFillMode===`forwards`&&(t.style.animationFillMode=r)})}},c=e=>{e.target===t&&(a.current=Hn(r.current))};return t.addEventListener(`animationstart`,c),t.addEventListener(`animationcancel`,o),t.addEventListener(`animationend`,o),()=>{n.clearTimeout(e),t.removeEventListener(`animationstart`,c),t.removeEventListener(`animationcancel`,o),t.removeEventListener(`animationend`,o)}}else s(`ANIMATION_END`)},[t,s]),{isPresent:[`mounted`,`unmountSuspended`].includes(o),ref:_.useCallback(e=>{r.current=e?getComputedStyle(e):null,n(e)},[])}}function Bn(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}function Vn(...e){let t=_.useRef(e);return t.current=e,_.useCallback(e=>{let n=t.current,r=!1,i=n.map(t=>{let n=Bn(t,e);return!r&&typeof n==`function`&&(r=!0),n});if(r)return()=>{for(let e=0;e<i.length;e++){let t=i[e];typeof t==`function`?t():Bn(n[e],null)}}},[])}function Hn(e){return e?.animationName||`none`}function Un(e){let t=Object.getOwnPropertyDescriptor(e.props,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var Wn=0,Gn=null;function Kn(){_.useEffect(()=>{Gn||={start:qn(),end:qn()};let{start:e,end:t}=Gn;return document.body.firstElementChild!==e&&document.body.insertAdjacentElement(`afterbegin`,e),document.body.lastElementChild!==t&&document.body.insertAdjacentElement(`beforeend`,t),Wn++,()=>{Wn===1&&(Gn?.start.remove(),Gn?.end.remove(),Gn=null),Wn=Math.max(0,Wn-1)}},[])}function qn(){let e=document.createElement(`span`);return e.setAttribute(`data-radix-focus-guard`,``),e.tabIndex=0,e.style.outline=`none`,e.style.opacity=`0`,e.style.position=`fixed`,e.style.pointerEvents=`none`,e}var Jn=function(){return Jn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var i in t=arguments[n],t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e},Jn.apply(this,arguments)};function Yn(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols==`function`)for(var i=0,r=Object.getOwnPropertySymbols(e);i<r.length;i++)t.indexOf(r[i])<0&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function Xn(e,t,n){if(n||arguments.length===2)for(var r=0,i=t.length,a;r<i;r++)(a||!(r in t))&&(a||=Array.prototype.slice.call(t,0,r),a[r]=t[r]);return e.concat(a||Array.prototype.slice.call(t))}var Zn=`right-scroll-bar-position`,Qn=`width-before-scroll-bar`,$n=`with-scroll-bars-hidden`,er=`--removed-body-scroll-bar-size`;function tr(e,t){return typeof e==`function`?e(t):e&&(e.current=t),e}function nr(e,t){var n=(0,_.useState)(function(){return{value:e,callback:t,facade:{get current(){return n.value},set current(e){var t=n.value;t!==e&&(n.value=e,n.callback(e,t))}}}})[0];return n.callback=t,n.facade}var rr=typeof window<`u`?_.useLayoutEffect:_.useEffect,ir=new WeakMap;function ar(e,t){var n=nr(t||null,function(t){return e.forEach(function(e){return tr(e,t)})});return rr(function(){var t=ir.get(n);if(t){var r=new Set(t),i=new Set(e),a=n.current;r.forEach(function(e){i.has(e)||tr(e,null)}),i.forEach(function(e){r.has(e)||tr(e,a)})}ir.set(n,e)},[e]),n}function or(e){return e}function sr(e,t){t===void 0&&(t=or);var n=[],r=!1;return{read:function(){if(r)throw Error("Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`.");return n.length?n[n.length-1]:e},useMedium:function(e){var i=t(e,r);return n.push(i),function(){n=n.filter(function(e){return e!==i})}},assignSyncMedium:function(e){for(r=!0;n.length;){var t=n;n=[],t.forEach(e)}n={push:function(t){return e(t)},filter:function(){return n}}},assignMedium:function(e){r=!0;var t=[];if(n.length){var i=n;n=[],i.forEach(e),t=n}var a=function(){var n=t;t=[],n.forEach(e)},o=function(){return Promise.resolve().then(a)};o(),n={push:function(e){t.push(e),o()},filter:function(e){return t=t.filter(e),n}}}}}function cr(e){e===void 0&&(e={});var t=sr(null);return t.options=Jn({async:!0,ssr:!1},e),t}var lr=function(e){var t=e.sideCar,n=Yn(e,[`sideCar`]);if(!t)throw Error("Sidecar: please provide `sideCar` property to import the right car");var r=t.read();if(!r)throw Error(`Sidecar medium not found`);return _.createElement(r,Jn({},n))};lr.isSideCarExport=!0;function ur(e,t){return e.useMedium(t),lr}var dr=cr(),fr=function(){},pr=_.forwardRef(function(e,t){var n=_.useRef(null),r=_.useState({onScrollCapture:fr,onWheelCapture:fr,onTouchMoveCapture:fr}),i=r[0],a=r[1],o=e.forwardProps,s=e.children,c=e.className,l=e.removeScrollBar,u=e.enabled,d=e.shards,f=e.sideCar,p=e.noRelative,m=e.noIsolation,h=e.inert,g=e.allowPinchZoom,v=e.as,y=v===void 0?`div`:v,b=e.gapMode,x=Yn(e,[`forwardProps`,`children`,`className`,`removeScrollBar`,`enabled`,`shards`,`sideCar`,`noRelative`,`noIsolation`,`inert`,`allowPinchZoom`,`as`,`gapMode`]),S=f,C=ar([n,t]),w=Jn(Jn({},x),i);return _.createElement(_.Fragment,null,u&&_.createElement(S,{sideCar:dr,removeScrollBar:l,shards:d,noRelative:p,noIsolation:m,inert:h,setCallbacks:a,allowPinchZoom:!!g,lockRef:n,gapMode:b}),o?_.cloneElement(_.Children.only(s),Jn(Jn({},w),{ref:C})):_.createElement(y,Jn({},w,{className:c,ref:C}),s))});pr.defaultProps={enabled:!0,removeScrollBar:!0,inert:!1},pr.classNames={fullWidth:Qn,zeroRight:Zn};var mr,hr=function(){if(mr)return mr;if(typeof __webpack_nonce__<`u`)return __webpack_nonce__};function gr(){if(!document)return null;var e=document.createElement(`style`);e.type=`text/css`;var t=hr();return t&&e.setAttribute(`nonce`,t),e}function _r(e,t){e.styleSheet?e.styleSheet.cssText=t:e.appendChild(document.createTextNode(t))}function vr(e){(document.head||document.getElementsByTagName(`head`)[0]).appendChild(e)}var yr=function(){var e=0,t=null;return{add:function(n){e==0&&(t=gr())&&(_r(t,n),vr(t)),e++},remove:function(){e--,!e&&t&&(t.parentNode&&t.parentNode.removeChild(t),t=null)}}},br=function(){var e=yr();return function(t,n){_.useEffect(function(){return e.add(t),function(){e.remove()}},[t&&n])}},xr=function(){var e=br();return function(t){var n=t.styles,r=t.dynamic;return e(n,r),null}},Sr={left:0,top:0,right:0,gap:0},Cr=function(e){return parseInt(e||``,10)||0},wr=function(e){var t=window.getComputedStyle(document.body),n=t[e===`padding`?`paddingLeft`:`marginLeft`],r=t[e===`padding`?`paddingTop`:`marginTop`],i=t[e===`padding`?`paddingRight`:`marginRight`];return[Cr(n),Cr(r),Cr(i)]},Tr=function(e){if(e===void 0&&(e=`margin`),typeof window>`u`)return Sr;var t=wr(e),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,r-n+t[2]-t[0])}},Er=xr(),Dr=`data-scroll-locked`,Or=function(e,t,n,r){var i=e.left,a=e.top,o=e.right,s=e.gap;return n===void 0&&(n=`margin`),`
|
|
16
|
+
`);return(0,N.jsxs)(`div`,{className:`code-file`,children:[(0,N.jsx)(`div`,{className:`code-file-head`,children:e.path}),(0,N.jsx)(`div`,{className:`code-lines`,children:o.map((o,s)=>{let c=s+1,l=rt(e.path,c);return(0,N.jsx)(yt,{n:c,text:o,turn:t.get(l),asserts:n.get(l),isOpen:r.has(l),onToggle:()=>i(l),t:a},c)})})]})}function yt({n:e,text:t,turn:n,asserts:r,isOpen:i,onToggle:a,t:o}){let s=!!n,c=!!(r&&r.length),l=c?r?.every(e=>e.passed)?`pass`:r?.some(e=>!e.passed&&e.severity===`gate`)?`fail`:`warn`:null,u=s||c;return(0,N.jsxs)(N.Fragment,{children:[(0,N.jsxs)(`div`,{className:`code-line`+(l?` line-${l}`:``)+(s&&!l?` line-send`:``)+(u?` line-clickable`:``)+(i?` is-open`:``),onClick:u?a:void 0,role:u?`button`:void 0,tabIndex:u?0:void 0,onKeyDown:u?e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),a())}:void 0,children:[(0,N.jsx)(`span`,{className:`ln`,children:e}),(0,N.jsx)(`span`,{className:`gmark`,children:c?l===`pass`?(0,N.jsx)(Le,{className:`gstat good`,"aria-hidden":`true`}):l===`warn`?(0,N.jsx)(Ie,{className:`gstat warn`,"aria-hidden":`true`}):(0,N.jsx)(Re,{className:`gstat bad`,"aria-hidden":`true`}):s?(0,N.jsx)(He,{className:`gsend`,"aria-hidden":`true`}):null}),(0,N.jsx)(`code`,{className:`ctext`,children:st(t)}),(0,N.jsxs)(`span`,{className:`lbadges`,children:[c?r?.map((e,t)=>(0,N.jsx)(bt,{a:e},t)):null,s?(0,N.jsx)(`span`,{className:`reply-hint`,children:o(i?`code.hide`:`code.reply`)}):u?(0,N.jsx)(Be,{className:`line-chev${i?` is-open`:``}`,"aria-hidden":`true`}):null]})]}),i&&s&&n?(0,N.jsx)(xt,{turn:n,t:o}):null,i&&c&&r?(0,N.jsx)(St,{asserts:r,t:o}):null]})}function bt({a:e}){return e.threshold!==void 0||e.score>0&&e.score<1?(0,N.jsxs)(`span`,{className:`abadge ${gt(e)}`,children:[D(e.score),e.threshold===void 0?null:(0,N.jsxs)(`span`,{className:`abadge-th`,children:[`/`,D(e.threshold)]})]}):null}function xt({turn:e,t}){return e.replies.length?(0,N.jsx)(`div`,{className:`line-detail reply-panel`,children:e.replies.map((e,n)=>e.kind===`text`?(0,N.jsxs)(`div`,{className:`reply-assistant`,children:[(0,N.jsx)(`span`,{className:`reply-role`,children:t(`transcript.assistant`)}),(0,N.jsx)(`div`,{className:`reply-text`,children:e.text})]},n):e.kind===`thinking`?(0,N.jsxs)(`details`,{className:`reply-think`,children:[(0,N.jsx)(`summary`,{children:t(`transcript.thinking`)}),(0,N.jsx)(`div`,{className:`reply-think-text`,children:e.text})]},n):e.kind===`error`?(0,N.jsxs)(`div`,{className:`reply-err`,children:[`! `,e.text]},n):e.kind===`tool`?(0,N.jsx)(ht,{call:e.ev,result:e.result,t},n):e.kind===`input`?(0,N.jsx)(mt,{event:{type:`input.requested`,request:e.ev.request},t},n):null)}):(0,N.jsx)(`div`,{className:`line-detail reply-empty`,children:t(`code.noReply`)})}function St({asserts:e,t}){return(0,N.jsx)(`div`,{className:`line-detail assert-detail`,children:e.map((e,n)=>(0,N.jsxs)(`div`,{className:`assert-row`,children:[(0,N.jsx)(`span`,{className:`abadge ${gt(e)}`,children:e.passed?t(`assert.pass`):t(`assert.fail`)}),(0,N.jsx)(`span`,{className:`assert-name`,children:e.name}),e.severity===`soft`?(0,N.jsx)(`span`,{className:`assert-sev`,children:t(`assert.soft`)}):null,e.threshold===void 0?null:(0,N.jsxs)(`span`,{className:`assert-score`,children:[D(e.score),` / `,D(e.threshold)]}),e.detail?(0,N.jsx)(`div`,{className:`assert-reason`,children:e.detail}):null,e.evidence?(0,N.jsxs)(`details`,{className:`assert-evidence`,children:[(0,N.jsx)(`summary`,{children:t(`assert.evidence`)}),(0,N.jsx)(`pre`,{className:`assert-evidence-pre`,children:e.evidence})]}):null]},n))})}function Ct({assertions:e,events:t,t:n}){let r=e||[];return(0,N.jsxs)(`div`,{className:`nosource`,children:[(0,N.jsx)(`div`,{className:`nosource-note`,children:n(`code.noSource`)}),r.length?(0,N.jsxs)(`div`,{className:`nosource-block`,children:[(0,N.jsx)(`div`,{className:`nosource-head`,children:n(`code.checks`)}),(0,N.jsx)(St,{asserts:r,t:n})]}):null,t?.length?(0,N.jsxs)(`div`,{className:`nosource-block`,children:[(0,N.jsx)(`div`,{className:`nosource-head`,children:n(`code.conversation`)}),(0,N.jsx)(dt,{events:t,t:n})]}):null]})}function wt({spans:e,t}){if(!e?.length)return(0,N.jsx)(`div`,{className:`trace-span-meta`,children:t(`trace.noSpans`)});let n=Math.min(...e.map(e=>e.startMs)),r=Math.max(...e.map(e=>e.endMs)),i=Math.max(1,r-n),a=new Map(e.map(e=>[e.spanId,e])),o=e=>{let t=0,n=e,r=new Set;for(;n&&n.parentSpanId&&a.has(n.parentSpanId)&&!r.has(n.spanId);){r.add(n.spanId);let e=a.get(n.parentSpanId);if(!e||(n=e,t++,t>40))break}return t},s=[...e].sort((e,t)=>e.startMs-t.startMs||o(e)-o(t));return(0,N.jsxs)(`div`,{className:`trace`,children:[(0,N.jsxs)(`div`,{className:`trace-span-meta`,children:[t(`trace.total`),` `,ne(i),` · `,e.length,` `,t(`trace.spans`),` · `,t(`trace.clickDetails`)]}),s.map(e=>{let t=(e.startMs-n)/i*100,r=Math.max(.6,(e.endMs-e.startMs)/i*100),a=e.kind||`other`,s=e.status===`error`?`bad`:`k-`+a,c=Tt(e.attributes),l=(0,N.jsxs)(`summary`,{className:`trace-row`,children:[(0,N.jsxs)(`div`,{className:`trace-label`,style:{paddingLeft:o(e)*12},title:e.name,children:[a===`other`?null:(0,N.jsx)(`span`,{className:`kind-chip k-${a}`,children:a}),e.name]}),(0,N.jsx)(`div`,{className:`trace-track`,children:(0,N.jsx)(`div`,{className:`trace-bar ${s}`,style:{left:`${t}%`,width:`${r}%`}})}),(0,N.jsx)(`div`,{className:`trace-dur num`,children:ne(e.endMs-e.startMs)})]});return c?(0,N.jsxs)(`details`,{className:`span-d`,children:[l,c]},e.spanId):(0,N.jsx)(`div`,{className:`span-d`,children:l},e.spanId)})]})}function Tt(e){if(!e)return null;let t=/^(code\.|thread\.|target$|busy_ns$|idle_ns$|rpc\.|app_server\.)/,n=Object.keys(e).filter(e=>!t.test(e));if(!n.length)return null;let r=n.filter(e=>e.startsWith(`io.`)),i=n.filter(e=>!e.startsWith(`io.`)).sort();return(0,N.jsxs)(`div`,{className:`span-attrs`,children:[r.map(t=>{let n=t.replace(/^io\./,``),r=String(e[t]);return n===`input`||n===`output`?(0,N.jsxs)(`div`,{className:`attr-io`,children:[(0,N.jsx)(`span`,{className:`attr-k`,children:n}),(0,N.jsx)(`pre`,{className:`attr-pre`,children:r})]},t):(0,N.jsx)(Et,{label:n,value:r},t)}),i.map(t=>(0,N.jsx)(Et,{label:t,value:typeof e[t]==`object`?JSON.stringify(e[t]):String(e[t])},t))]})}function Et({label:e,value:t}){return(0,N.jsxs)(`div`,{className:`attr-row`,children:[(0,N.jsx)(`span`,{className:`attr-k`,children:e}),(0,N.jsx)(`span`,{className:`attr-v`,children:t})]})}function Dt({type:e,src:t,autoLoad:n=!1,t:r}){let[i,a]=(0,_.useState)(n),[o,s]=(0,_.useState)(!1),[c,l]=(0,_.useState)(null),[u,d]=(0,_.useState)(``),f=async()=>{if(!o){s(!0);try{let e=await fetch(`/artifact?p=`+encodeURIComponent(t));if(!e.ok)throw Error(`HTTP `+e.status);l(await e.json()),d(``)}catch(e){s(!1),d(`${r(`trace.loadFailed`)} ${String(e)}`)}}};return(0,_.useEffect)(()=>{n&&f()},[]),(0,N.jsxs)(`details`,{className:`trace-details`,open:i,onToggle:e=>{let t=e.currentTarget.open;a(t),t&&f()},children:[(0,N.jsx)(`summary`,{children:r(e===`transcript`?`trace.transcript`:`trace.timing`)}),(0,N.jsxs)(`div`,{className:`trace-slot`,children:[u?(0,N.jsx)(`div`,{className:`trace-span-meta`,children:u}):c?null:(0,N.jsx)(`div`,{className:`trace-span-meta`,children:r(`trace.loading`)}),c&&e===`transcript`?(0,N.jsx)(dt,{events:Qe(c)??[],t:r}):null,c&&e===`trace`?(0,N.jsx)(wt,{spans:$e(c)??[],t:r}):null]})]})}typeof window<`u`&&window.document&&window.document.createElement;function P(e,t,{checkForDefaultPrevented:n=!0}={}){return function(r){if(e?.(r),n===!1||!r.defaultPrevented)return t?.(r)}}function Ot(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}function kt(...e){return t=>{let n=!1,r=e.map(e=>{let r=Ot(e,t);return!n&&typeof r==`function`&&(n=!0),r});if(n)return()=>{for(let t=0;t<r.length;t++){let n=r[t];typeof n==`function`?n():Ot(e[t],null)}}}}function At(...e){return _.useCallback(kt(...e),e)}function jt(e,t=[]){let n=[];function r(t,r){let i=_.createContext(r);i.displayName=t+`Context`;let a=n.length;n=[...n,r];let o=t=>{let{scope:n,children:r,...o}=t,s=n?.[e]?.[a]||i,c=_.useMemo(()=>o,Object.values(o));return(0,N.jsx)(s.Provider,{value:c,children:r})};o.displayName=t+`Provider`;function s(n,o){let s=o?.[e]?.[a]||i,c=_.useContext(s);if(c)return c;if(r!==void 0)return r;throw Error(`\`${n}\` must be used within \`${t}\``)}return[o,s]}let i=()=>{let t=n.map(e=>_.createContext(e));return function(n){let r=n?.[e]||t;return _.useMemo(()=>({[`__scope${e}`]:{...n,[e]:r}}),[n,r])}};return i.scopeName=e,[r,Mt(i,...t)]}function Mt(...e){let t=e[0];if(e.length===1)return t;let n=()=>{let n=e.map(e=>({useScope:e(),scopeName:e.scopeName}));return function(e){let r=n.reduce((t,{useScope:n,scopeName:r})=>{let i=n(e)[`__scope${r}`];return{...t,...i}},{});return _.useMemo(()=>({[`__scope${t.scopeName}`]:r}),[r])}};return n.scopeName=t.scopeName,n}var Nt=globalThis?.document?_.useLayoutEffect:()=>{},Pt=_.useId||(()=>void 0),Ft=0;function It(e){let[t,n]=_.useState(Pt());return Nt(()=>{e||n(e=>e??String(Ft++))},[e]),e||(t?`radix-${t}`:``)}var Lt=_.useInsertionEffect||Nt;function Rt({prop:e,defaultProp:t,onChange:n=()=>{},caller:r}){let[i,a,o]=zt({defaultProp:t,onChange:n}),s=e!==void 0,c=s?e:i;{let t=_.useRef(e!==void 0);_.useEffect(()=>{let e=t.current;e!==s&&console.warn(`${r} is changing from ${e?`controlled`:`uncontrolled`} to ${s?`controlled`:`uncontrolled`}. Components should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled value for the lifetime of the component.`),t.current=s},[s,r])}return[c,_.useCallback(t=>{if(s){let n=Bt(t)?t(e):t;n!==e&&o.current?.(n)}else a(t)},[s,e,a,o])]}function zt({defaultProp:e,onChange:t}){let[n,r]=_.useState(e),i=_.useRef(n),a=_.useRef(t);return Lt(()=>{a.current=t},[t]),_.useEffect(()=>{i.current!==n&&(a.current?.(n),i.current=n)},[n,i]),[n,r,a]}function Bt(e){return typeof e==`function`}var Vt=c(m(),1);function Ht(e){let t=_.forwardRef((t,n)=>{let{children:r,...i}=t,a=null,o=!1,s=[];Yt(r)&&typeof $t==`function`&&(r=$t(r._payload)),_.Children.forEach(r,e=>{if(qt(e)){o=!0;let t=e,n=`child`in t.props?t.props.child:t.props.children;Yt(n)&&typeof $t==`function`&&(n=$t(n._payload)),a=Wt(t,n),s.push(a?.props?.children)}else s.push(e)}),a?a=_.cloneElement(a,void 0,s):!o&&_.Children.count(r)===1&&_.isValidElement(r)&&(a=r);let c=a?Kt(a):void 0,l=At(n,c);if(!a){if(r||r===0)throw Error(o?Qt(e):Zt(e));return r}let u=Gt(i,a.props??{});return a.type!==_.Fragment&&(u.ref=n?l:c),_.cloneElement(a,u)});return t.displayName=`${e}.Slot`,t}var Ut=Symbol.for(`radix.slottable`),Wt=(e,t)=>{if(`child`in e.props){let t=e.props.child;return _.isValidElement(t)?_.cloneElement(t,void 0,e.props.children(t.props.children)):null}return _.isValidElement(t)?t:null};function Gt(e,t){let n={...t};for(let r in t){let i=e[r],a=t[r];/^on[A-Z]/.test(r)?i&&a?n[r]=(...e)=>{let t=a(...e);return i(...e),t}:i&&(n[r]=i):r===`style`?n[r]={...i,...a}:r===`className`&&(n[r]=[i,a].filter(Boolean).join(` `))}return{...e,...n}}function Kt(e){let t=Object.getOwnPropertyDescriptor(e.props,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}function qt(e){return _.isValidElement(e)&&typeof e.type==`function`&&`__radixId`in e.type&&e.type.__radixId===Ut}var Jt=Symbol.for(`react.lazy`);function Yt(e){return typeof e==`object`&&!!e&&`$$typeof`in e&&e.$$typeof===Jt&&`_payload`in e&&Xt(e._payload)}function Xt(e){return typeof e==`object`&&!!e&&`then`in e}var Zt=e=>`${e} failed to slot onto its children. Expected a single React element child or \`Slottable\`.`,Qt=e=>`${e} failed to slot onto its \`Slottable\`. Expected \`Slottable\` to receive a single React element child.`,$t=_.use,en=[`a`,`button`,`div`,`form`,`h2`,`h3`,`img`,`input`,`label`,`li`,`nav`,`ol`,`p`,`select`,`span`,`svg`,`ul`].reduce((e,t)=>{let n=Ht(`Primitive.${t}`),r=_.forwardRef((e,r)=>{let{asChild:i,...a}=e,o=i?n:t;return typeof window<`u`&&(window[Symbol.for(`radix-ui`)]=!0),(0,N.jsx)(o,{...a,ref:r})});return r.displayName=`Primitive.${t}`,{...e,[t]:r}},{});function tn(e,t){e&&Vt.flushSync(()=>e.dispatchEvent(t))}function nn(e){let t=_.useRef(e);return _.useEffect(()=>{t.current=e}),_.useMemo(()=>((...e)=>t.current?.(...e)),[])}function rn(e,t=globalThis?.document){let n=nn(e);_.useEffect(()=>{let e=e=>{e.key===`Escape`&&n(e)};return t.addEventListener(`keydown`,e,{capture:!0}),()=>t.removeEventListener(`keydown`,e,{capture:!0})},[n,t])}var an=`DismissableLayer`,on=`dismissableLayer.update`,sn=`dismissableLayer.pointerDownOutside`,cn=`dismissableLayer.focusOutside`,ln,un=_.createContext({layers:new Set,layersWithOutsidePointerEventsDisabled:new Set,branches:new Set,dismissableSurfaces:new Set}),dn=_.forwardRef((e,t)=>{let{disableOutsidePointerEvents:n=!1,deferPointerDownOutside:r=!1,onEscapeKeyDown:i,onPointerDownOutside:a,onFocusOutside:o,onInteractOutside:s,onDismiss:c,...l}=e,u=_.useContext(un),[d,f]=_.useState(null),p=d?.ownerDocument??globalThis?.document,[,m]=_.useState({}),h=At(t,e=>f(e)),g=Array.from(u.layers),[v]=[...u.layersWithOutsidePointerEventsDisabled].slice(-1),y=g.indexOf(v),b=d?g.indexOf(d):-1,x=u.layersWithOutsidePointerEventsDisabled.size>0,S=b>=y,C=_.useRef(!1),w=hn(e=>{let t=e.target;if(!(t instanceof Node))return;let n=[...u.branches].some(e=>e.contains(t));!S||n||(a?.(e),s?.(e),e.defaultPrevented||c?.())},{ownerDocument:p,deferPointerDownOutside:r,isDeferredPointerDownOutsideRef:C,dismissableSurfaces:u.dismissableSurfaces}),T=gn(e=>{if(r&&C.current)return;let t=e.target;[...u.branches].some(e=>e.contains(t))||(o?.(e),s?.(e),e.defaultPrevented||c?.())},p);return rn(e=>{b===u.layers.size-1&&(i?.(e),!e.defaultPrevented&&c&&(e.preventDefault(),c()))},p),_.useEffect(()=>{if(d)return n&&(u.layersWithOutsidePointerEventsDisabled.size===0&&(ln=p.body.style.pointerEvents,p.body.style.pointerEvents=`none`),u.layersWithOutsidePointerEventsDisabled.add(d)),u.layers.add(d),_n(),()=>{n&&(u.layersWithOutsidePointerEventsDisabled.delete(d),u.layersWithOutsidePointerEventsDisabled.size===0&&(p.body.style.pointerEvents=ln))}},[d,p,n,u]),_.useEffect(()=>()=>{d&&(u.layers.delete(d),u.layersWithOutsidePointerEventsDisabled.delete(d),_n())},[d,u]),_.useEffect(()=>{let e=()=>m({});return document.addEventListener(on,e),()=>document.removeEventListener(on,e)},[]),(0,N.jsx)(en.div,{...l,ref:h,style:{pointerEvents:x?S?`auto`:`none`:void 0,...e.style},onFocusCapture:P(e.onFocusCapture,T.onFocusCapture),onBlurCapture:P(e.onBlurCapture,T.onBlurCapture),onPointerDownCapture:P(e.onPointerDownCapture,w.onPointerDownCapture)})});dn.displayName=an;var fn=`DismissableLayerBranch`,pn=_.forwardRef((e,t)=>{let n=_.useContext(un),r=_.useRef(null),i=At(t,r);return _.useEffect(()=>{let e=r.current;if(e)return n.branches.add(e),()=>{n.branches.delete(e)}},[n.branches]),(0,N.jsx)(en.div,{...e,ref:i})});pn.displayName=fn;function mn(){let e=_.useContext(un),[t,n]=_.useState(null);return _.useEffect(()=>{if(t)return e.dismissableSurfaces.add(t),()=>{e.dismissableSurfaces.delete(t)}},[t,e.dismissableSurfaces]),n}function hn(e,t){let{ownerDocument:n=globalThis?.document,deferPointerDownOutside:r=!1,isDeferredPointerDownOutsideRef:i,dismissableSurfaces:a}=t,o=nn(e),s=_.useRef(!1),c=_.useRef(!1),l=_.useRef(new Map),u=_.useRef(()=>{});return _.useEffect(()=>{function e(){c.current=!1,i.current=!1,l.current.clear()}function t(){return Array.from(l.current.values()).some(Boolean)}function d(e){if(!c.current)return;let t=e.target;t instanceof Node&&[...a].some(e=>e.contains(t))||l.current.set(e.type,!0),e.type===`click`&&window.setTimeout(()=>{c.current&&u.current()},0)}function f(e){c.current&&l.current.set(e.type,!1)}let p=a=>{if(a.target&&!s.current){let s=function(){n.removeEventListener(`click`,u.current);let r=t();e(),r||vn(sn,o,d,{discrete:!0})},d={originalEvent:a};c.current=!0,i.current=r&&a.button===0,l.current.clear(),!r||a.button!==0?s():(n.removeEventListener(`click`,u.current),u.current=s,n.addEventListener(`click`,u.current,{once:!0}))}else n.removeEventListener(`click`,u.current),e();s.current=!1},m=[`pointerup`,`mousedown`,`mouseup`,`touchstart`,`touchend`,`click`];for(let e of m)n.addEventListener(e,d,!0),n.addEventListener(e,f);let h=window.setTimeout(()=>{n.addEventListener(`pointerdown`,p)},0);return()=>{window.clearTimeout(h),n.removeEventListener(`pointerdown`,p),n.removeEventListener(`click`,u.current);for(let e of m)n.removeEventListener(e,d,!0),n.removeEventListener(e,f)}},[n,o,r,i,a]),{onPointerDownCapture:()=>s.current=!0}}function gn(e,t=globalThis?.document){let n=nn(e),r=_.useRef(!1);return _.useEffect(()=>{let e=e=>{e.target&&!r.current&&vn(cn,n,{originalEvent:e},{discrete:!1})};return t.addEventListener(`focusin`,e),()=>t.removeEventListener(`focusin`,e)},[t,n]),{onFocusCapture:()=>r.current=!0,onBlurCapture:()=>r.current=!1}}function _n(){let e=new CustomEvent(on);document.dispatchEvent(e)}function vn(e,t,n,{discrete:r}){let i=n.originalEvent.target,a=new CustomEvent(e,{bubbles:!1,cancelable:!0,detail:n});t&&i.addEventListener(e,t,{once:!0}),r?tn(i,a):i.dispatchEvent(a)}var yn=`focusScope.autoFocusOnMount`,bn=`focusScope.autoFocusOnUnmount`,xn={bubbles:!1,cancelable:!0},Sn=`FocusScope`,Cn=_.forwardRef((e,t)=>{let{loop:n=!1,trapped:r=!1,onMountAutoFocus:i,onUnmountAutoFocus:a,...o}=e,[s,c]=_.useState(null),l=nn(i),u=nn(a),d=_.useRef(null),f=At(t,e=>c(e)),p=_.useRef({paused:!1,pause(){this.paused=!0},resume(){this.paused=!1}}).current;_.useEffect(()=>{if(r){let e=function(e){if(p.paused||!s)return;let t=e.target;s.contains(t)?d.current=t:An(d.current,{select:!0})},t=function(e){if(p.paused||!s)return;let t=e.relatedTarget;t!==null&&(s.contains(t)||An(d.current,{select:!0}))},n=function(e){if(document.activeElement===document.body)for(let t of e)t.removedNodes.length>0&&An(s)};document.addEventListener(`focusin`,e),document.addEventListener(`focusout`,t);let r=new MutationObserver(n);return s&&r.observe(s,{childList:!0,subtree:!0}),()=>{document.removeEventListener(`focusin`,e),document.removeEventListener(`focusout`,t),r.disconnect()}}},[r,s,p.paused]),_.useEffect(()=>{if(s){jn.add(p);let e=document.activeElement;if(!s.contains(e)){let t=new CustomEvent(yn,xn);s.addEventListener(yn,l),s.dispatchEvent(t),t.defaultPrevented||(wn(Pn(En(s)),{select:!0}),document.activeElement===e&&An(s))}return()=>{s.removeEventListener(yn,l),setTimeout(()=>{let t=new CustomEvent(bn,xn);s.addEventListener(bn,u),s.dispatchEvent(t),t.defaultPrevented||An(e??document.body,{select:!0}),s.removeEventListener(bn,u),jn.remove(p)},0)}}},[s,l,u,p]);let m=_.useCallback(e=>{if(!n&&!r||p.paused)return;let t=e.key===`Tab`&&!e.altKey&&!e.ctrlKey&&!e.metaKey,i=document.activeElement;if(t&&i){let t=e.currentTarget,[r,a]=Tn(t);r&&a?!e.shiftKey&&i===a?(e.preventDefault(),n&&An(r,{select:!0})):e.shiftKey&&i===r&&(e.preventDefault(),n&&An(a,{select:!0})):i===t&&e.preventDefault()}},[n,r,p.paused]);return(0,N.jsx)(en.div,{tabIndex:-1,...o,ref:f,onKeyDown:m})});Cn.displayName=Sn;function wn(e,{select:t=!1}={}){let n=document.activeElement;for(let r of e)if(An(r,{select:t}),document.activeElement!==n)return}function Tn(e){let t=En(e);return[Dn(t,e),Dn(t.reverse(),e)]}function En(e){let t=[],n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT,{acceptNode:e=>{let t=e.tagName===`INPUT`&&e.type===`hidden`;return e.disabled||e.hidden||t?NodeFilter.FILTER_SKIP:e.tabIndex>=0?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});for(;n.nextNode();)t.push(n.currentNode);return t}function Dn(e,t){for(let n of e)if(!On(n,{upTo:t}))return n}function On(e,{upTo:t}){if(getComputedStyle(e).visibility===`hidden`)return!0;for(;e;){if(t!==void 0&&e===t)return!1;if(getComputedStyle(e).display===`none`)return!0;e=e.parentElement}return!1}function kn(e){return e instanceof HTMLInputElement&&`select`in e}function An(e,{select:t=!1}={}){if(e&&e.focus){let n=document.activeElement;e.focus({preventScroll:!0}),e!==n&&kn(e)&&t&&e.select()}}var jn=Mn();function Mn(){let e=[];return{add(t){let n=e[0];t!==n&&n?.pause(),e=Nn(e,t),e.unshift(t)},remove(t){e=Nn(e,t),e[0]?.resume()}}}function Nn(e,t){let n=[...e],r=n.indexOf(t);return r!==-1&&n.splice(r,1),n}function Pn(e){return e.filter(e=>e.tagName!==`A`)}var Fn=`Portal`,In=_.forwardRef((e,t)=>{let{container:n,...r}=e,[i,a]=_.useState(!1);Nt(()=>a(!0),[]);let o=n||i&&globalThis?.document?.body;return o?Vt.createPortal((0,N.jsx)(en.div,{...r,ref:t}),o):null});In.displayName=Fn;function Ln(e,t){return _.useReducer((e,n)=>t[e][n]??e,e)}var Rn=e=>{let{present:t,children:n}=e,r=zn(t),i=typeof n==`function`?n({present:r.isPresent}):_.Children.only(n),a=Vn(r.ref,Un(i));return typeof n==`function`||r.isPresent?_.cloneElement(i,{ref:a}):null};Rn.displayName=`Presence`;function zn(e){let[t,n]=_.useState(),r=_.useRef(null),i=_.useRef(e),a=_.useRef(`none`),[o,s]=Ln(e?`mounted`:`unmounted`,{mounted:{UNMOUNT:`unmounted`,ANIMATION_OUT:`unmountSuspended`},unmountSuspended:{MOUNT:`mounted`,ANIMATION_END:`unmounted`},unmounted:{MOUNT:`mounted`}});return _.useEffect(()=>{let e=Hn(r.current);a.current=o===`mounted`?e:`none`},[o]),Nt(()=>{let t=r.current,n=i.current;if(n!==e){let r=a.current,o=Hn(t);e?s(`MOUNT`):o===`none`||t?.display===`none`?s(`UNMOUNT`):s(n&&r!==o?`ANIMATION_OUT`:`UNMOUNT`),i.current=e}},[e,s]),Nt(()=>{if(t){let e,n=t.ownerDocument.defaultView??window,o=a=>{let o=Hn(r.current).includes(CSS.escape(a.animationName));if(a.target===t&&o&&(s(`ANIMATION_END`),!i.current)){let r=t.style.animationFillMode;t.style.animationFillMode=`forwards`,e=n.setTimeout(()=>{t.style.animationFillMode===`forwards`&&(t.style.animationFillMode=r)})}},c=e=>{e.target===t&&(a.current=Hn(r.current))};return t.addEventListener(`animationstart`,c),t.addEventListener(`animationcancel`,o),t.addEventListener(`animationend`,o),()=>{n.clearTimeout(e),t.removeEventListener(`animationstart`,c),t.removeEventListener(`animationcancel`,o),t.removeEventListener(`animationend`,o)}}else s(`ANIMATION_END`)},[t,s]),{isPresent:[`mounted`,`unmountSuspended`].includes(o),ref:_.useCallback(e=>{r.current=e?getComputedStyle(e):null,n(e)},[])}}function Bn(e,t){if(typeof e==`function`)return e(t);e!=null&&(e.current=t)}function Vn(...e){let t=_.useRef(e);return t.current=e,_.useCallback(e=>{let n=t.current,r=!1,i=n.map(t=>{let n=Bn(t,e);return!r&&typeof n==`function`&&(r=!0),n});if(r)return()=>{for(let e=0;e<i.length;e++){let t=i[e];typeof t==`function`?t():Bn(n[e],null)}}},[])}function Hn(e){return e?.animationName||`none`}function Un(e){let t=Object.getOwnPropertyDescriptor(e.props,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning;return n?e.ref:(t=Object.getOwnPropertyDescriptor(e,`ref`)?.get,n=t&&`isReactWarning`in t&&t.isReactWarning,n?e.props.ref:e.props.ref||e.ref)}var Wn=0,Gn=null;function Kn(){_.useEffect(()=>{Gn||={start:qn(),end:qn()};let{start:e,end:t}=Gn;return document.body.firstElementChild!==e&&document.body.insertAdjacentElement(`afterbegin`,e),document.body.lastElementChild!==t&&document.body.insertAdjacentElement(`beforeend`,t),Wn++,()=>{Wn===1&&(Gn?.start.remove(),Gn?.end.remove(),Gn=null),Wn=Math.max(0,Wn-1)}},[])}function qn(){let e=document.createElement(`span`);return e.setAttribute(`data-radix-focus-guard`,``),e.tabIndex=0,e.style.outline=`none`,e.style.opacity=`0`,e.style.position=`fixed`,e.style.pointerEvents=`none`,e}var Jn=function(){return Jn=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var i in t=arguments[n],t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e},Jn.apply(this,arguments)};function Yn(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&typeof Object.getOwnPropertySymbols==`function`)for(var i=0,r=Object.getOwnPropertySymbols(e);i<r.length;i++)t.indexOf(r[i])<0&&Object.prototype.propertyIsEnumerable.call(e,r[i])&&(n[r[i]]=e[r[i]]);return n}function Xn(e,t,n){if(n||arguments.length===2)for(var r=0,i=t.length,a;r<i;r++)(a||!(r in t))&&(a||=Array.prototype.slice.call(t,0,r),a[r]=t[r]);return e.concat(a||Array.prototype.slice.call(t))}var Zn=`right-scroll-bar-position`,Qn=`width-before-scroll-bar`,$n=`with-scroll-bars-hidden`,er=`--removed-body-scroll-bar-size`;function tr(e,t){return typeof e==`function`?e(t):e&&(e.current=t),e}function nr(e,t){var n=(0,_.useState)(function(){return{value:e,callback:t,facade:{get current(){return n.value},set current(e){var t=n.value;t!==e&&(n.value=e,n.callback(e,t))}}}})[0];return n.callback=t,n.facade}var rr=typeof window<`u`?_.useLayoutEffect:_.useEffect,ir=new WeakMap;function ar(e,t){var n=nr(t||null,function(t){return e.forEach(function(e){return tr(e,t)})});return rr(function(){var t=ir.get(n);if(t){var r=new Set(t),i=new Set(e),a=n.current;r.forEach(function(e){i.has(e)||tr(e,null)}),i.forEach(function(e){r.has(e)||tr(e,a)})}ir.set(n,e)},[e]),n}function or(e){return e}function sr(e,t){t===void 0&&(t=or);var n=[],r=!1;return{read:function(){if(r)throw Error("Sidecar: could not `read` from an `assigned` medium. `read` could be used only with `useMedium`.");return n.length?n[n.length-1]:e},useMedium:function(e){var i=t(e,r);return n.push(i),function(){n=n.filter(function(e){return e!==i})}},assignSyncMedium:function(e){for(r=!0;n.length;){var t=n;n=[],t.forEach(e)}n={push:function(t){return e(t)},filter:function(){return n}}},assignMedium:function(e){r=!0;var t=[];if(n.length){var i=n;n=[],i.forEach(e),t=n}var a=function(){var n=t;t=[],n.forEach(e)},o=function(){return Promise.resolve().then(a)};o(),n={push:function(e){t.push(e),o()},filter:function(e){return t=t.filter(e),n}}}}}function cr(e){e===void 0&&(e={});var t=sr(null);return t.options=Jn({async:!0,ssr:!1},e),t}var lr=function(e){var t=e.sideCar,n=Yn(e,[`sideCar`]);if(!t)throw Error("Sidecar: please provide `sideCar` property to import the right car");var r=t.read();if(!r)throw Error(`Sidecar medium not found`);return _.createElement(r,Jn({},n))};lr.isSideCarExport=!0;function ur(e,t){return e.useMedium(t),lr}var dr=cr(),fr=function(){},pr=_.forwardRef(function(e,t){var n=_.useRef(null),r=_.useState({onScrollCapture:fr,onWheelCapture:fr,onTouchMoveCapture:fr}),i=r[0],a=r[1],o=e.forwardProps,s=e.children,c=e.className,l=e.removeScrollBar,u=e.enabled,d=e.shards,f=e.sideCar,p=e.noRelative,m=e.noIsolation,h=e.inert,g=e.allowPinchZoom,v=e.as,y=v===void 0?`div`:v,b=e.gapMode,x=Yn(e,[`forwardProps`,`children`,`className`,`removeScrollBar`,`enabled`,`shards`,`sideCar`,`noRelative`,`noIsolation`,`inert`,`allowPinchZoom`,`as`,`gapMode`]),S=f,C=ar([n,t]),w=Jn(Jn({},x),i);return _.createElement(_.Fragment,null,u&&_.createElement(S,{sideCar:dr,removeScrollBar:l,shards:d,noRelative:p,noIsolation:m,inert:h,setCallbacks:a,allowPinchZoom:!!g,lockRef:n,gapMode:b}),o?_.cloneElement(_.Children.only(s),Jn(Jn({},w),{ref:C})):_.createElement(y,Jn({},w,{className:c,ref:C}),s))});pr.defaultProps={enabled:!0,removeScrollBar:!0,inert:!1},pr.classNames={fullWidth:Qn,zeroRight:Zn};var mr,hr=function(){if(mr)return mr;if(typeof __webpack_nonce__<`u`)return __webpack_nonce__};function gr(){if(!document)return null;var e=document.createElement(`style`);e.type=`text/css`;var t=hr();return t&&e.setAttribute(`nonce`,t),e}function _r(e,t){e.styleSheet?e.styleSheet.cssText=t:e.appendChild(document.createTextNode(t))}function vr(e){(document.head||document.getElementsByTagName(`head`)[0]).appendChild(e)}var yr=function(){var e=0,t=null;return{add:function(n){e==0&&(t=gr())&&(_r(t,n),vr(t)),e++},remove:function(){e--,!e&&t&&(t.parentNode&&t.parentNode.removeChild(t),t=null)}}},br=function(){var e=yr();return function(t,n){_.useEffect(function(){return e.add(t),function(){e.remove()}},[t&&n])}},xr=function(){var e=br();return function(t){var n=t.styles,r=t.dynamic;return e(n,r),null}},Sr={left:0,top:0,right:0,gap:0},Cr=function(e){return parseInt(e||``,10)||0},wr=function(e){var t=window.getComputedStyle(document.body),n=t[e===`padding`?`paddingLeft`:`marginLeft`],r=t[e===`padding`?`paddingTop`:`marginTop`],i=t[e===`padding`?`paddingRight`:`marginRight`];return[Cr(n),Cr(r),Cr(i)]},Tr=function(e){if(e===void 0&&(e=`margin`),typeof window>`u`)return Sr;var t=wr(e),n=document.documentElement.clientWidth,r=window.innerWidth;return{left:t[0],top:t[1],right:t[2],gap:Math.max(0,r-n+t[2]-t[0])}},Er=xr(),Dr=`data-scroll-locked`,Or=function(e,t,n,r){var i=e.left,a=e.top,o=e.right,s=e.gap;return n===void 0&&(n=`margin`),`
|
|
17
17
|
.${$n} {
|
|
18
18
|
overflow: hidden ${r};
|
|
19
19
|
padding-right: ${s}px ${r};
|