@mono-agent/agent-app 0.20.14 → 0.21.0
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 +227 -80
- package/dist/adapter-send-tools.d.ts +3 -2
- package/dist/adapter-send-tools.d.ts.map +1 -1
- package/dist/adapter-send-tools.js +15 -5
- package/dist/adapter-send-tools.js.map +1 -1
- package/dist/app-controller-channels.d.ts +2 -0
- package/dist/app-controller-channels.d.ts.map +1 -1
- package/dist/app-controller-channels.js +10 -1
- package/dist/app-controller-channels.js.map +1 -1
- package/dist/app-controller-maintenance.d.ts +3 -1
- package/dist/app-controller-maintenance.d.ts.map +1 -1
- package/dist/app-controller-maintenance.js +3 -0
- package/dist/app-controller-maintenance.js.map +1 -1
- package/dist/app-controller-responder.d.ts +2 -0
- package/dist/app-controller-responder.d.ts.map +1 -1
- package/dist/app-controller-responder.js +21 -17
- package/dist/app-controller-responder.js.map +1 -1
- package/dist/app-controller-traceability.d.ts.map +1 -1
- package/dist/app-controller-traceability.js +3 -0
- package/dist/app-controller-traceability.js.map +1 -1
- package/dist/app-controller-types.d.ts +1 -0
- package/dist/app-controller-types.d.ts.map +1 -1
- package/dist/app-controller.d.ts +2 -0
- package/dist/app-controller.d.ts.map +1 -1
- package/dist/app-controller.js +3 -0
- package/dist/app-controller.js.map +1 -1
- package/dist/artifact-retention.js +11 -0
- package/dist/artifact-retention.js.map +1 -1
- package/dist/background.d.ts +0 -6
- package/dist/background.d.ts.map +1 -1
- package/dist/background.js +5 -58
- package/dist/background.js.map +1 -1
- package/dist/channel-drivers/tui.d.ts +2 -2
- package/dist/channel-drivers/tui.d.ts.map +1 -1
- package/dist/channel-drivers/tui.js +27 -8
- package/dist/channel-drivers/tui.js.map +1 -1
- package/dist/cli-args.d.ts +4 -5
- package/dist/cli-args.d.ts.map +1 -1
- package/dist/cli-args.js +20 -19
- package/dist/cli-args.js.map +1 -1
- package/dist/cli-background-command.d.ts.map +1 -1
- package/dist/cli-background-command.js +4 -0
- package/dist/cli-background-command.js.map +1 -1
- package/dist/cli-commands.d.ts.map +1 -1
- package/dist/cli-commands.js +13 -2
- package/dist/cli-commands.js.map +1 -1
- package/dist/cli-help.d.ts.map +1 -1
- package/dist/cli-help.js +33 -19
- package/dist/cli-help.js.map +1 -1
- package/dist/cli-init-command.d.ts.map +1 -1
- package/dist/cli-init-command.js +26 -22
- package/dist/cli-init-command.js.map +1 -1
- package/dist/cli-install-skill-command.d.ts.map +1 -1
- package/dist/cli-install-skill-command.js +12 -3
- package/dist/cli-install-skill-command.js.map +1 -1
- package/dist/config-reference.d.ts +1 -0
- package/dist/config-reference.d.ts.map +1 -1
- package/dist/config-reference.js +66 -10
- package/dist/config-reference.js.map +1 -1
- package/dist/configured-agent.d.ts +9 -1
- package/dist/configured-agent.d.ts.map +1 -1
- package/dist/configured-agent.js +95 -29
- package/dist/configured-agent.js.map +1 -1
- package/dist/cron-control-store.d.ts.map +1 -1
- package/dist/cron-control-store.js +4 -2
- package/dist/cron-control-store.js.map +1 -1
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +215 -45
- package/dist/doctor.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interaction-bridge.d.ts +3 -3
- package/dist/interaction-bridge.d.ts.map +1 -1
- package/dist/interaction-bridge.js +27 -10
- package/dist/interaction-bridge.js.map +1 -1
- package/dist/launchd.d.ts +2 -0
- package/dist/launchd.d.ts.map +1 -1
- package/dist/launchd.js +3 -0
- package/dist/launchd.js.map +1 -1
- package/dist/local-tui-session.d.ts +14 -0
- package/dist/local-tui-session.d.ts.map +1 -0
- package/dist/local-tui-session.js +100 -0
- package/dist/local-tui-session.js.map +1 -0
- package/dist/mcp-apps.d.ts.map +1 -1
- package/dist/mcp-apps.js +3 -0
- package/dist/mcp-apps.js.map +1 -1
- package/dist/memory-journal.d.ts +53 -0
- package/dist/memory-journal.d.ts.map +1 -0
- package/dist/memory-journal.js +586 -0
- package/dist/memory-journal.js.map +1 -0
- package/dist/memory-recall.d.ts.map +1 -1
- package/dist/memory-recall.js +16 -2
- package/dist/memory-recall.js.map +1 -1
- package/dist/memory-retrieval.d.ts +9 -0
- package/dist/memory-retrieval.d.ts.map +1 -1
- package/dist/memory-retrieval.js +20 -0
- package/dist/memory-retrieval.js.map +1 -1
- package/dist/modules/base.js +1 -1
- package/dist/modules/base.js.map +1 -1
- package/dist/modules/known-tools.d.ts +1 -1
- package/dist/modules/known-tools.d.ts.map +1 -1
- package/dist/modules/known-tools.js +1 -0
- package/dist/modules/known-tools.js.map +1 -1
- package/dist/monitors-command.js +12 -2
- package/dist/monitors-command.js.map +1 -1
- package/dist/monitors-config.d.ts +4 -1
- package/dist/monitors-config.d.ts.map +1 -1
- package/dist/monitors-config.js +5 -1
- package/dist/monitors-config.js.map +1 -1
- package/dist/monitors-context.d.ts.map +1 -1
- package/dist/monitors-context.js +14 -2
- package/dist/monitors-context.js.map +1 -1
- package/dist/monitors-service.d.ts +2 -2
- package/dist/monitors-service.d.ts.map +1 -1
- package/dist/monitors-service.js +227 -96
- package/dist/monitors-service.js.map +1 -1
- package/dist/monitors-store.d.ts +11 -1
- package/dist/monitors-store.d.ts.map +1 -1
- package/dist/monitors-store.js +36 -6
- package/dist/monitors-store.js.map +1 -1
- package/dist/notify-destinations.d.ts +3 -2
- package/dist/notify-destinations.d.ts.map +1 -1
- package/dist/notify-destinations.js +6 -7
- package/dist/notify-destinations.js.map +1 -1
- package/dist/posted-reply-history.d.ts.map +1 -1
- package/dist/posted-reply-history.js +40 -3
- package/dist/posted-reply-history.js.map +1 -1
- package/dist/proactive-notify.d.ts +20 -1
- package/dist/proactive-notify.d.ts.map +1 -1
- package/dist/proactive-notify.js +56 -3
- package/dist/proactive-notify.js.map +1 -1
- package/dist/process-job-channel-routing.js +2 -1
- package/dist/process-job-channel-routing.js.map +1 -1
- package/dist/process-job-output-tail.d.ts +53 -0
- package/dist/process-job-output-tail.d.ts.map +1 -0
- package/dist/process-job-output-tail.js +257 -0
- package/dist/process-job-output-tail.js.map +1 -0
- package/dist/process-jobs-config.d.ts +1 -1
- package/dist/process-jobs-config.js +1 -1
- package/dist/process-jobs-config.js.map +1 -1
- package/dist/process-jobs-context.d.ts +3 -1
- package/dist/process-jobs-context.d.ts.map +1 -1
- package/dist/process-jobs-context.js +44 -11
- package/dist/process-jobs-context.js.map +1 -1
- package/dist/process-jobs-runtime.d.ts.map +1 -1
- package/dist/process-jobs-runtime.js +14 -0
- package/dist/process-jobs-runtime.js.map +1 -1
- package/dist/process-jobs-service.d.ts.map +1 -1
- package/dist/process-jobs-service.js +115 -23
- package/dist/process-jobs-service.js.map +1 -1
- package/dist/process-jobs-store.d.ts +3 -1
- package/dist/process-jobs-store.d.ts.map +1 -1
- package/dist/process-jobs-store.js +4 -1
- package/dist/process-jobs-store.js.map +1 -1
- package/dist/process-output-redaction.d.ts +26 -1
- package/dist/process-output-redaction.d.ts.map +1 -1
- package/dist/process-output-redaction.js +164 -2
- package/dist/process-output-redaction.js.map +1 -1
- package/dist/project-skills.d.ts +11 -5
- package/dist/project-skills.d.ts.map +1 -1
- package/dist/project-skills.js +88 -39
- package/dist/project-skills.js.map +1 -1
- package/dist/provider-auth-checks.d.ts +27 -0
- package/dist/provider-auth-checks.d.ts.map +1 -0
- package/dist/provider-auth-checks.js +349 -0
- package/dist/provider-auth-checks.js.map +1 -0
- package/dist/provider-auth-observations.d.ts +22 -0
- package/dist/provider-auth-observations.d.ts.map +1 -0
- package/dist/provider-auth-observations.js +139 -0
- package/dist/provider-auth-observations.js.map +1 -0
- package/dist/provider-auth-operator.d.ts +19 -0
- package/dist/provider-auth-operator.d.ts.map +1 -0
- package/dist/provider-auth-operator.js +560 -0
- package/dist/provider-auth-operator.js.map +1 -0
- package/dist/provider-auth-status.d.ts +20 -0
- package/dist/provider-auth-status.d.ts.map +1 -0
- package/dist/provider-auth-status.js +235 -0
- package/dist/provider-auth-status.js.map +1 -0
- package/dist/provider-model-catalog.d.ts +17 -0
- package/dist/provider-model-catalog.d.ts.map +1 -1
- package/dist/provider-model-catalog.js +113 -2
- package/dist/provider-model-catalog.js.map +1 -1
- package/dist/provider-setup.d.ts +22 -0
- package/dist/provider-setup.d.ts.map +1 -1
- package/dist/provider-setup.js +101 -15
- package/dist/provider-setup.js.map +1 -1
- package/dist/reply-artifacts.d.ts +3 -1
- package/dist/reply-artifacts.d.ts.map +1 -1
- package/dist/reply-artifacts.js +45 -10
- package/dist/reply-artifacts.js.map +1 -1
- package/dist/request-model-override.d.ts +11 -2
- package/dist/request-model-override.d.ts.map +1 -1
- package/dist/request-model-override.js +51 -1
- package/dist/request-model-override.js.map +1 -1
- package/dist/request-scoped-mcp.d.ts +3 -0
- package/dist/request-scoped-mcp.d.ts.map +1 -1
- package/dist/request-scoped-mcp.js +1 -1
- package/dist/request-scoped-mcp.js.map +1 -1
- package/dist/run-history.d.ts.map +1 -1
- package/dist/run-history.js +56 -13
- package/dist/run-history.js.map +1 -1
- package/dist/seen-conversations.d.ts +4 -3
- package/dist/seen-conversations.d.ts.map +1 -1
- package/dist/seen-conversations.js +6 -5
- package/dist/seen-conversations.js.map +1 -1
- package/dist/session-history.d.ts +14 -0
- package/dist/session-history.d.ts.map +1 -1
- package/dist/session-history.js +120 -5
- package/dist/session-history.js.map +1 -1
- package/dist/systemd-command.d.ts +8 -0
- package/dist/systemd-command.d.ts.map +1 -0
- package/dist/systemd-command.js +206 -0
- package/dist/systemd-command.js.map +1 -0
- package/dist/systemd.d.ts +51 -0
- package/dist/systemd.d.ts.map +1 -0
- package/dist/systemd.js +299 -0
- package/dist/systemd.js.map +1 -0
- package/dist/tool-output-artifacts.d.ts +4 -0
- package/dist/tool-output-artifacts.d.ts.map +1 -0
- package/dist/tool-output-artifacts.js +17 -0
- package/dist/tool-output-artifacts.js.map +1 -0
- package/dist/tui-command.d.ts +0 -45
- package/dist/tui-command.d.ts.map +1 -1
- package/dist/tui-command.js +27 -264
- package/dist/tui-command.js.map +1 -1
- package/dist/untrusted-text.js +2 -2
- package/dist/web-command.d.ts +3 -0
- package/dist/web-command.d.ts.map +1 -1
- package/dist/web-command.js +112 -7
- package/dist/web-command.js.map +1 -1
- package/dist/web-request-coordinator.d.ts +19 -0
- package/dist/web-request-coordinator.d.ts.map +1 -0
- package/dist/web-request-coordinator.js +242 -0
- package/dist/web-request-coordinator.js.map +1 -0
- package/dist/wizard/prompts.d.ts.map +1 -1
- package/dist/wizard/prompts.js +1 -0
- package/dist/wizard/prompts.js.map +1 -1
- package/dist/wizard/run.js +1 -1
- package/dist/wizard/run.js.map +1 -1
- package/package.json +18 -18
- package/schema/mono-agent.config.schema.json +120 -8
- package/skills/mono-agent-composer/SKILL.md +4 -4
- package/skills/mono-agent-composer/references/config-blueprint.md +18 -7
- package/skills/mono-agent-composer/references/discovery-questions.md +10 -5
- package/skills/mono-agent-composer/references/feature-coverage.md +30 -14
- package/skills/mono-agent-composer/references/package-map.md +6 -3
- package/skills/mono-agent-composer/references/playbooks.md +20 -5
- package/skills/mono-agent-composer/references/validation.md +4 -3
- package/dist/configuration-proposal-main.d.ts +0 -3
- package/dist/configuration-proposal-main.d.ts.map +0 -1
- package/dist/configuration-proposal-main.js +0 -13
- package/dist/configuration-proposal-main.js.map +0 -1
- package/dist/configuration-proposal-tool.d.ts +0 -33
- package/dist/configuration-proposal-tool.d.ts.map +0 -1
- package/dist/configuration-proposal-tool.js +0 -180
- package/dist/configuration-proposal-tool.js.map +0 -1
- package/dist/local-configuration.d.ts +0 -99
- package/dist/local-configuration.d.ts.map +0 -1
- package/dist/local-configuration.js +0 -1302
- package/dist/local-configuration.js.map +0 -1
package/dist/doctor.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { inspectWebControl } from "./web-request-coordinator.js";
|
|
1
2
|
import { execFile as execFileCallback } from "node:child_process";
|
|
2
3
|
import { constants } from "node:fs";
|
|
3
4
|
import { access, lstat, mkdir, readdir, readFile, realpath, stat } from "node:fs/promises";
|
|
@@ -16,6 +17,7 @@ import { buildMonoAgentConfigView, EFFORT_LEVELS, findJsonSecretConfigWarnings,
|
|
|
16
17
|
import { describeSandboxEffectiveState, MODEL_REFERENCE_ECHO_MAX_BYTES, MODEL_REFERENCE_REASON_MAX_BYTES, resolveSandboxEffectiveState, RuntimeAdapterError, sandboxEffectiveStateWarning, sanitizeModelReferenceText, } from "@mono-agent/runtime-adapter";
|
|
17
18
|
import { isAppCoreConfigError, loadAppCoreConfig, } from "./app-config.js";
|
|
18
19
|
import { isRememberToolAllowed, isRememberToolPolicyName } from "./memory-remember.js";
|
|
20
|
+
import { isMemoryJournalToolAllowed, isMemoryJournalToolPolicyName } from "./memory-journal.js";
|
|
19
21
|
import { adapterSendToolNames, isAdapterSendToolAllowed, resolveAdapterSendToolsSettings } from "./adapter-send-tools.js";
|
|
20
22
|
import { canonicalToolName, isAllowAllTools, isKnownToolName, isMcpToolName, suggestToolName } from "./modules/known-tools.js";
|
|
21
23
|
import { collectChannelConfigViews } from "./channel-config-view.js";
|
|
@@ -37,8 +39,9 @@ import { formatInteractionBridgeUrl, loadInteractionSettings } from "./interacti
|
|
|
37
39
|
import { FIRST_RUN_MEMORY_INITIALIZING_MARKER } from "./first-run-managed-memory.js";
|
|
38
40
|
import { DEFAULT_MEMORY_EMBEDDING_ENDPOINTS, probeMemoryEmbeddingSelection, } from "./memory-embedding-service.js";
|
|
39
41
|
import { piAuthRecoveryCommand } from "./provider-setup.js";
|
|
42
|
+
import { collectUsedProviderReferences } from "./provider-auth-status.js";
|
|
40
43
|
import { inspectPiAuthStore } from "./pi-auth-store-inspection.js";
|
|
41
|
-
import { checkManagedProjectSkills, managedProjectSkillsExist } from "./project-skills.js";
|
|
44
|
+
import { activeProjectSkillSelections, checkManagedProjectSkills, isRetiredProjectSkillName, managedProjectSkillsExist, } from "./project-skills.js";
|
|
42
45
|
import { runtimeProvenanceDetail } from "./runtime-provenance.js";
|
|
43
46
|
import { resolveAdvertisedModelEffort } from "./model-effort-capabilities.js";
|
|
44
47
|
import { loadSupermemoryPlugin } from "./supermemory-plugin.js";
|
|
@@ -51,6 +54,7 @@ const CONTINUATION_V2_ROLLBACK_GUARD = "UPGRADED-TO-RECORDS-V3";
|
|
|
51
54
|
const CONTINUATION_V2_ROLLBACK_GUARD_CONTENT = "This state directory uses continuation records v3. Older runtimes must not open records-v2.\n";
|
|
52
55
|
const DOCTOR_STATUS_TIMEOUT_MS = 5_000;
|
|
53
56
|
const DOCTOR_STATUS_MAX_BUFFER_BYTES = 64 * 1024;
|
|
57
|
+
const OLLAMA_WEB_SEARCH_PROBE_MAX_BYTES = 2 * 1024 * 1024;
|
|
54
58
|
const defaultDoctorStatusExecFile = async (file, args, options) => {
|
|
55
59
|
const { stdout } = await execFile(file, [...args], options);
|
|
56
60
|
return { stdout };
|
|
@@ -78,7 +82,7 @@ export async function validateMonoAgentFolder(options) {
|
|
|
78
82
|
}
|
|
79
83
|
sections.push(await runtimeProvenanceSection(options.verifiedRuntimeProvenanceDetail));
|
|
80
84
|
if (coreConfig !== undefined) {
|
|
81
|
-
const staticTriggerCredentialRefs = await collectStaticTriggerCredentialRefs(drivers, options);
|
|
85
|
+
const staticTriggerCredentialRefs = await collectStaticTriggerCredentialRefs(coreConfig, drivers, options);
|
|
82
86
|
const jsonResult = await readMonoAgentConfigJson(options.configPath);
|
|
83
87
|
// Channel secrets (bot tokens, API keys) live outside the core view, so the
|
|
84
88
|
// placement check spans both: core sections + every channel's config view.
|
|
@@ -238,37 +242,10 @@ function staticTriggerConfigEntries(driverId, loaded) {
|
|
|
238
242
|
* Collect static trigger model overrides for credential readiness. Dynamic
|
|
239
243
|
* webhook request-body overrides are intentionally unavailable at validate time.
|
|
240
244
|
*/
|
|
241
|
-
async function collectStaticTriggerCredentialRefs(drivers, input) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
if (driver.id !== "webhook" && driver.id !== "cron")
|
|
246
|
-
continue;
|
|
247
|
-
let loaded;
|
|
248
|
-
try {
|
|
249
|
-
loaded = await driver.loadConfig(input);
|
|
250
|
-
}
|
|
251
|
-
catch {
|
|
252
|
-
// The channel section owns malformed/unreadable config diagnostics.
|
|
253
|
-
continue;
|
|
254
|
-
}
|
|
255
|
-
for (const { entryPath, entry } of staticTriggerConfigEntries(driver.id, loaded)) {
|
|
256
|
-
if (typeof entry.model !== "string")
|
|
257
|
-
continue;
|
|
258
|
-
try {
|
|
259
|
-
const ref = parseMonoRuntimeModelReference(entry.model);
|
|
260
|
-
const key = `${entryPath}\u0000${modelReferenceKey(ref)}`;
|
|
261
|
-
if (seen.has(key))
|
|
262
|
-
continue;
|
|
263
|
-
seen.add(key);
|
|
264
|
-
refs.push({ label: entryPath, ref });
|
|
265
|
-
}
|
|
266
|
-
catch {
|
|
267
|
-
// The channel section owns invalid model-reference syntax.
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
return refs;
|
|
245
|
+
async function collectStaticTriggerCredentialRefs(config, drivers, input) {
|
|
246
|
+
return (await collectUsedProviderReferences(config, drivers, input))
|
|
247
|
+
.filter(({ usage }) => usage.kind === "cron" || usage.kind === "webhook")
|
|
248
|
+
.map(({ usage, ref }) => ({ label: usage.label, ref }));
|
|
272
249
|
}
|
|
273
250
|
async function applyRequestModelOverrideCompatibilityChecks(sections, config, drivers, input) {
|
|
274
251
|
const piModelResolutionFailures = [];
|
|
@@ -697,6 +674,8 @@ function hasNonEmptyCredentialValue(value) {
|
|
|
697
674
|
async function contextSection(config, cwd) {
|
|
698
675
|
const details = [];
|
|
699
676
|
let status = "ok";
|
|
677
|
+
const activeSelectedSkills = activeProjectSkillSelections(config.context.selectedSkills);
|
|
678
|
+
const retiredSelectedSkills = config.context.selectedSkills.filter(isRetiredProjectSkillName);
|
|
700
679
|
if (await pathExists(config.context.identityPath)) {
|
|
701
680
|
details.push(`Identity: ${config.context.identityPath}`);
|
|
702
681
|
}
|
|
@@ -708,10 +687,19 @@ async function contextSection(config, cwd) {
|
|
|
708
687
|
status = "error";
|
|
709
688
|
details.push(`Soul file is missing: ${config.context.soulPath}`);
|
|
710
689
|
}
|
|
711
|
-
|
|
690
|
+
for (const skill of retiredSelectedSkills) {
|
|
691
|
+
if (status === "ok")
|
|
692
|
+
status = "waiting";
|
|
693
|
+
details.push(`Skill \`${skill}\` is retired and ignored. Remove it from context.selectedSkills or ` +
|
|
694
|
+
"MONO_AGENT_SELECTED_SKILLS, then run `mono-agent install-skill --project --check`." +
|
|
695
|
+
(config.context.skillDisclosure === "index"
|
|
696
|
+
? " Skill disclosure runs as `full` until the retired selector is removed."
|
|
697
|
+
: ""));
|
|
698
|
+
}
|
|
699
|
+
if (activeSelectedSkills.length > 0 && config.context.skillsRoot !== undefined) {
|
|
712
700
|
if (await pathExists(config.context.skillsRoot)) {
|
|
713
701
|
details.push(`Skills root: ${config.context.skillsRoot}`);
|
|
714
|
-
for (const skill of
|
|
702
|
+
for (const skill of activeSelectedSkills) {
|
|
715
703
|
const skillPath = join(config.context.skillsRoot, skill, "SKILL.md");
|
|
716
704
|
if (await pathExists(skillPath)) {
|
|
717
705
|
details.push(`Skill \`${skill}\`: ${skillPath}`);
|
|
@@ -727,7 +715,7 @@ async function contextSection(config, cwd) {
|
|
|
727
715
|
details.push(`Skills root is missing: ${config.context.skillsRoot}`);
|
|
728
716
|
}
|
|
729
717
|
}
|
|
730
|
-
else if (
|
|
718
|
+
else if (activeSelectedSkills.length > 0) {
|
|
731
719
|
status = "error";
|
|
732
720
|
details.push("Skills are selected but context.skillsRoot is not set.");
|
|
733
721
|
}
|
|
@@ -762,7 +750,15 @@ function memoryConsolidationCronIssue(expression) {
|
|
|
762
750
|
}
|
|
763
751
|
async function memorySection(config, cwd, env, liveness, allowFilesystemWrites, preferAppPluginInstall) {
|
|
764
752
|
if (config.memory === undefined) {
|
|
765
|
-
return {
|
|
753
|
+
return {
|
|
754
|
+
id: "memory",
|
|
755
|
+
label: "Memory",
|
|
756
|
+
status: "disabled",
|
|
757
|
+
details: [
|
|
758
|
+
"No memory configured.",
|
|
759
|
+
"Chronological journal: disabled because no local memory backend is configured.",
|
|
760
|
+
],
|
|
761
|
+
};
|
|
766
762
|
}
|
|
767
763
|
// External backend (e.g. supermemory): mode/embeddings/llm are bujo-only and
|
|
768
764
|
// ignored, so validate the plugin-owned shape before any soft liveness probe.
|
|
@@ -808,6 +804,9 @@ async function memorySection(config, cwd, env, liveness, allowFilesystemWrites,
|
|
|
808
804
|
sm.apiKey === undefined
|
|
809
805
|
? "Auth: no API key configured (keyless — works only if the instance allows it)."
|
|
810
806
|
: "Auth: API key configured.",
|
|
807
|
+
config.memory.recallTool?.enabled === false
|
|
808
|
+
? "Explicit memory read tools are disabled by memory.recallTool.enabled. Chronological journal browsing is also unsupported by Supermemory."
|
|
809
|
+
: "Chronological journal: unsupported by Supermemory; MemoryJournal is not offered.",
|
|
811
810
|
];
|
|
812
811
|
if (!liveness) {
|
|
813
812
|
details.push("Supermemory liveness probe skipped; ingestion is async.");
|
|
@@ -825,6 +824,9 @@ async function memorySection(config, cwd, env, liveness, allowFilesystemWrites,
|
|
|
825
824
|
}
|
|
826
825
|
const details = [
|
|
827
826
|
`Mode: ${config.memory.mode}, path: ${config.memory.path}, writeMode: ${config.memory.writeMode}.`,
|
|
827
|
+
config.memory.recallTool?.enabled === false
|
|
828
|
+
? `Explicit memory read tools are disabled by memory.recallTool.enabled; the local ${config.memory.mode} tier supports chronology but MemoryJournal is not offered.`
|
|
829
|
+
: `Chronological journal: supported by the local ${config.memory.mode} tier when tool policy allows MemoryJournal.`,
|
|
828
830
|
];
|
|
829
831
|
let status = "ok";
|
|
830
832
|
if (config.memory.llm !== undefined) {
|
|
@@ -1237,6 +1239,27 @@ async function toolsSection(config, input) {
|
|
|
1237
1239
|
details.push(`Allowed tools: ${allowedTools.join(", ")}.`);
|
|
1238
1240
|
let mcpNoteAdded = false;
|
|
1239
1241
|
for (const name of allowedTools) {
|
|
1242
|
+
if (isMemoryJournalToolPolicyName(name)) {
|
|
1243
|
+
// This app-owned MCP surface must be checked before the generic MCP
|
|
1244
|
+
// branch, using the same deny-wins spellings as runtime composition.
|
|
1245
|
+
if (!isMemoryJournalToolAllowed(config.tools)) {
|
|
1246
|
+
status = "waiting";
|
|
1247
|
+
details.push(`${name} is listed but tool policy still resolves to denied (deny wins, including the mcp__mono-agent-memory-journal__* spelling) - the tool will not be offered.`);
|
|
1248
|
+
}
|
|
1249
|
+
else if (config.memory === undefined) {
|
|
1250
|
+
status = "waiting";
|
|
1251
|
+
details.push(`${name} is in allowedTools but no memory block is configured - chronological journal browsing will not work.`);
|
|
1252
|
+
}
|
|
1253
|
+
else if (config.memory.recallTool?.enabled === false) {
|
|
1254
|
+
status = "waiting";
|
|
1255
|
+
details.push(`${name} is in allowedTools but memory.recallTool.enabled is off - explicit memory read tools will not work.`);
|
|
1256
|
+
}
|
|
1257
|
+
else if ((config.memory.backend ?? "bujo") === "supermemory") {
|
|
1258
|
+
status = "waiting";
|
|
1259
|
+
details.push(`${name} is in allowedTools but the Supermemory backend exposes no chronological journal surface - the tool will not be offered.`);
|
|
1260
|
+
}
|
|
1261
|
+
continue;
|
|
1262
|
+
}
|
|
1240
1263
|
if (isRememberToolPolicyName(name)) {
|
|
1241
1264
|
// Reconcile with the runtime's own resolution, which honours the
|
|
1242
1265
|
// `mcp__mono-agent-memory-write__*` spellings and deny-wins. This check
|
|
@@ -1440,31 +1463,61 @@ async function toolsSection(config, input) {
|
|
|
1440
1463
|
return { id: "tools", label: "Tools & MCP", status, details };
|
|
1441
1464
|
}
|
|
1442
1465
|
const MIN_AGENT_BROWSER_VERSION = [0, 33, 1];
|
|
1466
|
+
function formatSearchBackendChain(backends) {
|
|
1467
|
+
if (backends.length <= 1)
|
|
1468
|
+
return backends[0] ?? "none";
|
|
1469
|
+
return `${backends.slice(0, -1).join(", ")}, then ${backends.at(-1)}`;
|
|
1470
|
+
}
|
|
1443
1471
|
async function webToolsSection(config, input, liveness) {
|
|
1444
1472
|
const web = config.tools.web;
|
|
1445
1473
|
const search = web?.search ?? {
|
|
1446
1474
|
backend: "auto",
|
|
1475
|
+
maxRequestsPerRun: 4,
|
|
1447
1476
|
codex: { model: "gpt-5.6-luna" },
|
|
1448
1477
|
};
|
|
1449
1478
|
const fetchConfig = web?.fetch ?? { render: "never", browserCommand: "agent-browser" };
|
|
1450
|
-
const details = [
|
|
1479
|
+
const details = [
|
|
1480
|
+
`WebSearch backend: ${search.backend}.`,
|
|
1481
|
+
`WebSearch request budget: ${search.maxRequestsPerRun ?? 4} per logical run.`,
|
|
1482
|
+
`Web coordination: ${web?.coordination ?? "process"}.`,
|
|
1483
|
+
];
|
|
1451
1484
|
let status = "ok";
|
|
1452
|
-
if (
|
|
1485
|
+
if (web?.coordination === "host") {
|
|
1486
|
+
try {
|
|
1487
|
+
const shared = await inspectWebControl();
|
|
1488
|
+
details.push(shared.exists ? "Host web control state is valid." : "Host web control state will be initialized on first request.");
|
|
1489
|
+
}
|
|
1490
|
+
catch {
|
|
1491
|
+
status = "waiting";
|
|
1492
|
+
details.push("Host web control state is unavailable; web requests will fail closed. Inspect with mono-agent web-control status.");
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
const searxngEndpoint = search.searxng?.endpoint ?? search.endpoint;
|
|
1496
|
+
const autoEligibleBackends = [
|
|
1497
|
+
...(search.ollama === undefined ? [] : ["configured Ollama"]),
|
|
1498
|
+
...(searxngEndpoint === undefined ? [] : ["configured SearXNG"]),
|
|
1499
|
+
"Codex",
|
|
1500
|
+
"keyless",
|
|
1501
|
+
];
|
|
1502
|
+
const autoAfterOllama = formatSearchBackendChain(autoEligibleBackends.slice(1));
|
|
1503
|
+
if (searxngEndpoint === undefined) {
|
|
1453
1504
|
details.push(search.backend === "keyless"
|
|
1454
1505
|
? "SearXNG is not configured; keyless search is enabled."
|
|
1455
1506
|
: search.backend === "codex"
|
|
1456
1507
|
? "SearXNG is not configured; strict Codex subscription search is enabled."
|
|
1457
1508
|
: search.backend === "searxng"
|
|
1458
1509
|
? "SearXNG is not configured."
|
|
1459
|
-
:
|
|
1510
|
+
: search.ollama === undefined
|
|
1511
|
+
? "SearXNG is not configured; auto mode starts with Codex subscription search, then keyless search."
|
|
1512
|
+
: "SearXNG is not configured; auto mode uses configured Ollama, then Codex subscription search, then keyless search.");
|
|
1460
1513
|
}
|
|
1461
1514
|
else {
|
|
1462
|
-
details.push(`SearXNG endpoint: ${
|
|
1515
|
+
details.push(`SearXNG endpoint: ${searxngEndpoint}.`);
|
|
1463
1516
|
if (!liveness) {
|
|
1464
1517
|
details.push("SearXNG liveness was not probed.");
|
|
1465
1518
|
}
|
|
1466
1519
|
else {
|
|
1467
|
-
const probe = await probeSearxngEndpoint(
|
|
1520
|
+
const probe = await probeSearxngEndpoint(searxngEndpoint);
|
|
1468
1521
|
if (probe.ok) {
|
|
1469
1522
|
details.push("SearXNG JSON search probe succeeded.");
|
|
1470
1523
|
}
|
|
@@ -1472,14 +1525,42 @@ async function webToolsSection(config, input, liveness) {
|
|
|
1472
1525
|
status = "waiting";
|
|
1473
1526
|
details.push(`[WARN] SearXNG JSON search probe failed (${probe.reason}). ` +
|
|
1474
1527
|
(search.backend === "auto"
|
|
1475
|
-
? "Start the local companion or fix tools.web.search.endpoint; auto mode can still fall back to Codex subscription search, then keyless search."
|
|
1476
|
-
: "Start the local companion or fix tools.web.search.endpoint; strict SearXNG mode has no fallback."));
|
|
1528
|
+
? "Start the local companion or fix tools.web.search.searxng.endpoint; auto mode can still fall back to Codex subscription search, then keyless search."
|
|
1529
|
+
: "Start the local companion or fix tools.web.search.searxng.endpoint; strict SearXNG mode has no fallback."));
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
if (search.backend === "ollama" || (search.backend === "auto" && search.ollama !== undefined)) {
|
|
1534
|
+
const ollama = search.ollama;
|
|
1535
|
+
if (ollama === undefined) {
|
|
1536
|
+
status = "waiting";
|
|
1537
|
+
details.push("[WARN] Ollama Web Search is selected but its resolved configuration is missing.");
|
|
1538
|
+
}
|
|
1539
|
+
else if (!liveness) {
|
|
1540
|
+
details.push(`Ollama Web Search origin: ${ollama.baseUrl}. ${search.backend === "ollama" ? "Strict Ollama mode has no fallback." : `Auto mode advances to ${autoAfterOllama} when Ollama is unavailable.`}`);
|
|
1541
|
+
details.push("Ollama Web Search liveness was not probed.");
|
|
1542
|
+
}
|
|
1543
|
+
else {
|
|
1544
|
+
details.push(`Ollama Web Search origin: ${ollama.baseUrl}. ${search.backend === "ollama" ? "Strict Ollama mode has no fallback." : `Auto mode advances to ${autoAfterOllama} when Ollama is unavailable.`}`);
|
|
1545
|
+
const probe = await probeOllamaWebSearch(ollama);
|
|
1546
|
+
if (probe.ok)
|
|
1547
|
+
details.push("Ollama Web Search JSON probe succeeded.");
|
|
1548
|
+
else {
|
|
1549
|
+
status = "waiting";
|
|
1550
|
+
details.push(`[WARN] Ollama Web Search probe failed (${probe.reason}). ${search.backend === "ollama" ? "Strict Ollama mode has no fallback." : `Auto mode can still advance to ${autoAfterOllama}.`}`);
|
|
1477
1551
|
}
|
|
1478
1552
|
}
|
|
1479
1553
|
}
|
|
1554
|
+
else if (search.ollama !== undefined) {
|
|
1555
|
+
details.push(`Ollama Web Search is configured but inactive because backend ${search.backend} is strict.`);
|
|
1556
|
+
}
|
|
1480
1557
|
if (search.backend === "auto") {
|
|
1481
1558
|
const codexModel = search.codex?.model ?? "gpt-5.6-luna";
|
|
1482
|
-
|
|
1559
|
+
const beforeCodex = autoEligibleBackends.slice(0, autoEligibleBackends.indexOf("Codex"));
|
|
1560
|
+
const codexPosition = beforeCodex.length === 0
|
|
1561
|
+
? "as the first eligible backend"
|
|
1562
|
+
: `after ${formatSearchBackendChain(beforeCodex)}`;
|
|
1563
|
+
details.push(`Codex subscription fallback model: ${codexModel}; readiness is checked lazily when auto mode reaches it ${codexPosition}.`);
|
|
1483
1564
|
}
|
|
1484
1565
|
else if (search.backend === "codex") {
|
|
1485
1566
|
const codexModel = search.codex?.model ?? "gpt-5.6-luna";
|
|
@@ -1519,6 +1600,95 @@ async function webToolsSection(config, input, liveness) {
|
|
|
1519
1600
|
}
|
|
1520
1601
|
return { id: "web-tools", label: "Web search & fetch", status, details };
|
|
1521
1602
|
}
|
|
1603
|
+
async function probeOllamaWebSearch(config) {
|
|
1604
|
+
const ctrl = new AbortController();
|
|
1605
|
+
const timer = setTimeout(() => { ctrl.abort(); }, LIVENESS_PROBE_TIMEOUT_MS);
|
|
1606
|
+
const official = config.baseUrl === "https://ollama.com";
|
|
1607
|
+
const paths = official ? ["/api/web_search"] : ["/api/experimental/web_search", "/api/web_search"];
|
|
1608
|
+
try {
|
|
1609
|
+
for (let index = 0; index < paths.length; index += 1) {
|
|
1610
|
+
const response = await fetch(`${config.baseUrl}${paths[index]}`, {
|
|
1611
|
+
method: "POST",
|
|
1612
|
+
headers: {
|
|
1613
|
+
Accept: "application/json",
|
|
1614
|
+
"Content-Type": "application/json",
|
|
1615
|
+
...(official ? { Authorization: `Bearer ${config.apiKey}` } : {}),
|
|
1616
|
+
},
|
|
1617
|
+
body: JSON.stringify({ query: "mono-agent doctor", max_results: 1 }),
|
|
1618
|
+
redirect: "error",
|
|
1619
|
+
signal: ctrl.signal,
|
|
1620
|
+
});
|
|
1621
|
+
if (!official && index === 0 && [404, 405].includes(response.status)) {
|
|
1622
|
+
await response.body?.cancel();
|
|
1623
|
+
continue;
|
|
1624
|
+
}
|
|
1625
|
+
if ([401, 403].includes(response.status)) {
|
|
1626
|
+
await response.body?.cancel();
|
|
1627
|
+
return { ok: false, reason: official
|
|
1628
|
+
? `hosted authentication failed; check ${config.apiKeyEnv}`
|
|
1629
|
+
: "the local proxy requires sign-in; run ollama signin or repair its proxy authentication" };
|
|
1630
|
+
}
|
|
1631
|
+
if (!response.ok) {
|
|
1632
|
+
await response.body?.cancel();
|
|
1633
|
+
return { ok: false, reason: `HTTP ${response.status}` };
|
|
1634
|
+
}
|
|
1635
|
+
const declared = Number(response.headers.get("content-length"));
|
|
1636
|
+
if (Number.isFinite(declared) && declared > OLLAMA_WEB_SEARCH_PROBE_MAX_BYTES) {
|
|
1637
|
+
await response.body?.cancel();
|
|
1638
|
+
return { ok: false, reason: `response exceeded ${OLLAMA_WEB_SEARCH_PROBE_MAX_BYTES} bytes` };
|
|
1639
|
+
}
|
|
1640
|
+
const bytes = await readBoundedProbeResponse(response, OLLAMA_WEB_SEARCH_PROBE_MAX_BYTES);
|
|
1641
|
+
let body;
|
|
1642
|
+
try {
|
|
1643
|
+
body = JSON.parse(new TextDecoder().decode(bytes));
|
|
1644
|
+
}
|
|
1645
|
+
catch {
|
|
1646
|
+
return { ok: false, reason: "response was not valid JSON" };
|
|
1647
|
+
}
|
|
1648
|
+
if (!body || typeof body !== "object" || !Array.isArray(body.results)) {
|
|
1649
|
+
return { ok: false, reason: "response did not contain a results array" };
|
|
1650
|
+
}
|
|
1651
|
+
return { ok: true, reason: "" };
|
|
1652
|
+
}
|
|
1653
|
+
return { ok: false, reason: "this Ollama version supports neither local Web Search endpoint" };
|
|
1654
|
+
}
|
|
1655
|
+
catch (error) {
|
|
1656
|
+
return { ok: false, reason: error instanceof Error ? error.message : String(error) };
|
|
1657
|
+
}
|
|
1658
|
+
finally {
|
|
1659
|
+
clearTimeout(timer);
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
async function readBoundedProbeResponse(response, maxBytes) {
|
|
1663
|
+
const reader = response.body?.getReader();
|
|
1664
|
+
if (reader === undefined)
|
|
1665
|
+
throw new Error("response body could not be read safely");
|
|
1666
|
+
const chunks = [];
|
|
1667
|
+
let total = 0;
|
|
1668
|
+
try {
|
|
1669
|
+
while (true) {
|
|
1670
|
+
const next = await reader.read();
|
|
1671
|
+
if (next.done)
|
|
1672
|
+
break;
|
|
1673
|
+
total += next.value.byteLength;
|
|
1674
|
+
if (total > maxBytes) {
|
|
1675
|
+
await reader.cancel();
|
|
1676
|
+
throw new Error(`response exceeded ${maxBytes} bytes`);
|
|
1677
|
+
}
|
|
1678
|
+
chunks.push(next.value);
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
finally {
|
|
1682
|
+
reader.releaseLock();
|
|
1683
|
+
}
|
|
1684
|
+
const joined = new Uint8Array(total);
|
|
1685
|
+
let offset = 0;
|
|
1686
|
+
for (const chunk of chunks) {
|
|
1687
|
+
joined.set(chunk, offset);
|
|
1688
|
+
offset += chunk.byteLength;
|
|
1689
|
+
}
|
|
1690
|
+
return joined;
|
|
1691
|
+
}
|
|
1522
1692
|
async function probeSearxngEndpoint(endpoint) {
|
|
1523
1693
|
const ctrl = new AbortController();
|
|
1524
1694
|
const timer = setTimeout(() => { ctrl.abort(); }, LIVENESS_PROBE_TIMEOUT_MS);
|