@capybara-hq/kernel 0.1.0-rc.2 → 0.1.0-rc.4
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/dist/admin/admin.controller.d.ts +9 -4
- package/dist/admin/admin.controller.js +13 -4
- package/dist/admin/extensions.controller.d.ts +8 -1
- package/dist/admin/extensions.controller.js +22 -2
- package/dist/agents/agent-lookup.d.ts +3 -0
- package/dist/agents/agent-lookup.js +20 -2
- package/dist/agents/agent-profile.service.d.ts +29 -0
- package/dist/agents/agent-profile.service.js +117 -0
- package/dist/agents/agents.controller.d.ts +93 -3
- package/dist/agents/agents.controller.js +114 -4
- package/dist/agents/agents.module.js +6 -2
- package/dist/agents/agents.service.d.ts +13 -5
- package/dist/agents/agents.service.js +49 -13
- package/dist/agents/definition.d.ts +35 -8
- package/dist/agents/definition.js +203 -17
- package/dist/agents/instruction-files.d.ts +60 -0
- package/dist/agents/instruction-files.js +111 -0
- package/dist/agents/models.controller.d.ts +9 -3
- package/dist/agents/models.controller.js +19 -4
- package/dist/agents/profile.d.ts +96 -0
- package/dist/agents/profile.js +51 -0
- package/dist/agents/readiness.controller.d.ts +26 -0
- package/dist/agents/readiness.controller.js +56 -0
- package/dist/agents/templates.js +20 -5
- package/dist/background/background.controller.d.ts +38 -0
- package/dist/background/background.controller.js +87 -0
- package/dist/background/background.module.d.ts +10 -0
- package/dist/background/background.module.js +32 -0
- package/dist/background/finish.d.ts +43 -0
- package/dist/background/finish.js +94 -0
- package/dist/background/launch-lock.d.ts +14 -0
- package/dist/background/launch-lock.js +39 -0
- package/dist/background/launch.d.ts +36 -0
- package/dist/background/launch.js +70 -0
- package/dist/background/poll.job.d.ts +53 -0
- package/dist/background/poll.job.js +182 -0
- package/dist/background/render.d.ts +23 -0
- package/dist/background/render.js +48 -0
- package/dist/background/session.d.ts +37 -0
- package/dist/background/session.js +66 -0
- package/dist/background/status.d.ts +35 -0
- package/dist/background/status.js +57 -0
- package/dist/background/stop.d.ts +62 -0
- package/dist/background/stop.js +225 -0
- package/dist/background/store.d.ts +150 -0
- package/dist/background/store.js +351 -0
- package/dist/background/store.module.d.ts +6 -0
- package/dist/background/store.module.js +22 -0
- package/dist/background/tasks.service.d.ts +67 -0
- package/dist/background/tasks.service.js +186 -0
- package/dist/background/wake-rules.d.ts +57 -0
- package/dist/background/wake-rules.js +83 -0
- package/dist/background/wake.d.ts +28 -0
- package/dist/background/wake.js +57 -0
- package/dist/catalog/catalog-content.js +4 -1
- package/dist/catalog/claude/agents.js +15 -10
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/plugin-import.js +1 -1
- package/dist/catalog/plugin-upgrade.js +1 -1
- package/dist/channels/cards.d.ts +8 -2
- package/dist/channels/cards.js +17 -9
- package/dist/channels/connections.service.d.ts +16 -1
- package/dist/channels/connections.service.js +38 -4
- package/dist/channels/threads.d.ts +5 -0
- package/dist/channels/threads.js +8 -0
- package/dist/config/schema.d.ts +18 -0
- package/dist/config/schema.js +104 -2
- package/dist/conversations/access.js +2 -0
- package/dist/conversations/artifacts.d.ts +1 -1
- package/dist/conversations/artifacts.js +1 -1
- package/dist/conversations/attachments.service.d.ts +30 -0
- package/dist/conversations/attachments.service.js +130 -5
- package/dist/conversations/conversations.controller.d.ts +36 -5
- package/dist/conversations/conversations.controller.js +62 -12
- package/dist/conversations/conversations.module.js +3 -0
- package/dist/conversations/conversations.service.d.ts +44 -2
- package/dist/conversations/conversations.service.js +140 -12
- package/dist/conversations/event-log.d.ts +12 -1
- package/dist/conversations/event-log.js +29 -1
- package/dist/conversations/events.d.ts +81 -3
- package/dist/conversations/events.js +83 -16
- package/dist/conversations/queue.d.ts +3 -1
- package/dist/conversations/queue.js +13 -2
- package/dist/conversations/queue.service.js +3 -1
- package/dist/conversations/titles.d.ts +7 -0
- package/dist/conversations/titles.js +15 -0
- package/dist/db/kernel-schema.d.ts +60 -4
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.js +3 -0
- package/dist/errors.d.ts +8 -0
- package/dist/errors.js +8 -0
- package/dist/evals/recorded-tools.d.ts +27 -1
- package/dist/evals/recorded-tools.js +85 -10
- package/dist/evals/run-replay.d.ts +10 -2
- package/dist/evals/run-replay.js +49 -12
- package/dist/evals/step-replay.js +12 -6
- package/dist/evals/trajectory.d.ts +2 -2
- package/dist/evals/trajectory.js +1 -1
- package/dist/extensions/admin-ops.js +2 -0
- package/dist/extensions/admin-view.d.ts +3 -1
- package/dist/extensions/admin-view.js +10 -2
- package/dist/extensions/blobs.js +1 -0
- package/dist/extensions/config-issues.d.ts +13 -1
- package/dist/extensions/config-issues.js +22 -5
- package/dist/extensions/config-json-schema.d.ts +43 -7
- package/dist/extensions/config-json-schema.js +124 -58
- package/dist/extensions/deployment-config-store.d.ts +6 -0
- package/dist/extensions/deployment-config.d.ts +50 -3
- package/dist/extensions/deployment-config.js +125 -28
- package/dist/extensions/display-name.d.ts +22 -0
- package/dist/extensions/display-name.js +77 -0
- package/dist/extensions/extensions.module.js +6 -0
- package/dist/extensions/host.d.ts +26 -1
- package/dist/extensions/host.js +82 -9
- package/dist/extensions/org-config.controller.d.ts +11 -3
- package/dist/extensions/org-config.controller.js +14 -6
- package/dist/extensions/org-config.d.ts +6 -0
- package/dist/extensions/org-config.js +12 -13
- package/dist/extensions/package.d.ts +14 -1
- package/dist/extensions/package.js +51 -2
- package/dist/extensions/permission-view.d.ts +3 -0
- package/dist/extensions/point-defaults.controller.d.ts +34 -0
- package/dist/extensions/point-defaults.controller.js +71 -0
- package/dist/extensions/point-defaults.d.ts +64 -0
- package/dist/extensions/point-defaults.js +206 -0
- package/dist/extensions/registry.d.ts +1 -1
- package/dist/extensions/registry.js +2 -0
- package/dist/http/api.module.js +8 -0
- package/dist/http/nest-logger.d.ts +6 -5
- package/dist/http/nest-logger.js +24 -10
- package/dist/identity/auth.controller.js +9 -5
- package/dist/identity/cookies.d.ts +20 -5
- package/dist/identity/cookies.js +44 -6
- package/dist/identity/me.controller.d.ts +5 -1
- package/dist/identity/me.controller.js +12 -3
- package/dist/identity/sessions.d.ts +12 -0
- package/dist/identity/sessions.js +45 -0
- package/dist/identity/settings.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/infra/config/kernel-config.service.js +6 -0
- package/dist/infra/database/database.module.js +1 -0
- package/dist/infra/events/kernel-events.d.ts +8 -0
- package/dist/infra/lifecycle/process-guards.js +4 -0
- package/dist/infra/logging/logging.module.d.ts +4 -2
- package/dist/infra/logging/logging.module.js +24 -6
- package/dist/infra/queue/redis-connection.d.ts +6 -0
- package/dist/infra/queue/redis-connection.js +7 -0
- package/dist/infra/redis/redis.module.js +6 -2
- package/dist/infra/tokens.d.ts +6 -1
- package/dist/infra/tokens.js +6 -1
- package/dist/lifecycle/kernel-lifecycle.js +5 -0
- package/dist/log.d.ts +13 -1
- package/dist/log.js +93 -17
- package/dist/models/purposes.d.ts +23 -0
- package/dist/models/purposes.js +31 -10
- package/dist/orgs/offboarding.d.ts +3 -1
- package/dist/orgs/offboarding.js +26 -16
- package/dist/orgs/settings.service.d.ts +7 -2
- package/dist/orgs/settings.service.js +15 -4
- package/dist/roles/worker.module.js +6 -0
- package/dist/runtime/context/build.d.ts +15 -13
- package/dist/runtime/context/build.js +45 -27
- package/dist/runtime/context/claude-tools.d.ts +3 -1
- package/dist/runtime/context/claude-tools.js +12 -12
- package/dist/runtime/context/compaction.js +4 -0
- package/dist/runtime/context/legacy-text.d.ts +22 -0
- package/dist/runtime/context/legacy-text.js +37 -0
- package/dist/runtime/context/skills.d.ts +29 -11
- package/dist/runtime/context/skills.js +37 -30
- package/dist/runtime/langgraph-loop.js +3 -2
- package/dist/runtime/loop.d.ts +5 -4
- package/dist/runtime/maintenance.d.ts +4 -2
- package/dist/runtime/maintenance.js +17 -5
- package/dist/runtime/model-call.d.ts +17 -1
- package/dist/runtime/model-call.js +4 -3
- package/dist/runtime/providers.d.ts +6 -0
- package/dist/runtime/providers.js +8 -0
- package/dist/runtime/run-finish.d.ts +1 -1
- package/dist/runtime/run-queue.d.ts +28 -5
- package/dist/runtime/run-queue.js +131 -35
- package/dist/runtime/run-worker.d.ts +2 -2
- package/dist/runtime/run-worker.js +20 -7
- package/dist/runtime/runtime.module.js +8 -3
- package/dist/runtime/step-log.d.ts +6 -0
- package/dist/runtime/step-log.js +16 -2
- package/dist/runtime/subagents/definition.d.ts +1 -6
- package/dist/runtime/subagents/definition.js +14 -13
- package/dist/runtime/subagents/dispatch.d.ts +2 -2
- package/dist/runtime/subagents/dispatch.js +2 -2
- package/dist/runtime/subagents/org-agents.js +2 -1
- package/dist/runtime/subagents/roster.d.ts +1 -1
- package/dist/runtime/subagents/roster.js +1 -1
- package/dist/runtime/subagents/skill-fork.d.ts +2 -2
- package/dist/runtime/subagents/skill-fork.js +2 -2
- package/dist/runtime/subagents/subagents.service.d.ts +3 -3
- package/dist/runtime/subagents/subagents.service.js +3 -3
- package/dist/runtime/usage-report.d.ts +2 -1
- package/dist/runtime/usage-report.js +2 -1
- package/dist/runtime/waits.d.ts +13 -7
- package/dist/runtime/waits.js +42 -16
- package/dist/sandbox/sandbox.module.js +6 -1
- package/dist/sandbox/sandbox.service.d.ts +61 -3
- package/dist/sandbox/sandbox.service.js +141 -7
- package/dist/skills/catalog.d.ts +4 -4
- package/dist/skills/catalog.js +4 -4
- package/dist/skills/changes.service.d.ts +2 -2
- package/dist/skills/changes.service.js +5 -4
- package/dist/skills/invocation-keys.d.ts +1 -1
- package/dist/skills/invocation-keys.js +1 -1
- package/dist/skills/invoke.d.ts +1 -1
- package/dist/skills/invoke.js +5 -4
- package/dist/tools/approvals.service.d.ts +6 -0
- package/dist/tools/approvals.service.js +21 -1
- package/dist/tools/builtin-names.d.ts +91 -0
- package/dist/tools/builtin-names.js +143 -0
- package/dist/tools/builtins/agent.d.ts +7 -7
- package/dist/tools/builtins/agent.js +7 -11
- package/dist/tools/builtins/ask-user.d.ts +1 -1
- package/dist/tools/builtins/ask-user.js +2 -2
- package/dist/tools/builtins/builtin-tools.d.ts +17 -3
- package/dist/tools/builtins/builtin-tools.js +36 -4
- package/dist/tools/builtins/read-tool-output.d.ts +1 -1
- package/dist/tools/builtins/read-tool-output.js +2 -2
- package/dist/tools/builtins/sandbox/bash.d.ts +4 -4
- package/dist/tools/builtins/sandbox/bash.js +259 -29
- package/dist/tools/builtins/sandbox/common.d.ts +30 -7
- package/dist/tools/builtins/sandbox/common.js +9 -5
- package/dist/tools/builtins/sandbox/deliver.d.ts +1 -1
- package/dist/tools/builtins/sandbox/deliver.js +12 -12
- package/dist/tools/builtins/sandbox/edit.d.ts +1 -1
- package/dist/tools/builtins/sandbox/edit.js +41 -30
- package/dist/tools/builtins/sandbox/file-state.d.ts +34 -0
- package/dist/tools/builtins/sandbox/file-state.js +34 -0
- package/dist/tools/builtins/sandbox/glob-match.d.ts +1 -1
- package/dist/tools/builtins/sandbox/glob-match.js +1 -1
- package/dist/tools/builtins/sandbox/glob.d.ts +1 -1
- package/dist/tools/builtins/sandbox/glob.js +4 -4
- package/dist/tools/builtins/sandbox/grep.d.ts +7 -4
- package/dist/tools/builtins/sandbox/grep.js +147 -30
- package/dist/tools/builtins/sandbox/index.d.ts +3 -1
- package/dist/tools/builtins/sandbox/index.js +7 -1
- package/dist/tools/builtins/sandbox/read.d.ts +2 -2
- package/dist/tools/builtins/sandbox/read.js +21 -14
- package/dist/tools/builtins/sandbox/task-output.d.ts +63 -0
- package/dist/tools/builtins/sandbox/task-output.js +304 -0
- package/dist/tools/builtins/sandbox/task-stop.d.ts +10 -0
- package/dist/tools/builtins/sandbox/task-stop.js +112 -0
- package/dist/tools/builtins/sandbox/write.d.ts +1 -1
- package/dist/tools/builtins/sandbox/write.js +37 -33
- package/dist/tools/builtins/skill-load.d.ts +3 -3
- package/dist/tools/builtins/skill-load.js +32 -16
- package/dist/tools/builtins/skill-write.d.ts +4 -4
- package/dist/tools/builtins/skill-write.js +10 -10
- package/dist/tools/builtins/tool-search.d.ts +13 -9
- package/dist/tools/builtins/tool-search.js +25 -14
- package/dist/tools/builtins/web/errors.d.ts +8 -0
- package/dist/tools/builtins/web/errors.js +53 -0
- package/dist/tools/builtins/web/extract.d.ts +62 -0
- package/dist/tools/builtins/web/extract.js +267 -0
- package/dist/tools/builtins/web/fetch.d.ts +55 -0
- package/dist/tools/builtins/web/fetch.js +174 -0
- package/dist/tools/builtins/web/index.d.ts +13 -0
- package/dist/tools/builtins/web/index.js +12 -0
- package/dist/tools/builtins/web/page-cache.d.ts +25 -0
- package/dist/tools/builtins/web/page-cache.js +77 -0
- package/dist/tools/builtins/web/search.d.ts +25 -0
- package/dist/tools/builtins/web/search.js +209 -0
- package/dist/tools/builtins/web/url.d.ts +17 -0
- package/dist/tools/builtins/web/url.js +43 -0
- package/dist/tools/connectors.service.js +4 -4
- package/dist/tools/display-names.d.ts +9 -0
- package/dist/tools/display-names.js +24 -0
- package/dist/tools/drift.js +5 -5
- package/dist/tools/elicitation.js +1 -1
- package/dist/tools/info.d.ts +20 -4
- package/dist/tools/info.js +55 -32
- package/dist/tools/legacy-data.d.ts +34 -0
- package/dist/tools/legacy-data.js +76 -0
- package/dist/tools/legacy-keys.d.ts +51 -0
- package/dist/tools/legacy-keys.js +115 -0
- package/dist/tools/naming.d.ts +1 -5
- package/dist/tools/naming.js +1 -7
- package/dist/tools/oauth/flow-paths.d.ts +1 -1
- package/dist/tools/oauth/flow-paths.js +1 -1
- package/dist/tools/outputs.js +1 -1
- package/dist/tools/pipeline.d.ts +13 -7
- package/dist/tools/pipeline.js +112 -39
- package/dist/tools/policy.d.ts +1 -14
- package/dist/tools/policy.js +13 -19
- package/dist/tools/questions.controller.d.ts +1 -1
- package/dist/tools/questions.controller.js +1 -1
- package/dist/tools/questions.service.d.ts +1 -1
- package/dist/tools/registry.d.ts +38 -24
- package/dist/tools/registry.js +54 -47
- package/dist/tools/resources.d.ts +1 -1
- package/dist/tools/resources.js +1 -1
- package/dist/tools/tools.module.js +13 -1
- package/dist/tools/validate.js +1 -1
- package/package.json +3 -3
- package/src/migrations/0063_tool_keys_claude_code.sql +220 -0
- package/src/migrations/0064_account_last_org.sql +7 -0
- package/src/migrations/0065_conversation_archive.sql +8 -0
- package/src/migrations/0066_extension_display_name.sql +4 -0
- package/src/migrations/0067_agent_profiles.sql +20 -0
- package/src/migrations/0068_agent_avatar_uploads.sql +7 -0
- package/src/migrations/0069_attachments_agent_idx.sql +3 -0
- package/src/migrations/0070_background_tasks.sql +37 -0
- package/src/migrations/0071_background_tasks_reserve.sql +6 -0
- package/src/migrations/0072_background_tasks_stopping.sql +5 -0
- package/src/migrations/0073_org_extension_point_defaults.sql +11 -0
- package/dist/tools/builtins/sandbox/names.d.ts +0 -7
- package/dist/tools/builtins/sandbox/names.js +0 -20
|
@@ -14,6 +14,8 @@ export interface AccountsTable {
|
|
|
14
14
|
is_enterprise_admin: Generated<boolean>;
|
|
15
15
|
created_at: Ts;
|
|
16
16
|
updated_at: Ts;
|
|
17
|
+
/** 0064: the org the account last chose as current; a new session starts in it. */
|
|
18
|
+
last_org_id: ColumnType<string | null, string | null | undefined, string | null>;
|
|
17
19
|
}
|
|
18
20
|
export interface IdentitiesTable {
|
|
19
21
|
source: string;
|
|
@@ -149,6 +151,11 @@ export interface AgentsTable {
|
|
|
149
151
|
org_role: Generated<"admin" | "member" | "guest">;
|
|
150
152
|
current_version: number;
|
|
151
153
|
needs_reassignment: Generated<boolean>;
|
|
154
|
+
/** 0067: the profile (display data, outside the versions). */
|
|
155
|
+
profile_avatar: ColumnType<Record<string, unknown> | null, string | null | undefined, string | null>;
|
|
156
|
+
profile_description: Generated<string>;
|
|
157
|
+
profile_quick_actions: ColumnType<unknown[], string | undefined, string>;
|
|
158
|
+
profile_updated_at: Ts;
|
|
152
159
|
created_at: Ts;
|
|
153
160
|
updated_at: Ts;
|
|
154
161
|
deleted_at: TsNullable;
|
|
@@ -199,6 +206,10 @@ export interface ConversationsTable {
|
|
|
199
206
|
queue_paused: ColumnType<boolean, boolean | undefined, boolean>;
|
|
200
207
|
/** 0062: why the queue paused (`QueuePauseReason`); null when not paused or not recorded. */
|
|
201
208
|
queue_pause_reason: ColumnType<string | null, string | null | undefined, string | null>;
|
|
209
|
+
/** 0065: when the owner archived it (hidden from the default lists); null = not archived. */
|
|
210
|
+
archived_at: ColumnType<Date | null, Date | string | null | undefined, Date | string | null>;
|
|
211
|
+
/** 0065: when the owner deleted it (soft delete: hidden everywhere for the owner); null = live. */
|
|
212
|
+
deleted_at: ColumnType<Date | null, Date | string | null | undefined, Date | string | null>;
|
|
202
213
|
}
|
|
203
214
|
/** 0060: an org's order of file-preview@1 previewers (UI refresh B Task 11). */
|
|
204
215
|
export interface FilePreviewersTable {
|
|
@@ -208,6 +219,15 @@ export interface FilePreviewersTable {
|
|
|
208
219
|
position: number;
|
|
209
220
|
disabled: ColumnType<boolean, boolean | undefined, boolean>;
|
|
210
221
|
}
|
|
222
|
+
/** 0073: an org's default provider of an `org-default` extension point. */
|
|
223
|
+
export interface OrgExtensionPointDefaultsTable {
|
|
224
|
+
org_id: string;
|
|
225
|
+
/** The extension point name without the major (`web-search`). */
|
|
226
|
+
point: string;
|
|
227
|
+
extension: string;
|
|
228
|
+
updated_at: Ts;
|
|
229
|
+
updated_by: string | null;
|
|
230
|
+
}
|
|
211
231
|
/** 0059: a queued message (not in the event log until sent). */
|
|
212
232
|
export interface ConversationQueueTable {
|
|
213
233
|
id: string;
|
|
@@ -269,7 +289,7 @@ export interface RunsTable {
|
|
|
269
289
|
/** 0054: when this run's `subagents` wait expires (set while it waits on sub-agents). */
|
|
270
290
|
wait_expires_at: TsNullable;
|
|
271
291
|
}
|
|
272
|
-
/** 0053: one row per sub-agent dispatch (an `
|
|
292
|
+
/** 0053: one row per sub-agent dispatch (an `Agent` call of a parent run). */
|
|
273
293
|
export interface SubagentDispatchesTable {
|
|
274
294
|
parent_run_id: string;
|
|
275
295
|
parent_call_id: string;
|
|
@@ -400,7 +420,7 @@ export interface ApprovalsTable {
|
|
|
400
420
|
/** 0056: the reason given with a denial (null without one). */
|
|
401
421
|
deny_reason: Generated<string | null>;
|
|
402
422
|
}
|
|
403
|
-
/** 0010_tools.sql:
|
|
423
|
+
/** 0010_tools.sql:AskUserQuestion 提问。 */
|
|
404
424
|
export interface QuestionsTable {
|
|
405
425
|
id: string;
|
|
406
426
|
org_id: string;
|
|
@@ -547,9 +567,11 @@ export interface AttachmentsTable {
|
|
|
547
567
|
expires_at: TsNullable;
|
|
548
568
|
/** 0024:上传用途(技能包不能绑定到消息)。 */
|
|
549
569
|
purpose: ColumnType<AttachmentPurpose, AttachmentPurpose | undefined, AttachmentPurpose>;
|
|
570
|
+
/** 0068: the agent whose profile uses this avatar upload (set once, when it is saved). */
|
|
571
|
+
agent_id: ColumnType<string | null, string | null | undefined, string | null>;
|
|
550
572
|
}
|
|
551
|
-
/** 预签名上传的用途:对话附件 / 技能包 zip
|
|
552
|
-
export type AttachmentPurpose = "chat" | "skill-package";
|
|
573
|
+
/** 预签名上传的用途:对话附件 / 技能包 zip / agent avatar image. */
|
|
574
|
+
export type AttachmentPurpose = "chat" | "skill-package" | "agent-avatar";
|
|
553
575
|
/** 技能版本的清单(`skill_versions.manifest`)。 */
|
|
554
576
|
export interface SkillManifest {
|
|
555
577
|
name: string;
|
|
@@ -630,6 +652,33 @@ export interface SkillChangeRequestsTable {
|
|
|
630
652
|
decided_at: TsNullable;
|
|
631
653
|
created_at: Ts;
|
|
632
654
|
}
|
|
655
|
+
/** 0070_background_tasks.sql: a Bash command running in the background in a conversation's sandbox. */
|
|
656
|
+
export interface BackgroundTasksTable {
|
|
657
|
+
id: string;
|
|
658
|
+
org_id: string;
|
|
659
|
+
conversation_id: string;
|
|
660
|
+
sandbox_conversation_id: string;
|
|
661
|
+
run_id: string;
|
|
662
|
+
call_id: string;
|
|
663
|
+
trigger_account_id: string;
|
|
664
|
+
description: string;
|
|
665
|
+
command: string;
|
|
666
|
+
/** NULL while the launch is reserved but not started (0071). */
|
|
667
|
+
sid: string | null;
|
|
668
|
+
output_path: string;
|
|
669
|
+
status: ColumnType<"running" | "completed" | "failed" | "stopped" | "timed_out" | "lost", string | undefined, string>;
|
|
670
|
+
lost_reason: ColumnType<string | null, string | null | undefined, string | null>;
|
|
671
|
+
exit_code: ColumnType<number | null, number | null | undefined, number | null>;
|
|
672
|
+
started_at: Ts;
|
|
673
|
+
finished_at: TsNullable;
|
|
674
|
+
deadline_at: Date | string;
|
|
675
|
+
/** NULL while the launch is reserved but not started (0071). */
|
|
676
|
+
sandbox_created_at: Date | string | null;
|
|
677
|
+
kill_pending: ColumnType<boolean, boolean | undefined, boolean>;
|
|
678
|
+
read_offset: ColumnType<string, number | string | undefined, number | string>;
|
|
679
|
+
/** Set while a stop is under way (0072); the poller skips such a task. */
|
|
680
|
+
stopping_at: ColumnType<Date | null, Date | string | null | undefined, Date | string | null>;
|
|
681
|
+
}
|
|
633
682
|
/** 0023_sandboxes.sql:按对话的沙箱(见 sandbox/sandbox.service.ts)。 */
|
|
634
683
|
export interface SandboxesTable {
|
|
635
684
|
conversation_id: string;
|
|
@@ -788,6 +837,11 @@ export interface ExtensionPackagesTable {
|
|
|
788
837
|
source_ref: string;
|
|
789
838
|
uploaded_by: string | null;
|
|
790
839
|
created_at: Ts;
|
|
840
|
+
/** 0066: the plugin.json `displayName`; null without one and for packages stored before 0066. */
|
|
841
|
+
display_name: ColumnType<{
|
|
842
|
+
zh: string;
|
|
843
|
+
en: string;
|
|
844
|
+
} | null, string | null | undefined, string | null>;
|
|
791
845
|
}
|
|
792
846
|
/** 0030, renamed in 0041: package bytes when there is no object storage. */
|
|
793
847
|
export interface ExtensionBlobsTable {
|
|
@@ -867,6 +921,7 @@ export interface KernelDatabase {
|
|
|
867
921
|
conversation_events: ConversationEventsTable;
|
|
868
922
|
conversation_queue: ConversationQueueTable;
|
|
869
923
|
file_previewers: FilePreviewersTable;
|
|
924
|
+
org_extension_point_defaults: OrgExtensionPointDefaultsTable;
|
|
870
925
|
runs: RunsTable;
|
|
871
926
|
subagent_dispatches: SubagentDispatchesTable;
|
|
872
927
|
agent_templates: AgentTemplatesTable;
|
|
@@ -890,6 +945,7 @@ export interface KernelDatabase {
|
|
|
890
945
|
directory_exclusions: DirectoryExclusionsTable;
|
|
891
946
|
attachments: AttachmentsTable;
|
|
892
947
|
sandboxes: SandboxesTable;
|
|
948
|
+
background_tasks: BackgroundTasksTable;
|
|
893
949
|
skills: SkillsTable;
|
|
894
950
|
skill_versions: SkillVersionsTable;
|
|
895
951
|
skill_change_requests: SkillChangeRequestsTable;
|
package/dist/db/pool.d.ts
CHANGED
|
@@ -18,6 +18,11 @@ export declare function pgConnectOptions(cfg: {
|
|
|
18
18
|
*/
|
|
19
19
|
export declare function createDb(url: string, poolMax: number, onError?: (err: Error) => void, opts?: {
|
|
20
20
|
connectTimeoutMs?: number | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* How long an idle client stays in the pool (pg's `idleTimeoutMillis`; unset = pg's 10 s).
|
|
23
|
+
* Every new client costs a TCP + auth handshake, several round trips to a distant database.
|
|
24
|
+
*/
|
|
25
|
+
idleTimeoutMs?: number | undefined;
|
|
21
26
|
/**
|
|
22
27
|
* Error of a client while it is checked out: pg-pool drops its own listener on checkout, so
|
|
23
28
|
* without this a backend killed between two statements is an uncaught exception.
|
package/dist/db/pool.js
CHANGED
|
@@ -22,6 +22,9 @@ export function createDb(url, poolMax, onError = (err) => console.error("[db] id
|
|
|
22
22
|
connectionString: url,
|
|
23
23
|
max: poolMax,
|
|
24
24
|
...pgConnectOptions(opts),
|
|
25
|
+
...(opts.idleTimeoutMs !== undefined && { idleTimeoutMillis: opts.idleTimeoutMs }),
|
|
26
|
+
// a client kept idle longer must notice a dead peer (a dropped VPN, a NAT timeout) by itself
|
|
27
|
+
keepAlive: true,
|
|
25
28
|
});
|
|
26
29
|
pool.on("error", onError);
|
|
27
30
|
pool.on("connect", (client) => client.on("error", opts.onClientError ?? onError));
|
package/dist/errors.d.ts
CHANGED
|
@@ -110,7 +110,11 @@ export declare const ERROR_CODES: {
|
|
|
110
110
|
readonly "setup.token_invalid": 403;
|
|
111
111
|
readonly "agent.not_found": 404;
|
|
112
112
|
readonly "agent.version_conflict": 409;
|
|
113
|
+
/** The profile was changed since the client read it (`expectedUpdatedAt` is stale). */
|
|
114
|
+
readonly "agent.profile_conflict": 409;
|
|
113
115
|
readonly "agent.model_unavailable": 400;
|
|
116
|
+
/** A save gave `instructionFiles` and an `instructions` that is not their join. */
|
|
117
|
+
readonly "agent.instructions_mismatch": 400;
|
|
114
118
|
/**
|
|
115
119
|
* `skills.pinned` of an agent definition is refused (details: `{ skill, reason, totalBytes? }`;
|
|
116
120
|
* reasons `not_selected`, `not_found`, `duplicate`, `too_many`, `too_large`, `manual_only`).
|
|
@@ -130,6 +134,10 @@ export declare const ERROR_CODES: {
|
|
|
130
134
|
/** A sub-agent's conversation takes no messages from people (sub-agents spec §6.1). */
|
|
131
135
|
readonly "conversation.read_only": 409;
|
|
132
136
|
readonly "run.not_active": 409;
|
|
137
|
+
/** A background task that is not in this conversation (or its sub-agents), or does not exist. */
|
|
138
|
+
readonly "background_task.not_found": 404;
|
|
139
|
+
/** The task's output cannot be read now (its sandbox is not running and no finish recorded it). */
|
|
140
|
+
readonly "background_task.output_unavailable": 409;
|
|
133
141
|
readonly "connector.not_found": 404;
|
|
134
142
|
readonly "connector.slug_taken": 409;
|
|
135
143
|
readonly "connector.connect_failed": 502;
|
package/dist/errors.js
CHANGED
|
@@ -110,7 +110,11 @@ export const ERROR_CODES = {
|
|
|
110
110
|
"setup.token_invalid": 403,
|
|
111
111
|
"agent.not_found": 404,
|
|
112
112
|
"agent.version_conflict": 409,
|
|
113
|
+
/** The profile was changed since the client read it (`expectedUpdatedAt` is stale). */
|
|
114
|
+
"agent.profile_conflict": 409,
|
|
113
115
|
"agent.model_unavailable": 400,
|
|
116
|
+
/** A save gave `instructionFiles` and an `instructions` that is not their join. */
|
|
117
|
+
"agent.instructions_mismatch": 400,
|
|
114
118
|
/**
|
|
115
119
|
* `skills.pinned` of an agent definition is refused (details: `{ skill, reason, totalBytes? }`;
|
|
116
120
|
* reasons `not_selected`, `not_found`, `duplicate`, `too_many`, `too_large`, `manual_only`).
|
|
@@ -130,6 +134,10 @@ export const ERROR_CODES = {
|
|
|
130
134
|
/** A sub-agent's conversation takes no messages from people (sub-agents spec §6.1). */
|
|
131
135
|
"conversation.read_only": 409,
|
|
132
136
|
"run.not_active": 409,
|
|
137
|
+
/** A background task that is not in this conversation (or its sub-agents), or does not exist. */
|
|
138
|
+
"background_task.not_found": 404,
|
|
139
|
+
/** The task's output cannot be read now (its sandbox is not running and no finish recorded it). */
|
|
140
|
+
"background_task.output_unavailable": 409,
|
|
133
141
|
"connector.not_found": 404,
|
|
134
142
|
"connector.slug_taken": 409,
|
|
135
143
|
"connector.connect_failed": 502,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EventLog } from "../conversations/event-log.js";
|
|
2
|
+
import { type LegacyScope } from "../tools/legacy-keys.js";
|
|
2
3
|
import { type ToolPipeline, type ToolStepContext } from "../tools/pipeline.js";
|
|
3
4
|
import type { CaseSnapshot } from "./snapshot.js";
|
|
4
5
|
/**
|
|
@@ -15,12 +16,34 @@ export interface RecordedCall {
|
|
|
15
16
|
inputKey: string;
|
|
16
17
|
content: string;
|
|
17
18
|
isError: boolean;
|
|
18
|
-
/** 原结果里的 `
|
|
19
|
+
/** 原结果里的 `ToolSearch` 已加载工具(照抄:之后请求的已加载集合由日志还原)。 */
|
|
19
20
|
loadedTools?: string[];
|
|
20
21
|
contentTypes?: string[];
|
|
21
22
|
/** 原 `tool_call_started` 的定义指纹(没有开始事件的调用为空串)。 */
|
|
22
23
|
specHash: string;
|
|
24
|
+
/** The recorded call used release-candidate names; `toolKey` and `inputKey` are already the current ones. */
|
|
25
|
+
legacy?: true;
|
|
23
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* The connectors and extensions an rc `<x>__<tool>` key can name, from positive evidence in the
|
|
29
|
+
* snapshot only (a head with no evidence, or evidence of both kinds, stays unmapped, so its
|
|
30
|
+
* recorded calls are unmatched, which is a safe miss):
|
|
31
|
+
* - a connector: the tool definition the key was recorded with (`toolSpecs`, found by the specHash of
|
|
32
|
+
* its `tool_call_started` or its `model_call` tools / catalog entry) has `connectorData`;
|
|
33
|
+
* - an extension: that definition exists without `connectorData` and its name is the key's tool
|
|
34
|
+
* part, or an agent definition names exactly that tool as a `{ kind: "plugin", plugin: x, name }` ref.
|
|
35
|
+
*/
|
|
36
|
+
export declare function legacyScopeOf(s: CaseSnapshot): LegacyScope;
|
|
37
|
+
/**
|
|
38
|
+
* A recorded call in the current names: an rc builtin or `<x>__<tool>` key becomes its current
|
|
39
|
+
* key with the input's parameters renamed. Only the recorded side is ever normalized; a call
|
|
40
|
+
* already in current names (or one that cannot be mapped) is returned as is.
|
|
41
|
+
*/
|
|
42
|
+
export declare function currentCall(name: string, input: unknown, scope: LegacyScope): {
|
|
43
|
+
name: string;
|
|
44
|
+
input: unknown;
|
|
45
|
+
legacy: boolean;
|
|
46
|
+
};
|
|
24
47
|
/** 规范化 JSON:对象键递归按码点排序,数组保持顺序;`undefined` 按 JSON 规则省略。 */
|
|
25
48
|
export declare function canonicalJson(v: unknown): string;
|
|
26
49
|
/** The matching key of a call: the canonical JSON of its input without the ignored fields. */
|
|
@@ -43,7 +66,10 @@ export declare class RecordedToolPipeline implements Pick<ToolPipeline, "runStep
|
|
|
43
66
|
private readonly d;
|
|
44
67
|
private readonly used;
|
|
45
68
|
private misses;
|
|
69
|
+
private legacyHits;
|
|
46
70
|
constructor(d: RecordedToolPipelineDeps);
|
|
71
|
+
/** Calls so far matched with a recording made under release-candidate tool names. */
|
|
72
|
+
legacyMatches(): number;
|
|
47
73
|
/** 至今没有匹配到记录的调用数。 */
|
|
48
74
|
unmatched(): number;
|
|
49
75
|
runStep(ctx: ToolStepContext): Promise<{
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { assistantIdemKey } from "../runtime/model-call.js";
|
|
2
|
+
import { MATCH_IGNORED_FIELDS } from "../tools/builtin-names.js";
|
|
3
|
+
import { isLegacyPrefixedKey, legacyToolInput, legacyToolKey, } from "../tools/legacy-keys.js";
|
|
2
4
|
import { RUN_STOPPED_TEXT } from "../tools/pipeline.js";
|
|
3
5
|
/**
|
|
4
6
|
* 整轮回放的工具管线(C6 / Review Focus 3):只回放原运行记录的工具结果,**从不执行任何工具**——
|
|
@@ -7,6 +9,77 @@ import { RUN_STOPPED_TEXT } from "../tools/pipeline.js";
|
|
|
7
9
|
*/
|
|
8
10
|
/** 没有匹配记录时模型看到的工具结果(模型可见,英文)。 */
|
|
9
11
|
export const REPLAY_NO_RECORDING = "[replay] No recorded result matches this tool call (same tool and arguments); the tool was not executed during replay.";
|
|
12
|
+
/**
|
|
13
|
+
* The connectors and extensions an rc `<x>__<tool>` key can name, from positive evidence in the
|
|
14
|
+
* snapshot only (a head with no evidence, or evidence of both kinds, stays unmapped, so its
|
|
15
|
+
* recorded calls are unmatched, which is a safe miss):
|
|
16
|
+
* - a connector: the tool definition the key was recorded with (`toolSpecs`, found by the specHash of
|
|
17
|
+
* its `tool_call_started` or its `model_call` tools / catalog entry) has `connectorData`;
|
|
18
|
+
* - an extension: that definition exists without `connectorData` and its name is the key's tool
|
|
19
|
+
* part, or an agent definition names exactly that tool as a `{ kind: "plugin", plugin: x, name }` ref.
|
|
20
|
+
*/
|
|
21
|
+
export function legacyScopeOf(s) {
|
|
22
|
+
const hashes = new Map();
|
|
23
|
+
const note = (key, hash) => {
|
|
24
|
+
if (!isLegacyPrefixedKey(key))
|
|
25
|
+
return;
|
|
26
|
+
const set = hashes.get(key) ?? new Set();
|
|
27
|
+
if (hash !== undefined && hash !== "")
|
|
28
|
+
set.add(hash);
|
|
29
|
+
hashes.set(key, set);
|
|
30
|
+
};
|
|
31
|
+
for (const e of s.events) {
|
|
32
|
+
if (e.type === "tool_call_started") {
|
|
33
|
+
const p = e.payload;
|
|
34
|
+
note(p.toolKey, p.specHash);
|
|
35
|
+
}
|
|
36
|
+
else if (e.type === "model_call") {
|
|
37
|
+
const r = e.payload.request;
|
|
38
|
+
for (const t of [...(r?.tools ?? []), ...(r?.catalog ?? [])])
|
|
39
|
+
note(t.key, t.specHash);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const extensionNames = new Set();
|
|
43
|
+
const connectorSlugs = new Set();
|
|
44
|
+
const planted = new Set();
|
|
45
|
+
for (const def of Object.values(s.definitions)) {
|
|
46
|
+
for (const t of def.tools)
|
|
47
|
+
if (t.kind === "plugin")
|
|
48
|
+
planted.add(`${t.plugin}__${t.name}`);
|
|
49
|
+
}
|
|
50
|
+
for (const [key, set] of hashes) {
|
|
51
|
+
const i = key.indexOf("__");
|
|
52
|
+
const head = key.slice(0, i);
|
|
53
|
+
const tool = key.slice(i + 2);
|
|
54
|
+
for (const h of set) {
|
|
55
|
+
const spec = s.toolSpecs[h];
|
|
56
|
+
if (spec === undefined)
|
|
57
|
+
continue;
|
|
58
|
+
if (spec.connectorData !== undefined) {
|
|
59
|
+
connectorSlugs.add(head);
|
|
60
|
+
}
|
|
61
|
+
else if (spec.name === tool) {
|
|
62
|
+
extensionNames.add(head);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
for (const key of planted) {
|
|
67
|
+
if (hashes.has(key))
|
|
68
|
+
extensionNames.add(key.slice(0, key.indexOf("__")));
|
|
69
|
+
}
|
|
70
|
+
return { connectorSlugs, extensionNames };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* A recorded call in the current names: an rc builtin or `<x>__<tool>` key becomes its current
|
|
74
|
+
* key with the input's parameters renamed. Only the recorded side is ever normalized; a call
|
|
75
|
+
* already in current names (or one that cannot be mapped) is returned as is.
|
|
76
|
+
*/
|
|
77
|
+
export function currentCall(name, input, scope) {
|
|
78
|
+
const key = legacyToolKey(name, scope);
|
|
79
|
+
if (key === null)
|
|
80
|
+
return { name, input, legacy: false };
|
|
81
|
+
return { name: key, input: legacyToolInput(name, input), legacy: true };
|
|
82
|
+
}
|
|
10
83
|
/** 规范化 JSON:对象键递归按码点排序,数组保持顺序;`undefined` 按 JSON 规则省略。 */
|
|
11
84
|
export function canonicalJson(v) {
|
|
12
85
|
const norm = (x) => {
|
|
@@ -23,14 +96,6 @@ export function canonicalJson(v) {
|
|
|
23
96
|
};
|
|
24
97
|
return JSON.stringify(norm(v) ?? null);
|
|
25
98
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Input fields left out when matching, per tool: display-only arguments the model writes that do not
|
|
28
|
-
* change what the tool does. `sandbox_bash`'s `description` became required in UI refresh B, so a
|
|
29
|
-
* recording without it and a replayed call with one (or a different wording) still match.
|
|
30
|
-
*/
|
|
31
|
-
const MATCH_IGNORED_FIELDS = {
|
|
32
|
-
sandbox_bash: ["description"],
|
|
33
|
-
};
|
|
34
99
|
/** The matching key of a call: the canonical JSON of its input without the ignored fields. */
|
|
35
100
|
export function matchKey(toolKey, input) {
|
|
36
101
|
const ignored = MATCH_IGNORED_FIELDS[toolKey];
|
|
@@ -64,6 +129,7 @@ export function recordedCalls(s) {
|
|
|
64
129
|
started.set(p.callId, p.specHash);
|
|
65
130
|
}
|
|
66
131
|
}
|
|
132
|
+
const scope = legacyScopeOf(s);
|
|
67
133
|
const out = [];
|
|
68
134
|
for (const e of own) {
|
|
69
135
|
if (e.type !== "assistant_message")
|
|
@@ -76,9 +142,11 @@ export function recordedCalls(s) {
|
|
|
76
142
|
const r = results.get(call.id);
|
|
77
143
|
if (!r)
|
|
78
144
|
continue;
|
|
145
|
+
const cur = currentCall(call.name, call.input, scope);
|
|
79
146
|
out.push({
|
|
80
|
-
toolKey:
|
|
81
|
-
inputKey: matchKey(
|
|
147
|
+
toolKey: cur.name,
|
|
148
|
+
inputKey: matchKey(cur.name, cur.input),
|
|
149
|
+
...(cur.legacy && { legacy: true }),
|
|
82
150
|
content: r.content,
|
|
83
151
|
isError: r.isError,
|
|
84
152
|
...(r.loadedTools !== undefined && { loadedTools: r.loadedTools }),
|
|
@@ -98,9 +166,14 @@ export class RecordedToolPipeline {
|
|
|
98
166
|
d;
|
|
99
167
|
used = new Set();
|
|
100
168
|
misses = 0;
|
|
169
|
+
legacyHits = 0;
|
|
101
170
|
constructor(d) {
|
|
102
171
|
this.d = d;
|
|
103
172
|
}
|
|
173
|
+
/** Calls so far matched with a recording made under release-candidate tool names. */
|
|
174
|
+
legacyMatches() {
|
|
175
|
+
return this.legacyHits;
|
|
176
|
+
}
|
|
104
177
|
/** 至今没有匹配到记录的调用数。 */
|
|
105
178
|
unmatched() {
|
|
106
179
|
return this.misses;
|
|
@@ -162,6 +235,8 @@ export class RecordedToolPipeline {
|
|
|
162
235
|
if (i < 0)
|
|
163
236
|
return undefined;
|
|
164
237
|
this.used.add(i);
|
|
238
|
+
if (this.d.recordings[i]?.legacy === true)
|
|
239
|
+
this.legacyHits++;
|
|
165
240
|
return this.d.recordings[i];
|
|
166
241
|
}
|
|
167
242
|
}
|
|
@@ -19,7 +19,10 @@ import type { ResolvedCandidate } from "./step-replay.js";
|
|
|
19
19
|
*
|
|
20
20
|
* - 种子:原运行 `run_started` 之前的事件按原 seq 插入(`last_seq` 停在其前一位,新的 `run_started` 因此与原来同 seq),
|
|
21
21
|
* 原运行开始时的 `skills_catalog` 照抄;然后写 `runs` 行与 `run_started`,`agent` 用候选定义。
|
|
22
|
-
* -
|
|
22
|
+
* - 插话:原运行中途吸收的可吸收事件(user_message, and finished background tasks: background Bash
|
|
23
|
+
* spec §4.4),在「原吸收步骤 ≤ 当前步骤」时追加进评测对话并交给 loop(a recorded finish is
|
|
24
|
+
* appended as recorded: no task starts, polls or stops)。
|
|
25
|
+
* - A wake run (its boundary a finished background task, not a message) is seeded from that event.
|
|
23
26
|
* - 计费(C7,与单步回放同一套):每次模型请求(含压缩、重试、兜底)发出前查运行仍在执行、仍持有认领;
|
|
24
27
|
* 收完按真实用量、没收完按估算 `consumeTokens`(越限即 `capped`,下一次请求前停下)。
|
|
25
28
|
* - 附件按快照自己的组织与原对话取(C3)。
|
|
@@ -37,6 +40,11 @@ export interface RunReplayResult {
|
|
|
37
40
|
usage: ModelUsage;
|
|
38
41
|
steps: number;
|
|
39
42
|
unmatched: number;
|
|
43
|
+
/**
|
|
44
|
+
* Set when a call was matched with a recording made under the release-candidate tool names
|
|
45
|
+
* (`sandbox_edit` for `Edit`, `docs__search` for `mcp__docs__search`, old parameter names).
|
|
46
|
+
*/
|
|
47
|
+
legacyKeyMatch?: true;
|
|
40
48
|
}
|
|
41
49
|
/** 原运行(基线)的同形摘要。 */
|
|
42
50
|
export type RunBaseline = Omit<RunReplayResult, "conversationId" | "outcome" | "unmatched">;
|
|
@@ -96,7 +104,7 @@ export interface ReplaySeed {
|
|
|
96
104
|
/** The conversation's `consumed_seq` when the original run started. */
|
|
97
105
|
consumed: number;
|
|
98
106
|
seeds: SnapshotEvent[];
|
|
99
|
-
/** The run's trigger seq (the last
|
|
107
|
+
/** The run's trigger seq (its boundary: the last unconsumed message, or the waking finish). */
|
|
100
108
|
trigger: number;
|
|
101
109
|
agentVersion: number;
|
|
102
110
|
model: ModelRef;
|
package/dist/evals/run-replay.js
CHANGED
|
@@ -13,6 +13,7 @@ import { Inject, Injectable } from "@nestjs/common";
|
|
|
13
13
|
import { sql } from "kysely";
|
|
14
14
|
import { normalizeStoredDefinition } from "../agents/definition.js";
|
|
15
15
|
import { EventLog } from "../conversations/event-log.js";
|
|
16
|
+
import { isAbsorbable, } from "../conversations/events.js";
|
|
16
17
|
import { ApiError } from "../errors.js";
|
|
17
18
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
18
19
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
@@ -22,7 +23,7 @@ import { RunError } from "../runtime/model-call.js";
|
|
|
22
23
|
import { recordedSkillForks } from "../runtime/subagents/skill-fork.js";
|
|
23
24
|
import { skillsCatalogIdemKey } from "../skills/catalog.js";
|
|
24
25
|
import { ACTIVE_EVAL_STATUSES, addUsage, consumeTokens, TOO_MANY_ERRORS, usageTokens, } from "./budget.js";
|
|
25
|
-
import { RecordedToolPipeline, recordedCalls } from "./recorded-tools.js";
|
|
26
|
+
import { currentCall, legacyScopeOf, RecordedToolPipeline, recordedCalls, } from "./recorded-tools.js";
|
|
26
27
|
/** 写种子时发现已失去认领或运行已不在执行:本次执行停下,不留评测对话。 */
|
|
27
28
|
export class ReplayClaimLost extends Error {
|
|
28
29
|
constructor() {
|
|
@@ -177,7 +178,7 @@ const ZERO = {
|
|
|
177
178
|
cacheWriteTokens: 0,
|
|
178
179
|
};
|
|
179
180
|
/** 一次运行的工具调用序列、最后的回复、停止原因、用量与步数(基线与候选同一算法)。 */
|
|
180
|
-
function summarize(events, runId) {
|
|
181
|
+
function summarize(events, runId, scope) {
|
|
181
182
|
const toolCalls = [];
|
|
182
183
|
let usage = ZERO;
|
|
183
184
|
let last = null;
|
|
@@ -189,8 +190,14 @@ function summarize(events, runId) {
|
|
|
189
190
|
const p = e.payload;
|
|
190
191
|
steps.add(p.step);
|
|
191
192
|
for (const b of p.content) {
|
|
192
|
-
if (b.type
|
|
193
|
+
if (b.type !== "tool_call")
|
|
194
|
+
continue;
|
|
195
|
+
if (scope === undefined)
|
|
193
196
|
toolCalls.push({ name: b.name, input: b.input });
|
|
197
|
+
else {
|
|
198
|
+
const { name, input } = currentCall(b.name, b.input, scope);
|
|
199
|
+
toolCalls.push({ name, input });
|
|
200
|
+
}
|
|
194
201
|
}
|
|
195
202
|
last = { content: p.content, stopReason: p.stopReason };
|
|
196
203
|
}
|
|
@@ -214,7 +221,9 @@ function summarize(events, runId) {
|
|
|
214
221
|
}
|
|
215
222
|
/** 原运行(快照)的摘要,作为整轮回放的基线。 */
|
|
216
223
|
export function runBaseline(s) {
|
|
217
|
-
|
|
224
|
+
// an rc recording is read in the current tool names, so the diff against a candidate only
|
|
225
|
+
// shows real differences
|
|
226
|
+
return summarize(s.events, s.runId, legacyScopeOf(s));
|
|
218
227
|
}
|
|
219
228
|
/**
|
|
220
229
|
* 删掉一个评测对话(崩溃重跑前清掉上一次的残留):先删它各次运行的 checkpoint,再删对话(事件、运行随之级联删除)。
|
|
@@ -252,6 +261,28 @@ function absorbedByStep(s) {
|
|
|
252
261
|
}
|
|
253
262
|
return out;
|
|
254
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* The replayed run's boundary (`trigger_seq`): a wake run's recorded one (`run_started.triggerSeq`,
|
|
266
|
+
* background Bash spec §3); otherwise the newest message after `consumed`, else the newest finish
|
|
267
|
+
* after it that could have woken the run (not reported, no `stoppedBy`), else the last
|
|
268
|
+
* message (old logs, as before).
|
|
269
|
+
*/
|
|
270
|
+
function replayTrigger(started, seeds, consumed) {
|
|
271
|
+
const recorded = started;
|
|
272
|
+
if (recorded.trigger === "background_task" && recorded.triggerSeq !== undefined) {
|
|
273
|
+
return recorded.triggerSeq;
|
|
274
|
+
}
|
|
275
|
+
const lastMessage = seeds.findLast((e) => e.type === "user_message")?.seq;
|
|
276
|
+
if (lastMessage !== undefined && lastMessage > consumed)
|
|
277
|
+
return lastMessage;
|
|
278
|
+
const wake = seeds.findLast((e) => {
|
|
279
|
+
if (e.type !== "background_task_finished" || e.seq <= consumed)
|
|
280
|
+
return false;
|
|
281
|
+
const p = e.payload;
|
|
282
|
+
return !p.reported && p.stoppedBy === undefined;
|
|
283
|
+
})?.seq;
|
|
284
|
+
return wake ?? lastMessage ?? 0;
|
|
285
|
+
}
|
|
255
286
|
const readAll = async (eventLog, conversationId) => {
|
|
256
287
|
const out = [];
|
|
257
288
|
let after = 0;
|
|
@@ -286,7 +317,7 @@ export async function replayRun(d, s, candidate, evalRunId, signal) {
|
|
|
286
317
|
consumed = Math.max(consumed, e.payload.consumedUpToSeq);
|
|
287
318
|
}
|
|
288
319
|
}
|
|
289
|
-
const trigger =
|
|
320
|
+
const trigger = replayTrigger(start.payload, seeds, consumed);
|
|
290
321
|
const catalog = s.events.find((e) => e.runId === s.runId && e.type === "skills_catalog" && e.seq > R);
|
|
291
322
|
// a sub-agent's case (spec §15.3) runs the effective definition frozen in its subagent_started
|
|
292
323
|
// (the request renders that event's preamble and instructions; its tools come from it too), with
|
|
@@ -419,7 +450,7 @@ export async function replayRun(d, s, candidate, evalRunId, signal) {
|
|
|
419
450
|
return "stop";
|
|
420
451
|
},
|
|
421
452
|
});
|
|
422
|
-
//
|
|
453
|
+
// 插话:原运行开始之后到达、且被原运行某一步吸收的可吸收事件(user_message / background_task_finished)
|
|
423
454
|
const absorbed = absorbedByStep(s);
|
|
424
455
|
const stepsInOrder = [...absorbed.keys()].sort((a, b) => a - b);
|
|
425
456
|
/** 第 k 步(含)之前原运行吸收到的最大位置;原运行没有模型调用时不设限。 */
|
|
@@ -434,7 +465,7 @@ export async function replayRun(d, s, candidate, evalRunId, signal) {
|
|
|
434
465
|
return cap;
|
|
435
466
|
};
|
|
436
467
|
const interjections = s.events
|
|
437
|
-
.filter((e) => e.type === "user_message" && e.seq > R)
|
|
468
|
+
.filter((e) => (e.type === "user_message" || e.type === "background_task_finished") && e.seq > R)
|
|
438
469
|
.flatMap((e) => {
|
|
439
470
|
const step = stepsInOrder.find((k) => absorbed.get(k) >= e.seq);
|
|
440
471
|
return step === undefined ? [] : [{ event: e, step }];
|
|
@@ -442,7 +473,7 @@ export async function replayRun(d, s, candidate, evalRunId, signal) {
|
|
|
442
473
|
/** 已追加的插话:原 seq → 评测对话里的 seq。 */
|
|
443
474
|
const fed = new Map();
|
|
444
475
|
let prepared = 0;
|
|
445
|
-
const
|
|
476
|
+
const pendingAbsorbable = async (afterSeq) => {
|
|
446
477
|
prepared++;
|
|
447
478
|
// loop 的步骤从 1 起(与运行时相同),每步的 prepare 调用一次:第 n 次调用即第 n 步
|
|
448
479
|
const k = prepared;
|
|
@@ -451,7 +482,7 @@ export async function replayRun(d, s, candidate, evalRunId, signal) {
|
|
|
451
482
|
continue;
|
|
452
483
|
const [w] = await eventLog.append(conversationId, [
|
|
453
484
|
{
|
|
454
|
-
type:
|
|
485
|
+
type: x.event.type,
|
|
455
486
|
idemKey: `replay_interjection:${runId}:${x.event.seq}`,
|
|
456
487
|
payload: x.event.payload,
|
|
457
488
|
},
|
|
@@ -463,7 +494,7 @@ export async function replayRun(d, s, candidate, evalRunId, signal) {
|
|
|
463
494
|
const fedSeqs = new Set(fed.values());
|
|
464
495
|
const out = [];
|
|
465
496
|
for (const e of await readAll(eventLog, conversationId)) {
|
|
466
|
-
if (e
|
|
497
|
+
if (!isAbsorbable(e) || e.seq <= afterSeq)
|
|
467
498
|
continue;
|
|
468
499
|
if (fedSeqs.has(e.seq) || (e.seq < R && e.seq <= cap))
|
|
469
500
|
out.push(e);
|
|
@@ -494,7 +525,7 @@ export async function replayRun(d, s, candidate, evalRunId, signal) {
|
|
|
494
525
|
signal: loopSignal,
|
|
495
526
|
shutdown: new AbortController().signal,
|
|
496
527
|
sink: () => { },
|
|
497
|
-
|
|
528
|
+
pendingAbsorbable,
|
|
498
529
|
limits: {
|
|
499
530
|
maxSteps: subagent === undefined ? runtime.maxSteps : Math.min(subagent.maxSteps, runtime.maxSteps),
|
|
500
531
|
deadline,
|
|
@@ -558,5 +589,11 @@ export async function replayRun(d, s, candidate, evalRunId, signal) {
|
|
|
558
589
|
});
|
|
559
590
|
await Promise.allSettled([...charges]);
|
|
560
591
|
const summary = summarize(await readAll(eventLog, conversationId), runId);
|
|
561
|
-
return {
|
|
592
|
+
return {
|
|
593
|
+
conversationId,
|
|
594
|
+
outcome: outcome.kind,
|
|
595
|
+
...summary,
|
|
596
|
+
unmatched: pipeline.unmatched(),
|
|
597
|
+
...(pipeline.legacyMatches() > 0 && { legacyKeyMatch: true }),
|
|
598
|
+
};
|
|
562
599
|
}
|
|
@@ -54,10 +54,9 @@ subagent) {
|
|
|
54
54
|
? { ...(from.modelParams ?? {}) }
|
|
55
55
|
: {});
|
|
56
56
|
const definition = {
|
|
57
|
-
...from,
|
|
57
|
+
...withInstructions(from, c.instructions),
|
|
58
58
|
model,
|
|
59
59
|
modelParams: params,
|
|
60
|
-
...(c.instructions !== undefined && { instructions: c.instructions }),
|
|
61
60
|
};
|
|
62
61
|
const changed = agentVersion !== base.agentVersion ||
|
|
63
62
|
!sameModel(model, base.definition.model) ||
|
|
@@ -73,13 +72,20 @@ subagent) {
|
|
|
73
72
|
changed,
|
|
74
73
|
overridesSwitch,
|
|
75
74
|
...(otherVersion && {
|
|
76
|
-
subagentVersion:
|
|
77
|
-
...versionDef,
|
|
78
|
-
...(c.instructions !== undefined && { instructions: c.instructions }),
|
|
79
|
-
},
|
|
75
|
+
subagentVersion: withInstructions(versionDef, c.instructions),
|
|
80
76
|
}),
|
|
81
77
|
};
|
|
82
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* A candidate's `instructions` override: the prompt files it was joined from no longer describe
|
|
81
|
+
* it, so they are dropped (never model-visible either way).
|
|
82
|
+
*/
|
|
83
|
+
function withInstructions(def, instructions) {
|
|
84
|
+
if (instructions === undefined)
|
|
85
|
+
return def;
|
|
86
|
+
const { instructionFiles: _files, ...rest } = def;
|
|
87
|
+
return { ...rest, instructions };
|
|
88
|
+
}
|
|
83
89
|
/**
|
|
84
90
|
* 候选请求已经发出、但没有正常收完(出错、超时、中止):`tokens` 是这次尝试应计入预算的估算用量,
|
|
85
91
|
* `cause` 是原始错误(调用方按它分类重试)。请求发出之前的失败(解析模型、取附件)原样抛出,不计费。
|
|
@@ -54,7 +54,7 @@ export interface TrajectoryToolCall {
|
|
|
54
54
|
byAccountId: string | null;
|
|
55
55
|
decidedAt: string | null;
|
|
56
56
|
} | null;
|
|
57
|
-
/** 最近一次输入请求(`
|
|
57
|
+
/** 最近一次输入请求(`AskUserQuestion`、插件 `input_required`、MCP elicitation)。 */
|
|
58
58
|
question: {
|
|
59
59
|
questionId: string;
|
|
60
60
|
askedAt: string;
|
|
@@ -64,7 +64,7 @@ export interface TrajectoryToolCall {
|
|
|
64
64
|
/** A `tool.preExecute` policy hook denied the call (it never started). */
|
|
65
65
|
hookDenied?: TrajectoryHookDenial;
|
|
66
66
|
/**
|
|
67
|
-
* An `
|
|
67
|
+
* An `Agent` call that dispatched (or resumed) a sub-agent (phase C, spec §15.4): the child
|
|
68
68
|
* conversation (`subagentId`, whose trajectory the viewer links to), the run it started and that
|
|
69
69
|
* run's end (`running` until its `subagent_finished`).
|
|
70
70
|
*/
|
package/dist/evals/trajectory.js
CHANGED
|
@@ -130,7 +130,7 @@ function buildRun({ started, events }, prices, forks) {
|
|
|
130
130
|
assistants.set(e.payload.step, [...(assistants.get(e.payload.step) ?? []), e]);
|
|
131
131
|
break;
|
|
132
132
|
case "usage":
|
|
133
|
-
// a compaction or
|
|
133
|
+
// a compaction, title or web_fetch call's usage is not a step call's: counted in the totals only (I-1)
|
|
134
134
|
if (e.payload.purpose !== undefined) {
|
|
135
135
|
compactions.push(e);
|
|
136
136
|
break;
|