openclaw-channel-bgos 0.6.1
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 +87 -0
- package/dist/agent-hints.d.ts +29 -0
- package/dist/agent-hints.d.ts.map +1 -0
- package/dist/agent-hints.js +169 -0
- package/dist/agent-hints.js.map +1 -0
- package/dist/approval-handler.d.ts +71 -0
- package/dist/approval-handler.d.ts.map +1 -0
- package/dist/approval-handler.js +121 -0
- package/dist/approval-handler.js.map +1 -0
- package/dist/bgos-api.d.ts +111 -0
- package/dist/bgos-api.d.ts.map +1 -0
- package/dist/bgos-api.js +136 -0
- package/dist/bgos-api.js.map +1 -0
- package/dist/bgos-ws.d.ts +69 -0
- package/dist/bgos-ws.d.ts.map +1 -0
- package/dist/bgos-ws.js +172 -0
- package/dist/bgos-ws.js.map +1 -0
- package/dist/commands-sync.d.ts +24 -0
- package/dist/commands-sync.d.ts.map +1 -0
- package/dist/commands-sync.js +43 -0
- package/dist/commands-sync.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +36 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon-helpers.d.ts +109 -0
- package/dist/daemon-helpers.d.ts.map +1 -0
- package/dist/daemon-helpers.js +194 -0
- package/dist/daemon-helpers.js.map +1 -0
- package/dist/daemon.d.ts +23 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +645 -0
- package/dist/daemon.js.map +1 -0
- package/dist/default-commands.d.ts +17 -0
- package/dist/default-commands.d.ts.map +1 -0
- package/dist/default-commands.js +59 -0
- package/dist/default-commands.js.map +1 -0
- package/dist/inbound.d.ts +39 -0
- package/dist/inbound.d.ts.map +1 -0
- package/dist/inbound.js +39 -0
- package/dist/inbound.js.map +1 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/openclaw-gateway-client.d.ts +48 -0
- package/dist/openclaw-gateway-client.d.ts.map +1 -0
- package/dist/openclaw-gateway-client.js +109 -0
- package/dist/openclaw-gateway-client.js.map +1 -0
- package/dist/outbound.d.ts +160 -0
- package/dist/outbound.d.ts.map +1 -0
- package/dist/outbound.js +229 -0
- package/dist/outbound.js.map +1 -0
- package/dist/pair-cli.d.ts +30 -0
- package/dist/pair-cli.d.ts.map +1 -0
- package/dist/pair-cli.js +28 -0
- package/dist/pair-cli.js.map +1 -0
- package/dist/peers-server.d.ts +67 -0
- package/dist/peers-server.d.ts.map +1 -0
- package/dist/peers-server.js +226 -0
- package/dist/peers-server.js.map +1 -0
- package/dist/processed-ids.d.ts +35 -0
- package/dist/processed-ids.d.ts.map +1 -0
- package/dist/processed-ids.js +54 -0
- package/dist/processed-ids.js.map +1 -0
- package/dist/setup-entry.d.ts +44 -0
- package/dist/setup-entry.d.ts.map +1 -0
- package/dist/setup-entry.js +60 -0
- package/dist/setup-entry.js.map +1 -0
- package/dist/types.d.ts +279 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/openclaw.plugin.json +36 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# openclaw-channel-bgos
|
|
2
|
+
|
|
3
|
+
OpenClaw channel plugin for BGOS — chat with your OpenClaw agents inside the BGOS app.
|
|
4
|
+
|
|
5
|
+
Mirrors the shape of the Telegram plugin: pairing, inbound push + REST backfill, outbound text/buttons/approvals, slash-command manifest sync.
|
|
6
|
+
|
|
7
|
+
## Status
|
|
8
|
+
|
|
9
|
+
**Scaffold — not yet published.** Core adapters are implemented and unit-tested. Full wiring into OpenClaw's channel-plugin SDK (the `defineChannelPluginEntry` wrapper and agent-dispatch hook) happens in Phase 4 against a live OpenClaw gateway.
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
- Node.js 20+
|
|
14
|
+
- BGOS backend with the `/api/v1/integrations/*` endpoints (PR #41 merged and deployed — see `docs/superpowers/specs/2026-04-20-openclaw-bgos-integration-design.md`)
|
|
15
|
+
- OpenClaw gateway ≥ 1.0 (for the SDK wrapper in Phase 4)
|
|
16
|
+
|
|
17
|
+
## Install (local dev)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
cd openclaw-channel-bgos
|
|
21
|
+
npm install
|
|
22
|
+
npm run build
|
|
23
|
+
npm test # runs vitest — 30 tests against a mock BGOS server
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Pair from OpenClaw CLI
|
|
27
|
+
|
|
28
|
+
Once published (or `npm link`-ed into an OpenClaw workspace):
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
openclaw pair bgos BGOS-ABCD-EF
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This calls `POST /api/v1/integrations/pair-exchange`, stores the raw pairing token at `~/.openclaw/secrets/bgos.json` with mode 0600, and echoes the local agent-route catalog back to BGOS so it renders the checklist.
|
|
35
|
+
|
|
36
|
+
## Plugin config (channels.bgos)
|
|
37
|
+
|
|
38
|
+
```json5
|
|
39
|
+
{
|
|
40
|
+
"channels": {
|
|
41
|
+
"bgos": {
|
|
42
|
+
"baseUrl": "https://api.brandgrowthos.ai",
|
|
43
|
+
"pairingToken": "<token from CLI>",
|
|
44
|
+
"reconnect": { "initialDelayMs": 1000, "maxDelayMs": 30000 }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Or via env: `BGOS_BASE_URL` + `BGOS_PAIRING_TOKEN`.
|
|
51
|
+
|
|
52
|
+
## What's inside
|
|
53
|
+
|
|
54
|
+
- `BgosApi` — typed axios client with the X-BGOS-Pairing header
|
|
55
|
+
- `BgosWs` — Socket.IO client (pairingToken handshake, exponential-backoff reconnect, REST backfill on reconnect)
|
|
56
|
+
- `BgosOutbound` — sendText / sendButtons / sendApprovalRequest / sendAgentError
|
|
57
|
+
- `ApprovalHandler` — native-approval protocol using `__approval__:<decision>:<req_id>` callback_data
|
|
58
|
+
- `CommandsSync` — debounced manifest PUT per assistant
|
|
59
|
+
- `pairBgos(...)` — CLI entry for `openclaw pair bgos <CODE>`
|
|
60
|
+
- `bgosSetupWizard` — `defineSetupPluginEntry`-compatible setup object
|
|
61
|
+
- `createBgosChannel(cfg, options)` — composes all of the above; returns handles incl. a shutdown()
|
|
62
|
+
|
|
63
|
+
## End-to-end testing (manual — needs a real OpenClaw gateway)
|
|
64
|
+
|
|
65
|
+
See `docs/e2e-manual.md` for the human-run recipe (install, pair, tick an agent in BGOS, send a message, assert agent replies).
|
|
66
|
+
|
|
67
|
+
## BGOS agent capabilities
|
|
68
|
+
|
|
69
|
+
Agents reaching the BGOS app through this plugin should understand BGOS's full capability surface — markdown rendering, inline buttons, `ask_user_input`, approvals, files, and slash commands. The canonical reference lives at:
|
|
70
|
+
|
|
71
|
+
> `hermes-channel-bgos/docs/bgos-agent-capabilities.md`
|
|
72
|
+
|
|
73
|
+
Until OpenClaw ships a formal mechanism for surfacing this to agents at connect time (planned — see the canonical doc's per-plugin section), include a summary of relevant capabilities in your agent's system prompt.
|
|
74
|
+
|
|
75
|
+
**Recent additions (Phase 4, April 2026)** — inbound messages from BGOS now carry these read-only fields, surfaced in `inbound_message` WS payloads and via the REST backfill endpoint:
|
|
76
|
+
|
|
77
|
+
- `replyToId` (number | null) — when set, the user is replying to that earlier message; quote a 1-line preview of the replied-to message when relevant.
|
|
78
|
+
- `forwardedFromMessageId` (number | null) — when set, the user forwarded the content from another chat; treat as a quote, not the user's own words.
|
|
79
|
+
- `isPinned` (boolean) + `pinnedAt` (ISO string | null) — the user marked this important; weight pinned messages first when summarizing.
|
|
80
|
+
|
|
81
|
+
A new `message_pinned` WebSocket event (`{ message_id, chat_id, user_id, is_pinned, pinned_at }`) fires on `user:<userId>` rooms when the user pins or unpins. The plugin can use this to keep any local pin-state mirror fresh; agents themselves rarely need to subscribe.
|
|
82
|
+
|
|
83
|
+
Bookmarks are private to the user and not surfaced to agents.
|
|
84
|
+
|
|
85
|
+
## License
|
|
86
|
+
|
|
87
|
+
MIT © BrandGrowthOS
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BGOS system-prompt addendum for OpenClaw agents.
|
|
3
|
+
*
|
|
4
|
+
* This block is appended to every OpenClaw agent's system prompt when the
|
|
5
|
+
* agent is dispatched via the BGOS origin. Mirrors the gobot-channel-bgos
|
|
6
|
+
* and hermes-channel-bgos PLATFORM_HINTS content so agents speaking to
|
|
7
|
+
* BGOS through OpenClaw get the same capability surface.
|
|
8
|
+
*
|
|
9
|
+
* Source of truth for what BGOS exposes: `hermes-channel-bgos/docs/
|
|
10
|
+
* bgos-agent-capabilities.md`. When that doc changes, this string MUST
|
|
11
|
+
* change too — the `bgos-plugin-capability-sync` skill enforces this.
|
|
12
|
+
*
|
|
13
|
+
* Integration note: the OpenClaw host SHOULD call
|
|
14
|
+
* `buildSystemPromptWithHints(agentSystemPrompt)` in its dispatch handler
|
|
15
|
+
* before calling the LLM. See `bgos-plugin-capability-sync` and
|
|
16
|
+
* `bgos-agent-capabilities.md` §OpenClaw for the TBD hook location.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* The complete addendum, including its leading separator. Append to a
|
|
20
|
+
* system prompt verbatim.
|
|
21
|
+
*/
|
|
22
|
+
export declare const BGOS_AGENT_HINTS: string;
|
|
23
|
+
/**
|
|
24
|
+
* Append BGOS_AGENT_HINTS to a base system prompt.
|
|
25
|
+
*
|
|
26
|
+
* Idempotent — calling twice on the same input yields the same output.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildSystemPromptWithHints(originalPrompt: string): string;
|
|
29
|
+
//# sourceMappingURL=agent-hints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-hints.d.ts","sourceRoot":"","sources":["../src/agent-hints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA2IH;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAA0C,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAMzE"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BGOS system-prompt addendum for OpenClaw agents.
|
|
3
|
+
*
|
|
4
|
+
* This block is appended to every OpenClaw agent's system prompt when the
|
|
5
|
+
* agent is dispatched via the BGOS origin. Mirrors the gobot-channel-bgos
|
|
6
|
+
* and hermes-channel-bgos PLATFORM_HINTS content so agents speaking to
|
|
7
|
+
* BGOS through OpenClaw get the same capability surface.
|
|
8
|
+
*
|
|
9
|
+
* Source of truth for what BGOS exposes: `hermes-channel-bgos/docs/
|
|
10
|
+
* bgos-agent-capabilities.md`. When that doc changes, this string MUST
|
|
11
|
+
* change too — the `bgos-plugin-capability-sync` skill enforces this.
|
|
12
|
+
*
|
|
13
|
+
* Integration note: the OpenClaw host SHOULD call
|
|
14
|
+
* `buildSystemPromptWithHints(agentSystemPrompt)` in its dispatch handler
|
|
15
|
+
* before calling the LLM. See `bgos-plugin-capability-sync` and
|
|
16
|
+
* `bgos-agent-capabilities.md` §OpenClaw for the TBD hook location.
|
|
17
|
+
*/
|
|
18
|
+
const SEPARATOR = "\n\n---\n# BGOS Channel — Agent Capabilities\n\n";
|
|
19
|
+
const BGOS_AGENT_HINTS_BODY = [
|
|
20
|
+
"You are responding through the BGOS chat app. Replies render in a polished",
|
|
21
|
+
"mobile + desktop chat UI; the agent capabilities below are what BGOS",
|
|
22
|
+
"supports natively.",
|
|
23
|
+
"",
|
|
24
|
+
"## Markdown",
|
|
25
|
+
"Replies render as full markdown: **bold**, *italic*, `inline code`, fenced",
|
|
26
|
+
"code blocks, [links](url), `#`/`##`/`###` headers, bulleted + numbered",
|
|
27
|
+
"lists, `>` blockquotes. Tables don't render on mobile — use lists instead.",
|
|
28
|
+
"Inline image markdown (`![]()`) does NOT render — use the file send",
|
|
29
|
+
"primitives below instead.",
|
|
30
|
+
"",
|
|
31
|
+
"## Sending files / media (you → user)",
|
|
32
|
+
"Use one of the typed wrappers on `BgosOutbound`:",
|
|
33
|
+
" - sendImage({ filename, mimeType, bytes }) cap 10 MB; mime image/*",
|
|
34
|
+
" - sendVideo({ filename, mimeType, bytes }) cap 100 MB; mime video/*",
|
|
35
|
+
" - sendAudio({ filename, mimeType, bytes }) cap 25 MB; mime audio/*",
|
|
36
|
+
" - sendDocument({ filename, mimeType, bytes }) cap 25 MB; any mime",
|
|
37
|
+
"Or sendFile(...) for the low-level path. The plugin picks inline base64",
|
|
38
|
+
"(<500 KB) or presigned-PUT S3 (≥500 KB) automatically — you don't need",
|
|
39
|
+
"to think about it.",
|
|
40
|
+
"",
|
|
41
|
+
"## Inline option buttons (non-blocking)",
|
|
42
|
+
"Use BgosOutbound.sendButtons(). Offer 2–6 tappable chips without blocking.",
|
|
43
|
+
"Chips stay clickable indefinitely. Use for async nudges, check-ins,",
|
|
44
|
+
"anywhere the user is NOT actively waiting. Sentinels: `__skip__` (built-in",
|
|
45
|
+
"Skip chip) and `__custom__` (user typed free text; also arrives as a normal",
|
|
46
|
+
"message — correlate by message_id).",
|
|
47
|
+
"",
|
|
48
|
+
"## Approval bubbles (dangerous tools)",
|
|
49
|
+
"Use BgosOutbound.sendApprovalRequest(). Renders a 4-button bubble (Allow",
|
|
50
|
+
"once / Allow for session / Always allow / Deny). Callback arrives as",
|
|
51
|
+
"`callback_data` = `ea:<decision>:<reqId>` where decision ∈ {once, session,",
|
|
52
|
+
"always, deny}. Default 60 s fail-closed timeout (server-side).",
|
|
53
|
+
"",
|
|
54
|
+
"## ask_user_input — blocking pop-under",
|
|
55
|
+
"Use BgosOutbound.sendAskUserInput({ questions: [...] }). Pops a",
|
|
56
|
+
"sheet/modal over the chat and BLOCKS until the user answers. 1–4 questions",
|
|
57
|
+
"per carousel.",
|
|
58
|
+
"",
|
|
59
|
+
"Wire shape: the plugin POSTS ONE message row PER question, all sharing a",
|
|
60
|
+
"single askId (auto-generated unless you supply one). The frontend groups",
|
|
61
|
+
"rows by askId and renders them as one blocking sheet. The call returns",
|
|
62
|
+
"{ ids: number[], askId: string } — `ids` are the per-question message ids,",
|
|
63
|
+
"`askId` is the shared correlation id.",
|
|
64
|
+
"",
|
|
65
|
+
"Per-question fields:",
|
|
66
|
+
" - question (string) REQUIRED — shown above the answer area",
|
|
67
|
+
" - askOrder (number, optional) 1-based display order; defaults to array index+1",
|
|
68
|
+
" - options[] (optional) pre-defined chips ({ text, value }), max 6",
|
|
69
|
+
" - allowFreeText (optional) show a free-text composer beneath chips",
|
|
70
|
+
" - allowSkip (optional) allow skipping (sends `__skip__`)",
|
|
71
|
+
"",
|
|
72
|
+
"Use only when the user is actively in conversation. For async/proactive",
|
|
73
|
+
"nudges, use sendButtons instead.",
|
|
74
|
+
"",
|
|
75
|
+
"## Slash commands",
|
|
76
|
+
"Bridge-local — handled by the OpenClaw daemon, never reach the agent:",
|
|
77
|
+
" - /new drops conversation history for this chat (context reset)",
|
|
78
|
+
" - /retry re-dispatches the previous user turn to the agent",
|
|
79
|
+
" - /status daemon liveness probe (route, gateway health, latency)",
|
|
80
|
+
"Native agent commands arrive as regular text starting with `/` and are",
|
|
81
|
+
"forwarded to you. Register your command catalog via the integrations",
|
|
82
|
+
"commands endpoint so they show in the BGOS slash picker.",
|
|
83
|
+
"",
|
|
84
|
+
"## A2A — initiate a peer message (you → another BGOS assistant)",
|
|
85
|
+
"BGOS exposes the user's other assistants as PEERS (Ava, Mario, Hades, …).",
|
|
86
|
+
"OpenClaw's native sessions_send(label=...) does NOT find them — that",
|
|
87
|
+
"registry is in-process. Instead, call the daemon's local HTTP surface:",
|
|
88
|
+
"",
|
|
89
|
+
" GET http://127.0.0.1:31848/v1/peers?as=<your_agent_route>",
|
|
90
|
+
" → { peers: [ { assistantId, name, avatarUrl, color, introduced, expiresAt } ] }",
|
|
91
|
+
" Lists peers visible to your assistant (filtered by introductions).",
|
|
92
|
+
"",
|
|
93
|
+
" POST http://127.0.0.1:31848/v1/peers/send",
|
|
94
|
+
" body: {",
|
|
95
|
+
" \"as\": \"<your_agent_route>\", // REQUIRED",
|
|
96
|
+
" \"target\": \"Ava\" | <assistantId number>, // REQUIRED — name OR id",
|
|
97
|
+
" \"text\": \"<your message>\", // REQUIRED",
|
|
98
|
+
" \"parent_message_id\": <number>, // optional — auto-uses",
|
|
99
|
+
" // most recent inbound",
|
|
100
|
+
" \"wait_for_reply\": true, // optional — block ≤ 50s",
|
|
101
|
+
" \"timeout_seconds\": 45, // optional, 1–50",
|
|
102
|
+
" \"turn_state\": \"expecting_reply\"|\"more_coming\"|\"final\"",
|
|
103
|
+
" }",
|
|
104
|
+
" → { messageId, chatId, conversationId, reply? }",
|
|
105
|
+
"",
|
|
106
|
+
"Routing semantics:",
|
|
107
|
+
" - The peer assistant receives your message via THEIR channel adapter",
|
|
108
|
+
" (n8n webhook for Ava, Hermes for hermes-routed agents, etc.).",
|
|
109
|
+
" - The user sees a SideConversationCard in the originating chat,",
|
|
110
|
+
" anchored to parent_message_id. Don't omit parent_message_id unless",
|
|
111
|
+
" the daemon can auto-resolve from a recent inbound — the call errors",
|
|
112
|
+
" cleanly with `no_parent_message` otherwise.",
|
|
113
|
+
" - Call port is configurable via --peers-port / BGOS_PEERS_PORT (default 31848).",
|
|
114
|
+
"",
|
|
115
|
+
"Quick example (Hades reaches out to Ava):",
|
|
116
|
+
" POST /v1/peers/send",
|
|
117
|
+
" { \"as\": \"hades\", \"target\": \"Ava\", \"text\": \"Heads up — task X is done.\" }",
|
|
118
|
+
"",
|
|
119
|
+
"## SHARED-ASSISTANT CONTEXT",
|
|
120
|
+
"This assistant may be shared with other users. Every inbound message includes:",
|
|
121
|
+
" - userId : the user who sent THIS message (always trust this for isolation)",
|
|
122
|
+
" - isSharedRecipient : true if the message is from a share recipient (not the owner)",
|
|
123
|
+
" - shareOwnerUserId : the original assistant creator's id, present on shared messages",
|
|
124
|
+
"",
|
|
125
|
+
"When isSharedRecipient is true, the daemon also injects a system message",
|
|
126
|
+
"naming the userId + shareOwnerUserId right before your turn. Treat it as",
|
|
127
|
+
"authoritative scoping. If you store data per-user (memory, files,",
|
|
128
|
+
"preferences), key it by `userId` so recipients are isolated from the owner",
|
|
129
|
+
"and from each other.",
|
|
130
|
+
"",
|
|
131
|
+
"## Message actions — reply / forward / pin / bookmark",
|
|
132
|
+
"Inbound messages and prior-turn history may carry read-only fields:",
|
|
133
|
+
" - replyToId (number | null) — user is replying to an earlier message.",
|
|
134
|
+
" Surfaces in history as the marker `[reply→#<id>]` prepended to the turn.",
|
|
135
|
+
" - forwardedFromMessageId (number | null) — treat content as a quote.",
|
|
136
|
+
" Surfaces as `[forwarded from #<id>]`.",
|
|
137
|
+
" - isPinned (boolean) + pinnedAt (ISO string | null) — weight pinned",
|
|
138
|
+
" messages heavily when summarizing. Surfaces as `[pinned]`.",
|
|
139
|
+
" - fromAgent ({ assistantId, userId, name } | null) — the inbound was",
|
|
140
|
+
" authored by another agent (a2a). Treat it like a peer, not a user.",
|
|
141
|
+
"These are user gestures — DO NOT auto-pin, auto-bookmark, or forward",
|
|
142
|
+
"without explicit consent.",
|
|
143
|
+
"",
|
|
144
|
+
"## Agent-to-agent (a2a) outbound",
|
|
145
|
+
"When you reply on behalf of another agent (peer) or want the recipient to",
|
|
146
|
+
"see the message as coming from a peer agent rather than yourself, pass",
|
|
147
|
+
"`fromAgent: { assistantId, userId, name }` to sendText/sendButtons/",
|
|
148
|
+
"sendImage/etc. The replyToId field correlates side-thread replies — set",
|
|
149
|
+
"it to the inbound peer message id when answering an a2a side thread so",
|
|
150
|
+
"the originator's poll matches precisely.",
|
|
151
|
+
].join("\n");
|
|
152
|
+
/**
|
|
153
|
+
* The complete addendum, including its leading separator. Append to a
|
|
154
|
+
* system prompt verbatim.
|
|
155
|
+
*/
|
|
156
|
+
export const BGOS_AGENT_HINTS = SEPARATOR + BGOS_AGENT_HINTS_BODY;
|
|
157
|
+
/**
|
|
158
|
+
* Append BGOS_AGENT_HINTS to a base system prompt.
|
|
159
|
+
*
|
|
160
|
+
* Idempotent — calling twice on the same input yields the same output.
|
|
161
|
+
*/
|
|
162
|
+
export function buildSystemPromptWithHints(originalPrompt) {
|
|
163
|
+
const base = originalPrompt ?? "";
|
|
164
|
+
if (base.includes("BGOS Channel — Agent Capabilities")) {
|
|
165
|
+
return base;
|
|
166
|
+
}
|
|
167
|
+
return base + BGOS_AGENT_HINTS;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=agent-hints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-hints.js","sourceRoot":"","sources":["../src/agent-hints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,SAAS,GACb,kDAAkD,CAAC;AAErD,MAAM,qBAAqB,GAAG;IAC5B,4EAA4E;IAC5E,sEAAsE;IACtE,oBAAoB;IACpB,EAAE;IACF,aAAa;IACb,4EAA4E;IAC5E,wEAAwE;IACxE,4EAA4E;IAC5E,qEAAqE;IACrE,2BAA2B;IAC3B,EAAE;IACF,uCAAuC;IACvC,kDAAkD;IAClD,yEAAyE;IACzE,0EAA0E;IAC1E,yEAAyE;IACzE,qEAAqE;IACrE,yEAAyE;IACzE,wEAAwE;IACxE,oBAAoB;IACpB,EAAE;IACF,yCAAyC;IACzC,4EAA4E;IAC5E,qEAAqE;IACrE,4EAA4E;IAC5E,6EAA6E;IAC7E,qCAAqC;IACrC,EAAE;IACF,uCAAuC;IACvC,0EAA0E;IAC1E,sEAAsE;IACtE,4EAA4E;IAC5E,gEAAgE;IAChE,EAAE;IACF,wCAAwC;IACxC,iEAAiE;IACjE,4EAA4E;IAC5E,eAAe;IACf,EAAE;IACF,0EAA0E;IAC1E,0EAA0E;IAC1E,wEAAwE;IACxE,4EAA4E;IAC5E,uCAAuC;IACvC,EAAE;IACF,sBAAsB;IACtB,uEAAuE;IACvE,kFAAkF;IAClF,2EAA2E;IAC3E,wEAAwE;IACxE,kEAAkE;IAClE,EAAE;IACF,yEAAyE;IACzE,kCAAkC;IAClC,EAAE;IACF,mBAAmB;IACnB,uEAAuE;IACvE,yEAAyE;IACzE,kEAAkE;IAClE,uEAAuE;IACvE,wEAAwE;IACxE,sEAAsE;IACtE,0DAA0D;IAC1D,EAAE;IACF,iEAAiE;IACjE,2EAA2E;IAC3E,sEAAsE;IACtE,wEAAwE;IACxE,EAAE;IACF,6DAA6D;IAC7D,qFAAqF;IACrF,wEAAwE;IACxE,EAAE;IACF,6CAA6C;IAC7C,aAAa;IACb,kEAAkE;IAClE,gFAAgF;IAChF,oEAAoE;IACpE,8EAA8E;IAC9E,6EAA6E;IAC7E,+EAA+E;IAC/E,wEAAwE;IACxE,qEAAqE;IACrE,OAAO;IACP,qDAAqD;IACrD,EAAE;IACF,oBAAoB;IACpB,wEAAwE;IACxE,mEAAmE;IACnE,mEAAmE;IACnE,wEAAwE;IACxE,yEAAyE;IACzE,iDAAiD;IACjD,mFAAmF;IACnF,EAAE;IACF,2CAA2C;IAC3C,uBAAuB;IACvB,wFAAwF;IACxF,EAAE;IACF,6BAA6B;IAC7B,gFAAgF;IAChF,0FAA0F;IAC1F,uFAAuF;IACvF,yFAAyF;IACzF,EAAE;IACF,0EAA0E;IAC1E,0EAA0E;IAC1E,mEAAmE;IACnE,4EAA4E;IAC5E,sBAAsB;IACtB,EAAE;IACF,uDAAuD;IACvD,qEAAqE;IACrE,yEAAyE;IACzE,8EAA8E;IAC9E,wEAAwE;IACxE,2CAA2C;IAC3C,uEAAuE;IACvE,gEAAgE;IAChE,wEAAwE;IACxE,wEAAwE;IACxE,sEAAsE;IACtE,2BAA2B;IAC3B,EAAE;IACF,kCAAkC;IAClC,2EAA2E;IAC3E,wEAAwE;IACxE,qEAAqE;IACrE,yEAAyE;IACzE,wEAAwE;IACxE,0CAA0C;CAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAW,SAAS,GAAG,qBAAqB,CAAC;AAE1E;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CAAC,cAAsB;IAC/D,MAAM,IAAI,GAAG,cAAc,IAAI,EAAE,CAAC;IAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,mCAAmC,CAAC,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,GAAG,gBAAgB,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { BgosOutbound } from "./outbound.js";
|
|
2
|
+
import type { ApprovalMeta, CallbackResultPayload } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Approval request / response bridge.
|
|
5
|
+
*
|
|
6
|
+
* When an OpenClaw agent requests consent (native approval flow), call
|
|
7
|
+
* requestApproval(...). It POSTs an approval_request message to BGOS and
|
|
8
|
+
* returns a promise that resolves when the user clicks one of the four
|
|
9
|
+
* tier buttons (Allow once / Allow for session / Always allow / Deny)
|
|
10
|
+
* via the corresponding callback_result WS event.
|
|
11
|
+
*
|
|
12
|
+
* Correlation happens via ApprovalMeta.request_id, which we embed into
|
|
13
|
+
* each option's callback_data as `ea:<decision>:<req_id>`.
|
|
14
|
+
* handleCallbackResult(...) is the wiring hook for the WS listener and
|
|
15
|
+
* accepts BOTH the spec'd `ea:` prefix AND the legacy `__approval__:`
|
|
16
|
+
* prefix for one release of backwards compatibility (drop the legacy
|
|
17
|
+
* branch in plugin v0.7.0 once Kc's prod daemon is on v0.5.0+).
|
|
18
|
+
*/
|
|
19
|
+
export type ApprovalDecision = "once" | "session" | "always" | "deny";
|
|
20
|
+
/**
|
|
21
|
+
* Parse an approval callback into `{ decision, requestId }`. Accepts
|
|
22
|
+
* both `ea:` (spec) and `__approval__:` (legacy) prefixes; aliases
|
|
23
|
+
* legacy `approve` to the spec'd `once`. Returns null when the payload
|
|
24
|
+
* is not an approval callback (regular button clicks pass through).
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseApprovalCallback(cb: string | undefined): {
|
|
27
|
+
decision: ApprovalDecision;
|
|
28
|
+
requestId: string;
|
|
29
|
+
} | null;
|
|
30
|
+
export interface PendingApproval {
|
|
31
|
+
requestId: string;
|
|
32
|
+
resolve: (decision: ApprovalDecision) => void;
|
|
33
|
+
reject: (err: Error) => void;
|
|
34
|
+
timeout: NodeJS.Timeout;
|
|
35
|
+
}
|
|
36
|
+
export declare class ApprovalHandler {
|
|
37
|
+
private readonly outbound;
|
|
38
|
+
private readonly pending;
|
|
39
|
+
constructor(outbound: BgosOutbound);
|
|
40
|
+
/**
|
|
41
|
+
* Post an approval_request and wait for Approve/Deny.
|
|
42
|
+
* Resolves with the decision or rejects after `timeoutMs` (default 30 min).
|
|
43
|
+
*/
|
|
44
|
+
requestApproval(params: {
|
|
45
|
+
assistantId: number;
|
|
46
|
+
chatId: number;
|
|
47
|
+
text: string;
|
|
48
|
+
meta: ApprovalMeta;
|
|
49
|
+
timeoutMs?: number;
|
|
50
|
+
}): Promise<ApprovalDecision>;
|
|
51
|
+
/**
|
|
52
|
+
* Wire this into BgosWs.on("callback_result", ...). Decodes the
|
|
53
|
+
* approval prefix from the option's callback_data and resolves the
|
|
54
|
+
* matching pending approval, if any.
|
|
55
|
+
*
|
|
56
|
+
* Accepts:
|
|
57
|
+
* - `ea:<choice>:<reqId>` (spec, since plugin v0.5.0)
|
|
58
|
+
* - `__approval__:<choice>:<reqId>` (legacy 2-button, kept for one
|
|
59
|
+
* release so daemons in flight don't break — drop in v0.7.0)
|
|
60
|
+
*
|
|
61
|
+
* Returns true if the payload matched a pending approval, false
|
|
62
|
+
* otherwise (regular button click — caller should route it to the
|
|
63
|
+
* agent's interaction handler).
|
|
64
|
+
*/
|
|
65
|
+
handleCallbackResult(payload: CallbackResultPayload & {
|
|
66
|
+
callbackData?: string;
|
|
67
|
+
}): boolean;
|
|
68
|
+
/** Graceful teardown — rejects all pending. */
|
|
69
|
+
shutdown(): void;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=approval-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-handler.d.ts","sourceRoot":"","sources":["../src/approval-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EACV,YAAY,EACZ,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;AAgBtE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,MAAM,GAAG,SAAS,GACrB;IAAE,QAAQ,EAAE,gBAAgB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqB1D;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC9C,MAAM,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC;CACzB;AAED,qBAAa,eAAe;IAGd,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsC;gBAEjC,QAAQ,EAAE,YAAY;IAEnD;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,YAAY,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA+B7B;;;;;;;;;;;;;OAaG;IACH,oBAAoB,CAClB,OAAO,EAAE,qBAAqB,GAAG;QAAE,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GACzD,OAAO;IAWV,+CAA+C;IAC/C,QAAQ,IAAI,IAAI;CAOjB"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const APPROVAL_DECISIONS = new Set([
|
|
2
|
+
"once",
|
|
3
|
+
"session",
|
|
4
|
+
"always",
|
|
5
|
+
"deny",
|
|
6
|
+
]);
|
|
7
|
+
/** Legacy 2-button decisions (plugin v0.4.x and earlier). Translated
|
|
8
|
+
* to the new 4-tier vocabulary so callers see one consistent enum. */
|
|
9
|
+
const LEGACY_DECISION_ALIASES = {
|
|
10
|
+
approve: "once",
|
|
11
|
+
deny: "deny",
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Parse an approval callback into `{ decision, requestId }`. Accepts
|
|
15
|
+
* both `ea:` (spec) and `__approval__:` (legacy) prefixes; aliases
|
|
16
|
+
* legacy `approve` to the spec'd `once`. Returns null when the payload
|
|
17
|
+
* is not an approval callback (regular button clicks pass through).
|
|
18
|
+
*/
|
|
19
|
+
export function parseApprovalCallback(cb) {
|
|
20
|
+
if (!cb)
|
|
21
|
+
return null;
|
|
22
|
+
let rest;
|
|
23
|
+
if (cb.startsWith("ea:")) {
|
|
24
|
+
rest = cb.slice("ea:".length);
|
|
25
|
+
}
|
|
26
|
+
else if (cb.startsWith("__approval__:")) {
|
|
27
|
+
rest = cb.slice("__approval__:".length);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const colon = rest.indexOf(":");
|
|
33
|
+
if (colon < 0)
|
|
34
|
+
return null;
|
|
35
|
+
const rawDecision = rest.slice(0, colon);
|
|
36
|
+
const requestId = rest.slice(colon + 1);
|
|
37
|
+
if (!requestId)
|
|
38
|
+
return null;
|
|
39
|
+
const decision = (APPROVAL_DECISIONS.has(rawDecision)
|
|
40
|
+
? rawDecision
|
|
41
|
+
: LEGACY_DECISION_ALIASES[rawDecision]) ?? null;
|
|
42
|
+
if (!decision)
|
|
43
|
+
return null;
|
|
44
|
+
return { decision, requestId };
|
|
45
|
+
}
|
|
46
|
+
export class ApprovalHandler {
|
|
47
|
+
outbound;
|
|
48
|
+
pending = new Map();
|
|
49
|
+
constructor(outbound) {
|
|
50
|
+
this.outbound = outbound;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Post an approval_request and wait for Approve/Deny.
|
|
54
|
+
* Resolves with the decision or rejects after `timeoutMs` (default 30 min).
|
|
55
|
+
*/
|
|
56
|
+
requestApproval(params) {
|
|
57
|
+
// Register the pending entry SYNCHRONOUSLY so a callback that arrives
|
|
58
|
+
// before the POST resolves still matches. POST is fired in parallel;
|
|
59
|
+
// if it fails we reject the pending promise.
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
const ms = params.timeoutMs ?? 30 * 60 * 1000;
|
|
62
|
+
const timeout = setTimeout(() => {
|
|
63
|
+
this.pending.delete(params.meta.request_id);
|
|
64
|
+
reject(new Error("approval timeout"));
|
|
65
|
+
}, ms);
|
|
66
|
+
this.pending.set(params.meta.request_id, {
|
|
67
|
+
requestId: params.meta.request_id,
|
|
68
|
+
resolve,
|
|
69
|
+
reject,
|
|
70
|
+
timeout,
|
|
71
|
+
});
|
|
72
|
+
this.outbound
|
|
73
|
+
.sendApprovalRequest({
|
|
74
|
+
assistantId: params.assistantId,
|
|
75
|
+
chatId: params.chatId,
|
|
76
|
+
text: params.text,
|
|
77
|
+
meta: params.meta,
|
|
78
|
+
})
|
|
79
|
+
.catch((err) => {
|
|
80
|
+
clearTimeout(timeout);
|
|
81
|
+
this.pending.delete(params.meta.request_id);
|
|
82
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Wire this into BgosWs.on("callback_result", ...). Decodes the
|
|
88
|
+
* approval prefix from the option's callback_data and resolves the
|
|
89
|
+
* matching pending approval, if any.
|
|
90
|
+
*
|
|
91
|
+
* Accepts:
|
|
92
|
+
* - `ea:<choice>:<reqId>` (spec, since plugin v0.5.0)
|
|
93
|
+
* - `__approval__:<choice>:<reqId>` (legacy 2-button, kept for one
|
|
94
|
+
* release so daemons in flight don't break — drop in v0.7.0)
|
|
95
|
+
*
|
|
96
|
+
* Returns true if the payload matched a pending approval, false
|
|
97
|
+
* otherwise (regular button click — caller should route it to the
|
|
98
|
+
* agent's interaction handler).
|
|
99
|
+
*/
|
|
100
|
+
handleCallbackResult(payload) {
|
|
101
|
+
const parsed = parseApprovalCallback(payload.callbackData);
|
|
102
|
+
if (!parsed)
|
|
103
|
+
return false;
|
|
104
|
+
const entry = this.pending.get(parsed.requestId);
|
|
105
|
+
if (!entry)
|
|
106
|
+
return false;
|
|
107
|
+
clearTimeout(entry.timeout);
|
|
108
|
+
this.pending.delete(parsed.requestId);
|
|
109
|
+
entry.resolve(parsed.decision);
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
/** Graceful teardown — rejects all pending. */
|
|
113
|
+
shutdown() {
|
|
114
|
+
for (const [, entry] of this.pending) {
|
|
115
|
+
clearTimeout(entry.timeout);
|
|
116
|
+
entry.reject(new Error("plugin shutting down"));
|
|
117
|
+
}
|
|
118
|
+
this.pending.clear();
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=approval-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-handler.js","sourceRoot":"","sources":["../src/approval-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { type AgentCatalogEntry, type BgosMessageEnvelope, type CommandManifestEntry, type InboundMessagePayload, type IntegrationPairing, type OutboundMessagePayload, type PairExchangeResponse, type PluginConfig } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Thin typed wrapper around the BGOS integration endpoints. All methods
|
|
4
|
+
* attach the X-BGOS-Pairing header from cfg.pairingToken.
|
|
5
|
+
*
|
|
6
|
+
* A 401 from any request is mapped to PairingRevokedError so callers
|
|
7
|
+
* (WS client, outbound adapter) can short-circuit and let the setup
|
|
8
|
+
* wizard prompt for re-pair.
|
|
9
|
+
*/
|
|
10
|
+
export declare class BgosApi {
|
|
11
|
+
private readonly http;
|
|
12
|
+
constructor(cfg: PluginConfig);
|
|
13
|
+
/** GET /integrations/me — confirms token + touches last_seen_at.
|
|
14
|
+
* Includes assistant→agent_route bindings so the plugin can seed
|
|
15
|
+
* its dispatch map on cold start.
|
|
16
|
+
*/
|
|
17
|
+
whoami(): Promise<{
|
|
18
|
+
pairing_id: number;
|
|
19
|
+
user_id: string;
|
|
20
|
+
device_label: string;
|
|
21
|
+
integration: string;
|
|
22
|
+
assistants?: Array<{
|
|
23
|
+
assistant_id: number;
|
|
24
|
+
agent_route: string | null;
|
|
25
|
+
name: string;
|
|
26
|
+
/** Count of slash-commands currently set; lets callers decide
|
|
27
|
+
* whether to seed defaults without a second round-trip. */
|
|
28
|
+
command_count?: number;
|
|
29
|
+
}>;
|
|
30
|
+
}>;
|
|
31
|
+
/** Pair exchange (Public; does NOT need X-BGOS-Pairing). */
|
|
32
|
+
static pairExchange(baseUrl: string, params: {
|
|
33
|
+
code: string;
|
|
34
|
+
deviceLabel: string;
|
|
35
|
+
agentCatalog?: AgentCatalogEntry[];
|
|
36
|
+
}): Promise<PairExchangeResponse>;
|
|
37
|
+
/** Plugin pushes (or updates) the agent catalog for this pairing. */
|
|
38
|
+
pushAgentCatalog(pairingId: number, agents: AgentCatalogEntry[]): Promise<void>;
|
|
39
|
+
/** Plugin replaces the slash-command manifest for a single bound assistant. */
|
|
40
|
+
putCommands(assistantId: number, commands: CommandManifestEntry[]): Promise<void>;
|
|
41
|
+
/** REST backfill after a WS reconnect. */
|
|
42
|
+
inboundSince(sinceMessageId: number): Promise<{
|
|
43
|
+
messages: InboundMessagePayload[];
|
|
44
|
+
}>;
|
|
45
|
+
/** Fetch the recent message history for a chat — used by the daemon to
|
|
46
|
+
* rebuild conversation context before dispatching to a stateless
|
|
47
|
+
* gateway. Backend returns up to 100 entries ASC by created_at. */
|
|
48
|
+
getMessages(chatId: number, userId: string): Promise<BgosMessageEnvelope[]>;
|
|
49
|
+
/** Agent reply — assistant message with optional inline buttons/approval. */
|
|
50
|
+
postMessage(payload: OutboundMessagePayload): Promise<{
|
|
51
|
+
id: number;
|
|
52
|
+
}>;
|
|
53
|
+
/** Request a presigned PUT for a file ≥500 KB that the agent wants to send. */
|
|
54
|
+
createUploadUrl(params: {
|
|
55
|
+
filename: string;
|
|
56
|
+
mimeType: string;
|
|
57
|
+
size: number;
|
|
58
|
+
}): Promise<{
|
|
59
|
+
upload_url: string;
|
|
60
|
+
s3_key: string;
|
|
61
|
+
expires_at: string;
|
|
62
|
+
}>;
|
|
63
|
+
/** List this pairing's active/paired state. Mostly used in setup wizard. */
|
|
64
|
+
listPairings(): Promise<IntegrationPairing[]>;
|
|
65
|
+
/**
|
|
66
|
+
* A2A peer discovery for an OpenClaw agent. Returns the user's other
|
|
67
|
+
* assistants the caller is allowed to reach (filtered by the
|
|
68
|
+
* agent_introductions table). The caller's assistant id is sent via
|
|
69
|
+
* X-Caller-Assistant-Id; backend uses it to scope visibility +
|
|
70
|
+
* enforce per-pair introduction rules.
|
|
71
|
+
*
|
|
72
|
+
* Used by the daemon's peers HTTP server (peers_list) so OpenClaw
|
|
73
|
+
* agents can discover Ava/Mario/etc. by name before initiating a
|
|
74
|
+
* peer message via sendToPeer().
|
|
75
|
+
*/
|
|
76
|
+
listPeers(callerAssistantId: number): Promise<Array<{
|
|
77
|
+
assistantId: number;
|
|
78
|
+
name: string;
|
|
79
|
+
avatarUrl: string | null;
|
|
80
|
+
color: string | null;
|
|
81
|
+
introduced: boolean;
|
|
82
|
+
expiresAt: string | null;
|
|
83
|
+
}>>;
|
|
84
|
+
/**
|
|
85
|
+
* Initiate (or continue) a peer side-thread from this OpenClaw agent
|
|
86
|
+
* to another BGOS assistant. Backend creates/reuses the a2a chat,
|
|
87
|
+
* persists the message, and emits inbound_message to the target's
|
|
88
|
+
* channel adapter with peerConversationId + turnState set.
|
|
89
|
+
*
|
|
90
|
+
* @param parentMessageId Required by the backend: anchors the
|
|
91
|
+
* SideConversationCard in the originating chat. Daemon picks the
|
|
92
|
+
* most-recent inbound for this caller's assistant when the agent
|
|
93
|
+
* doesn't supply one (see peers-server.ts).
|
|
94
|
+
*/
|
|
95
|
+
sendToPeer(callerAssistantId: number, targetAssistantId: number, params: {
|
|
96
|
+
text: string;
|
|
97
|
+
parentMessageId: number;
|
|
98
|
+
waitForReply?: boolean;
|
|
99
|
+
timeoutSeconds?: number;
|
|
100
|
+
turnState?: "expecting_reply" | "more_coming" | "final";
|
|
101
|
+
}): Promise<{
|
|
102
|
+
messageId: number;
|
|
103
|
+
chatId: number;
|
|
104
|
+
conversationId: number;
|
|
105
|
+
reply?: {
|
|
106
|
+
text: string;
|
|
107
|
+
messageId: number;
|
|
108
|
+
};
|
|
109
|
+
}>;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=bgos-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bgos-api.d.ts","sourceRoot":"","sources":["../src/bgos-api.ts"],"names":[],"mappings":"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"}
|