@mutirolabs/openclaw-brain 0.2.0 → 0.2.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/CHANGELOG.md +20 -1
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/src/actions.js +40 -0
- package/dist/src/actions.js.map +1 -0
- package/dist/src/agent-tools.js +547 -0
- package/dist/src/agent-tools.js.map +1 -0
- package/dist/src/bridge-client.js +172 -0
- package/dist/src/bridge-client.js.map +1 -0
- package/dist/src/bridge-messages.js +226 -0
- package/dist/src/bridge-messages.js.map +1 -0
- package/dist/src/bridge-protocol.js +42 -0
- package/dist/src/bridge-protocol.js.map +1 -0
- package/dist/src/bridge-session.js +279 -0
- package/dist/src/bridge-session.js.map +1 -0
- package/dist/src/channel.js +167 -0
- package/dist/src/channel.js.map +1 -0
- package/dist/src/channel.runtime.js +422 -0
- package/dist/src/channel.runtime.js.map +1 -0
- package/dist/src/config.js +61 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/inbound.js +92 -0
- package/dist/src/inbound.js.map +1 -0
- package/dist/src/live-snapshot.js +151 -0
- package/dist/src/live-snapshot.js.map +1 -0
- package/dist/src/outbound.js +205 -0
- package/dist/src/outbound.js.map +1 -0
- package/dist/src/setup-surface.js +252 -0
- package/dist/src/setup-surface.js.map +1 -0
- package/dist/src/signal-forwarder.js +119 -0
- package/dist/src/signal-forwarder.js.map +1 -0
- package/package.json +5 -2
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// Bridges OpenClaw's mid-turn reply-dispatch hooks into Mutiro's
|
|
2
|
+
// signal.emit envelopes so the user sees a live "typing / searching /
|
|
3
|
+
// remembering" indicator while the agent works. Fire-and-forget: signals
|
|
4
|
+
// are transient UI chrome, not messages. No correlation required.
|
|
5
|
+
//
|
|
6
|
+
// Maps OpenClaw callbacks (from GetReplyOptions) to Mutiro's signal
|
|
7
|
+
// vocabulary (SIGNAL_TYPE_* in spec/protobuf/shared/signal.proto).
|
|
8
|
+
const REASONING_DEBOUNCE_MS = 500;
|
|
9
|
+
const TOOL_DETAIL_MAX_CHARS = 120;
|
|
10
|
+
const TOOL_SIGNAL_MAP = {
|
|
11
|
+
// Web
|
|
12
|
+
web_search: { signal: "SIGNAL_TYPE_WEB_SEARCHING", intent: "Searching web" },
|
|
13
|
+
web_fetch: { signal: "SIGNAL_TYPE_WEB_FETCHING", intent: "Fetching" },
|
|
14
|
+
fetch: { signal: "SIGNAL_TYPE_WEB_FETCHING", intent: "Fetching" },
|
|
15
|
+
// Memory / recall
|
|
16
|
+
recall: { signal: "SIGNAL_TYPE_RECALLING", intent: "Recalling" },
|
|
17
|
+
memory_search: { signal: "SIGNAL_TYPE_RECALLING", intent: "Searching memory" },
|
|
18
|
+
memory: { signal: "SIGNAL_TYPE_READING_MEMORY", intent: "Reading memory" },
|
|
19
|
+
memory_remember: { signal: "SIGNAL_TYPE_WRITING_MEMORY", intent: "Saving memory" },
|
|
20
|
+
memory_write: { signal: "SIGNAL_TYPE_WRITING_MEMORY", intent: "Saving memory" },
|
|
21
|
+
// Media
|
|
22
|
+
image_generate: { signal: "SIGNAL_TYPE_CREATING_IMAGE", intent: "Creating image" },
|
|
23
|
+
image: { signal: "SIGNAL_TYPE_CREATING_IMAGE", intent: "Working with image" },
|
|
24
|
+
// Scheduling / planning
|
|
25
|
+
cron: { signal: "SIGNAL_TYPE_SCHEDULING", intent: "Scheduling" },
|
|
26
|
+
update_plan: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Updating plan" },
|
|
27
|
+
// Mutiro-native channel tools
|
|
28
|
+
mutiro_send_voice_message: { signal: "SIGNAL_TYPE_SENDING_VOICE", intent: "Sending voice" },
|
|
29
|
+
mutiro_send_card: { signal: "SIGNAL_TYPE_ATTACHING_FILE", intent: "Preparing card" },
|
|
30
|
+
mutiro_forward_message: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Forwarding message" },
|
|
31
|
+
// File operations (coding profile). Mutiro has no dedicated SIGNAL_TYPE_*
|
|
32
|
+
// for file I/O; use CUSTOM + readable intent so the user still sees the
|
|
33
|
+
// action. Phase (e.g. the path being touched) is appended when present.
|
|
34
|
+
read: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Reading file" },
|
|
35
|
+
write: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Writing file" },
|
|
36
|
+
edit: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Editing file" },
|
|
37
|
+
apply_patch: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Applying patch" },
|
|
38
|
+
// Shell / process
|
|
39
|
+
exec: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Running command" },
|
|
40
|
+
bash: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Running command" },
|
|
41
|
+
process: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Managing process" },
|
|
42
|
+
// UI surfaces
|
|
43
|
+
canvas: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Updating canvas" },
|
|
44
|
+
browser: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Browsing" },
|
|
45
|
+
// Sessions / control plane
|
|
46
|
+
sessions_list: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Listing sessions" },
|
|
47
|
+
sessions_history: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Reading history" },
|
|
48
|
+
sessions_send: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Sending to session" },
|
|
49
|
+
session_status: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Checking status" },
|
|
50
|
+
message: { signal: "SIGNAL_TYPE_CUSTOM", intent: "Messaging" },
|
|
51
|
+
};
|
|
52
|
+
const truncateDetail = (raw) => {
|
|
53
|
+
const collapsed = raw.replace(/\s+/g, " ").trim();
|
|
54
|
+
if (collapsed.length <= TOOL_DETAIL_MAX_CHARS)
|
|
55
|
+
return collapsed;
|
|
56
|
+
return `${collapsed.slice(0, TOOL_DETAIL_MAX_CHARS - 1).trimEnd()}…`;
|
|
57
|
+
};
|
|
58
|
+
export const createSignalForwarder = (session, target) => {
|
|
59
|
+
let lastReasoningAt = 0;
|
|
60
|
+
const emit = (signalType, detail) => {
|
|
61
|
+
session.outbound.emitSignal(target, signalType, detail ?? "");
|
|
62
|
+
};
|
|
63
|
+
return {
|
|
64
|
+
thinking: () => emit("SIGNAL_TYPE_THINKING", "Processing…"),
|
|
65
|
+
typing: () => emit("SIGNAL_TYPE_TYPING", "Writing response…"),
|
|
66
|
+
reasoning: () => {
|
|
67
|
+
// onReasoningStream fires per-token; throttle so we ship at most one
|
|
68
|
+
// REASONING pulse every REASONING_DEBOUNCE_MS to avoid spamming the
|
|
69
|
+
// host + Mutiro clients.
|
|
70
|
+
const now = Date.now();
|
|
71
|
+
if (now - lastReasoningAt < REASONING_DEBOUNCE_MS)
|
|
72
|
+
return;
|
|
73
|
+
lastReasoningAt = now;
|
|
74
|
+
emit("SIGNAL_TYPE_REASONING", "Thinking…");
|
|
75
|
+
},
|
|
76
|
+
toolStart: (name, _phase) => {
|
|
77
|
+
const trimmedName = (name ?? "").trim();
|
|
78
|
+
if (!trimmedName) {
|
|
79
|
+
emit("SIGNAL_TYPE_TOOL_RUNNING");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// `onToolStart.phase` is a lifecycle marker ("start"/"update"/"end"),
|
|
83
|
+
// not semantic payload — ignore it. Tools with args (read, write,
|
|
84
|
+
// exec, etc.) fire a follow-up `onItemEvent` whose `title` carries
|
|
85
|
+
// the real detail (e.g. "read src/x.ts"); itemEvent() refines the
|
|
86
|
+
// pill to that value. For tools that never emit an item event, the
|
|
87
|
+
// intent label alone is still meaningful.
|
|
88
|
+
const spec = TOOL_SIGNAL_MAP[trimmedName];
|
|
89
|
+
const intent = spec?.intent ?? trimmedName;
|
|
90
|
+
emit(spec?.signal ?? "SIGNAL_TYPE_CUSTOM", truncateDetail(intent));
|
|
91
|
+
},
|
|
92
|
+
itemStart: (params) => {
|
|
93
|
+
// Higher-fidelity source than toolStart: title resolves tool args
|
|
94
|
+
// into a display ("read src/x.ts", "exec pytest -k foo", etc.) via
|
|
95
|
+
// OpenClaw's inferToolMetaFromArgs. When we have both the tool
|
|
96
|
+
// signal type AND the rich title, emit with the specific signal
|
|
97
|
+
// type so the UI still shows the right pill style.
|
|
98
|
+
const name = (params.name ?? "").trim();
|
|
99
|
+
const title = (params.title ?? "").trim();
|
|
100
|
+
if (!name && !title)
|
|
101
|
+
return;
|
|
102
|
+
const spec = name ? TOOL_SIGNAL_MAP[name] : undefined;
|
|
103
|
+
const detail = truncateDetail(title || spec?.intent || name);
|
|
104
|
+
emit(spec?.signal ?? "SIGNAL_TYPE_CUSTOM", detail);
|
|
105
|
+
},
|
|
106
|
+
compactionStart: () => emit("SIGNAL_TYPE_REMEMBERING", "Organizing context…"),
|
|
107
|
+
compactionEnd: () => {
|
|
108
|
+
// No explicit clear — the next signal (or TURN_COMPLETE) replaces the
|
|
109
|
+
// visible pill on Mutiro clients.
|
|
110
|
+
},
|
|
111
|
+
planUpdate: (title) => {
|
|
112
|
+
const detail = (title ?? "").trim();
|
|
113
|
+
emit("SIGNAL_TYPE_CUSTOM", detail ? `Planning: ${truncateDetail(detail)}` : "Planning…");
|
|
114
|
+
},
|
|
115
|
+
custom: (detail) => emit("SIGNAL_TYPE_CUSTOM", truncateDetail(detail)),
|
|
116
|
+
turnComplete: () => emit("SIGNAL_TYPE_TURN_COMPLETE"),
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=signal-forwarder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal-forwarder.js","sourceRoot":"","sources":["../../src/signal-forwarder.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,sEAAsE;AACtE,yEAAyE;AACzE,kEAAkE;AAClE,EAAE;AACF,oEAAoE;AACpE,mEAAmE;AAKnE,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAQlC,MAAM,eAAe,GAAmC;IACtD,MAAM;IACN,UAAU,EAAE,EAAE,MAAM,EAAE,2BAA2B,EAAE,MAAM,EAAE,eAAe,EAAE;IAC5E,SAAS,EAAE,EAAE,MAAM,EAAE,0BAA0B,EAAE,MAAM,EAAE,UAAU,EAAE;IACrE,KAAK,EAAE,EAAE,MAAM,EAAE,0BAA0B,EAAE,MAAM,EAAE,UAAU,EAAE;IAEjE,kBAAkB;IAClB,MAAM,EAAE,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,EAAE,WAAW,EAAE;IAChE,aAAa,EAAE,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,EAAE,kBAAkB,EAAE;IAC9E,MAAM,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE,MAAM,EAAE,gBAAgB,EAAE;IAC1E,eAAe,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE,MAAM,EAAE,eAAe,EAAE;IAClF,YAAY,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE,MAAM,EAAE,eAAe,EAAE;IAE/E,QAAQ;IACR,cAAc,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE,MAAM,EAAE,gBAAgB,EAAE;IAClF,KAAK,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE,MAAM,EAAE,oBAAoB,EAAE;IAE7E,wBAAwB;IACxB,IAAI,EAAE,EAAE,MAAM,EAAE,wBAAwB,EAAE,MAAM,EAAE,YAAY,EAAE;IAChE,WAAW,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,eAAe,EAAE;IAEtE,8BAA8B;IAC9B,yBAAyB,EAAE,EAAE,MAAM,EAAE,2BAA2B,EAAE,MAAM,EAAE,eAAe,EAAE;IAC3F,gBAAgB,EAAE,EAAE,MAAM,EAAE,4BAA4B,EAAE,MAAM,EAAE,gBAAgB,EAAE;IACpF,sBAAsB,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,oBAAoB,EAAE;IAEtF,0EAA0E;IAC1E,wEAAwE;IACxE,wEAAwE;IACxE,IAAI,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,cAAc,EAAE;IAC9D,KAAK,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,cAAc,EAAE;IAC/D,IAAI,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,cAAc,EAAE;IAC9D,WAAW,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,gBAAgB,EAAE;IAEvE,kBAAkB;IAClB,IAAI,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,iBAAiB,EAAE;IACjE,IAAI,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,iBAAiB,EAAE;IACjE,OAAO,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,kBAAkB,EAAE;IAErE,cAAc;IACd,MAAM,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,iBAAiB,EAAE;IACnE,OAAO,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,UAAU,EAAE;IAE7D,2BAA2B;IAC3B,aAAa,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,kBAAkB,EAAE;IAC3E,gBAAgB,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,iBAAiB,EAAE;IAC7E,aAAa,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,oBAAoB,EAAE;IAC7E,cAAc,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,iBAAiB,EAAE;IAC3E,OAAO,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,WAAW,EAAE;CAC/D,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,GAAW,EAAU,EAAE;IAC7C,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,IAAI,SAAS,CAAC,MAAM,IAAI,qBAAqB;QAAE,OAAO,SAAS,CAAC;IAChE,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC;AACvE,CAAC,CAAC;AAeF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,OAAsB,EACtB,MAA4B,EACX,EAAE;IACnB,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,CAAC,UAAkB,EAAE,MAAe,EAAE,EAAE;QACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC,CAAC;IAEF,OAAO;QACL,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,aAAa,CAAC;QAC3D,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,mBAAmB,CAAC;QAC7D,SAAS,EAAE,GAAG,EAAE;YACd,qEAAqE;YACrE,oEAAoE;YACpE,yBAAyB;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,IAAI,GAAG,GAAG,eAAe,GAAG,qBAAqB;gBAAE,OAAO;YAC1D,eAAe,GAAG,GAAG,CAAC;YACtB,IAAI,CAAC,uBAAuB,EAAE,WAAW,CAAC,CAAC;QAC7C,CAAC;QACD,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YAC1B,MAAM,WAAW,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACxC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,IAAI,CAAC,0BAA0B,CAAC,CAAC;gBACjC,OAAO;YACT,CAAC;YACD,sEAAsE;YACtE,kEAAkE;YAClE,mEAAmE;YACnE,kEAAkE;YAClE,mEAAmE;YACnE,0CAA0C;YAC1C,MAAM,IAAI,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC;YAC1C,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,WAAW,CAAC;YAC3C,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,oBAAoB,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YACpB,kEAAkE;YAClE,mEAAmE;YACnE,+DAA+D;YAC/D,gEAAgE;YAChE,mDAAmD;YACnD,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK;gBAAE,OAAO;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACtD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,IAAI,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC;YAC7D,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,oBAAoB,EAAE,MAAM,CAAC,CAAC;QACrD,CAAC;QACD,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,qBAAqB,CAAC;QAC7E,aAAa,EAAE,GAAG,EAAE;YAClB,sEAAsE;YACtE,kCAAkC;QACpC,CAAC;QACD,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;YACpB,MAAM,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACpC,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;QACtE,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC;KACtD,CAAC;AACJ,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mutirolabs/openclaw-brain",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "The official Mutiro Channel extension for OpenClaw. OpenClaw is the brain; Mutiro is the messaging surface, identity, and state.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "ISC",
|
|
@@ -14,8 +14,10 @@
|
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
16
|
"check": "tsc -p tsconfig.json --noEmit",
|
|
17
|
+
"clean": "rm -rf dist",
|
|
18
|
+
"build": "npm run clean && tsc -p tsconfig.build.json",
|
|
17
19
|
"gateway": "openclaw gateway run",
|
|
18
|
-
"prepublishOnly": "npm run check"
|
|
20
|
+
"prepublishOnly": "npm run check && npm run build"
|
|
19
21
|
},
|
|
20
22
|
"publishConfig": {
|
|
21
23
|
"access": "public"
|
|
@@ -28,6 +30,7 @@
|
|
|
28
30
|
"agent"
|
|
29
31
|
],
|
|
30
32
|
"files": [
|
|
33
|
+
"dist",
|
|
31
34
|
"index.ts",
|
|
32
35
|
"src",
|
|
33
36
|
"docs",
|