codex-channel-bgos 0.2.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.
Files changed (151) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +114 -0
  3. package/dist/adapter.d.ts +96 -0
  4. package/dist/adapter.d.ts.map +1 -0
  5. package/dist/adapter.js +677 -0
  6. package/dist/adapter.js.map +1 -0
  7. package/dist/agent-hints.d.ts +20 -0
  8. package/dist/agent-hints.d.ts.map +1 -0
  9. package/dist/agent-hints.js +92 -0
  10. package/dist/agent-hints.js.map +1 -0
  11. package/dist/agent-identity.d.ts +36 -0
  12. package/dist/agent-identity.d.ts.map +1 -0
  13. package/dist/agent-identity.js +42 -0
  14. package/dist/agent-identity.js.map +1 -0
  15. package/dist/attachment-bridge.d.ts +64 -0
  16. package/dist/attachment-bridge.d.ts.map +1 -0
  17. package/dist/attachment-bridge.js +216 -0
  18. package/dist/attachment-bridge.js.map +1 -0
  19. package/dist/auth-mode.d.ts +34 -0
  20. package/dist/auth-mode.d.ts.map +1 -0
  21. package/dist/auth-mode.js +48 -0
  22. package/dist/auth-mode.js.map +1 -0
  23. package/dist/bgos-api.d.ts +191 -0
  24. package/dist/bgos-api.d.ts.map +1 -0
  25. package/dist/bgos-api.js +225 -0
  26. package/dist/bgos-api.js.map +1 -0
  27. package/dist/bgos-ws.d.ts +94 -0
  28. package/dist/bgos-ws.d.ts.map +1 -0
  29. package/dist/bgos-ws.js +310 -0
  30. package/dist/bgos-ws.js.map +1 -0
  31. package/dist/capabilities.d.ts +28 -0
  32. package/dist/capabilities.d.ts.map +1 -0
  33. package/dist/capabilities.js +44 -0
  34. package/dist/capabilities.js.map +1 -0
  35. package/dist/catalog-sync.d.ts +26 -0
  36. package/dist/catalog-sync.d.ts.map +1 -0
  37. package/dist/catalog-sync.js +24 -0
  38. package/dist/catalog-sync.js.map +1 -0
  39. package/dist/cli.d.ts +3 -0
  40. package/dist/cli.d.ts.map +1 -0
  41. package/dist/cli.js +152 -0
  42. package/dist/cli.js.map +1 -0
  43. package/dist/codex-host.d.ts +44 -0
  44. package/dist/codex-host.d.ts.map +1 -0
  45. package/dist/codex-host.js +142 -0
  46. package/dist/codex-host.js.map +1 -0
  47. package/dist/commands-sync.d.ts +24 -0
  48. package/dist/commands-sync.d.ts.map +1 -0
  49. package/dist/commands-sync.js +43 -0
  50. package/dist/commands-sync.js.map +1 -0
  51. package/dist/config.d.ts +4 -0
  52. package/dist/config.d.ts.map +1 -0
  53. package/dist/config.js +36 -0
  54. package/dist/config.js.map +1 -0
  55. package/dist/default-commands.d.ts +27 -0
  56. package/dist/default-commands.d.ts.map +1 -0
  57. package/dist/default-commands.js +64 -0
  58. package/dist/default-commands.js.map +1 -0
  59. package/dist/event-mapper.d.ts +43 -0
  60. package/dist/event-mapper.d.ts.map +1 -0
  61. package/dist/event-mapper.js +127 -0
  62. package/dist/event-mapper.js.map +1 -0
  63. package/dist/heartbeat.d.ts +75 -0
  64. package/dist/heartbeat.d.ts.map +1 -0
  65. package/dist/heartbeat.js +186 -0
  66. package/dist/heartbeat.js.map +1 -0
  67. package/dist/inbound-handler.d.ts +167 -0
  68. package/dist/inbound-handler.d.ts.map +1 -0
  69. package/dist/inbound-handler.js +282 -0
  70. package/dist/inbound-handler.js.map +1 -0
  71. package/dist/inbound-input.d.ts +17 -0
  72. package/dist/inbound-input.d.ts.map +1 -0
  73. package/dist/inbound-input.js +25 -0
  74. package/dist/inbound-input.js.map +1 -0
  75. package/dist/index.d.ts +25 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +18 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/install-service.d.ts +8 -0
  80. package/dist/install-service.d.ts.map +1 -0
  81. package/dist/install-service.js +66 -0
  82. package/dist/install-service.js.map +1 -0
  83. package/dist/last-id-store.d.ts +33 -0
  84. package/dist/last-id-store.d.ts.map +1 -0
  85. package/dist/last-id-store.js +101 -0
  86. package/dist/last-id-store.js.map +1 -0
  87. package/dist/load-config.d.ts +30 -0
  88. package/dist/load-config.d.ts.map +1 -0
  89. package/dist/load-config.js +86 -0
  90. package/dist/load-config.js.map +1 -0
  91. package/dist/media-classify.d.ts +37 -0
  92. package/dist/media-classify.d.ts.map +1 -0
  93. package/dist/media-classify.js +108 -0
  94. package/dist/media-classify.js.map +1 -0
  95. package/dist/media-guard.d.ts +13 -0
  96. package/dist/media-guard.d.ts.map +1 -0
  97. package/dist/media-guard.js +159 -0
  98. package/dist/media-guard.js.map +1 -0
  99. package/dist/outbound-retry.d.ts +24 -0
  100. package/dist/outbound-retry.d.ts.map +1 -0
  101. package/dist/outbound-retry.js +75 -0
  102. package/dist/outbound-retry.js.map +1 -0
  103. package/dist/outbound.d.ts +223 -0
  104. package/dist/outbound.d.ts.map +1 -0
  105. package/dist/outbound.js +366 -0
  106. package/dist/outbound.js.map +1 -0
  107. package/dist/outbox.d.ts +16 -0
  108. package/dist/outbox.d.ts.map +1 -0
  109. package/dist/outbox.js +88 -0
  110. package/dist/outbox.js.map +1 -0
  111. package/dist/pair-cli.d.ts +44 -0
  112. package/dist/pair-cli.d.ts.map +1 -0
  113. package/dist/pair-cli.js +182 -0
  114. package/dist/pair-cli.js.map +1 -0
  115. package/dist/pending-unknown-store.d.ts +26 -0
  116. package/dist/pending-unknown-store.d.ts.map +1 -0
  117. package/dist/pending-unknown-store.js +135 -0
  118. package/dist/pending-unknown-store.js.map +1 -0
  119. package/dist/processed-ids.d.ts +36 -0
  120. package/dist/processed-ids.d.ts.map +1 -0
  121. package/dist/processed-ids.js +55 -0
  122. package/dist/processed-ids.js.map +1 -0
  123. package/dist/reply-markers.d.ts +42 -0
  124. package/dist/reply-markers.d.ts.map +1 -0
  125. package/dist/reply-markers.js +124 -0
  126. package/dist/reply-markers.js.map +1 -0
  127. package/dist/setup/supervisor.d.ts +16 -0
  128. package/dist/setup/supervisor.d.ts.map +1 -0
  129. package/dist/setup/supervisor.js +61 -0
  130. package/dist/setup/supervisor.js.map +1 -0
  131. package/dist/thread-map.d.ts +12 -0
  132. package/dist/thread-map.d.ts.map +1 -0
  133. package/dist/thread-map.js +72 -0
  134. package/dist/thread-map.js.map +1 -0
  135. package/dist/tool-progress.d.ts +103 -0
  136. package/dist/tool-progress.d.ts.map +1 -0
  137. package/dist/tool-progress.js +216 -0
  138. package/dist/tool-progress.js.map +1 -0
  139. package/dist/types.d.ts +244 -0
  140. package/dist/types.d.ts.map +1 -0
  141. package/dist/types.js +16 -0
  142. package/dist/types.js.map +1 -0
  143. package/dist/version.d.ts +2 -0
  144. package/dist/version.d.ts.map +1 -0
  145. package/dist/version.js +28 -0
  146. package/dist/version.js.map +1 -0
  147. package/dist/voice-rpc.d.ts +37 -0
  148. package/dist/voice-rpc.d.ts.map +1 -0
  149. package/dist/voice-rpc.js +44 -0
  150. package/dist/voice-rpc.js.map +1 -0
  151. package/package.json +47 -0
