@ouro.bot/cli 0.1.0-alpha.26 → 0.1.0-alpha.260
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/README.md +187 -191
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +1 -1
- package/changelog.json +1576 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +140 -0
- package/dist/arc/episodes.js +117 -0
- package/dist/arc/intentions.js +133 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +237 -0
- package/dist/arc/presence.js +185 -0
- package/dist/heart/active-work.js +832 -0
- package/dist/heart/agent-entry.js +37 -2
- package/dist/heart/auth/auth-flow.js +447 -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 +111 -0
- package/dist/heart/config-registry.js +304 -0
- package/dist/heart/config.js +63 -30
- package/dist/heart/core.js +644 -196
- package/dist/heart/cross-chat-delivery.js +131 -0
- package/dist/heart/daemon/agent-config-check.js +149 -0
- package/dist/heart/daemon/agent-discovery.js +145 -0
- package/dist/heart/daemon/agent-service.js +360 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +557 -0
- package/dist/heart/daemon/cli-exec.js +1877 -0
- package/dist/heart/daemon/cli-parse.js +759 -0
- package/dist/heart/daemon/cli-render.js +464 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/daemon-cli.js +29 -1179
- package/dist/heart/daemon/daemon-entry.js +216 -4
- package/dist/heart/daemon/daemon-health.js +136 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +153 -12
- package/dist/heart/daemon/daemon-tombstone.js +123 -0
- package/dist/heart/daemon/daemon.js +590 -54
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
- package/dist/heart/daemon/inner-status.js +89 -0
- package/dist/heart/daemon/launchd.js +39 -8
- package/dist/heart/daemon/log-tailer.js +4 -3
- package/dist/heart/daemon/message-router.js +17 -8
- package/dist/heart/daemon/os-cron-deps.js +134 -0
- package/dist/heart/daemon/ouro-bot-entry.js +1 -1
- package/dist/heart/daemon/process-manager.js +123 -0
- package/dist/heart/daemon/run-hooks.js +2 -0
- package/dist/heart/daemon/runtime-logging.js +58 -15
- package/dist/heart/daemon/runtime-metadata.js +101 -0
- package/dist/heart/daemon/runtime-mode.js +67 -0
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +72 -3
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +94 -0
- package/dist/heart/daemon/socket-client.js +276 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/thoughts.js +510 -0
- package/dist/heart/delegation.js +62 -0
- package/dist/heart/habits/habit-migration.js +181 -0
- package/dist/heart/habits/habit-parser.js +119 -0
- package/dist/heart/habits/habit-scheduler.js +371 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +30 -120
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
- package/dist/heart/{daemon → hatch}/specialist-prompt.js +10 -7
- package/dist/heart/{daemon → hatch}/specialist-tools.js +49 -3
- package/dist/heart/identity.js +157 -55
- package/dist/heart/kicks.js +2 -20
- package/dist/heart/mcp/mcp-server.js +653 -0
- package/dist/heart/migrate-config.js +127 -0
- package/dist/heart/model-capabilities.js +59 -0
- package/dist/heart/outlook/outlook-http.js +439 -0
- package/dist/heart/outlook/outlook-read.js +1618 -0
- package/dist/heart/outlook/outlook-render.js +1032 -0
- package/dist/heart/outlook/outlook-types.js +7 -0
- package/dist/heart/outlook/outlook-view.js +194 -0
- package/dist/heart/progress-story.js +42 -0
- package/dist/heart/provider-failover.js +88 -0
- package/dist/heart/provider-ping.js +162 -0
- package/dist/heart/providers/anthropic-token.js +163 -0
- package/dist/heart/providers/anthropic.js +169 -46
- package/dist/heart/providers/azure.js +98 -11
- package/dist/heart/providers/error-classification.js +63 -0
- package/dist/heart/providers/github-copilot.js +136 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +23 -5
- package/dist/heart/providers/openai-codex.js +33 -22
- package/dist/heart/session-activity.js +172 -0
- package/dist/heart/session-recall.js +216 -0
- package/dist/heart/start-of-turn-packet.js +330 -0
- package/dist/heart/streaming.js +36 -27
- package/dist/heart/sync.js +277 -0
- package/dist/heart/target-resolution.js +127 -0
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/tool-activity-callbacks.js +36 -0
- package/dist/heart/tool-description.js +135 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +358 -0
- package/dist/heart/turn-coordinator.js +28 -0
- package/dist/heart/versioning/ouro-bot-global-installer.js +128 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/{daemon → versioning}/ouro-path-installer.js +78 -35
- package/dist/heart/versioning/ouro-version-manager.js +171 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +30 -6
- package/dist/heart/{daemon → versioning}/update-checker.js +12 -2
- package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +41 -3
- package/dist/mind/associative-recall.js +126 -66
- package/dist/mind/bundle-manifest.js +8 -1
- package/dist/mind/context.js +125 -14
- package/dist/mind/{memory.js → diary.js} +68 -96
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/first-impressions.js +16 -2
- package/dist/mind/friends/channel.js +56 -0
- package/dist/mind/friends/group-context.js +144 -0
- package/dist/mind/friends/resolver.js +37 -0
- package/dist/mind/friends/store-file.js +58 -3
- 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/pending.js +76 -9
- package/dist/mind/phrases.js +1 -0
- package/dist/mind/prompt.js +765 -109
- package/dist/mind/scrutiny.js +173 -0
- package/dist/mind/token-estimate.js +8 -12
- package/dist/nerves/coverage/audit.js +1 -1
- package/dist/nerves/coverage/file-completeness.js +50 -5
- package/dist/nerves/coverage/run-artifacts.js +1 -1
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +64 -4
- package/dist/nerves/observation.js +20 -0
- package/dist/nerves/runtime.js +5 -1
- package/dist/outlook-ui/assets/index-Ck8agNeO.js +61 -0
- package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
- package/dist/outlook-ui/index.html +15 -0
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +11 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +319 -0
- package/dist/repertoire/bw-installer.js +79 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +330 -0
- package/dist/repertoire/coding/feedback.js +197 -30
- package/dist/repertoire/coding/manager.js +149 -2
- package/dist/repertoire/coding/spawner.js +55 -9
- package/dist/repertoire/coding/tools.js +170 -7
- package/dist/repertoire/commerce-errors.js +109 -0
- package/dist/repertoire/commerce-self-test.js +156 -0
- package/dist/repertoire/credential-access.js +515 -0
- package/dist/repertoire/duffel-client.js +185 -0
- package/dist/repertoire/github-client.js +14 -55
- package/dist/repertoire/graph-client.js +11 -52
- package/dist/repertoire/guardrails.js +369 -0
- package/dist/repertoire/mcp-client.js +255 -0
- package/dist/repertoire/mcp-manager.js +305 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +14 -23
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tasks/board.js +43 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +28 -10
- package/dist/repertoire/tasks/lifecycle.js +2 -2
- package/dist/repertoire/tasks/parser.js +3 -2
- package/dist/repertoire/tasks/scanner.js +194 -37
- package/dist/repertoire/tasks/transitions.js +11 -28
- package/dist/repertoire/tools-base.js +43 -771
- package/dist/repertoire/tools-bluebubbles.js +201 -0
- package/dist/repertoire/tools-bridge.js +141 -0
- package/dist/repertoire/tools-config.js +185 -0
- package/dist/repertoire/tools-continuity.js +248 -0
- package/dist/repertoire/tools-credential.js +182 -0
- package/dist/repertoire/tools-files.js +342 -0
- package/dist/repertoire/tools-flight.js +224 -0
- package/dist/repertoire/tools-flow.js +62 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-memory.js +347 -0
- package/dist/repertoire/tools-session.js +739 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +243 -0
- package/dist/repertoire/tools-teams.js +12 -62
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +110 -0
- package/dist/repertoire/tools.js +155 -130
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +118 -0
- package/dist/repertoire/vault-setup.js +241 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/attention-queue.js +97 -0
- package/dist/senses/bluebubbles/attachment-cache.js +53 -0
- package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +145 -10
- package/dist/senses/bluebubbles/entry.js +13 -0
- package/dist/senses/bluebubbles/inbound-log.js +110 -0
- package/dist/senses/bluebubbles/index.js +1374 -0
- package/dist/senses/bluebubbles/media.js +455 -0
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +20 -5
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
- package/dist/senses/bluebubbles/runtime-state.js +109 -0
- package/dist/senses/bluebubbles/session-cleanup.js +72 -0
- package/dist/senses/cli/image-paste.js +211 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +416 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +60 -0
- package/dist/senses/cli/streaming-markdown.js +526 -0
- package/dist/senses/cli/tool-display.js +83 -0
- package/dist/senses/cli/tool-render.js +85 -0
- package/dist/senses/cli/tui-store.js +236 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +1 -1
- package/dist/senses/cli-layout.js +187 -0
- package/dist/senses/cli.js +568 -246
- package/dist/senses/commands.js +65 -1
- package/dist/senses/continuity.js +94 -0
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +112 -19
- package/dist/senses/inner-dialog.js +593 -85
- package/dist/senses/pipeline.js +552 -0
- package/dist/senses/shared-turn.js +199 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams.js +664 -165
- package/dist/senses/trust-gate.js +112 -2
- package/package.json +14 -7
- package/skills/agent-commerce.md +106 -0
- package/skills/browser-navigation.md +110 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +81 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/subagent-installer.js +0 -134
- package/dist/senses/bluebubbles-entry.js +0 -11
- package/dist/senses/bluebubbles-media.js +0 -244
- package/dist/senses/bluebubbles.js +0 -421
- package/dist/senses/debug-activity.js +0 -107
- package/subagents/README.md +0 -73
- package/subagents/work-doer.md +0 -235
- package/subagents/work-merger.md +0 -618
- package/subagents/work-planner.md +0 -382
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
- /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
- /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
- /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
- /package/dist/heart/{daemon → versioning}/update-hooks.js +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deriveCommitments = deriveCommitments;
|
|
4
|
+
exports.formatCommitments = formatCommitments;
|
|
5
|
+
const obligations_1 = require("../arc/obligations");
|
|
6
|
+
const runtime_1 = require("../nerves/runtime");
|
|
7
|
+
function describeActiveObligation(obligation) {
|
|
8
|
+
if (obligation.status === "pending") {
|
|
9
|
+
return `i owe ${obligation.origin.friendId}: ${obligation.content}`;
|
|
10
|
+
}
|
|
11
|
+
const surface = obligation.currentSurface?.label;
|
|
12
|
+
const statusText = obligation.status.replaceAll("_", " ");
|
|
13
|
+
if (surface) {
|
|
14
|
+
return `i owe ${obligation.origin.friendId}: ${obligation.content} (${statusText} in ${surface})`;
|
|
15
|
+
}
|
|
16
|
+
return `i owe ${obligation.origin.friendId}: ${obligation.content} (${statusText})`;
|
|
17
|
+
}
|
|
18
|
+
function deriveCommitments(activeWorkFrame, innerJob, pendingObligations) {
|
|
19
|
+
const committedTo = [];
|
|
20
|
+
const completionCriteria = [];
|
|
21
|
+
const safeToIgnore = [];
|
|
22
|
+
// Persistent obligations from the obligation store
|
|
23
|
+
// Sort by status priority: investigating/waiting/updating before pending
|
|
24
|
+
if (pendingObligations && pendingObligations.length > 0) {
|
|
25
|
+
const sorted = [...pendingObligations].sort((a, b) => {
|
|
26
|
+
const advancedA = a.status !== "pending" && a.status !== "fulfilled" ? 0 : 1;
|
|
27
|
+
const advancedB = b.status !== "pending" && b.status !== "fulfilled" ? 0 : 1;
|
|
28
|
+
return advancedA - advancedB;
|
|
29
|
+
});
|
|
30
|
+
let hasAdvancedObligation = false;
|
|
31
|
+
for (const ob of sorted) {
|
|
32
|
+
if (!(0, obligations_1.isOpenObligationStatus)(ob.status))
|
|
33
|
+
continue;
|
|
34
|
+
committedTo.push(describeActiveObligation(ob));
|
|
35
|
+
if (ob.status !== "pending")
|
|
36
|
+
hasAdvancedObligation = true;
|
|
37
|
+
}
|
|
38
|
+
completionCriteria.push("fulfill my outstanding obligations");
|
|
39
|
+
if (hasAdvancedObligation) {
|
|
40
|
+
completionCriteria.push("close my active obligation loops");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Inner job
|
|
44
|
+
if (innerJob.status === "queued" || innerJob.status === "running") {
|
|
45
|
+
const contentSuffix = innerJob.content ? ` -- ${innerJob.content.slice(0, 60)}` : "";
|
|
46
|
+
committedTo.push(`i'm thinking through something privately${contentSuffix}`);
|
|
47
|
+
}
|
|
48
|
+
else if (innerJob.status === "surfaced") {
|
|
49
|
+
committedTo.push("i finished thinking about something and need to bring it back");
|
|
50
|
+
}
|
|
51
|
+
// mustResolveBeforeHandoff
|
|
52
|
+
if (activeWorkFrame.mustResolveBeforeHandoff) {
|
|
53
|
+
committedTo.push("i need to finish what i started before moving on");
|
|
54
|
+
completionCriteria.push("resolve the current thread before moving on");
|
|
55
|
+
}
|
|
56
|
+
// Bridges
|
|
57
|
+
for (const bridge of activeWorkFrame.bridges) {
|
|
58
|
+
committedTo.push(`i have shared work: ${bridge.summary || bridge.objective}`);
|
|
59
|
+
}
|
|
60
|
+
if (activeWorkFrame.bridges.length > 0) {
|
|
61
|
+
completionCriteria.push("keep shared work aligned across sessions");
|
|
62
|
+
}
|
|
63
|
+
// Tasks
|
|
64
|
+
for (const taskName of activeWorkFrame.taskPressure?.liveTaskNames ?? []) {
|
|
65
|
+
committedTo.push(`i'm tracking: ${taskName}`);
|
|
66
|
+
}
|
|
67
|
+
// Obligation completion criteria
|
|
68
|
+
if (innerJob.obligationStatus === "pending") {
|
|
69
|
+
const name = innerJob.origin?.friendName ?? innerJob.origin?.friendId ?? "them";
|
|
70
|
+
completionCriteria.push(`bring my answer back to ${name}`);
|
|
71
|
+
}
|
|
72
|
+
// Default completion criteria
|
|
73
|
+
if (completionCriteria.length === 0) {
|
|
74
|
+
completionCriteria.push("just be present in this conversation");
|
|
75
|
+
}
|
|
76
|
+
// Safe to ignore
|
|
77
|
+
if (innerJob.status === "idle" && !(activeWorkFrame.inner?.hasPending)) {
|
|
78
|
+
safeToIgnore.push("no private thinking in progress");
|
|
79
|
+
}
|
|
80
|
+
if (activeWorkFrame.bridges.length === 0) {
|
|
81
|
+
safeToIgnore.push("no shared work to coordinate");
|
|
82
|
+
}
|
|
83
|
+
if ((activeWorkFrame.taskPressure?.liveTaskNames ?? []).length === 0) {
|
|
84
|
+
safeToIgnore.push("no active tasks to track");
|
|
85
|
+
}
|
|
86
|
+
(0, runtime_1.emitNervesEvent)({
|
|
87
|
+
component: "engine",
|
|
88
|
+
event: "engine.commitments_derive",
|
|
89
|
+
message: "derived commitments frame",
|
|
90
|
+
meta: { committedCount: committedTo.length, criteriaCount: completionCriteria.length },
|
|
91
|
+
});
|
|
92
|
+
return { committedTo, completionCriteria, safeToIgnore };
|
|
93
|
+
}
|
|
94
|
+
function formatCommitments(commitments) {
|
|
95
|
+
const sections = [];
|
|
96
|
+
if (commitments.committedTo.length === 0) {
|
|
97
|
+
sections.push("i'm not holding anything specific right now. i'm free to be present.");
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
sections.push("## what i'm holding right now");
|
|
101
|
+
sections.push("");
|
|
102
|
+
sections.push(commitments.committedTo.map((c) => `- ${c}`).join("\n"));
|
|
103
|
+
}
|
|
104
|
+
sections.push("");
|
|
105
|
+
sections.push("## what \"done\" looks like");
|
|
106
|
+
sections.push(commitments.completionCriteria.map((c) => `- ${c}`).join("\n"));
|
|
107
|
+
sections.push("");
|
|
108
|
+
sections.push("## what i can let go of");
|
|
109
|
+
sections.push(commitments.safeToIgnore.map((c) => `- ${c}`).join("\n"));
|
|
110
|
+
return sections.join("\n");
|
|
111
|
+
}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CONFIG_REGISTRY = void 0;
|
|
4
|
+
exports.getRegistryEntries = getRegistryEntries;
|
|
5
|
+
exports.getRegistryEntriesByTier = getRegistryEntriesByTier;
|
|
6
|
+
exports.getRegistryEntriesByTopic = getRegistryEntriesByTopic;
|
|
7
|
+
exports.getRegistryEntry = getRegistryEntry;
|
|
8
|
+
const runtime_1 = require("../nerves/runtime");
|
|
9
|
+
// --- Validation helpers ---
|
|
10
|
+
const KNOWN_PROVIDERS = ["anthropic", "azure", "minimax", "openai-codex", "github-copilot"];
|
|
11
|
+
function validateNumber(value) {
|
|
12
|
+
if (typeof value !== "number")
|
|
13
|
+
return `expected number, got ${typeof value}`;
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
function validateBoolean(value) {
|
|
17
|
+
if (typeof value !== "boolean")
|
|
18
|
+
return `expected boolean, got ${typeof value}`;
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
function validateString(value) {
|
|
22
|
+
if (typeof value !== "string")
|
|
23
|
+
return `expected string, got ${typeof value}`;
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
function validateStringEnum(allowed) {
|
|
27
|
+
return (value) => {
|
|
28
|
+
if (typeof value !== "string")
|
|
29
|
+
return `expected string, got ${typeof value}`;
|
|
30
|
+
if (!allowed.includes(value))
|
|
31
|
+
return `expected one of [${allowed.join(", ")}], got "${value}"`;
|
|
32
|
+
return undefined;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function validateInteger(min, max) {
|
|
36
|
+
return (value) => {
|
|
37
|
+
if (typeof value !== "number")
|
|
38
|
+
return `expected number, got ${typeof value}`;
|
|
39
|
+
if (!Number.isInteger(value))
|
|
40
|
+
return `expected integer, got ${value}`;
|
|
41
|
+
if (value < min || value > max)
|
|
42
|
+
return `expected integer between ${min} and ${max}, got ${value}`;
|
|
43
|
+
return undefined;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function validateStringArray(value) {
|
|
47
|
+
if (!Array.isArray(value))
|
|
48
|
+
return `expected array, got ${typeof value}`;
|
|
49
|
+
for (let i = 0; i < value.length; i++) {
|
|
50
|
+
if (typeof value[i] !== "string")
|
|
51
|
+
return `expected string at index ${i}, got ${typeof value[i]}`;
|
|
52
|
+
}
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
function validateStringEnumArray(allowed) {
|
|
56
|
+
return (value) => {
|
|
57
|
+
if (!Array.isArray(value))
|
|
58
|
+
return `expected array, got ${typeof value}`;
|
|
59
|
+
for (let i = 0; i < value.length; i++) {
|
|
60
|
+
if (typeof value[i] !== "string")
|
|
61
|
+
return `expected string at index ${i}, got ${typeof value[i]}`;
|
|
62
|
+
if (!allowed.includes(value[i]))
|
|
63
|
+
return `expected one of [${allowed.join(", ")}] at index ${i}, got "${value[i]}"`;
|
|
64
|
+
}
|
|
65
|
+
return undefined;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function validateObject(requiredFields) {
|
|
69
|
+
return (value) => {
|
|
70
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
71
|
+
return `expected object, got ${Array.isArray(value) ? "array" : typeof value}`;
|
|
72
|
+
}
|
|
73
|
+
const obj = value;
|
|
74
|
+
for (const [field, validator] of Object.entries(requiredFields)) {
|
|
75
|
+
if (!(field in obj))
|
|
76
|
+
return `missing required field "${field}"`;
|
|
77
|
+
const err = validator(obj[field]);
|
|
78
|
+
if (err)
|
|
79
|
+
return `field "${field}": ${err}`;
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const registryData = [
|
|
85
|
+
// --- Managed: harness-only ---
|
|
86
|
+
{
|
|
87
|
+
path: "version",
|
|
88
|
+
tier: "managed",
|
|
89
|
+
description: "Agent config schema version. Managed by the harness. Must be an integer >= 1.",
|
|
90
|
+
default: 2,
|
|
91
|
+
effects: "Controls which config migrations apply on load. Changing incorrectly can corrupt config.",
|
|
92
|
+
topics: ["schema", "migration"],
|
|
93
|
+
validate: validateNumber,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
path: "enabled",
|
|
97
|
+
tier: "managed",
|
|
98
|
+
description: "Whether the agent is enabled. Managed by the harness. When false, the agent refuses to start.",
|
|
99
|
+
default: true,
|
|
100
|
+
effects: "Disables all agent functionality when set to false.",
|
|
101
|
+
topics: ["lifecycle", "activation"],
|
|
102
|
+
validate: validateBoolean,
|
|
103
|
+
},
|
|
104
|
+
// --- Self: agent-configurable ---
|
|
105
|
+
{
|
|
106
|
+
path: "mcpServers",
|
|
107
|
+
tier: "self",
|
|
108
|
+
description: "MCP server configurations. Maps server name to command, args, and env. The agent can add or remove MCP servers.",
|
|
109
|
+
default: undefined,
|
|
110
|
+
effects: "Adds or removes MCP tool servers.",
|
|
111
|
+
topics: ["tools", "mcp", "servers", "extensions"],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
path: "humanFacing.provider",
|
|
115
|
+
tier: "self",
|
|
116
|
+
description: "Provider for human-facing interactions (CLI, Teams, BlueBubbles).",
|
|
117
|
+
default: "anthropic",
|
|
118
|
+
effects: "Changes the LLM provider used for all human-facing conversations. Affects quality, latency, and cost.",
|
|
119
|
+
topics: ["model", "provider", "llm", "human"],
|
|
120
|
+
validate: validateStringEnum(KNOWN_PROVIDERS),
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
path: "humanFacing.model",
|
|
124
|
+
tier: "self",
|
|
125
|
+
description: "Model name for human-facing interactions.",
|
|
126
|
+
default: "claude-opus-4-6",
|
|
127
|
+
effects: "Changes the specific model used for human-facing conversations.",
|
|
128
|
+
topics: ["model", "provider", "llm", "human"],
|
|
129
|
+
validate: validateString,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
path: "agentFacing.provider",
|
|
133
|
+
tier: "self",
|
|
134
|
+
description: "Provider for agent-facing interactions (inner dialog, delegation).",
|
|
135
|
+
default: "anthropic",
|
|
136
|
+
effects: "Changes the LLM provider used for inner dialog and agent-to-agent communication.",
|
|
137
|
+
topics: ["model", "provider", "llm", "agent", "inner-dialog"],
|
|
138
|
+
validate: validateStringEnum(KNOWN_PROVIDERS),
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
path: "agentFacing.model",
|
|
142
|
+
tier: "self",
|
|
143
|
+
description: "Model name for agent-facing interactions.",
|
|
144
|
+
default: "claude-opus-4-6",
|
|
145
|
+
effects: "Changes the specific model used for inner dialog and agent-to-agent communication.",
|
|
146
|
+
topics: ["model", "provider", "llm", "agent", "inner-dialog"],
|
|
147
|
+
validate: validateString,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
path: "context.maxTokens",
|
|
151
|
+
tier: "self",
|
|
152
|
+
description: "Maximum context window size in tokens.",
|
|
153
|
+
default: 80000,
|
|
154
|
+
effects: "Larger values allow more context but increase cost and latency. Must match model capability.",
|
|
155
|
+
topics: ["context", "tokens", "memory", "performance"],
|
|
156
|
+
validate: validateInteger(1000, 1000000),
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
path: "senses.cli",
|
|
160
|
+
tier: "self",
|
|
161
|
+
description: "CLI sense configuration. Controls whether the CLI interface is enabled.",
|
|
162
|
+
default: { enabled: true },
|
|
163
|
+
effects: "Enables or disables the CLI (terminal) interaction channel.",
|
|
164
|
+
topics: ["senses", "cli", "channels", "interface"],
|
|
165
|
+
validate: validateObject({ enabled: validateBoolean }),
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
path: "senses.teams",
|
|
169
|
+
tier: "self",
|
|
170
|
+
description: "Teams sense configuration. Controls whether the Teams interface is enabled.",
|
|
171
|
+
default: { enabled: false },
|
|
172
|
+
effects: "Enables or disables the Microsoft Teams interaction channel.",
|
|
173
|
+
topics: ["senses", "teams", "channels", "interface"],
|
|
174
|
+
validate: validateObject({ enabled: validateBoolean }),
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
path: "senses.bluebubbles",
|
|
178
|
+
tier: "self",
|
|
179
|
+
description: "BlueBubbles sense configuration. Controls whether the iMessage interface is enabled.",
|
|
180
|
+
default: { enabled: false },
|
|
181
|
+
effects: "Enables or disables the BlueBubbles (iMessage) interaction channel.",
|
|
182
|
+
topics: ["senses", "bluebubbles", "imessage", "channels", "interface"],
|
|
183
|
+
validate: validateObject({ enabled: validateBoolean }),
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
path: "sync.enabled",
|
|
187
|
+
tier: "self",
|
|
188
|
+
description: "Whether git-based bundle sync is enabled.",
|
|
189
|
+
default: false,
|
|
190
|
+
effects: "Enables automatic synchronization of agent state via git. Requires sync.remote to be configured.",
|
|
191
|
+
topics: ["sync", "git", "state", "backup"],
|
|
192
|
+
validate: validateBoolean,
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
path: "sync.remote",
|
|
196
|
+
tier: "self",
|
|
197
|
+
description: "Git remote name used for bundle sync.",
|
|
198
|
+
default: "origin",
|
|
199
|
+
effects: "Controls which git remote is used when sync is enabled.",
|
|
200
|
+
topics: ["sync", "git", "remote"],
|
|
201
|
+
validate: validateString,
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
path: "context.contextMargin",
|
|
205
|
+
tier: "self",
|
|
206
|
+
description: "Percentage of context window reserved as margin before compaction triggers.",
|
|
207
|
+
default: 20,
|
|
208
|
+
effects: "Higher values trigger compaction earlier, preserving more headroom. Lower values use more context.",
|
|
209
|
+
topics: ["context", "compaction", "memory", "performance"],
|
|
210
|
+
validate: validateInteger(0, 100),
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
path: "phrases.thinking",
|
|
214
|
+
tier: "self",
|
|
215
|
+
description: "Array of phrases displayed while the agent is thinking.",
|
|
216
|
+
default: ["working"],
|
|
217
|
+
effects: "Changes the thinking indicator text shown to users. Purely cosmetic.",
|
|
218
|
+
topics: ["phrases", "ux", "display", "personality"],
|
|
219
|
+
validate: validateStringArray,
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
path: "phrases.tool",
|
|
223
|
+
tier: "self",
|
|
224
|
+
description: "Array of phrases displayed while the agent is running a tool.",
|
|
225
|
+
default: ["running tool"],
|
|
226
|
+
effects: "Changes the tool-use indicator text shown to users. Purely cosmetic.",
|
|
227
|
+
topics: ["phrases", "ux", "display", "personality"],
|
|
228
|
+
validate: validateStringArray,
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
path: "phrases.followup",
|
|
232
|
+
tier: "self",
|
|
233
|
+
description: "Array of phrases displayed during follow-up processing.",
|
|
234
|
+
default: ["processing"],
|
|
235
|
+
effects: "Changes the follow-up indicator text shown to users. Purely cosmetic.",
|
|
236
|
+
topics: ["phrases", "ux", "display", "personality"],
|
|
237
|
+
validate: validateStringArray,
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
path: "shell.defaultTimeout",
|
|
241
|
+
tier: "self",
|
|
242
|
+
description: "Default timeout in milliseconds for shell command execution.",
|
|
243
|
+
default: undefined,
|
|
244
|
+
effects: "Controls how long shell commands run before timing out. Undefined uses system default.",
|
|
245
|
+
topics: ["shell", "timeout", "execution", "tools"],
|
|
246
|
+
validate: validateInteger(1000, 600000),
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
path: "logging.level",
|
|
250
|
+
tier: "self",
|
|
251
|
+
description: "Minimum log level: debug, info, warn, or error.",
|
|
252
|
+
default: undefined,
|
|
253
|
+
effects: "Controls verbosity of runtime logging. Lower levels produce more output.",
|
|
254
|
+
topics: ["logging", "debug", "diagnostics"],
|
|
255
|
+
validate: validateStringEnum(["debug", "info", "warn", "error"]),
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
path: "logging.sinks",
|
|
259
|
+
tier: "self",
|
|
260
|
+
description: "Array of log sink types: 'terminal' and/or 'ndjson'.",
|
|
261
|
+
default: undefined,
|
|
262
|
+
effects: "Controls where log output is directed. Terminal shows in console, ndjson writes structured logs.",
|
|
263
|
+
topics: ["logging", "output", "diagnostics"],
|
|
264
|
+
validate: validateStringEnumArray(["terminal", "ndjson"]),
|
|
265
|
+
},
|
|
266
|
+
];
|
|
267
|
+
exports.CONFIG_REGISTRY = new Map(registryData.map((entry) => [entry.path, entry]));
|
|
268
|
+
function getRegistryEntries() {
|
|
269
|
+
(0, runtime_1.emitNervesEvent)({
|
|
270
|
+
component: "heart",
|
|
271
|
+
event: "config_registry.access",
|
|
272
|
+
message: "listing all registry entries",
|
|
273
|
+
meta: { count: exports.CONFIG_REGISTRY.size },
|
|
274
|
+
});
|
|
275
|
+
return [...exports.CONFIG_REGISTRY.values()];
|
|
276
|
+
}
|
|
277
|
+
function getRegistryEntriesByTier(tier) {
|
|
278
|
+
(0, runtime_1.emitNervesEvent)({
|
|
279
|
+
component: "heart",
|
|
280
|
+
event: "config_registry.access",
|
|
281
|
+
message: `filtering registry entries by tier ${tier}`,
|
|
282
|
+
meta: { tier },
|
|
283
|
+
});
|
|
284
|
+
return [...exports.CONFIG_REGISTRY.values()].filter((entry) => entry.tier === tier);
|
|
285
|
+
}
|
|
286
|
+
function getRegistryEntriesByTopic(topic) {
|
|
287
|
+
const needle = topic.toLowerCase();
|
|
288
|
+
(0, runtime_1.emitNervesEvent)({
|
|
289
|
+
component: "heart",
|
|
290
|
+
event: "config_registry.access",
|
|
291
|
+
message: `filtering registry entries by topic "${topic}"`,
|
|
292
|
+
meta: { topic },
|
|
293
|
+
});
|
|
294
|
+
return [...exports.CONFIG_REGISTRY.values()].filter((entry) => entry.topics.some((t) => t.toLowerCase().includes(needle)));
|
|
295
|
+
}
|
|
296
|
+
function getRegistryEntry(path) {
|
|
297
|
+
(0, runtime_1.emitNervesEvent)({
|
|
298
|
+
component: "heart",
|
|
299
|
+
event: "config_registry.access",
|
|
300
|
+
message: `looking up registry entry for "${path}"`,
|
|
301
|
+
meta: { path },
|
|
302
|
+
});
|
|
303
|
+
return exports.CONFIG_REGISTRY.get(path);
|
|
304
|
+
}
|
package/dist/heart/config.js
CHANGED
|
@@ -40,6 +40,8 @@ exports.getAzureConfig = getAzureConfig;
|
|
|
40
40
|
exports.getMinimaxConfig = getMinimaxConfig;
|
|
41
41
|
exports.getAnthropicConfig = getAnthropicConfig;
|
|
42
42
|
exports.getOpenAICodexConfig = getOpenAICodexConfig;
|
|
43
|
+
exports.getGithubCopilotConfig = getGithubCopilotConfig;
|
|
44
|
+
exports.getProviderConfig = getProviderConfig;
|
|
43
45
|
exports.getTeamsConfig = getTeamsConfig;
|
|
44
46
|
exports.getTeamsSecondaryConfig = getTeamsSecondaryConfig;
|
|
45
47
|
exports.getContextConfig = getContextConfig;
|
|
@@ -49,38 +51,40 @@ exports.getTeamsChannelConfig = getTeamsChannelConfig;
|
|
|
49
51
|
exports.getBlueBubblesConfig = getBlueBubblesConfig;
|
|
50
52
|
exports.getBlueBubblesChannelConfig = getBlueBubblesChannelConfig;
|
|
51
53
|
exports.getIntegrationsConfig = getIntegrationsConfig;
|
|
54
|
+
exports.getSyncConfig = getSyncConfig;
|
|
52
55
|
exports.getOpenAIEmbeddingsApiKey = getOpenAIEmbeddingsApiKey;
|
|
53
56
|
exports.getLogsDir = getLogsDir;
|
|
57
|
+
exports.sanitizeKey = sanitizeKey;
|
|
58
|
+
exports.slugify = slugify;
|
|
59
|
+
exports.resolveSessionPath = resolveSessionPath;
|
|
54
60
|
exports.sessionPath = sessionPath;
|
|
55
61
|
exports.logPath = logPath;
|
|
56
62
|
const fs = __importStar(require("fs"));
|
|
57
63
|
const path = __importStar(require("path"));
|
|
58
|
-
const os = __importStar(require("os"));
|
|
59
64
|
const identity_1 = require("./identity");
|
|
60
65
|
const runtime_1 = require("../nerves/runtime");
|
|
61
66
|
const DEFAULT_SECRETS_TEMPLATE = {
|
|
62
67
|
providers: {
|
|
63
|
-
// Keep provider field ordering consistent: model first, then auth credentials,
|
|
64
|
-
// then provider-specific transport fields.
|
|
65
68
|
azure: {
|
|
66
|
-
modelName: "",
|
|
67
69
|
apiKey: "",
|
|
68
70
|
endpoint: "",
|
|
69
71
|
deployment: "",
|
|
70
72
|
apiVersion: "2025-04-01-preview",
|
|
73
|
+
managedIdentityClientId: "",
|
|
71
74
|
},
|
|
72
75
|
minimax: {
|
|
73
|
-
model: "",
|
|
74
76
|
apiKey: "",
|
|
75
77
|
},
|
|
76
78
|
anthropic: {
|
|
77
|
-
model: "claude-opus-4-6",
|
|
78
79
|
setupToken: "",
|
|
79
80
|
},
|
|
80
81
|
"openai-codex": {
|
|
81
|
-
model: "gpt-5.4",
|
|
82
82
|
oauthAccessToken: "",
|
|
83
83
|
},
|
|
84
|
+
"github-copilot": {
|
|
85
|
+
githubToken: "",
|
|
86
|
+
baseUrl: "",
|
|
87
|
+
},
|
|
84
88
|
},
|
|
85
89
|
teams: {
|
|
86
90
|
clientId: "",
|
|
@@ -113,6 +117,9 @@ const DEFAULT_SECRETS_TEMPLATE = {
|
|
|
113
117
|
webhookPath: "/bluebubbles-webhook",
|
|
114
118
|
requestTimeoutMs: 30000,
|
|
115
119
|
},
|
|
120
|
+
vault: {
|
|
121
|
+
masterPassword: "",
|
|
122
|
+
},
|
|
116
123
|
integrations: {
|
|
117
124
|
perplexityApiKey: "",
|
|
118
125
|
openaiEmbeddingsApiKey: "",
|
|
@@ -125,6 +132,7 @@ function defaultRuntimeConfig() {
|
|
|
125
132
|
minimax: { ...DEFAULT_SECRETS_TEMPLATE.providers.minimax },
|
|
126
133
|
anthropic: { ...DEFAULT_SECRETS_TEMPLATE.providers.anthropic },
|
|
127
134
|
"openai-codex": { ...DEFAULT_SECRETS_TEMPLATE.providers["openai-codex"] },
|
|
135
|
+
"github-copilot": { ...DEFAULT_SECRETS_TEMPLATE.providers["github-copilot"] },
|
|
128
136
|
},
|
|
129
137
|
teams: { ...DEFAULT_SECRETS_TEMPLATE.teams },
|
|
130
138
|
teamsSecondary: { ...DEFAULT_SECRETS_TEMPLATE.teamsSecondary },
|
|
@@ -133,10 +141,11 @@ function defaultRuntimeConfig() {
|
|
|
133
141
|
teamsChannel: { ...DEFAULT_SECRETS_TEMPLATE.teamsChannel },
|
|
134
142
|
bluebubbles: { ...DEFAULT_SECRETS_TEMPLATE.bluebubbles },
|
|
135
143
|
bluebubblesChannel: { ...DEFAULT_SECRETS_TEMPLATE.bluebubblesChannel },
|
|
144
|
+
vault: { ...DEFAULT_SECRETS_TEMPLATE.vault },
|
|
136
145
|
integrations: { ...DEFAULT_SECRETS_TEMPLATE.integrations },
|
|
137
146
|
};
|
|
138
147
|
}
|
|
139
|
-
let
|
|
148
|
+
let _runtimeConfigOverride = null;
|
|
140
149
|
let _testContextOverride = null;
|
|
141
150
|
function resolveConfigPath() {
|
|
142
151
|
return (0, identity_1.getAgentSecretsPath)();
|
|
@@ -158,15 +167,6 @@ function deepMerge(defaults, partial) {
|
|
|
158
167
|
return result;
|
|
159
168
|
}
|
|
160
169
|
function loadConfig() {
|
|
161
|
-
if (_cachedConfig) {
|
|
162
|
-
(0, runtime_1.emitNervesEvent)({
|
|
163
|
-
event: "config.load",
|
|
164
|
-
component: "config/identity",
|
|
165
|
-
message: "config loaded from cache",
|
|
166
|
-
meta: { source: "cache" },
|
|
167
|
-
});
|
|
168
|
-
return _cachedConfig;
|
|
169
|
-
}
|
|
170
170
|
const configPath = resolveConfigPath();
|
|
171
171
|
// Auto-create config directory if it doesn't exist
|
|
172
172
|
const configDir = path.dirname(configPath);
|
|
@@ -227,7 +227,10 @@ function loadConfig() {
|
|
|
227
227
|
},
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
|
-
|
|
230
|
+
const mergedConfig = deepMerge(defaultRuntimeConfig(), sanitizedFileData);
|
|
231
|
+
const config = _runtimeConfigOverride
|
|
232
|
+
? deepMerge(mergedConfig, _runtimeConfigOverride)
|
|
233
|
+
: mergedConfig;
|
|
231
234
|
(0, runtime_1.emitNervesEvent)({
|
|
232
235
|
event: "config.load",
|
|
233
236
|
component: "config/identity",
|
|
@@ -235,22 +238,22 @@ function loadConfig() {
|
|
|
235
238
|
meta: {
|
|
236
239
|
source: "disk",
|
|
237
240
|
used_defaults_only: Object.keys(fileData).length === 0,
|
|
241
|
+
override_applied: _runtimeConfigOverride !== null,
|
|
238
242
|
},
|
|
239
243
|
});
|
|
240
|
-
return
|
|
244
|
+
return config;
|
|
241
245
|
}
|
|
242
246
|
function resetConfigCache() {
|
|
243
|
-
|
|
247
|
+
_runtimeConfigOverride = null;
|
|
244
248
|
_testContextOverride = null;
|
|
245
249
|
}
|
|
246
250
|
function patchRuntimeConfig(partial) {
|
|
247
|
-
loadConfig(); // ensure _cachedConfig exists
|
|
248
251
|
const contextPatch = partial.context;
|
|
249
252
|
if (contextPatch) {
|
|
250
253
|
const base = _testContextOverride ?? identity_1.DEFAULT_AGENT_CONTEXT;
|
|
251
254
|
_testContextOverride = deepMerge(base, contextPatch);
|
|
252
255
|
}
|
|
253
|
-
|
|
256
|
+
_runtimeConfigOverride = deepMerge((_runtimeConfigOverride ?? {}), partial);
|
|
254
257
|
}
|
|
255
258
|
function getAzureConfig() {
|
|
256
259
|
const config = loadConfig();
|
|
@@ -268,6 +271,14 @@ function getOpenAICodexConfig() {
|
|
|
268
271
|
const config = loadConfig();
|
|
269
272
|
return { ...config.providers["openai-codex"] };
|
|
270
273
|
}
|
|
274
|
+
function getGithubCopilotConfig() {
|
|
275
|
+
const config = loadConfig();
|
|
276
|
+
return { ...config.providers["github-copilot"] };
|
|
277
|
+
}
|
|
278
|
+
function getProviderConfig(provider) {
|
|
279
|
+
const config = loadConfig();
|
|
280
|
+
return { ...config.providers[provider] };
|
|
281
|
+
}
|
|
271
282
|
function getTeamsConfig() {
|
|
272
283
|
const config = loadConfig();
|
|
273
284
|
return { ...config.teams };
|
|
@@ -335,24 +346,46 @@ function getIntegrationsConfig() {
|
|
|
335
346
|
const config = loadConfig();
|
|
336
347
|
return { ...config.integrations };
|
|
337
348
|
}
|
|
349
|
+
function getSyncConfig() {
|
|
350
|
+
try {
|
|
351
|
+
const agentConfig = (0, identity_1.loadAgentConfig)();
|
|
352
|
+
return {
|
|
353
|
+
enabled: agentConfig.sync?.enabled ?? false,
|
|
354
|
+
remote: agentConfig.sync?.remote ?? "origin",
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
/* v8 ignore next -- defensive: loadAgentConfig failure in test/bootstrap @preserve */
|
|
359
|
+
return { enabled: false, remote: "origin" };
|
|
360
|
+
}
|
|
361
|
+
}
|
|
338
362
|
function getOpenAIEmbeddingsApiKey() {
|
|
339
363
|
return getIntegrationsConfig().openaiEmbeddingsApiKey;
|
|
340
364
|
}
|
|
341
365
|
function getLogsDir() {
|
|
342
|
-
return path.join(
|
|
366
|
+
return path.join((0, identity_1.getAgentRoot)(), "state", "logs");
|
|
343
367
|
}
|
|
344
368
|
function sanitizeKey(key) {
|
|
345
369
|
return key.replace(/[/:]/g, "_");
|
|
346
370
|
}
|
|
347
|
-
function
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
371
|
+
function slugify(value) {
|
|
372
|
+
return value
|
|
373
|
+
.trim()
|
|
374
|
+
.toLowerCase()
|
|
375
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
376
|
+
.replace(/^-+/, "")
|
|
377
|
+
.replace(/-+$/, "");
|
|
378
|
+
}
|
|
379
|
+
function resolveSessionPath(friendId, channel, key, options) {
|
|
380
|
+
const dir = path.join((0, identity_1.getAgentRoot)(), "state", "sessions", friendId, channel);
|
|
381
|
+
if (options?.ensureDir) {
|
|
382
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
383
|
+
}
|
|
354
384
|
return path.join(dir, sanitizeKey(key) + ".json");
|
|
355
385
|
}
|
|
386
|
+
function sessionPath(friendId, channel, key) {
|
|
387
|
+
return resolveSessionPath(friendId, channel, key, { ensureDir: true });
|
|
388
|
+
}
|
|
356
389
|
function logPath(channel, key) {
|
|
357
390
|
return path.join(getLogsDir(), channel, sanitizeKey(key) + ".ndjson");
|
|
358
391
|
}
|