@ouro.bot/cli 0.1.0-alpha.966 → 0.1.0-alpha.967
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,13 @@
|
|
|
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.967",
|
|
6
|
+
"changes": [
|
|
7
|
+
"When you reply to an older Telegram message, the Butler now sees which message you are answering, so a quick \"yes\" goes to the question you meant instead of the newest one.",
|
|
8
|
+
"Replies to the Butler's control cards and notices are not mistaken for answers to his questions."
|
|
9
|
+
]
|
|
10
|
+
},
|
|
4
11
|
{
|
|
5
12
|
"version": "0.1.0-alpha.966",
|
|
6
13
|
"changes": [
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<?xml version="1.0"?>
|
|
2
2
|
<Container version="2">
|
|
3
3
|
<Name>ouro-butler</Name>
|
|
4
|
-
<Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.
|
|
4
|
+
<Repository>ghcr.io/ourostack/ouroboros-butler:0.1.0-alpha.967</Repository>
|
|
5
5
|
<Registry>https://github.com/ourostack/ouroboros/pkgs/container/ouroboros-butler</Registry>
|
|
6
6
|
<Network>host</Network>
|
|
7
7
|
<Shell>sh</Shell>
|
|
@@ -5,6 +5,7 @@ exports.priorWorkInstruction = priorWorkInstruction;
|
|
|
5
5
|
exports.labelPriorWorkSurface = labelPriorWorkSurface;
|
|
6
6
|
exports.extractMessageText = extractMessageText;
|
|
7
7
|
exports.extractOrderedListReferents = extractOrderedListReferents;
|
|
8
|
+
exports.stampReplyingToText = stampReplyingToText;
|
|
8
9
|
exports.buildOrientationFrame = buildOrientationFrame;
|
|
9
10
|
exports.renderOrientationFrame = renderOrientationFrame;
|
|
10
11
|
const runtime_1 = require("../nerves/runtime");
|
|
@@ -188,6 +189,16 @@ function deriveActionPolicy(signals, combinedSpeech, priorAssistantReferents, la
|
|
|
188
189
|
clearedBy: CORRECTION_HOLD_CLEARED_BY,
|
|
189
190
|
};
|
|
190
191
|
}
|
|
192
|
+
// A reply names the message it answers. The sense stamps that message's text on the
|
|
193
|
+
// user message, so "yes" binds to what was replied to, not to the latest thing said.
|
|
194
|
+
function stampReplyingToText(message, text) {
|
|
195
|
+
;
|
|
196
|
+
message._replyingToText = text;
|
|
197
|
+
}
|
|
198
|
+
function replyingToTextOf(message) {
|
|
199
|
+
const text = message._replyingToText;
|
|
200
|
+
return typeof text === "string" && text.trim() ? text.trim() : undefined;
|
|
201
|
+
}
|
|
191
202
|
function buildOrientationFrame(input) {
|
|
192
203
|
const derivedCurrent = input.currentUserMessages
|
|
193
204
|
? { messages: input.currentUserMessages, firstIndex: input.messages.length }
|
|
@@ -195,8 +206,10 @@ function buildOrientationFrame(input) {
|
|
|
195
206
|
const currentUserSpeech = derivedCurrent.messages
|
|
196
207
|
.map((message) => extractMessageText(message))
|
|
197
208
|
.filter((text) => text.length > 0);
|
|
209
|
+
const replyingToText = derivedCurrent.messages.map(replyingToTextOf).find((text) => text !== undefined);
|
|
198
210
|
const previousAssistant = latestAssistantBefore(input.messages, derivedCurrent.firstIndex);
|
|
199
|
-
const priorAssistantReferents = extractOrderedListReferents(extractMessageText(previousAssistant));
|
|
211
|
+
const priorAssistantReferents = extractOrderedListReferents(replyingToText ?? extractMessageText(previousAssistant));
|
|
212
|
+
const source = replyingToText && !input.source?.replyingToText ? { kind: input.channel, ...input.source, replyingToText } : input.source;
|
|
200
213
|
const candidateStructuredOutput = latestStructuredOutputFrom(input.structuredOutputs);
|
|
201
214
|
const speechKind = input.speechKind ?? "utterance";
|
|
202
215
|
const signals = deriveSignals(currentUserSpeech, priorAssistantReferents, candidateStructuredOutput, speechKind);
|
|
@@ -213,7 +226,7 @@ function buildOrientationFrame(input) {
|
|
|
213
226
|
...(latestStructuredOutput ? { latestStructuredOutput } : {}),
|
|
214
227
|
signals,
|
|
215
228
|
actionPolicy,
|
|
216
|
-
...(
|
|
229
|
+
...(source ? { source } : {}),
|
|
217
230
|
...(speechKind === "utterance" ? {} : { speechKind }),
|
|
218
231
|
};
|
|
219
232
|
(0, runtime_1.emitNervesEvent)({
|
|
@@ -62,6 +62,7 @@ const pipeline_1 = require("./pipeline");
|
|
|
62
62
|
const mcp_manager_1 = require("../repertoire/mcp-manager");
|
|
63
63
|
const runtime_1 = require("../nerves/runtime");
|
|
64
64
|
const session_transaction_1 = require("../mind/session-transaction");
|
|
65
|
+
const orientation_frame_1 = require("../heart/orientation-frame");
|
|
65
66
|
const turn_execution_lease_1 = require("../heart/turn-execution-lease");
|
|
66
67
|
const RESPONSE_CAP = 50_000;
|
|
67
68
|
const OUTWARD_DELIVERY_TOOL_ACKS = new Map([
|
|
@@ -270,6 +271,23 @@ function rawSessionEvents(value) {
|
|
|
270
271
|
const record = value;
|
|
271
272
|
return record.version === 2 && Array.isArray(record.events) ? record.events : [];
|
|
272
273
|
}
|
|
274
|
+
// What the agent said in a replied-to message: the settle answer it delivered, else its text.
|
|
275
|
+
// Only the agent's own messages are quoted; a control card or notice is not something it asked.
|
|
276
|
+
function spokenText(event) {
|
|
277
|
+
if (event?.role !== "assistant")
|
|
278
|
+
return "";
|
|
279
|
+
for (const call of event.toolCalls) {
|
|
280
|
+
if (call.function.name !== "settle")
|
|
281
|
+
continue;
|
|
282
|
+
try {
|
|
283
|
+
const answer = JSON.parse(call.function.arguments).answer;
|
|
284
|
+
if (typeof answer === "string" && answer.trim())
|
|
285
|
+
return answer.trim().slice(0, 1200);
|
|
286
|
+
}
|
|
287
|
+
catch { /* a malformed settle names nothing */ }
|
|
288
|
+
}
|
|
289
|
+
return typeof event.content === "string" ? event.content.trim().slice(0, 1200) : "";
|
|
290
|
+
}
|
|
273
291
|
function exactProjectedIngressMessage(existing, messages, eventId, nativeValue) {
|
|
274
292
|
if (!nativeValue || typeof nativeValue !== "object" || Array.isArray(nativeValue))
|
|
275
293
|
return null;
|
|
@@ -462,6 +480,8 @@ async function runSenseTurnExclusive(options, owner) {
|
|
|
462
480
|
system.content = system.content.split(`\n${marker}`)[0] + `\n${marker}\n${JSON.stringify(options.shepherdSession)}\nUse this exact UUID for shepherd_read/shepherd_send. If gone, fail explicitly; never substitute a short ref. This locator grants no authority.`;
|
|
463
481
|
}
|
|
464
482
|
}
|
|
483
|
+
const replyToEventId = precommittedIngressEvent?.relations.replyToEventId ?? options.ingressRelations?.replyToEventId;
|
|
484
|
+
const repliedToText = spokenText(existing?.events?.find((event) => event.id === replyToEventId));
|
|
465
485
|
if (precommittedIngressEvent) {
|
|
466
486
|
const projectedIngress = exactProjectedIngressMessage(existing, sessionMessages, precommittedIngressEvent.id, baseSession.value);
|
|
467
487
|
if (!projectedIngress || projectedIngress.role !== "user" || projectedIngress.content !== userMessage)
|
|
@@ -471,6 +491,8 @@ async function runSenseTurnExclusive(options, owner) {
|
|
|
471
491
|
threadRootEventId: precommittedIngressEvent.relations.threadRootEventId,
|
|
472
492
|
references: precommittedIngressEvent.relations.references,
|
|
473
493
|
});
|
|
494
|
+
if (repliedToText)
|
|
495
|
+
(0, orientation_frame_1.stampReplyingToText)(projectedIngress, repliedToText);
|
|
474
496
|
}
|
|
475
497
|
// Pending dir
|
|
476
498
|
const pendingDir = (0, pending_1.getPendingDir)(agentName, friendId, channel, sessionKey);
|
|
@@ -580,6 +602,8 @@ async function runSenseTurnExclusive(options, owner) {
|
|
|
580
602
|
(0, session_events_1.stampIngressTime)(userMsg);
|
|
581
603
|
if (options.ingressRelations)
|
|
582
604
|
(0, session_events_1.stampIngressRelations)(userMsg, options.ingressRelations);
|
|
605
|
+
if (repliedToText)
|
|
606
|
+
(0, orientation_frame_1.stampReplyingToText)(userMsg, repliedToText);
|
|
583
607
|
inboundMessages.push(userMsg);
|
|
584
608
|
}
|
|
585
609
|
const turnResult = await (0, pipeline_1.handleInboundTurn)({
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouro.bot/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.967",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@ouro.bot/cli",
|
|
9
|
-
"version": "0.1.0-alpha.
|
|
9
|
+
"version": "0.1.0-alpha.967",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
12
12
|
"@azure/identity": "^4.13.0",
|