@@ -0,0 +1,75 @@
1
+ export interface HeartbeatLastError {
2
+ code: string;
3
+ message: string;
4
+ at: string;
5
+ }
6
+ /** Wire shape POSTed to the backend heartbeat endpoint. */
7
+ export interface HeartbeatDto {
8
+ daemonVersion?: string;
9
+ uptimeS?: number;
10
+ wsConnected?: boolean;
11
+ lastError?: HeartbeatLastError | null;
12
+ /** Active Codex auth mode ("chatgpt" | "apikey"), D7 surfacing. */
13
+ authMode?: string;
14
+ }
15
+ /** Local heartbeat file shape (contract C1). */
16
+ export interface HeartbeatFileState {
17
+ ts: string;
18
+ pid: number;
19
+ version: string;
20
+ wsConnected: boolean;
21
+ wsConnectedSince: string | null;
22
+ lastInboundAt: string | null;
23
+ lastOutboundAt: string | null;
24
+ lastError: HeartbeatLastError | null;
25
+ pairingId: number | null;
26
+ authMode: string | null;
27
+ }
28
+ export interface HeartbeatDeps {
29
+ version: string;
30
+ /** Best-effort POST to the backend heartbeat endpoint. */
31
+ postHeartbeat: (body: HeartbeatDto) => Promise<void>;
32
+ /** Active Codex auth mode, surfaced in the payload + local file (D7). */
33
+ authMode?: string;
34
+ /** Injectable clock for tests. */
35
+ now?: () => number;
36
+ }
37
+ export declare class HeartbeatController {
38
+ private readonly deps;
39
+ private wsConnected;
40
+ private wsConnectedSince;
41
+ private lastInboundAt;
42
+ private lastOutboundAt;
43
+ private lastError;
44
+ private pairingId;
45
+ private readonly startedAtMs;
46
+ private readonly now;
47
+ private fileTimer;
48
+ private netTimer;
49
+ private netEnabled;
50
+ private started;
51
+ constructor(deps: HeartbeatDeps);
52
+ start(): void;
53
+ stop(): void;
54
+ private armNetworkTimer;
55
+ private clearNetworkTimer;
56
+ /** Enable/disable the NETWORK sink (fatal latch disables it; recovery
57
+ * re-enables). The local file keeps writing regardless. */
58
+ setNetEnabled(enabled: boolean): void;
59
+ setWsConnected(connected: boolean, since: string | null): void;
60
+ setPairingId(id: number | null): void;
61
+ recordInbound(): void;
62
+ recordOutbound(): void;
63
+ /**
64
+ * Record (or clear) the last error. A change of error CODE (including to
65
+ * null) is an "error transition": it writes the file AND posts a network
66
+ * heartbeat immediately.
67
+ */
68
+ setLastError(err: HeartbeatLastError | null): void;
69
+ /** Current error code (used by callers to decide whether to clear). */
70
+ getLastErrorCode(): string | null;
71
+ snapshotFile(): HeartbeatFileState;
72
+ private writeFile;
73
+ private postNetwork;
74
+ }
75
+ //# sourceMappingURL=heartbeat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../src/heartbeat.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,2DAA2D;AAC3D,MAAM,WAAW,YAAY;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACtC,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACrC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,aAAa,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAiBD,qBAAa,mBAAmB;IAelB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAdjC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,SAAS,CAAuB;IAExC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,OAAO,CAAS;gBAEK,IAAI,EAAE,aAAa;IAKhD,KAAK,IAAI,IAAI;IAUb,IAAI,IAAI,IAAI;IASZ,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,iBAAiB;IAOzB;gEAC4D;IAC5D,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAYrC,cAAc,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAS9D,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIrC,aAAa,IAAI,IAAI;IAIrB,cAAc,IAAI,IAAI;IAItB;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,GAAG,IAAI;IAWlD,uEAAuE;IACvE,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,YAAY,IAAI,kBAAkB;IAelC,OAAO,CAAC,SAAS;YAcH,WAAW;CAuB1B"}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Daemon liveness + error telemetry for the BGOS channel (contract C1).
3
+ *
4
+ * Two sinks:
5
+ * 1. Network: POST /api/v1/integrations/heartbeat every
6
+ * CODEX_BGOS_HEARTBEAT_INTERVAL seconds (default 60, 0 disables) PLUS
7
+ * once on start and on every error transition. Backend touches
8
+ * last_seen_at + records daemon_version / last_error_*.
9
+ * 2. Local file: `$CODEX_BGOS_HOME/bgos_heartbeat.json` written every 30s and on
10
+ * state change, atomic tmp+rename mode 0600. Read by the fork watchdog.
11
+ *
12
+ * During a fatal latch (revoked / rotated token) the network sink is disabled
13
+ * but the local file keeps writing so the watchdog can see the lastError.
14
+ */
15
+ import { mkdirSync, renameSync, writeFileSync } from "node:fs";
16
+ import { homedir } from "node:os";
17
+ import { dirname, join } from "node:path";
18
+ const FILE_INTERVAL_MS = 30_000;
19
+ function heartbeatPath() {
20
+ const root = process.env.CODEX_BGOS_HOME ?? join(homedir(), ".codex-bgos");
21
+ return join(root, "bgos_heartbeat.json");
22
+ }
23
+ function resolveNetworkIntervalMs() {
24
+ const raw = process.env.CODEX_BGOS_HEARTBEAT_INTERVAL;
25
+ if (raw === undefined || raw === "")
26
+ return 60_000;
27
+ const n = Number(raw);
28
+ if (!Number.isFinite(n) || n < 0)
29
+ return 60_000;
30
+ return n * 1000;
31
+ }
32
+ export class HeartbeatController {
33
+ deps;
34
+ wsConnected = false;
35
+ wsConnectedSince = null;
36
+ lastInboundAt = null;
37
+ lastOutboundAt = null;
38
+ lastError = null;
39
+ pairingId = null;
40
+ startedAtMs;
41
+ now;
42
+ fileTimer = null;
43
+ netTimer = null;
44
+ netEnabled = true;
45
+ started = false;
46
+ constructor(deps) {
47
+ this.deps = deps;
48
+ this.now = deps.now ?? (() => Date.now());
49
+ this.startedAtMs = this.now();
50
+ }
51
+ start() {
52
+ if (this.started)
53
+ return;
54
+ this.started = true;
55
+ this.writeFile();
56
+ void this.postNetwork();
57
+ this.fileTimer = setInterval(() => this.writeFile(), FILE_INTERVAL_MS);
58
+ this.fileTimer.unref?.();
59
+ this.armNetworkTimer();
60
+ }
61
+ stop() {
62
+ this.started = false;
63
+ if (this.fileTimer !== null) {
64
+ clearInterval(this.fileTimer);
65
+ this.fileTimer = null;
66
+ }
67
+ this.clearNetworkTimer();
68
+ }
69
+ armNetworkTimer() {
70
+ this.clearNetworkTimer();
71
+ const intervalMs = resolveNetworkIntervalMs();
72
+ if (intervalMs <= 0)
73
+ return; // 0 disables periodic network heartbeat
74
+ this.netTimer = setInterval(() => void this.postNetwork(), intervalMs);
75
+ this.netTimer.unref?.();
76
+ }
77
+ clearNetworkTimer() {
78
+ if (this.netTimer !== null) {
79
+ clearInterval(this.netTimer);
80
+ this.netTimer = null;
81
+ }
82
+ }
83
+ /** Enable/disable the NETWORK sink (fatal latch disables it; recovery
84
+ * re-enables). The local file keeps writing regardless. */
85
+ setNetEnabled(enabled) {
86
+ if (this.netEnabled === enabled)
87
+ return;
88
+ this.netEnabled = enabled;
89
+ if (!this.started)
90
+ return;
91
+ if (enabled) {
92
+ this.armNetworkTimer();
93
+ void this.postNetwork();
94
+ }
95
+ else {
96
+ this.clearNetworkTimer();
97
+ }
98
+ }
99
+ setWsConnected(connected, since) {
100
+ if (this.wsConnected === connected && this.wsConnectedSince === since) {
101
+ return;
102
+ }
103
+ this.wsConnected = connected;
104
+ this.wsConnectedSince = since;
105
+ this.writeFile(); // state change
106
+ }
107
+ setPairingId(id) {
108
+ this.pairingId = id;
109
+ }
110
+ recordInbound() {
111
+ this.lastInboundAt = new Date(this.now()).toISOString();
112
+ }
113
+ recordOutbound() {
114
+ this.lastOutboundAt = new Date(this.now()).toISOString();
115
+ }
116
+ /**
117
+ * Record (or clear) the last error. A change of error CODE (including to
118
+ * null) is an "error transition": it writes the file AND posts a network
119
+ * heartbeat immediately.
120
+ */
121
+ setLastError(err) {
122
+ const prevCode = this.lastError?.code ?? null;
123
+ const nextCode = err?.code ?? null;
124
+ const transition = prevCode !== nextCode;
125
+ this.lastError = err;
126
+ if (transition) {
127
+ this.writeFile();
128
+ void this.postNetwork();
129
+ }
130
+ }
131
+ /** Current error code (used by callers to decide whether to clear). */
132
+ getLastErrorCode() {
133
+ return this.lastError?.code ?? null;
134
+ }
135
+ snapshotFile() {
136
+ return {
137
+ ts: new Date(this.now()).toISOString(),
138
+ pid: process.pid,
139
+ version: this.deps.version,
140
+ wsConnected: this.wsConnected,
141
+ wsConnectedSince: this.wsConnectedSince,
142
+ lastInboundAt: this.lastInboundAt,
143
+ lastOutboundAt: this.lastOutboundAt,
144
+ lastError: this.lastError,
145
+ pairingId: this.pairingId,
146
+ authMode: this.deps.authMode ?? null,
147
+ };
148
+ }
149
+ writeFile() {
150
+ try {
151
+ const target = heartbeatPath();
152
+ mkdirSync(dirname(target), { recursive: true });
153
+ const tmp = `${target}.${process.pid}.tmp`;
154
+ writeFileSync(tmp, JSON.stringify(this.snapshotFile(), null, 2), {
155
+ mode: 0o600,
156
+ });
157
+ renameSync(tmp, target);
158
+ }
159
+ catch {
160
+ /* best-effort */
161
+ }
162
+ }
163
+ async postNetwork() {
164
+ if (!this.netEnabled)
165
+ return;
166
+ if (resolveNetworkIntervalMs() <= 0) {
167
+ // interval 0 disables periodic posts; still allow start()'s single
168
+ // post? No: 0 means "disabled", so skip entirely.
169
+ return;
170
+ }
171
+ const uptimeS = Math.max(0, Math.floor((this.now() - this.startedAtMs) / 1000));
172
+ try {
173
+ await this.deps.postHeartbeat({
174
+ daemonVersion: this.deps.version,
175
+ uptimeS,
176
+ wsConnected: this.wsConnected,
177
+ lastError: this.lastError,
178
+ authMode: this.deps.authMode,
179
+ });
180
+ }
181
+ catch {
182
+ /* best-effort: a heartbeat failure must never break the daemon */
183
+ }
184
+ }
185
+ }
186
+ //# sourceMappingURL=heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../src/heartbeat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ import type { BgosOutbound } from "./outbound.js";
2
+ import type { ToolProgressOrchestrator } from "./tool-progress.js";
3
+ import type { ApprovalMeta, InboundMessagePayload, MessageOption } from "./types.js";
4
+ /**
5
+ * Reply handle the fork's `processMessageForAgent` calls into.
6
+ *
7
+ * Mirrors the Telegram side (which the fork builds in
8
+ * `src/adapters/bgos/reply-handle.ts`) so a single agent handler can
9
+ * speak to either origin without branching internally. Methods are
10
+ * Promise-returning so the fork can await delivery confirmation when it
11
+ * cares.
12
+ */
13
+ export interface ReplyHandle {
14
+ origin: "bgos";
15
+ sendText: (text: string) => Promise<{
16
+ id: number;
17
+ }>;
18
+ sendButtons: (text: string, options: MessageOption[]) => Promise<{
19
+ id: number;
20
+ }>;
21
+ sendApprovalRequest: (text: string, meta: ApprovalMeta) => Promise<{
22
+ id: number;
23
+ }>;
24
+ sendAskUserInput: (prompt: string, options?: MessageOption[], modal?: boolean) => Promise<{
25
+ id: number;
26
+ }>;
27
+ sendFile: (filePath: string, caption?: string) => Promise<{
28
+ id: number;
29
+ }>;
30
+ sendImage: (filePath: string, caption?: string) => Promise<{
31
+ id: number;
32
+ }>;
33
+ sendVideo: (filePath: string, caption?: string) => Promise<{
34
+ id: number;
35
+ }>;
36
+ sendTyping: () => Promise<void>;
37
+ /** Publish a local file path to BGOS as a `files[]` entry; useful when
38
+ * the agent emits structured tool output rather than a `MEDIA:` line.
39
+ * The `filePath` is validated against the `CODEX_BGOS_MEDIA_ROOT` allowlist
40
+ * (see media-guard.ts) before any bytes are read - paths outside the
41
+ * root, traversal, escaping symlinks, and sensitive locations throw. */
42
+ uploadFile: (filePath: string, opts?: {
43
+ fileName?: string;
44
+ mimeType?: string;
45
+ }) => Promise<{
46
+ fileName: string;
47
+ fileMimeType: string;
48
+ size: number;
49
+ }>;
50
+ /**
51
+ * Record that a tool just started executing in the current agent turn.
52
+ * The plugin emits a live `tool_progress` card in BGOS - POSTing on the
53
+ * first call per turn, PATCHing on subsequent calls (debounced).
54
+ *
55
+ * Codex fork wiring: call this from `callClaudeStreaming`'s `onToolStart`
56
+ * hook on the BGOS dispatch path:
57
+ *
58
+ * onToolStart: (toolName) => replyHandle.sendToolStart(toolName)
59
+ *
60
+ * No-op when the adapter wasn't constructed with a tool-progress
61
+ * orchestrator (old host code) - safe to call unconditionally.
62
+ * `args` is optional, ≤120 chars (truncated by the plugin).
63
+ */
64
+ sendToolStart: (toolName: string, args?: string) => Promise<void>;
65
+ /**
66
+ * End-of-turn signal - transitions the active tool_progress card from
67
+ * state="running" to "done" so the frontend auto-collapses it. The
68
+ * fork should call this AFTER the agent's text reply has been sent
69
+ * via `sendText` (or even if the turn ends without a reply). Idempotent
70
+ * - safe to call multiple times. No-op when no card exists for this
71
+ * chat (turn used no tools).
72
+ */
73
+ finalizeTurn: () => Promise<void>;
74
+ }
75
+ /**
76
+ * Args the fork's dispatch function receives. Kept deliberately flat
77
+ * and dependency-free so the fork can adapt them onto whatever shape
78
+ * Codex's internal pipeline expects.
79
+ */
80
+ export interface DispatchArgs {
81
+ origin: "bgos";
82
+ agentRoute: string;
83
+ assistantId: number;
84
+ chatId: number;
85
+ /** The BGOS message id of this inbound. Surfaced so the fork can correlate
86
+ * / log; the reply anchoring (reply_to_id) is handled automatically by
87
+ * the ReplyHandle for a2a side-threads. */
88
+ messageId: number;
89
+ userId: string;
90
+ text: string;
91
+ /** Local file paths the user attached (already downloaded). Empty
92
+ * when the user only sent text. */
93
+ attachments: Array<{
94
+ localPath: string;
95
+ fileName: string;
96
+ mimeType: string;
97
+ kind: "photo" | "video" | "document" | "voice";
98
+ }>;
99
+ /** Append to the agent's existing system prompt (hints injection
100
+ * happens here so every dispatch carries them). */
101
+ systemPrompt: string;
102
+ /** Reply handle scoped to BGOS - the agent only talks back via this. */
103
+ replyHandle: ReplyHandle;
104
+ /** Slash-command metadata if `messageType==='slash_command'`. */
105
+ command?: {
106
+ name: string;
107
+ args: string;
108
+ };
109
+ messageType: InboundMessagePayload["messageType"];
110
+ /** Present when this inbound is a peer agent's a2a side-thread message.
111
+ * The reply is auto-routed back to the peer (via `/send-message` with
112
+ * `reply_to_id`) so the peer's `wait_for_reply` resolves - the agent
113
+ * does NOT need to do anything special. Surfaced for awareness / future
114
+ * use (e.g. tailoring the reply to `turnState`). */
115
+ peerConversationId?: number;
116
+ /** Turn state on the peer side-thread (`expecting_reply` | `more_coming`
117
+ * | `final`) when `peerConversationId` is set. */
118
+ turnState?: string;
119
+ }
120
+ export type DispatchFn = (args: DispatchArgs) => Promise<void>;
121
+ export interface InboundHandlerDeps {
122
+ outbound: BgosOutbound;
123
+ /** Map an assistant id to the bound agent route. Adapter-provided. */
124
+ getRouteForAssistant(assistantId: number): string | null;
125
+ /** The fork-supplied dispatch function. May be `null` until the fork
126
+ * calls `setDispatch(fn)` - early WS messages then no-op safely. */
127
+ getDispatch(): DispatchFn | null;
128
+ /** Optional system-prompt prefix (e.g. agent persona). The handler
129
+ * appends `BGOS_AGENT_HINTS` to whatever this returns. */
130
+ getSystemPrompt?(agentRoute: string): string;
131
+ /** Tool-progress card orchestrator - adapter-provided. The factory
132
+ * wires `replyHandle.sendToolStart` + `replyHandle.finalizeTurn`
133
+ * through this. Optional for back-compat; older host code that
134
+ * doesn't call these methods continues to work, just without cards. */
135
+ toolProgress?: ToolProgressOrchestrator;
136
+ /** Called (best-effort) when a message is about to dispatch, driving the
137
+ * heartbeat `lastInboundAt` timestamp. Optional. */
138
+ onInbound?(): void;
139
+ /** Rate-limited, single-flight scope refresh invoked when an inbound
140
+ * arrives for an assistant_id NOT in the route map. The adapter refreshes
141
+ * identity (whoami) so a newly-exposed agent heals without a restart. The
142
+ * handler retries the route lookup ONCE after this resolves. Optional. */
143
+ onUnknownAssistant?(assistantId: number): Promise<void>;
144
+ }
145
+ /**
146
+ * Build a BGOS-scoped ReplyHandle. Extracted so both the inbound dispatch
147
+ * path AND the adapter's `makeReplyHandle` factory (contract C6, for the
148
+ * fork's HITL button-click resume) produce an identical surface.
149
+ *
150
+ * `replyVia` / `replyToId` are set by the inbound path for a2a peer replies;
151
+ * `makeReplyHandle` leaves them undefined (a plain reply into a chat).
152
+ */
153
+ export declare function buildReplyHandle(deps: {
154
+ outbound: BgosOutbound;
155
+ toolProgress?: ToolProgressOrchestrator;
156
+ }, target: {
157
+ assistantId: number;
158
+ chatId: number;
159
+ replyVia?: "send-message";
160
+ replyToId?: number;
161
+ }): ReplyHandle;
162
+ /**
163
+ * Build the inbound-event handler. Returns an async function the
164
+ * adapter wires onto `BgosWs`'s `inbound_message` event.
165
+ */
166
+ export declare function createInboundHandler(deps: InboundHandlerDeps): (event: InboundMessagePayload) => Promise<void>;
167
+ //# sourceMappingURL=inbound-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbound-handler.d.ts","sourceRoot":"","sources":["../src/inbound-handler.ts"],"names":[],"mappings":"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"}