@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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isAgentVisibleTo } from "../../agents/agent-lookup.js";
|
|
2
2
|
import { normalizeStoredDefinition } from "../../agents/definition.js";
|
|
3
3
|
import { audit } from "../../identity/audit.js";
|
|
4
|
+
import { normalizeStoredDefinitionIn } from "../../tools/legacy-data.js";
|
|
4
5
|
/**
|
|
5
6
|
* Checks the gates for dispatching `agentId` from a parent whose current definition is
|
|
6
7
|
* `parentDefinition` (read live by the caller: R5, removing an allowlist entry stops new
|
|
@@ -23,7 +24,7 @@ export async function checkOrgAgent(db, a) {
|
|
|
23
24
|
if (!(a.parentDefinition.subagents?.agents ?? []).some((x) => x.agentId === a.agentId)) {
|
|
24
25
|
return { ok: false, gate: "allowlist" };
|
|
25
26
|
}
|
|
26
|
-
const definition =
|
|
27
|
+
const definition = await normalizeStoredDefinitionIn(db, a.orgId, row.definition);
|
|
27
28
|
if (definition.subagents?.dispatchable !== true)
|
|
28
29
|
return { ok: false, gate: "dispatchable" };
|
|
29
30
|
if (!(await isAgentVisibleTo(db, a.agentId, a.triggerAccountId))) {
|
|
@@ -45,7 +45,7 @@ export declare const isGeneralAlias: (agent: string) => boolean;
|
|
|
45
45
|
* `general-purpose` for no `agent` and Claude's built-in types; else a roster type (a bare name
|
|
46
46
|
* prefers the skill's own plugin's template `<plugin>:<name>`, then {@link findType}). An `agent`
|
|
47
47
|
* that does not resolve falls back to `general-purpose` and is returned as `unknown`. `inRoster`:
|
|
48
|
-
* the type is one the parent's `
|
|
48
|
+
* the type is one the parent's `Agent` tool offers (`general-purpose` is not when
|
|
49
49
|
* `subagents.general === false`, which does not block a person's fork invocation).
|
|
50
50
|
*/
|
|
51
51
|
export declare function resolveSkillForkType(db: KernelSchemaDb, orgId: string, parent: Pick<AgentDefinition, "subagents">, agent: string | undefined, plugin: string | undefined): Promise<{
|
|
@@ -90,7 +90,7 @@ export const isGeneralAlias = (agent) => GENERAL_ALIASES.has(agent);
|
|
|
90
90
|
* `general-purpose` for no `agent` and Claude's built-in types; else a roster type (a bare name
|
|
91
91
|
* prefers the skill's own plugin's template `<plugin>:<name>`, then {@link findType}). An `agent`
|
|
92
92
|
* that does not resolve falls back to `general-purpose` and is returned as `unknown`. `inRoster`:
|
|
93
|
-
* the type is one the parent's `
|
|
93
|
+
* the type is one the parent's `Agent` tool offers (`general-purpose` is not when
|
|
94
94
|
* `subagents.general === false`, which does not block a person's fork invocation).
|
|
95
95
|
*/
|
|
96
96
|
export async function resolveSkillForkType(db, orgId, parent, agent, plugin) {
|
|
@@ -8,7 +8,7 @@ import { type DispatchDeps } from "./dispatch.js";
|
|
|
8
8
|
/**
|
|
9
9
|
* Forked skills (phase D spec §6): a person's invocation of a `context: fork` skill starts its own
|
|
10
10
|
* run (the run boundary, {@link forkBoundary}), whose `prepare` node dispatches the sub-agent
|
|
11
|
-
* through phase C's `dispatchSubagent` before any model call and waits on it like an `
|
|
11
|
+
* through phase C's `dispatchSubagent` before any model call and waits on it like an `Agent` call
|
|
12
12
|
* (`subagents` wait `sa-<runId>-0`). When the child has ended, `prepare` appends the model-visible
|
|
13
13
|
* `skill_fork_result` and the parent's model answers. Every terminal path of the run (and the wait
|
|
14
14
|
* sweep) pairs a fork invocation without a report ({@link pairStoppedForks}), so the log never holds
|
|
@@ -110,7 +110,7 @@ export declare const recordedSkillForks: (eventLog: Pick<EventLog, "append" | "f
|
|
|
110
110
|
* In the transaction of a run's terminal path (or the wait sweep): the run's fork invocation
|
|
111
111
|
* (its trigger message, by the run boundary) without a report gets one now: the ended child's
|
|
112
112
|
* result (and the parent's missing `subagent_finished`), {@link AGENT_STOPPED_WITH_RUN_TEXT} for a
|
|
113
|
-
* child still active (the caller stops it after its commit, as for `
|
|
113
|
+
* child still active (the caller stops it after its commit, as for `Agent` calls), or
|
|
114
114
|
* {@link FORK_NOT_STARTED_TEXT} when nothing was dispatched. Returns the call ids written
|
|
115
115
|
* (`skill-<seq>`) and the highest seq; the caller notifies after its commit.
|
|
116
116
|
*/
|
|
@@ -7,7 +7,7 @@ import { dispatchSubagent } from "./dispatch.js";
|
|
|
7
7
|
/**
|
|
8
8
|
* Forked skills (phase D spec §6): a person's invocation of a `context: fork` skill starts its own
|
|
9
9
|
* run (the run boundary, {@link forkBoundary}), whose `prepare` node dispatches the sub-agent
|
|
10
|
-
* through phase C's `dispatchSubagent` before any model call and waits on it like an `
|
|
10
|
+
* through phase C's `dispatchSubagent` before any model call and waits on it like an `Agent` call
|
|
11
11
|
* (`subagents` wait `sa-<runId>-0`). When the child has ended, `prepare` appends the model-visible
|
|
12
12
|
* `skill_fork_result` and the parent's model answers. Every terminal path of the run (and the wait
|
|
13
13
|
* sweep) pairs a fork invocation without a report ({@link pairStoppedForks}), so the log never holds
|
|
@@ -190,7 +190,7 @@ export const recordedSkillForks = (eventLog, recorded) => ({
|
|
|
190
190
|
* In the transaction of a run's terminal path (or the wait sweep): the run's fork invocation
|
|
191
191
|
* (its trigger message, by the run boundary) without a report gets one now: the ended child's
|
|
192
192
|
* result (and the parent's missing `subagent_finished`), {@link AGENT_STOPPED_WITH_RUN_TEXT} for a
|
|
193
|
-
* child still active (the caller stops it after its commit, as for `
|
|
193
|
+
* child still active (the caller stops it after its commit, as for `Agent` calls), or
|
|
194
194
|
* {@link FORK_NOT_STARTED_TEXT} when nothing was dispatched. Returns the call ids written
|
|
195
195
|
* (`skill-<seq>`) and the highest seq; the caller notifies after its commit.
|
|
196
196
|
*/
|
|
@@ -12,7 +12,7 @@ import { type ChildWriter, type DispatchArgs, type DispatchCommit, type Dispatch
|
|
|
12
12
|
import { type SubagentStep } from "./progress.js";
|
|
13
13
|
import { type SkillForkDeps, type SkillForks } from "./skill-fork.js";
|
|
14
14
|
/**
|
|
15
|
-
* Sub-agents (phase C, spec §7) and forked skills (phase D): the `
|
|
15
|
+
* Sub-agents (phase C, spec §7) and forked skills (phase D): the `Agent` tool's dispatch (the
|
|
16
16
|
* tool pipeline calls {@link dispatch}), a run's fork invocation ({@link skillForks}, the loop's
|
|
17
17
|
* `prepare`) and a child step's progress on the parent's stream ({@link progress}). Child runs go
|
|
18
18
|
* to the sub-agent run queue through {@link RunJobs}. The child lifecycle after dispatch (a
|
|
@@ -28,13 +28,13 @@ export declare class SubagentsService {
|
|
|
28
28
|
/** The live fork handler of the loop (`LoopDeps.skillForks`). */
|
|
29
29
|
readonly skillForks: SkillForks;
|
|
30
30
|
constructor(kdb: KernelDb, eventLog: EventLog, purposes: ModelPurposesService, registry: ProviderRegistry, config: KernelConfigService, jobs: RunJobs, invoker: SkillInvoker, bus: ExtensionContext["bus"], log: KernelLogger, txHost: TransactionHost);
|
|
31
|
-
/** Dispatches the sub-agent of one `
|
|
31
|
+
/** Dispatches the sub-agent of one `Agent` call (`dispatchSubagent`). */
|
|
32
32
|
dispatch(a: DispatchArgs): Promise<DispatchOutcome>;
|
|
33
33
|
/** The dispatch's writes in a transaction of their own (see `commitDispatchIn`). */
|
|
34
34
|
commitDispatch(a: DispatchArgs, plan: DispatchPlan, child: ChildWriter): Promise<DispatchCommit | null>;
|
|
35
35
|
/** A sub-agent's finished step on its parent's stream (sub-agents spec §14.2). Never throws. */
|
|
36
36
|
progress(s: SubagentStep): Promise<void>;
|
|
37
37
|
}
|
|
38
|
-
/** Sub-agent dispatch (the tools domain's `
|
|
38
|
+
/** Sub-agent dispatch (the tools domain's `Agent` tool and the run loop use it). */
|
|
39
39
|
export declare class SubagentsModule {
|
|
40
40
|
}
|
|
@@ -24,7 +24,7 @@ import { commitDispatchIn, dispatchSubagent, } from "./dispatch.js";
|
|
|
24
24
|
import { publishSubagentProgress } from "./progress.js";
|
|
25
25
|
import { liveSkillForks } from "./skill-fork.js";
|
|
26
26
|
/**
|
|
27
|
-
* Sub-agents (phase C, spec §7) and forked skills (phase D): the `
|
|
27
|
+
* Sub-agents (phase C, spec §7) and forked skills (phase D): the `Agent` tool's dispatch (the
|
|
28
28
|
* tool pipeline calls {@link dispatch}), a run's fork invocation ({@link skillForks}, the loop's
|
|
29
29
|
* `prepare`) and a child step's progress on the parent's stream ({@link progress}). Child runs go
|
|
30
30
|
* to the sub-agent run queue through {@link RunJobs}. The child lifecycle after dispatch (a
|
|
@@ -58,7 +58,7 @@ let SubagentsService = class SubagentsService {
|
|
|
58
58
|
};
|
|
59
59
|
this.skillForks = liveSkillForks(this.deps);
|
|
60
60
|
}
|
|
61
|
-
/** Dispatches the sub-agent of one `
|
|
61
|
+
/** Dispatches the sub-agent of one `Agent` call (`dispatchSubagent`). */
|
|
62
62
|
dispatch(a) {
|
|
63
63
|
return dispatchSubagent(this.deps, a);
|
|
64
64
|
}
|
|
@@ -88,7 +88,7 @@ SubagentsService = __decorate([
|
|
|
88
88
|
__param(9, Inject(TransactionHost))
|
|
89
89
|
], SubagentsService);
|
|
90
90
|
export { SubagentsService };
|
|
91
|
-
/** Sub-agent dispatch (the tools domain's `
|
|
91
|
+
/** Sub-agent dispatch (the tools domain's `Agent` tool and the run loop use it). */
|
|
92
92
|
let SubagentsModule = class SubagentsModule {
|
|
93
93
|
};
|
|
94
94
|
SubagentsModule = __decorate([
|
|
@@ -93,7 +93,8 @@ export declare function narrowPending(stored: readonly string[] | undefined, fai
|
|
|
93
93
|
* using up an attempt.
|
|
94
94
|
* Handlers must be idempotent by `eventId` (`<conversationId>/<seq>`). Nothing is written to the event
|
|
95
95
|
* log (never model-visible). Compaction calls log usage too (`purpose: "compaction"`) and are reported,
|
|
96
|
-
* as are conversation title calls (`purpose: "title"`, no run: `runId` is "")
|
|
96
|
+
* as are conversation title calls (`purpose: "title"`, no run: `runId` is "") and `WebFetch`
|
|
97
|
+
* extraction calls (`purpose: "web_fetch"`).
|
|
97
98
|
* Single-step eval replays and judge requests log no usage: not reported (M7).
|
|
98
99
|
*/
|
|
99
100
|
export declare class UsageReporter {
|
|
@@ -160,7 +160,8 @@ export function narrowPending(stored, failed) {
|
|
|
160
160
|
* using up an attempt.
|
|
161
161
|
* Handlers must be idempotent by `eventId` (`<conversationId>/<seq>`). Nothing is written to the event
|
|
162
162
|
* log (never model-visible). Compaction calls log usage too (`purpose: "compaction"`) and are reported,
|
|
163
|
-
* as are conversation title calls (`purpose: "title"`, no run: `runId` is "")
|
|
163
|
+
* as are conversation title calls (`purpose: "title"`, no run: `runId` is "") and `WebFetch`
|
|
164
|
+
* extraction calls (`purpose: "web_fetch"`).
|
|
164
165
|
* Single-step eval replays and judge requests log no usage: not reported (M7).
|
|
165
166
|
*/
|
|
166
167
|
let UsageReporter = class UsageReporter {
|
package/dist/runtime/waits.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Logger } from "@capybara-hq/plugin-sdk";
|
|
2
2
|
import { type OnApplicationShutdown } from "@nestjs/common";
|
|
3
3
|
import { type Job, type Queue } from "bullmq";
|
|
4
|
+
import { BackgroundTaskStopper } from "../background/stop.js";
|
|
4
5
|
import { EventLog } from "../conversations/event-log.js";
|
|
5
6
|
import type { KernelSchemaDb } from "../db/kernel-schema.js";
|
|
6
7
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
@@ -42,7 +43,7 @@ export interface WaitSweepResult {
|
|
|
42
43
|
/** 运行已终态、被本次扫描取消的审批 / 输入请求。 */
|
|
43
44
|
cancelled: number;
|
|
44
45
|
/**
|
|
45
|
-
* Finished parent runs whose open `
|
|
46
|
+
* Finished parent runs whose open `Agent` calls had no `tool_result`, repaired (final review
|
|
46
47
|
* I3: the next run would send an unpaired tool call, which providers refuse).
|
|
47
48
|
*/
|
|
48
49
|
repaired: number;
|
|
@@ -75,7 +76,7 @@ export declare class Waits implements OnApplicationShutdown {
|
|
|
75
76
|
private readonly questions;
|
|
76
77
|
private readonly runQueue;
|
|
77
78
|
/**
|
|
78
|
-
* Writes, in the caller's transaction, the results of a stopped run's open `
|
|
79
|
+
* Writes, in the caller's transaction, the results of a stopped run's open `Agent` calls;
|
|
79
80
|
* `fire` runs their observe hooks after the commit.
|
|
80
81
|
*/
|
|
81
82
|
private readonly pipeline;
|
|
@@ -91,12 +92,14 @@ export declare class Waits implements OnApplicationShutdown {
|
|
|
91
92
|
/** The maintenance queue: wait timeout jobs (`MaintenanceProcessor` consumes them). */
|
|
92
93
|
private readonly timeouts;
|
|
93
94
|
private readonly log;
|
|
95
|
+
/** Stops a finished sub-agent run's background tasks ({@link childFinished}). */
|
|
96
|
+
private readonly background;
|
|
94
97
|
readonly txHost: TransactionHost;
|
|
95
98
|
/** Drops the `run.orphaned` subscription (the events may outlive this instance). */
|
|
96
99
|
private readonly unsubscribe;
|
|
97
100
|
constructor(kdb: KernelDb, eventLog: EventLog, approvals: Pick<ApprovalsService, "expire" | "cancelPendingIn">, questions: Pick<QuestionsService, "expire" | "cancelPendingIn">, runQueue: Pick<RunQueue, "enqueue" | "repairOrphan" | "abortIfOrphaned">,
|
|
98
101
|
/**
|
|
99
|
-
* Writes, in the caller's transaction, the results of a stopped run's open `
|
|
102
|
+
* Writes, in the caller's transaction, the results of a stopped run's open `Agent` calls;
|
|
100
103
|
* `fire` runs their observe hooks after the commit.
|
|
101
104
|
*/
|
|
102
105
|
pipeline: Pick<ToolPipeline, "stopOpenAgentCalls">, finisher: Pick<RunFinish, "finishIn">,
|
|
@@ -109,7 +112,9 @@ export declare class Waits implements OnApplicationShutdown {
|
|
|
109
112
|
*/
|
|
110
113
|
abort: Pick<RunAbort, "requested" | "request">,
|
|
111
114
|
/** The maintenance queue: wait timeout jobs (`MaintenanceProcessor` consumes them). */
|
|
112
|
-
timeouts: Pick<Queue, "add">, events: KernelEvents, log: Pick<Logger, "error" | "warn">,
|
|
115
|
+
timeouts: Pick<Queue, "add">, events: KernelEvents, log: Pick<Logger, "error" | "warn">,
|
|
116
|
+
/** Stops a finished sub-agent run's background tasks ({@link childFinished}). */
|
|
117
|
+
background: Pick<BackgroundTaskStopper, "stopSubagentTasks">, txHost: TransactionHost);
|
|
113
118
|
/** Unsubscribes after the stop phases: events emitted while they drain are still handled. */
|
|
114
119
|
onApplicationShutdown(): void;
|
|
115
120
|
/** The context's handle (the transaction of a `@Transactional` method, else the pool). */
|
|
@@ -163,7 +168,7 @@ export declare class Waits implements OnApplicationShutdown {
|
|
|
163
168
|
* 运行已不是 waiting(例如刚被续跑)→ 返回 false,由调用方走常规中止。
|
|
164
169
|
*/
|
|
165
170
|
abortWaiting(conversationId: string, runId: string, byAccountId: string | null, detail?: RunAbortDetail): Promise<boolean>;
|
|
166
|
-
/** {@link abortWaiting}'s transaction; the open `
|
|
171
|
+
/** {@link abortWaiting}'s transaction; the open `Agent` calls it wrote go back through `st`. */
|
|
167
172
|
private abortWaitingIn;
|
|
168
173
|
/** 扫描 3:运行已终态(如暂停途中失败)仍 pending 的审批 / 输入请求 → 取消(写决定 / 回答事件)。 */
|
|
169
174
|
private sweepFinishedRuns;
|
|
@@ -193,7 +198,7 @@ export declare class Waits implements OnApplicationShutdown {
|
|
|
193
198
|
*/
|
|
194
199
|
private sweepSubagentOrphans;
|
|
195
200
|
/**
|
|
196
|
-
* Finished parent runs (past the grace period, within the last day) with an `
|
|
201
|
+
* Finished parent runs (past the grace period, within the last day) with an `Agent` call that has
|
|
197
202
|
* no `tool_result` (final review I3): a terminal path that skipped `stopOpenAgentCalls`, such as
|
|
198
203
|
* an old replica's abort, would otherwise leave an unpaired tool call that every later request of
|
|
199
204
|
* the conversation sends and providers refuse. Each is repaired under the conversation row lock
|
|
@@ -247,7 +252,8 @@ export declare class Waits implements OnApplicationShutdown {
|
|
|
247
252
|
* the conditional resume lets exactly one succeed, the last to see all its siblings terminal. A
|
|
248
253
|
* run that is not a dispatched child, or not terminal yet, is left alone. A crash in between is
|
|
249
254
|
* repaired by the wait sweep and by the parent's tools node, which writes a missing
|
|
250
|
-
* `subagent_finished` itself.
|
|
255
|
+
* `subagent_finished` itself. The running background tasks the terminal child run started are
|
|
256
|
+
* then stopped (not those of a later follow-up run of the same child).
|
|
251
257
|
*/
|
|
252
258
|
childFinished(childRunId: string): Promise<void>;
|
|
253
259
|
/**
|
package/dist/runtime/waits.js
CHANGED
|
@@ -11,6 +11,7 @@ import { getQueueToken } from "@nestjs/bullmq";
|
|
|
11
11
|
import { Inject, Injectable } from "@nestjs/common";
|
|
12
12
|
import { DelayedError } from "bullmq";
|
|
13
13
|
import { sql } from "kysely";
|
|
14
|
+
import { BackgroundTaskStopper } from "../background/stop.js";
|
|
14
15
|
import { EventLog } from "../conversations/event-log.js";
|
|
15
16
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
16
17
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
@@ -70,12 +71,13 @@ let Waits = class Waits {
|
|
|
70
71
|
abort;
|
|
71
72
|
timeouts;
|
|
72
73
|
log;
|
|
74
|
+
background;
|
|
73
75
|
txHost;
|
|
74
76
|
/** Drops the `run.orphaned` subscription (the events may outlive this instance). */
|
|
75
77
|
unsubscribe;
|
|
76
78
|
constructor(kdb, eventLog, approvals, questions, runQueue,
|
|
77
79
|
/**
|
|
78
|
-
* Writes, in the caller's transaction, the results of a stopped run's open `
|
|
80
|
+
* Writes, in the caller's transaction, the results of a stopped run's open `Agent` calls;
|
|
79
81
|
* `fire` runs their observe hooks after the commit.
|
|
80
82
|
*/
|
|
81
83
|
pipeline, finisher,
|
|
@@ -88,7 +90,9 @@ let Waits = class Waits {
|
|
|
88
90
|
*/
|
|
89
91
|
abort,
|
|
90
92
|
/** The maintenance queue: wait timeout jobs (`MaintenanceProcessor` consumes them). */
|
|
91
|
-
timeouts, events, log,
|
|
93
|
+
timeouts, events, log,
|
|
94
|
+
/** Stops a finished sub-agent run's background tasks ({@link childFinished}). */
|
|
95
|
+
background, txHost) {
|
|
92
96
|
this.kdb = kdb;
|
|
93
97
|
this.eventLog = eventLog;
|
|
94
98
|
this.approvals = approvals;
|
|
@@ -100,6 +104,7 @@ let Waits = class Waits {
|
|
|
100
104
|
this.abort = abort;
|
|
101
105
|
this.timeouts = timeouts;
|
|
102
106
|
this.log = log;
|
|
107
|
+
this.background = background;
|
|
103
108
|
this.txHost = txHost;
|
|
104
109
|
// an orphaned parent run (marked failed by `ensureRun`) stops its children at once; the
|
|
105
110
|
// sweep's `sweepChildrenOfFinished` is the backstop
|
|
@@ -193,9 +198,17 @@ let Waits = class Waits {
|
|
|
193
198
|
const row = waitingFor.kind === "approval"
|
|
194
199
|
? await this.db
|
|
195
200
|
.selectFrom("approvals")
|
|
196
|
-
.select(["tool_key", "expires_at"])
|
|
201
|
+
.select(["tool_key", "expires_at", "requested_for", "approver_role"])
|
|
197
202
|
.where("id", "=", waitingFor.id)
|
|
198
203
|
.executeTakeFirst()
|
|
204
|
+
.then((r) => r && {
|
|
205
|
+
tool_key: r.tool_key,
|
|
206
|
+
expires_at: r.expires_at,
|
|
207
|
+
approver: {
|
|
208
|
+
requestedFor: r.requested_for,
|
|
209
|
+
approverRole: r.approver_role,
|
|
210
|
+
},
|
|
211
|
+
})
|
|
199
212
|
: await this.db
|
|
200
213
|
.selectFrom("questions")
|
|
201
214
|
.select([sql `spec->>'toolKey'`.as("tool_key"), "expires_at"])
|
|
@@ -213,7 +226,10 @@ let Waits = class Waits {
|
|
|
213
226
|
childRunId: runId,
|
|
214
227
|
kind: waitingFor.kind,
|
|
215
228
|
...(waitingFor.kind === "approval"
|
|
216
|
-
? {
|
|
229
|
+
? {
|
|
230
|
+
approvalId: waitingFor.id,
|
|
231
|
+
...row.approver,
|
|
232
|
+
}
|
|
217
233
|
: { questionId: waitingFor.id }),
|
|
218
234
|
toolKey: row.tool_key,
|
|
219
235
|
expiresAt: new Date(row.expires_at).toISOString(),
|
|
@@ -337,7 +353,7 @@ let Waits = class Waits {
|
|
|
337
353
|
await this.stopChildren(runId, null).catch((err) => this.log.error("cannot stop the sub-agents of a run", { runId, err }));
|
|
338
354
|
return true;
|
|
339
355
|
}
|
|
340
|
-
/** {@link abortWaiting}'s transaction; the open `
|
|
356
|
+
/** {@link abortWaiting}'s transaction; the open `Agent` calls it wrote go back through `st`. */
|
|
341
357
|
async abortWaitingIn(conversationId, runId, byAccountId, detail, st) {
|
|
342
358
|
const t = this.db;
|
|
343
359
|
await t
|
|
@@ -385,7 +401,7 @@ let Waits = class Waits {
|
|
|
385
401
|
if (typeof spec.step === "number")
|
|
386
402
|
steps.add(spec.step);
|
|
387
403
|
}
|
|
388
|
-
// a parent waiting on sub-agents (spec §12): its open `
|
|
404
|
+
// a parent waiting on sub-agents (spec §12): its open `Agent` calls get their results
|
|
389
405
|
const agents = await this.pipeline.stopOpenAgentCalls(runId);
|
|
390
406
|
for (const step of agents.steps)
|
|
391
407
|
steps.add(step);
|
|
@@ -626,7 +642,7 @@ let Waits = class Waits {
|
|
|
626
642
|
return out;
|
|
627
643
|
}
|
|
628
644
|
/**
|
|
629
|
-
* Finished parent runs (past the grace period, within the last day) with an `
|
|
645
|
+
* Finished parent runs (past the grace period, within the last day) with an `Agent` call that has
|
|
630
646
|
* no `tool_result` (final review I3): a terminal path that skipped `stopOpenAgentCalls`, such as
|
|
631
647
|
* an old replica's abort, would otherwise leave an unpaired tool call that every later request of
|
|
632
648
|
* the conversation sends and providers refuse. Each is repaired under the conversation row lock
|
|
@@ -887,7 +903,7 @@ let Waits = class Waits {
|
|
|
887
903
|
* 等待中的调用给取消说明,其余(排在等待调用之后、尚未执行的)给「未执行」说明。
|
|
888
904
|
*/
|
|
889
905
|
async stoppedResults(t, conversationId, runId, steps, cancelled,
|
|
890
|
-
/** Calls whose result the caller writes itself (open `
|
|
906
|
+
/** Calls whose result the caller writes itself (open `Agent` calls). */
|
|
891
907
|
skip = new Set()) {
|
|
892
908
|
const out = [];
|
|
893
909
|
for (const step of steps.sort((a, b) => a - b)) {
|
|
@@ -925,7 +941,8 @@ let Waits = class Waits {
|
|
|
925
941
|
* the conditional resume lets exactly one succeed, the last to see all its siblings terminal. A
|
|
926
942
|
* run that is not a dispatched child, or not terminal yet, is left alone. A crash in between is
|
|
927
943
|
* repaired by the wait sweep and by the parent's tools node, which writes a missing
|
|
928
|
-
* `subagent_finished` itself.
|
|
944
|
+
* `subagent_finished` itself. The running background tasks the terminal child run started are
|
|
945
|
+
* then stopped (not those of a later follow-up run of the same child).
|
|
929
946
|
*/
|
|
930
947
|
async childFinished(childRunId) {
|
|
931
948
|
const row = await dispatchOfChildRun(this.db, childRunId);
|
|
@@ -938,13 +955,21 @@ let Waits = class Waits {
|
|
|
938
955
|
.executeTakeFirst();
|
|
939
956
|
if (!run || !TERMINAL_STATUSES.has(run.status))
|
|
940
957
|
return;
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
958
|
+
try {
|
|
959
|
+
const r = await childResult(this.eventLog, row);
|
|
960
|
+
if (!r) {
|
|
961
|
+
this.log.warn("sub-agent run is terminal without a terminal event", { childRunId });
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
await this.eventLog.append(row.parentConversationId, [finishedEvent(row, r.finished)]);
|
|
965
|
+
await this.resume(row.parentRunId, childRunId);
|
|
966
|
+
}
|
|
967
|
+
finally {
|
|
968
|
+
// whichever way the child run ended (its worker, a stop while waiting, an orphan repair):
|
|
969
|
+
// nobody can read or stop the background tasks it started through its model any more
|
|
970
|
+
// (background Bash spec §4.3). Never throws.
|
|
971
|
+
await this.background.stopSubagentTasks(row.childConversationId, childRunId);
|
|
945
972
|
}
|
|
946
|
-
await this.eventLog.append(row.parentConversationId, [finishedEvent(row, r.finished)]);
|
|
947
|
-
await this.resume(row.parentRunId, childRunId);
|
|
948
973
|
}
|
|
949
974
|
/**
|
|
950
975
|
* Stops the active children of a parent run (sub-agents spec §12), or only those dispatched in
|
|
@@ -1020,7 +1045,8 @@ Waits = __decorate([
|
|
|
1020
1045
|
__param(9, Inject(getQueueToken(MAINTENANCE_QUEUE_NAME))),
|
|
1021
1046
|
__param(10, Inject(KernelEvents)),
|
|
1022
1047
|
__param(11, Inject(KERNEL_LOGGER)),
|
|
1023
|
-
__param(12, Inject(
|
|
1048
|
+
__param(12, Inject(BackgroundTaskStopper)),
|
|
1049
|
+
__param(13, Inject(TransactionHost))
|
|
1024
1050
|
], Waits);
|
|
1025
1051
|
export { Waits };
|
|
1026
1052
|
/**
|
|
@@ -5,6 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { Module } from "@nestjs/common";
|
|
8
|
+
import { BackgroundStoreModule } from "../background/store.module.js";
|
|
8
9
|
import { ExtensionRegistryModule } from "../extensions/registry.js";
|
|
9
10
|
import { QueueModule } from "../infra/queue/queue.module.js";
|
|
10
11
|
import { MAINTENANCE_QUEUE_NAME } from "../runtime/maintenance-queue.js";
|
|
@@ -22,7 +23,11 @@ let SandboxModule = class SandboxModule {
|
|
|
22
23
|
};
|
|
23
24
|
SandboxModule = __decorate([
|
|
24
25
|
Module({
|
|
25
|
-
imports: [
|
|
26
|
+
imports: [
|
|
27
|
+
ExtensionRegistryModule,
|
|
28
|
+
BackgroundStoreModule,
|
|
29
|
+
QueueModule.registerQueue(MAINTENANCE_QUEUE_NAME),
|
|
30
|
+
],
|
|
26
31
|
providers: [SandboxProviders, SandboxLeases, SandboxService, SandboxJobs],
|
|
27
32
|
exports: [SandboxService, SandboxJobs],
|
|
28
33
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type SandboxHandle, type SandboxProvider } from "@capybara-hq/plugin-sdk";
|
|
2
2
|
import type { Redis } from "ioredis";
|
|
3
3
|
import { type Selectable } from "kysely";
|
|
4
|
+
import { BackgroundTaskStore } from "../background/store.js";
|
|
4
5
|
import { type KernelConfig } from "../config/schema.js";
|
|
5
6
|
import type { SandboxesTable } from "../db/kernel-schema.js";
|
|
6
7
|
import { ApiError } from "../errors.js";
|
|
@@ -28,6 +29,28 @@ interface Instance {
|
|
|
28
29
|
handle: SandboxHandle;
|
|
29
30
|
createdAt: number;
|
|
30
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* The provider {@link SandboxService.ifRunning} passes to its callback: every `exec` carries the
|
|
34
|
+
* holder's tag, like the one `withSandbox` passes.
|
|
35
|
+
*/
|
|
36
|
+
export type TaggedProvider = SandboxProvider;
|
|
37
|
+
/** What {@link SandboxService.ifRunning} did. */
|
|
38
|
+
export type IfRunningResult<T> = {
|
|
39
|
+
kind: "ran";
|
|
40
|
+
value: T;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* No sandbox, or the instance is not running: `status` is the sandbox row's (`suspended`,
|
|
44
|
+
* `creating`, `destroyed`, or `running` recorded with another provider), `gone` without a row.
|
|
45
|
+
*/
|
|
46
|
+
| {
|
|
47
|
+
kind: "not_running";
|
|
48
|
+
status: SandboxesTable["status"] | "gone";
|
|
49
|
+
}
|
|
50
|
+
/** The sandbox now records another instance (a rebuild). */
|
|
51
|
+
| {
|
|
52
|
+
kind: "other_instance";
|
|
53
|
+
};
|
|
31
54
|
/**
|
|
32
55
|
* The row still records the instance `gone` (same handle and same `created_at`). Handles compare
|
|
33
56
|
* canonically: a jsonb round trip reorders a multi-key handle's keys (final review m9).
|
|
@@ -100,11 +123,15 @@ export declare class SandboxService {
|
|
|
100
123
|
private readonly providers;
|
|
101
124
|
private readonly config;
|
|
102
125
|
private readonly log;
|
|
126
|
+
/** Background tasks lost while their process may live on (killed after a resume). */
|
|
127
|
+
private readonly background;
|
|
103
128
|
constructor(db: KernelDb,
|
|
104
129
|
/** The record of the instance each holder last used (`capk:sandbox-seen:…`). */
|
|
105
130
|
redis: Pick<Redis, "set">, leases: SandboxLeases,
|
|
106
131
|
/** The `sandbox@1` provider (read at every call: providers are ready after the extension load). */
|
|
107
|
-
providers: Pick<SandboxProviders, "current" | "lookup">, config: Pick<KernelConfigService, "get">, log: Pick<KernelLogger, "info" | "warn"
|
|
132
|
+
providers: Pick<SandboxProviders, "current" | "lookup">, config: Pick<KernelConfigService, "get">, log: Pick<KernelLogger, "info" | "warn">,
|
|
133
|
+
/** Background tasks lost while their process may live on (killed after a resume). */
|
|
134
|
+
background: Pick<BackgroundTaskStore, "pendingKills" | "clearKill">);
|
|
108
135
|
/** Poll interval while waiting for a lease (the leases' own). */
|
|
109
136
|
private get pollMs();
|
|
110
137
|
/** 是否有沙箱提供方。 */
|
|
@@ -119,6 +146,29 @@ export declare class SandboxService {
|
|
|
119
146
|
status: "running" | "suspended";
|
|
120
147
|
lastUsedAt: Date;
|
|
121
148
|
} | null>;
|
|
149
|
+
/**
|
|
150
|
+
* The instance the conversation's sandbox records now (its `created_at`), while it has one that
|
|
151
|
+
* runs or is suspended; null otherwise. Read without a lease: a caller inside `withSandbox`
|
|
152
|
+
* reads the instance its own lease keeps.
|
|
153
|
+
*/
|
|
154
|
+
currentInstance(conversationId: string): Promise<{
|
|
155
|
+
createdAt: Date;
|
|
156
|
+
} | null>;
|
|
157
|
+
/**
|
|
158
|
+
* Runs `fn` on the conversation's sandbox only while it runs the instance created at
|
|
159
|
+
* `instance.createdAt` (background tasks, spec 2026-11-05-background-bash-design §4.3). It never
|
|
160
|
+
* creates, resumes or rebuilds a sandbox: a sandbox that is missing, suspended, being created or
|
|
161
|
+
* destroyed (or recorded with another provider) is `not_running`, one that records another
|
|
162
|
+
* instance is `other_instance`. Otherwise `fn` runs under a shared lease, as a `withSandbox`
|
|
163
|
+
* holder does (its tag on every exec, crashed holders' commands killed), and `last_used_at`
|
|
164
|
+
* moves forward when it ends. Waits for the lease up to `sandbox.lockWaitSeconds`
|
|
165
|
+
* (`sandbox.busy`); `signal` (optional) ends the wait with its abort reason. The signal passed
|
|
166
|
+
* to `fn` aborts with `signal` or when the lease is lost. Errors of `fn` (`SandboxGoneError`
|
|
167
|
+
* too) are thrown as they are.
|
|
168
|
+
*/
|
|
169
|
+
ifRunning<T>(conversationId: string, instance: {
|
|
170
|
+
createdAt: Date;
|
|
171
|
+
}, fn: (p: TaggedProvider, h: SandboxHandle, signal: AbortSignal) => Promise<T>, signal?: AbortSignal): Promise<IfRunningResult<T>>;
|
|
122
172
|
/**
|
|
123
173
|
* A short lease on one path of the conversation's sandbox around the kernel's own
|
|
124
174
|
* read-modify-write of that file (spec §10.4); waits up to 30 s, then throws
|
|
@@ -164,8 +214,8 @@ export declare class SandboxService {
|
|
|
164
214
|
/** Recorded running with the current provider, and not the instance found gone. */
|
|
165
215
|
private usable;
|
|
166
216
|
/**
|
|
167
|
-
* Under a just-taken shared lease: confirms the row is still
|
|
168
|
-
* null), records the holder and kills crashed holders' commands.
|
|
217
|
+
* Under a just-taken shared lease: confirms the row is still `accept`ed (else releases and
|
|
218
|
+
* returns null), records the holder and kills crashed holders' commands.
|
|
169
219
|
*/
|
|
170
220
|
private asShared;
|
|
171
221
|
/**
|
|
@@ -206,6 +256,14 @@ export declare class SandboxService {
|
|
|
206
256
|
* 结束);其余失败只记 warn。提供方没有 `killAll` 时只记 info。
|
|
207
257
|
*/
|
|
208
258
|
private killLeftovers;
|
|
259
|
+
/**
|
|
260
|
+
* Under the exclusive lease, right after a resume or a (re)build: kills the sessions of the
|
|
261
|
+
* background tasks marked lost while their process may live on (`kill_pending`), in one exec of
|
|
262
|
+
* `pkill -KILL -s <sid>`, then clears their flags. Tasks of another instance have no process
|
|
263
|
+
* here and are only cleared. A gone instance and an abort are thrown; another failure is warned
|
|
264
|
+
* and leaves the flags of this instance's tasks for the next resume.
|
|
265
|
+
*/
|
|
266
|
+
private killPendingTasks;
|
|
209
267
|
private require;
|
|
210
268
|
/**
|
|
211
269
|
* 防护写入:lease 仍在、且记录的 generation 仍是锁内读到的值时才写(并加一);否则抛 {@link SandboxLockLostError}。
|