@ouro.bot/cli 0.1.0-alpha.47 → 0.1.0-alpha.49
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 +16 -0
- package/dist/heart/bridges/manager.js +321 -0
- package/dist/heart/bridges/state-machine.js +115 -0
- package/dist/heart/bridges/store.js +123 -0
- package/dist/heart/daemon/thoughts.js +9 -1
- package/dist/heart/session-recall.js +116 -0
- package/dist/heart/turn-coordinator.js +28 -0
- package/dist/mind/pending.js +11 -0
- package/dist/mind/prompt.js +8 -1
- package/dist/repertoire/tasks/board.js +12 -0
- package/dist/repertoire/tasks/index.js +21 -0
- package/dist/repertoire/tools-base.js +136 -34
- package/dist/repertoire/tools.js +2 -0
- package/dist/senses/bluebubbles.js +127 -123
- package/dist/senses/cli.js +1 -0
- package/dist/senses/inner-dialog-worker.js +41 -15
- package/dist/senses/inner-dialog.js +1 -0
- package/dist/senses/pipeline.js +17 -0
- package/dist/senses/teams.js +1 -0
- package/package.json +1 -1
- package/subagents/work-doer.md +1 -1
- package/subagents/work-planner.md +1 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.recallSession = recallSession;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const runtime_1 = require("../nerves/runtime");
|
|
39
|
+
function normalizeContent(content) {
|
|
40
|
+
if (typeof content === "string")
|
|
41
|
+
return content;
|
|
42
|
+
if (!Array.isArray(content))
|
|
43
|
+
return "";
|
|
44
|
+
return content
|
|
45
|
+
.map((part) => (part && typeof part === "object" && "type" in part && part.type === "text" && "text" in part
|
|
46
|
+
? String(part.text ?? "")
|
|
47
|
+
: ""))
|
|
48
|
+
.filter((text) => text.length > 0)
|
|
49
|
+
.join("");
|
|
50
|
+
}
|
|
51
|
+
function buildSummaryInstruction(friendId, channel, trustLevel) {
|
|
52
|
+
if (friendId === "self" && channel === "inner") {
|
|
53
|
+
return "summarize this session transcript fully and transparently. this is my own inner dialog — include all details, decisions, and reasoning.";
|
|
54
|
+
}
|
|
55
|
+
return `summarize this session transcript. the person asking has trust level: ${trustLevel}. family=full transparency, friend=share work and general topics but protect other people's identities, acquaintance=very guarded minimal disclosure.`;
|
|
56
|
+
}
|
|
57
|
+
function clip(text, limit = 160) {
|
|
58
|
+
const compact = text.replace(/\s+/g, " ").trim();
|
|
59
|
+
return compact.length > limit ? compact.slice(0, limit - 1) + "…" : compact;
|
|
60
|
+
}
|
|
61
|
+
function buildSnapshot(summary, tailMessages) {
|
|
62
|
+
const lines = [`recent focus: ${clip(summary, 240)}`];
|
|
63
|
+
const latestUser = [...tailMessages].reverse().find((message) => message.role === "user")?.content;
|
|
64
|
+
const latestAssistant = [...tailMessages].reverse().find((message) => message.role === "assistant")?.content;
|
|
65
|
+
if (latestUser) {
|
|
66
|
+
lines.push(`latest user: ${clip(latestUser)}`);
|
|
67
|
+
}
|
|
68
|
+
if (latestAssistant) {
|
|
69
|
+
lines.push(`latest assistant: ${clip(latestAssistant)}`);
|
|
70
|
+
}
|
|
71
|
+
return lines.join("\n");
|
|
72
|
+
}
|
|
73
|
+
async function recallSession(options) {
|
|
74
|
+
(0, runtime_1.emitNervesEvent)({
|
|
75
|
+
component: "daemon",
|
|
76
|
+
event: "daemon.session_recall",
|
|
77
|
+
message: "recalling session transcript tail",
|
|
78
|
+
meta: {
|
|
79
|
+
friendId: options.friendId,
|
|
80
|
+
channel: options.channel,
|
|
81
|
+
key: options.key,
|
|
82
|
+
messageCount: options.messageCount,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
let raw;
|
|
86
|
+
try {
|
|
87
|
+
raw = fs.readFileSync(options.sessionPath, "utf-8");
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return { kind: "missing" };
|
|
91
|
+
}
|
|
92
|
+
const parsed = JSON.parse(raw);
|
|
93
|
+
const tailMessages = (parsed.messages ?? [])
|
|
94
|
+
.map((message) => ({
|
|
95
|
+
role: typeof message.role === "string" ? message.role : "",
|
|
96
|
+
content: normalizeContent(message.content),
|
|
97
|
+
}))
|
|
98
|
+
.filter((message) => message.role !== "system" && message.content.length > 0)
|
|
99
|
+
.slice(-options.messageCount);
|
|
100
|
+
if (tailMessages.length === 0) {
|
|
101
|
+
return { kind: "empty" };
|
|
102
|
+
}
|
|
103
|
+
const transcript = tailMessages
|
|
104
|
+
.map((message) => `[${message.role}] ${message.content}`)
|
|
105
|
+
.join("\n");
|
|
106
|
+
const summary = options.summarize
|
|
107
|
+
? await options.summarize(transcript, buildSummaryInstruction(options.friendId, options.channel, options.trustLevel ?? "family"))
|
|
108
|
+
: transcript;
|
|
109
|
+
return {
|
|
110
|
+
kind: "ok",
|
|
111
|
+
transcript,
|
|
112
|
+
summary,
|
|
113
|
+
snapshot: buildSnapshot(summary, tailMessages),
|
|
114
|
+
tailMessages,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createTurnCoordinator = createTurnCoordinator;
|
|
4
|
+
exports.withSharedTurnLock = withSharedTurnLock;
|
|
5
|
+
exports.tryBeginSharedTurn = tryBeginSharedTurn;
|
|
6
|
+
exports.endSharedTurn = endSharedTurn;
|
|
7
|
+
exports.isSharedTurnActive = isSharedTurnActive;
|
|
8
|
+
exports.enqueueSharedFollowUp = enqueueSharedFollowUp;
|
|
9
|
+
exports.drainSharedFollowUps = drainSharedFollowUps;
|
|
4
10
|
const runtime_1 = require("../nerves/runtime");
|
|
11
|
+
function scopedKey(scope, key) {
|
|
12
|
+
return `${scope}:${key}`;
|
|
13
|
+
}
|
|
5
14
|
function createTurnCoordinator() {
|
|
6
15
|
const turnLocks = new Map();
|
|
7
16
|
const activeTurns = new Set();
|
|
@@ -60,3 +69,22 @@ function createTurnCoordinator() {
|
|
|
60
69
|
},
|
|
61
70
|
};
|
|
62
71
|
}
|
|
72
|
+
const _sharedTurnCoordinator = createTurnCoordinator();
|
|
73
|
+
function withSharedTurnLock(scope, key, fn) {
|
|
74
|
+
return _sharedTurnCoordinator.withTurnLock(scopedKey(scope, key), fn);
|
|
75
|
+
}
|
|
76
|
+
function tryBeginSharedTurn(scope, key) {
|
|
77
|
+
return _sharedTurnCoordinator.tryBeginTurn(scopedKey(scope, key));
|
|
78
|
+
}
|
|
79
|
+
function endSharedTurn(scope, key) {
|
|
80
|
+
_sharedTurnCoordinator.endTurn(scopedKey(scope, key));
|
|
81
|
+
}
|
|
82
|
+
function isSharedTurnActive(scope, key) {
|
|
83
|
+
return _sharedTurnCoordinator.isTurnActive(scopedKey(scope, key));
|
|
84
|
+
}
|
|
85
|
+
function enqueueSharedFollowUp(scope, key, followUp) {
|
|
86
|
+
_sharedTurnCoordinator.enqueueFollowUp(scopedKey(scope, key), followUp);
|
|
87
|
+
}
|
|
88
|
+
function drainSharedFollowUps(scope, key) {
|
|
89
|
+
return _sharedTurnCoordinator.drainFollowUps(scopedKey(scope, key));
|
|
90
|
+
}
|
package/dist/mind/pending.js
CHANGED
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.INNER_DIALOG_PENDING = void 0;
|
|
37
37
|
exports.getPendingDir = getPendingDir;
|
|
38
38
|
exports.getInnerDialogPendingDir = getInnerDialogPendingDir;
|
|
39
|
+
exports.hasPendingMessages = hasPendingMessages;
|
|
39
40
|
exports.drainPending = drainPending;
|
|
40
41
|
const fs = __importStar(require("fs"));
|
|
41
42
|
const path = __importStar(require("path"));
|
|
@@ -50,6 +51,16 @@ exports.INNER_DIALOG_PENDING = { friendId: "self", channel: "inner", key: "dialo
|
|
|
50
51
|
function getInnerDialogPendingDir(agentName) {
|
|
51
52
|
return getPendingDir(agentName, exports.INNER_DIALOG_PENDING.friendId, exports.INNER_DIALOG_PENDING.channel, exports.INNER_DIALOG_PENDING.key);
|
|
52
53
|
}
|
|
54
|
+
function hasPendingMessages(pendingDir) {
|
|
55
|
+
if (!fs.existsSync(pendingDir))
|
|
56
|
+
return false;
|
|
57
|
+
try {
|
|
58
|
+
return fs.readdirSync(pendingDir).some((entry) => entry.endsWith(".json") || entry.endsWith(".json.processing"));
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
53
64
|
function drainPending(pendingDir) {
|
|
54
65
|
if (!fs.existsSync(pendingDir))
|
|
55
66
|
return [];
|
package/dist/mind/prompt.js
CHANGED
|
@@ -412,6 +412,12 @@ function memoryFriendToolContractSection() {
|
|
|
412
412
|
- My psyche files (SOUL, IDENTITY, TACIT, LORE, ASPIRATIONS) are always loaded - I already know who I am.
|
|
413
413
|
- My task board is always loaded - I already know my work.`;
|
|
414
414
|
}
|
|
415
|
+
function bridgeContextSection(options) {
|
|
416
|
+
const bridgeContext = options?.bridgeContext?.trim() ?? "";
|
|
417
|
+
if (!bridgeContext)
|
|
418
|
+
return "";
|
|
419
|
+
return bridgeContext.startsWith("## ") ? bridgeContext : `## active bridge work\n${bridgeContext}`;
|
|
420
|
+
}
|
|
415
421
|
function toolBehaviorSection(options) {
|
|
416
422
|
if (!(options?.toolChoiceRequired ?? true))
|
|
417
423
|
return "";
|
|
@@ -543,13 +549,14 @@ async function buildSystem(channel = "cli", options, context) {
|
|
|
543
549
|
mixedTrustGroupSection(context),
|
|
544
550
|
skillsSection(),
|
|
545
551
|
taskBoardSection(),
|
|
552
|
+
bridgeContextSection(options),
|
|
546
553
|
buildSessionSummary({
|
|
547
554
|
sessionsDir: path.join((0, identity_1.getAgentRoot)(), "state", "sessions"),
|
|
548
555
|
friendsDir: path.join((0, identity_1.getAgentRoot)(), "friends"),
|
|
549
556
|
agentName: (0, identity_1.getAgentName)(),
|
|
550
557
|
currentFriendId: context?.friend?.id,
|
|
551
558
|
currentChannel: channel,
|
|
552
|
-
currentKey: "session",
|
|
559
|
+
currentKey: options?.currentSessionKey ?? "session",
|
|
553
560
|
}),
|
|
554
561
|
memoryFriendToolContractSection(),
|
|
555
562
|
toolBehaviorSection(options),
|
|
@@ -59,6 +59,12 @@ function activeSessionLines(tasks) {
|
|
|
59
59
|
});
|
|
60
60
|
return active.map((task) => task.stem).sort();
|
|
61
61
|
}
|
|
62
|
+
function activeBridgeLines(tasks) {
|
|
63
|
+
return tasks
|
|
64
|
+
.filter((task) => typeof task.frontmatter.active_bridge === "string" && String(task.frontmatter.active_bridge).trim())
|
|
65
|
+
.map((task) => `${task.stem} -> ${String(task.frontmatter.active_bridge).trim()}`)
|
|
66
|
+
.sort();
|
|
67
|
+
}
|
|
62
68
|
function actionRequired(index, byStatus) {
|
|
63
69
|
const actions = [...index.parseErrors, ...index.invalidFilenames.map((filePath) => `bad filename: ${filePath}`)];
|
|
64
70
|
if (byStatus.blocked.length > 0) {
|
|
@@ -99,6 +105,11 @@ function buildTaskBoard(index) {
|
|
|
99
105
|
fullLines.push("## active sessions");
|
|
100
106
|
fullLines.push(active.map((line) => `- ${line}`).join("\n"));
|
|
101
107
|
}
|
|
108
|
+
const activeBridges = activeBridgeLines(index.tasks);
|
|
109
|
+
if (activeBridges.length > 0) {
|
|
110
|
+
fullLines.push("## active bridges");
|
|
111
|
+
fullLines.push(activeBridges.map((line) => `- ${line}`).join("\n"));
|
|
112
|
+
}
|
|
102
113
|
return {
|
|
103
114
|
compact,
|
|
104
115
|
full: fullLines.join("\n\n"),
|
|
@@ -106,6 +117,7 @@ function buildTaskBoard(index) {
|
|
|
106
117
|
actionRequired: actionRequired(index, byStatus),
|
|
107
118
|
unresolvedDependencies: unresolved,
|
|
108
119
|
activeSessions: active,
|
|
120
|
+
activeBridges,
|
|
109
121
|
};
|
|
110
122
|
}
|
|
111
123
|
function boardStatus(board, status) {
|
|
@@ -115,6 +115,12 @@ class FileTaskModule {
|
|
|
115
115
|
frontmatter.parent_task = null;
|
|
116
116
|
frontmatter.depends_on = [];
|
|
117
117
|
}
|
|
118
|
+
if (input.activeBridge && input.activeBridge.trim()) {
|
|
119
|
+
frontmatter.active_bridge = input.activeBridge.trim();
|
|
120
|
+
}
|
|
121
|
+
if (Array.isArray(input.bridgeSessions) && input.bridgeSessions.length > 0) {
|
|
122
|
+
frontmatter.bridge_sessions = input.bridgeSessions.filter((value) => typeof value === "string" && value.trim());
|
|
123
|
+
}
|
|
118
124
|
const content = (0, parser_1.renderTaskFile)(frontmatter, input.body);
|
|
119
125
|
const validation = (0, middleware_1.validateWrite)(filePath, content);
|
|
120
126
|
if (!validation.ok) {
|
|
@@ -125,6 +131,21 @@ class FileTaskModule {
|
|
|
125
131
|
(0, scanner_1.clearTaskScanCache)();
|
|
126
132
|
return filePath;
|
|
127
133
|
}
|
|
134
|
+
bindBridge(name, input) {
|
|
135
|
+
const task = this.getTask(name);
|
|
136
|
+
if (!task) {
|
|
137
|
+
return { ok: false, reason: `task not found: ${name}` };
|
|
138
|
+
}
|
|
139
|
+
const content = fs.readFileSync(task.path, "utf-8");
|
|
140
|
+
const parsed = (0, parser_1.parseTaskFile)(content, task.path);
|
|
141
|
+
const frontmatter = removeRuntimeFrontmatter(parsed.frontmatter);
|
|
142
|
+
frontmatter.active_bridge = input.bridgeId.trim();
|
|
143
|
+
frontmatter.bridge_sessions = input.sessionRefs.filter((value) => value.trim().length > 0);
|
|
144
|
+
frontmatter.updated = formatDate();
|
|
145
|
+
fs.writeFileSync(task.path, (0, parser_1.renderTaskFile)(frontmatter, parsed.body), "utf-8");
|
|
146
|
+
(0, scanner_1.clearTaskScanCache)();
|
|
147
|
+
return { ok: true, path: task.path };
|
|
148
|
+
}
|
|
128
149
|
updateStatus(name, toStatus) {
|
|
129
150
|
const normalized = (0, transitions_1.normalizeTaskStatus)(toStatus);
|
|
130
151
|
if (!normalized) {
|
|
@@ -44,6 +44,8 @@ const runtime_1 = require("../nerves/runtime");
|
|
|
44
44
|
const identity_1 = require("../heart/identity");
|
|
45
45
|
const socket_client_1 = require("../heart/daemon/socket-client");
|
|
46
46
|
const thoughts_1 = require("../heart/daemon/thoughts");
|
|
47
|
+
const manager_1 = require("../heart/bridges/manager");
|
|
48
|
+
const session_recall_1 = require("../heart/session-recall");
|
|
47
49
|
const tools_1 = require("./coding/tools");
|
|
48
50
|
const memory_1 = require("../mind/memory");
|
|
49
51
|
const pending_1 = require("../mind/pending");
|
|
@@ -61,6 +63,16 @@ function buildContextDiff(lines, changeStart, changeEnd, contextSize = 3) {
|
|
|
61
63
|
}
|
|
62
64
|
return result.join("\n");
|
|
63
65
|
}
|
|
66
|
+
const NO_SESSION_FOUND_MESSAGE = "no session found for that friend/channel/key combination.";
|
|
67
|
+
const EMPTY_SESSION_MESSAGE = "session exists but has no non-system messages.";
|
|
68
|
+
async function recallSessionSafely(options) {
|
|
69
|
+
try {
|
|
70
|
+
return await (0, session_recall_1.recallSession)(options);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return { kind: "missing" };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
64
76
|
exports.baseToolDefinitions = [
|
|
65
77
|
{
|
|
66
78
|
tool: {
|
|
@@ -585,6 +597,103 @@ exports.baseToolDefinitions = [
|
|
|
585
597
|
},
|
|
586
598
|
},
|
|
587
599
|
// -- cross-session awareness --
|
|
600
|
+
{
|
|
601
|
+
tool: {
|
|
602
|
+
type: "function",
|
|
603
|
+
function: {
|
|
604
|
+
name: "bridge_manage",
|
|
605
|
+
description: "create and manage shared live-work bridges across already-active sessions.",
|
|
606
|
+
parameters: {
|
|
607
|
+
type: "object",
|
|
608
|
+
properties: {
|
|
609
|
+
action: {
|
|
610
|
+
type: "string",
|
|
611
|
+
enum: ["begin", "attach", "status", "promote_task", "complete", "cancel"],
|
|
612
|
+
},
|
|
613
|
+
bridgeId: { type: "string", description: "bridge id for all actions except begin" },
|
|
614
|
+
objective: { type: "string", description: "objective for begin" },
|
|
615
|
+
summary: { type: "string", description: "optional concise shared-work summary" },
|
|
616
|
+
friendId: { type: "string", description: "target friend id for attach" },
|
|
617
|
+
channel: { type: "string", description: "target channel for attach" },
|
|
618
|
+
key: { type: "string", description: "target session key for attach (defaults to 'session')" },
|
|
619
|
+
title: { type: "string", description: "task title override for promote_task" },
|
|
620
|
+
category: { type: "string", description: "task category override for promote_task" },
|
|
621
|
+
body: { type: "string", description: "task body override for promote_task" },
|
|
622
|
+
},
|
|
623
|
+
required: ["action"],
|
|
624
|
+
},
|
|
625
|
+
},
|
|
626
|
+
},
|
|
627
|
+
handler: async (args, ctx) => {
|
|
628
|
+
const manager = (0, manager_1.createBridgeManager)();
|
|
629
|
+
const action = (args.action || "").trim();
|
|
630
|
+
if (action === "begin") {
|
|
631
|
+
if (!ctx?.currentSession) {
|
|
632
|
+
return "bridge_manage begin requires an active session context.";
|
|
633
|
+
}
|
|
634
|
+
const objective = (args.objective || "").trim();
|
|
635
|
+
if (!objective)
|
|
636
|
+
return "objective is required for bridge begin.";
|
|
637
|
+
return (0, manager_1.formatBridgeStatus)(manager.beginBridge({
|
|
638
|
+
objective,
|
|
639
|
+
summary: (args.summary || objective).trim(),
|
|
640
|
+
session: ctx.currentSession,
|
|
641
|
+
}));
|
|
642
|
+
}
|
|
643
|
+
const bridgeId = (args.bridgeId || "").trim();
|
|
644
|
+
if (!bridgeId) {
|
|
645
|
+
return "bridgeId is required for this bridge action.";
|
|
646
|
+
}
|
|
647
|
+
if (action === "attach") {
|
|
648
|
+
const friendId = (args.friendId || "").trim();
|
|
649
|
+
const channel = (args.channel || "").trim();
|
|
650
|
+
const key = (args.key || "session").trim();
|
|
651
|
+
if (!friendId || !channel) {
|
|
652
|
+
return "friendId and channel are required for bridge attach.";
|
|
653
|
+
}
|
|
654
|
+
const sessionPath = (0, config_1.resolveSessionPath)(friendId, channel, key);
|
|
655
|
+
const recall = await recallSessionSafely({
|
|
656
|
+
sessionPath,
|
|
657
|
+
friendId,
|
|
658
|
+
channel,
|
|
659
|
+
key,
|
|
660
|
+
messageCount: 20,
|
|
661
|
+
trustLevel: ctx?.context?.friend?.trustLevel,
|
|
662
|
+
summarize: ctx?.summarize,
|
|
663
|
+
});
|
|
664
|
+
if (recall.kind === "missing") {
|
|
665
|
+
return NO_SESSION_FOUND_MESSAGE;
|
|
666
|
+
}
|
|
667
|
+
return (0, manager_1.formatBridgeStatus)(manager.attachSession(bridgeId, {
|
|
668
|
+
friendId,
|
|
669
|
+
channel,
|
|
670
|
+
key,
|
|
671
|
+
sessionPath,
|
|
672
|
+
snapshot: recall.kind === "ok" ? recall.snapshot : EMPTY_SESSION_MESSAGE,
|
|
673
|
+
}));
|
|
674
|
+
}
|
|
675
|
+
if (action === "status") {
|
|
676
|
+
const bridge = manager.getBridge(bridgeId);
|
|
677
|
+
if (!bridge)
|
|
678
|
+
return `bridge not found: ${bridgeId}`;
|
|
679
|
+
return (0, manager_1.formatBridgeStatus)(bridge);
|
|
680
|
+
}
|
|
681
|
+
if (action === "promote_task") {
|
|
682
|
+
return (0, manager_1.formatBridgeStatus)(manager.promoteBridgeToTask(bridgeId, {
|
|
683
|
+
title: args.title,
|
|
684
|
+
category: args.category,
|
|
685
|
+
body: args.body,
|
|
686
|
+
}));
|
|
687
|
+
}
|
|
688
|
+
if (action === "complete") {
|
|
689
|
+
return (0, manager_1.formatBridgeStatus)(manager.completeBridge(bridgeId));
|
|
690
|
+
}
|
|
691
|
+
if (action === "cancel") {
|
|
692
|
+
return (0, manager_1.formatBridgeStatus)(manager.cancelBridge(bridgeId));
|
|
693
|
+
}
|
|
694
|
+
return `unknown bridge action: ${action}`;
|
|
695
|
+
},
|
|
696
|
+
},
|
|
588
697
|
{
|
|
589
698
|
tool: {
|
|
590
699
|
type: "function",
|
|
@@ -605,43 +714,36 @@ exports.baseToolDefinitions = [
|
|
|
605
714
|
},
|
|
606
715
|
},
|
|
607
716
|
handler: async (args, ctx) => {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
if (
|
|
615
|
-
|
|
616
|
-
return "status mode is only available for self/inner dialog.";
|
|
617
|
-
}
|
|
618
|
-
const sessionPath = (0, thoughts_1.getInnerDialogSessionPath)((0, identity_1.getAgentRoot)());
|
|
619
|
-
const pendingDir = (0, pending_1.getInnerDialogPendingDir)((0, identity_1.getAgentName)());
|
|
620
|
-
return (0, thoughts_1.formatInnerDialogStatus)((0, thoughts_1.readInnerDialogStatus)(sessionPath, pendingDir));
|
|
621
|
-
}
|
|
622
|
-
const sessFile = (0, config_1.resolveSessionPath)(friendId, channel, key);
|
|
623
|
-
const raw = fs.readFileSync(sessFile, "utf-8");
|
|
624
|
-
const data = JSON.parse(raw);
|
|
625
|
-
const messages = (data.messages || [])
|
|
626
|
-
.filter((m) => m.role !== "system");
|
|
627
|
-
const tail = messages.slice(-count);
|
|
628
|
-
if (tail.length === 0)
|
|
629
|
-
return "session exists but has no non-system messages.";
|
|
630
|
-
const transcript = tail.map((m) => `[${m.role}] ${m.content}`).join("\n");
|
|
631
|
-
// LLM summarization when summarize function is available
|
|
632
|
-
if (ctx?.summarize) {
|
|
633
|
-
const trustLevel = ctx.context?.friend?.trustLevel ?? "family";
|
|
634
|
-
const isSelfQuery = friendId === "self";
|
|
635
|
-
const instruction = isSelfQuery
|
|
636
|
-
? "summarize this session transcript fully and transparently. this is my own inner dialog — include all details, decisions, and reasoning."
|
|
637
|
-
: `summarize this session transcript. the person asking has trust level: ${trustLevel}. family=full transparency, friend=share work and general topics but protect other people's identities, acquaintance=very guarded minimal disclosure.`;
|
|
638
|
-
return await ctx.summarize(transcript, instruction);
|
|
717
|
+
const friendId = args.friendId;
|
|
718
|
+
const channel = args.channel;
|
|
719
|
+
const key = args.key || "session";
|
|
720
|
+
const count = parseInt(args.messageCount || "20", 10);
|
|
721
|
+
const mode = args.mode || "transcript";
|
|
722
|
+
if (mode === "status") {
|
|
723
|
+
if (friendId !== "self" || channel !== "inner") {
|
|
724
|
+
return "status mode is only available for self/inner dialog.";
|
|
639
725
|
}
|
|
640
|
-
|
|
726
|
+
const sessionPath = (0, thoughts_1.getInnerDialogSessionPath)((0, identity_1.getAgentRoot)());
|
|
727
|
+
const pendingDir = (0, pending_1.getInnerDialogPendingDir)((0, identity_1.getAgentName)());
|
|
728
|
+
return (0, thoughts_1.formatInnerDialogStatus)((0, thoughts_1.readInnerDialogStatus)(sessionPath, pendingDir));
|
|
729
|
+
}
|
|
730
|
+
const sessFile = (0, config_1.resolveSessionPath)(friendId, channel, key);
|
|
731
|
+
const recall = await recallSessionSafely({
|
|
732
|
+
sessionPath: sessFile,
|
|
733
|
+
friendId,
|
|
734
|
+
channel,
|
|
735
|
+
key,
|
|
736
|
+
messageCount: count,
|
|
737
|
+
trustLevel: ctx?.context?.friend?.trustLevel,
|
|
738
|
+
summarize: ctx?.summarize,
|
|
739
|
+
});
|
|
740
|
+
if (recall.kind === "missing") {
|
|
741
|
+
return NO_SESSION_FOUND_MESSAGE;
|
|
641
742
|
}
|
|
642
|
-
|
|
643
|
-
return
|
|
743
|
+
if (recall.kind === "empty") {
|
|
744
|
+
return EMPTY_SESSION_MESSAGE;
|
|
644
745
|
}
|
|
746
|
+
return recall.summary;
|
|
645
747
|
},
|
|
646
748
|
},
|
|
647
749
|
{
|
package/dist/repertoire/tools.js
CHANGED
|
@@ -205,6 +205,8 @@ function summarizeArgs(name, args) {
|
|
|
205
205
|
if (name === "save_friend_note") {
|
|
206
206
|
return summarizeKeyValues(args, ["type", "key", "content"]);
|
|
207
207
|
}
|
|
208
|
+
if (name === "bridge_manage")
|
|
209
|
+
return summarizeKeyValues(args, ["action", "bridgeId", "objective", "friendId", "channel", "key"]);
|
|
208
210
|
if (name === "ado_backlog_list")
|
|
209
211
|
return summarizeKeyValues(args, ["organization", "project"]);
|
|
210
212
|
if (name === "ado_batch_update")
|