@ouro.bot/cli 0.1.0-alpha.723 → 0.1.0-alpha.725
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 +295 -275
- package/dist/heart/active-work.js +10 -3
- package/dist/heart/core.js +343 -77
- package/dist/heart/daemon/cli-exec.js +132 -15
- package/dist/heart/daemon/cli-help.js +13 -2
- package/dist/heart/daemon/cli-parse.js +82 -1
- package/dist/heart/daemon/daemon.js +286 -33
- package/dist/heart/daemon/doctor.js +82 -6
- package/dist/heart/daemon/habit-private-wake.js +6 -1
- package/dist/heart/habits/habit-cancel.js +810 -0
- package/dist/heart/habits/habit-lifecycle.js +1327 -0
- package/dist/heart/habits/habit-migration.js +28 -23
- package/dist/heart/habits/habit-parser.js +72 -8
- package/dist/heart/habits/habit-runtime-state.js +3 -24
- package/dist/heart/habits/habit-scheduler.js +268 -50
- package/dist/heart/habits/habit-session.js +16 -0
- package/dist/heart/hatch/hatch-flow.js +6 -4
- package/dist/heart/mailbox/readers/runtime-readers.js +26 -27
- package/dist/heart/orientation-frame.js +58 -1
- package/dist/heart/provider-attempt.js +4 -1
- package/dist/heart/providers/anthropic.js +23 -2
- package/dist/heart/start-of-turn-packet.js +14 -11
- package/dist/heart/streaming.js +565 -185
- package/dist/mind/obligation-steering.js +15 -9
- package/dist/mind/prompt.js +58 -26
- package/dist/nerves/coverage/run-artifacts.js +55 -35
- package/dist/nerves/review/cli.js +2 -2
- package/dist/nerves/review/core.js +14 -7
- package/dist/repertoire/tools-base.js +2 -0
- package/dist/repertoire/tools-habits.js +103 -0
- package/dist/repertoire/tools.js +18 -3
- package/dist/rsvp/cli.js +126 -20
- package/dist/rsvp/diagnostics.js +12 -2
- package/dist/rsvp/habit-policy.js +7 -0
- package/dist/rsvp/habit-stage.js +19 -4
- package/dist/rsvp/native-habit-runner.js +151 -11
- package/dist/rsvp/outbound-state.js +360 -0
- package/dist/senses/bluebubbles/client.js +90 -17
- package/dist/senses/bluebubbles/inbound-log.js +1 -0
- package/dist/senses/bluebubbles/index.js +662 -425
- package/dist/senses/bluebubbles/model.js +57 -13
- package/dist/senses/bluebubbles/mutation-log.js +21 -10
- package/dist/senses/bluebubbles/reaction-policy.js +55 -0
- package/dist/senses/bluebubbles/semantic-receipts.js +1818 -0
- package/dist/senses/cli/tui-store.js +1 -0
- package/dist/senses/cli.js +1 -0
- package/dist/senses/habit-lifecycle-guard.js +24 -0
- package/dist/senses/ingress-evidence.js +2 -0
- package/dist/senses/mail.js +129 -0
- package/dist/senses/pipeline.js +90 -24
- package/dist/senses/private-runtime-worker.js +21 -20
- package/dist/senses/private-runtime.js +79 -29
- package/dist/senses/shared-turn.js +1 -0
- package/dist/senses/teams.js +1 -0
- package/package.json +6 -1
|
@@ -76,6 +76,7 @@ const await_parser_1 = require("../heart/awaiting/await-parser");
|
|
|
76
76
|
const await_runtime_state_1 = require("../heart/awaiting/await-runtime-state");
|
|
77
77
|
const habit_parser_1 = require("../heart/habits/habit-parser");
|
|
78
78
|
const habit_runtime_state_1 = require("../heart/habits/habit-runtime-state");
|
|
79
|
+
const habit_lifecycle_guard_1 = require("./habit-lifecycle-guard");
|
|
79
80
|
const cadence_1 = require("../heart/daemon/cadence");
|
|
80
81
|
const habit_policy_1 = require("../rsvp/habit-policy");
|
|
81
82
|
const daemon_health_1 = require("../heart/daemon/daemon-health");
|
|
@@ -344,6 +345,14 @@ function assertPayloadBinding(decision, kind, id) {
|
|
|
344
345
|
return;
|
|
345
346
|
throw new Error(`private-runtime decision payload mismatch: missing ${kind} origin ref ${id}`);
|
|
346
347
|
}
|
|
348
|
+
function assertNoSendBinding(decision, noSend) {
|
|
349
|
+
const refs = decision.originRefs.filter((ref) => ref.kind === "capability" && ref.id === "no-send");
|
|
350
|
+
if (noSend === true && refs.length === 1)
|
|
351
|
+
return;
|
|
352
|
+
if (noSend === undefined && refs.length === 0)
|
|
353
|
+
return;
|
|
354
|
+
throw new Error("private-runtime decision payload mismatch: no-send capability binding does not match the turn");
|
|
355
|
+
}
|
|
347
356
|
function ledgerDecisionFor(decision) {
|
|
348
357
|
const ledgerPath = decision.ledgerLocator?.path;
|
|
349
358
|
if (!ledgerPath) {
|
|
@@ -389,6 +398,7 @@ function assertPrivateTurnDecisionAllowed(input) {
|
|
|
389
398
|
assertPayloadBinding(decision, "task", options?.taskId);
|
|
390
399
|
assertPayloadBinding(decision, "habit", options?.habitName);
|
|
391
400
|
assertPayloadBinding(decision, "await", options?.awaitName);
|
|
401
|
+
assertNoSendBinding(decision, options?.noSend);
|
|
392
402
|
const ledgerRow = ledgerDecisionFor(decision);
|
|
393
403
|
const decidedAtMs = Date.parse(ledgerRow.decidedAt);
|
|
394
404
|
if (!Number.isFinite(decidedAtMs)) {
|
|
@@ -489,6 +499,7 @@ function extractToolCallNames(messages) {
|
|
|
489
499
|
}
|
|
490
500
|
function createPrivateRuntimeCallbacks() {
|
|
491
501
|
return {
|
|
502
|
+
settleOutputMode: "final_only",
|
|
492
503
|
onModelStart: () => { },
|
|
493
504
|
onModelStreamStart: () => { },
|
|
494
505
|
onTextChunk: () => { },
|
|
@@ -795,6 +806,32 @@ function buildHabitSurfacePolicy(origin, surface) {
|
|
|
795
806
|
lines.push("- use send_message for intentional contact; use surface only for a held return tied to an existing return obligation.");
|
|
796
807
|
return lines.join("\n");
|
|
797
808
|
}
|
|
809
|
+
function reduceHabitSessionToNoSend(habitSession) {
|
|
810
|
+
const deniedTools = new Set([
|
|
811
|
+
...(habitSession?.permissionEnvelope.deniedTools ?? []),
|
|
812
|
+
...(habitSession?.toolPolicy.grantedTools ?? []),
|
|
813
|
+
...(habitSession?.toolPolicy.deniedTools ?? []),
|
|
814
|
+
"send_message",
|
|
815
|
+
"surface",
|
|
816
|
+
]);
|
|
817
|
+
return {
|
|
818
|
+
...habitSession,
|
|
819
|
+
noSend: true,
|
|
820
|
+
permissionEnvelope: {
|
|
821
|
+
schemaVersion: 1,
|
|
822
|
+
canMessageOutward: false,
|
|
823
|
+
returnRoutes: [],
|
|
824
|
+
deniedTools: [...deniedTools],
|
|
825
|
+
warnings: [...(habitSession?.permissionEnvelope.warnings ?? [])],
|
|
826
|
+
},
|
|
827
|
+
toolPolicy: {
|
|
828
|
+
requestedTools: habitSession?.toolPolicy.requestedTools ?? null,
|
|
829
|
+
grantedTools: [],
|
|
830
|
+
deniedTools: [...deniedTools],
|
|
831
|
+
outwardMessagingAllowed: false,
|
|
832
|
+
},
|
|
833
|
+
};
|
|
834
|
+
}
|
|
798
835
|
async function runPrivateRuntimeTurn(options) {
|
|
799
836
|
const now = options?.now ?? (() => new Date());
|
|
800
837
|
const reason = options?.reason ?? "instinct";
|
|
@@ -873,37 +910,43 @@ async function runPrivateRuntimeTurn(options) {
|
|
|
873
910
|
let habitSurface = { family: true, originator: true, extra: [] };
|
|
874
911
|
if (preparedHabit) {
|
|
875
912
|
if (rsvpHabit && !preparedHabit.rsvp) {
|
|
876
|
-
|
|
913
|
+
const detail = preparedHabit.status === "degraded"
|
|
914
|
+
? preparedHabit.degradedDetail
|
|
915
|
+
: null;
|
|
916
|
+
throw new Error(`RSVP habit metadata is required before private runtime execution: ${detail ?? habitName}`);
|
|
877
917
|
}
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
habitTools = preparedHabit.tools;
|
|
882
|
-
habitOrigin = preparedHabit.origin;
|
|
883
|
-
habitSurface = preparedHabit.surface;
|
|
918
|
+
const blockedReason = (0, habit_lifecycle_guard_1.privateRuntimeHabitRejectionReason)(preparedHabit, "private-runtime");
|
|
919
|
+
if (blockedReason)
|
|
920
|
+
throw new Error(blockedReason);
|
|
884
921
|
}
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
habitLastRun = parsed.lastRun;
|
|
895
|
-
habitTools = parsed.tools;
|
|
896
|
-
habitOrigin = parsed.origin;
|
|
897
|
-
habitSurface = parsed.surface;
|
|
898
|
-
}
|
|
899
|
-
catch (error) {
|
|
900
|
-
if (rsvpHabit) {
|
|
901
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
902
|
-
throw new Error(`RSVP habit metadata is required before private runtime execution: ${reason}`);
|
|
903
|
-
}
|
|
904
|
-
// Habit file missing or unreadable
|
|
922
|
+
let currentHabit;
|
|
923
|
+
try {
|
|
924
|
+
const habitContent = fs.readFileSync(habitFilePath, "utf-8");
|
|
925
|
+
currentHabit = (0, habit_runtime_state_1.applyHabitRuntimeState)(agentRoot, (0, habit_parser_1.parseHabitFile)(habitContent, habitFilePath));
|
|
926
|
+
}
|
|
927
|
+
catch (error) {
|
|
928
|
+
const readReason = error instanceof Error ? error.message : String(error);
|
|
929
|
+
if (rsvpHabit) {
|
|
930
|
+
throw new Error(`RSVP habit metadata is required before private runtime execution: ${readReason}`);
|
|
905
931
|
}
|
|
932
|
+
const degraded = (0, habit_parser_1.createDegradedHabitFile)(habitFilePath, "read_error", "", readReason);
|
|
933
|
+
const blockedReason = (0, habit_lifecycle_guard_1.privateRuntimeHabitRejectionReason)(degraded, "private-runtime");
|
|
934
|
+
throw new Error(blockedReason);
|
|
935
|
+
}
|
|
936
|
+
if (rsvpHabit && !currentHabit.rsvp) {
|
|
937
|
+
const detail = currentHabit.status === "degraded" ? currentHabit.degradedDetail : null;
|
|
938
|
+
throw new Error(`RSVP habit metadata is required before private runtime execution: ${detail ?? habitName}`);
|
|
906
939
|
}
|
|
940
|
+
const currentBlockedReason = (0, habit_lifecycle_guard_1.privateRuntimeHabitRejectionReason)(currentHabit, "private-runtime");
|
|
941
|
+
if (currentBlockedReason)
|
|
942
|
+
throw new Error(currentBlockedReason);
|
|
943
|
+
const executableHabit = preparedHabit ?? currentHabit;
|
|
944
|
+
habitBody = executableHabit.body || undefined;
|
|
945
|
+
habitTitle = executableHabit.title || habitName;
|
|
946
|
+
habitLastRun = executableHabit.lastRun;
|
|
947
|
+
habitTools = executableHabit.tools;
|
|
948
|
+
habitOrigin = executableHabit.origin;
|
|
949
|
+
habitSurface = executableHabit.surface;
|
|
907
950
|
// If the habit file couldn't be read at all (no body, no title parsed), error message
|
|
908
951
|
if (habitBody === undefined && habitTitle === habitName) {
|
|
909
952
|
userContent = `habit "${habitName}" could not be read (file not found or unreadable). check habits/${habitName}.md exists.`;
|
|
@@ -1027,6 +1070,12 @@ async function runPrivateRuntimeTurn(options) {
|
|
|
1027
1070
|
meta: { habitName: options.habitName },
|
|
1028
1071
|
});
|
|
1029
1072
|
}
|
|
1073
|
+
if (options?.noSend === true) {
|
|
1074
|
+
habitToolsResolved = [];
|
|
1075
|
+
}
|
|
1076
|
+
const effectiveHabitSession = options?.noSend === true
|
|
1077
|
+
? reduceHabitSessionToNoSend(options.habitSession)
|
|
1078
|
+
: options?.habitSession;
|
|
1030
1079
|
const sessionLoader = {
|
|
1031
1080
|
loadOrCreate: async () => {
|
|
1032
1081
|
if (existingMessages.length > 0) {
|
|
@@ -1111,9 +1160,10 @@ async function runPrivateRuntimeTurn(options) {
|
|
|
1111
1160
|
toolContext: {
|
|
1112
1161
|
signin: async () => undefined,
|
|
1113
1162
|
delegatedOrigins: attentionQueue,
|
|
1114
|
-
...(options?.
|
|
1163
|
+
...(options?.noSend ? { noSend: true } : {}),
|
|
1164
|
+
...(effectiveHabitSession ? { habitSession: effectiveHabitSession } : {}),
|
|
1115
1165
|
},
|
|
1116
|
-
...(
|
|
1166
|
+
...(effectiveHabitSession ? { habitSession: effectiveHabitSession } : {}),
|
|
1117
1167
|
},
|
|
1118
1168
|
});
|
|
1119
1169
|
// Post-turn routeDelegatedCompletion removed: delivery is now inline via surface tool.
|
|
@@ -288,6 +288,7 @@ async function runSenseTurn(options) {
|
|
|
288
288
|
};
|
|
289
289
|
/* v8 ignore start — no-op callback stubs; only onTextChunk does real work (covered via mock) */
|
|
290
290
|
const callbacks = {
|
|
291
|
+
settleOutputMode: "retractable_buffer",
|
|
291
292
|
onModelStart: () => { },
|
|
292
293
|
onModelStreamStart: () => { },
|
|
293
294
|
onTextChunk: (chunk) => { pendingResponseText += chunk; },
|
package/dist/senses/teams.js
CHANGED
|
@@ -409,6 +409,7 @@ function createTeamsCallbacks(stream, controller, sendMessage, options) {
|
|
|
409
409
|
}
|
|
410
410
|
}
|
|
411
411
|
return {
|
|
412
|
+
settleOutputMode: "final_only",
|
|
412
413
|
onModelStart: () => {
|
|
413
414
|
if (hadRealOutput)
|
|
414
415
|
return; // real output already shown; don't overwrite with phrases
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouro.bot/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.725",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": ">=22"
|
|
6
|
+
},
|
|
4
7
|
"main": "dist/heart/daemon/ouro-entry.js",
|
|
5
8
|
"bin": {
|
|
6
9
|
"cli": "dist/heart/daemon/ouro-bot-entry.js",
|
|
@@ -61,6 +64,7 @@
|
|
|
61
64
|
"@ouro.bot/friends": "0.1.0-alpha.7",
|
|
62
65
|
"@types/react": "^17.0.91",
|
|
63
66
|
"@types/ws": "^8.18.1",
|
|
67
|
+
"better-sqlite3": "13.0.2",
|
|
64
68
|
"fast-glob": "^3.3.3",
|
|
65
69
|
"ink": "^3.2.0",
|
|
66
70
|
"mailparser": "^3.9.8",
|
|
@@ -77,6 +81,7 @@
|
|
|
77
81
|
},
|
|
78
82
|
"devDependencies": {
|
|
79
83
|
"@testing-library/react": "^16.3.2",
|
|
84
|
+
"@types/better-sqlite3": "7.6.13",
|
|
80
85
|
"@types/mailparser": "^3.4.6",
|
|
81
86
|
"@types/semver": "^7.7.1",
|
|
82
87
|
"@types/smtp-server": "^3.5.13",
|