@ouro.bot/cli 0.1.0-alpha.14 → 0.1.0-alpha.141
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/AdoptionSpecialist.ouro/psyche/SOUL.md +2 -2
- package/AdoptionSpecialist.ouro/psyche/identities/monty.md +2 -2
- package/README.md +151 -205
- package/changelog.json +913 -0
- package/dist/heart/active-work.js +633 -0
- package/dist/heart/bridges/manager.js +358 -0
- package/dist/heart/bridges/state-machine.js +135 -0
- package/dist/heart/bridges/store.js +123 -0
- package/dist/heart/commitments.js +105 -0
- package/dist/heart/config.js +66 -21
- package/dist/heart/core.js +645 -112
- package/dist/heart/cross-chat-delivery.js +146 -0
- package/dist/heart/daemon/agent-discovery.js +81 -0
- package/dist/heart/daemon/agent-service.js +467 -0
- package/dist/heart/daemon/auth-flow.js +457 -0
- package/dist/heart/daemon/daemon-cli.js +1840 -196
- package/dist/heart/daemon/daemon-entry.js +80 -3
- package/dist/heart/daemon/daemon-runtime-sync.js +212 -0
- package/dist/heart/daemon/daemon.js +301 -1
- package/dist/heart/daemon/hatch-animation.js +10 -3
- package/dist/heart/daemon/hatch-flow.js +15 -80
- package/dist/heart/daemon/heartbeat-timer.js +131 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +92 -0
- package/dist/heart/daemon/launchd.js +159 -0
- package/dist/heart/daemon/log-tailer.js +4 -3
- package/dist/heart/daemon/mcp-server.js +464 -0
- package/dist/heart/daemon/message-router.js +17 -8
- package/dist/heart/daemon/ouro-bot-global-installer.js +128 -0
- package/dist/heart/daemon/ouro-path-installer.js +67 -34
- package/dist/heart/daemon/ouro-version-manager.js +171 -0
- package/dist/heart/daemon/process-manager.js +13 -0
- package/dist/heart/daemon/run-hooks.js +37 -0
- package/dist/heart/daemon/runtime-logging.js +58 -15
- package/dist/heart/daemon/runtime-metadata.js +219 -0
- package/dist/heart/daemon/runtime-mode.js +67 -0
- package/dist/heart/daemon/sense-manager.js +50 -2
- package/dist/heart/daemon/skill-management-installer.js +94 -0
- package/dist/heart/daemon/socket-client.js +202 -0
- package/dist/heart/daemon/specialist-orchestrator.js +2 -2
- package/dist/heart/daemon/specialist-prompt.js +10 -7
- package/dist/heart/daemon/specialist-tools.js +52 -3
- package/dist/heart/daemon/staged-restart.js +114 -0
- package/dist/heart/daemon/thoughts.js +507 -0
- package/dist/heart/daemon/update-checker.js +111 -0
- package/dist/heart/daemon/update-hooks.js +138 -0
- package/dist/heart/daemon/wrapper-publish-guard.js +86 -0
- package/dist/heart/delegation.js +62 -0
- package/dist/heart/identity.js +64 -21
- package/dist/heart/kicks.js +2 -20
- package/dist/heart/model-capabilities.js +48 -0
- package/dist/heart/obligations.js +197 -0
- package/dist/heart/progress-story.js +42 -0
- package/dist/heart/provider-failover.js +88 -0
- package/dist/heart/provider-ping.js +159 -0
- package/dist/heart/providers/anthropic-token.js +163 -0
- package/dist/heart/providers/anthropic.js +195 -34
- package/dist/heart/providers/azure.js +115 -9
- package/dist/heart/providers/github-copilot.js +157 -0
- package/dist/heart/providers/minimax.js +33 -3
- package/dist/heart/providers/openai-codex.js +49 -14
- package/dist/heart/session-activity.js +173 -0
- package/dist/heart/session-recall.js +216 -0
- package/dist/heart/streaming.js +117 -33
- package/dist/heart/target-resolution.js +123 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-coordinator.js +28 -0
- package/dist/mind/associative-recall.js +122 -32
- package/dist/mind/bundle-manifest.js +14 -0
- package/dist/mind/context.js +125 -14
- package/dist/mind/{memory.js → diary.js} +70 -56
- package/dist/mind/first-impressions.js +16 -2
- package/dist/mind/friends/channel.js +35 -0
- package/dist/mind/friends/group-context.js +144 -0
- package/dist/mind/friends/store-file.js +19 -0
- package/dist/mind/friends/trust-explanation.js +74 -0
- package/dist/mind/friends/types.js +8 -0
- package/dist/mind/journal-index.js +161 -0
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/obligations.js +134 -0
- package/dist/mind/pending.js +76 -9
- package/dist/mind/phrases.js +1 -0
- package/dist/mind/prompt.js +554 -88
- package/dist/mind/token-estimate.js +8 -12
- package/dist/nerves/cli-logging.js +15 -2
- package/dist/nerves/coverage/run-artifacts.js +1 -1
- package/dist/nerves/index.js +12 -0
- package/dist/nerves/runtime.js +5 -1
- package/dist/repertoire/ado-client.js +4 -2
- package/dist/repertoire/ado-semantic.js +6 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +254 -0
- package/dist/repertoire/coding/feedback.js +301 -0
- package/dist/repertoire/coding/index.js +4 -1
- package/dist/repertoire/coding/manager.js +210 -4
- package/dist/repertoire/coding/spawner.js +59 -12
- package/dist/repertoire/coding/tools.js +176 -4
- package/dist/repertoire/data/ado-endpoints.json +188 -0
- package/dist/repertoire/guardrails.js +290 -0
- package/dist/repertoire/mcp-client.js +254 -0
- package/dist/repertoire/mcp-manager.js +198 -0
- package/dist/repertoire/skills.js +14 -23
- package/dist/repertoire/tasks/board.js +12 -0
- package/dist/repertoire/tasks/index.js +23 -9
- package/dist/repertoire/tasks/transitions.js +1 -2
- package/dist/repertoire/tools-base.js +980 -271
- package/dist/repertoire/tools-bluebubbles.js +94 -0
- package/dist/repertoire/tools-github.js +1 -6
- package/dist/repertoire/tools-teams.js +65 -59
- package/dist/repertoire/tools.js +266 -91
- package/dist/senses/attention-queue.js +97 -0
- package/dist/senses/bluebubbles-client.js +210 -5
- package/dist/senses/bluebubbles-entry.js +2 -0
- package/dist/senses/bluebubbles-inbound-log.js +109 -0
- package/dist/senses/bluebubbles-media.js +339 -0
- package/dist/senses/bluebubbles-model.js +12 -4
- package/dist/senses/bluebubbles-mutation-log.js +45 -5
- package/dist/senses/bluebubbles-runtime-state.js +109 -0
- package/dist/senses/bluebubbles-session-cleanup.js +72 -0
- package/dist/senses/bluebubbles.js +944 -45
- package/dist/senses/cli-entry.js +1 -1
- package/dist/senses/cli-layout.js +187 -0
- package/dist/senses/cli.js +374 -131
- package/dist/senses/contextual-heartbeat.js +102 -0
- package/dist/senses/continuity.js +94 -0
- package/dist/senses/debug-activity.js +154 -0
- package/dist/senses/inner-dialog-worker.js +47 -18
- package/dist/senses/inner-dialog.js +500 -84
- package/dist/senses/pipeline.js +454 -0
- package/dist/senses/surface-tool.js +82 -0
- package/dist/senses/teams.js +607 -129
- package/dist/senses/trust-gate.js +112 -2
- package/package.json +12 -4
- package/skills/configure-dev-tools.md +109 -0
- package/subagents/README.md +4 -70
- package/dist/heart/daemon/subagent-installer.js +0 -134
- package/subagents/work-doer.md +0 -233
- package/subagents/work-merger.md +0 -624
- package/subagents/work-planner.md +0 -373
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildContextualHeartbeat = buildContextualHeartbeat;
|
|
4
|
+
const runtime_1 = require("../nerves/runtime");
|
|
5
|
+
const STALE_THRESHOLD_MS = 30 * 60 * 1000; // 30 minutes
|
|
6
|
+
const MAX_JOURNAL_FILES = 10;
|
|
7
|
+
function formatElapsed(ms) {
|
|
8
|
+
const minutes = Math.floor(ms / 60000);
|
|
9
|
+
if (minutes < 60) {
|
|
10
|
+
return `${minutes} ${minutes === 1 ? "minute" : "minutes"}`;
|
|
11
|
+
}
|
|
12
|
+
const hours = Math.floor(minutes / 60);
|
|
13
|
+
return `${hours} ${hours === 1 ? "hour" : "hours"}`;
|
|
14
|
+
}
|
|
15
|
+
function formatRelativeTime(nowMs, mtimeMs) {
|
|
16
|
+
const diffMs = nowMs - mtimeMs;
|
|
17
|
+
const minutes = Math.floor(diffMs / 60000);
|
|
18
|
+
if (minutes < 1)
|
|
19
|
+
return "just now";
|
|
20
|
+
if (minutes < 60)
|
|
21
|
+
return `${minutes} ${minutes === 1 ? "minute" : "minutes"} ago`;
|
|
22
|
+
const hours = Math.floor(minutes / 60);
|
|
23
|
+
if (hours < 24)
|
|
24
|
+
return `${hours} ${hours === 1 ? "hour" : "hours"} ago`;
|
|
25
|
+
const days = Math.floor(hours / 24);
|
|
26
|
+
return `${days} ${days === 1 ? "day" : "days"} ago`;
|
|
27
|
+
}
|
|
28
|
+
function buildContextualHeartbeat(options) {
|
|
29
|
+
const { lastCompletedAt, pendingObligations, lastSurfaceAt, checkpoint, now, readJournalDir, } = options;
|
|
30
|
+
const nowDate = now();
|
|
31
|
+
const nowMs = nowDate.getTime();
|
|
32
|
+
const journalFiles = readJournalDir();
|
|
33
|
+
// Cold start: no journal files and no runtime state
|
|
34
|
+
if (journalFiles.length === 0 && !lastCompletedAt) {
|
|
35
|
+
const lines = ["...time passing. anything stirring?"];
|
|
36
|
+
if (checkpoint) {
|
|
37
|
+
lines.push(`\nlast i remember: ${checkpoint}`);
|
|
38
|
+
}
|
|
39
|
+
(0, runtime_1.emitNervesEvent)({
|
|
40
|
+
component: "senses",
|
|
41
|
+
event: "senses.contextual_heartbeat_built",
|
|
42
|
+
message: "contextual heartbeat built (cold start)",
|
|
43
|
+
meta: { coldStart: true },
|
|
44
|
+
});
|
|
45
|
+
return lines.join("\n");
|
|
46
|
+
}
|
|
47
|
+
const sections = [];
|
|
48
|
+
// Elapsed time since last turn
|
|
49
|
+
if (lastCompletedAt) {
|
|
50
|
+
const lastMs = new Date(lastCompletedAt).getTime();
|
|
51
|
+
const elapsed = nowMs - lastMs;
|
|
52
|
+
sections.push(`it's been ${formatElapsed(elapsed)} since your last turn.`);
|
|
53
|
+
}
|
|
54
|
+
// Pending attention count
|
|
55
|
+
if (pendingObligations.length > 0) {
|
|
56
|
+
const count = pendingObligations.length;
|
|
57
|
+
sections.push(`you're holding ${count} ${count === 1 ? "thought" : "thoughts"}.`);
|
|
58
|
+
}
|
|
59
|
+
// Journal index
|
|
60
|
+
if (journalFiles.length > 0) {
|
|
61
|
+
const sorted = [...journalFiles].sort((a, b) => b.mtime - a.mtime).slice(0, MAX_JOURNAL_FILES);
|
|
62
|
+
const indexLines = ["## journal"];
|
|
63
|
+
for (const file of sorted) {
|
|
64
|
+
const ago = formatRelativeTime(nowMs, file.mtime);
|
|
65
|
+
const previewClause = file.preview ? ` — ${file.preview}` : "";
|
|
66
|
+
indexLines.push(`- ${file.name} (${ago})${previewClause}`);
|
|
67
|
+
}
|
|
68
|
+
sections.push(indexLines.join("\n"));
|
|
69
|
+
}
|
|
70
|
+
// Journal entries since last surface
|
|
71
|
+
if (lastSurfaceAt && journalFiles.length > 0) {
|
|
72
|
+
const surfaceMs = new Date(lastSurfaceAt).getTime();
|
|
73
|
+
const entriesSinceSurface = journalFiles.filter((f) => f.mtime > surfaceMs).length;
|
|
74
|
+
if (entriesSinceSurface > 0) {
|
|
75
|
+
const surfaceElapsed = formatElapsed(nowMs - surfaceMs);
|
|
76
|
+
sections.push(`${entriesSinceSurface} journal ${entriesSinceSurface === 1 ? "entry" : "entries"} since you last surfaced, ${surfaceElapsed} ago.`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Stale obligation alerts
|
|
80
|
+
const staleObligations = pendingObligations.filter((o) => o.staleness >= STALE_THRESHOLD_MS);
|
|
81
|
+
if (staleObligations.length > 0) {
|
|
82
|
+
for (const obligation of staleObligations) {
|
|
83
|
+
sections.push(`this has been sitting for ${formatElapsed(obligation.staleness)}: ${obligation.content}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Checkpoint
|
|
87
|
+
if (checkpoint) {
|
|
88
|
+
sections.push(`last i remember: ${checkpoint}`);
|
|
89
|
+
}
|
|
90
|
+
(0, runtime_1.emitNervesEvent)({
|
|
91
|
+
component: "senses",
|
|
92
|
+
event: "senses.contextual_heartbeat_built",
|
|
93
|
+
message: "contextual heartbeat built",
|
|
94
|
+
meta: {
|
|
95
|
+
hasJournal: journalFiles.length > 0,
|
|
96
|
+
hasLastCompleted: !!lastCompletedAt,
|
|
97
|
+
obligationCount: pendingObligations.length,
|
|
98
|
+
staleCount: staleObligations.length,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
return sections.join("\n\n");
|
|
102
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeContinuityClauses = normalizeContinuityClauses;
|
|
4
|
+
exports.resolveMustResolveBeforeHandoff = resolveMustResolveBeforeHandoff;
|
|
5
|
+
exports.classifySteeringFollowUpEffect = classifySteeringFollowUpEffect;
|
|
6
|
+
const runtime_1 = require("../nerves/runtime");
|
|
7
|
+
const NO_HANDOFF_CLAUSES = new Set([
|
|
8
|
+
"dont return control until complete or blocked",
|
|
9
|
+
"do not return control until complete or blocked",
|
|
10
|
+
"dont hand back control until complete or blocked",
|
|
11
|
+
"do not hand back control until complete or blocked",
|
|
12
|
+
"keep going until youre done",
|
|
13
|
+
"keep going until you are done",
|
|
14
|
+
"keep working until youre done",
|
|
15
|
+
"keep working until you are done",
|
|
16
|
+
"dont stop until youre done",
|
|
17
|
+
"do not stop until youre done",
|
|
18
|
+
"only come back if blocked",
|
|
19
|
+
"only return if blocked",
|
|
20
|
+
"only respond if blocked",
|
|
21
|
+
"work autonomously on this",
|
|
22
|
+
"work on this autonomously",
|
|
23
|
+
"handle this autonomously",
|
|
24
|
+
]);
|
|
25
|
+
const CANCEL_SUPERSEDE_CLAUSES = new Set([
|
|
26
|
+
"stop",
|
|
27
|
+
"cancel that",
|
|
28
|
+
"cancel this",
|
|
29
|
+
"never mind",
|
|
30
|
+
"nevermind",
|
|
31
|
+
"forget it",
|
|
32
|
+
"ignore that",
|
|
33
|
+
"ignore this",
|
|
34
|
+
"hold off",
|
|
35
|
+
"ill take it from here",
|
|
36
|
+
"i will take it from here",
|
|
37
|
+
"lets do something else",
|
|
38
|
+
"stop working on that",
|
|
39
|
+
"stop working on this",
|
|
40
|
+
"dont do that",
|
|
41
|
+
"do not do that",
|
|
42
|
+
]);
|
|
43
|
+
function normalizeContinuityClauses(text) {
|
|
44
|
+
return text
|
|
45
|
+
.toLowerCase()
|
|
46
|
+
.split(/[\n.!?;]+/)
|
|
47
|
+
.map((clause) => clause.replace(/[^a-z\s]/g, "").replace(/\s+/g, " ").trim())
|
|
48
|
+
.filter(Boolean);
|
|
49
|
+
}
|
|
50
|
+
function resolveMustResolveBeforeHandoff(initialValue, ingressTexts) {
|
|
51
|
+
let current = initialValue;
|
|
52
|
+
for (const text of ingressTexts ?? []) {
|
|
53
|
+
for (const clause of normalizeContinuityClauses(text)) {
|
|
54
|
+
if (CANCEL_SUPERSEDE_CLAUSES.has(clause)) {
|
|
55
|
+
current = false;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (NO_HANDOFF_CLAUSES.has(clause)) {
|
|
59
|
+
current = true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
(0, runtime_1.emitNervesEvent)({
|
|
64
|
+
component: "senses",
|
|
65
|
+
event: "senses.continuity_state_resolved",
|
|
66
|
+
message: "resolved continuity handoff state from ingress text",
|
|
67
|
+
meta: {
|
|
68
|
+
initialValue,
|
|
69
|
+
finalValue: current,
|
|
70
|
+
ingressCount: ingressTexts?.length ?? 0,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
return current;
|
|
74
|
+
}
|
|
75
|
+
function classifySteeringFollowUpEffect(text) {
|
|
76
|
+
const clauses = normalizeContinuityClauses(text);
|
|
77
|
+
let effect = "none";
|
|
78
|
+
if (clauses.some((clause) => CANCEL_SUPERSEDE_CLAUSES.has(clause))) {
|
|
79
|
+
effect = "clear_and_supersede";
|
|
80
|
+
}
|
|
81
|
+
else if (clauses.some((clause) => NO_HANDOFF_CLAUSES.has(clause))) {
|
|
82
|
+
effect = "set_no_handoff";
|
|
83
|
+
}
|
|
84
|
+
(0, runtime_1.emitNervesEvent)({
|
|
85
|
+
component: "senses",
|
|
86
|
+
event: "senses.continuity_follow_up_classified",
|
|
87
|
+
message: "classified steering follow-up continuity effect",
|
|
88
|
+
meta: {
|
|
89
|
+
effect,
|
|
90
|
+
clauseCount: clauses.length,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
return effect;
|
|
94
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDebugActivityController = createDebugActivityController;
|
|
4
|
+
const format_1 = require("../mind/format");
|
|
5
|
+
const phrases_1 = require("../mind/phrases");
|
|
6
|
+
const runtime_1 = require("../nerves/runtime");
|
|
7
|
+
const progress_story_1 = require("../heart/progress-story");
|
|
8
|
+
function createDebugActivityController(options) {
|
|
9
|
+
let queue = Promise.resolve();
|
|
10
|
+
let statusMessageGuid;
|
|
11
|
+
let typingActive = false;
|
|
12
|
+
let hadToolRun = false;
|
|
13
|
+
let followupShown = false;
|
|
14
|
+
let lastPhrase = "";
|
|
15
|
+
function reportTransportError(operation, error) {
|
|
16
|
+
(0, runtime_1.emitNervesEvent)({
|
|
17
|
+
level: "warn",
|
|
18
|
+
component: "senses",
|
|
19
|
+
event: "senses.debug_activity_transport_error",
|
|
20
|
+
message: "debug activity transport failed",
|
|
21
|
+
meta: {
|
|
22
|
+
operation,
|
|
23
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
options.onTransportError?.(operation, error);
|
|
27
|
+
}
|
|
28
|
+
function enqueue(operation, task) {
|
|
29
|
+
queue = queue
|
|
30
|
+
.then(task)
|
|
31
|
+
.catch((error) => {
|
|
32
|
+
reportTransportError(operation, error);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
function nextPhrase(pool) {
|
|
36
|
+
const phrase = (0, phrases_1.pickPhrase)(pool, lastPhrase);
|
|
37
|
+
lastPhrase = phrase;
|
|
38
|
+
return phrase;
|
|
39
|
+
}
|
|
40
|
+
function startTypingNow() {
|
|
41
|
+
if (typingActive) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
typingActive = true;
|
|
45
|
+
enqueue("typing_start", async () => {
|
|
46
|
+
await options.transport.setTyping(true);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function setStatus(text) {
|
|
50
|
+
(0, runtime_1.emitNervesEvent)({
|
|
51
|
+
component: "senses",
|
|
52
|
+
event: "senses.debug_activity_update",
|
|
53
|
+
message: "debug activity status updated",
|
|
54
|
+
meta: {
|
|
55
|
+
hasStatusGuid: Boolean(statusMessageGuid),
|
|
56
|
+
textLength: text.length,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
const shouldStartTyping = !typingActive;
|
|
60
|
+
if (shouldStartTyping) {
|
|
61
|
+
typingActive = true;
|
|
62
|
+
}
|
|
63
|
+
enqueue("status_update", async () => {
|
|
64
|
+
if (statusMessageGuid) {
|
|
65
|
+
await options.transport.editStatus(statusMessageGuid, text);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
statusMessageGuid = await options.transport.sendStatus(text);
|
|
69
|
+
}
|
|
70
|
+
if (shouldStartTyping) {
|
|
71
|
+
await options.transport.setTyping(true);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
onModelStart() {
|
|
77
|
+
const pool = hadToolRun ? options.followupPhrases : options.thinkingPhrases;
|
|
78
|
+
if (options.startTypingOnModelStart) {
|
|
79
|
+
startTypingNow();
|
|
80
|
+
}
|
|
81
|
+
if (options.suppressInitialModelStatus && !statusMessageGuid && !hadToolRun) {
|
|
82
|
+
nextPhrase(pool);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
setStatus((0, progress_story_1.renderProgressStory)((0, progress_story_1.buildProgressStory)({
|
|
86
|
+
scope: "shared-work",
|
|
87
|
+
phase: "processing",
|
|
88
|
+
objective: `${nextPhrase(pool)}...`,
|
|
89
|
+
})));
|
|
90
|
+
},
|
|
91
|
+
onToolStart(name, args) {
|
|
92
|
+
hadToolRun = true;
|
|
93
|
+
followupShown = false;
|
|
94
|
+
const argSummary = Object.values(args).join(", ");
|
|
95
|
+
const detail = argSummary ? ` (${argSummary})` : "";
|
|
96
|
+
setStatus((0, progress_story_1.renderProgressStory)((0, progress_story_1.buildProgressStory)({
|
|
97
|
+
scope: "shared-work",
|
|
98
|
+
phase: "processing",
|
|
99
|
+
objective: `running ${name}${detail}...`,
|
|
100
|
+
})));
|
|
101
|
+
},
|
|
102
|
+
onToolEnd(name, summary, success) {
|
|
103
|
+
hadToolRun = true;
|
|
104
|
+
followupShown = false;
|
|
105
|
+
setStatus((0, progress_story_1.renderProgressStory)((0, progress_story_1.buildProgressStory)({
|
|
106
|
+
scope: "shared-work",
|
|
107
|
+
phase: "processing",
|
|
108
|
+
objective: (0, format_1.formatToolResult)(name, summary, success),
|
|
109
|
+
})));
|
|
110
|
+
},
|
|
111
|
+
onTextChunk(text) {
|
|
112
|
+
if (!text) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (!hadToolRun && options.startTypingOnFirstTextChunk) {
|
|
116
|
+
startTypingNow();
|
|
117
|
+
}
|
|
118
|
+
if (!hadToolRun || followupShown) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
followupShown = true;
|
|
122
|
+
if (options.suppressFollowupPhraseStatus) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
setStatus((0, progress_story_1.renderProgressStory)((0, progress_story_1.buildProgressStory)({
|
|
126
|
+
scope: "shared-work",
|
|
127
|
+
phase: "processing",
|
|
128
|
+
objective: `${nextPhrase(options.followupPhrases)}...`,
|
|
129
|
+
})));
|
|
130
|
+
},
|
|
131
|
+
onError(error) {
|
|
132
|
+
setStatus((0, progress_story_1.renderProgressStory)((0, progress_story_1.buildProgressStory)({
|
|
133
|
+
scope: "shared-work",
|
|
134
|
+
phase: "errored",
|
|
135
|
+
outcomeText: (0, format_1.formatError)(error),
|
|
136
|
+
})));
|
|
137
|
+
this.finish();
|
|
138
|
+
},
|
|
139
|
+
async drain() {
|
|
140
|
+
await queue;
|
|
141
|
+
},
|
|
142
|
+
async finish() {
|
|
143
|
+
if (!typingActive) {
|
|
144
|
+
await queue;
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
typingActive = false;
|
|
148
|
+
enqueue("typing_stop", async () => {
|
|
149
|
+
await options.transport.setTyping(false);
|
|
150
|
+
});
|
|
151
|
+
await queue;
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
@@ -4,26 +4,52 @@ exports.createInnerDialogWorker = createInnerDialogWorker;
|
|
|
4
4
|
exports.startInnerDialogWorker = startInnerDialogWorker;
|
|
5
5
|
const inner_dialog_1 = require("./inner-dialog");
|
|
6
6
|
const runtime_1 = require("../nerves/runtime");
|
|
7
|
-
|
|
7
|
+
const identity_1 = require("../heart/identity");
|
|
8
|
+
const pending_1 = require("../mind/pending");
|
|
9
|
+
function createInnerDialogWorker(runTurn = (options) => (0, inner_dialog_1.runInnerDialogTurn)(options), hasPendingWork = () => (0, pending_1.hasPendingMessages)((0, pending_1.getInnerDialogPendingDir)((0, identity_1.getAgentName)()))) {
|
|
8
10
|
let running = false;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
let rerunRequested = false;
|
|
12
|
+
let rerunReason = "instinct";
|
|
13
|
+
let rerunTaskId;
|
|
14
|
+
async function run(reason, taskId) {
|
|
15
|
+
if (running) {
|
|
16
|
+
rerunRequested = true;
|
|
17
|
+
rerunReason = reason;
|
|
18
|
+
if (taskId !== undefined) {
|
|
19
|
+
rerunTaskId = taskId;
|
|
20
|
+
}
|
|
11
21
|
return;
|
|
22
|
+
}
|
|
12
23
|
running = true;
|
|
13
24
|
try {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
let nextReason = reason;
|
|
26
|
+
let nextTaskId = taskId;
|
|
27
|
+
do {
|
|
28
|
+
rerunRequested = false;
|
|
29
|
+
try {
|
|
30
|
+
await runTurn({ reason: nextReason, taskId: nextTaskId });
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
(0, runtime_1.emitNervesEvent)({
|
|
34
|
+
level: "error",
|
|
35
|
+
component: "senses",
|
|
36
|
+
event: "senses.inner_dialog_worker_error",
|
|
37
|
+
message: "inner dialog worker turn failed",
|
|
38
|
+
meta: {
|
|
39
|
+
reason: nextReason,
|
|
40
|
+
error: error instanceof Error ? error.message : String(error),
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (!rerunRequested && hasPendingWork()) {
|
|
45
|
+
rerunRequested = true;
|
|
46
|
+
rerunReason = "instinct";
|
|
47
|
+
}
|
|
48
|
+
nextReason = rerunReason;
|
|
49
|
+
nextTaskId = rerunTaskId;
|
|
50
|
+
rerunReason = "instinct";
|
|
51
|
+
rerunTaskId = undefined;
|
|
52
|
+
} while (rerunRequested);
|
|
27
53
|
}
|
|
28
54
|
finally {
|
|
29
55
|
running = false;
|
|
@@ -37,8 +63,11 @@ function createInnerDialogWorker(runTurn = (options) => (0, inner_dialog_1.runIn
|
|
|
37
63
|
await run("heartbeat");
|
|
38
64
|
return;
|
|
39
65
|
}
|
|
40
|
-
if (maybeMessage.type === "poke"
|
|
41
|
-
|
|
66
|
+
if (maybeMessage.type === "poke") {
|
|
67
|
+
await run("instinct", maybeMessage.taskId);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (maybeMessage.type === "chat" ||
|
|
42
71
|
maybeMessage.type === "message") {
|
|
43
72
|
await run("instinct");
|
|
44
73
|
return;
|