@ouro.bot/cli 0.1.0-alpha.154 → 0.1.0-alpha.156
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.json
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.156",
|
|
6
|
+
"changes": [
|
|
7
|
+
"polish: observe tool now hidden (like settle/rest/descend)",
|
|
8
|
+
"polish(bb): batch rapid tool status messages within 500ms debounce window",
|
|
9
|
+
"polish(tools): word-boundary truncation instead of mid-word cut",
|
|
10
|
+
"polish(commands): /commands output uses em dash separators",
|
|
11
|
+
"polish(bb): re-enable typing indicator after each status message"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"version": "0.1.0-alpha.155",
|
|
16
|
+
"changes": [
|
|
17
|
+
"polish(debug): dynamic toggle, richer descriptions, human-readable results"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
4
20
|
{
|
|
5
21
|
"version": "0.1.0-alpha.154",
|
|
6
22
|
"changes": [
|
|
@@ -8,22 +8,28 @@ function createToolActivityCallbacks(options) {
|
|
|
8
8
|
component: "engine",
|
|
9
9
|
event: "engine.tool_activity_callbacks_created",
|
|
10
10
|
message: "tool activity callbacks initialized",
|
|
11
|
-
meta: {
|
|
11
|
+
meta: {},
|
|
12
12
|
});
|
|
13
|
+
// Track the last description so we can reference it in END messages
|
|
14
|
+
let lastDescription = null;
|
|
13
15
|
return {
|
|
14
16
|
onToolStart(name, args) {
|
|
15
17
|
const description = (0, tool_description_1.humanReadableToolDescription)(name, args);
|
|
16
18
|
if (description === null)
|
|
17
|
-
return; // hidden tool (settle, rest)
|
|
19
|
+
return; // hidden tool (settle, rest, descend)
|
|
20
|
+
lastDescription = description;
|
|
18
21
|
options.onDescription(description);
|
|
19
22
|
},
|
|
20
23
|
onToolEnd(name, summary, success) {
|
|
24
|
+
const desc = lastDescription ?? name;
|
|
25
|
+
// Strip trailing "..." from description for the result line
|
|
26
|
+
const cleanDesc = desc.endsWith("...") ? desc.slice(0, -3) : desc;
|
|
21
27
|
if (!success) {
|
|
22
|
-
options.onFailure(
|
|
28
|
+
options.onFailure(`\u2717 ${cleanDesc} — ${summary}`);
|
|
23
29
|
return;
|
|
24
30
|
}
|
|
25
|
-
if (options.isDebug) {
|
|
26
|
-
options.onResult(
|
|
31
|
+
if (options.isDebug()) {
|
|
32
|
+
options.onResult(`\u2713 ${cleanDesc}`);
|
|
27
33
|
}
|
|
28
34
|
},
|
|
29
35
|
};
|
|
@@ -9,9 +9,16 @@ function basename(filePath) {
|
|
|
9
9
|
function truncate(text, max) {
|
|
10
10
|
if (text.length <= max)
|
|
11
11
|
return text;
|
|
12
|
-
|
|
12
|
+
// Cut at last space before maxLen to avoid mid-word truncation
|
|
13
|
+
const slice = text.slice(0, max - 1);
|
|
14
|
+
const lastSpace = slice.lastIndexOf(" ");
|
|
15
|
+
if (lastSpace > 0)
|
|
16
|
+
return text.slice(0, lastSpace) + "\u2026";
|
|
17
|
+
// No space found (single long word) — hard truncate
|
|
18
|
+
return slice + "\u2026";
|
|
13
19
|
}
|
|
14
20
|
const TOOL_DESCRIPTIONS = {
|
|
21
|
+
// File operations
|
|
15
22
|
shell: (args) => {
|
|
16
23
|
const cmd = args.command;
|
|
17
24
|
if (!cmd)
|
|
@@ -36,11 +43,11 @@ const TOOL_DESCRIPTIONS = {
|
|
|
36
43
|
return "editing a file...";
|
|
37
44
|
return `editing ${basename(fp)}...`;
|
|
38
45
|
},
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
if (!
|
|
42
|
-
return "searching
|
|
43
|
-
return `searching
|
|
46
|
+
glob: (args) => {
|
|
47
|
+
const p = args.pattern;
|
|
48
|
+
if (!p)
|
|
49
|
+
return "searching for files...";
|
|
50
|
+
return `searching for ${truncate(p, 40)}...`;
|
|
44
51
|
},
|
|
45
52
|
grep: (args) => {
|
|
46
53
|
const p = args.pattern;
|
|
@@ -48,21 +55,65 @@ const TOOL_DESCRIPTIONS = {
|
|
|
48
55
|
return "searching code...";
|
|
49
56
|
return `searching code for '${truncate(p, 40)}'...`;
|
|
50
57
|
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
// Memory and knowledge
|
|
59
|
+
recall: (args) => {
|
|
60
|
+
const q = args.query;
|
|
61
|
+
if (!q)
|
|
62
|
+
return "searching memory...";
|
|
63
|
+
return `searching memory for '${truncate(q, 40)}'...`;
|
|
64
|
+
},
|
|
65
|
+
diary_write: (args) => {
|
|
66
|
+
const about = args.about;
|
|
67
|
+
return about ? `noting something about ${truncate(about, 30)}...` : "noting something down...";
|
|
68
|
+
},
|
|
69
|
+
save_friend_note: () => "making a note about you...",
|
|
70
|
+
get_friend_note: () => "checking my notes...",
|
|
71
|
+
load_skill: (args) => {
|
|
72
|
+
const name = args.name || args.skill;
|
|
73
|
+
return name ? `loading ${name} skill...` : "loading a skill...";
|
|
74
|
+
},
|
|
75
|
+
// Session and context
|
|
76
|
+
query_session: (args) => {
|
|
77
|
+
const mode = args.mode;
|
|
78
|
+
if (mode === "search")
|
|
79
|
+
return `searching session for '${truncate(args.query || "", 30)}'...`;
|
|
80
|
+
if (mode === "status")
|
|
81
|
+
return "checking inner dialog status...";
|
|
82
|
+
return "checking session history...";
|
|
83
|
+
},
|
|
84
|
+
web_search: (args) => {
|
|
85
|
+
const q = args.query;
|
|
86
|
+
return q ? `searching the web for '${truncate(q, 35)}'...` : "searching the web...";
|
|
87
|
+
},
|
|
88
|
+
coding_spawn: (args) => {
|
|
89
|
+
const runner = args.runner;
|
|
90
|
+
return runner ? `starting ${runner} coding session...` : "starting coding session...";
|
|
91
|
+
},
|
|
92
|
+
coding_status: () => "checking coding sessions...",
|
|
93
|
+
coding_tail: () => "reading coding output...",
|
|
94
|
+
coding_kill: () => "stopping coding session...",
|
|
95
|
+
bridge_manage: () => "managing conversation bridge...",
|
|
96
|
+
// Communication
|
|
97
|
+
send_message: (args) => {
|
|
98
|
+
const to = args.to;
|
|
99
|
+
return to ? `sending a message to ${to}...` : "sending a message...";
|
|
100
|
+
},
|
|
101
|
+
surface: () => "sharing a thought...",
|
|
102
|
+
// Metacognitive (agent's inner life)
|
|
103
|
+
ponder: (args) => {
|
|
104
|
+
const thought = args.thought;
|
|
105
|
+
return thought ? `thinking about ${truncate(thought, 40)}...` : "thinking deeper...";
|
|
106
|
+
},
|
|
107
|
+
observe: () => null,
|
|
108
|
+
claude: () => "reasoning...",
|
|
109
|
+
set_reasoning_effort: (args) => {
|
|
110
|
+
const level = args.level;
|
|
111
|
+
return level ? `setting thinking depth to ${level}...` : "adjusting thinking depth...";
|
|
56
112
|
},
|
|
57
|
-
|
|
58
|
-
web_search: () => "searching the web...",
|
|
59
|
-
coding_spawn: () => "starting coding session...",
|
|
60
|
-
ponder: () => "thinking deeper...",
|
|
61
|
-
observe: () => "listening...",
|
|
62
|
-
diary_write: () => "noting something down...",
|
|
63
|
-
save_friend_note: () => "making a note...",
|
|
113
|
+
// Hidden — these ARE the response or end-of-turn
|
|
64
114
|
settle: () => null,
|
|
65
115
|
rest: () => null,
|
|
116
|
+
descend: () => null,
|
|
66
117
|
};
|
|
67
118
|
function humanReadableToolDescription(name, args) {
|
|
68
119
|
(0, runtime_1.emitNervesEvent)({
|
|
@@ -34,6 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.enrichReactionText = enrichReactionText;
|
|
37
|
+
exports.createStatusBatcher = createStatusBatcher;
|
|
37
38
|
exports.handleBlueBubblesEvent = handleBlueBubblesEvent;
|
|
38
39
|
exports.recoverMissedBlueBubblesMessages = recoverMissedBlueBubblesMessages;
|
|
39
40
|
exports.createBlueBubblesWebhookHandler = createBlueBubblesWebhookHandler;
|
|
@@ -81,6 +82,44 @@ function enrichReactionText(baseText, originalText, maxLen) {
|
|
|
81
82
|
: originalText;
|
|
82
83
|
return `${baseText} to: "${truncated}"`;
|
|
83
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Accumulates status descriptions and debounces them.
|
|
87
|
+
* If multiple descriptions arrive within `delayMs`, they are joined with ` · `
|
|
88
|
+
* and sent as a single message. Flush sends immediately and clears the timer.
|
|
89
|
+
*/
|
|
90
|
+
function createStatusBatcher(send, delayMs) {
|
|
91
|
+
(0, runtime_1.emitNervesEvent)({
|
|
92
|
+
component: "senses",
|
|
93
|
+
event: "senses.bluebubbles_status_batcher_created",
|
|
94
|
+
message: "status batcher initialized",
|
|
95
|
+
meta: { delayMs },
|
|
96
|
+
});
|
|
97
|
+
let pending = [];
|
|
98
|
+
let timer = null;
|
|
99
|
+
function fire() {
|
|
100
|
+
if (pending.length === 0)
|
|
101
|
+
return;
|
|
102
|
+
const combined = pending.join(" \u00b7 ");
|
|
103
|
+
pending = [];
|
|
104
|
+
timer = null;
|
|
105
|
+
send(combined);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
add(text) {
|
|
109
|
+
pending.push(text);
|
|
110
|
+
if (timer !== null)
|
|
111
|
+
clearTimeout(timer);
|
|
112
|
+
timer = setTimeout(fire, delayMs);
|
|
113
|
+
},
|
|
114
|
+
flush() {
|
|
115
|
+
if (timer !== null) {
|
|
116
|
+
clearTimeout(timer);
|
|
117
|
+
timer = null;
|
|
118
|
+
}
|
|
119
|
+
fire();
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
84
123
|
const defaultDeps = {
|
|
85
124
|
getAgentName: identity_1.getAgentName,
|
|
86
125
|
buildSystem: prompt_1.buildSystem,
|
|
@@ -401,15 +440,18 @@ function createBlueBubblesCallbacks(client, chat, replyTarget, isGroupChat) {
|
|
|
401
440
|
text,
|
|
402
441
|
replyToMessageGuid: replyTarget.getReplyToMessageGuid(),
|
|
403
442
|
});
|
|
443
|
+
// Re-enable typing indicator — sending a message clears the typing bubble
|
|
444
|
+
await client.setTyping(chat, true);
|
|
404
445
|
});
|
|
405
446
|
}
|
|
447
|
+
const statusBatcher = createStatusBatcher((text) => sendStatus(text), 500);
|
|
406
448
|
const toolCallbacks = (0, tool_activity_callbacks_1.createToolActivityCallbacks)({
|
|
407
|
-
onDescription: (text) =>
|
|
449
|
+
onDescription: (text) => statusBatcher.add(text),
|
|
408
450
|
/* v8 ignore next -- onResult only called in debug mode; tested via tool-activity-callbacks.test.ts @preserve */
|
|
409
|
-
onResult: (text) => sendStatus(text),
|
|
451
|
+
onResult: (text) => { statusBatcher.flush(); sendStatus(text); },
|
|
410
452
|
/* v8 ignore next -- onFailure only called on tool failure; tested via tool-activity-callbacks.test.ts @preserve */
|
|
411
|
-
onFailure: (text) => sendStatus(
|
|
412
|
-
isDebug:
|
|
453
|
+
onFailure: (text) => { statusBatcher.flush(); sendStatus(text); },
|
|
454
|
+
isDebug: commands_1.getDebugMode,
|
|
413
455
|
});
|
|
414
456
|
return {
|
|
415
457
|
onModelStart() {
|
|
@@ -471,6 +513,7 @@ function createBlueBubblesCallbacks(client, chat, replyTarget, isGroupChat) {
|
|
|
471
513
|
textBuffer = "";
|
|
472
514
|
},
|
|
473
515
|
async flush() {
|
|
516
|
+
statusBatcher.flush();
|
|
474
517
|
await queue;
|
|
475
518
|
const trimmed = textBuffer.trim();
|
|
476
519
|
if (!trimmed) {
|
|
@@ -495,6 +538,7 @@ function createBlueBubblesCallbacks(client, chat, replyTarget, isGroupChat) {
|
|
|
495
538
|
});
|
|
496
539
|
},
|
|
497
540
|
async finish() {
|
|
541
|
+
statusBatcher.flush();
|
|
498
542
|
if (!typingActive) {
|
|
499
543
|
await queue;
|
|
500
544
|
return;
|
package/dist/senses/commands.js
CHANGED
|
@@ -72,7 +72,7 @@ function registerDefaultCommands(registry) {
|
|
|
72
72
|
channels: ["cli", "teams"],
|
|
73
73
|
handler: (ctx) => {
|
|
74
74
|
const cmds = registry.list(ctx.channel);
|
|
75
|
-
const lines = cmds.map((c) => `/${c.name}
|
|
75
|
+
const lines = cmds.map((c) => `/${c.name} \u2014 ${c.description}`);
|
|
76
76
|
return { action: "response", message: lines.join("\n") };
|
|
77
77
|
},
|
|
78
78
|
});
|
|
@@ -87,11 +87,16 @@ function registerDefaultCommands(registry) {
|
|
|
87
87
|
});
|
|
88
88
|
registry.register({
|
|
89
89
|
name: "debug",
|
|
90
|
-
description: "toggle debug mode
|
|
91
|
-
channels: ["cli", "teams", "bluebubbles"],
|
|
90
|
+
description: "toggle debug mode — see more detail about what I'm doing",
|
|
91
|
+
channels: ["cli", "teams", "bluebubbles", "mcp"],
|
|
92
92
|
handler: () => {
|
|
93
93
|
_debugMode = !_debugMode;
|
|
94
|
-
return {
|
|
94
|
+
return {
|
|
95
|
+
action: "response",
|
|
96
|
+
message: _debugMode
|
|
97
|
+
? "debug mode on — you'll see more detail about what I'm doing"
|
|
98
|
+
: "debug mode off — back to clean output",
|
|
99
|
+
};
|
|
95
100
|
},
|
|
96
101
|
});
|
|
97
102
|
(0, runtime_1.emitNervesEvent)({
|
package/dist/senses/teams.js
CHANGED
|
@@ -433,8 +433,8 @@ function createTeamsCallbacks(stream, controller, sendMessage, options) {
|
|
|
433
433
|
/* v8 ignore next -- onResult only called in debug mode; tested via tool-activity-callbacks.test.ts @preserve */
|
|
434
434
|
onResult: (text) => safeUpdate(text),
|
|
435
435
|
/* v8 ignore next -- onFailure tested via onToolEnd failure test @preserve */
|
|
436
|
-
onFailure: (text) => safeUpdate(
|
|
437
|
-
isDebug:
|
|
436
|
+
onFailure: (text) => safeUpdate(text),
|
|
437
|
+
isDebug: commands_2.getDebugMode,
|
|
438
438
|
});
|
|
439
439
|
return {
|
|
440
440
|
onToolStart: (name, args) => {
|