@ouro.bot/cli 0.1.0-alpha.92 → 0.1.0-alpha.93
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 +18 -2
- 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.93",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Final-answer truth checks now require fresh external-state verification (gh pr view, npm view, etc.) before allowing intent=complete when a live obligation is active, preventing stale or guessed merge/publish/deploy claims."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.92",
|
|
6
12
|
"changes": [
|
package/dist/heart/core.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.getModel = getModel;
|
|
|
7
7
|
exports.getProvider = getProvider;
|
|
8
8
|
exports.createSummarize = createSummarize;
|
|
9
9
|
exports.getProviderDisplayLabel = getProviderDisplayLabel;
|
|
10
|
+
exports.isExternalStateQuery = isExternalStateQuery;
|
|
10
11
|
exports.getFinalAnswerRetryError = getFinalAnswerRetryError;
|
|
11
12
|
exports.stripLastToolCalls = stripLastToolCalls;
|
|
12
13
|
exports.repairOrphanedToolCalls = repairOrphanedToolCalls;
|
|
@@ -228,7 +229,14 @@ function parseFinalAnswerPayload(argumentsText) {
|
|
|
228
229
|
return {};
|
|
229
230
|
}
|
|
230
231
|
}
|
|
231
|
-
|
|
232
|
+
/** Returns true when a tool call queries external state (GitHub, npm registry). */
|
|
233
|
+
function isExternalStateQuery(toolName, args) {
|
|
234
|
+
if (toolName !== "shell")
|
|
235
|
+
return false;
|
|
236
|
+
const cmd = String(args.command ?? "");
|
|
237
|
+
return /\bgh\s+(pr|run|api|issue)\b/.test(cmd) || /\bnpm\s+(view|info|show)\b/.test(cmd);
|
|
238
|
+
}
|
|
239
|
+
function getFinalAnswerRetryError(mustResolveBeforeHandoff, intent, sawSteeringFollowUp, delegationDecision, sawSendMessageSelf, sawGoInward, sawQuerySession, currentObligation, innerJob, sawExternalStateQuery) {
|
|
232
240
|
// 1. Delegation adherence: delegate-inward without evidence of inward action
|
|
233
241
|
if (delegationDecision?.target === "delegate-inward" && !sawSendMessageSelf && !sawGoInward && !sawQuerySession) {
|
|
234
242
|
(0, runtime_1.emitNervesEvent)({
|
|
@@ -258,6 +266,10 @@ function getFinalAnswerRetryError(mustResolveBeforeHandoff, intent, sawSteeringF
|
|
|
258
266
|
if (mustResolveBeforeHandoff && intent === "complete" && currentObligation && !sawSteeringFollowUp) {
|
|
259
267
|
return "you still owe the live session a visible return on this work. don't end the turn yet — continue until you've brought back the external-state update, or use intent=blocked with the concrete blocker.";
|
|
260
268
|
}
|
|
269
|
+
// 6. External-state grounding: obligation + complete requires fresh external verification
|
|
270
|
+
if (intent === "complete" && currentObligation && !sawExternalStateQuery && !sawSteeringFollowUp) {
|
|
271
|
+
return "you're claiming this work is complete, but the external state hasn't been verified this turn. ground your claim with a fresh check (gh pr view, npm view, gh run view, etc.) before calling final_answer.";
|
|
272
|
+
}
|
|
261
273
|
return null;
|
|
262
274
|
}
|
|
263
275
|
// Re-export kick utilities for backward compat
|
|
@@ -477,6 +489,7 @@ async function runAgent(messages, callbacks, channel, signal, options) {
|
|
|
477
489
|
let sawGoInward = false;
|
|
478
490
|
let sawQuerySession = false;
|
|
479
491
|
let sawBridgeManage = false;
|
|
492
|
+
let sawExternalStateQuery = false;
|
|
480
493
|
// Prevent MaxListenersExceeded warning — each iteration adds a listener
|
|
481
494
|
try {
|
|
482
495
|
require("events").setMaxListeners(50, signal);
|
|
@@ -585,7 +598,7 @@ async function runAgent(messages, callbacks, channel, signal, options) {
|
|
|
585
598
|
// Extract answer from the tool call arguments.
|
|
586
599
|
// Supports: {"answer":"text","intent":"..."} or "text" (JSON string).
|
|
587
600
|
const { answer, intent } = parseFinalAnswerPayload(result.toolCalls[0].arguments);
|
|
588
|
-
const retryError = getFinalAnswerRetryError(mustResolveBeforeHandoffActive, intent, sawSteeringFollowUp, options?.delegationDecision, sawSendMessageSelf, sawGoInward, sawQuerySession, options?.currentObligation ?? null, options?.activeWorkFrame?.inner?.job);
|
|
601
|
+
const retryError = getFinalAnswerRetryError(mustResolveBeforeHandoffActive, intent, sawSteeringFollowUp, options?.delegationDecision, sawSendMessageSelf, sawGoInward, sawQuerySession, options?.currentObligation ?? null, options?.activeWorkFrame?.inner?.job, sawExternalStateQuery);
|
|
589
602
|
const validDirectReply = mustResolveBeforeHandoffActive && intent === "direct_reply" && sawSteeringFollowUp;
|
|
590
603
|
const validTerminalIntent = intent === "complete" || intent === "blocked";
|
|
591
604
|
const validClosure = answer != null
|
|
@@ -783,6 +796,9 @@ async function runAgent(messages, callbacks, channel, signal, options) {
|
|
|
783
796
|
/* v8 ignore next -- flag tested via truth-check integration tests @preserve */
|
|
784
797
|
if (tc.name === "bridge_manage")
|
|
785
798
|
sawBridgeManage = true;
|
|
799
|
+
/* v8 ignore next -- flag tested via truth-check integration tests @preserve */
|
|
800
|
+
if (isExternalStateQuery(tc.name, args))
|
|
801
|
+
sawExternalStateQuery = true;
|
|
786
802
|
const argSummary = (0, tools_1.summarizeArgs)(tc.name, args);
|
|
787
803
|
// Confirmation check for mutate tools
|
|
788
804
|
if ((0, tools_1.isConfirmationRequired)(tc.name) && !options?.skipConfirmation) {
|