@canonmsg/backend-contracts 1.9.0 → 2.1.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/dist/agentBehaviorPolicy.d.ts +45 -86
- package/dist/agentBehaviorPolicy.js +0 -53
- package/dist/cjs/agentBehaviorPolicy.js +1 -54
- package/dist/cjs/contactRequest.js +0 -30
- package/dist/cjs/diffRedaction.js +73 -0
- package/dist/cjs/index.js +1 -8
- package/dist/cjs/media.js +0 -13
- package/dist/cjs/message.js +44 -65
- package/dist/cjs/runtimeCardFields.js +1 -58
- package/dist/cjs/turnProtocol.js +1 -41
- package/dist/contactRequest.d.ts +23 -42
- package/dist/contactRequest.js +0 -29
- package/dist/diffRedaction.d.ts +6 -0
- package/dist/diffRedaction.js +68 -0
- package/dist/index.d.ts +1 -8
- package/dist/index.js +1 -8
- package/dist/media.d.ts +11 -24
- package/dist/media.js +0 -12
- package/dist/message.d.ts +79 -132
- package/dist/message.js +45 -65
- package/dist/runtimeCardFields.d.ts +39 -112
- package/dist/runtimeCardFields.js +0 -57
- package/dist/turnProtocol.d.ts +24 -91
- package/dist/turnProtocol.js +0 -40
- package/package.json +5 -8
- package/dist/bridgeLocal.d.ts +0 -1871
- package/dist/bridgeLocal.js +0 -744
- package/dist/cjs/bridgeLocal.js +0 -747
- package/dist/cjs/controlSignals.js +0 -44
- package/dist/cjs/endpointRegistry.js +0 -264
- package/dist/cjs/hitl.js +0 -171
- package/dist/cjs/inboundFrame.js +0 -92
- package/dist/cjs/restEndpoints.js +0 -237
- package/dist/cjs/sendContextual.js +0 -92
- package/dist/cjs/sseEvents.js +0 -281
- package/dist/controlSignals.d.ts +0 -55
- package/dist/controlSignals.js +0 -41
- package/dist/endpointRegistry.d.ts +0 -13
- package/dist/endpointRegistry.js +0 -261
- package/dist/hitl.d.ts +0 -303
- package/dist/hitl.js +0 -168
- package/dist/inboundFrame.d.ts +0 -229
- package/dist/inboundFrame.js +0 -89
- package/dist/restEndpoints.d.ts +0 -531
- package/dist/restEndpoints.js +0 -234
- package/dist/schemas/agent-behavior-settings-record.schema.json +0 -48
- package/dist/schemas/bridge-connection-state-notification.schema.json +0 -19
- package/dist/schemas/bridge-get-attachment-params.schema.json +0 -24
- package/dist/schemas/bridge-get-attachment-result.schema.json +0 -20
- package/dist/schemas/bridge-hello-params.schema.json +0 -42
- package/dist/schemas/bridge-hello-result.schema.json +0 -105
- package/dist/schemas/bridge-hitl-state.schema.json +0 -38
- package/dist/schemas/bridge-ok-result.schema.json +0 -15
- package/dist/schemas/bridge-publish-streaming-event-params.schema.json +0 -138
- package/dist/schemas/bridge-ready-notification.schema.json +0 -79
- package/dist/schemas/bridge-resync-reason.schema.json +0 -9
- package/dist/schemas/bridge-resync.schema.json +0 -18
- package/dist/schemas/bridge-rpc-error.schema.json +0 -19
- package/dist/schemas/bridge-rpc-id.schema.json +0 -12
- package/dist/schemas/bridge-rpc-notification.schema.json +0 -20
- package/dist/schemas/bridge-rpc-request.schema.json +0 -31
- package/dist/schemas/bridge-rpc-response.schema.json +0 -81
- package/dist/schemas/bridge-status-result.schema.json +0 -76
- package/dist/schemas/bridge-stream-clear-event.schema.json +0 -15
- package/dist/schemas/bridge-stream-event.schema.json +0 -112
- package/dist/schemas/bridge-stream-final-event.schema.json +0 -19
- package/dist/schemas/bridge-stream-text-event.schema.json +0 -31
- package/dist/schemas/bridge-stream-thinking-event.schema.json +0 -15
- package/dist/schemas/bridge-stream-tool-event.schema.json +0 -36
- package/dist/schemas/bridge-upload-media-params.schema.json +0 -28
- package/dist/schemas/bridge-upstream-state.schema.json +0 -10
- package/dist/schemas/contacts-response.schema.json +0 -52
- package/dist/schemas/control-channel-key.schema.json +0 -10
- package/dist/schemas/control-primitive-event.schema.json +0 -30
- package/dist/schemas/control-primitive-map.schema.json +0 -15
- package/dist/schemas/control-session-event.schema.json +0 -26
- package/dist/schemas/control-session-node.schema.json +0 -11
- package/dist/schemas/control-signal-event.schema.json +0 -35
- package/dist/schemas/control-signal-node.schema.json +0 -22
- package/dist/schemas/control-signal-type.schema.json +0 -10
- package/dist/schemas/conversations-response.schema.json +0 -167
- package/dist/schemas/create-contact-request-request.schema.json +0 -17
- package/dist/schemas/create-contact-request-response.schema.json +0 -51
- package/dist/schemas/create-conversation-request.schema.json +0 -82
- package/dist/schemas/create-conversation-response.schema.json +0 -29
- package/dist/schemas/delete-message-response.schema.json +0 -11
- package/dist/schemas/delivery-intent.schema.json +0 -11
- package/dist/schemas/forward-message-request.schema.json +0 -25
- package/dist/schemas/forward-message-response.schema.json +0 -35
- package/dist/schemas/forwarded-from.schema.json +0 -18
- package/dist/schemas/get-messages-query.schema.json +0 -17
- package/dist/schemas/hitl-approval-category.schema.json +0 -15
- package/dist/schemas/hitl-approval-detail.schema.json +0 -21
- package/dist/schemas/hitl-approval-outcome-record.schema.json +0 -33
- package/dist/schemas/hitl-approval-reply-record.schema.json +0 -57
- package/dist/schemas/hitl-approval-request-record.schema.json +0 -105
- package/dist/schemas/hitl-approval-risk.schema.json +0 -11
- package/dist/schemas/hitl-card-outcome-record.schema.json +0 -48
- package/dist/schemas/hitl-card-reply-record.schema.json +0 -46
- package/dist/schemas/hitl-card-request-record.schema.json +0 -73
- package/dist/schemas/hitl-input-answers.schema.json +0 -23
- package/dist/schemas/hitl-input-kind.schema.json +0 -10
- package/dist/schemas/hitl-input-outcome-record.schema.json +0 -46
- package/dist/schemas/hitl-input-question.schema.json +0 -54
- package/dist/schemas/hitl-input-reply-record.schema.json +0 -44
- package/dist/schemas/hitl-input-request-record.schema.json +0 -134
- package/dist/schemas/hitl-pending.schema.json +0 -31
- package/dist/schemas/hitl-request-accepted.schema.json +0 -18
- package/dist/schemas/hitl-request-kind.schema.json +0 -10
- package/dist/schemas/hitl-resolution-status.schema.json +0 -10
- package/dist/schemas/hitl-resolution.schema.json +0 -38
- package/dist/schemas/hitl-session-rule.schema.json +0 -32
- package/dist/schemas/inbound-disposition.schema.json +0 -13
- package/dist/schemas/inbound-frame-attachment-v1.schema.json +0 -94
- package/dist/schemas/inbound-frame-contact-card-v1.schema.json +0 -59
- package/dist/schemas/inbound-frame-group-context-v1.schema.json +0 -96
- package/dist/schemas/inbound-frame-reply-context-v1.schema.json +0 -261
- package/dist/schemas/inbound-frame-shape-v1.schema.json +0 -12
- package/dist/schemas/inbound-frame-v1.schema.json +0 -506
- package/dist/schemas/mark-read-response.schema.json +0 -11
- package/dist/schemas/media-attachment-kind.schema.json +0 -11
- package/dist/schemas/media-attachment.schema.json +0 -42
- package/dist/schemas/messages-page-response.schema.json +0 -290
- package/dist/schemas/participation-decision-input.schema.json +0 -44
- package/dist/schemas/participation-history-message.schema.json +0 -23
- package/dist/schemas/participation-history-snapshot.schema.json +0 -37
- package/dist/schemas/participation-style.schema.json +0 -13
- package/dist/schemas/react-request.schema.json +0 -22
- package/dist/schemas/react-response.schema.json +0 -35
- package/dist/schemas/resolve-admission-request.schema.json +0 -30
- package/dist/schemas/resolve-admission-response.schema.json +0 -129
- package/dist/schemas/resolved-agent-behavior-policy-record.schema.json +0 -81
- package/dist/schemas/rest-contact.schema.json +0 -40
- package/dist/schemas/rest-conversation-last-message.schema.json +0 -77
- package/dist/schemas/rest-conversation.schema.json +0 -155
- package/dist/schemas/rest-message.schema.json +0 -252
- package/dist/schemas/rest-ok-response.schema.json +0 -11
- package/dist/schemas/rest-session-selection.schema.json +0 -40
- package/dist/schemas/runtime-card-field-choice.schema.json +0 -23
- package/dist/schemas/runtime-card-field-type.schema.json +0 -17
- package/dist/schemas/runtime-card-field.schema.json +0 -180
- package/dist/schemas/runtime-card-line-item-column-type.schema.json +0 -12
- package/dist/schemas/runtime-card-line-item-column.schema.json +0 -74
- package/dist/schemas/send-contextual-deferred-response.schema.json +0 -39
- package/dist/schemas/send-contextual-messaged-response.schema.json +0 -42
- package/dist/schemas/send-contextual-request.schema.json +0 -103
- package/dist/schemas/send-contextual-response.schema.json +0 -105
- package/dist/schemas/send-contextual-self-context.schema.json +0 -19
- package/dist/schemas/send-contextual-state-response.schema.json +0 -24
- package/dist/schemas/send-message-request.schema.json +0 -106
- package/dist/schemas/send-message-response.schema.json +0 -14
- package/dist/schemas/sender-type.schema.json +0 -9
- package/dist/schemas/serialize-message-input.schema.json +0 -29
- package/dist/schemas/serialized-agent-client-type.schema.json +0 -12
- package/dist/schemas/serialized-contact-card.schema.json +0 -65
- package/dist/schemas/serialized-contact-request-status.schema.json +0 -11
- package/dist/schemas/serialized-contact-request.schema.json +0 -157
- package/dist/schemas/serialized-content-type.schema.json +0 -13
- package/dist/schemas/serialized-message.schema.json +0 -249
- package/dist/schemas/serialized-reactions.schema.json +0 -14
- package/dist/schemas/serialized-sender-type.schema.json +0 -9
- package/dist/schemas/set-streaming-request.schema.json +0 -67
- package/dist/schemas/set-typing-request.schema.json +0 -25
- package/dist/schemas/sse-access-policy.schema.json +0 -10
- package/dist/schemas/sse-agent-context-payload.schema.json +0 -57
- package/dist/schemas/sse-connected-payload.schema.json +0 -18
- package/dist/schemas/sse-contact-payload.schema.json +0 -40
- package/dist/schemas/sse-contact-removed-payload.schema.json +0 -14
- package/dist/schemas/sse-contact-request-payload.schema.json +0 -157
- package/dist/schemas/sse-conversation-updated-payload.schema.json +0 -48
- package/dist/schemas/sse-error-payload.schema.json +0 -23
- package/dist/schemas/sse-event-envelope.schema.json +0 -40
- package/dist/schemas/sse-event-family.schema.json +0 -12
- package/dist/schemas/sse-event-type.schema.json +0 -26
- package/dist/schemas/sse-heartbeat-payload.schema.json +0 -14
- package/dist/schemas/sse-membership-change.schema.json +0 -28
- package/dist/schemas/sse-message-created-payload.schema.json +0 -414
- package/dist/schemas/sse-message-deleted-payload.schema.json +0 -18
- package/dist/schemas/sse-message-updated-payload.schema.json +0 -46
- package/dist/schemas/sse-presence-payload.schema.json +0 -21
- package/dist/schemas/sse-provenance.schema.json +0 -64
- package/dist/schemas/sse-replay-expired-payload.schema.json +0 -21
- package/dist/schemas/sse-runtime-control-kind.schema.json +0 -13
- package/dist/schemas/sse-runtime-control-payload.schema.json +0 -44
- package/dist/schemas/sse-self-context.schema.json +0 -45
- package/dist/schemas/sse-turn-dispatch.schema.json +0 -29
- package/dist/schemas/sse-typing-payload.schema.json +0 -32
- package/dist/schemas/sse-voice-session-event-payload.schema.json +0 -170
- package/dist/schemas/sse-voice-session.schema.json +0 -157
- package/dist/schemas/trigger-decision.schema.json +0 -27
- package/dist/schemas/turn-lifecycle-state.schema.json +0 -14
- package/dist/schemas/turn-message-semantics.schema.json +0 -10
- package/dist/schemas/turn-metadata.schema.json +0 -56
- package/dist/schemas/turn-state-like.schema.json +0 -39
- package/dist/schemas/update-disposition-request.schema.json +0 -22
- package/dist/schemas/upload-media-request.schema.json +0 -25
- package/dist/schemas/upload-media-response.schema.json +0 -55
- package/dist/sendContextual.d.ts +0 -114
- package/dist/sendContextual.js +0 -89
- package/dist/sseEvents.d.ts +0 -474
- package/dist/sseEvents.js +0 -278
package/dist/bridgeLocal.js
DELETED
|
@@ -1,744 +0,0 @@
|
|
|
1
|
-
// Bridge ⇄ runtime-adapter LOCAL JSON-RPC contract v1 (types + schemas ONLY —
|
|
2
|
-
// no runtime, no transport; Phase 4 builds the bridge against these).
|
|
3
|
-
//
|
|
4
|
-
// Source spec: docs/design/bridge-local-api.md §A–§C. Where that draft
|
|
5
|
-
// conflicts with code-grounded wire shapes (event names, REST payloads), the
|
|
6
|
-
// code-grounded schemas in this package win — payload slots below COMPOSE
|
|
7
|
-
// restEndpoints.ts / hitl.ts / sseEvents.ts / controlSignals.ts so every
|
|
8
|
-
// shape is defined once.
|
|
9
|
-
//
|
|
10
|
-
// Protocol: JSON-RPC 2.0 over one duplex channel (stdio pipe or unix
|
|
11
|
-
// socket / named pipe), NDJSON framing. Requests adapter→bridge (replied),
|
|
12
|
-
// notifications bridge→adapter (never awaited). `hello` carries
|
|
13
|
-
// protocolVersion — the local contract is version-guarded from v1.
|
|
14
|
-
import { z } from 'zod';
|
|
15
|
-
import { SerializedContactRequestSchema } from './contactRequest.js';
|
|
16
|
-
import { DeliveryIntentSchema, TurnLifecycleStateSchema } from './turnProtocol.js';
|
|
17
|
-
import { ControlPrimitiveEventSchema, ControlSessionEventSchema, ControlSignalEventSchema, } from './controlSignals.js';
|
|
18
|
-
import { HitlApprovalCategorySchema, HitlApprovalDetailSchema, HitlApprovalRiskSchema, HitlInputKindSchema, HitlInputQuestionSchema, HitlPendingSchema, HitlRequestAcceptedSchema, HitlResolutionSchema, HitlResolutionStatusSchema, } from './hitl.js';
|
|
19
|
-
import { ContactsResponseSchema, ConversationsResponseSchema, CreateContactRequestRequestSchema, CreateContactRequestResponseSchema, CreateConversationRequestSchema, CreateConversationResponseSchema, ForwardMessageRequestSchema, ForwardMessageResponseSchema, MessagesPageResponseSchema, ReactRequestSchema, ReactResponseSchema, ResolveAdmissionRequestSchema, ResolveAdmissionResponseSchema, RestContactSchema, RestSessionSelectionSchema, SendMessageRequestSchema, SendMessageResponseSchema, UpdateDispositionRequestSchema, UploadMediaResponseSchema, } from './restEndpoints.js';
|
|
20
|
-
import { SendContextualRequestSchema, SendContextualResponseSchema, } from './sendContextual.js';
|
|
21
|
-
import { SseAgentContextPayloadSchema, SseConversationUpdatedPayloadSchema, SseEventFamilySchema, SseMessageCreatedPayloadSchema, SseMessageDeletedPayloadSchema, SseMessageUpdatedPayloadSchema, SsePresencePayloadSchema, SseTypingPayloadSchema, SseVoiceSessionEventPayloadSchema, } from './sseEvents.js';
|
|
22
|
-
export const BRIDGE_LOCAL_PROTOCOL_VERSION = 1;
|
|
23
|
-
const OkResultSchema = z.object({ ok: z.literal(true) });
|
|
24
|
-
export { OkResultSchema as BridgeOkResultSchema };
|
|
25
|
-
// ── §A Session lifecycle ───────────────────────────────────────────────
|
|
26
|
-
export const BridgeHelloParamsSchema = z.object({
|
|
27
|
-
protocolVersion: z.number(),
|
|
28
|
-
/** Adapter self-identification (claude-code | codex | openclaw | hermes | …). */
|
|
29
|
-
clientType: z.string(),
|
|
30
|
-
/** Event families to deliver; [] = pure-request adapter, no C-notifications. */
|
|
31
|
-
wantFamilies: z.array(SseEventFamilySchema),
|
|
32
|
-
/** Replay C-notifications missed while disconnected. */
|
|
33
|
-
resumeCursor: z.string().optional(),
|
|
34
|
-
/** Publish the runtime descriptor in the same round trip. */
|
|
35
|
-
runtimeDescriptor: z.record(z.string(), z.unknown()).optional(),
|
|
36
|
-
});
|
|
37
|
-
// ── §G resume cursor / resync ───────────────────────────────────────────
|
|
38
|
-
//
|
|
39
|
-
// The bridge keeps a bounded, locally-sequenced event log. Every replayable
|
|
40
|
-
// §C event notification carries the OPAQUE `cursor` token that produced it;
|
|
41
|
-
// adapters persist the last cursor they fully processed and present it as
|
|
42
|
-
// `hello.resumeCursor` on reconnect to replay exactly the gap. When the
|
|
43
|
-
// cursor cannot be honored the hello result answers `sinceCursor: null`
|
|
44
|
-
// PLUS a `resync` field — the adapter must treat the gap as lost locally and
|
|
45
|
-
// recover out-of-band (REST backfill / state refresh). Never silent loss.
|
|
46
|
-
export const BridgeResyncReasonSchema = z.enum([
|
|
47
|
-
/** Cursor was valid but its events were evicted from the bounded log. */
|
|
48
|
-
'cursor-expired',
|
|
49
|
-
/** Cursor was never issued by this bridge run (restart or corruption). */
|
|
50
|
-
'unknown-cursor',
|
|
51
|
-
]);
|
|
52
|
-
export const BridgeResyncSchema = z.object({
|
|
53
|
-
reason: BridgeResyncReasonSchema,
|
|
54
|
-
});
|
|
55
|
-
/**
|
|
56
|
-
* Shape mixin for replayable §C notification params (`.extend(...)` onto the
|
|
57
|
-
* payload schema). `cursor` is optional in the schema for compatibility, but
|
|
58
|
-
* the bridge always sends it on log-delivered notifications. `ready` and
|
|
59
|
-
* `connectionState` are connection-scoped (never replayed) and carry none.
|
|
60
|
-
*/
|
|
61
|
-
export const BRIDGE_EVENT_CURSOR_SHAPE = {
|
|
62
|
-
cursor: z.string().optional(),
|
|
63
|
-
};
|
|
64
|
-
export const BridgeHelloResultSchema = z.object({
|
|
65
|
-
protocolVersion: z.number(),
|
|
66
|
-
agentId: z.string(),
|
|
67
|
-
agentName: z.string(),
|
|
68
|
-
agentContext: SseAgentContextPayloadSchema,
|
|
69
|
-
/** Cursor the delivered replay starts from; null = no replay. */
|
|
70
|
-
sinceCursor: z.string().nullable(),
|
|
71
|
-
/**
|
|
72
|
-
* Present when resumeCursor could not be honored (§G): delivery starts at
|
|
73
|
-
* the live head and the adapter must recover the gap out-of-band.
|
|
74
|
-
*/
|
|
75
|
-
resync: BridgeResyncSchema.optional(),
|
|
76
|
-
});
|
|
77
|
-
export const BridgeUpstreamStateSchema = z.enum(['connected', 'reconnecting', 'down']);
|
|
78
|
-
export const BridgeReadyNotificationSchema = z.object({
|
|
79
|
-
agentId: z.string(),
|
|
80
|
-
agentContext: SseAgentContextPayloadSchema,
|
|
81
|
-
upstreamState: BridgeUpstreamStateSchema,
|
|
82
|
-
});
|
|
83
|
-
export const BridgeConnectionStateNotificationSchema = z.object({
|
|
84
|
-
upstream: BridgeUpstreamStateSchema,
|
|
85
|
-
});
|
|
86
|
-
/**
|
|
87
|
-
* `status` result (B4.6 observability): a live snapshot of the daemon
|
|
88
|
-
* process, its upstream health, and the B4.2 hub counters. Additive to
|
|
89
|
-
* contract v1 — served by the daemon and rendered by `canon-bridge status`.
|
|
90
|
-
*/
|
|
91
|
-
export const BridgeStatusResultSchema = z.object({
|
|
92
|
-
/** Daemon process id. */
|
|
93
|
-
pid: z.number(),
|
|
94
|
-
/** canon-bridge binary (package) version. */
|
|
95
|
-
version: z.string(),
|
|
96
|
-
/** bridgeLocal contract version the daemon speaks. */
|
|
97
|
-
protocolVersion: z.number(),
|
|
98
|
-
/** ISO timestamp of daemon start. */
|
|
99
|
-
startedAt: z.string(),
|
|
100
|
-
uptimeMs: z.number(),
|
|
101
|
-
/** Lifecycle profile served (one identity per daemon). */
|
|
102
|
-
profile: z.string(),
|
|
103
|
-
/** Socket / named-pipe path; null in stdio (spawned-child) mode. */
|
|
104
|
-
socketPath: z.string().nullable(),
|
|
105
|
-
agentId: z.string(),
|
|
106
|
-
agentName: z.string(),
|
|
107
|
-
upstream: BridgeUpstreamStateSchema,
|
|
108
|
-
/** Adapter connections currently subscribed to the fan-out. */
|
|
109
|
-
connectedClients: z.number(),
|
|
110
|
-
/** Non-zero B4.2 hub counters (upstream.* / fanout.*). */
|
|
111
|
-
counters: z.record(z.string(), z.number()),
|
|
112
|
-
});
|
|
113
|
-
// ── §B7 HITL state (durable; resolution arrives via onHitlResolved) ────
|
|
114
|
-
export const BridgeHitlStateSchema = z.object({
|
|
115
|
-
status: z.union([z.literal('pending'), HitlResolutionStatusSchema]),
|
|
116
|
-
answer: z.record(z.string(), z.unknown()).optional(),
|
|
117
|
-
expiresAt: z.string(),
|
|
118
|
-
});
|
|
119
|
-
// ── §B8 media (named schemas so the bridge + Framework share the types) ──
|
|
120
|
-
//
|
|
121
|
-
// Byte transfer is bridge-owned (adapter-interface §1): adapters hand the
|
|
122
|
-
// bridge a {path} (streamed from disk — preferred for anything big) or
|
|
123
|
-
// inline {bytes} (base64, size-capped so a frame never breaches the NDJSON
|
|
124
|
-
// line limit). getAttachment returns the bridge-cached materialization.
|
|
125
|
-
export const BridgeUploadMediaParamsSchema = z.object({
|
|
126
|
-
/** Absolute file path — the bridge streams it (exactly one of path | bytes). */
|
|
127
|
-
path: z.string().optional(),
|
|
128
|
-
/** Base64 bytes — size-capped by the bridge; prefer `path` for large files. */
|
|
129
|
-
bytes: z.string().optional(),
|
|
130
|
-
mime: z.string(),
|
|
131
|
-
fileName: z.string(),
|
|
132
|
-
conversationId: z.string(),
|
|
133
|
-
});
|
|
134
|
-
export const BridgeGetAttachmentParamsSchema = z.object({
|
|
135
|
-
/** Storage download URL from a MediaAttachment (exactly one of url | attachmentId). */
|
|
136
|
-
url: z.string().optional(),
|
|
137
|
-
attachmentId: z.string().optional(),
|
|
138
|
-
as: z.enum(['path', 'bytes']),
|
|
139
|
-
});
|
|
140
|
-
export const BridgeGetAttachmentResultSchema = z.object({
|
|
141
|
-
/** Stable bridge-cache path — present when as:'path'. */
|
|
142
|
-
path: z.string().optional(),
|
|
143
|
-
/** Base64 — present when as:'bytes'; capped by the bridge's bytes ceiling. */
|
|
144
|
-
bytes: z.string().optional(),
|
|
145
|
-
mime: z.string(),
|
|
146
|
-
});
|
|
147
|
-
const conversationScoped = z.object({ conversationId: z.string() });
|
|
148
|
-
const messageScoped = z.object({ conversationId: z.string(), messageId: z.string() });
|
|
149
|
-
/**
|
|
150
|
-
* RTDB server-timestamp sentinel — code-grounded pass-through (hosts write
|
|
151
|
-
* `{'.sv':'timestamp'}` for openedAt/completedAt today; the bridge forwards
|
|
152
|
-
* it to the RTDB REST API untouched).
|
|
153
|
-
*/
|
|
154
|
-
const ServerTimestampSentinelSchema = z.object({ '.sv': z.literal('timestamp') });
|
|
155
|
-
const EpochOrServerTimestampSchema = z.union([z.number(), ServerTimestampSentinelSchema]);
|
|
156
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
157
|
-
// W2-A4 REGION START — bridge-owned streaming assembly (raw event surface).
|
|
158
|
-
// ADDITIVE: `publishStreamingEvent` lets a channel adapter forward RAW turn
|
|
159
|
-
// events (a text segment begin/append/replace, a tool-trail item, a thinking
|
|
160
|
-
// tick, a final compose, or a clear). The BRIDGE owns snapshot assembly, the
|
|
161
|
-
// single write cadence, thinking keepalive, final compose, and node clear —
|
|
162
|
-
// so adapters stop reimplementing turn-output-controller + a keepalive loop
|
|
163
|
-
// (T1: they also stop swallowing the write failure). The pre-existing
|
|
164
|
-
// snapshot `publishStreaming` (below) is UNTOUCHED — coding hosts still call
|
|
165
|
-
// it via agent-host/runtime-writers.
|
|
166
|
-
// ─────────────────────────────────────────────────────────────────────────
|
|
167
|
-
/** A single tool-trail item forwarded raw; the bridge folds it into `blocks`. */
|
|
168
|
-
export const BridgeStreamToolEventSchema = z.object({
|
|
169
|
-
kind: z.literal('tool'),
|
|
170
|
-
/** Stable block id (adapter-scoped, e.g. `tool:{turnId}`). */
|
|
171
|
-
id: z.string(),
|
|
172
|
-
status: z.enum(['running', 'completed', 'failed']).optional(),
|
|
173
|
-
title: z.string().optional(),
|
|
174
|
-
summary: z.string().optional(),
|
|
175
|
-
detail: z.string().optional(),
|
|
176
|
-
});
|
|
177
|
-
/**
|
|
178
|
-
* A visible-text segment. `mode:'append'` concatenates onto the segment's
|
|
179
|
-
* running text; `mode:'replace'` overwrites it (the adapter already holds the
|
|
180
|
-
* full segment). The bridge rebuilds the bubble text from its text segments in
|
|
181
|
-
* sequence order, exactly as the core turn-output-controller does today.
|
|
182
|
-
*/
|
|
183
|
-
export const BridgeStreamTextEventSchema = z.object({
|
|
184
|
-
kind: z.literal('text'),
|
|
185
|
-
/** Segment id (adapter-scoped, e.g. `text:{turnId}:{n}`). */
|
|
186
|
-
id: z.string(),
|
|
187
|
-
mode: z.enum(['append', 'replace']),
|
|
188
|
-
text: z.string(),
|
|
189
|
-
});
|
|
190
|
-
/** A thinking tick (onset or keepalive) — no content; keeps the bubble warm. */
|
|
191
|
-
export const BridgeStreamThinkingEventSchema = z.object({
|
|
192
|
-
kind: z.literal('thinking'),
|
|
193
|
-
});
|
|
194
|
-
/**
|
|
195
|
-
* Final compose: the assembled reply text is written one last time (status
|
|
196
|
-
* settles to `streaming`) and the node is LEFT in place for the final-message
|
|
197
|
-
* handoff. Clearing is a separate `clear` event / `clearStreaming`.
|
|
198
|
-
*/
|
|
199
|
-
export const BridgeStreamFinalEventSchema = z.object({
|
|
200
|
-
kind: z.literal('final'),
|
|
201
|
-
text: z.string(),
|
|
202
|
-
});
|
|
203
|
-
/** Clear the streaming node (turn ended / interrupted). */
|
|
204
|
-
export const BridgeStreamClearEventSchema = z.object({
|
|
205
|
-
kind: z.literal('clear'),
|
|
206
|
-
});
|
|
207
|
-
export const BridgeStreamEventSchema = z.discriminatedUnion('kind', [
|
|
208
|
-
BridgeStreamTextEventSchema,
|
|
209
|
-
BridgeStreamToolEventSchema,
|
|
210
|
-
BridgeStreamThinkingEventSchema,
|
|
211
|
-
BridgeStreamFinalEventSchema,
|
|
212
|
-
BridgeStreamClearEventSchema,
|
|
213
|
-
]);
|
|
214
|
-
export const BridgePublishStreamingEventParamsSchema = conversationScoped.extend({
|
|
215
|
-
/** New turnId resets the bridge's accumulation for this conversation. */
|
|
216
|
-
turnId: z.string().nullable().optional(),
|
|
217
|
-
messageId: z.string().optional(),
|
|
218
|
-
event: BridgeStreamEventSchema,
|
|
219
|
-
});
|
|
220
|
-
// W2-A4 REGION END — bridge-owned streaming assembly.
|
|
221
|
-
export const BRIDGE_LOCAL_METHODS = {
|
|
222
|
-
// §A lifecycle
|
|
223
|
-
hello: { params: BridgeHelloParamsSchema, result: BridgeHelloResultSchema },
|
|
224
|
-
/** Liveness probe — the bridge answers without touching upstream. */
|
|
225
|
-
ping: { params: z.object({}), result: OkResultSchema },
|
|
226
|
-
shutdown: { params: z.object({}), result: OkResultSchema },
|
|
227
|
-
/** Daemon snapshot (B4.6): process, upstream health, hub counters. */
|
|
228
|
-
status: { params: z.object({}), result: BridgeStatusResultSchema },
|
|
229
|
-
// §B1 messaging (outbound)
|
|
230
|
-
sendMessage: {
|
|
231
|
-
params: SendMessageRequestSchema,
|
|
232
|
-
// B4.3 additive: the bridge chunks oversized text (core retry/chunking);
|
|
233
|
-
// messageId is the FINAL chunk (carries the caller's metadata/turn
|
|
234
|
-
// semantics), messageIds lists every part in send order.
|
|
235
|
-
result: SendMessageResponseSchema.extend({
|
|
236
|
-
messageIds: z.array(z.string()).optional(),
|
|
237
|
-
}),
|
|
238
|
-
},
|
|
239
|
-
sendContextualMessage: {
|
|
240
|
-
params: SendContextualRequestSchema,
|
|
241
|
-
result: SendContextualResponseSchema,
|
|
242
|
-
},
|
|
243
|
-
reactToMessage: { params: ReactRequestSchema, result: ReactResponseSchema },
|
|
244
|
-
forwardMessage: { params: ForwardMessageRequestSchema, result: ForwardMessageResponseSchema },
|
|
245
|
-
deleteMessage: { params: messageScoped, result: OkResultSchema },
|
|
246
|
-
markRead: { params: conversationScoped, result: OkResultSchema },
|
|
247
|
-
setDisposition: {
|
|
248
|
-
params: messageScoped.extend(UpdateDispositionRequestSchema.shape),
|
|
249
|
-
result: OkResultSchema,
|
|
250
|
-
},
|
|
251
|
-
// §B2 reading / history
|
|
252
|
-
getMessages: {
|
|
253
|
-
params: z.object({
|
|
254
|
-
conversationId: z.string(),
|
|
255
|
-
limit: z.number().optional(),
|
|
256
|
-
before: z.string().optional(),
|
|
257
|
-
includeBehavior: z.boolean().optional(),
|
|
258
|
-
}),
|
|
259
|
-
// B4.3 additive: nextCursor is the bridge-derived `before` token for the
|
|
260
|
-
// next page (oldest returned message id), present when the page filled
|
|
261
|
-
// the requested limit. The REST surface itself emits no cursor.
|
|
262
|
-
result: MessagesPageResponseSchema.extend({
|
|
263
|
-
nextCursor: z.string().optional(),
|
|
264
|
-
}),
|
|
265
|
-
},
|
|
266
|
-
getConversations: { params: z.object({}), result: ConversationsResponseSchema },
|
|
267
|
-
// §B3 conversation / group management
|
|
268
|
-
createConversation: {
|
|
269
|
-
params: CreateConversationRequestSchema,
|
|
270
|
-
result: CreateConversationResponseSchema,
|
|
271
|
-
},
|
|
272
|
-
updateTopic: {
|
|
273
|
-
params: conversationScoped.extend({ topic: z.string() }),
|
|
274
|
-
result: OkResultSchema,
|
|
275
|
-
},
|
|
276
|
-
updateName: {
|
|
277
|
-
params: conversationScoped.extend({ name: z.string() }),
|
|
278
|
-
result: OkResultSchema,
|
|
279
|
-
},
|
|
280
|
-
updateAvatar: {
|
|
281
|
-
params: conversationScoped.extend({ avatarUrl: z.string().nullable().optional() }),
|
|
282
|
-
result: OkResultSchema,
|
|
283
|
-
},
|
|
284
|
-
addMember: {
|
|
285
|
-
params: conversationScoped.extend({ userId: z.string() }),
|
|
286
|
-
result: z.union([
|
|
287
|
-
z.object({ status: z.literal('added') }),
|
|
288
|
-
z.object({ status: z.literal('pending'), requestId: z.string() }),
|
|
289
|
-
]),
|
|
290
|
-
},
|
|
291
|
-
removeMember: {
|
|
292
|
-
params: conversationScoped.extend({ userId: z.string() }),
|
|
293
|
-
result: OkResultSchema,
|
|
294
|
-
},
|
|
295
|
-
leaveConversation: { params: conversationScoped, result: OkResultSchema },
|
|
296
|
-
muteConversation: {
|
|
297
|
-
params: conversationScoped.extend({ until: z.number().optional() }),
|
|
298
|
-
result: OkResultSchema,
|
|
299
|
-
},
|
|
300
|
-
unmuteConversation: { params: conversationScoped, result: OkResultSchema },
|
|
301
|
-
hideConversation: { params: conversationScoped, result: OkResultSchema },
|
|
302
|
-
// §B4 contacts / admission / blocking
|
|
303
|
-
createContactRequest: {
|
|
304
|
-
params: CreateContactRequestRequestSchema,
|
|
305
|
-
result: CreateContactRequestResponseSchema,
|
|
306
|
-
},
|
|
307
|
-
listContacts: { params: z.object({}), result: ContactsResponseSchema },
|
|
308
|
-
getContact: {
|
|
309
|
-
params: z.object({ contactId: z.string() }),
|
|
310
|
-
result: RestContactSchema.nullable(),
|
|
311
|
-
},
|
|
312
|
-
removeContact: { params: z.object({ contactId: z.string() }), result: OkResultSchema },
|
|
313
|
-
listContactRequests: {
|
|
314
|
-
params: z.object({}),
|
|
315
|
-
result: z.object({ requests: z.array(SerializedContactRequestSchema) }),
|
|
316
|
-
},
|
|
317
|
-
resolveAdmission: {
|
|
318
|
-
params: ResolveAdmissionRequestSchema,
|
|
319
|
-
result: ResolveAdmissionResponseSchema,
|
|
320
|
-
},
|
|
321
|
-
reachOut: {
|
|
322
|
-
// B6.1 additive (P6 openclaw): the optional fields mirror core
|
|
323
|
-
// reachOutToCanonContact options — contact-request message, agent
|
|
324
|
-
// session config/selection, and SendMessageOptions passthrough — so
|
|
325
|
-
// channel adapters keep today's reach-out fidelity through the bridge.
|
|
326
|
-
params: z.object({
|
|
327
|
-
targetId: z.string(),
|
|
328
|
-
/**
|
|
329
|
-
* Optional (B6.1): core reach-out treats a missing text as
|
|
330
|
-
* "resolve/open the conversation only" — the openclaw media path
|
|
331
|
-
* reaches out first and sends the uploaded attachment separately.
|
|
332
|
-
*/
|
|
333
|
-
text: z.string().optional(),
|
|
334
|
-
selfContext: z.string().optional(),
|
|
335
|
-
/** Contact-request message when admission requires approval. */
|
|
336
|
-
requestMessage: z.string().optional(),
|
|
337
|
-
/** Initial agent session config — opaque pass-through. */
|
|
338
|
-
sessionConfig: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
339
|
-
/** Same union as the REST send surfaces (incl. mode: 'specific'). */
|
|
340
|
-
sessionSelection: RestSessionSelectionSchema.optional(),
|
|
341
|
-
/** SendMessageOptions passthrough (replyTo, selfContextId, metadata, …). */
|
|
342
|
-
sendMessageOptions: z.record(z.string(), z.unknown()).optional(),
|
|
343
|
-
}),
|
|
344
|
-
result: z.record(z.string(), z.unknown()),
|
|
345
|
-
},
|
|
346
|
-
blockUser: { params: z.object({ userId: z.string() }), result: OkResultSchema },
|
|
347
|
-
unblockUser: { params: z.object({ userId: z.string() }), result: OkResultSchema },
|
|
348
|
-
// §B5 live presence / streaming (bridge throttles internally)
|
|
349
|
-
setTyping: {
|
|
350
|
-
params: conversationScoped.extend({ state: z.enum(['typing', 'thinking', 'clear']) }),
|
|
351
|
-
result: OkResultSchema,
|
|
352
|
-
},
|
|
353
|
-
publishStreaming: {
|
|
354
|
-
params: conversationScoped.extend({
|
|
355
|
-
turnId: z.string().nullable().optional(),
|
|
356
|
-
messageId: z.string().optional(),
|
|
357
|
-
text: z.string().optional(),
|
|
358
|
-
delta: z.string().optional(),
|
|
359
|
-
/** TurnOutputBlock[] — opaque pass-through. */
|
|
360
|
-
blocks: z.array(z.record(z.string(), z.unknown())).optional(),
|
|
361
|
-
/**
|
|
362
|
-
* Explicit bubble/presentation status override (union of B6.1 openclaw
|
|
363
|
-
* + P6 host surface): 'tool' / 'waiting_input' cannot be derived from
|
|
364
|
-
* text/blocks. Omitted: the bridge derives thinking/streaming from
|
|
365
|
-
* content as before.
|
|
366
|
-
*/
|
|
367
|
-
status: z.enum(['thinking', 'streaming', 'tool', 'waiting_input']).optional(),
|
|
368
|
-
done: z.boolean().optional(),
|
|
369
|
-
}),
|
|
370
|
-
result: OkResultSchema,
|
|
371
|
-
},
|
|
372
|
-
clearStreaming: { params: conversationScoped, result: OkResultSchema },
|
|
373
|
-
// W2-A4 additive: raw streaming events (bridge owns assembly/cadence/
|
|
374
|
-
// keepalive/final/clear). Coexists with the snapshot publishStreaming above.
|
|
375
|
-
publishStreamingEvent: {
|
|
376
|
-
params: BridgePublishStreamingEventParamsSchema,
|
|
377
|
-
result: OkResultSchema,
|
|
378
|
-
},
|
|
379
|
-
// §B6 runtime presentation (adapter owns content, bridge publishes)
|
|
380
|
-
publishRuntimeDescriptor: {
|
|
381
|
-
params: z.object({
|
|
382
|
-
descriptor: z.record(z.string(), z.unknown()),
|
|
383
|
-
/**
|
|
384
|
-
* B6.1 additive (P6 openclaw): rides into the published /agent-runtime
|
|
385
|
-
* payload — hosts and host-mode channel plugins publish hostMode: true
|
|
386
|
-
* today and the field is app-visible. Latched for subsequent publishes;
|
|
387
|
-
* defaults to false (bridge-adapter split is not a host process).
|
|
388
|
-
*/
|
|
389
|
-
hostMode: z.boolean().optional(),
|
|
390
|
-
}),
|
|
391
|
-
result: OkResultSchema,
|
|
392
|
-
},
|
|
393
|
-
publishRuntimeStatus: {
|
|
394
|
-
// Code-grounded correction (B4.3): RTDB runtime-info lives per
|
|
395
|
-
// conversation (/runtime-info/{convoId}/{agentId}), so the publish is
|
|
396
|
-
// conversation-scoped. `presentation` carries the remaining
|
|
397
|
-
// RuntimeInfoPayload fields (surfaceMode, facts, inventories, notes, …)
|
|
398
|
-
// as an opaque pass-through.
|
|
399
|
-
params: conversationScoped.extend({
|
|
400
|
-
statusItems: z.array(z.record(z.string(), z.unknown())).optional(),
|
|
401
|
-
presentation: z.record(z.string(), z.unknown()).optional(),
|
|
402
|
-
}),
|
|
403
|
-
result: OkResultSchema,
|
|
404
|
-
},
|
|
405
|
-
publishTurnState: {
|
|
406
|
-
// B6.1 additive (P6 openclaw): the remaining CanonTurnStatePayload
|
|
407
|
-
// fields hosts publish today. `completedAt: true` asks the bridge to
|
|
408
|
-
// stamp the server timestamp (the RTDB sentinel is bridge-owned).
|
|
409
|
-
params: conversationScoped.extend({
|
|
410
|
-
turnId: z.string().nullable().optional(),
|
|
411
|
-
state: TurnLifecycleStateSchema,
|
|
412
|
-
queueDepth: z.number().optional(),
|
|
413
|
-
capabilities: z.record(z.string(), z.unknown()).optional(),
|
|
414
|
-
// Union of B6.1 (openclaw) + P6 host surface — the remaining
|
|
415
|
-
// code-grounded TurnStatePayload fields (rtdb-rest.ts).
|
|
416
|
-
currentSpeakerId: z.string().nullable().optional(),
|
|
417
|
-
lastAcceptedIntent: DeliveryIntentSchema.nullable().optional(),
|
|
418
|
-
activeMessageIds: z.array(z.string()).optional(),
|
|
419
|
-
openedAt: EpochOrServerTimestampSchema.optional(),
|
|
420
|
-
turnUpdatedAt: EpochOrServerTimestampSchema.nullable().optional(),
|
|
421
|
-
// `true` (B6.1 openclaw) asks the bridge to stamp the server-timestamp
|
|
422
|
-
// sentinel; hosts (P6) pass an epoch or the sentinel through directly.
|
|
423
|
-
completedAt: z
|
|
424
|
-
.union([z.boolean(), EpochOrServerTimestampSchema])
|
|
425
|
-
.nullable()
|
|
426
|
-
.optional(),
|
|
427
|
-
}),
|
|
428
|
-
result: OkResultSchema,
|
|
429
|
-
},
|
|
430
|
-
clearTurnState: { params: conversationScoped, result: OkResultSchema },
|
|
431
|
-
publishActivity: {
|
|
432
|
-
params: conversationScoped.extend({
|
|
433
|
-
activityItems: z.array(z.record(z.string(), z.unknown())),
|
|
434
|
-
}),
|
|
435
|
-
result: OkResultSchema,
|
|
436
|
-
},
|
|
437
|
-
clearActivity: {
|
|
438
|
-
// B6.1 additive (P6 openclaw): remove activity blocks. `all` wipes the
|
|
439
|
-
// conversation's node; `itemIds` removes specific blocks; neither falls
|
|
440
|
-
// back to the publisher's terminal-only sweep semantics.
|
|
441
|
-
params: conversationScoped.extend({
|
|
442
|
-
all: z.boolean().optional(),
|
|
443
|
-
itemIds: z.array(z.string()).optional(),
|
|
444
|
-
}),
|
|
445
|
-
result: OkResultSchema,
|
|
446
|
-
},
|
|
447
|
-
/** B6.1 additive: clear the per-conversation runtime-info node. */
|
|
448
|
-
clearRuntimeStatus: { params: conversationScoped, result: OkResultSchema },
|
|
449
|
-
/**
|
|
450
|
-
* B6.1 additive: clear /agent-runtime for this identity (preserves
|
|
451
|
-
* descriptor-bearing payloads with updatedAt: 0, like hosts do today).
|
|
452
|
-
*/
|
|
453
|
-
clearRuntimeDescriptor: { params: z.object({}), result: OkResultSchema },
|
|
454
|
-
// §B7 HITL (durable; returns requestId, resolves via onHitlResolved).
|
|
455
|
-
//
|
|
456
|
-
// P6 host surface (additive): process-executing hosts publish the SAME
|
|
457
|
-
// rich records channel runtimes create today (approval cards with
|
|
458
|
-
// diff/details/native handles, titled input cards, card ids the runtime
|
|
459
|
-
// correlates on). All new fields are optional — the narrow Phase-4 shape
|
|
460
|
-
// still parses. `requestId`/`inputId`/`cardId`-style explicit ids become
|
|
461
|
-
// the bridge record's requestId so adapters keep their own correlation.
|
|
462
|
-
// `responseUserId: null` means "let the server pick a reachable responder"
|
|
463
|
-
// (codex cards today); absent keeps the Phase-4 default (agent owner).
|
|
464
|
-
requestApproval: {
|
|
465
|
-
// B6.1 additive (P6 openclaw): optional approval-card fidelity fields
|
|
466
|
-
// (core createRuntimeApprovalRequest passthrough) so native runtime
|
|
467
|
-
// approvals keep their tool name, detail rows, correlation handles and
|
|
468
|
-
// allow-always affordance through the bridge.
|
|
469
|
-
params: conversationScoped.extend({
|
|
470
|
-
detail: z.string(),
|
|
471
|
-
risk: HitlApprovalRiskSchema,
|
|
472
|
-
category: HitlApprovalCategorySchema,
|
|
473
|
-
expiresAt: z.string().optional(),
|
|
474
|
-
approvalId: z.string().optional(),
|
|
475
|
-
/** Card header tool name; defaults to the category. */
|
|
476
|
-
toolName: z.string().optional(),
|
|
477
|
-
riskLevel: z.enum(['normal', 'destructive']).optional(),
|
|
478
|
-
details: z.array(HitlApprovalDetailSchema).optional(),
|
|
479
|
-
/** File-change preview (CanonUnifiedDiff) — opaque pass-through. */
|
|
480
|
-
diff: z.record(z.string(), z.unknown()).optional(),
|
|
481
|
-
/** Native runtime correlation handles — opaque pass-through. */
|
|
482
|
-
native: z.record(z.string(), z.unknown()).optional(),
|
|
483
|
-
turnId: z.string().optional(),
|
|
484
|
-
runtimeId: z.string().optional(),
|
|
485
|
-
/** Offer the "always allow" session-rule affordance on the card. */
|
|
486
|
-
allowSessionRule: z.boolean().optional(),
|
|
487
|
-
responseUserId: z.string().nullable().optional(),
|
|
488
|
-
}),
|
|
489
|
-
result: HitlRequestAcceptedSchema,
|
|
490
|
-
},
|
|
491
|
-
requestInput: {
|
|
492
|
-
params: conversationScoped.extend({
|
|
493
|
-
questions: z.array(HitlInputQuestionSchema),
|
|
494
|
-
expiresAt: z.string().optional(),
|
|
495
|
-
inputId: z.string().optional(),
|
|
496
|
-
title: z.string().optional(),
|
|
497
|
-
prompt: z.string().optional(),
|
|
498
|
-
kind: HitlInputKindSchema.optional(),
|
|
499
|
-
sensitive: z.boolean().optional(),
|
|
500
|
-
native: z.record(z.string(), z.unknown()).optional(),
|
|
501
|
-
turnId: z.string().optional(),
|
|
502
|
-
responseUserId: z.string().nullable().optional(),
|
|
503
|
-
}),
|
|
504
|
-
result: HitlRequestAcceptedSchema,
|
|
505
|
-
},
|
|
506
|
-
requestCard: {
|
|
507
|
-
params: conversationScoped.extend({
|
|
508
|
-
/** canon.card.v1 content — opaque pass-through. */
|
|
509
|
-
card: z.record(z.string(), z.unknown()),
|
|
510
|
-
expiresAt: z.string().optional(),
|
|
511
|
-
cardId: z.string().optional(),
|
|
512
|
-
native: z.record(z.string(), z.unknown()).optional(),
|
|
513
|
-
turnId: z.string().optional(),
|
|
514
|
-
responseUserId: z.string().nullable().optional(),
|
|
515
|
-
}),
|
|
516
|
-
result: HitlRequestAcceptedSchema,
|
|
517
|
-
},
|
|
518
|
-
getHitlState: {
|
|
519
|
-
params: z.object({ requestId: z.string() }),
|
|
520
|
-
result: BridgeHitlStateSchema,
|
|
521
|
-
},
|
|
522
|
-
cancelHitl: { params: z.object({ requestId: z.string() }), result: OkResultSchema },
|
|
523
|
-
// §B8 media (named schemas above — the bridge + Framework share them)
|
|
524
|
-
uploadMedia: {
|
|
525
|
-
params: BridgeUploadMediaParamsSchema,
|
|
526
|
-
result: UploadMediaResponseSchema,
|
|
527
|
-
},
|
|
528
|
-
getAttachment: {
|
|
529
|
-
params: BridgeGetAttachmentParamsSchema,
|
|
530
|
-
result: BridgeGetAttachmentResultSchema,
|
|
531
|
-
},
|
|
532
|
-
// §B9 voice (media stays client↔LiveKit; bridge brokers the token).
|
|
533
|
-
// Code-grounded correction (B4.3): every /voice/sessions/:id REST op
|
|
534
|
-
// requires the conversationId (body or query) — the session doc lives
|
|
535
|
-
// under the conversation — so the session-scoped methods carry it too.
|
|
536
|
-
createVoiceSession: {
|
|
537
|
-
params: conversationScoped.extend({ targetAgentId: z.string().optional() }),
|
|
538
|
-
result: z.looseObject({ sessionId: z.string() }),
|
|
539
|
-
},
|
|
540
|
-
joinVoiceSession: {
|
|
541
|
-
params: z.object({ sessionId: z.string(), conversationId: z.string() }),
|
|
542
|
-
result: z.looseObject({ url: z.string(), token: z.string() }),
|
|
543
|
-
},
|
|
544
|
-
endVoiceSession: {
|
|
545
|
-
params: z.object({ sessionId: z.string(), conversationId: z.string() }),
|
|
546
|
-
result: OkResultSchema,
|
|
547
|
-
},
|
|
548
|
-
getVoiceSession: {
|
|
549
|
-
params: z.object({ sessionId: z.string(), conversationId: z.string() }),
|
|
550
|
-
result: SseVoiceSessionEventPayloadSchema,
|
|
551
|
-
},
|
|
552
|
-
// §B10 registration / identity
|
|
553
|
-
getAgent: {
|
|
554
|
-
params: z.object({}),
|
|
555
|
-
result: z.object({
|
|
556
|
-
agentId: z.string(),
|
|
557
|
-
agentName: z.string(),
|
|
558
|
-
context: SseAgentContextPayloadSchema,
|
|
559
|
-
}),
|
|
560
|
-
},
|
|
561
|
-
register: {
|
|
562
|
-
params: z.record(z.string(), z.unknown()),
|
|
563
|
-
// pollToken (when issued) authorizes subsequent status polls.
|
|
564
|
-
result: z.object({ requestId: z.string(), pollToken: z.string().optional() }),
|
|
565
|
-
},
|
|
566
|
-
getRegistrationStatus: {
|
|
567
|
-
// `baseUrl` (B6.1 additive) supports the pre-identity bootstrap: the
|
|
568
|
-
// registration statics are unauthenticated, so a stub-identity bridge
|
|
569
|
-
// can serve them with an explicit endpoint.
|
|
570
|
-
params: z.object({
|
|
571
|
-
requestId: z.string(),
|
|
572
|
-
pollToken: z.string().optional(),
|
|
573
|
-
baseUrl: z.string().optional(),
|
|
574
|
-
}),
|
|
575
|
-
result: z.looseObject({ status: z.string() }),
|
|
576
|
-
},
|
|
577
|
-
/**
|
|
578
|
-
* Acknowledge one-time API-key delivery after an approved registration
|
|
579
|
-
* (POST /agents/status/:id/ack). Best-effort on the wire; failures surface
|
|
580
|
-
* as upstream-band errors. Additive union of Phase 5 + P6 openclaw: the
|
|
581
|
-
* Hermes port consumed it through the GENERIC Python escape hatch first
|
|
582
|
-
* (a bridge-side method addition with zero framework-py release), and
|
|
583
|
-
* `baseUrl` (B6.1) supports the wizard's per-call pre-identity bootstrap.
|
|
584
|
-
*/
|
|
585
|
-
ackRegistrationStatus: {
|
|
586
|
-
params: z.object({
|
|
587
|
-
requestId: z.string(),
|
|
588
|
-
pollToken: z.string().optional(),
|
|
589
|
-
baseUrl: z.string().optional(),
|
|
590
|
-
}),
|
|
591
|
-
result: OkResultSchema,
|
|
592
|
-
},
|
|
593
|
-
// §5b host-profile surface (bridge-execution-plan Phase 4 step 5b) —
|
|
594
|
-
// additive methods for process-executing (host-mode) adapters, beyond §B.
|
|
595
|
-
// Shapes mirror @canonmsg/core host-runtime-wire.ts; runtime payloads are
|
|
596
|
-
// opaque pass-through (AgentRuntime).
|
|
597
|
-
publishHostAgentRuntime: {
|
|
598
|
-
params: z.object({
|
|
599
|
-
/** Defaults to the hello clientType. */
|
|
600
|
-
clientType: z.string().optional(),
|
|
601
|
-
/** AgentRuntime — opaque pass-through. */
|
|
602
|
-
runtime: z.record(z.string(), z.unknown()),
|
|
603
|
-
}),
|
|
604
|
-
result: OkResultSchema,
|
|
605
|
-
},
|
|
606
|
-
publishHostSessionSnapshots: {
|
|
607
|
-
params: z.object({
|
|
608
|
-
conversationIds: z.array(z.string()),
|
|
609
|
-
/** Defaults to the hello clientType. */
|
|
610
|
-
clientType: z.string().optional(),
|
|
611
|
-
/** AgentRuntime — opaque pass-through. */
|
|
612
|
-
runtime: z.record(z.string(), z.unknown()),
|
|
613
|
-
workspaceOptions: z.array(z.object({ id: z.string(), cwd: z.string() })).optional(),
|
|
614
|
-
defaultCwd: z.string().optional(),
|
|
615
|
-
extraSessionConfigFields: z.array(z.string()).optional(),
|
|
616
|
-
/** conversationId → live session-config overrides (JSON'd Map). */
|
|
617
|
-
liveSessionConfigByConversation: z
|
|
618
|
-
.record(z.string(), z.record(z.string(), z.unknown()))
|
|
619
|
-
.optional(),
|
|
620
|
-
}),
|
|
621
|
-
result: OkResultSchema,
|
|
622
|
-
},
|
|
623
|
-
// §5b host-profile surface, P6 additions (bridge-execution-plan Phase 6) —
|
|
624
|
-
// the remaining RTDB planes the process-executing hosts touched directly
|
|
625
|
-
// until now: the per-conversation session-state node, its config read, and
|
|
626
|
-
// the terminal clears. Payloads mirror @canonmsg/core rtdb-rest.ts shapes
|
|
627
|
-
// as opaque pass-through; the bridge executes them through the core
|
|
628
|
-
// runtime-state publisher (hostMode) over its single RTDB handle.
|
|
629
|
-
getSessionConfig: {
|
|
630
|
-
params: conversationScoped,
|
|
631
|
-
/** Raw `/session-config/{convoId}/{agentId}` node; adapters parse locally. */
|
|
632
|
-
result: z.record(z.string(), z.unknown()).nullable(),
|
|
633
|
-
},
|
|
634
|
-
publishSessionState: {
|
|
635
|
-
params: conversationScoped.extend({
|
|
636
|
-
/** SessionStatePayload minus updatedAt — opaque pass-through. */
|
|
637
|
-
state: z.record(z.string(), z.unknown()),
|
|
638
|
-
}),
|
|
639
|
-
result: OkResultSchema,
|
|
640
|
-
},
|
|
641
|
-
clearSessionState: { params: conversationScoped, result: OkResultSchema },
|
|
642
|
-
// clearTurnState is defined once under §B6 above (both legs added it; the
|
|
643
|
-
// clear is publisher-agnostic so channel adapters and hosts share it).
|
|
644
|
-
/**
|
|
645
|
-
* Terminal /agent-runtime clear through the HOST publisher. Same RTDB
|
|
646
|
-
* effect as §B6.1 clearRuntimeDescriptor (preserve descriptor-bearing
|
|
647
|
-
* payloads with updatedAt: 0) — kept as a distinct §5b name because host
|
|
648
|
-
* consumers correlate it with the publishHostAgentRuntime plane.
|
|
649
|
-
*/
|
|
650
|
-
clearAgentRuntime: { params: z.object({}), result: OkResultSchema },
|
|
651
|
-
};
|
|
652
|
-
export const BRIDGE_LOCAL_METHOD_NAMES = Object.keys(BRIDGE_LOCAL_METHODS);
|
|
653
|
-
// ── §C Notification registry (bridge → adapter, one-way) ───────────────
|
|
654
|
-
export const BRIDGE_LOCAL_NOTIFICATIONS = {
|
|
655
|
-
// §A — connection-scoped, never replayed, no cursor
|
|
656
|
-
ready: BridgeReadyNotificationSchema,
|
|
657
|
-
connectionState: BridgeConnectionStateNotificationSchema,
|
|
658
|
-
// §C1 inbound messages (pre-filtered: deduped, self/control stripped)
|
|
659
|
-
onMessage: SseMessageCreatedPayloadSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
660
|
-
onMessageUpdated: SseMessageUpdatedPayloadSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
661
|
-
onMessageDeleted: SseMessageDeletedPayloadSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
662
|
-
onConversationUpdated: SseConversationUpdatedPayloadSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
663
|
-
// §C2 control (bridge consumed from RTDB — adapters never poll)
|
|
664
|
-
onControlSignal: ControlSignalEventSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
665
|
-
onSessionControl: ControlSessionEventSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
666
|
-
// §C2 addition (P6, both legs): `/control/.../primitive` runtime command
|
|
667
|
-
// dispatch (/status, /compact, …) consumed by the bridge poller — adapters
|
|
668
|
-
// (openclaw handlers, codex compact) never poll RTDB themselves.
|
|
669
|
-
onControlPrimitive: ControlPrimitiveEventSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
670
|
-
// §C6 HITL resolution (durable; matches a §B7 requestId)
|
|
671
|
-
onHitlResolved: HitlResolutionSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
672
|
-
onHitlPending: HitlPendingSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
673
|
-
/**
|
|
674
|
-
* §C6 addition (P6 host surface): a stripped HITL control-reply message
|
|
675
|
-
* (metadata.type approval_reply / plan_approval_reply) that matched NO
|
|
676
|
-
* bridge-owned HITL record fans out here instead of being dropped —
|
|
677
|
-
* process-executing hosts run reply flows the bridge did not raise
|
|
678
|
-
* (claude plan approval is a plain sendMessage + metadata-reply waiter).
|
|
679
|
-
* `message` is the serialized Canon message, opaque pass-through.
|
|
680
|
-
*/
|
|
681
|
-
onControlReply: z.object({
|
|
682
|
-
conversationId: z.string(),
|
|
683
|
-
message: z.record(z.string(), z.unknown()),
|
|
684
|
-
}).extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
685
|
-
// §C3 contacts
|
|
686
|
-
onContactChanged: z.object({
|
|
687
|
-
kind: z.enum(['request', 'approved', 'added', 'updated', 'removed']),
|
|
688
|
-
contact: z.record(z.string(), z.unknown()),
|
|
689
|
-
}).extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
690
|
-
// §C4 typing / presence
|
|
691
|
-
onTyping: SseTypingPayloadSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
692
|
-
onPresence: SsePresencePayloadSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
693
|
-
// §C5 voice
|
|
694
|
-
onVoiceSessionStarted: SseVoiceSessionEventPayloadSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
695
|
-
onVoiceSessionEnded: SseVoiceSessionEventPayloadSchema.extend(BRIDGE_EVENT_CURSOR_SHAPE),
|
|
696
|
-
};
|
|
697
|
-
export const BRIDGE_LOCAL_NOTIFICATION_NAMES = Object.keys(BRIDGE_LOCAL_NOTIFICATIONS);
|
|
698
|
-
/**
|
|
699
|
-
* Event family per §C notification, mirroring SSE_EVENT_FAMILY_BY_TYPE.
|
|
700
|
-
* `lifecycle` notifications are connection-scoped and delivered to every
|
|
701
|
-
* client; family notifications are filtered by `hello.wantFamilies`
|
|
702
|
-
* (`wantFamilies: []` = pure-request adapter, no §C events at all).
|
|
703
|
-
*/
|
|
704
|
-
export const BRIDGE_LOCAL_NOTIFICATION_FAMILIES = {
|
|
705
|
-
ready: 'lifecycle',
|
|
706
|
-
connectionState: 'lifecycle',
|
|
707
|
-
onMessage: 'messages',
|
|
708
|
-
onMessageUpdated: 'messages',
|
|
709
|
-
onMessageDeleted: 'messages',
|
|
710
|
-
onConversationUpdated: 'messages',
|
|
711
|
-
onControlSignal: 'runtime_turn',
|
|
712
|
-
onSessionControl: 'runtime_turn',
|
|
713
|
-
onControlPrimitive: 'runtime_turn',
|
|
714
|
-
onHitlResolved: 'runtime_turn',
|
|
715
|
-
onHitlPending: 'runtime_turn',
|
|
716
|
-
onControlReply: 'runtime_turn',
|
|
717
|
-
onContactChanged: 'contacts',
|
|
718
|
-
onTyping: 'typing_presence',
|
|
719
|
-
onPresence: 'typing_presence',
|
|
720
|
-
onVoiceSessionStarted: 'voice',
|
|
721
|
-
onVoiceSessionEnded: 'voice',
|
|
722
|
-
};
|
|
723
|
-
// ── JSON-RPC 2.0 framing ───────────────────────────────────────────────
|
|
724
|
-
export const BridgeRpcIdSchema = z.union([z.string(), z.number()]);
|
|
725
|
-
export const BridgeRpcRequestSchema = z.object({
|
|
726
|
-
jsonrpc: z.literal('2.0'),
|
|
727
|
-
id: BridgeRpcIdSchema,
|
|
728
|
-
method: z.string(),
|
|
729
|
-
params: z.unknown().optional(),
|
|
730
|
-
});
|
|
731
|
-
export const BridgeRpcNotificationSchema = z.object({
|
|
732
|
-
jsonrpc: z.literal('2.0'),
|
|
733
|
-
method: z.string(),
|
|
734
|
-
params: z.unknown().optional(),
|
|
735
|
-
});
|
|
736
|
-
export const BridgeRpcErrorSchema = z.object({
|
|
737
|
-
code: z.number(),
|
|
738
|
-
message: z.string(),
|
|
739
|
-
data: z.unknown().optional(),
|
|
740
|
-
});
|
|
741
|
-
export const BridgeRpcResponseSchema = z.union([
|
|
742
|
-
z.object({ jsonrpc: z.literal('2.0'), id: BridgeRpcIdSchema, result: z.unknown() }),
|
|
743
|
-
z.object({ jsonrpc: z.literal('2.0'), id: BridgeRpcIdSchema.nullable(), error: BridgeRpcErrorSchema }),
|
|
744
|
-
]);
|