@capybara-hq/kernel 0.1.0-rc.23 → 0.1.0-rc.25
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/bootstrap.json +25 -25
- package/dist/admin/admin.module.d.ts +2 -1
- package/dist/admin/admin.module.js +9 -3
- package/dist/admin/health.service.d.ts +2 -2
- package/dist/admin/health.service.js +6 -2
- package/dist/admin/outbox-dead.controller.d.ts +23 -0
- package/dist/admin/outbox-dead.controller.js +62 -0
- package/dist/admin/outbox-dead.schemas.d.ts +8 -0
- package/dist/admin/outbox-dead.schemas.js +18 -0
- package/dist/admin/outbox-dead.service.d.ts +66 -0
- package/dist/admin/outbox-dead.service.js +179 -0
- package/dist/admin/overview.service.d.ts +40 -5
- package/dist/admin/overview.service.js +41 -7
- package/dist/agents/agents.module.js +3 -0
- package/dist/agents/agents.service.d.ts +6 -1
- package/dist/agents/agents.service.js +11 -2
- package/dist/agents/from-template.js +1 -1
- package/dist/background/finish.d.ts +5 -2
- package/dist/background/finish.js +14 -3
- package/dist/background/launch.d.ts +2 -1
- package/dist/background/launch.js +5 -2
- package/dist/background/store.d.ts +8 -0
- package/dist/background/store.js +24 -0
- package/dist/catalog/admin-catalog.controller.d.ts +21 -2
- package/dist/catalog/admin-catalog.controller.js +45 -6
- package/dist/catalog/admin-catalog.schemas.d.ts +5 -0
- package/dist/catalog/admin-catalog.schemas.js +8 -0
- package/dist/catalog/catalog-import.module.js +0 -4
- package/dist/catalog/catalog-scope.service.d.ts +63 -26
- package/dist/catalog/catalog-scope.service.js +146 -71
- package/dist/catalog/catalog.module.d.ts +2 -1
- package/dist/catalog/catalog.module.js +9 -4
- package/dist/catalog/catalog.service.d.ts +11 -4
- package/dist/catalog/catalog.service.js +21 -5
- package/dist/catalog/cli.d.ts +4 -3
- package/dist/catalog/cli.js +8 -13
- package/dist/catalog/job-ids.d.ts +8 -20
- package/dist/catalog/job-ids.js +11 -16
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/org-plugin-uploads.d.ts +11 -4
- package/dist/catalog/org-plugin-uploads.js +21 -6
- package/dist/catalog/owned-items.d.ts +6 -13
- package/dist/catalog/owned-items.js +11 -29
- package/dist/catalog/owned-plugin-cleanup.d.ts +8 -17
- package/dist/catalog/owned-plugin-cleanup.js +12 -66
- package/dist/catalog/platform-components.d.ts +56 -34
- package/dist/catalog/platform-components.js +68 -78
- package/dist/catalog/platform-import-update.d.ts +50 -0
- package/dist/catalog/platform-import-update.js +116 -0
- package/dist/catalog/plugin-import.d.ts +64 -26
- package/dist/catalog/plugin-import.js +113 -77
- package/dist/catalog/plugin-upgrade.d.ts +22 -4
- package/dist/catalog/plugin-upgrade.js +26 -19
- package/dist/catalog/scope-jobs.d.ts +59 -0
- package/dist/catalog/scope-jobs.js +65 -0
- package/dist/catalog/scope-sync-workers.d.ts +22 -0
- package/dist/catalog/scope-sync-workers.js +58 -2
- package/dist/catalog/scope-sync.d.ts +40 -65
- package/dist/catalog/scope-sync.js +114 -122
- package/dist/channels/channels.module.d.ts +5 -2
- package/dist/channels/channels.module.js +9 -2
- package/dist/channels/deliver-job.d.ts +25 -0
- package/dist/channels/deliver-job.js +25 -0
- package/dist/channels/inbound.d.ts +1 -1
- package/dist/channels/inbound.js +4 -17
- package/dist/channels/jobs.d.ts +28 -18
- package/dist/channels/jobs.js +63 -26
- package/dist/channels/threads.d.ts +4 -3
- package/dist/channels/threads.js +4 -3
- package/dist/config/schema.d.ts +0 -3
- package/dist/config/schema.js +11 -20
- package/dist/conversations/agent-tree.d.ts +16 -0
- package/dist/conversations/agent-tree.js +36 -0
- package/dist/conversations/conversations.controller.js +4 -2
- package/dist/conversations/conversations.service.d.ts +61 -19
- package/dist/conversations/conversations.service.js +69 -43
- package/dist/conversations/event-log.d.ts +7 -10
- package/dist/conversations/event-log.js +24 -15
- package/dist/conversations/events.d.ts +21 -0
- package/dist/conversations/events.js +26 -2
- package/dist/conversations/queue.service.d.ts +8 -3
- package/dist/conversations/queue.service.js +37 -13
- package/dist/conversations/source.d.ts +10 -0
- package/dist/conversations/source.js +17 -0
- package/dist/conversations/titles.d.ts +21 -8
- package/dist/conversations/titles.js +42 -15
- package/dist/conversations/tree.d.ts +10 -0
- package/dist/conversations/tree.js +35 -0
- package/dist/db/kernel-schema.d.ts +35 -22
- package/dist/devices/devices.service.d.ts +23 -11
- package/dist/devices/devices.service.js +34 -26
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +11 -0
- package/dist/evals/run-replay.d.ts +13 -2
- package/dist/evals/run-replay.js +42 -9
- package/dist/evals/snapshot.d.ts +7 -1
- package/dist/evals/snapshot.js +2 -1
- package/dist/extensions/extensions.module.js +3 -0
- package/dist/extensions/hooks.d.ts +22 -3
- package/dist/extensions/hooks.js +15 -1
- package/dist/extensions/lifecycle-hooks.d.ts +99 -0
- package/dist/extensions/lifecycle-hooks.js +273 -0
- package/dist/extensions/lifecycle.d.ts +6 -1
- package/dist/extensions/lifecycle.js +9 -2
- package/dist/extensions/org-config.d.ts +13 -1
- package/dist/extensions/org-config.js +19 -2
- package/dist/extensions/permission-view.d.ts +9 -5
- package/dist/extensions/permission-view.js +9 -4
- package/dist/extensions/point-defaults.d.ts +28 -1
- package/dist/extensions/point-defaults.js +44 -13
- package/dist/extensions/usage-subscribers.d.ts +43 -0
- package/dist/extensions/usage-subscribers.js +108 -0
- package/dist/http/api.module.js +2 -0
- package/dist/inbox/inbox.service.d.ts +6 -20
- package/dist/inbox/inbox.service.js +0 -3
- package/dist/inbox/org-notices.d.ts +1 -1
- package/dist/inbox/platform-inbox.service.d.ts +3 -32
- package/dist/inbox/platform-inbox.service.js +5 -54
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/infra/cli/kernel-cli.module.js +5 -0
- package/dist/infra/events/kernel-events.d.ts +9 -35
- package/dist/infra/outbox/outbox-relay.module.d.ts +6 -0
- package/dist/infra/outbox/outbox-relay.module.js +18 -0
- package/dist/infra/outbox/outbox.dispatcher.d.ts +103 -0
- package/dist/infra/outbox/outbox.dispatcher.js +310 -0
- package/dist/infra/outbox/outbox.module.d.ts +24 -0
- package/dist/infra/outbox/outbox.module.js +50 -0
- package/dist/infra/outbox/outbox.relay.d.ts +31 -0
- package/dist/infra/outbox/outbox.relay.js +76 -0
- package/dist/infra/outbox/outbox.service.d.ts +51 -0
- package/dist/infra/outbox/outbox.service.js +131 -0
- package/dist/infra/outbox/registry.d.ts +244 -0
- package/dist/infra/outbox/registry.js +234 -0
- package/dist/infra/queue/queue-names.d.ts +8 -0
- package/dist/infra/queue/queue-names.js +17 -0
- package/dist/kernel.module.js +3 -0
- package/dist/local-devices/device-policy.service.d.ts +4 -0
- package/dist/local-devices/device-policy.service.js +61 -3
- package/dist/local-devices/machines.d.ts +13 -5
- package/dist/local-devices/machines.js +45 -7
- package/dist/local-devices/policy-summary.d.ts +44 -1
- package/dist/local-devices/policy-summary.js +69 -0
- package/dist/models/embeddings.d.ts +9 -9
- package/dist/models/embeddings.js +11 -18
- package/dist/models/models.module.js +3 -0
- package/dist/orgs/directory-sync.js +1 -1
- package/dist/orgs/members.service.js +1 -1
- package/dist/orgs/offboarding.d.ts +50 -57
- package/dist/orgs/offboarding.js +117 -162
- package/dist/orgs/orgs.module.js +3 -0
- package/dist/orgs/orgs.service.d.ts +11 -5
- package/dist/orgs/orgs.service.js +22 -6
- package/dist/overrides.d.ts +23 -3
- package/dist/overrides.js +12 -2
- package/dist/platform/exclusions.js +5 -0
- package/dist/platform/ops/admin.ops.js +18 -2
- package/dist/platform/ops/catalog-admin.ops.d.ts +3 -1
- package/dist/platform/ops/catalog-admin.ops.js +32 -4
- package/dist/platform/ops/inbox.ops.js +4 -20
- package/dist/platform/ops/outbox.ops.d.ts +21 -0
- package/dist/platform/ops/outbox.ops.js +125 -0
- package/dist/platform/ops/platform.ops.d.ts +1 -0
- package/dist/platform/ops/platform.ops.js +6 -3
- package/dist/platform/ops/schedules.ops.js +40 -1
- package/dist/platform/platform-ops.module.d.ts +2 -1
- package/dist/platform/platform-ops.module.js +3 -0
- package/dist/platform/route-schemas.js +3 -0
- package/dist/roles/worker-role.d.ts +10 -5
- package/dist/roles/worker-role.js +19 -9
- package/dist/roles/worker.module.js +11 -8
- package/dist/runtime/context/build.d.ts +3 -0
- package/dist/runtime/context/build.js +15 -0
- package/dist/runtime/context/plugin-context.d.ts +20 -0
- package/dist/runtime/context/plugin-context.js +30 -0
- package/dist/runtime/langgraph-loop.js +17 -5
- package/dist/runtime/limits.d.ts +15 -0
- package/dist/runtime/limits.js +25 -0
- package/dist/runtime/loop.d.ts +16 -3
- package/dist/runtime/loop.js +2 -1
- package/dist/runtime/maintenance.d.ts +7 -3
- package/dist/runtime/maintenance.js +52 -12
- package/dist/runtime/model-call.d.ts +20 -17
- package/dist/runtime/model-call.js +15 -24
- package/dist/runtime/plugin-context.service.d.ts +69 -0
- package/dist/runtime/plugin-context.service.js +208 -0
- package/dist/runtime/queue-lost-jobs.d.ts +24 -0
- package/dist/runtime/queue-lost-jobs.js +51 -0
- package/dist/runtime/run-control.d.ts +47 -5
- package/dist/runtime/run-control.js +79 -12
- package/dist/runtime/run-finish.d.ts +39 -12
- package/dist/runtime/run-finish.js +97 -14
- package/dist/runtime/run-jobs.d.ts +95 -13
- package/dist/runtime/run-jobs.js +199 -28
- package/dist/runtime/run-orphan-check.job.d.ts +142 -0
- package/dist/runtime/run-orphan-check.job.js +339 -0
- package/dist/runtime/run-processors.d.ts +16 -9
- package/dist/runtime/run-processors.js +1 -1
- package/dist/runtime/run-queue.d.ts +75 -53
- package/dist/runtime/run-queue.js +189 -263
- package/dist/runtime/run-steps.d.ts +1 -2
- package/dist/runtime/run-steps.js +8 -11
- package/dist/runtime/run-worker.d.ts +26 -16
- package/dist/runtime/run-worker.js +132 -37
- package/dist/runtime/runtime.module.d.ts +2 -3
- package/dist/runtime/runtime.module.js +7 -6
- package/dist/runtime/step-log.d.ts +16 -4
- package/dist/runtime/step-log.js +26 -6
- package/dist/runtime/stream.controller.d.ts +2 -4
- package/dist/runtime/stream.controller.js +5 -11
- package/dist/runtime/subagents/child.js +1 -1
- package/dist/runtime/subagents/definition.d.ts +2 -1
- package/dist/runtime/subagents/definition.js +4 -2
- package/dist/runtime/subagents/deliveries.d.ts +6 -3
- package/dist/runtime/subagents/deliveries.js +16 -7
- package/dist/runtime/subagents/dispatch.d.ts +12 -12
- package/dist/runtime/subagents/dispatch.js +14 -38
- package/dist/runtime/subagents/messages.d.ts +5 -1
- package/dist/runtime/subagents/messages.js +11 -3
- package/dist/runtime/subagents/skill-fork.d.ts +3 -3
- package/dist/runtime/subagents/skill-fork.js +8 -5
- package/dist/runtime/subagents/subagents.service.js +1 -1
- package/dist/runtime/subagents/tree-jobs.d.ts +61 -0
- package/dist/runtime/subagents/tree-jobs.js +86 -0
- package/dist/runtime/usage-report-jobs.d.ts +23 -48
- package/dist/runtime/usage-report-jobs.js +67 -119
- package/dist/runtime/usage-report.d.ts +28 -77
- package/dist/runtime/usage-report.js +35 -213
- package/dist/runtime/waits.d.ts +48 -198
- package/dist/runtime/waits.js +103 -805
- package/dist/sandbox/jobs.d.ts +20 -10
- package/dist/sandbox/jobs.js +23 -17
- package/dist/sandbox/sandbox.service.d.ts +17 -4
- package/dist/sandbox/sandbox.service.js +55 -14
- package/dist/schedules/calendar.d.ts +134 -0
- package/dist/schedules/calendar.js +410 -0
- package/dist/schedules/fire.d.ts +26 -7
- package/dist/schedules/fire.js +91 -22
- package/dist/schedules/job-ids.d.ts +66 -17
- package/dist/schedules/job-ids.js +81 -13
- package/dist/schedules/run-tracker.d.ts +0 -5
- package/dist/schedules/run-tracker.js +2 -14
- package/dist/schedules/scan.job.d.ts +13 -32
- package/dist/schedules/scan.job.js +50 -164
- package/dist/schedules/schedule-math.d.ts +42 -0
- package/dist/schedules/schedule-math.js +52 -0
- package/dist/schedules/scheduled-tasks.service.d.ts +22 -6
- package/dist/schedules/scheduled-tasks.service.js +70 -14
- package/dist/schedules/schedules.controller.d.ts +5 -1
- package/dist/schedules/schedules.controller.js +15 -1
- package/dist/schedules/schedules.module.js +0 -4
- package/dist/schedules/schedules.schemas.d.ts +35 -0
- package/dist/schedules/schedules.schemas.js +27 -0
- package/dist/schedules/store.d.ts +5 -0
- package/dist/schedules/store.js +20 -0
- package/dist/skills/changes.controller.d.ts +1 -1
- package/dist/skills/changes.controller.js +1 -1
- package/dist/tools/approvals.service.d.ts +41 -11
- package/dist/tools/approvals.service.js +108 -14
- package/dist/tools/builtin-names.d.ts +5 -3
- package/dist/tools/builtin-names.js +12 -4
- package/dist/tools/builtins/builtin-tools.d.ts +1 -2
- package/dist/tools/builtins/builtin-tools.js +21 -17
- package/dist/tools/builtins/sandbox/bash.js +9 -3
- package/dist/tools/builtins/sandbox/common.d.ts +18 -1
- package/dist/tools/builtins/sandbox/common.js +14 -1
- package/dist/tools/builtins/sandbox/index.d.ts +2 -1
- package/dist/tools/builtins/sandbox/index.js +4 -1
- package/dist/tools/builtins/sandbox/task-list.d.ts +12 -0
- package/dist/tools/builtins/sandbox/task-list.js +130 -0
- package/dist/tools/builtins/sandbox/task-output.d.ts +8 -1
- package/dist/tools/builtins/sandbox/task-output.js +21 -3
- package/dist/tools/builtins/web/extract.d.ts +2 -4
- package/dist/tools/builtins/web/extract.js +2 -5
- package/dist/tools/pipeline.d.ts +12 -3
- package/dist/tools/pipeline.js +6 -1
- package/dist/tools/questions.service.d.ts +30 -10
- package/dist/tools/questions.service.js +41 -27
- package/dist/tools/registry.d.ts +12 -3
- package/dist/tools/registry.js +13 -3
- package/dist/tools/tools.module.js +4 -3
- package/package.json +3 -3
- package/src/migrations/0118_device_policy_ops.sql +6 -0
- package/src/migrations/0119_outbox.sql +22 -0
- package/src/migrations/0120_drop_usage_report_sweep.sql +7 -0
- package/src/migrations/0121_drop_platform_migration_runs.sql +12 -0
- package/src/migrations/0122_drop_scheduled_task_runs_rechecked_at.sql +5 -0
- package/src/migrations/0123_pgvector.sql +27 -0
- package/src/migrations/0124_conversation_source.sql +36 -0
- package/dist/catalog/platform-migration.d.ts +0 -115
- package/dist/catalog/platform-migration.js +0 -583
- package/dist/infra/queue/add-job-once.d.ts +0 -14
- package/dist/infra/queue/add-job-once.js +0 -16
|
@@ -19,7 +19,6 @@ import { KernelDb } from "../infra/database/kernel-db.js";
|
|
|
19
19
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
20
20
|
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
21
21
|
import { KernelEvents } from "../infra/events/kernel-events.js";
|
|
22
|
-
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
23
22
|
import { ProviderRegistry } from "../runtime/providers.js";
|
|
24
23
|
import { RunControl as RunControlService } from "../runtime/run-control.js";
|
|
25
24
|
import { rootConversationOf } from "../runtime/subagents/child.js";
|
|
@@ -130,7 +129,6 @@ let ConversationsService = class ConversationsService {
|
|
|
130
129
|
access;
|
|
131
130
|
runs;
|
|
132
131
|
providers;
|
|
133
|
-
log;
|
|
134
132
|
content;
|
|
135
133
|
attachments;
|
|
136
134
|
invoker;
|
|
@@ -144,7 +142,7 @@ let ConversationsService = class ConversationsService {
|
|
|
144
142
|
/** Starts and stops the conversation's runs. */
|
|
145
143
|
runs,
|
|
146
144
|
/** Resolves a switched-to model and its declared parameters (UI refresh B). */
|
|
147
|
-
providers,
|
|
145
|
+
providers,
|
|
148
146
|
/** Reads `@` resources with the sender's credentials. */
|
|
149
147
|
content,
|
|
150
148
|
/** Binds uploaded files to the conversation in the message's transaction. */
|
|
@@ -165,7 +163,6 @@ let ConversationsService = class ConversationsService {
|
|
|
165
163
|
this.access = access;
|
|
166
164
|
this.runs = runs;
|
|
167
165
|
this.providers = providers;
|
|
168
|
-
this.log = log;
|
|
169
166
|
this.content = content;
|
|
170
167
|
this.attachments = attachments;
|
|
171
168
|
this.invoker = invoker;
|
|
@@ -176,22 +173,14 @@ let ConversationsService = class ConversationsService {
|
|
|
176
173
|
this.events = events;
|
|
177
174
|
this.txHost = txHost;
|
|
178
175
|
}
|
|
179
|
-
/**
|
|
180
|
-
* 不阻塞地调用一次 `ensureRun`(打开 SSE、读事件时):它幂等,并顺带清理孤儿运行,
|
|
181
|
-
* 会话不会因为某次运行结束后的投递失败而永远停在「运行中」。失败只记日志。
|
|
182
|
-
*/
|
|
183
|
-
kickRun(conversationId) {
|
|
184
|
-
this.runs
|
|
185
|
-
.ensureRun(conversationId)
|
|
186
|
-
.catch((err) => this.log.warn("ensureRun on conversation open failed", { conversationId, err }));
|
|
187
|
-
}
|
|
188
176
|
/**
|
|
189
177
|
* Creates an empty conversation bound to its device (`pick`, see
|
|
190
178
|
* {@link ConversationDevices.forNew}); an agent the account cannot use →
|
|
191
179
|
* `agent.not_found`, a device it may not use → `device.not_found` /
|
|
192
|
-
* `device.unavailable`, and nothing is created.
|
|
180
|
+
* `device.unavailable`, and nothing is created. `opts.source` records where the conversation
|
|
181
|
+
* comes from.
|
|
193
182
|
*/
|
|
194
|
-
async create(orgId, accountId, agentId, pick = {}) {
|
|
183
|
+
async create(orgId, accountId, agentId, pick = {}, opts) {
|
|
195
184
|
await this.agents.get(orgId, agentId, accountId);
|
|
196
185
|
const deviceId = await this.devices.forNew(orgId, accountId, pick);
|
|
197
186
|
const row = await this.db
|
|
@@ -202,6 +191,7 @@ let ConversationsService = class ConversationsService {
|
|
|
202
191
|
agent_id: agentId,
|
|
203
192
|
account_id: accountId,
|
|
204
193
|
device_id: deviceId,
|
|
194
|
+
source: opts.source,
|
|
205
195
|
})
|
|
206
196
|
.returning(COLUMNS)
|
|
207
197
|
.executeTakeFirstOrThrow();
|
|
@@ -215,10 +205,10 @@ let ConversationsService = class ConversationsService {
|
|
|
215
205
|
* `agent.not_found` and nothing is written. Queues a run afterwards, like `postUserMessage`.
|
|
216
206
|
* `events` are every event the create wrote, in seq order from seq 1 (a `model_switched` before
|
|
217
207
|
* the message when the send switched), so a client can seed the new conversation's log whole.
|
|
218
|
-
* `internal
|
|
219
|
-
* `conversations.scheduled_task_id`, and its zone override.
|
|
208
|
+
* `internal`: the conversation's source and, for kernel callers only, a scheduled task's marker,
|
|
209
|
+
* which also sets `conversations.scheduled_task_id`, and its zone override.
|
|
220
210
|
*/
|
|
221
|
-
async createWithMessage(orgId, accountId, agentId, input, pick = {}, internal
|
|
211
|
+
async createWithMessage(orgId, accountId, agentId, input, pick = {}, internal) {
|
|
222
212
|
const agent = await this.agents.get(orgId, agentId, accountId);
|
|
223
213
|
const prior = await this.findCreated(orgId, accountId, agentId, input.clientMessageId);
|
|
224
214
|
if (prior)
|
|
@@ -237,7 +227,7 @@ let ConversationsService = class ConversationsService {
|
|
|
237
227
|
return raced;
|
|
238
228
|
}
|
|
239
229
|
await this.eventLog.notify(id, written.seq);
|
|
240
|
-
await this.
|
|
230
|
+
await this.startRun(id);
|
|
241
231
|
return { conversation: await this.rowView(id), event: written, events: all, created: true };
|
|
242
232
|
}
|
|
243
233
|
/** The conversation row and its first message (undefined: a concurrent retry committed first). */
|
|
@@ -254,6 +244,7 @@ let ConversationsService = class ConversationsService {
|
|
|
254
244
|
device_id: conv.deviceId,
|
|
255
245
|
create_request_id: input.clientMessageId,
|
|
256
246
|
scheduled_task_id: internal.schedule?.taskId ?? null,
|
|
247
|
+
source: internal.source,
|
|
257
248
|
})
|
|
258
249
|
.onConflict((oc) => oc
|
|
259
250
|
.columns(["org_id", "account_id", "create_request_id"])
|
|
@@ -292,9 +283,16 @@ let ConversationsService = class ConversationsService {
|
|
|
292
283
|
return null;
|
|
293
284
|
// what the first send wrote: the log from its start up to the message
|
|
294
285
|
const events = (await this.eventLog.readAfter(row.id, 0, event.seq)).filter((e) => e.seq <= event.seq);
|
|
295
|
-
await this.
|
|
286
|
+
await this.startRun(row.id);
|
|
296
287
|
return { conversation: toView(row), event, events, created: false };
|
|
297
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* The direct `ensureRun` after a message's commit ({@link RunControl.ensureRunAfterCommit}): a
|
|
291
|
+
* failure never fails the request, since the message's transaction owes the ensure-run backstop.
|
|
292
|
+
*/
|
|
293
|
+
startRun(conversationId) {
|
|
294
|
+
return this.runs.ensureRunAfterCommit(conversationId);
|
|
295
|
+
}
|
|
298
296
|
async rowView(id) {
|
|
299
297
|
return toView(await this.db
|
|
300
298
|
.selectFrom("conversations")
|
|
@@ -352,7 +350,7 @@ let ConversationsService = class ConversationsService {
|
|
|
352
350
|
if (!(e instanceof ApiError && e.code === "run.not_active"))
|
|
353
351
|
throw e;
|
|
354
352
|
}
|
|
355
|
-
await this.markDeleted(conversationId);
|
|
353
|
+
await this.markDeleted(orgId, conversationId, accountId);
|
|
356
354
|
// after the mark, so no finish or delivery of the stops below can start a run on the deleted
|
|
357
355
|
// root (`ensureRun` refuses it). The sandbox's tasks stop first, so the sub-agents' tasks end
|
|
358
356
|
// as a deletion; the tree stop then only stops a task a sub-agent started in between
|
|
@@ -362,13 +360,15 @@ let ConversationsService = class ConversationsService {
|
|
|
362
360
|
await this.runs.stopTree(conversationId, accountId, { includeSelf: false });
|
|
363
361
|
await this.eventLog.publishChanged(conversationId, "deleted");
|
|
364
362
|
}
|
|
365
|
-
// the publish happens after the commit, in the caller
|
|
366
|
-
|
|
363
|
+
// the publish happens after the commit, in the caller; the tree stop after it is owed here
|
|
364
|
+
// (transactional outbox spec §6), so a process that dies before it still stops the tree
|
|
365
|
+
async markDeleted(orgId, conversationId, accountId) {
|
|
367
366
|
await this.db
|
|
368
367
|
.updateTable("conversations")
|
|
369
368
|
.set({ deleted_at: sql `now()` })
|
|
370
369
|
.where("id", "=", conversationId)
|
|
371
370
|
.execute();
|
|
371
|
+
await this.runs.oweStopDeletedTree(conversationId, accountId, orgId);
|
|
372
372
|
// Queued messages must not start a run on a deleted conversation
|
|
373
373
|
await this.db
|
|
374
374
|
.deleteFrom("conversation_queue")
|
|
@@ -681,26 +681,28 @@ let ConversationsService = class ConversationsService {
|
|
|
681
681
|
return conversationId;
|
|
682
682
|
return rootConversationOf(this.db.db, row.parent_conversation_id);
|
|
683
683
|
}
|
|
684
|
-
/**
|
|
684
|
+
/**
|
|
685
|
+
* 读事件(先做 `get` 的可见性判定). A read never changes run state (transactional outbox spec
|
|
686
|
+
* §6): a run nobody runs is the `run-orphan-check`'s to repair.
|
|
687
|
+
*/
|
|
685
688
|
async listEvents(orgId, conversationId, viewerAccountId, afterSeq, limit) {
|
|
686
689
|
await this.get(orgId, conversationId, viewerAccountId);
|
|
687
|
-
this.kickRun(conversationId);
|
|
688
690
|
return this.eventLog.readAfter(conversationId, afterSeq, limit);
|
|
689
691
|
}
|
|
690
692
|
/**
|
|
691
693
|
* The turn-aligned page of events before `beforeSeq` (`null`: the log's last page), with how
|
|
692
694
|
* many runs started before it ({@link EventLog.readTurnPageBefore}; history paging spec §2).
|
|
693
|
-
* Visibility as {@link get};
|
|
695
|
+
* Visibility as {@link get}; a read only, as {@link listEvents}.
|
|
694
696
|
*/
|
|
695
697
|
async listEventsBefore(orgId, conversationId, viewerAccountId, beforeSeq, limit) {
|
|
696
698
|
await this.get(orgId, conversationId, viewerAccountId);
|
|
697
|
-
this.kickRun(conversationId);
|
|
698
699
|
return this.eventLog.readTurnPageBefore(conversationId, beforeSeq, limit, EVENTS_TURN_EXTEND);
|
|
699
700
|
}
|
|
700
701
|
/**
|
|
701
702
|
* 追加一条用户消息;带 `clientMessageId` 时重复提交返回同一事件。写入后调用 `ensureRun`:
|
|
702
703
|
* 没有进行中的运行时投递一轮;运行中则由当前运行在步骤间隙吸收,或在它结束时再次 `ensureRun`。
|
|
703
|
-
*
|
|
704
|
+
* A failed `ensureRun` is logged, not thrown: the message's transaction owes the ensure-run
|
|
705
|
+
* backstop, which starts the run once the queue is reachable (transactional outbox spec §6).
|
|
704
706
|
*
|
|
705
707
|
* `attachments`(`@` 资源引用):内核以发送者的凭据读取资源(打码、限长),作为用户文本之后的额外文本块写入同一条
|
|
706
708
|
* user_message,并在 `payload.attachments` 记录元数据(第 i 个附件对应 `content[i + 1]`)。读取失败整条不写。
|
|
@@ -719,7 +721,7 @@ let ConversationsService = class ConversationsService {
|
|
|
719
721
|
input.clientMessageId !== undefined) {
|
|
720
722
|
const existing = await this.eventLog.findByIdem(conversationId, userMessageIdemKey(input.clientMessageId));
|
|
721
723
|
if (existing) {
|
|
722
|
-
await this.
|
|
724
|
+
await this.startRun(conversationId);
|
|
723
725
|
return existing;
|
|
724
726
|
}
|
|
725
727
|
}
|
|
@@ -750,7 +752,7 @@ let ConversationsService = class ConversationsService {
|
|
|
750
752
|
.execute();
|
|
751
753
|
await this.eventLog.publishChanged(conversationId, "archived");
|
|
752
754
|
}
|
|
753
|
-
await this.
|
|
755
|
+
await this.startRun(conversationId);
|
|
754
756
|
return event;
|
|
755
757
|
}
|
|
756
758
|
/**
|
|
@@ -812,10 +814,19 @@ let ConversationsService = class ConversationsService {
|
|
|
812
814
|
* conversations (network ask-to-allow spec §6.7). The queue's "send now" uses it as the direct
|
|
813
815
|
* send does; announce after the commit with {@link announceSkipped}. `toSeq` is the highest seq
|
|
814
816
|
* written in this conversation (null: none).
|
|
817
|
+
*
|
|
818
|
+
* Lock order: this (root) conversation (the caller's), its pending questions, the sub-agents'
|
|
819
|
+
* conversations with a pending network ask (id order), the asks themselves (the root's and the
|
|
820
|
+
* sub-agents'), and only then the run rows, as each skipped wait's run resumes in this
|
|
821
|
+
* transaction. Every run row comes after every conversation and decided row (ruling R19); a
|
|
822
|
+
* sub-agent's conversation comes after the root's questions, which only this path locks with a
|
|
823
|
+
* sub-agent conversation after them.
|
|
815
824
|
*/
|
|
816
825
|
async skipWaitsIn(conversationId, accountId, messageSeq) {
|
|
817
826
|
const q = await this.questions.skipPendingIn(conversationId, accountId, messageSeq);
|
|
818
827
|
const n = await this.approvals.skipNetworkIn(conversationId, accountId);
|
|
828
|
+
for (const w of [...q.records, ...n.records])
|
|
829
|
+
await this.runs.resumeIn(w.runId, w.id);
|
|
819
830
|
const here = n.seqs.get(conversationId);
|
|
820
831
|
const toSeq = q.toSeq === null && here === undefined ? null : Math.max(q.toSeq ?? 0, here ?? 0);
|
|
821
832
|
return { skipped: { questions: q.records, network: n.records, seqs: n.seqs }, toSeq };
|
|
@@ -823,7 +834,8 @@ let ConversationsService = class ConversationsService {
|
|
|
823
834
|
/**
|
|
824
835
|
* After the commit: announces each skipped question (`question.answered`, outcome `skipped`) and
|
|
825
836
|
* network ask (`approval.decided`, status `skipped`; a sub-agent's conversation is notified
|
|
826
|
-
* first)
|
|
837
|
+
* first) as domain events with no kernel subscriber: the IM card updates are owed by the skips'
|
|
838
|
+
* appends (transactional outbox spec §8.1); the run resumed in the message's transaction.
|
|
827
839
|
*/
|
|
828
840
|
async announceSkipped(skipped) {
|
|
829
841
|
for (const q of skipped.questions) {
|
|
@@ -877,6 +889,10 @@ let ConversationsService = class ConversationsService {
|
|
|
877
889
|
events.push(this.userMessage(accountId, input, extra, blocks, invoked, context, internal.schedule));
|
|
878
890
|
const { events: written, fresh } = await this.eventLog.appendInReport(conversationId, events);
|
|
879
891
|
const message = written.at(-1);
|
|
892
|
+
// the run this message starts is owed with it: the direct ensureRun after the commit may never
|
|
893
|
+
// happen (the process died) or fail (transactional outbox spec §6)
|
|
894
|
+
if (fresh.at(-1) === true)
|
|
895
|
+
await this.runs.oweEnsureRun(conversationId, message.seq, orgId);
|
|
880
896
|
const skips = fresh.at(-1) === true
|
|
881
897
|
? await this.skipWaitsIn(conversationId, accountId, message.seq)
|
|
882
898
|
: { skipped: NO_REPLY_SKIPS, toSeq: null };
|
|
@@ -995,13 +1011,24 @@ let ConversationsService = class ConversationsService {
|
|
|
995
1011
|
throw new ApiError("run.not_active", "No active run to abort");
|
|
996
1012
|
const runs = this.runs;
|
|
997
1013
|
// 等待中:直接结束;没成功(刚被续跑、已回到 queued)则按下面的常规路径中止。
|
|
1014
|
+
// the stop's terminal transaction owed the ensure-run backstop; the direct call starts what
|
|
1015
|
+
// waited for the stopped run now
|
|
998
1016
|
if (run.status === "waiting" && (await runs.abortWaiting(conversationId, run.id, accountId))) {
|
|
999
|
-
|
|
1017
|
+
await runs.ensureRunAfterCommit(conversationId);
|
|
1018
|
+
return run.id;
|
|
1019
|
+
}
|
|
1020
|
+
// a queued run no worker has started yet is ended in PG (ruling R27), never left to the stop
|
|
1021
|
+
// marker's TTL: the marker first, so a worker that takes it meanwhile stops too
|
|
1022
|
+
if (run.status === "queued") {
|
|
1023
|
+
await runs.requestAbort(run.id, accountId);
|
|
1024
|
+
if (await runs.abortQueued(conversationId, run.id, accountId)) {
|
|
1025
|
+
await runs.ensureRunAfterCommit(conversationId);
|
|
1026
|
+
}
|
|
1000
1027
|
return run.id;
|
|
1001
1028
|
}
|
|
1002
1029
|
// 孤儿运行没有 worker 在听中止广播:直接写成 aborted,之后再看有没有等待中的消息要起新一轮。
|
|
1003
1030
|
if (await runs.abortIfOrphaned(conversationId, run.id, accountId)) {
|
|
1004
|
-
|
|
1031
|
+
await runs.ensureRunAfterCommit(conversationId);
|
|
1005
1032
|
return run.id;
|
|
1006
1033
|
}
|
|
1007
1034
|
await runs.requestAbort(run.id, accountId);
|
|
@@ -1034,15 +1061,14 @@ ConversationsService = __decorate([
|
|
|
1034
1061
|
__param(3, Inject(ConversationAccess)),
|
|
1035
1062
|
__param(4, Inject(RunControlService)),
|
|
1036
1063
|
__param(5, Inject(ProviderRegistry)),
|
|
1037
|
-
__param(6, Inject(
|
|
1038
|
-
__param(7, Inject(
|
|
1039
|
-
__param(8, Inject(
|
|
1040
|
-
__param(9, Inject(
|
|
1041
|
-
__param(10, Inject(
|
|
1042
|
-
__param(11, Inject(
|
|
1043
|
-
__param(12, Inject(
|
|
1044
|
-
__param(13, Inject(
|
|
1045
|
-
__param(14, Inject(
|
|
1046
|
-
__param(15, Inject(TransactionHost))
|
|
1064
|
+
__param(6, Inject(ConnectorContent)),
|
|
1065
|
+
__param(7, Inject(AttachmentsService)),
|
|
1066
|
+
__param(8, Inject(SkillInvoker)),
|
|
1067
|
+
__param(9, Inject(BackgroundTaskStopper)),
|
|
1068
|
+
__param(10, Inject(ConversationDevices)),
|
|
1069
|
+
__param(11, Inject(QuestionsService)),
|
|
1070
|
+
__param(12, Inject(ApprovalsService)),
|
|
1071
|
+
__param(13, Inject(KernelEvents)),
|
|
1072
|
+
__param(14, Inject(TransactionHost))
|
|
1047
1073
|
], ConversationsService);
|
|
1048
1074
|
export { ConversationsService };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
2
2
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
3
|
-
import {
|
|
3
|
+
import { OutboxService } from "../infra/outbox/outbox.service.js";
|
|
4
4
|
import type { KernelLogger } from "../log.js";
|
|
5
5
|
import { type ConversationEvent, type ConversationEventType } from "./events.js";
|
|
6
6
|
/** 事件日志依赖的总线:内核 bus(命名空间 `kernel`)。 */
|
|
@@ -74,17 +74,17 @@ export type ConversationChange = (typeof CONVERSATION_CHANGES)[number];
|
|
|
74
74
|
* seq 由 `conversations.last_seq` 在会话行锁内连续分配(多副本并发写同一会话时串行化);
|
|
75
75
|
* 幂等键的「先查后写」也在同一把行锁内完成。
|
|
76
76
|
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
77
|
+
* An append to a conversation with a channel target (`channel_deliveries`, read with the row lock)
|
|
78
|
+
* owes the conversation's IM delivery in the append's transaction (transactional outbox spec
|
|
79
|
+
* §8.1); a conversation without one writes nothing more.
|
|
80
80
|
*/
|
|
81
81
|
export declare class EventLog {
|
|
82
82
|
private readonly db;
|
|
83
83
|
private readonly bus;
|
|
84
84
|
private readonly log;
|
|
85
|
-
private readonly
|
|
85
|
+
private readonly outbox;
|
|
86
86
|
readonly txHost: TransactionHost;
|
|
87
|
-
constructor(db: KernelDb, bus: EventBus, log: Pick<KernelLogger, "warn">,
|
|
87
|
+
constructor(db: KernelDb, bus: EventBus, log: Pick<KernelLogger, "warn">, outbox: Pick<OutboxService, "add">, txHost: TransactionHost);
|
|
88
88
|
/**
|
|
89
89
|
* 追加事件,返回与输入一一对应的事件(幂等命中的为已有事件)。
|
|
90
90
|
* 自开一个独立事务(`requires_new`,与调用方的事务无关),提交后发布 `conv.<id>`。
|
|
@@ -107,10 +107,7 @@ export declare class EventLog {
|
|
|
107
107
|
fresh: boolean[];
|
|
108
108
|
}>;
|
|
109
109
|
private appendOwn;
|
|
110
|
-
/**
|
|
111
|
-
* 发布「日志已推进到 toSeq」;发布失败只记日志(事件已提交,订阅方可按 seq 补读)。Then announces
|
|
112
|
-
* it in-process (`conversation.event-appended`); a failing subscriber is logged by KernelEvents.
|
|
113
|
-
*/
|
|
110
|
+
/** 发布「日志已推进到 toSeq」;发布失败只记日志(事件已提交,订阅方可按 seq 补读)。 */
|
|
114
111
|
notify(conversationId: string, toSeq: number): Promise<void>;
|
|
115
112
|
/**
|
|
116
113
|
* Publishes a `changed` frame on the conversation topic (rename, generated title, selection, ...).
|
|
@@ -9,11 +9,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
9
9
|
};
|
|
10
10
|
import { Inject, Injectable, Module } from "@nestjs/common";
|
|
11
11
|
import { sql } from "kysely";
|
|
12
|
+
import { oweDelivery } from "../channels/deliver-job.js";
|
|
12
13
|
import { ApiError } from "../errors.js";
|
|
13
14
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
14
15
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
15
16
|
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
16
|
-
import {
|
|
17
|
+
import { OutboxService } from "../infra/outbox/outbox.service.js";
|
|
17
18
|
import { KERNEL_BUS, KERNEL_LOGGER } from "../infra/tokens.js";
|
|
18
19
|
import { ConversationEventSchema, } from "./events.js";
|
|
19
20
|
/**
|
|
@@ -75,21 +76,21 @@ const EVENT_COLUMNS = [
|
|
|
75
76
|
* seq 由 `conversations.last_seq` 在会话行锁内连续分配(多副本并发写同一会话时串行化);
|
|
76
77
|
* 幂等键的「先查后写」也在同一把行锁内完成。
|
|
77
78
|
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
79
|
+
* An append to a conversation with a channel target (`channel_deliveries`, read with the row lock)
|
|
80
|
+
* owes the conversation's IM delivery in the append's transaction (transactional outbox spec
|
|
81
|
+
* §8.1); a conversation without one writes nothing more.
|
|
81
82
|
*/
|
|
82
83
|
let EventLog = class EventLog {
|
|
83
84
|
db;
|
|
84
85
|
bus;
|
|
85
86
|
log;
|
|
86
|
-
|
|
87
|
+
outbox;
|
|
87
88
|
txHost;
|
|
88
|
-
constructor(db, bus, log,
|
|
89
|
+
constructor(db, bus, log, outbox, txHost) {
|
|
89
90
|
this.db = db;
|
|
90
91
|
this.bus = bus;
|
|
91
92
|
this.log = log;
|
|
92
|
-
this.
|
|
93
|
+
this.outbox = outbox;
|
|
93
94
|
this.txHost = txHost;
|
|
94
95
|
}
|
|
95
96
|
/**
|
|
@@ -126,10 +127,7 @@ let EventLog = class EventLog {
|
|
|
126
127
|
const { events: out, toSeq } = await this.write(conversationId, events, bodies);
|
|
127
128
|
return { events: out, toSeq };
|
|
128
129
|
}
|
|
129
|
-
/**
|
|
130
|
-
* 发布「日志已推进到 toSeq」;发布失败只记日志(事件已提交,订阅方可按 seq 补读)。Then announces
|
|
131
|
-
* it in-process (`conversation.event-appended`); a failing subscriber is logged by KernelEvents.
|
|
132
|
-
*/
|
|
130
|
+
/** 发布「日志已推进到 toSeq」;发布失败只记日志(事件已提交,订阅方可按 seq 补读)。 */
|
|
133
131
|
async notify(conversationId, toSeq) {
|
|
134
132
|
const msg = { kind: "events", toSeq };
|
|
135
133
|
try {
|
|
@@ -138,7 +136,6 @@ let EventLog = class EventLog {
|
|
|
138
136
|
catch (err) {
|
|
139
137
|
this.log.warn("conversation event notify failed", { conversationId, toSeq, err });
|
|
140
138
|
}
|
|
141
|
-
await this.events.emit("conversation.event-appended", { conversationId, toSeq });
|
|
142
139
|
}
|
|
143
140
|
/**
|
|
144
141
|
* Publishes a `changed` frame on the conversation topic (rename, generated title, selection, ...).
|
|
@@ -300,10 +297,20 @@ let EventLog = class EventLog {
|
|
|
300
297
|
/** The append itself, in the context's transaction (both callers open or join one). */
|
|
301
298
|
async write(conversationId, events, bodies) {
|
|
302
299
|
const t = this.db;
|
|
303
|
-
// 先锁会话行:之后的幂等查询与 seq 分配都在这把锁内,并发 append 依次执行。
|
|
300
|
+
// 先锁会话行:之后的幂等查询与 seq 分配都在这把锁内,并发 append 依次执行。The same statement
|
|
301
|
+
// reads whether the conversation has a channel target (its primary key), under the lock that
|
|
302
|
+
// `ChannelJobs.bind` takes too
|
|
304
303
|
const conv = await t
|
|
305
304
|
.selectFrom("conversations")
|
|
306
|
-
.select(
|
|
305
|
+
.select((eb) => [
|
|
306
|
+
"org_id",
|
|
307
|
+
eb
|
|
308
|
+
.exists(eb
|
|
309
|
+
.selectFrom("channel_deliveries")
|
|
310
|
+
.select("channel_deliveries.conversation_id")
|
|
311
|
+
.whereRef("channel_deliveries.conversation_id", "=", "conversations.id"))
|
|
312
|
+
.as("im"),
|
|
313
|
+
])
|
|
307
314
|
.where("id", "=", conversationId)
|
|
308
315
|
.forUpdate()
|
|
309
316
|
.executeTakeFirst();
|
|
@@ -378,6 +385,8 @@ let EventLog = class EventLog {
|
|
|
378
385
|
}))
|
|
379
386
|
.returning(EVENT_COLUMNS)
|
|
380
387
|
.execute();
|
|
388
|
+
if (conv.im)
|
|
389
|
+
await oweDelivery(this.outbox, { conversationId, orgId: conv.org_id, seq: toSeq });
|
|
381
390
|
const bySeq = new Map(inserted.map((r) => [Number(r.seq), toEvent(r)]));
|
|
382
391
|
return {
|
|
383
392
|
events: plan.map((p) => p.kind === "old" ? p.event : bySeq.get(base + p.index + 1)),
|
|
@@ -400,7 +409,7 @@ EventLog = __decorate([
|
|
|
400
409
|
__param(0, Inject(KernelDb)),
|
|
401
410
|
__param(1, Inject(KERNEL_BUS)),
|
|
402
411
|
__param(2, Inject(KERNEL_LOGGER)),
|
|
403
|
-
__param(3, Inject(
|
|
412
|
+
__param(3, Inject(OutboxService)),
|
|
404
413
|
__param(4, Inject(TransactionHost))
|
|
405
414
|
], EventLog);
|
|
406
415
|
export { EventLog };
|
|
@@ -200,6 +200,20 @@ export declare const RunContextSchema: z.ZodObject<{
|
|
|
200
200
|
person: z.ZodString;
|
|
201
201
|
}, z.core.$strip>>;
|
|
202
202
|
}, z.core.$strip>;
|
|
203
|
+
/**
|
|
204
|
+
* The most UTF-8 bytes a `plugin_context` event's text may hold (memory spec §6.1): the providers'
|
|
205
|
+
* limit, so the log takes every text a provider may return.
|
|
206
|
+
*/
|
|
207
|
+
export declare const PLUGIN_CONTEXT_MAX_BYTES: number;
|
|
208
|
+
/**
|
|
209
|
+
* `plugin_context` (memory spec §6.1): the text a `context@1` provider added at a run start. Empty
|
|
210
|
+
* text means the provider has nothing (any more); `hash` is the sha256 (hex) of `text`.
|
|
211
|
+
*/
|
|
212
|
+
export declare const PluginContextSchema: z.ZodObject<{
|
|
213
|
+
plugin: z.ZodString;
|
|
214
|
+
text: z.ZodString;
|
|
215
|
+
hash: z.ZodString;
|
|
216
|
+
}, z.core.$strip>;
|
|
203
217
|
/**
|
|
204
218
|
* 会话事件(`type` + `payload`)的判别联合。事件日志只追加,写入前用它校验 payload;
|
|
205
219
|
* 读出时按写入时的形状原样返回。
|
|
@@ -547,6 +561,13 @@ export declare const ConversationEventSchema: z.ZodDiscriminatedUnion<[z.ZodObje
|
|
|
547
561
|
person: z.ZodString;
|
|
548
562
|
}, z.core.$strip>>;
|
|
549
563
|
}, z.core.$strip>;
|
|
564
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
565
|
+
type: z.ZodLiteral<"plugin_context">;
|
|
566
|
+
payload: z.ZodObject<{
|
|
567
|
+
plugin: z.ZodString;
|
|
568
|
+
text: z.ZodString;
|
|
569
|
+
hash: z.ZodString;
|
|
570
|
+
}, z.core.$strip>;
|
|
550
571
|
}, z.core.$strip>, z.ZodObject<{
|
|
551
572
|
type: z.ZodLiteral<"tools_changed">;
|
|
552
573
|
payload: z.ZodObject<{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DOCUMENT_MEDIA_TYPES, hasControlChars, IMAGE_MEDIA_TYPES, isAttachmentId, isSkillName, MEDIA_NAME_MAX_CHARS, } from "@capybara-hq/plugin-sdk";
|
|
1
|
+
import { CONTEXT_LIMITS, DOCUMENT_MEDIA_TYPES, hasControlChars, IMAGE_MEDIA_TYPES, isAttachmentId, isSkillName, MEDIA_NAME_MAX_CHARS, } from "@capybara-hq/plugin-sdk";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { AgentDefinitionSchema, DisabledSkillRef, DisabledToolRef, ModelRef, } from "../agents/definition.js";
|
|
4
4
|
import { ORG_ROLES } from "../orgs/roles.js";
|
|
@@ -228,6 +228,22 @@ export const RunContextSchema = z.object({
|
|
|
228
228
|
.optional(),
|
|
229
229
|
});
|
|
230
230
|
const ev = (type, payload) => z.object({ type: z.literal(type), payload });
|
|
231
|
+
/**
|
|
232
|
+
* The most UTF-8 bytes a `plugin_context` event's text may hold (memory spec §6.1): the providers'
|
|
233
|
+
* limit, so the log takes every text a provider may return.
|
|
234
|
+
*/
|
|
235
|
+
export const PLUGIN_CONTEXT_MAX_BYTES = CONTEXT_LIMITS.maxBytes;
|
|
236
|
+
/**
|
|
237
|
+
* `plugin_context` (memory spec §6.1): the text a `context@1` provider added at a run start. Empty
|
|
238
|
+
* text means the provider has nothing (any more); `hash` is the sha256 (hex) of `text`.
|
|
239
|
+
*/
|
|
240
|
+
export const PluginContextSchema = z.object({
|
|
241
|
+
plugin: z.string().min(1).max(64),
|
|
242
|
+
text: z.string().refine((t) => Buffer.byteLength(t, "utf8") <= PLUGIN_CONTEXT_MAX_BYTES, {
|
|
243
|
+
message: `at most ${PLUGIN_CONTEXT_MAX_BYTES} UTF-8 bytes`,
|
|
244
|
+
}),
|
|
245
|
+
hash: z.string().regex(/^[0-9a-f]{64}$/),
|
|
246
|
+
});
|
|
231
247
|
/**
|
|
232
248
|
* An agent definition frozen into a log (`subagent_started`): the current schema, with the
|
|
233
249
|
* selected and pinned skills of older logs still accepted (skills default-on spec §4: history
|
|
@@ -485,6 +501,13 @@ export const ConversationEventSchema = z.discriminatedUnion("type", [
|
|
|
485
501
|
* system message (`runContextText`); a summary covering it restores the current values.
|
|
486
502
|
*/
|
|
487
503
|
ev("run_context", RunContextSchema),
|
|
504
|
+
/**
|
|
505
|
+
* Text a `context@1` provider added at a run start (memory spec §6.1), written only when its
|
|
506
|
+
* hash differs from the plugin's previous one in the conversation. **Model-visible**: rendered
|
|
507
|
+
* at its position as a system message (`pluginContextText`, nothing for empty text); a summary
|
|
508
|
+
* covering it is followed by the latest non-empty one per plugin again.
|
|
509
|
+
*/
|
|
510
|
+
ev("plugin_context", PluginContextSchema),
|
|
488
511
|
/**
|
|
489
512
|
* The step's resolved tool set differs from the one the conversation's previous model request
|
|
490
513
|
* offered (`toolSetChange`): tool names as the model sees them, sorted. Written before that
|
|
@@ -776,7 +799,8 @@ export const ConversationEventSchema = z.discriminatedUnion("type", [
|
|
|
776
799
|
* naming a template's skills the child loads first (skills default-on spec §6.1).
|
|
777
800
|
*/
|
|
778
801
|
preamble: z.string(),
|
|
779
|
-
|
|
802
|
+
/** The child's step limit; 0 = no limit (`runtime.maxSteps` 0, no template limit). */
|
|
803
|
+
maxSteps: z.number().int().nonnegative(),
|
|
780
804
|
warnings: z.array(z.string()).optional(),
|
|
781
805
|
})),
|
|
782
806
|
/**
|
|
@@ -12,12 +12,12 @@ export declare class ConversationQueue {
|
|
|
12
12
|
private readonly db;
|
|
13
13
|
private readonly eventLog;
|
|
14
14
|
private readonly conversations;
|
|
15
|
-
/** Starts the conversation's next run (
|
|
15
|
+
/** Starts the conversation's next run after a commit (a failure is logged, never thrown). */
|
|
16
16
|
private readonly runs;
|
|
17
17
|
readonly txHost: TransactionHost;
|
|
18
18
|
constructor(db: KernelDb, eventLog: Pick<EventLog, "appendIn" | "notify" | "publishChanged" | "findByIdem">, conversations: Pick<ConversationsService, "get" | "writable" | "resolveExtra" | "bindIn" | "checkPick" | "prepareQueuedSkill" | "skipWaitsIn" | "announceSkipped">,
|
|
19
|
-
/** Starts the conversation's next run (
|
|
20
|
-
runs: Pick<RunControl, "
|
|
19
|
+
/** Starts the conversation's next run after a commit (a failure is logged, never thrown). */
|
|
20
|
+
runs: Pick<RunControl, "ensureRunAfterCommit" | "oweEnsureRun" | "wakeHeldTree" | "oweHeldTreeIn">, txHost: TransactionHost);
|
|
21
21
|
list(orgId: string, conversationId: string, accountId: string): Promise<{
|
|
22
22
|
items: QueueItem[];
|
|
23
23
|
paused: boolean;
|
|
@@ -60,6 +60,11 @@ export declare class ConversationQueue {
|
|
|
60
60
|
private sendNowIn;
|
|
61
61
|
/** "Continue sending": clears the pause and lets `ensureRun` send the head item. */
|
|
62
62
|
resume(orgId: string, conversationId: string, accountId: string): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Clears the pause and owes the ensure-run backstop that sends the head item (no event of its
|
|
65
|
+
* own, so under the conversation's newest seq; transactional outbox spec §6).
|
|
66
|
+
*/
|
|
67
|
+
private resumeIn;
|
|
63
68
|
/** A queued item or a sent message for this client id (outside any transaction). */
|
|
64
69
|
private prior;
|
|
65
70
|
private lockConversation;
|