@ouro.bot/cli 0.1.0-alpha.669 → 0.1.0-alpha.670
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/a2a/onboarding.js +2 -2
- package/dist/heart/core.js +3 -3
- package/dist/heart/cross-chat-delivery.js +2 -2
- package/dist/heart/daemon/cli-exec.js +3 -3
- package/dist/heart/daemon/cli-parse.js +2 -2
- package/dist/heart/daemon/daemon.js +2 -2
- package/dist/heart/daemon/runtime-logging.js +6 -0
- package/dist/heart/target-resolution.js +2 -2
- package/dist/mind/prompt.js +12 -14
- package/dist/mind/provenance-trust.js +2 -2
- package/dist/repertoire/guardrails.js +3 -3
- package/dist/repertoire/tools-a2a.js +6 -7
- package/dist/repertoire/tools-mail.js +2 -2
- package/dist/repertoire/tools-record.js +2 -2
- package/dist/repertoire/tools-trip.js +2 -2
- package/dist/senses/bluebubbles/index.js +9 -14
- package/dist/senses/cli.js +5 -8
- package/dist/senses/inner-dialog-worker.js +2 -2
- package/dist/senses/inner-dialog.js +3 -4
- package/dist/senses/shared-turn.js +5 -8
- package/dist/senses/teams.js +10 -14
- package/dist/senses/trust-gate.js +2 -2
- package/dist/senses/voice/outbound.js +2 -2
- package/dist/senses/voice/twilio-phone.js +9 -11
- package/package.json +2 -1
- package/dist/mind/friends/channel.js +0 -132
- package/dist/mind/friends/group-context.js +0 -144
- package/dist/mind/friends/resolver.js +0 -187
- package/dist/mind/friends/store-file.js +0 -247
- package/dist/mind/friends/store.js +0 -4
- package/dist/mind/friends/tokens.js +0 -26
- package/dist/mind/friends/trust-explanation.js +0 -74
- package/dist/mind/friends/types.js +0 -29
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.670",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Depend on the extracted @ouro.bot/friends package (git dependency) and remove the in-tree src/mind/friends/ copy; wire the package's observability seam into harness nerves."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.669",
|
|
6
12
|
"changes": [
|
package/dist/a2a/onboarding.js
CHANGED
|
@@ -38,13 +38,13 @@ const node_crypto_1 = require("node:crypto");
|
|
|
38
38
|
const path = __importStar(require("node:path"));
|
|
39
39
|
const identity_1 = require("../heart/identity");
|
|
40
40
|
const runtime_1 = require("../nerves/runtime");
|
|
41
|
-
const
|
|
41
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
42
42
|
const client_1 = require("./client");
|
|
43
43
|
function storeFor(options) {
|
|
44
44
|
if (options.store)
|
|
45
45
|
return options.store;
|
|
46
46
|
/* v8 ignore next -- default bundle root fallback is owned by identity path tests; CLI and onboarding tests inject explicit roots @preserve */
|
|
47
|
-
return new
|
|
47
|
+
return new friends_1.FileFriendStore(path.join(options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)(), `${options.agentName}.ouro`, "friends"));
|
|
48
48
|
}
|
|
49
49
|
function agentIdFor(_card, cardUrl) {
|
|
50
50
|
const parsed = new URL(cardUrl);
|
package/dist/heart/core.js
CHANGED
|
@@ -17,7 +17,7 @@ exports.runAgent = runAgent;
|
|
|
17
17
|
const config_1 = require("./config");
|
|
18
18
|
const identity_1 = require("./identity");
|
|
19
19
|
const tools_1 = require("../repertoire/tools");
|
|
20
|
-
const
|
|
20
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
21
21
|
const tools_2 = require("../repertoire/tools");
|
|
22
22
|
const runtime_1 = require("../nerves/runtime");
|
|
23
23
|
const context_1 = require("../mind/context");
|
|
@@ -722,7 +722,7 @@ function buildAuthFailureGuidance(provider, model, agentName, detail) {
|
|
|
722
722
|
return lines.join("\n");
|
|
723
723
|
}
|
|
724
724
|
async function runAgent(messages, callbacks, channel, signal, options) {
|
|
725
|
-
const facing = (0,
|
|
725
|
+
const facing = (0, friends_1.channelToFacing)(channel);
|
|
726
726
|
let providerRuntime = await getProviderRuntime(facing);
|
|
727
727
|
const provider = providerRuntime.id;
|
|
728
728
|
const toolChoiceRequired = options?.toolChoiceRequired ?? true;
|
|
@@ -858,7 +858,7 @@ async function runAgent(messages, callbacks, channel, signal, options) {
|
|
|
858
858
|
}
|
|
859
859
|
catch { /* unsupported */ }
|
|
860
860
|
const toolPreferences = currentContext?.friend?.toolPreferences;
|
|
861
|
-
const baseTools = options?.tools ?? (0, tools_1.getToolsForChannel)(channel ? (0,
|
|
861
|
+
const baseTools = options?.tools ?? (0, tools_1.getToolsForChannel)(channel ? (0, friends_1.getChannelCapabilities)(channel) : undefined, toolPreferences && Object.keys(toolPreferences).length > 0 ? toolPreferences : undefined, currentContext, providerRuntime.capabilities, options?.mcpManager, providerRuntime.model);
|
|
862
862
|
// Augment tool context with reasoning effort controls from provider
|
|
863
863
|
const baseToolContext = options?.toolContext
|
|
864
864
|
?? (options?.orientationFrame ? { signin: async () => undefined, orientationFrame: options.orientationFrame } : undefined);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.deliverCrossChatMessage = deliverCrossChatMessage;
|
|
4
|
-
const
|
|
4
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
5
5
|
const runtime_1 = require("../nerves/runtime");
|
|
6
6
|
function buildPendingEnvelope(request, agentName, now) {
|
|
7
7
|
return {
|
|
@@ -24,7 +24,7 @@ function queueForLater(request, deps, detail, rawStatus = "queued_for_later") {
|
|
|
24
24
|
function isExplicitlyAuthorized(request) {
|
|
25
25
|
return request.intent === "explicit_cross_chat"
|
|
26
26
|
&& Boolean(request.authorizingSession)
|
|
27
|
-
&& (0,
|
|
27
|
+
&& (0, friends_1.isTrustedLevel)(request.authorizingSession?.trustLevel);
|
|
28
28
|
}
|
|
29
29
|
async function deliverCrossChatMessage(request, deps) {
|
|
30
30
|
(0, runtime_1.emitNervesEvent)({
|
|
@@ -57,7 +57,7 @@ const path = __importStar(require("path"));
|
|
|
57
57
|
const semver = __importStar(require("semver"));
|
|
58
58
|
const identity_1 = require("../identity");
|
|
59
59
|
const runtime_1 = require("../../nerves/runtime");
|
|
60
|
-
const
|
|
60
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
61
61
|
const runtime_metadata_1 = require("./runtime-metadata");
|
|
62
62
|
const runtime_mode_1 = require("./runtime-mode");
|
|
63
63
|
const platform_1 = require("../platform");
|
|
@@ -3910,7 +3910,7 @@ async function queueMailOperationTargetNotification(agentName, content, deps) {
|
|
|
3910
3910
|
sessionsDir,
|
|
3911
3911
|
friendsDir,
|
|
3912
3912
|
agentName,
|
|
3913
|
-
friendStore: new
|
|
3913
|
+
friendStore: new friends_1.FileFriendStore(friendsDir),
|
|
3914
3914
|
});
|
|
3915
3915
|
const target = candidates.find((candidate) => candidate.delivery.mode !== "blocked");
|
|
3916
3916
|
if (!target)
|
|
@@ -7043,7 +7043,7 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
7043
7043
|
const friendsDir = agentName
|
|
7044
7044
|
? path.join(deps.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)(), `${agentName}.ouro`, "friends")
|
|
7045
7045
|
: path.join(deps.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)(), "friends");
|
|
7046
|
-
store = new
|
|
7046
|
+
store = new friends_1.FileFriendStore(friendsDir);
|
|
7047
7047
|
}
|
|
7048
7048
|
/* v8 ignore stop */
|
|
7049
7049
|
const message = await executeFriendCommand(command, store);
|
|
@@ -14,7 +14,7 @@ exports.usage = usage;
|
|
|
14
14
|
exports.inferAgentNameFromRemote = inferAgentNameFromRemote;
|
|
15
15
|
exports.parseMcpServeCommand = parseMcpServeCommand;
|
|
16
16
|
exports.parseOuroCommand = parseOuroCommand;
|
|
17
|
-
const
|
|
17
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
18
18
|
const cli_help_1 = require("./cli-help");
|
|
19
19
|
const cli_desk_1 = require("./cli-desk");
|
|
20
20
|
const flight_recorder_1 = require("../../arc/flight-recorder");
|
|
@@ -340,7 +340,7 @@ function parseLinkCommand(args, kind = "friend.link") {
|
|
|
340
340
|
if (!friendId || !providerRaw || !externalId) {
|
|
341
341
|
throw new Error(`Usage\n${usage()}`);
|
|
342
342
|
}
|
|
343
|
-
if (!(0,
|
|
343
|
+
if (!(0, friends_1.isIdentityProvider)(providerRaw)) {
|
|
344
344
|
throw new Error(`Unknown identity provider '${providerRaw}'. Use aad|local|teams-conversation|imessage-handle|email-address|a2a-agent.`);
|
|
345
345
|
}
|
|
346
346
|
return {
|
|
@@ -59,7 +59,7 @@ const update_checker_1 = require("../versioning/update-checker");
|
|
|
59
59
|
const child_process_1 = require("child_process");
|
|
60
60
|
const pending_1 = require("../../mind/pending");
|
|
61
61
|
const agent_service_1 = require("./agent-service");
|
|
62
|
-
const
|
|
62
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
63
63
|
const mcp_manager_1 = require("../../repertoire/mcp-manager");
|
|
64
64
|
const mailbox_http_1 = require("../mailbox/mailbox-http");
|
|
65
65
|
const mailbox_types_1 = require("../mailbox/mailbox-types");
|
|
@@ -869,7 +869,7 @@ class OuroDaemon {
|
|
|
869
869
|
}
|
|
870
870
|
}
|
|
871
871
|
/** Drains per-sense pending dirs for always-on senses across all agents. */
|
|
872
|
-
static ALWAYS_ON_SENSES = new Set((0,
|
|
872
|
+
static ALWAYS_ON_SENSES = new Set((0, friends_1.getAlwaysOnSenseNames)());
|
|
873
873
|
async drainPendingSenseMessages() {
|
|
874
874
|
if (!fs.existsSync(this.bundlesRoot))
|
|
875
875
|
return;
|
|
@@ -37,6 +37,7 @@ exports.configureDaemonRuntimeLogger = configureDaemonRuntimeLogger;
|
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const nerves_1 = require("../../nerves");
|
|
40
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
40
41
|
const runtime_1 = require("../../nerves/runtime");
|
|
41
42
|
const identity_1 = require("../identity");
|
|
42
43
|
const ouro_version_manager_1 = require("../versioning/ouro-version-manager");
|
|
@@ -151,6 +152,11 @@ function configureDaemonRuntimeLogger(processName, options = {}) {
|
|
|
151
152
|
sinks,
|
|
152
153
|
});
|
|
153
154
|
(0, runtime_1.setRuntimeLogger)(logger);
|
|
155
|
+
// Wire the @ouro.bot/friends package's observability seam to the harness's real
|
|
156
|
+
// nerves emitter. The package ships a no-op emitNervesEvent by default; this
|
|
157
|
+
// injection forwards the extracted friend model's events into harness nerves so
|
|
158
|
+
// observability isn't lost when friends moved out of the tree. Idempotent.
|
|
159
|
+
(0, friends_1.setNervesEmitter)(runtime_1.emitNervesEvent);
|
|
154
160
|
(0, runtime_1.emitNervesEvent)({
|
|
155
161
|
component: "daemon",
|
|
156
162
|
event: "daemon.runtime_logger_configured",
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.listTargetSessionCandidates = listTargetSessionCandidates;
|
|
4
4
|
exports.formatTargetSessionCandidates = formatTargetSessionCandidates;
|
|
5
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
5
6
|
const session_transcript_1 = require("./session-transcript");
|
|
6
7
|
const session_activity_1 = require("./session-activity");
|
|
7
|
-
const trust_explanation_1 = require("../mind/friends/trust-explanation");
|
|
8
8
|
const runtime_1 = require("../nerves/runtime");
|
|
9
9
|
function synthesizeFriendRecord(candidate) {
|
|
10
10
|
return {
|
|
@@ -67,7 +67,7 @@ async function listTargetSessionCandidates(input) {
|
|
|
67
67
|
const candidates = [];
|
|
68
68
|
for (const entry of activity) {
|
|
69
69
|
const friend = await input.friendStore.get(entry.friendId) ?? synthesizeFriendRecord(entry);
|
|
70
|
-
const trust = (0,
|
|
70
|
+
const trust = (0, friends_1.describeTrustContext)({
|
|
71
71
|
friend,
|
|
72
72
|
channel: entry.channel,
|
|
73
73
|
});
|
package/dist/mind/prompt.js
CHANGED
|
@@ -69,9 +69,7 @@ const runtime_cwd_1 = require("../heart/runtime-cwd");
|
|
|
69
69
|
const config_1 = require("../heart/config");
|
|
70
70
|
const runtime_credentials_1 = require("../heart/runtime-credentials");
|
|
71
71
|
const runtime_mode_1 = require("../heart/daemon/runtime-mode");
|
|
72
|
-
const
|
|
73
|
-
const trust_explanation_1 = require("./friends/trust-explanation");
|
|
74
|
-
const channel_1 = require("./friends/channel");
|
|
72
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
75
73
|
const runtime_1 = require("../nerves/runtime");
|
|
76
74
|
const bundle_manifest_1 = require("./bundle-manifest");
|
|
77
75
|
const first_impressions_1 = require("./first-impressions");
|
|
@@ -548,7 +546,7 @@ function providerSection(channel, options) {
|
|
|
548
546
|
if (options?.providerVisibility) {
|
|
549
547
|
return `## my provider\n${(0, provider_visibility_1.formatAgentProviderVisibilityForPrompt)(options.providerVisibility)}`;
|
|
550
548
|
}
|
|
551
|
-
return `## my provider\n${(0, core_1.getProviderDisplayLabel)((0,
|
|
549
|
+
return `## my provider\n${(0, core_1.getProviderDisplayLabel)((0, friends_1.channelToFacing)(channel))}`;
|
|
552
550
|
}
|
|
553
551
|
function dateSection() {
|
|
554
552
|
const now = new Date();
|
|
@@ -583,7 +581,7 @@ function uniqueToolsByName(tools) {
|
|
|
583
581
|
return unique;
|
|
584
582
|
}
|
|
585
583
|
function toolsSection(channel, options, context) {
|
|
586
|
-
const channelTools = options?.tools ?? (0, tools_1.getToolsForChannel)((0,
|
|
584
|
+
const channelTools = options?.tools ?? (0, tools_1.getToolsForChannel)((0, friends_1.getChannelCapabilities)(channel), undefined, context, options?.providerCapabilities, undefined, options?.chatModel);
|
|
587
585
|
const activeTools = channel === "inner"
|
|
588
586
|
? uniqueToolsByName([
|
|
589
587
|
...channelTools,
|
|
@@ -610,7 +608,7 @@ function toolRestrictionSection(context) {
|
|
|
610
608
|
lines.push(`certain paths (.git, secrets) are protected from writes.`);
|
|
611
609
|
lines.push(`destructive shell commands (rm -rf /, etc.) are always blocked.`);
|
|
612
610
|
// Trust-level guardrails only relevant for untrusted on remote channels
|
|
613
|
-
if (context?.friend && (0,
|
|
611
|
+
if (context?.friend && (0, friends_1.isRemoteChannel)(context.channel) && !(0, friends_1.isTrustedLevel)(context.friend.trustLevel)) {
|
|
614
612
|
lines.push(``);
|
|
615
613
|
lines.push(`some operations are guardrailed based on how well i know someone.`);
|
|
616
614
|
lines.push(`if something i try is blocked, i get a clear reason — i relay it warmly, not as a policy error.`);
|
|
@@ -636,7 +634,7 @@ function trustContextSection(context) {
|
|
|
636
634
|
/* v8 ignore next -- inner channel not reachable in unit tests @preserve */
|
|
637
635
|
if (channelName === "cli" || channelName === "inner")
|
|
638
636
|
return "";
|
|
639
|
-
const explanation = (0,
|
|
637
|
+
const explanation = (0, friends_1.describeTrustContext)({
|
|
640
638
|
friend: context.friend,
|
|
641
639
|
channel: channelName,
|
|
642
640
|
isGroupChat: context.isGroupChat,
|
|
@@ -775,10 +773,10 @@ function pendingMessagesSection(options) {
|
|
|
775
773
|
return lines.join("\n");
|
|
776
774
|
}
|
|
777
775
|
function tripPromptAccessAllowed(channel, context) {
|
|
778
|
-
const senseType = (0,
|
|
776
|
+
const senseType = (0, friends_1.getChannelCapabilities)(channel).senseType;
|
|
779
777
|
if (senseType === "local" || senseType === "internal")
|
|
780
778
|
return true;
|
|
781
|
-
return !!context?.friend && (0,
|
|
779
|
+
return !!context?.friend && (0, friends_1.isTrustedLevel)(context.friend.trustLevel);
|
|
782
780
|
}
|
|
783
781
|
function tripRecordDateRange(trip) {
|
|
784
782
|
if (trip.startDate && trip.endDate)
|
|
@@ -1263,7 +1261,7 @@ function channelNatureSection(capabilities) {
|
|
|
1263
1261
|
return "## channel nature\nthis is an org-gated channel — i know everyone here is already part of the organization.";
|
|
1264
1262
|
}
|
|
1265
1263
|
function groupChatParticipationSection(context) {
|
|
1266
|
-
if (!context?.isGroupChat || !(0,
|
|
1264
|
+
if (!context?.isGroupChat || !(0, friends_1.isRemoteChannel)(context.channel))
|
|
1267
1265
|
return "";
|
|
1268
1266
|
return `## group chat participation
|
|
1269
1267
|
group chats are conversations between people. i'm one participant, not the host.
|
|
@@ -1279,7 +1277,7 @@ observe must be the sole tool call in the turn (same rule as settle).
|
|
|
1279
1277
|
when unsure whether to chime in, i lean toward silence rather than noise.`;
|
|
1280
1278
|
}
|
|
1281
1279
|
function feedbackSignalSection(context) {
|
|
1282
|
-
if (!context || !(0,
|
|
1280
|
+
if (!context || !(0, friends_1.isRemoteChannel)(context.channel))
|
|
1283
1281
|
return "";
|
|
1284
1282
|
if (context.isGroupChat) {
|
|
1285
1283
|
return `## feedback signals
|
|
@@ -1312,7 +1310,7 @@ my approach. the reaction tells me something about how this person wants
|
|
|
1312
1310
|
to be talked to.`;
|
|
1313
1311
|
}
|
|
1314
1312
|
function mixedTrustGroupSection(context) {
|
|
1315
|
-
if (!context?.friend || !(0,
|
|
1313
|
+
if (!context?.friend || !(0, friends_1.isRemoteChannel)(context.channel))
|
|
1316
1314
|
return "";
|
|
1317
1315
|
if (!context.isGroupChat)
|
|
1318
1316
|
return "";
|
|
@@ -1360,7 +1358,7 @@ function channelHasCodingTools(channel, providerCapabilities) {
|
|
|
1360
1358
|
// Coding tools are capability/integration-gated, not vision-gated — passing
|
|
1361
1359
|
// undefined for chatModel keeps describe_image out of the scan (which is
|
|
1362
1360
|
// BB-scoped anyway) without affecting the coding-tool presence check.
|
|
1363
|
-
const tools = (0, tools_1.getToolsForChannel)((0,
|
|
1361
|
+
const tools = (0, tools_1.getToolsForChannel)((0, friends_1.getChannelCapabilities)(channel), undefined, undefined, providerCapabilities);
|
|
1364
1362
|
const codingToolNames = new Set(["edit_file", "write_file", "shell", "coding_spawn"]);
|
|
1365
1363
|
return tools.some((t) => codingToolNames.has(t.function.name));
|
|
1366
1364
|
}
|
|
@@ -1385,7 +1383,7 @@ async function buildSystem(channel = "cli", options, context) {
|
|
|
1385
1383
|
"# my body & environment",
|
|
1386
1384
|
bodyMapSection((0, identity_1.getAgentName)(), channel),
|
|
1387
1385
|
runtimeInfoSection(channel, options),
|
|
1388
|
-
channelNatureSection((0,
|
|
1386
|
+
channelNatureSection((0, friends_1.getChannelCapabilities)(channel)),
|
|
1389
1387
|
providerSection(channel, options),
|
|
1390
1388
|
// Group 3: my tools & capabilities
|
|
1391
1389
|
"# my tools & capabilities",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.classifyProvenanceTrust = classifyProvenanceTrust;
|
|
4
|
-
const
|
|
4
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
5
5
|
/**
|
|
6
6
|
* Classify a diary entry's provenance into a trust category.
|
|
7
7
|
*
|
|
@@ -19,7 +19,7 @@ function classifyProvenanceTrust(provenance) {
|
|
|
19
19
|
if (!provenance.channel && !provenance.friendId)
|
|
20
20
|
return "self";
|
|
21
21
|
// If there's a trust level from a friend, classify by trust
|
|
22
|
-
if (provenance.trust && (0,
|
|
22
|
+
if (provenance.trust && (0, friends_1.isTrustedLevel)(provenance.trust))
|
|
23
23
|
return "trusted";
|
|
24
24
|
// Everything else is external (non-inner channels without trusted friend)
|
|
25
25
|
return "external";
|
|
@@ -37,7 +37,7 @@ exports.OURO_CLI_TRUST_MANIFEST = void 0;
|
|
|
37
37
|
exports.guardInvocation = guardInvocation;
|
|
38
38
|
const fs = __importStar(require("node:fs"));
|
|
39
39
|
const path = __importStar(require("node:path"));
|
|
40
|
-
const
|
|
40
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
41
41
|
const runtime_1 = require("../nerves/runtime");
|
|
42
42
|
const store_1 = require("../commerce/store");
|
|
43
43
|
const deny = (reason) => ({ allowed: false, reason });
|
|
@@ -325,7 +325,7 @@ function checkCredentialTrustGuardrails(toolName, context) {
|
|
|
325
325
|
return deny(REASONS.needsTrust);
|
|
326
326
|
}
|
|
327
327
|
if (CREDENTIAL_TRUSTED_TOOLS.has(toolName) || TRAVEL_TRUSTED_TOOLS.has(toolName) || A2A_TRUSTED_TOOLS.has(toolName)) {
|
|
328
|
-
if ((0,
|
|
328
|
+
if ((0, friends_1.isTrustedLevel)(context.trustLevel))
|
|
329
329
|
return allow;
|
|
330
330
|
return deny(REASONS.needsTrust);
|
|
331
331
|
}
|
|
@@ -381,7 +381,7 @@ function checkTrustLevelGuardrails(toolName, args, context) {
|
|
|
381
381
|
return mcpResult;
|
|
382
382
|
}
|
|
383
383
|
// Trusted levels (family/friend) — no further trust guardrails. Undefined defaults to friend.
|
|
384
|
-
if ((0,
|
|
384
|
+
if ((0, friends_1.isTrustedLevel)(context.trustLevel))
|
|
385
385
|
return allow;
|
|
386
386
|
if (toolName === "shell") {
|
|
387
387
|
return checkShellTrustGuardrails(args.command || "", context.trustLevel);
|
|
@@ -37,8 +37,7 @@ exports.a2aToolDefinitions = void 0;
|
|
|
37
37
|
const path = __importStar(require("node:path"));
|
|
38
38
|
const identity_1 = require("../heart/identity");
|
|
39
39
|
const runtime_credentials_1 = require("../heart/runtime-credentials");
|
|
40
|
-
const
|
|
41
|
-
const store_file_1 = require("../mind/friends/store-file");
|
|
40
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
42
41
|
const runtime_1 = require("../nerves/runtime");
|
|
43
42
|
const client_1 = require("../a2a/client");
|
|
44
43
|
const outboundTaskTokens = new Map();
|
|
@@ -75,13 +74,13 @@ function storeFor(ctx) {
|
|
|
75
74
|
return ctx.friendStore;
|
|
76
75
|
/* v8 ignore next -- no-agentRoot fallback depends on process argv; normal tool calls inject agentRoot @preserve */
|
|
77
76
|
if (ctx?.agentRoot)
|
|
78
|
-
return new
|
|
79
|
-
return new
|
|
77
|
+
return new friends_1.FileFriendStore(path.join(ctx.agentRoot, "friends"));
|
|
78
|
+
return new friends_1.FileFriendStore(path.join((0, identity_1.getAgentRoot)(), "friends"));
|
|
80
79
|
}
|
|
81
80
|
function requireTrustedRequester(ctx) {
|
|
82
81
|
if (!ctx?.context?.friend?.id)
|
|
83
82
|
return "no friend context — cannot use A2A tools.";
|
|
84
|
-
if (!(0,
|
|
83
|
+
if (!(0, friends_1.isTrustedLevel)(ctx.context.friend.trustLevel))
|
|
85
84
|
return "A2A tools require friend or family trust.";
|
|
86
85
|
return null;
|
|
87
86
|
}
|
|
@@ -207,7 +206,7 @@ exports.a2aToolDefinitions = [
|
|
|
207
206
|
const peer = await storeFor(ctx).get(args.friend_id);
|
|
208
207
|
if (!peer || !isA2APeer(peer))
|
|
209
208
|
return `A2A peer not found: ${args.friend_id}`;
|
|
210
|
-
if (!(0,
|
|
209
|
+
if (!(0, friends_1.isTrustedLevel)(peer.trustLevel))
|
|
211
210
|
return "target A2A peer must be friend or family trust before outbound messages.";
|
|
212
211
|
try {
|
|
213
212
|
const endpoint = await resolveA2AEndpoint(peer);
|
|
@@ -259,7 +258,7 @@ exports.a2aToolDefinitions = [
|
|
|
259
258
|
const peer = await storeFor(ctx).get(args.friend_id);
|
|
260
259
|
if (!peer || !isA2APeer(peer))
|
|
261
260
|
return `A2A peer not found: ${args.friend_id}`;
|
|
262
|
-
if (!(0,
|
|
261
|
+
if (!(0, friends_1.isTrustedLevel)(peer.trustLevel))
|
|
263
262
|
return "target A2A peer must be friend or family trust before task lookup.";
|
|
264
263
|
try {
|
|
265
264
|
const endpoint = await resolveA2AEndpoint(peer);
|
|
@@ -9,7 +9,7 @@ exports.mergeCachedMailSearchDocuments = mergeCachedMailSearchDocuments;
|
|
|
9
9
|
exports.searchSuccessfulImportArchives = searchSuccessfulImportArchives;
|
|
10
10
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
11
11
|
const node_crypto_1 = require("node:crypto");
|
|
12
|
-
const
|
|
12
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
13
13
|
const file_store_1 = require("../mailroom/file-store");
|
|
14
14
|
const reader_1 = require("../mailroom/reader");
|
|
15
15
|
const outbound_1 = require("../mailroom/outbound");
|
|
@@ -29,7 +29,7 @@ const MAIL_SEARCH_INDEX_FETCH_CONCURRENCY = 80;
|
|
|
29
29
|
const MAIL_SEARCH_INDEX_BATCH_SIZE = 500;
|
|
30
30
|
function trustAllowsMailRead(ctx) {
|
|
31
31
|
const trustLevel = ctx?.context?.friend?.trustLevel;
|
|
32
|
-
const allowed = trustLevel === undefined || (0,
|
|
32
|
+
const allowed = trustLevel === undefined || (0, friends_1.isTrustedLevel)(trustLevel);
|
|
33
33
|
(0, runtime_1.emitNervesEvent)({
|
|
34
34
|
component: "repertoire",
|
|
35
35
|
event: "repertoire.mail_tool_access",
|
|
@@ -40,7 +40,7 @@ const session_events_1 = require("../heart/session-events");
|
|
|
40
40
|
const embedding_provider_1 = require("../mind/embedding-provider");
|
|
41
41
|
const note_search_1 = require("../mind/note-search");
|
|
42
42
|
const record_paths_1 = require("../mind/record-paths");
|
|
43
|
-
const
|
|
43
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
44
44
|
const runtime_1 = require("../nerves/runtime");
|
|
45
45
|
const identity_1 = require("../heart/identity");
|
|
46
46
|
const NOTES_INDEX_VERSION = 1;
|
|
@@ -60,7 +60,7 @@ function hasRecordReadTrust(ctx) {
|
|
|
60
60
|
if (hasSelfTrust(ctx))
|
|
61
61
|
return true;
|
|
62
62
|
const friend = ctx?.context?.friend;
|
|
63
|
-
return Boolean(friend) && (0,
|
|
63
|
+
return Boolean(friend) && (0, friends_1.isTrustedLevel)(friend?.trustLevel);
|
|
64
64
|
}
|
|
65
65
|
function bundleRelativeLocator(filePath, ctx) {
|
|
66
66
|
const agentRoot = ctx?.agentRoot ?? (0, identity_1.getAgentRoot)();
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.tripToolDefinitions = void 0;
|
|
4
4
|
const node_crypto_1 = require("node:crypto");
|
|
5
|
-
const
|
|
5
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
6
6
|
const runtime_1 = require("../nerves/runtime");
|
|
7
7
|
const store_1 = require("../trips/store");
|
|
8
8
|
const core_1 = require("../trips/core");
|
|
9
9
|
const identity_1 = require("../heart/identity");
|
|
10
10
|
function trustAllowsTripAccess(ctx) {
|
|
11
11
|
const trustLevel = ctx?.context?.friend?.trustLevel;
|
|
12
|
-
return trustLevel === undefined || (0,
|
|
12
|
+
return trustLevel === undefined || (0, friends_1.isTrustedLevel)(trustLevel);
|
|
13
13
|
}
|
|
14
14
|
function isRecord(value) {
|
|
15
15
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
@@ -65,12 +65,7 @@ const identity_1 = require("../../heart/identity");
|
|
|
65
65
|
const runtime_cwd_1 = require("../../heart/runtime-cwd");
|
|
66
66
|
const turn_coordinator_1 = require("../../heart/turn-coordinator");
|
|
67
67
|
const context_1 = require("../../mind/context");
|
|
68
|
-
const
|
|
69
|
-
const group_context_1 = require("../../mind/friends/group-context");
|
|
70
|
-
const resolver_1 = require("../../mind/friends/resolver");
|
|
71
|
-
const store_file_1 = require("../../mind/friends/store-file");
|
|
72
|
-
const types_1 = require("../../mind/friends/types");
|
|
73
|
-
const channel_1 = require("../../mind/friends/channel");
|
|
68
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
74
69
|
const pending_1 = require("../../mind/pending");
|
|
75
70
|
const prompt_1 = require("../../mind/prompt");
|
|
76
71
|
const mcp_manager_1 = require("../../repertoire/mcp-manager");
|
|
@@ -247,11 +242,11 @@ const defaultDeps = {
|
|
|
247
242
|
postTurnTrim: context_1.postTurnTrim,
|
|
248
243
|
deferPostTurnPersist: context_1.deferPostTurnPersist,
|
|
249
244
|
sessionPath: config_1.sessionPath,
|
|
250
|
-
accumulateFriendTokens:
|
|
245
|
+
accumulateFriendTokens: friends_1.accumulateFriendTokens,
|
|
251
246
|
createClient: () => (0, client_1.createBlueBubblesClient)(),
|
|
252
247
|
recordMutation: mutation_log_1.recordBlueBubblesMutation,
|
|
253
|
-
createFriendStore: () => new
|
|
254
|
-
createFriendResolver: (store, params) => new
|
|
248
|
+
createFriendStore: () => new friends_1.FileFriendStore(path.join((0, identity_1.getAgentRoot)(), "friends")),
|
|
249
|
+
createFriendResolver: (store, params) => new friends_1.FriendResolver(store, params),
|
|
255
250
|
createServer: http.createServer,
|
|
256
251
|
getOwnHandles: () => [...(0, config_1.getBlueBubblesConfig)().ownHandles, ...discoveredOwnHandles],
|
|
257
252
|
};
|
|
@@ -1226,7 +1221,7 @@ async function handleBlueBubblesNormalizedEvent(event, resolvedDeps, source, opt
|
|
|
1226
1221
|
}
|
|
1227
1222
|
}
|
|
1228
1223
|
if (event.kind === "message" && event.chat.isGroup) {
|
|
1229
|
-
await (0,
|
|
1224
|
+
await (0, friends_1.upsertGroupContextParticipants)({
|
|
1230
1225
|
store,
|
|
1231
1226
|
participants: (event.chat.participantHandles ?? []).map((externalId) => ({
|
|
1232
1227
|
provider: "imessage-handle",
|
|
@@ -1281,7 +1276,7 @@ async function handleBlueBubblesNormalizedEvent(event, resolvedDeps, source, opt
|
|
|
1281
1276
|
let timeoutReason = null;
|
|
1282
1277
|
// BB-specific tool context wrappers
|
|
1283
1278
|
const summarize = (0, core_1.createSummarize)("human");
|
|
1284
|
-
const bbCapabilities = (0,
|
|
1279
|
+
const bbCapabilities = (0, friends_1.getChannelCapabilities)("bluebubbles");
|
|
1285
1280
|
const pendingDir = (0, pending_1.getPendingDir)(resolvedDeps.getAgentName(), friendId, "bluebubbles", event.chat.sessionKey);
|
|
1286
1281
|
// ── Compute trust gate context for group/acquaintance rules ─────
|
|
1287
1282
|
const groupHasFamilyMember = await checkGroupHasFamilyMember(store, event);
|
|
@@ -2394,8 +2389,8 @@ async function sendProactiveBlueBubblesMessageToSession(params, deps = {}) {
|
|
|
2394
2389
|
return { delivered: false, reason: "friend_not_found" };
|
|
2395
2390
|
}
|
|
2396
2391
|
const explicitCrossChatAuthorized = params.intent === "explicit_cross_chat"
|
|
2397
|
-
&&
|
|
2398
|
-
if (!explicitCrossChatAuthorized && !
|
|
2392
|
+
&& friends_1.TRUSTED_LEVELS.has(params.authorizingSession?.trustLevel ?? "stranger");
|
|
2393
|
+
if (!explicitCrossChatAuthorized && !friends_1.TRUSTED_LEVELS.has(friend.trustLevel ?? "stranger")) {
|
|
2399
2394
|
(0, runtime_1.emitNervesEvent)({
|
|
2400
2395
|
component: "senses",
|
|
2401
2396
|
event: "senses.bluebubbles_proactive_trust_skip",
|
|
@@ -2599,7 +2594,7 @@ async function drainAndSendPendingBlueBubbles(deps = {}, pendingRoot) {
|
|
|
2599
2594
|
});
|
|
2600
2595
|
continue;
|
|
2601
2596
|
}
|
|
2602
|
-
if (!
|
|
2597
|
+
if (!friends_1.TRUSTED_LEVELS.has(friend.trustLevel ?? "stranger")) {
|
|
2603
2598
|
result.skipped++;
|
|
2604
2599
|
try {
|
|
2605
2600
|
fs.unlinkSync(filePath);
|
package/dist/senses/cli.js
CHANGED
|
@@ -63,14 +63,11 @@ const commands_1 = require("./commands");
|
|
|
63
63
|
const identity_1 = require("../heart/identity");
|
|
64
64
|
const mcp_manager_1 = require("../repertoire/mcp-manager");
|
|
65
65
|
const nerves_1 = require("../nerves");
|
|
66
|
-
const
|
|
67
|
-
const resolver_1 = require("../mind/friends/resolver");
|
|
68
|
-
const tokens_1 = require("../mind/friends/tokens");
|
|
66
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
69
67
|
const cli_logging_1 = require("../nerves/cli-logging");
|
|
70
68
|
const runtime_1 = require("../nerves/runtime");
|
|
71
69
|
const trust_gate_1 = require("./trust-gate");
|
|
72
70
|
const pipeline_1 = require("./pipeline");
|
|
73
|
-
const channel_1 = require("../mind/friends/channel");
|
|
74
71
|
const session_lock_1 = require("./session-lock");
|
|
75
72
|
const update_hooks_1 = require("../heart/versioning/update-hooks");
|
|
76
73
|
const bundle_meta_1 = require("../heart/daemon/hooks/bundle-meta");
|
|
@@ -948,10 +945,10 @@ async function main(agentName, options) {
|
|
|
948
945
|
(0, core_1.getProvider)("human");
|
|
949
946
|
// Resolve context kernel (identity + channel) for CLI
|
|
950
947
|
const friendsPath = path.join((0, identity_1.getAgentRoot)(), "friends");
|
|
951
|
-
const friendStore = new
|
|
948
|
+
const friendStore = new friends_1.FileFriendStore(friendsPath);
|
|
952
949
|
const username = os.userInfo().username;
|
|
953
950
|
const localExternalId = username;
|
|
954
|
-
const resolver = new
|
|
951
|
+
const resolver = new friends_1.FriendResolver(friendStore, {
|
|
955
952
|
provider: "local",
|
|
956
953
|
externalId: localExternalId,
|
|
957
954
|
displayName: username,
|
|
@@ -989,7 +986,7 @@ async function main(agentName, options) {
|
|
|
989
986
|
// Repair any orphaned tool calls from a crash mid-turn
|
|
990
987
|
(0, core_1.repairOrphanedToolCalls)(sessionMessages);
|
|
991
988
|
// Per-turn pipeline input: CLI capabilities and pending dir
|
|
992
|
-
const cliCapabilities = (0,
|
|
989
|
+
const cliCapabilities = (0, friends_1.getChannelCapabilities)("cli");
|
|
993
990
|
const currentAgentName = (0, identity_1.getAgentName)();
|
|
994
991
|
const pendingDir = (0, pending_1.getPendingDir)(currentAgentName, friendId, "cli", "session");
|
|
995
992
|
const summarize = (0, core_1.createSummarize)("human");
|
|
@@ -1075,7 +1072,7 @@ async function main(agentName, options) {
|
|
|
1075
1072
|
sessionEvents = events.length > 0 ? events : sessionEvents;
|
|
1076
1073
|
});
|
|
1077
1074
|
},
|
|
1078
|
-
accumulateFriendTokens:
|
|
1075
|
+
accumulateFriendTokens: friends_1.accumulateFriendTokens,
|
|
1079
1076
|
signal,
|
|
1080
1077
|
runAgentOptions: {
|
|
1081
1078
|
toolChoiceRequired: (0, commands_1.getToolChoiceRequired)(),
|
|
@@ -47,7 +47,7 @@ const habit_runtime_state_1 = require("../heart/habits/habit-runtime-state");
|
|
|
47
47
|
const habit_session_1 = require("../heart/habits/habit-session");
|
|
48
48
|
const flight_recorder_1 = require("../arc/flight-recorder");
|
|
49
49
|
const habit_session_summary_1 = require("../heart/habits/habit-session-summary");
|
|
50
|
-
const
|
|
50
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
51
51
|
const tools_base_1 = require("../repertoire/tools-base");
|
|
52
52
|
const tools_surface_1 = require("../repertoire/tools-surface");
|
|
53
53
|
const tools_1 = require("../repertoire/tools");
|
|
@@ -205,7 +205,7 @@ async function prepareHabitRun(habitName, trigger, startedAt) {
|
|
|
205
205
|
const operationId = habit.continuity.mode === "stateful" ? `habit:${habit.name}` : null;
|
|
206
206
|
const priorSessionSummary = readPriorSessionSummary(agentRoot, operationId);
|
|
207
207
|
const paths = (0, habit_session_1.createHabitSessionPaths)(agentRoot, runId, habit.name);
|
|
208
|
-
const friendStore = new
|
|
208
|
+
const friendStore = new friends_1.FileFriendStore(path.join(agentRoot, "friends"));
|
|
209
209
|
const permissionEnvelope = await (0, habit_session_1.normalizeHabitPermissionEnvelope)(habit, { agentRoot, friendStore });
|
|
210
210
|
const toolPolicy = (0, habit_session_1.filterHabitToolsForEnvelope)([...tools_base_1.baseToolDefinitions, tools_surface_1.surfaceToolDefinition], habit.tools ?? null, permissionEnvelope, riskProfileForHabitPolicy);
|
|
211
211
|
return {
|
|
@@ -60,9 +60,8 @@ const pending_1 = require("../mind/pending");
|
|
|
60
60
|
const obligations_1 = require("../arc/obligations");
|
|
61
61
|
const attention_queue_1 = require("./attention-queue");
|
|
62
62
|
const packets_1 = require("../arc/packets");
|
|
63
|
-
const
|
|
63
|
+
const friends_1 = require("@ouro.bot/friends");
|
|
64
64
|
const trust_gate_1 = require("./trust-gate");
|
|
65
|
-
const tokens_1 = require("../mind/friends/tokens");
|
|
66
65
|
const pipeline_1 = require("./pipeline");
|
|
67
66
|
const nerves_1 = require("../nerves");
|
|
68
67
|
const runtime_1 = require("../nerves/runtime");
|
|
@@ -817,7 +816,7 @@ async function runInnerDialogTurn(options) {
|
|
|
817
816
|
}
|
|
818
817
|
const userMessage = { role: "user", content: userContent };
|
|
819
818
|
// ── Session loader: wraps existing session logic ──────────────────
|
|
820
|
-
const innerCapabilities = (0,
|
|
819
|
+
const innerCapabilities = (0, friends_1.getChannelCapabilities)("inner");
|
|
821
820
|
const selfFriend = createSelfFriend(agentName);
|
|
822
821
|
const selfContext = { friend: selfFriend, channel: innerCapabilities };
|
|
823
822
|
const mcpManager = await (0, mcp_manager_1.getSharedMcpManager)() ?? undefined;
|
|
@@ -889,7 +888,7 @@ async function runInnerDialogTurn(options) {
|
|
|
889
888
|
const prepared = (0, context_1.postTurnTrim)(turnMessages, usage, hooks);
|
|
890
889
|
return (0, context_1.deferPostTurnPersist)(sessionPathArg, prepared, usage, state);
|
|
891
890
|
},
|
|
892
|
-
accumulateFriendTokens:
|
|
891
|
+
accumulateFriendTokens: friends_1.accumulateFriendTokens,
|
|
893
892
|
signal: options?.signal,
|
|
894
893
|
/* v8 ignore start -- attention queue: callback invoked by pipeline during pending drain; tested via attention-queue unit tests @preserve */
|
|
895
894
|
onPendingDrained: (drained) => {
|