@edspencer/paddock 0.0.1 → 0.56.0
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/README.md +69 -0
- package/install-notice.mjs +29 -0
- package/package.json +58 -5
- package/packages/server/dist/adoptable.d.ts +127 -0
- package/packages/server/dist/adoptable.js +315 -0
- package/packages/server/dist/app.d.ts +67 -0
- package/packages/server/dist/app.js +325 -0
- package/packages/server/dist/archive.d.ts +42 -0
- package/packages/server/dist/archive.js +125 -0
- package/packages/server/dist/attachments-config.d.ts +114 -0
- package/packages/server/dist/attachments-config.js +165 -0
- package/packages/server/dist/attachments-hint.d.ts +53 -0
- package/packages/server/dist/attachments-hint.js +140 -0
- package/packages/server/dist/attachments.d.ts +33 -0
- package/packages/server/dist/attachments.js +117 -0
- package/packages/server/dist/auth.d.ts +84 -0
- package/packages/server/dist/auth.js +247 -0
- package/packages/server/dist/background.d.ts +36 -0
- package/packages/server/dist/background.js +137 -0
- package/packages/server/dist/bind-safety.d.ts +56 -0
- package/packages/server/dist/bind-safety.js +51 -0
- package/packages/server/dist/brand.d.ts +44 -0
- package/packages/server/dist/brand.js +88 -0
- package/packages/server/dist/chat-dto.d.ts +210 -0
- package/packages/server/dist/chat-dto.js +308 -0
- package/packages/server/dist/cli/import-chats.d.ts +21 -0
- package/packages/server/dist/cli/import-chats.js +197 -0
- package/packages/server/dist/cli/paddock.d.ts +2 -0
- package/packages/server/dist/cli/paddock.js +247 -0
- package/packages/server/dist/concurrency.d.ts +57 -0
- package/packages/server/dist/concurrency.js +71 -0
- package/packages/server/dist/config.d.ts +512 -0
- package/packages/server/dist/config.js +593 -0
- package/packages/server/dist/curation-config.d.ts +55 -0
- package/packages/server/dist/curation-config.js +64 -0
- package/packages/server/dist/event-bus.d.ts +87 -0
- package/packages/server/dist/event-bus.js +48 -0
- package/packages/server/dist/git.d.ts +128 -0
- package/packages/server/dist/git.js +446 -0
- package/packages/server/dist/github-auth.d.ts +44 -0
- package/packages/server/dist/github-auth.js +169 -0
- package/packages/server/dist/herdctl-agent-config.d.ts +98 -0
- package/packages/server/dist/herdctl-agent-config.js +331 -0
- package/packages/server/dist/herdctl-agent-names.d.ts +172 -0
- package/packages/server/dist/herdctl-agent-names.js +228 -0
- package/packages/server/dist/herdctl-jobs-index.d.ts +65 -0
- package/packages/server/dist/herdctl-jobs-index.js +225 -0
- package/packages/server/dist/herdctl-jobs.d.ts +98 -0
- package/packages/server/dist/herdctl-jobs.js +225 -0
- package/packages/server/dist/herdctl.d.ts +572 -0
- package/packages/server/dist/herdctl.js +1218 -0
- package/packages/server/dist/hook-config.d.ts +217 -0
- package/packages/server/dist/hook-config.js +224 -0
- package/packages/server/dist/http-bytes.d.ts +24 -0
- package/packages/server/dist/http-bytes.js +52 -0
- package/packages/server/dist/index.d.ts +1 -0
- package/packages/server/dist/index.js +14 -0
- package/packages/server/dist/instance-config.d.ts +135 -0
- package/packages/server/dist/instance-config.js +345 -0
- package/packages/server/dist/localcommand.d.ts +23 -0
- package/packages/server/dist/localcommand.js +140 -0
- package/packages/server/dist/management-auth.d.ts +99 -0
- package/packages/server/dist/management-auth.js +165 -0
- package/packages/server/dist/management-config.d.ts +164 -0
- package/packages/server/dist/management-config.js +286 -0
- package/packages/server/dist/management-mcp-server.d.ts +20 -0
- package/packages/server/dist/management-mcp-server.js +95 -0
- package/packages/server/dist/management-metadata.d.ts +67 -0
- package/packages/server/dist/management-metadata.js +56 -0
- package/packages/server/dist/management-ops.d.ts +110 -0
- package/packages/server/dist/management-ops.js +449 -0
- package/packages/server/dist/management-policy.d.ts +172 -0
- package/packages/server/dist/management-policy.js +259 -0
- package/packages/server/dist/message-provenance.d.ts +112 -0
- package/packages/server/dist/message-provenance.js +260 -0
- package/packages/server/dist/models.d.ts +164 -0
- package/packages/server/dist/models.js +208 -0
- package/packages/server/dist/openapi.d.ts +66 -0
- package/packages/server/dist/openapi.js +183 -0
- package/packages/server/dist/parent-detach.d.ts +30 -0
- package/packages/server/dist/parent-detach.js +109 -0
- package/packages/server/dist/preload.d.ts +43 -0
- package/packages/server/dist/preload.js +55 -0
- package/packages/server/dist/project-files.d.ts +76 -0
- package/packages/server/dist/project-files.js +191 -0
- package/packages/server/dist/project-mime.d.ts +35 -0
- package/packages/server/dist/project-mime.js +55 -0
- package/packages/server/dist/project-paths.d.ts +88 -0
- package/packages/server/dist/project-paths.js +126 -0
- package/packages/server/dist/project-types.d.ts +316 -0
- package/packages/server/dist/project-types.js +48 -0
- package/packages/server/dist/projects.d.ts +202 -0
- package/packages/server/dist/projects.js +894 -0
- package/packages/server/dist/queued-message.d.ts +35 -0
- package/packages/server/dist/queued-message.js +116 -0
- package/packages/server/dist/read-state.d.ts +46 -0
- package/packages/server/dist/read-state.js +139 -0
- package/packages/server/dist/recovery-config.d.ts +111 -0
- package/packages/server/dist/recovery-config.js +105 -0
- package/packages/server/dist/recovery.d.ts +262 -0
- package/packages/server/dist/recovery.js +490 -0
- package/packages/server/dist/resume-drain.d.ts +122 -0
- package/packages/server/dist/resume-drain.js +158 -0
- package/packages/server/dist/route-context.d.ts +168 -0
- package/packages/server/dist/route-context.js +39 -0
- package/packages/server/dist/route-errors.d.ts +8 -0
- package/packages/server/dist/route-errors.js +13 -0
- package/packages/server/dist/routes/chats.d.ts +12 -0
- package/packages/server/dist/routes/chats.js +1406 -0
- package/packages/server/dist/routes/git.d.ts +13 -0
- package/packages/server/dist/routes/git.js +236 -0
- package/packages/server/dist/routes/mcp.d.ts +83 -0
- package/packages/server/dist/routes/mcp.js +250 -0
- package/packages/server/dist/routes/meta.d.ts +15 -0
- package/packages/server/dist/routes/meta.js +447 -0
- package/packages/server/dist/routes/projects.d.ts +25 -0
- package/packages/server/dist/routes/projects.js +736 -0
- package/packages/server/dist/routes/triggers.d.ts +21 -0
- package/packages/server/dist/routes/triggers.js +324 -0
- package/packages/server/dist/routes/workspace-mount.d.ts +48 -0
- package/packages/server/dist/routes/workspace-mount.js +32 -0
- package/packages/server/dist/routes.d.ts +26 -0
- package/packages/server/dist/routes.js +29 -0
- package/packages/server/dist/run-provenance.d.ts +109 -0
- package/packages/server/dist/run-provenance.js +206 -0
- package/packages/server/dist/runs.d.ts +92 -0
- package/packages/server/dist/runs.js +72 -0
- package/packages/server/dist/schedule-config.d.ts +68 -0
- package/packages/server/dist/schedule-config.js +75 -0
- package/packages/server/dist/schedule-session.d.ts +34 -0
- package/packages/server/dist/schedule-session.js +120 -0
- package/packages/server/dist/self-mcp-descriptions.d.ts +20 -0
- package/packages/server/dist/self-mcp-descriptions.js +145 -0
- package/packages/server/dist/self-mcp-read.d.ts +15 -0
- package/packages/server/dist/self-mcp-read.js +97 -0
- package/packages/server/dist/self-mcp-triggers.d.ts +30 -0
- package/packages/server/dist/self-mcp-triggers.js +144 -0
- package/packages/server/dist/self-mcp-types.d.ts +248 -0
- package/packages/server/dist/self-mcp-types.js +10 -0
- package/packages/server/dist/self-mcp-util.d.ts +73 -0
- package/packages/server/dist/self-mcp-util.js +157 -0
- package/packages/server/dist/self-mcp-write.d.ts +35 -0
- package/packages/server/dist/self-mcp-write.js +215 -0
- package/packages/server/dist/self-mcp.d.ts +95 -0
- package/packages/server/dist/self-mcp.js +448 -0
- package/packages/server/dist/send-file-mcp.d.ts +46 -0
- package/packages/server/dist/send-file-mcp.js +281 -0
- package/packages/server/dist/session-hub.d.ts +186 -0
- package/packages/server/dist/session-hub.js +291 -0
- package/packages/server/dist/spawn-capability.d.ts +99 -0
- package/packages/server/dist/spawn-capability.js +106 -0
- package/packages/server/dist/star.d.ts +26 -0
- package/packages/server/dist/star.js +94 -0
- package/packages/server/dist/start.d.ts +1 -0
- package/packages/server/dist/start.js +21 -0
- package/packages/server/dist/subagents.d.ts +337 -0
- package/packages/server/dist/subagents.js +626 -0
- package/packages/server/dist/sweep.d.ts +122 -0
- package/packages/server/dist/sweep.js +696 -0
- package/packages/server/dist/tooldetails.d.ts +33 -0
- package/packages/server/dist/tooldetails.js +466 -0
- package/packages/server/dist/transcribe.d.ts +69 -0
- package/packages/server/dist/transcribe.js +119 -0
- package/packages/server/dist/transcripts.d.ts +42 -0
- package/packages/server/dist/transcripts.js +164 -0
- package/packages/server/dist/trigger-config.d.ts +278 -0
- package/packages/server/dist/trigger-config.js +417 -0
- package/packages/server/dist/trigger-runtime.d.ts +94 -0
- package/packages/server/dist/trigger-runtime.js +82 -0
- package/packages/server/dist/trigger-session.d.ts +34 -0
- package/packages/server/dist/trigger-session.js +122 -0
- package/packages/server/dist/triggers.d.ts +83 -0
- package/packages/server/dist/triggers.js +124 -0
- package/packages/server/dist/trusted-proxy.d.ts +57 -0
- package/packages/server/dist/trusted-proxy.js +157 -0
- package/packages/server/dist/turn-notice.d.ts +154 -0
- package/packages/server/dist/turn-notice.js +271 -0
- package/packages/server/dist/unread.d.ts +36 -0
- package/packages/server/dist/unread.js +123 -0
- package/packages/server/dist/usage.d.ts +66 -0
- package/packages/server/dist/usage.js +243 -0
- package/packages/server/dist/wake-injection.d.ts +156 -0
- package/packages/server/dist/wake-injection.js +136 -0
- package/packages/server/dist/whisper-local.d.ts +9 -0
- package/packages/server/dist/whisper-local.js +122 -0
- package/packages/server/dist/ws-context.d.ts +158 -0
- package/packages/server/dist/ws-context.js +1 -0
- package/packages/server/dist/ws-protocol.d.ts +423 -0
- package/packages/server/dist/ws-protocol.js +251 -0
- package/packages/server/dist/ws-self-mcp.d.ts +52 -0
- package/packages/server/dist/ws-self-mcp.js +28 -0
- package/packages/server/dist/ws-triggers.d.ts +29 -0
- package/packages/server/dist/ws-triggers.js +261 -0
- package/packages/server/dist/ws-turn.d.ts +86 -0
- package/packages/server/dist/ws-turn.js +751 -0
- package/packages/server/dist/ws.d.ts +62 -0
- package/packages/server/dist/ws.js +1024 -0
- package/packages/server/package.json +6 -0
- package/packages/web/dist/assets/InstanceConfigPage-4cQGTj9Y.js +2 -0
- package/packages/web/dist/assets/MarkdownRenderer-CJZFLj_8.js +30 -0
- package/packages/web/dist/assets/ProjectRedirect-BHwVbbqB.js +2 -0
- package/packages/web/dist/assets/ProjectView-BOvuAITg.js +13 -0
- package/packages/web/dist/assets/ProjectsGrid-BCojZOGY.js +2 -0
- package/packages/web/dist/assets/arc-BVyxvnkl.js +2 -0
- package/packages/web/dist/assets/architectureDiagram-3BPJPVTR-Cd9Puqg1.js +37 -0
- package/packages/web/dist/assets/bash-I8pq0VWm.js +2 -0
- package/packages/web/dist/assets/blockDiagram-GPEHLZMM-B_AQt_Rx.js +133 -0
- package/packages/web/dist/assets/c-D2F1sQUL.js +2 -0
- package/packages/web/dist/assets/c4Diagram-AAUBKEIU-7e0TQtXB.js +11 -0
- package/packages/web/dist/assets/channel-C_1aISNn.js +2 -0
- package/packages/web/dist/assets/chunk-2J33WTMH-Dz4WZmUZ.js +2 -0
- package/packages/web/dist/assets/chunk-4BX2VUAB-DVWYldo6.js +2 -0
- package/packages/web/dist/assets/chunk-55IACEB6-BIMrizQd.js +2 -0
- package/packages/web/dist/assets/chunk-727SXJPM-CL2q9fF1.js +207 -0
- package/packages/web/dist/assets/chunk-AQP2D5EJ-BSq3HlQ9.js +232 -0
- package/packages/web/dist/assets/chunk-FMBD7UC4-Bgt64pLE.js +16 -0
- package/packages/web/dist/assets/chunk-ND2GUHAM-C8Pr2A38.js +2 -0
- package/packages/web/dist/assets/chunk-QZHKN3VN-BAOqh-MN.js +2 -0
- package/packages/web/dist/assets/classDiagram-4FO5ZUOK-B8JE7cHJ.js +2 -0
- package/packages/web/dist/assets/classDiagram-v2-Q7XG4LA2-B8JE7cHJ.js +2 -0
- package/packages/web/dist/assets/core-lJeGACQg.js +4 -0
- package/packages/web/dist/assets/cose-bilkent-S5V4N54A-BF4tameA.js +2 -0
- package/packages/web/dist/assets/cpp-Bm3ii6kY.js +2 -0
- package/packages/web/dist/assets/csharp-BNpuYZMG.js +2 -0
- package/packages/web/dist/assets/css-DazXZka4.js +2 -0
- package/packages/web/dist/assets/cytoscape.esm-CUqq0XTU.js +332 -0
- package/packages/web/dist/assets/dagre-BM42HDAG-DdsLM6ql.js +5 -0
- package/packages/web/dist/assets/defaultLocale-DX6XiGOO.js +2 -0
- package/packages/web/dist/assets/diagram-2AECGRRQ-BQ78S_RM.js +44 -0
- package/packages/web/dist/assets/diagram-5GNKFQAL-CAKE6nHE.js +11 -0
- package/packages/web/dist/assets/diagram-KO2AKTUF-fEvHRXgr.js +4 -0
- package/packages/web/dist/assets/diagram-LMA3HP47-CtWsgeSm.js +25 -0
- package/packages/web/dist/assets/diagram-OG6HWLK6-Buog8k7_.js +25 -0
- package/packages/web/dist/assets/erDiagram-TEJ5UH35-CWvVVPZS.js +86 -0
- package/packages/web/dist/assets/flowDiagram-I6XJVG4X-DsCGXtp4.js +163 -0
- package/packages/web/dist/assets/format-DamJQ9LO.js +2 -0
- package/packages/web/dist/assets/ganttDiagram-6RSMTGT7-CsdwIvvC.js +293 -0
- package/packages/web/dist/assets/gitGraphDiagram-PVQCEYII-hZvrX1sD.js +107 -0
- package/packages/web/dist/assets/go-BPx_y7j8.js +2 -0
- package/packages/web/dist/assets/graph-BlwPajkw.js +2 -0
- package/packages/web/dist/assets/index-CGbZdrm8.js +71 -0
- package/packages/web/dist/assets/index-DJDQ210-.css +1 -0
- package/packages/web/dist/assets/infoDiagram-5YYISTIA-nE_Vtz_l.js +3 -0
- package/packages/web/dist/assets/ini-B3BVgEsG.js +2 -0
- package/packages/web/dist/assets/init-Gi6I4Gst.js +2 -0
- package/packages/web/dist/assets/ishikawaDiagram-YF4QCWOH-2Nlqs0oH.js +71 -0
- package/packages/web/dist/assets/java-B5VKqtH2.js +2 -0
- package/packages/web/dist/assets/javascript-BKRaQes9.js +2 -0
- package/packages/web/dist/assets/journeyDiagram-JHISSGLW-mjU1fMc4.js +140 -0
- package/packages/web/dist/assets/json-DIYVocXf.js +2 -0
- package/packages/web/dist/assets/kanban-definition-UN3LZRKU-C_9xNaa3.js +90 -0
- package/packages/web/dist/assets/katex-C5jXJg4s.js +258 -0
- package/packages/web/dist/assets/kotlin-Cw-eF_bm.js +3 -0
- package/packages/web/dist/assets/lastTab-CU1zsF0j.js +2 -0
- package/packages/web/dist/assets/layout-Boy8vhSP.js +2 -0
- package/packages/web/dist/assets/linear-BxKd91ho.js +2 -0
- package/packages/web/dist/assets/mermaid.core-C-CuhD8I.js +310 -0
- package/packages/web/dist/assets/mindmap-definition-RKZ34NQL-Bs6yfcZv.js +97 -0
- package/packages/web/dist/assets/ordinal-Cboi1Yqb.js +2 -0
- package/packages/web/dist/assets/php-CRdd4dfS.js +3 -0
- package/packages/web/dist/assets/pieDiagram-4H26LBE5-DNdqX7O5.js +31 -0
- package/packages/web/dist/assets/python-kSlZHhJb.js +2 -0
- package/packages/web/dist/assets/quadrantDiagram-W4KKPZXB-ZMJl9OdZ.js +8 -0
- package/packages/web/dist/assets/queued-LamEU0GH.js +2 -0
- package/packages/web/dist/assets/requirementDiagram-4Y6WPE33-RmxMdm2q.js +85 -0
- package/packages/web/dist/assets/ruby-7T4ktxyv.js +2 -0
- package/packages/web/dist/assets/rust-HC3MBUhY.js +2 -0
- package/packages/web/dist/assets/sankeyDiagram-5OEKKPKP-OAAhWcfK.js +41 -0
- package/packages/web/dist/assets/scss-DZLA7YXz.js +2 -0
- package/packages/web/dist/assets/sequenceDiagram-3UESZ5HK-BWF7rCyN.js +163 -0
- package/packages/web/dist/assets/sql-BC88IN-V.js +2 -0
- package/packages/web/dist/assets/stateDiagram-AJRCARHV-M3b_zqqo.js +2 -0
- package/packages/web/dist/assets/stateDiagram-v2-BHNVJYJU-CI7saFDa.js +2 -0
- package/packages/web/dist/assets/swift-Dn8kKO_1.js +2 -0
- package/packages/web/dist/assets/timeline-definition-PNZ67QCA-BpOCh63N.js +121 -0
- package/packages/web/dist/assets/typescript-C2FFdlUC.js +2 -0
- package/packages/web/dist/assets/vennDiagram-CIIHVFJN-D_iPH45Q.js +35 -0
- package/packages/web/dist/assets/wardley-L42UT6IY-DVD9I2Om.js +174 -0
- package/packages/web/dist/assets/wardleyDiagram-YWT4CUSO-Bn1IKwjn.js +79 -0
- package/packages/web/dist/assets/xml-BXBhIUeX.js +2 -0
- package/packages/web/dist/assets/xychartDiagram-2RQKCTM6-DwtI0bkR.js +8 -0
- package/packages/web/dist/assets/yaml-drsDnIKT.js +2 -0
- package/packages/web/dist/favicon.ico +0 -0
- package/packages/web/dist/fonts/inter-latin.woff2 +0 -0
- package/packages/web/dist/fonts/jetbrains-mono-latin.woff2 +0 -0
- package/packages/web/dist/icons/apple-touch-icon.png +0 -0
- package/packages/web/dist/icons/favicon-16.png +0 -0
- package/packages/web/dist/icons/favicon-32.png +0 -0
- package/packages/web/dist/icons/icon-192.png +0 -0
- package/packages/web/dist/icons/icon-512.png +0 -0
- package/packages/web/dist/icons/maskable-512.png +0 -0
- package/packages/web/dist/index.html +56 -0
- package/packages/web/dist/manifest.webmanifest +32 -0
- package/packages/web/dist/sw.js +139 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared context types for the WebSocket chat handler (extracted #403).
|
|
3
|
+
*
|
|
4
|
+
* `makeChatHandler` in ws.ts closes over one `deps` bag plus a few shared inner
|
|
5
|
+
* closures (`startAgentTurn`, `composePreloadedPrompt`, `fireTrigger`, the hub).
|
|
6
|
+
* To split the ~2000-line handler into sibling modules (ws-self-mcp.ts,
|
|
7
|
+
* ws-triggers.ts, ws-turn.ts) those pieces need NAMED types instead of relying on
|
|
8
|
+
* closure scope — this module holds them. It has NO runtime imports from ws.ts, so
|
|
9
|
+
* both ws.ts and its siblings can import from here without an import cycle.
|
|
10
|
+
*/
|
|
11
|
+
import type { HerdctlService } from "./herdctl.js";
|
|
12
|
+
import type { ProjectStore } from "./projects.js";
|
|
13
|
+
import type { SweepService } from "./sweep.js";
|
|
14
|
+
import type { PaddockConfig } from "./config.js";
|
|
15
|
+
import type { DriveMode } from "./models.js";
|
|
16
|
+
import type { SessionHub } from "./session-hub.js";
|
|
17
|
+
import type { AttachmentStore } from "./attachments.js";
|
|
18
|
+
import type { QueuedMessageStore } from "./queued-message.js";
|
|
19
|
+
import type { ArchiveStore } from "./archive.js";
|
|
20
|
+
import type { ScheduleSessionStore } from "./schedule-session.js";
|
|
21
|
+
import type { RunProvenanceStore, TurnOrigin } from "./run-provenance.js";
|
|
22
|
+
import type { MessageProvenanceStore, MessageSender } from "./message-provenance.js";
|
|
23
|
+
import type { PaddockEventBus } from "./event-bus.js";
|
|
24
|
+
import type { TriggerService } from "./triggers.js";
|
|
25
|
+
import type { TriggerSessionStore } from "./trigger-session.js";
|
|
26
|
+
/**
|
|
27
|
+
* The store/service bag `makeChatHandler` is constructed with. Extracted to a
|
|
28
|
+
* named interface (#403) so the handler's extracted sibling modules can accept it
|
|
29
|
+
* by type instead of closing over it.
|
|
30
|
+
*/
|
|
31
|
+
export interface ChatHandlerDeps {
|
|
32
|
+
herdctl: HerdctlService;
|
|
33
|
+
projects: ProjectStore;
|
|
34
|
+
attachments: AttachmentStore;
|
|
35
|
+
/** Server config — carries the global keeper drive-mode default (Paddock#111). */
|
|
36
|
+
cfg: PaddockConfig;
|
|
37
|
+
/** Optional: post-turn overview/changelog curation engine (issues #2/#6). */
|
|
38
|
+
sweep?: SweepService;
|
|
39
|
+
/** Per-chat queued message persistence (#197). */
|
|
40
|
+
queuedMessage?: QueuedMessageStore;
|
|
41
|
+
/**
|
|
42
|
+
* Per-chat provenance sidecar (issue #261 / DD-3, DD-6): records how each chat
|
|
43
|
+
* was created (origin human/scheduled/spawned + spawn depth) so #262 can
|
|
44
|
+
* depth-gate spawning and #267 can badge provenance. A1 only carries/persists
|
|
45
|
+
* the marker — nothing gates on it yet.
|
|
46
|
+
*/
|
|
47
|
+
runProvenance?: RunProvenanceStore;
|
|
48
|
+
/**
|
|
49
|
+
* Per-MESSAGE provenance sidecar (issue #290): records WHO injected each
|
|
50
|
+
* machine-added turn (send_message / schedule / spawn kickoff) keyed by the
|
|
51
|
+
* TARGET session, so the chat history can attribute injected turns. Optional so
|
|
52
|
+
* existing tests need not supply it; absent ⇒ injected turns just render as
|
|
53
|
+
* unlabelled user bubbles (today's behaviour).
|
|
54
|
+
*/
|
|
55
|
+
messageProvenance?: MessageProvenanceStore;
|
|
56
|
+
/**
|
|
57
|
+
* Per-chat archived-flag sidecar (#95). Used by the self-MCP archive_chat /
|
|
58
|
+
* unarchive_chat write tools (#263) so a keeper can file a chat away — most
|
|
59
|
+
* usefully ITSELF, powering the "work → archive myself on success" convention.
|
|
60
|
+
*/
|
|
61
|
+
archive: ArchiveStore;
|
|
62
|
+
/**
|
|
63
|
+
* Owned-session sidecar for accreting schedules (issue #265 / DD-2): maps a
|
|
64
|
+
* `resume_session: true` schedule to the one chat it owns, created on its first
|
|
65
|
+
* fire and reused thereafter. Absent ⇒ scheduled chats still work but every
|
|
66
|
+
* accreting schedule would start fresh each fire (degrades to `resume_session:
|
|
67
|
+
* false`); wired in production, optional so existing tests need not supply it.
|
|
68
|
+
*/
|
|
69
|
+
scheduleSessions?: ScheduleSessionStore;
|
|
70
|
+
/**
|
|
71
|
+
* In-process lifecycle event bus (Epic T). When present (with {@link triggers}),
|
|
72
|
+
* this handler subscribes to lifecycle events (v1: `onArchive`) and fires each of
|
|
73
|
+
* the project's ENABLED matching EVENT triggers as its own `trigger-<slug>-<name>`
|
|
74
|
+
* agent turn via {@link startAgentTurn}. Absent ⇒ no event-trigger dispatch, so
|
|
75
|
+
* tests that don't exercise triggers need not supply it.
|
|
76
|
+
*/
|
|
77
|
+
events?: PaddockEventBus;
|
|
78
|
+
/**
|
|
79
|
+
* Unified trigger registry (Epic T / T1). When present, this handler fires the
|
|
80
|
+
* project's enabled EVENT triggers (via the {@link events} bus) and its SCHEDULE
|
|
81
|
+
* triggers (via herdctl's `setScheduleTriggerHandler`) through the SAME
|
|
82
|
+
* {@link startAgentTurn} core — the single execution engine for every trigger. Absent
|
|
83
|
+
* ⇒ no trigger dispatch, so tests that don't exercise triggers need not supply it.
|
|
84
|
+
*/
|
|
85
|
+
triggers?: TriggerService;
|
|
86
|
+
/**
|
|
87
|
+
* Owned-session sidecar for accreting triggers (`run.session: "resume"`, Epic T /
|
|
88
|
+
* T1) — maps a resume-type trigger to the one chat it accretes into across fires,
|
|
89
|
+
* created on its first fire and rebound off this store after a restart. Absent ⇒
|
|
90
|
+
* resume-type triggers degrade to a fresh chat each fire; wired in production,
|
|
91
|
+
* optional so existing tests need not supply it.
|
|
92
|
+
*/
|
|
93
|
+
triggerSessions?: TriggerSessionStore;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Options for the shared per-turn execution engine `startAgentTurn` (ws-turn.ts /
|
|
97
|
+
* ws.ts). Named here so the sibling modules that RECEIVE `startAgentTurn` as a
|
|
98
|
+
* context callback (self-MCP write tools, trigger firing) can type it.
|
|
99
|
+
*/
|
|
100
|
+
export interface StartAgentTurnOpts {
|
|
101
|
+
projectSlug: string;
|
|
102
|
+
agentName: string;
|
|
103
|
+
workingDir: string;
|
|
104
|
+
resume: string | null;
|
|
105
|
+
prompt: string;
|
|
106
|
+
driveMode: DriveMode;
|
|
107
|
+
fallbackModel: string;
|
|
108
|
+
/**
|
|
109
|
+
* Provenance of this server-initiated turn (issue #261 / DD-3). The self-MCP
|
|
110
|
+
* write tools pass `spawned` + the child's depth. Persisted for a NEW chat
|
|
111
|
+
* only (a resume/message keeps the target chat's existing marker).
|
|
112
|
+
*/
|
|
113
|
+
origin: TurnOrigin;
|
|
114
|
+
depth: number;
|
|
115
|
+
/**
|
|
116
|
+
* The chat that CREATED this one, when a chat did (issue #509). Stamped
|
|
117
|
+
* alongside `origin`/`depth` for a NEW chat, giving the nested chat list a
|
|
118
|
+
* RECORDED parent edge instead of leaving it to infer one from the kickoff
|
|
119
|
+
* message's sender.
|
|
120
|
+
*
|
|
121
|
+
* Absent when no calling chat exists — a schedule/hook fire, or the external
|
|
122
|
+
* `/mcp` transport (which binds `currentSessionId: () => null`).
|
|
123
|
+
*/
|
|
124
|
+
parent?: {
|
|
125
|
+
project: string;
|
|
126
|
+
sessionId: string;
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* The effective `maxSpawnDepth` for the chat this turn runs in (issue #262),
|
|
130
|
+
* already resolved by the caller from the TARGET project (per-project override
|
|
131
|
+
* else instance default). Gates whether this turn receives the self-MCP.
|
|
132
|
+
*/
|
|
133
|
+
maxSpawnDepth: number;
|
|
134
|
+
/**
|
|
135
|
+
* WHO caused this injected turn (issue #290). Present for a machine injection
|
|
136
|
+
* (another chat `send_message` / a schedule fire / a spawn kickoff); absent for
|
|
137
|
+
* a turn with no attributable non-human sender.
|
|
138
|
+
*/
|
|
139
|
+
sender?: MessageSender;
|
|
140
|
+
}
|
|
141
|
+
/** The shared per-turn execution engine — resolves the chat's sessionId as soon as known. */
|
|
142
|
+
export type StartAgentTurn = (opts: StartAgentTurnOpts) => Promise<string>;
|
|
143
|
+
/** Resolve a preloaded (OVERVIEW+CHANGELOG) prompt for a new chat (issues #1/#188). */
|
|
144
|
+
export type ComposePreloadedPrompt = (projectSlug: string, baseMessage: string) => Promise<string>;
|
|
145
|
+
/** Fire a project's named trigger on demand; resolves the started chat's id or null. */
|
|
146
|
+
export type FireTrigger = (slug: string, triggerName: string) => Promise<string | null>;
|
|
147
|
+
/**
|
|
148
|
+
* The context the self-MCP builder + trigger-firing cluster need: the deps bag,
|
|
149
|
+
* the shared hub, and the shared inner closures. Assembled once in ws.ts and
|
|
150
|
+
* passed to the extracted sibling functions.
|
|
151
|
+
*/
|
|
152
|
+
export interface ChatHandlerContext {
|
|
153
|
+
deps: ChatHandlerDeps;
|
|
154
|
+
hub: SessionHub;
|
|
155
|
+
startAgentTurn: StartAgentTurn;
|
|
156
|
+
composePreloadedPrompt: ComposePreloadedPrompt;
|
|
157
|
+
fireTrigger: FireTrigger;
|
|
158
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebSocket wire protocol + token/usage math (extracted from ws.ts, issue #403).
|
|
3
|
+
*
|
|
4
|
+
* Pure types + pure functions — no closure ties, no store/service dependencies.
|
|
5
|
+
* Holds:
|
|
6
|
+
* - the client->server and server->client message interfaces + unions,
|
|
7
|
+
* - the {@link isClientMessage} runtime guard,
|
|
8
|
+
* - the per-turn usage extraction/fold/resolve helpers.
|
|
9
|
+
*
|
|
10
|
+
* `ws.ts` re-exports every symbol here so external importers (and tests) that
|
|
11
|
+
* `import … from "./ws.js"` continue to resolve unchanged.
|
|
12
|
+
*
|
|
13
|
+
* See ws.ts's module doc comment for the on-the-wire protocol narrative.
|
|
14
|
+
*/
|
|
15
|
+
import type { SDKMessage } from "@herdctl/core";
|
|
16
|
+
import type { TurnNotice } from "./turn-notice.js";
|
|
17
|
+
/**
|
|
18
|
+
* Per-turn token usage as observed on the SDK stream, normalized to camelCase.
|
|
19
|
+
* Read defensively from either an assistant message (`m.message.usage`) or the
|
|
20
|
+
* final result message (`m.usage`) — fields are loosely typed in core.
|
|
21
|
+
*/
|
|
22
|
+
export interface TurnUsage {
|
|
23
|
+
inputTokens: number;
|
|
24
|
+
outputTokens: number;
|
|
25
|
+
cacheReadTokens: number;
|
|
26
|
+
cacheCreationTokens: number;
|
|
27
|
+
}
|
|
28
|
+
/** A model id seen on the SDK stream paired (best-effort) with its usage. */
|
|
29
|
+
interface ExtractedUsage {
|
|
30
|
+
usage: TurnUsage | null;
|
|
31
|
+
model: string | null;
|
|
32
|
+
/**
|
|
33
|
+
* True when this usage came from the terminal `type:"result"` SDK message,
|
|
34
|
+
* whose `usage` is a CUMULATIVE per-turn total aggregated across every internal
|
|
35
|
+
* API call (num_turns), not a single context-window snapshot (#398). Such a
|
|
36
|
+
* block must never feed the context-snapshot meter.
|
|
37
|
+
*/
|
|
38
|
+
fromResult: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Defensively extract per-turn usage + model from a raw SDK message. The SDK's
|
|
42
|
+
* `message` is typed `unknown` in core, and the CLI/SDK runtimes shape usage
|
|
43
|
+
* slightly differently, so every field access is guarded.
|
|
44
|
+
*
|
|
45
|
+
* - assistant message: `m.message.usage` (Anthropic usage block) + `m.message.model`.
|
|
46
|
+
* - result message: top-level `m.usage` (same field names). Flagged `fromResult`
|
|
47
|
+
* because that block is a cumulative per-turn total, not a snapshot (#398).
|
|
48
|
+
*
|
|
49
|
+
* Returns `{ usage: null, model: null, fromResult: false }` when neither is present.
|
|
50
|
+
*/
|
|
51
|
+
export declare function extractUsage(m: SDKMessage): ExtractedUsage;
|
|
52
|
+
/**
|
|
53
|
+
* The rendered output of a client-local slash command (`/context`, `/usage`, …) to
|
|
54
|
+
* surface as an assistant note, or null when this SDK message isn't one (issue #158).
|
|
55
|
+
*
|
|
56
|
+
* The interactive TUI renders these locally; a non-interactive SDK session (Paddock's
|
|
57
|
+
* path) instead surfaces the output as EITHER a `type:"system"` / `local_command`
|
|
58
|
+
* entry (its `content` wraps the output in `<local-command-stdout>…`) or a
|
|
59
|
+
* `model:"<synthetic>"` assistant placeholder carrying the text. @herdctl/chat's
|
|
60
|
+
* translator drops both (synthetic messages are skipped; system entries aren't text),
|
|
61
|
+
* so the live command turn would otherwise read as a silent no-op. We recover the text
|
|
62
|
+
* and emit it as an assistant note (mirroring the `compact_boundary` special-case),
|
|
63
|
+
* consistent with the history-path recovery in `localcommand.ts`. Bare placeholders
|
|
64
|
+
* (e.g. `/compact`'s "No response requested.") yield null so they stay quiet. Paddock's
|
|
65
|
+
* own context ring + cost meter remain the primary usage view; this just stops the
|
|
66
|
+
* output vanishing.
|
|
67
|
+
*/
|
|
68
|
+
export declare function extractLocalCommandOutput(m: SDKMessage): string | null;
|
|
69
|
+
/**
|
|
70
|
+
* Merge two context-snapshot usage blocks, keeping whichever best reflects the
|
|
71
|
+
* context window (issue #165). Only assistant / partial-assistant blocks are ever
|
|
72
|
+
* passed here — the terminal `result` block is folded separately (see
|
|
73
|
+
* {@link foldTurnUsage}), because its usage is cumulative, not a snapshot (#398).
|
|
74
|
+
*
|
|
75
|
+
* Assistant usage grows monotonically through a turn (each round re-reads the
|
|
76
|
+
* cached prefix), so "last assistant" == "max assistant". We still keep the MAX
|
|
77
|
+
* `contextTokens` (input + cacheRead + cacheCreation) defensively: an odd
|
|
78
|
+
* cache-less block can never LOWER the snapshot. `outputTokens` keeps the max
|
|
79
|
+
* seen.
|
|
80
|
+
*/
|
|
81
|
+
export declare function pickTurnUsage(prev: TurnUsage | null, next: TurnUsage): TurnUsage;
|
|
82
|
+
/**
|
|
83
|
+
* Running per-turn usage, keeping the context snapshot and the terminal result's
|
|
84
|
+
* cumulative totals STRICTLY SEPARATE (#398).
|
|
85
|
+
*
|
|
86
|
+
* The `result` SDK message's `usage` (`SDKResultSuccess.usage`) is a cumulative
|
|
87
|
+
* sum across every internal API call in the turn (`num_turns`) — on a long
|
|
88
|
+
* tool-heavy turn it dwarfs any single assistant block. Feeding it into the
|
|
89
|
+
* snapshot (as the old MAX heuristic did) inflated the live context meter (e.g.
|
|
90
|
+
* 828k when the true window was ~292k), only to be corrected on refresh from
|
|
91
|
+
* disk. So we route it to `cumulative` and never let it touch the snapshot.
|
|
92
|
+
*/
|
|
93
|
+
export interface TurnUsageState {
|
|
94
|
+
/** Context-window snapshot from assistant / partial-assistant messages. */
|
|
95
|
+
snapshot: TurnUsage | null;
|
|
96
|
+
/** Terminal result's cumulative per-turn totals — for cost/output only, never contextTokens. */
|
|
97
|
+
cumulative: TurnUsage | null;
|
|
98
|
+
/** Most recent model id seen paired with usage. */
|
|
99
|
+
model: string | null;
|
|
100
|
+
}
|
|
101
|
+
/** A fresh, empty per-turn usage accumulator. */
|
|
102
|
+
export declare function initTurnUsage(): TurnUsageState;
|
|
103
|
+
/**
|
|
104
|
+
* Fold one raw SDK message into the running usage state. Mirrors exactly what the
|
|
105
|
+
* ws.ts stream loop does, so tests can drive it the same way. Assistant usage
|
|
106
|
+
* accumulates into the context snapshot; the terminal `result` block is stashed
|
|
107
|
+
* separately as the turn's cumulative total (#398).
|
|
108
|
+
*/
|
|
109
|
+
export declare function foldTurnUsage(state: TurnUsageState, m: SDKMessage): TurnUsageState;
|
|
110
|
+
/**
|
|
111
|
+
* Resolve the final per-turn usage emitted on `chat:complete`. `contextTokens`
|
|
112
|
+
* always derives from the snapshot (the true window). The cumulative result block
|
|
113
|
+
* is used only to lift `outputTokens` to the turn's final total, and as a
|
|
114
|
+
* last-resort fallback for context if NO assistant usage was seen this turn (some
|
|
115
|
+
* runtimes emit usage only on the result — there cumulative == the single call).
|
|
116
|
+
*/
|
|
117
|
+
export declare function resolveTurnUsage(state: TurnUsageState): TurnUsage | null;
|
|
118
|
+
export interface ChatSendMessage {
|
|
119
|
+
type: "chat:send";
|
|
120
|
+
payload: {
|
|
121
|
+
/**
|
|
122
|
+
* Workspace key: a project slug. `""` is the ROOT workspace — a present
|
|
123
|
+
* empty string, not an absent value, so test it with `=== undefined`,
|
|
124
|
+
* never for falsiness.
|
|
125
|
+
*/
|
|
126
|
+
projectSlug?: string;
|
|
127
|
+
/** Session to resume; null/omitted starts a new chat. */
|
|
128
|
+
sessionId?: string | null;
|
|
129
|
+
message: string;
|
|
130
|
+
/**
|
|
131
|
+
* When true AND this is a NEW chat (sessionId null/omitted) AND the project
|
|
132
|
+
* has an OVERVIEW.md, prepend that overview to the prompt as a delimited
|
|
133
|
+
* context block (issue #1). No-op when no overview exists.
|
|
134
|
+
*/
|
|
135
|
+
preloadContext?: boolean;
|
|
136
|
+
/**
|
|
137
|
+
* Optional per-chat model override (a known model id). Unknown/absent ->
|
|
138
|
+
* the workspace's persisted model, else the keeper default. The keeper agent
|
|
139
|
+
* is re-registered at this model before triggering. (§7.)
|
|
140
|
+
*/
|
|
141
|
+
model?: string;
|
|
142
|
+
/**
|
|
143
|
+
* Files the user attached in the composer (issue #328). Each references an
|
|
144
|
+
* attachment already uploaded via `POST …/chats/:id/upload` (bytes in the
|
|
145
|
+
* store). The server validates them against the project's effective attachment
|
|
146
|
+
* config, then prepends a `<paddock-attachments>` hint block to the prompt
|
|
147
|
+
* pointing the keeper's `Read` tool at the absolute paths. Project chats only.
|
|
148
|
+
*/
|
|
149
|
+
attachments?: Array<{
|
|
150
|
+
id: string;
|
|
151
|
+
filename: string;
|
|
152
|
+
kind?: string;
|
|
153
|
+
}>;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
export interface ChatCancelMessage {
|
|
157
|
+
type: "chat:cancel";
|
|
158
|
+
payload: {
|
|
159
|
+
jobId: string;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Run a slash command (e.g. `/compact`) in the current chat.
|
|
164
|
+
*
|
|
165
|
+
* Unlike `chat:send`, this drives herdctl's streaming session so the CLI
|
|
166
|
+
* dispatches the command instead of treating the text as a plain prompt. The
|
|
167
|
+
* command acts on the resumed `sessionId`, so `/compact` compacts the real
|
|
168
|
+
* chat history. Output streams back over the same `chat:response` /
|
|
169
|
+
* `chat:tool_call` / `chat:complete` events as a normal turn.
|
|
170
|
+
*/
|
|
171
|
+
export interface ChatCommandMessage {
|
|
172
|
+
type: "chat:command";
|
|
173
|
+
payload: {
|
|
174
|
+
projectSlug?: string;
|
|
175
|
+
/** Session the command runs against. Required (a command needs a chat). */
|
|
176
|
+
sessionId?: string | null;
|
|
177
|
+
/** The full command text, including the leading slash (e.g. "/compact"). */
|
|
178
|
+
command: string;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Attach a socket to a session's live stream (issue #54). Sent on (re)connect so
|
|
183
|
+
* a socket that dropped mid-turn can re-attach to the still-running turn and be
|
|
184
|
+
* replayed the frames it missed.
|
|
185
|
+
*
|
|
186
|
+
* `wantReplay` MUST be false on a fresh mount (which also hydrates the transcript
|
|
187
|
+
* over REST) so buffered frames don't duplicate the transcript; it is true only
|
|
188
|
+
* for a genuine reconnect of a socket that was mid-turn, with `lastSeq` = the
|
|
189
|
+
* last per-turn `seq` the client applied (the replay is exactly the gap after it).
|
|
190
|
+
*/
|
|
191
|
+
export interface ChatSubscribeMessage {
|
|
192
|
+
type: "chat:subscribe";
|
|
193
|
+
payload: {
|
|
194
|
+
projectSlug?: string;
|
|
195
|
+
/** The session to attach to. Required. */
|
|
196
|
+
sessionId: string;
|
|
197
|
+
/** Replay the missed gap of a live turn (reconnect); false = future frames only. */
|
|
198
|
+
wantReplay?: boolean;
|
|
199
|
+
/** Last per-turn `seq` the client applied; the server replays everything after it. */
|
|
200
|
+
lastSeq?: number;
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Store a queued message to be auto-sent when the current turn completes (#197).
|
|
205
|
+
* The client sends this to persist the queue server-side so it survives browser
|
|
206
|
+
* close; the server stores it, checks after turn completion, and auto-sends if
|
|
207
|
+
* present. The web client also keeps a localStorage copy for live editing UX.
|
|
208
|
+
*/
|
|
209
|
+
export interface ChatSetQueueMessage {
|
|
210
|
+
type: "chat:set_queue";
|
|
211
|
+
payload: {
|
|
212
|
+
projectSlug?: string;
|
|
213
|
+
sessionId?: string | null;
|
|
214
|
+
/** The queued message text, or null/empty to clear. */
|
|
215
|
+
text?: string | null;
|
|
216
|
+
/**
|
|
217
|
+
* Client-stamped identity of this queued message (#245): the ms timestamp of
|
|
218
|
+
* when it was first enqueued, stable across reloads. The server records the ts
|
|
219
|
+
* of the message it last drained per session so it can skip re-sending a stale
|
|
220
|
+
* copy a reloaded client re-asserts. Absent → the server stamps `Date.now()`.
|
|
221
|
+
*/
|
|
222
|
+
ts?: number | null;
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Manually re-drive a keeper that hung because its background task was killed at
|
|
227
|
+
* the turn boundary (issue #301, Layer 2). The keeper's session stayed ALIVE (see
|
|
228
|
+
* edspencer/herdctl#374) so it's still injectable — this action injects a recovery
|
|
229
|
+
* nudge into it via {@link startAgentTurn}, exactly the message a human sends by
|
|
230
|
+
* hand today to unstick it, but one click and correctly attributed
|
|
231
|
+
* (`sender: { kind: "recovery" }`). Gated server-side on the resolved
|
|
232
|
+
* `recovery.surfaceKilledTask` (per-project override else instance default), so a
|
|
233
|
+
* client can't re-drive when the operator turned Layer 2 off.
|
|
234
|
+
*/
|
|
235
|
+
export interface ChatContinueMessage {
|
|
236
|
+
type: "chat:continue";
|
|
237
|
+
payload: {
|
|
238
|
+
projectSlug?: string;
|
|
239
|
+
/** The hung keeper session to re-drive. Required (recovery needs a chat). */
|
|
240
|
+
sessionId: string;
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
export interface PingMessage {
|
|
244
|
+
type: "ping";
|
|
245
|
+
}
|
|
246
|
+
export type ClientMessage = ChatSendMessage | ChatCommandMessage | ChatCancelMessage | ChatSubscribeMessage | ChatSetQueueMessage | ChatContinueMessage | PingMessage;
|
|
247
|
+
export interface Routing {
|
|
248
|
+
projectSlug: string;
|
|
249
|
+
sessionId: string | null;
|
|
250
|
+
jobId: string | null;
|
|
251
|
+
/**
|
|
252
|
+
* Per-turn, monotonic sequence number stamped by the SessionHub as the frame
|
|
253
|
+
* is emitted (issue #54). Lets a reconnecting client tell the server the last
|
|
254
|
+
* frame it applied so the exact missed gap can be replayed. Absent on frames
|
|
255
|
+
* not routed through the hub (e.g. chat:error).
|
|
256
|
+
*/
|
|
257
|
+
seq?: number;
|
|
258
|
+
}
|
|
259
|
+
export interface ChatResponseMessage {
|
|
260
|
+
type: "chat:response";
|
|
261
|
+
payload: Routing & {
|
|
262
|
+
chunk: string;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
export interface ChatToolCallMessage {
|
|
266
|
+
type: "chat:tool_call";
|
|
267
|
+
payload: Routing & {
|
|
268
|
+
toolName: string;
|
|
269
|
+
inputSummary?: string;
|
|
270
|
+
output: string;
|
|
271
|
+
isError: boolean;
|
|
272
|
+
durationMs?: number;
|
|
273
|
+
/**
|
|
274
|
+
* The originating tool_use id. Lets a client reconcile this completion with
|
|
275
|
+
* the pending row it created on the earlier `chat:tool_start` frame (#175).
|
|
276
|
+
*/
|
|
277
|
+
toolUseId?: string;
|
|
278
|
+
subagentType?: string;
|
|
279
|
+
description?: string;
|
|
280
|
+
hasSubagent?: boolean;
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* An in-flight tool_use, emitted the moment the tool STARTS — before it runs or
|
|
285
|
+
* produces a result (#175). Lets a client render a pending "running…" row for
|
|
286
|
+
* slow tools (especially subagents that run for minutes), keyed by `toolUseId`,
|
|
287
|
+
* then reconcile it when the matching `chat:tool_call` completion arrives.
|
|
288
|
+
* Sourced from `@herdctl/chat`'s `onToolStart` (v0.6.0+).
|
|
289
|
+
*/
|
|
290
|
+
export interface ChatToolStartMessage {
|
|
291
|
+
type: "chat:tool_start";
|
|
292
|
+
payload: Routing & {
|
|
293
|
+
toolName: string;
|
|
294
|
+
inputSummary?: string;
|
|
295
|
+
toolUseId?: string;
|
|
296
|
+
/** Subagent attribution: null = main agent, else the spawning Task tool_use id. */
|
|
297
|
+
parentToolUseId: string | null;
|
|
298
|
+
subagentType?: string;
|
|
299
|
+
description?: string;
|
|
300
|
+
hasSubagent?: boolean;
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
export interface ChatMessageBoundaryMessage {
|
|
304
|
+
type: "chat:message_boundary";
|
|
305
|
+
payload: Routing;
|
|
306
|
+
}
|
|
307
|
+
/** Per-turn token usage surfaced on chat:complete (camelCase, with the meter math). */
|
|
308
|
+
export interface ChatCompleteUsage {
|
|
309
|
+
inputTokens: number;
|
|
310
|
+
outputTokens: number;
|
|
311
|
+
cacheReadTokens: number;
|
|
312
|
+
cacheCreationTokens: number;
|
|
313
|
+
/** input + cacheRead + cacheCreation (what the context window holds). */
|
|
314
|
+
contextTokens: number;
|
|
315
|
+
/** getContextLimit(model). */
|
|
316
|
+
contextLimit: number;
|
|
317
|
+
}
|
|
318
|
+
export interface ChatCompleteMessage {
|
|
319
|
+
type: "chat:complete";
|
|
320
|
+
payload: Routing & {
|
|
321
|
+
success: boolean;
|
|
322
|
+
error?: string;
|
|
323
|
+
/** The model this turn ran on (lastModel ?? effectiveModel). Omitted if unknown. */
|
|
324
|
+
model?: string;
|
|
325
|
+
/** Last per-turn usage observed; omitted (with model) if none was seen. */
|
|
326
|
+
usage?: ChatCompleteUsage;
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
export interface ChatErrorMessage {
|
|
330
|
+
type: "chat:error";
|
|
331
|
+
payload: {
|
|
332
|
+
projectSlug: string;
|
|
333
|
+
error: string;
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Tell a re-attaching client to re-hydrate from the transcript instead of a
|
|
338
|
+
* frame replay (issue #54). Emitted only when the missed gap has aged out of the
|
|
339
|
+
* turn's bounded buffer — the rare fallback that trades live-ness for correctness.
|
|
340
|
+
*/
|
|
341
|
+
export interface ChatResyncMessage {
|
|
342
|
+
type: "chat:resync";
|
|
343
|
+
payload: {
|
|
344
|
+
projectSlug: string;
|
|
345
|
+
sessionId: string;
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* A session's live-turn status (issues #52/#53). Broadcast to all clients on a
|
|
350
|
+
* turn's start/stop transition, sent as a snapshot to a newly-connected socket,
|
|
351
|
+
* and sent in reply to a `chat:subscribe` for a session with a running turn. It
|
|
352
|
+
* lets a client restore the Stop button + `jobId` for a returning/remounted pane
|
|
353
|
+
* (#52) and drive the in-chat + per-chat-sidebar streaming indicators (#53).
|
|
354
|
+
*/
|
|
355
|
+
export interface ChatActiveMessage {
|
|
356
|
+
type: "chat:active";
|
|
357
|
+
payload: {
|
|
358
|
+
projectSlug: string;
|
|
359
|
+
sessionId: string;
|
|
360
|
+
/** The running turn's cancellable job id, when known. */
|
|
361
|
+
jobId: string | null;
|
|
362
|
+
running: boolean;
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Notify the client that the queued message was auto-sent by the server (#197).
|
|
367
|
+
* The client clears its localStorage copy of the queued message when it receives
|
|
368
|
+
* this frame, so queued messages don't duplicate if the browser closes before
|
|
369
|
+
* the turn completes.
|
|
370
|
+
*/
|
|
371
|
+
export interface ChatQueuedFlushedMessage {
|
|
372
|
+
type: "chat:queued_flushed";
|
|
373
|
+
payload: {
|
|
374
|
+
projectSlug: string;
|
|
375
|
+
sessionId: string;
|
|
376
|
+
/**
|
|
377
|
+
* The queued text the server is now auto-sending as a turn (#245). Present
|
|
378
|
+
* when the server actually drained+sent it — the client renders it as the
|
|
379
|
+
* user bubble in-transcript (the drained turn streams only the reply). Absent
|
|
380
|
+
* when the frame is just telling the client to clear a stale/already-sent copy.
|
|
381
|
+
*/
|
|
382
|
+
text?: string;
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* A background task was killed at the turn boundary and the keeper is idle
|
|
387
|
+
* (issue #347). Broadcast LIVE by the recovery engine the moment the kill is
|
|
388
|
+
* detected — the notification is otherwise trapped in the SDK input queue until
|
|
389
|
+
* a later turn flushes it, so without this the "keeper is idle / Continue"
|
|
390
|
+
* affordance only appeared after a manual refresh. The client renders it as the
|
|
391
|
+
* amber killed-task notice inline. Gated server-side on `recovery.surfaceKilledTask`.
|
|
392
|
+
*/
|
|
393
|
+
export interface ChatKilledTaskMessage {
|
|
394
|
+
type: "chat:killed_task";
|
|
395
|
+
payload: {
|
|
396
|
+
projectSlug: string;
|
|
397
|
+
sessionId: string;
|
|
398
|
+
/** The killed `<task-notification>`'s `<summary>`, or a generic fallback. */
|
|
399
|
+
summary: string;
|
|
400
|
+
/** ISO timestamp of detection — used by the client to dedup replays. */
|
|
401
|
+
timestamp: string;
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* A keeper turn dead-ended without a normal reply (issue #329): a synthetic
|
|
406
|
+
* subscription/usage-limit hit, the max-turns cap, or an error (network / API
|
|
407
|
+
* 5xx-overloaded / auth / crash). Emitted INLINE during the turn (session-routed
|
|
408
|
+
* like the other turn frames), so the chat surfaces WHY it stopped instead of
|
|
409
|
+
* looking dead. The client renders it as a distinct notice turn (with the reset
|
|
410
|
+
* time for a usage limit, and a Retry/Continue affordance when `retryable`).
|
|
411
|
+
*/
|
|
412
|
+
export interface ChatNoticeMessage {
|
|
413
|
+
type: "chat:notice";
|
|
414
|
+
payload: Routing & {
|
|
415
|
+
notice: TurnNotice;
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
export interface PongMessage {
|
|
419
|
+
type: "pong";
|
|
420
|
+
}
|
|
421
|
+
export type ServerMessage = ChatResponseMessage | ChatToolCallMessage | ChatToolStartMessage | ChatMessageBoundaryMessage | ChatCompleteMessage | ChatErrorMessage | ChatResyncMessage | ChatActiveMessage | ChatQueuedFlushedMessage | ChatKilledTaskMessage | ChatNoticeMessage | PongMessage;
|
|
422
|
+
export declare function isClientMessage(data: unknown): data is ClientMessage;
|
|
423
|
+
export {};
|