@ouro.bot/cli 0.1.0-alpha.639 → 0.1.0-alpha.640
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 +6 -0
- package/dist/heart/core.js +64 -6
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
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.640",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Reject text-only private-return queued acknowledgements unless ponder created packet-backed return work."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.639",
|
|
6
12
|
"changes": [
|
package/dist/heart/core.js
CHANGED
|
@@ -298,12 +298,18 @@ function messageContentText(content) {
|
|
|
298
298
|
.filter(Boolean)
|
|
299
299
|
.join("\n");
|
|
300
300
|
}
|
|
301
|
+
function isHarnessCorrectiveUserText(text) {
|
|
302
|
+
return text.startsWith("no tool was called this turn. you must end every turn")
|
|
303
|
+
|| text.startsWith("private-return acknowledgement claimed work was queued, but no ponder packet was created this turn.");
|
|
304
|
+
}
|
|
301
305
|
function latestUserMessageText(messages) {
|
|
302
306
|
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
303
307
|
const message = messages[i];
|
|
304
308
|
if (message?.role !== "user")
|
|
305
309
|
continue;
|
|
306
310
|
const text = messageContentText(message.content).trim();
|
|
311
|
+
if (isHarnessCorrectiveUserText(text))
|
|
312
|
+
continue;
|
|
307
313
|
if (text.length > 0)
|
|
308
314
|
return text;
|
|
309
315
|
}
|
|
@@ -675,12 +681,11 @@ async function runAgent(messages, callbacks, channel, signal, options) {
|
|
|
675
681
|
// which doesn't update mid-turn. The agent only needs to be told once;
|
|
676
682
|
// after that, repeated rest attempts mean they've acknowledged.
|
|
677
683
|
let freshWorkGateFired = false;
|
|
678
|
-
// Counter for
|
|
679
|
-
//
|
|
680
|
-
//
|
|
681
|
-
//
|
|
682
|
-
// a
|
|
683
|
-
// empty turn.
|
|
684
|
+
// Counter for no-tool-call violations. MiniMax reasoning models occasionally
|
|
685
|
+
// emit only a <think>...</think> block and stop, without any tool call — even
|
|
686
|
+
// when tool_choice is set to "required". Private-return requests also need
|
|
687
|
+
// a hard no-tool guard: a text-only "queued" acknowledgement is false unless
|
|
688
|
+
// a ponder packet created the return obligation in this turn.
|
|
684
689
|
let noToolCallRetries = 0;
|
|
685
690
|
const NO_TOOL_CALL_MAX_RETRIES = 2;
|
|
686
691
|
const toolLoopState = (0, tool_loop_1.createToolLoopState)();
|
|
@@ -938,7 +943,60 @@ async function runAgent(messages, callbacks, channel, signal, options) {
|
|
|
938
943
|
&& typeof result.content === "string"
|
|
939
944
|
&& stripThinkBlocksForViolationCheck(result.content).length === 0
|
|
940
945
|
&& result.content.length > 0;
|
|
946
|
+
const privateReturnTextAckRetryError = !result.toolCalls.length
|
|
947
|
+
? privateReturnMissingPonderError({
|
|
948
|
+
latestUserRequest: latestUserMessageText(messages),
|
|
949
|
+
answer: stripThinkBlocksForViolationCheck(result.content),
|
|
950
|
+
sawPonder,
|
|
951
|
+
})
|
|
952
|
+
: null;
|
|
941
953
|
if (!result.toolCalls.length) {
|
|
954
|
+
if (privateReturnTextAckRetryError) {
|
|
955
|
+
callbacks.onClearText?.();
|
|
956
|
+
if (noToolCallRetries < NO_TOOL_CALL_MAX_RETRIES) {
|
|
957
|
+
noToolCallRetries++;
|
|
958
|
+
(0, runtime_1.emitNervesEvent)({
|
|
959
|
+
level: "warn",
|
|
960
|
+
component: "engine",
|
|
961
|
+
event: "engine.no_tool_call_retry",
|
|
962
|
+
message: "model returned a text-only private-return acknowledgement without ponder; retrying with corrective nudge",
|
|
963
|
+
meta: {
|
|
964
|
+
attempt: noToolCallRetries,
|
|
965
|
+
cap: NO_TOOL_CALL_MAX_RETRIES,
|
|
966
|
+
provider: providerRuntime.id,
|
|
967
|
+
model: providerRuntime.model,
|
|
968
|
+
reason: "private_return_missing_ponder",
|
|
969
|
+
contentLength: result.content.length,
|
|
970
|
+
},
|
|
971
|
+
});
|
|
972
|
+
messages.push(msg);
|
|
973
|
+
messages.push({
|
|
974
|
+
role: "user",
|
|
975
|
+
content: `${privateReturnTextAckRetryError} Emit the ponder(action=create, ...) tool call now, or ask a blocking clarification without saying the private work is queued.`,
|
|
976
|
+
});
|
|
977
|
+
continue;
|
|
978
|
+
}
|
|
979
|
+
const blockedAnswer = "I could not start the private pass. No private-attention packet was created, so no return work was queued.";
|
|
980
|
+
(0, runtime_1.emitNervesEvent)({
|
|
981
|
+
level: "error",
|
|
982
|
+
component: "engine",
|
|
983
|
+
event: "engine.private_return_missing_ponder_blocked",
|
|
984
|
+
message: "private-return text acknowledgement skipped ponder through the retry cap; failing closed",
|
|
985
|
+
meta: {
|
|
986
|
+
cap: NO_TOOL_CALL_MAX_RETRIES,
|
|
987
|
+
provider: providerRuntime.id,
|
|
988
|
+
model: providerRuntime.model,
|
|
989
|
+
contentLength: result.content.length,
|
|
990
|
+
},
|
|
991
|
+
});
|
|
992
|
+
msg.content = blockedAnswer;
|
|
993
|
+
messages.push(msg);
|
|
994
|
+
callbacks.onTextChunk(blockedAnswer);
|
|
995
|
+
completion = { answer: blockedAnswer, intent: "blocked" };
|
|
996
|
+
outcome = "blocked";
|
|
997
|
+
done = true;
|
|
998
|
+
continue;
|
|
999
|
+
}
|
|
942
1000
|
if (onlyThinkContent && toolChoiceRequired && noToolCallRetries < NO_TOOL_CALL_MAX_RETRIES) {
|
|
943
1001
|
// Provider-level violation: tool_choice was required, model emitted
|
|
944
1002
|
// only a <think>...</think> block (or empty content) with no tool
|