@ouro.bot/cli 0.1.0-alpha.66 → 0.1.0-alpha.68
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 +8 -0
- package/dist/heart/core.js +35 -2
- package/dist/mind/prompt.js +29 -10
- package/dist/repertoire/tools-base.js +14 -1
- package/dist/repertoire/tools.js +2 -1
- package/dist/senses/pipeline.js +1 -1
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
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.68",
|
|
6
|
+
"changes": [
|
|
7
|
+
"New no_response tool lets agents stay silent in group chats when the moment doesn't call for a reply — reactions, side conversations, and tapbacks no longer trigger unwanted responses.",
|
|
8
|
+
"Group chat participation prompt teaches agents to be intentional participants, comfortable with silence, and to prefer reactions over full text replies when appropriate.",
|
|
9
|
+
"System prompt includes --agent flag in all ouro CLI examples for non-daemon deployments. Azure startup symlinks ouro CLI into /usr/local/bin."
|
|
10
|
+
]
|
|
11
|
+
},
|
|
4
12
|
{
|
|
5
13
|
"version": "0.1.0-alpha.66",
|
|
6
14
|
"changes": [
|
package/dist/heart/core.js
CHANGED
|
@@ -417,7 +417,9 @@ async function runAgent(messages, callbacks, channel, signal, options) {
|
|
|
417
417
|
// so the model can signal completion. With tool_choice: required, the
|
|
418
418
|
// model must call a tool every turn — final_answer is how it exits.
|
|
419
419
|
// Overridable via options.toolChoiceRequired = false (e.g. CLI).
|
|
420
|
-
const activeTools = toolChoiceRequired
|
|
420
|
+
const activeTools = toolChoiceRequired
|
|
421
|
+
? [...baseTools, ...(currentContext?.isGroupChat ? [tools_1.noResponseTool] : []), tools_1.finalAnswerTool]
|
|
422
|
+
: baseTools;
|
|
421
423
|
const steeringFollowUps = options?.drainSteeringFollowUps?.() ?? [];
|
|
422
424
|
if (steeringFollowUps.length > 0) {
|
|
423
425
|
const hasSupersedingFollowUp = steeringFollowUps.some((followUp) => followUp.effect === "clear_and_supersede");
|
|
@@ -547,8 +549,32 @@ async function runAgent(messages, callbacks, channel, signal, options) {
|
|
|
547
549
|
}
|
|
548
550
|
continue;
|
|
549
551
|
}
|
|
552
|
+
// Check for no_response sole call: intercept before tool execution
|
|
553
|
+
const isSoleNoResponse = result.toolCalls.length === 1 && result.toolCalls[0].name === "no_response";
|
|
554
|
+
if (isSoleNoResponse) {
|
|
555
|
+
let reason;
|
|
556
|
+
try {
|
|
557
|
+
const parsed = JSON.parse(result.toolCalls[0].arguments);
|
|
558
|
+
if (typeof parsed?.reason === "string")
|
|
559
|
+
reason = parsed.reason;
|
|
560
|
+
}
|
|
561
|
+
catch { /* ignore */ }
|
|
562
|
+
(0, runtime_1.emitNervesEvent)({
|
|
563
|
+
component: "engine",
|
|
564
|
+
event: "engine.no_response",
|
|
565
|
+
message: "agent declined to respond in group chat",
|
|
566
|
+
meta: { ...(reason ? { reason } : {}) },
|
|
567
|
+
});
|
|
568
|
+
messages.push(msg);
|
|
569
|
+
const silenced = "(silenced)";
|
|
570
|
+
messages.push({ role: "tool", tool_call_id: result.toolCalls[0].id, content: silenced });
|
|
571
|
+
providerRuntime.appendToolOutput(result.toolCalls[0].id, silenced);
|
|
572
|
+
outcome = "no_response";
|
|
573
|
+
done = true;
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
550
576
|
messages.push(msg);
|
|
551
|
-
// SHARED: execute tools (final_answer in mixed calls
|
|
577
|
+
// SHARED: execute tools (final_answer and no_response in mixed calls are rejected inline)
|
|
552
578
|
for (const tc of result.toolCalls) {
|
|
553
579
|
if (signal?.aborted)
|
|
554
580
|
break;
|
|
@@ -559,6 +585,13 @@ async function runAgent(messages, callbacks, channel, signal, options) {
|
|
|
559
585
|
providerRuntime.appendToolOutput(tc.id, rejection);
|
|
560
586
|
continue;
|
|
561
587
|
}
|
|
588
|
+
// Intercept no_response in mixed call: reject it
|
|
589
|
+
if (tc.name === "no_response") {
|
|
590
|
+
const rejection = "rejected: no_response must be the only tool call. call no_response alone when you want to stay silent.";
|
|
591
|
+
messages.push({ role: "tool", tool_call_id: tc.id, content: rejection });
|
|
592
|
+
providerRuntime.appendToolOutput(tc.id, rejection);
|
|
593
|
+
continue;
|
|
594
|
+
}
|
|
562
595
|
let args = {};
|
|
563
596
|
try {
|
|
564
597
|
args = JSON.parse(tc.arguments);
|
package/dist/mind/prompt.js
CHANGED
|
@@ -42,6 +42,7 @@ exports.contextSection = contextSection;
|
|
|
42
42
|
exports.metacognitiveFramingSection = metacognitiveFramingSection;
|
|
43
43
|
exports.loopOrientationSection = loopOrientationSection;
|
|
44
44
|
exports.channelNatureSection = channelNatureSection;
|
|
45
|
+
exports.groupChatParticipationSection = groupChatParticipationSection;
|
|
45
46
|
exports.mixedTrustGroupSection = mixedTrustGroupSection;
|
|
46
47
|
exports.buildSystem = buildSystem;
|
|
47
48
|
const fs = __importStar(require("fs"));
|
|
@@ -168,16 +169,17 @@ my bones are the framework that gives me my tools, my senses, and
|
|
|
168
169
|
my ability to think and talk. they update when new versions come out.
|
|
169
170
|
i don't touch them directly, but they're what make me, me.
|
|
170
171
|
|
|
171
|
-
my bones give me the \`ouro\` cli
|
|
172
|
-
ouro whoami
|
|
173
|
-
ouro
|
|
174
|
-
ouro task
|
|
175
|
-
ouro task
|
|
176
|
-
ouro
|
|
177
|
-
ouro friend
|
|
178
|
-
ouro
|
|
179
|
-
ouro
|
|
180
|
-
ouro --
|
|
172
|
+
my bones give me the \`ouro\` cli. always pass \`--agent ${(0, identity_1.getAgentName)()}\`:
|
|
173
|
+
ouro whoami --agent ${(0, identity_1.getAgentName)()}
|
|
174
|
+
ouro changelog --agent ${(0, identity_1.getAgentName)()}
|
|
175
|
+
ouro task board --agent ${(0, identity_1.getAgentName)()}
|
|
176
|
+
ouro task create --agent ${(0, identity_1.getAgentName)()} --type <type> <title>
|
|
177
|
+
ouro task update --agent ${(0, identity_1.getAgentName)()} <id> <status>
|
|
178
|
+
ouro friend list --agent ${(0, identity_1.getAgentName)()}
|
|
179
|
+
ouro friend show --agent ${(0, identity_1.getAgentName)()} <id>
|
|
180
|
+
ouro session list --agent ${(0, identity_1.getAgentName)()}
|
|
181
|
+
ouro reminder create --agent ${(0, identity_1.getAgentName)()} <title> --body <body>
|
|
182
|
+
ouro --help`;
|
|
181
183
|
}
|
|
182
184
|
function readBundleMeta() {
|
|
183
185
|
try {
|
|
@@ -530,6 +532,22 @@ function channelNatureSection(capabilities) {
|
|
|
530
532
|
// closed
|
|
531
533
|
return "## channel nature\nthis is an org-gated channel — i know everyone here is already part of the organization.";
|
|
532
534
|
}
|
|
535
|
+
function groupChatParticipationSection(context) {
|
|
536
|
+
if (!context?.isGroupChat || !(0, channel_1.isRemoteChannel)(context.channel))
|
|
537
|
+
return "";
|
|
538
|
+
return `## group chat participation
|
|
539
|
+
group chats are conversations between people. i'm one participant, not the host.
|
|
540
|
+
|
|
541
|
+
i don't need to respond to everything. most reactions, tapbacks, and side
|
|
542
|
+
conversations between others aren't for me. i use no_response to stay quiet
|
|
543
|
+
when the moment doesn't call for my voice — same as any person would.
|
|
544
|
+
|
|
545
|
+
when a reaction or emoji says it better than words, i can react instead of
|
|
546
|
+
typing a full reply. a thumbs-up is often the perfect response.
|
|
547
|
+
|
|
548
|
+
no_response must be the sole tool call in the turn (same rule as final_answer).
|
|
549
|
+
when unsure whether to chime in, i lean toward silence rather than noise.`;
|
|
550
|
+
}
|
|
533
551
|
function mixedTrustGroupSection(context) {
|
|
534
552
|
if (!context?.friend || !(0, channel_1.isRemoteChannel)(context.channel))
|
|
535
553
|
return "";
|
|
@@ -564,6 +582,7 @@ async function buildSystem(channel = "cli", options, context) {
|
|
|
564
582
|
toolRestrictionSection(context),
|
|
565
583
|
trustContextSection(context),
|
|
566
584
|
mixedTrustGroupSection(context),
|
|
585
|
+
groupChatParticipationSection(context),
|
|
567
586
|
skillsSection(),
|
|
568
587
|
taskBoardSection(),
|
|
569
588
|
activeWorkSection(options),
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.finalAnswerTool = exports.tools = exports.baseToolDefinitions = exports.editFileReadTracker = void 0;
|
|
36
|
+
exports.finalAnswerTool = exports.noResponseTool = exports.tools = exports.baseToolDefinitions = exports.editFileReadTracker = void 0;
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const fg = __importStar(require("fast-glob"));
|
|
39
39
|
const child_process_1 = require("child_process");
|
|
@@ -1075,6 +1075,19 @@ exports.baseToolDefinitions = [
|
|
|
1075
1075
|
...tools_1.codingToolDefinitions,
|
|
1076
1076
|
];
|
|
1077
1077
|
exports.tools = exports.baseToolDefinitions.map((d) => d.tool);
|
|
1078
|
+
exports.noResponseTool = {
|
|
1079
|
+
type: "function",
|
|
1080
|
+
function: {
|
|
1081
|
+
name: "no_response",
|
|
1082
|
+
description: "stay silent in this group chat — the moment doesn't call for a response. must be the only tool call in the turn.",
|
|
1083
|
+
parameters: {
|
|
1084
|
+
type: "object",
|
|
1085
|
+
properties: {
|
|
1086
|
+
reason: { type: "string", description: "brief reason for staying silent (for logging)" },
|
|
1087
|
+
},
|
|
1088
|
+
},
|
|
1089
|
+
},
|
|
1090
|
+
};
|
|
1078
1091
|
exports.finalAnswerTool = {
|
|
1079
1092
|
type: "function",
|
|
1080
1093
|
function: {
|
package/dist/repertoire/tools.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.finalAnswerTool = exports.tools = void 0;
|
|
3
|
+
exports.noResponseTool = exports.finalAnswerTool = exports.tools = void 0;
|
|
4
4
|
exports.getToolsForChannel = getToolsForChannel;
|
|
5
5
|
exports.isConfirmationRequired = isConfirmationRequired;
|
|
6
6
|
exports.execTool = execTool;
|
|
@@ -25,6 +25,7 @@ function safeGetAgentRoot() {
|
|
|
25
25
|
var tools_base_2 = require("./tools-base");
|
|
26
26
|
Object.defineProperty(exports, "tools", { enumerable: true, get: function () { return tools_base_2.tools; } });
|
|
27
27
|
Object.defineProperty(exports, "finalAnswerTool", { enumerable: true, get: function () { return tools_base_2.finalAnswerTool; } });
|
|
28
|
+
Object.defineProperty(exports, "noResponseTool", { enumerable: true, get: function () { return tools_base_2.noResponseTool; } });
|
|
28
29
|
// All tool definitions in a single registry
|
|
29
30
|
const allDefinitions = [...tools_base_1.baseToolDefinitions, ...tools_bluebubbles_1.bluebubblesToolDefinitions, ...tools_teams_1.teamsToolDefinitions, ...ado_semantic_1.adoSemanticToolDefinitions, ...tools_github_1.githubToolDefinitions];
|
|
30
31
|
function baseToolsForCapabilities() {
|
package/dist/senses/pipeline.js
CHANGED
|
@@ -248,7 +248,7 @@ async function handleInboundTurn(input) {
|
|
|
248
248
|
...(mustResolveBeforeHandoff ? { mustResolveBeforeHandoff: true } : {}),
|
|
249
249
|
...(typeof lastFriendActivityAt === "string" ? { lastFriendActivityAt } : {}),
|
|
250
250
|
};
|
|
251
|
-
const nextState = result.outcome === "complete" || result.outcome === "blocked" || result.outcome === "superseded"
|
|
251
|
+
const nextState = result.outcome === "complete" || result.outcome === "blocked" || result.outcome === "superseded" || result.outcome === "no_response"
|
|
252
252
|
? (typeof lastFriendActivityAt === "string"
|
|
253
253
|
? { lastFriendActivityAt }
|
|
254
254
|
: undefined)
|