@jungjaehoon/mama-os 0.20.0 → 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/CHANGELOG.md +48 -0
- package/dist/agent/agent-loop.d.ts +2 -1
- package/dist/agent/agent-loop.d.ts.map +1 -1
- package/dist/agent/agent-loop.js +65 -19
- package/dist/agent/agent-loop.js.map +1 -1
- package/dist/agent/claude-cli-wrapper.d.ts.map +1 -1
- package/dist/agent/claude-cli-wrapper.js +6 -2
- package/dist/agent/claude-cli-wrapper.js.map +1 -1
- package/dist/agent/cli-arg-redaction.d.ts +2 -0
- package/dist/agent/cli-arg-redaction.d.ts.map +1 -0
- package/dist/agent/cli-arg-redaction.js +18 -0
- package/dist/agent/cli-arg-redaction.js.map +1 -0
- package/dist/agent/code-act/constants.d.ts +1 -1
- package/dist/agent/code-act/constants.d.ts.map +1 -1
- package/dist/agent/code-act/constants.js +24 -3
- package/dist/agent/code-act/constants.js.map +1 -1
- package/dist/agent/code-act/host-bridge.d.ts +2 -0
- package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
- package/dist/agent/code-act/host-bridge.js +43 -7
- package/dist/agent/code-act/host-bridge.js.map +1 -1
- package/dist/agent/code-act/type-definition-generator.d.ts +2 -2
- package/dist/agent/code-act/type-definition-generator.d.ts.map +1 -1
- package/dist/agent/code-act/type-definition-generator.js +29 -4
- package/dist/agent/code-act/type-definition-generator.js.map +1 -1
- package/dist/agent/codex-home.d.ts +1 -1
- package/dist/agent/codex-home.d.ts.map +1 -1
- package/dist/agent/codex-home.js +43 -1
- package/dist/agent/codex-home.js.map +1 -1
- package/dist/agent/codex-mcp-process.d.ts +2 -0
- package/dist/agent/codex-mcp-process.d.ts.map +1 -1
- package/dist/agent/codex-mcp-process.js +1 -1
- package/dist/agent/codex-mcp-process.js.map +1 -1
- package/dist/agent/context-compile-service.d.ts +47 -0
- package/dist/agent/context-compile-service.d.ts.map +1 -0
- package/dist/agent/context-compile-service.js +435 -0
- package/dist/agent/context-compile-service.js.map +1 -0
- package/dist/agent/gateway-tool-executor.d.ts +16 -11
- package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
- package/dist/agent/gateway-tool-executor.js +539 -109
- package/dist/agent/gateway-tool-executor.js.map +1 -1
- package/dist/agent/gateway-tools.md +4 -3
- package/dist/agent/mama-tool-handlers.d.ts.map +1 -1
- package/dist/agent/mama-tool-handlers.js +37 -1
- package/dist/agent/mama-tool-handlers.js.map +1 -1
- package/dist/agent/managed-agent-runtime-sync.d.ts.map +1 -1
- package/dist/agent/managed-agent-runtime-sync.js +2 -4
- package/dist/agent/managed-agent-runtime-sync.js.map +1 -1
- package/dist/agent/managed-agent-validation.d.ts.map +1 -1
- package/dist/agent/managed-agent-validation.js +2 -1
- package/dist/agent/managed-agent-validation.js.map +1 -1
- package/dist/agent/os-agent-capabilities.md +13 -12
- package/dist/agent/persistent-cli-process.d.ts +1 -0
- package/dist/agent/persistent-cli-process.d.ts.map +1 -1
- package/dist/agent/persistent-cli-process.js +6 -1
- package/dist/agent/persistent-cli-process.js.map +1 -1
- package/dist/agent/tool-registry.d.ts.map +1 -1
- package/dist/agent/tool-registry.js +10 -2
- package/dist/agent/tool-registry.js.map +1 -1
- package/dist/agent/types.d.ts +30 -5
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/agent-context-handler.d.ts +10 -0
- package/dist/api/agent-context-handler.d.ts.map +1 -0
- package/dist/api/agent-context-handler.js +216 -0
- package/dist/api/agent-context-handler.js.map +1 -0
- package/dist/api/agent-handler.d.ts +2 -0
- package/dist/api/agent-handler.d.ts.map +1 -1
- package/dist/api/agent-handler.js +14 -7
- package/dist/api/agent-handler.js.map +1 -1
- package/dist/api/graph-api-types.d.ts +6 -1
- package/dist/api/graph-api-types.d.ts.map +1 -1
- package/dist/api/graph-api.d.ts +2 -1
- package/dist/api/graph-api.d.ts.map +1 -1
- package/dist/api/graph-api.js +193 -11
- package/dist/api/graph-api.js.map +1 -1
- package/dist/api/index.d.ts +11 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +13 -2
- package/dist/api/index.js.map +1 -1
- package/dist/api/intelligence-handler.d.ts +17 -6
- package/dist/api/intelligence-handler.d.ts.map +1 -1
- package/dist/api/intelligence-handler.js +59 -1
- package/dist/api/intelligence-handler.js.map +1 -1
- package/dist/api/operator-handler.d.ts +17 -0
- package/dist/api/operator-handler.d.ts.map +1 -0
- package/dist/api/operator-handler.js +88 -0
- package/dist/api/operator-handler.js.map +1 -0
- package/dist/api/report-handler.d.ts +7 -0
- package/dist/api/report-handler.d.ts.map +1 -1
- package/dist/api/report-handler.js +30 -0
- package/dist/api/report-handler.js.map +1 -1
- package/dist/api/report-persistence.d.ts +17 -0
- package/dist/api/report-persistence.d.ts.map +1 -0
- package/dist/api/report-persistence.js +91 -0
- package/dist/api/report-persistence.js.map +1 -0
- package/dist/cli/commands/start.d.ts +45 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +610 -197
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/config/config-manager.d.ts.map +1 -1
- package/dist/cli/config/config-manager.js +171 -4
- package/dist/cli/config/config-manager.js.map +1 -1
- package/dist/cli/config/types.d.ts +25 -5
- package/dist/cli/config/types.d.ts.map +1 -1
- package/dist/cli/config/types.js +5 -0
- package/dist/cli/config/types.js.map +1 -1
- package/dist/cli/runtime/agent-loop-init.d.ts +3 -0
- package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
- package/dist/cli/runtime/agent-loop-init.js +2 -0
- package/dist/cli/runtime/agent-loop-init.js.map +1 -1
- package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
- package/dist/cli/runtime/api-routes-init.js +396 -259
- package/dist/cli/runtime/api-routes-init.js.map +1 -1
- package/dist/cli/runtime/api-server-init.d.ts +2 -0
- package/dist/cli/runtime/api-server-init.d.ts.map +1 -1
- package/dist/cli/runtime/api-server-init.js +19 -8
- package/dist/cli/runtime/api-server-init.js.map +1 -1
- package/dist/cli/runtime/connector-init.d.ts +26 -7
- package/dist/cli/runtime/connector-init.d.ts.map +1 -1
- package/dist/cli/runtime/connector-init.js +79 -16
- package/dist/cli/runtime/connector-init.js.map +1 -1
- package/dist/cli/runtime/envelope-bootstrap.d.ts.map +1 -1
- package/dist/cli/runtime/envelope-bootstrap.js +8 -2
- package/dist/cli/runtime/envelope-bootstrap.js.map +1 -1
- package/dist/cli/runtime/gateway-init.d.ts +1 -1
- package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
- package/dist/cli/runtime/gateway-init.js.map +1 -1
- package/dist/cli/runtime/message-router-config.d.ts +4 -0
- package/dist/cli/runtime/message-router-config.d.ts.map +1 -0
- package/dist/cli/runtime/message-router-config.js +11 -0
- package/dist/cli/runtime/message-router-config.js.map +1 -0
- package/dist/cli/runtime/scheduler-init.d.ts.map +1 -1
- package/dist/cli/runtime/scheduler-init.js +12 -12
- package/dist/cli/runtime/scheduler-init.js.map +1 -1
- package/dist/cli/runtime/utilities.js +2 -2
- package/dist/cli/runtime/utilities.js.map +1 -1
- package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
- package/dist/connectors/framework/polling-scheduler.js +101 -5
- package/dist/connectors/framework/polling-scheduler.js.map +1 -1
- package/dist/connectors/kagemusha/query-tools.d.ts.map +1 -1
- package/dist/connectors/kagemusha/query-tools.js +14 -3
- package/dist/connectors/kagemusha/query-tools.js.map +1 -1
- package/dist/db/agent-store.d.ts.map +1 -1
- package/dist/db/agent-store.js +10 -3
- package/dist/db/agent-store.js.map +1 -1
- package/dist/db/migrations/wiki-artifacts.d.ts +3 -0
- package/dist/db/migrations/wiki-artifacts.d.ts.map +1 -0
- package/dist/db/migrations/wiki-artifacts.js +24 -0
- package/dist/db/migrations/wiki-artifacts.js.map +1 -0
- package/dist/envelope/enforcer.d.ts.map +1 -1
- package/dist/envelope/enforcer.js +48 -4
- package/dist/envelope/enforcer.js.map +1 -1
- package/dist/envelope/key-provider.d.ts +1 -0
- package/dist/envelope/key-provider.d.ts.map +1 -1
- package/dist/envelope/key-provider.js +86 -0
- package/dist/envelope/key-provider.js.map +1 -1
- package/dist/gateways/message-router.d.ts.map +1 -1
- package/dist/gateways/message-router.js +15 -3
- package/dist/gateways/message-router.js.map +1 -1
- package/dist/gateways/types.d.ts +5 -1
- package/dist/gateways/types.d.ts.map +1 -1
- package/dist/mcp/code-act-server.js +50 -7
- package/dist/mcp/code-act-server.js.map +1 -1
- package/dist/memory/raw-backed-memory-ingest.d.ts +26 -0
- package/dist/memory/raw-backed-memory-ingest.d.ts.map +1 -0
- package/dist/memory/raw-backed-memory-ingest.js +214 -0
- package/dist/memory/raw-backed-memory-ingest.js.map +1 -0
- package/dist/memory/scope-context.js +1 -1
- package/dist/multi-agent/agent-event-bus.d.ts +10 -0
- package/dist/multi-agent/agent-event-bus.d.ts.map +1 -1
- package/dist/multi-agent/agent-event-bus.js +34 -0
- package/dist/multi-agent/agent-event-bus.js.map +1 -1
- package/dist/multi-agent/agent-process-manager.d.ts +3 -0
- package/dist/multi-agent/agent-process-manager.d.ts.map +1 -1
- package/dist/multi-agent/agent-process-manager.js +118 -13
- package/dist/multi-agent/agent-process-manager.js.map +1 -1
- package/dist/multi-agent/conductor-persona.js +2 -2
- package/dist/multi-agent/dashboard-agent-persona.d.ts +6 -2
- package/dist/multi-agent/dashboard-agent-persona.d.ts.map +1 -1
- package/dist/multi-agent/dashboard-agent-persona.js +57 -30
- package/dist/multi-agent/dashboard-agent-persona.js.map +1 -1
- package/dist/multi-agent/memory-agent-persona.d.ts +1 -1
- package/dist/multi-agent/memory-agent-persona.d.ts.map +1 -1
- package/dist/multi-agent/memory-agent-persona.js +25 -4
- package/dist/multi-agent/memory-agent-persona.js.map +1 -1
- package/dist/multi-agent/runtime-process.d.ts +1 -0
- package/dist/multi-agent/runtime-process.d.ts.map +1 -1
- package/dist/multi-agent/runtime-process.js +1 -0
- package/dist/multi-agent/runtime-process.js.map +1 -1
- package/dist/multi-agent/types.d.ts +14 -4
- package/dist/multi-agent/types.d.ts.map +1 -1
- package/dist/multi-agent/types.js.map +1 -1
- package/dist/multi-agent/wiki-agent-persona.d.ts +7 -1
- package/dist/multi-agent/wiki-agent-persona.d.ts.map +1 -1
- package/dist/multi-agent/wiki-agent-persona.js +83 -61
- package/dist/multi-agent/wiki-agent-persona.js.map +1 -1
- package/dist/multi-agent/workflow-types.d.ts +1 -1
- package/dist/multi-agent/workflow-types.d.ts.map +1 -1
- package/dist/operator/board-slot-instructions.d.ts +18 -0
- package/dist/operator/board-slot-instructions.d.ts.map +1 -0
- package/dist/operator/board-slot-instructions.js +52 -0
- package/dist/operator/board-slot-instructions.js.map +1 -0
- package/dist/operator/connector-delta-repo.d.ts +33 -0
- package/dist/operator/connector-delta-repo.d.ts.map +1 -0
- package/dist/operator/connector-delta-repo.js +0 -0
- package/dist/operator/connector-delta-repo.js.map +1 -0
- package/dist/operator/mama-memory-port.d.ts +13 -0
- package/dist/operator/mama-memory-port.d.ts.map +1 -0
- package/dist/operator/mama-memory-port.js +35 -0
- package/dist/operator/mama-memory-port.js.map +1 -0
- package/dist/operator/operator-interfaces.d.ts +136 -0
- package/dist/operator/operator-interfaces.d.ts.map +1 -0
- package/dist/operator/operator-interfaces.js +15 -0
- package/dist/operator/operator-interfaces.js.map +1 -0
- package/dist/operator/operator-trigger-loop.d.ts +106 -0
- package/dist/operator/operator-trigger-loop.d.ts.map +1 -0
- package/dist/operator/operator-trigger-loop.js +228 -0
- package/dist/operator/operator-trigger-loop.js.map +1 -0
- package/dist/operator/report-run.d.ts +78 -0
- package/dist/operator/report-run.d.ts.map +1 -0
- package/dist/operator/report-run.js +141 -0
- package/dist/operator/report-run.js.map +1 -0
- package/dist/operator/report-scheduler.d.ts +43 -0
- package/dist/operator/report-scheduler.d.ts.map +1 -0
- package/dist/operator/report-scheduler.js +87 -0
- package/dist/operator/report-scheduler.js.map +1 -0
- package/dist/operator/situation-report.d.ts +86 -0
- package/dist/operator/situation-report.d.ts.map +1 -0
- package/dist/operator/situation-report.js +211 -0
- package/dist/operator/situation-report.js.map +1 -0
- package/dist/operator/trigger-author.d.ts +45 -0
- package/dist/operator/trigger-author.d.ts.map +1 -0
- package/dist/operator/trigger-author.js +217 -0
- package/dist/operator/trigger-author.js.map +1 -0
- package/dist/operator/trigger-evolve.d.ts +31 -0
- package/dist/operator/trigger-evolve.d.ts.map +1 -0
- package/dist/operator/trigger-evolve.js +51 -0
- package/dist/operator/trigger-evolve.js.map +1 -0
- package/dist/operator/trigger-fire.d.ts +29 -0
- package/dist/operator/trigger-fire.d.ts.map +1 -0
- package/dist/operator/trigger-fire.js +41 -0
- package/dist/operator/trigger-fire.js.map +1 -0
- package/dist/operator/trigger-matcher.d.ts +19 -0
- package/dist/operator/trigger-matcher.d.ts.map +1 -0
- package/dist/operator/trigger-matcher.js +61 -0
- package/dist/operator/trigger-matcher.js.map +1 -0
- package/dist/operator/trigger-registry.d.ts +36 -0
- package/dist/operator/trigger-registry.d.ts.map +1 -0
- package/dist/operator/trigger-registry.js +135 -0
- package/dist/operator/trigger-registry.js.map +1 -0
- package/dist/operator/trigger-review.d.ts +23 -0
- package/dist/operator/trigger-review.d.ts.map +1 -0
- package/dist/operator/trigger-review.js +127 -0
- package/dist/operator/trigger-review.js.map +1 -0
- package/dist/operator/trigger-types.d.ts +84 -0
- package/dist/operator/trigger-types.d.ts.map +1 -0
- package/dist/operator/trigger-types.js +14 -0
- package/dist/operator/trigger-types.js.map +1 -0
- package/dist/scheduler/cron-worker.d.ts.map +1 -1
- package/dist/scheduler/cron-worker.js +3 -1
- package/dist/scheduler/cron-worker.js.map +1 -1
- package/dist/security/security-monitor.d.ts.map +1 -1
- package/dist/security/security-monitor.js +1 -0
- package/dist/security/security-monitor.js.map +1 -1
- package/dist/wiki/obsidian-writer.d.ts +1 -1
- package/dist/wiki/obsidian-writer.d.ts.map +1 -1
- package/dist/wiki/obsidian-writer.js +67 -27
- package/dist/wiki/obsidian-writer.js.map +1 -1
- package/dist/wiki/path-safety.d.ts +2 -0
- package/dist/wiki/path-safety.d.ts.map +1 -0
- package/dist/wiki/path-safety.js +40 -0
- package/dist/wiki/path-safety.js.map +1 -0
- package/dist/wiki/types.d.ts +4 -2
- package/dist/wiki/types.d.ts.map +1 -1
- package/dist/wiki/types.js +1 -1
- package/dist/wiki/types.js.map +1 -1
- package/dist/wiki-artifacts/normalization.d.ts +8 -0
- package/dist/wiki-artifacts/normalization.d.ts.map +1 -0
- package/dist/wiki-artifacts/normalization.js +41 -0
- package/dist/wiki-artifacts/normalization.js.map +1 -0
- package/dist/wiki-artifacts/types.d.ts +52 -0
- package/dist/wiki-artifacts/types.d.ts.map +1 -0
- package/dist/wiki-artifacts/types.js +3 -0
- package/dist/wiki-artifacts/types.js.map +1 -0
- package/dist/wiki-artifacts/wiki-publish-adapter.d.ts +14 -0
- package/dist/wiki-artifacts/wiki-publish-adapter.d.ts.map +1 -0
- package/dist/wiki-artifacts/wiki-publish-adapter.js +71 -0
- package/dist/wiki-artifacts/wiki-publish-adapter.js.map +1 -0
- package/package.json +6 -4
- package/public/ui/assets/index-BDsaQNGd.js +62 -0
- package/public/ui/assets/index-C4URnm_X.css +1 -0
- package/public/ui/index.html +13 -0
- package/public/viewer/js/utils/api.js +2 -2
- package/public/viewer/src/utils/api.ts +9 -2
- package/public/viewer/sw.js +1 -1
- package/public/viewer/viewer.html +6 -0
|
@@ -54,6 +54,7 @@ const os_1 = require("os");
|
|
|
54
54
|
const child_process_1 = require("child_process");
|
|
55
55
|
const util_1 = require("util");
|
|
56
56
|
const debugLogger = __importStar(require("@jungjaehoon/mama-core/debug-logger"));
|
|
57
|
+
const mama_core_1 = require("@jungjaehoon/mama-core");
|
|
57
58
|
const security_monitor_js_1 = require("../security/security-monitor.js");
|
|
58
59
|
const scope_context_js_1 = require("../memory/scope-context.js");
|
|
59
60
|
const types_js_1 = require("./types.js");
|
|
@@ -67,6 +68,7 @@ const managed_agent_runtime_sync_js_1 = require("./managed-agent-runtime-sync.js
|
|
|
67
68
|
const managed_agent_validation_js_1 = require("./managed-agent-validation.js");
|
|
68
69
|
const delegation_executor_js_1 = require("./delegation-executor.js");
|
|
69
70
|
const index_js_1 = require("../envelope/index.js");
|
|
71
|
+
const wiki_publish_adapter_js_1 = require("../wiki-artifacts/wiki-publish-adapter.js");
|
|
70
72
|
const { DebugLogger } = debugLogger;
|
|
71
73
|
const securityLogger = new DebugLogger('SecurityAudit');
|
|
72
74
|
const TRUTHY_ENV_VALUES = new Set(['1', 'true', 'yes', 'on']);
|
|
@@ -79,24 +81,153 @@ const AGENT_DETAIL_TABS = new Set([
|
|
|
79
81
|
'validation',
|
|
80
82
|
'history',
|
|
81
83
|
]);
|
|
84
|
+
const RECALL_TEXT_REDACTION_PATTERNS = [
|
|
85
|
+
/MAMA_SYNTHETIC_[A-Z0-9_]+_DO_NOT_LEAK/g,
|
|
86
|
+
/synthetic:\/\/raw[^\s"']*/g,
|
|
87
|
+
/raw:[^\s"']*/g,
|
|
88
|
+
/\bhttps?:\/\/[^\s"'<>()]+/gi,
|
|
89
|
+
/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi,
|
|
90
|
+
/\b(?:Bearer|Token|Authorization)\s*[:=]?\s*[A-Za-z0-9._~+/=-]{8,}/gi,
|
|
91
|
+
/\b(?:api[_-]?key|token|secret|password)\s*[:=]\s*[^\s"']{8,}/gi,
|
|
92
|
+
/(?:ghp|gho|ghu|ghs|ghr|github_pat)_[A-Za-z0-9_]{8,}\b/g,
|
|
93
|
+
/xox[baprs]-[A-Za-z0-9-]{10,}\b/g,
|
|
94
|
+
/sk-[A-Za-z0-9_-]{20,}\b/g,
|
|
95
|
+
/\b[CU][A-Z0-9]{8,}\b/g,
|
|
96
|
+
/\b[0-9]{17,20}\b/g,
|
|
97
|
+
/(?:\/Users|\/home|\/tmp)\/[^\s"']*/g,
|
|
98
|
+
/[A-Za-z]:\\Users\\[^\s"']*/g,
|
|
99
|
+
];
|
|
100
|
+
const MAX_RECALL_TEXT_LENGTH = 280;
|
|
101
|
+
const RECALL_TEXT_REDACTION_SCAN_LIMIT = MAX_RECALL_TEXT_LENGTH + 2048;
|
|
82
102
|
const managedAgentMutationTails = new Map();
|
|
83
103
|
const MEMORY_SCOPE_AUDIT_TOOLS = new Set([
|
|
84
104
|
'mama_save',
|
|
85
105
|
'mama_search',
|
|
86
106
|
'mama_recall',
|
|
107
|
+
'context_compile',
|
|
87
108
|
'mama_update',
|
|
88
109
|
'mama_add',
|
|
89
110
|
'mama_ingest',
|
|
90
111
|
]);
|
|
91
112
|
const MEMORY_READ_PERMISSION_BEFORE_ENVELOPE_TOOLS = new Set([
|
|
113
|
+
'mama_save',
|
|
92
114
|
'mama_search',
|
|
93
115
|
'mama_recall',
|
|
116
|
+
'context_compile',
|
|
94
117
|
]);
|
|
95
118
|
const ENVELOPE_REQUIRED_SURFACES = new Set([
|
|
96
119
|
'model_tool',
|
|
97
120
|
'reactive_internal',
|
|
98
121
|
'code_act',
|
|
99
122
|
]);
|
|
123
|
+
class ContextPacketProvenanceError extends Error {
|
|
124
|
+
}
|
|
125
|
+
function asRecord(value) {
|
|
126
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
127
|
+
? value
|
|
128
|
+
: null;
|
|
129
|
+
}
|
|
130
|
+
function stringField(record, field) {
|
|
131
|
+
const value = record[field];
|
|
132
|
+
return typeof value === 'string' ? value : undefined;
|
|
133
|
+
}
|
|
134
|
+
function numberField(record, field) {
|
|
135
|
+
const value = record[field];
|
|
136
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
137
|
+
}
|
|
138
|
+
function sanitizeRecallText(value) {
|
|
139
|
+
if (!value) {
|
|
140
|
+
return undefined;
|
|
141
|
+
}
|
|
142
|
+
let sanitized = value.length > RECALL_TEXT_REDACTION_SCAN_LIMIT
|
|
143
|
+
? value.slice(0, RECALL_TEXT_REDACTION_SCAN_LIMIT)
|
|
144
|
+
: value;
|
|
145
|
+
for (const pattern of RECALL_TEXT_REDACTION_PATTERNS) {
|
|
146
|
+
sanitized = sanitized.replace(pattern, '[redacted]');
|
|
147
|
+
}
|
|
148
|
+
const wasTruncated = value.length > MAX_RECALL_TEXT_LENGTH || sanitized.length > MAX_RECALL_TEXT_LENGTH;
|
|
149
|
+
if (sanitized.length > MAX_RECALL_TEXT_LENGTH) {
|
|
150
|
+
sanitized = sanitized.slice(0, MAX_RECALL_TEXT_LENGTH);
|
|
151
|
+
}
|
|
152
|
+
if (wasTruncated) {
|
|
153
|
+
sanitized = `${sanitized} [truncated]`;
|
|
154
|
+
}
|
|
155
|
+
return sanitized;
|
|
156
|
+
}
|
|
157
|
+
function sanitizeRecallMemory(value) {
|
|
158
|
+
const record = asRecord(value);
|
|
159
|
+
if (!record) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
const safe = {};
|
|
163
|
+
const topic = sanitizeRecallText(stringField(record, 'topic'));
|
|
164
|
+
const kind = sanitizeRecallText(stringField(record, 'kind'));
|
|
165
|
+
const summary = sanitizeRecallText(stringField(record, 'summary'));
|
|
166
|
+
const status = sanitizeRecallText(stringField(record, 'status'));
|
|
167
|
+
const confidence = numberField(record, 'confidence');
|
|
168
|
+
if (topic) {
|
|
169
|
+
safe.topic = topic;
|
|
170
|
+
}
|
|
171
|
+
if (kind) {
|
|
172
|
+
safe.kind = kind;
|
|
173
|
+
}
|
|
174
|
+
if (summary) {
|
|
175
|
+
safe.summary = summary;
|
|
176
|
+
}
|
|
177
|
+
if (status) {
|
|
178
|
+
safe.status = status;
|
|
179
|
+
}
|
|
180
|
+
if (confidence !== undefined) {
|
|
181
|
+
safe.confidence = confidence;
|
|
182
|
+
}
|
|
183
|
+
return Object.keys(safe).length > 0 ? safe : null;
|
|
184
|
+
}
|
|
185
|
+
function sanitizeRecallMemories(value) {
|
|
186
|
+
if (!Array.isArray(value)) {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
return value
|
|
190
|
+
.map((memory) => sanitizeRecallMemory(memory))
|
|
191
|
+
.filter((memory) => memory !== null);
|
|
192
|
+
}
|
|
193
|
+
function sanitizeProfileEvidence(value) {
|
|
194
|
+
if (!Array.isArray(value)) {
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
return value
|
|
198
|
+
.map((item) => {
|
|
199
|
+
const record = asRecord(item);
|
|
200
|
+
if (!record) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
const evidence = {};
|
|
204
|
+
const topic = sanitizeRecallText(stringField(record, 'topic'));
|
|
205
|
+
if (topic) {
|
|
206
|
+
evidence.topic = topic;
|
|
207
|
+
}
|
|
208
|
+
return Object.keys(evidence).length > 0 ? evidence : null;
|
|
209
|
+
})
|
|
210
|
+
.filter((evidence) => evidence !== null);
|
|
211
|
+
}
|
|
212
|
+
function sanitizeMamaRecallBundle(bundle) {
|
|
213
|
+
const record = asRecord(bundle) ?? {};
|
|
214
|
+
const profile = asRecord(record.profile) ?? {};
|
|
215
|
+
const graphContext = asRecord(record.graph_context) ?? {};
|
|
216
|
+
const edges = Array.isArray(graphContext.edges) ? graphContext.edges : [];
|
|
217
|
+
return {
|
|
218
|
+
profile: {
|
|
219
|
+
static: sanitizeRecallMemories(profile.static),
|
|
220
|
+
dynamic: sanitizeRecallMemories(profile.dynamic),
|
|
221
|
+
evidence: sanitizeProfileEvidence(profile.evidence),
|
|
222
|
+
},
|
|
223
|
+
memories: sanitizeRecallMemories(record.memories),
|
|
224
|
+
graph_context: {
|
|
225
|
+
primary: sanitizeRecallMemories(graphContext.primary),
|
|
226
|
+
expanded: sanitizeRecallMemories(graphContext.expanded),
|
|
227
|
+
edge_count: edges.length,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
}
|
|
100
231
|
async function withManagedAgentMutationLock(agentId, fn) {
|
|
101
232
|
const previous = managedAgentMutationTails.get(agentId) ?? Promise.resolve();
|
|
102
233
|
let release;
|
|
@@ -147,6 +278,7 @@ class GatewayToolExecutor {
|
|
|
147
278
|
envelopeEnforcer = new index_js_1.EnvelopeEnforcer();
|
|
148
279
|
envelopeIssuanceMode;
|
|
149
280
|
metricsStore;
|
|
281
|
+
contextCompileService;
|
|
150
282
|
currentContext = null;
|
|
151
283
|
memoryAgentProcessManager = null;
|
|
152
284
|
agentProcessManager = null;
|
|
@@ -157,9 +289,12 @@ class GatewayToolExecutor {
|
|
|
157
289
|
disallowedGatewayTools = new Set();
|
|
158
290
|
reportPublisher = null;
|
|
159
291
|
wikiPublisher = null;
|
|
292
|
+
wikiPublishAdapter = null;
|
|
160
293
|
obsidianVaultPath = null;
|
|
161
|
-
|
|
294
|
+
obsidianVaultName = null;
|
|
295
|
+
setObsidianVaultPath(vaultPath, vaultName) {
|
|
162
296
|
this.obsidianVaultPath = vaultPath;
|
|
297
|
+
this.obsidianVaultName = vaultName ?? null;
|
|
163
298
|
}
|
|
164
299
|
agentEventBus = null;
|
|
165
300
|
setAgentEventBus(bus) {
|
|
@@ -387,6 +522,9 @@ class GatewayToolExecutor {
|
|
|
387
522
|
setWikiPublisher(fn) {
|
|
388
523
|
this.wikiPublisher = fn;
|
|
389
524
|
}
|
|
525
|
+
setWikiPublishAdapter(adapter) {
|
|
526
|
+
this.wikiPublishAdapter = adapter;
|
|
527
|
+
}
|
|
390
528
|
/** Check if a memory agent is available for routing memory writes. */
|
|
391
529
|
hasMemoryAgent() {
|
|
392
530
|
return this.memoryAgentProcessManager !== null;
|
|
@@ -423,6 +561,8 @@ class GatewayToolExecutor {
|
|
|
423
561
|
this.sessionStore = options.sessionStore;
|
|
424
562
|
this.envelopeIssuanceMode = options.envelopeIssuanceMode ?? 'enabled';
|
|
425
563
|
this.metricsStore = options.metricsStore ?? null;
|
|
564
|
+
this.contextCompileService = options.contextCompileService;
|
|
565
|
+
this.wikiPublishAdapter = options.wikiPublishAdapter ?? null;
|
|
426
566
|
this.browserTool = (0, browser_tool_js_1.getBrowserTool)({
|
|
427
567
|
screenshotDir: (0, path_1.join)(process.env.HOME || '', '.mama', 'workspace', 'media', 'outbound'),
|
|
428
568
|
});
|
|
@@ -474,6 +614,9 @@ class GatewayToolExecutor {
|
|
|
474
614
|
setTelegramGateway(gateway) {
|
|
475
615
|
this.telegramGateway = gateway;
|
|
476
616
|
}
|
|
617
|
+
setContextCompileService(service) {
|
|
618
|
+
this.contextCompileService = service;
|
|
619
|
+
}
|
|
477
620
|
/**
|
|
478
621
|
* Initialize the MAMA API by importing from mcp-server package
|
|
479
622
|
* Called lazily on first tool execution if not provided in constructor
|
|
@@ -818,6 +961,9 @@ class GatewayToolExecutor {
|
|
|
818
961
|
return { requestedScopes, envelopeScopesSnapshot, mismatch: 0 };
|
|
819
962
|
}
|
|
820
963
|
if (!requestedScopes || requestedScopes.length === 0) {
|
|
964
|
+
if (toolName === 'context_compile' && Array.isArray(input.scopes)) {
|
|
965
|
+
return { requestedScopes, envelopeScopesSnapshot, mismatch: 0 };
|
|
966
|
+
}
|
|
821
967
|
return {
|
|
822
968
|
requestedScopes,
|
|
823
969
|
envelopeScopesSnapshot,
|
|
@@ -836,7 +982,9 @@ class GatewayToolExecutor {
|
|
|
836
982
|
if (toolName === 'mama_save') {
|
|
837
983
|
return normalizeMemoryScopes(input.scopes);
|
|
838
984
|
}
|
|
839
|
-
if (toolName === 'mama_search' ||
|
|
985
|
+
if (toolName === 'mama_search' ||
|
|
986
|
+
toolName === 'mama_recall' ||
|
|
987
|
+
toolName === 'context_compile') {
|
|
840
988
|
return normalizeMemoryScopes(input.scopes);
|
|
841
989
|
}
|
|
842
990
|
if (toolName === 'mama_update') {
|
|
@@ -867,6 +1015,52 @@ class GatewayToolExecutor {
|
|
|
867
1015
|
projectId: process.env.MAMA_WORKSPACE || process.cwd(),
|
|
868
1016
|
});
|
|
869
1017
|
}
|
|
1018
|
+
resolveMamaRecallScopes(input) {
|
|
1019
|
+
const ctx = this.getExecutionState();
|
|
1020
|
+
const requestedScopes = normalizeMemoryScopes(input.scopes);
|
|
1021
|
+
const callerProvidedScopes = input.scopes !== undefined;
|
|
1022
|
+
const allowedScopes = ctx.envelope?.scope.memory_scopes ?? this.deriveMemoryScopesFromActiveContext(ctx) ?? [];
|
|
1023
|
+
const hasActiveScopeBoundary = Boolean(ctx.envelope || ctx.agentContext);
|
|
1024
|
+
if (callerProvidedScopes && !requestedScopes) {
|
|
1025
|
+
return {
|
|
1026
|
+
scopes: [],
|
|
1027
|
+
denial: {
|
|
1028
|
+
success: false,
|
|
1029
|
+
code: 'memory_scope_invalid',
|
|
1030
|
+
error: 'mama_recall scopes must be valid memory scope objects.',
|
|
1031
|
+
},
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
if (!hasActiveScopeBoundary) {
|
|
1035
|
+
if (callerProvidedScopes) {
|
|
1036
|
+
return {
|
|
1037
|
+
scopes: [],
|
|
1038
|
+
denial: {
|
|
1039
|
+
success: false,
|
|
1040
|
+
code: 'memory_scope_denied',
|
|
1041
|
+
error: 'mama_recall requires an active session or envelope for caller-supplied scopes.',
|
|
1042
|
+
},
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
return { scopes: [] };
|
|
1046
|
+
}
|
|
1047
|
+
if (!requestedScopes || requestedScopes.length === 0) {
|
|
1048
|
+
return { scopes: allowedScopes };
|
|
1049
|
+
}
|
|
1050
|
+
const allowedScopeKeys = new Set(allowedScopes.map(memoryScopeKey));
|
|
1051
|
+
const hasUnauthorizedScope = requestedScopes.some((scope) => !allowedScopeKeys.has(memoryScopeKey(scope)));
|
|
1052
|
+
if (hasUnauthorizedScope) {
|
|
1053
|
+
return {
|
|
1054
|
+
scopes: [],
|
|
1055
|
+
denial: {
|
|
1056
|
+
success: false,
|
|
1057
|
+
code: 'memory_scope_denied',
|
|
1058
|
+
error: 'mama_recall requested scopes outside the active session or envelope.',
|
|
1059
|
+
},
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
return { scopes: requestedScopes };
|
|
1063
|
+
}
|
|
870
1064
|
applyEnvelopeScopedReadDefaults(toolName, input, ctx) {
|
|
871
1065
|
// Memory read tools must inherit envelope scopes consistently when the
|
|
872
1066
|
// caller omits scopes. Otherwise recall can fall back to active-context
|
|
@@ -875,8 +1069,15 @@ class GatewayToolExecutor {
|
|
|
875
1069
|
return input;
|
|
876
1070
|
}
|
|
877
1071
|
const scopedInput = input;
|
|
1072
|
+
if (toolName === 'mama_save' && hasContextPacketIdInput(scopedInput)) {
|
|
1073
|
+
// Invalid context_packet_id values are rejected later in the mama_save
|
|
1074
|
+
// handler. Skip default-scope injection for any present value so that
|
|
1075
|
+
// subsequent validation can return context_packet_denied without being
|
|
1076
|
+
// masked by envelope-scope defaults.
|
|
1077
|
+
return input;
|
|
1078
|
+
}
|
|
878
1079
|
const hasCallerScopes = Array.isArray(scopedInput.scopes)
|
|
879
|
-
? scopedInput.scopes.length > 0
|
|
1080
|
+
? toolName === 'context_compile' || scopedInput.scopes.length > 0
|
|
880
1081
|
: scopedInput.scopes !== undefined;
|
|
881
1082
|
if (hasCallerScopes) {
|
|
882
1083
|
return input;
|
|
@@ -886,25 +1087,69 @@ class GatewayToolExecutor {
|
|
|
886
1087
|
scopes: ctx.envelope.scope.memory_scopes,
|
|
887
1088
|
};
|
|
888
1089
|
}
|
|
889
|
-
buildTrustedMemoryWriteOptions(toolName, gatewayCallId) {
|
|
1090
|
+
async buildTrustedMemoryWriteOptions(toolName, gatewayCallId, input) {
|
|
890
1091
|
const ctx = this.mergeWithFallbackExecutionContext(this.executionContextStorage.getStore());
|
|
891
1092
|
const capability = getTrustedProvenanceRuntime().createTrustedProvenanceCapability();
|
|
1093
|
+
const contextPacketId = getContextPacketIdForTrustedProvenance(input);
|
|
1094
|
+
const packetSourceRefs = [];
|
|
1095
|
+
let contextPacketScopes;
|
|
1096
|
+
if (contextPacketId) {
|
|
1097
|
+
if (!ctx?.envelope) {
|
|
1098
|
+
throw new ContextPacketProvenanceError('context_packet_id requires an active worker envelope.');
|
|
1099
|
+
}
|
|
1100
|
+
if (!ctx.modelRunId) {
|
|
1101
|
+
throw new ContextPacketProvenanceError('context_packet_id requires an active caller model run.');
|
|
1102
|
+
}
|
|
1103
|
+
let packet;
|
|
1104
|
+
try {
|
|
1105
|
+
packet = (0, mama_core_1.getContextPacketForTrustedUse)(await getContextPacketLookupAdapter(), {
|
|
1106
|
+
packetId: contextPacketId,
|
|
1107
|
+
envelopeHash: ctx.envelope.envelope_hash,
|
|
1108
|
+
callerModelRunId: ctx.modelRunId,
|
|
1109
|
+
});
|
|
1110
|
+
}
|
|
1111
|
+
catch (error) {
|
|
1112
|
+
throw new ContextPacketProvenanceError(error instanceof Error ? error.message : String(error));
|
|
1113
|
+
}
|
|
1114
|
+
if (!packet) {
|
|
1115
|
+
throw new ContextPacketProvenanceError(`Context packet not found: ${contextPacketId}`);
|
|
1116
|
+
}
|
|
1117
|
+
packetSourceRefs.push(...packet.source_refs.map(mama_core_1.serializeContextRefForProvenance));
|
|
1118
|
+
contextPacketScopes = packet.scopes.map((scope) => ({ kind: scope.kind, id: scope.id }));
|
|
1119
|
+
if (contextPacketScopes.length === 0) {
|
|
1120
|
+
throw new ContextPacketProvenanceError('Trusted context packet has no memory scopes.');
|
|
1121
|
+
}
|
|
1122
|
+
const requestedScopeValue = input.scopes;
|
|
1123
|
+
if (Array.isArray(requestedScopeValue) && requestedScopeValue.length === 0) {
|
|
1124
|
+
throw new ContextPacketProvenanceError('Requested save scope is outside the trusted context packet scope.');
|
|
1125
|
+
}
|
|
1126
|
+
const requestedScopes = normalizeMemoryScopes(requestedScopeValue);
|
|
1127
|
+
if (requestedScopes &&
|
|
1128
|
+
!requestedScopes.every((scope) => contextPacketScopes?.some((allowed) => memoryScopeKey(allowed) === memoryScopeKey(scope)))) {
|
|
1129
|
+
throw new ContextPacketProvenanceError('Requested save scope is outside the trusted context packet scope.');
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
892
1132
|
return {
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
1133
|
+
options: {
|
|
1134
|
+
capability,
|
|
1135
|
+
provenance: {
|
|
1136
|
+
actor: ctx?.agentContext?.roleName === 'memory_agent' ? 'memory_agent' : 'main_agent',
|
|
1137
|
+
agent_id: ctx?.agentId,
|
|
1138
|
+
model_run_id: ctx?.modelRunId ?? undefined,
|
|
1139
|
+
envelope_hash: ctx?.envelope?.envelope_hash,
|
|
1140
|
+
tool_name: toolName,
|
|
1141
|
+
gateway_call_id: gatewayCallId,
|
|
1142
|
+
...(contextPacketId ? { context_packet_id: contextPacketId } : {}),
|
|
1143
|
+
source_turn_id: ctx?.sourceTurnId,
|
|
1144
|
+
source_message_ref: ctx?.sourceMessageRef,
|
|
1145
|
+
source_refs: dedupeSourceRefs([
|
|
1146
|
+
...(ctx?.envelope?.envelope_hash ? [`envelope:${ctx.envelope.envelope_hash}`] : []),
|
|
1147
|
+
...(ctx?.sourceMessageRef ? [`message:${ctx.sourceMessageRef}`] : []),
|
|
1148
|
+
...packetSourceRefs,
|
|
1149
|
+
]),
|
|
1150
|
+
},
|
|
907
1151
|
},
|
|
1152
|
+
contextPacketScopes,
|
|
908
1153
|
};
|
|
909
1154
|
}
|
|
910
1155
|
supportsTrustedIngest(api) {
|
|
@@ -987,27 +1232,6 @@ class GatewayToolExecutor {
|
|
|
987
1232
|
// Audit warnings must never affect tool execution.
|
|
988
1233
|
}
|
|
989
1234
|
}
|
|
990
|
-
auditedAutoSave(parentToolName, input) {
|
|
991
|
-
const parentContext = this.executionContextStorage.getStore();
|
|
992
|
-
const task = (async () => {
|
|
993
|
-
try {
|
|
994
|
-
if (parentContext) {
|
|
995
|
-
const autosaveContext = {
|
|
996
|
-
...parentContext,
|
|
997
|
-
parentToolName,
|
|
998
|
-
};
|
|
999
|
-
await this.executionContextStorage.run(autosaveContext, () => this.execute('mama_save', input));
|
|
1000
|
-
return;
|
|
1001
|
-
}
|
|
1002
|
-
await this.execute('mama_save', input);
|
|
1003
|
-
}
|
|
1004
|
-
catch {
|
|
1005
|
-
// Autosave is intentionally non-fatal for report/wiki publish tools.
|
|
1006
|
-
}
|
|
1007
|
-
})();
|
|
1008
|
-
parentContext?.backgroundTasks?.register(task);
|
|
1009
|
-
void task;
|
|
1010
|
-
}
|
|
1011
1235
|
async executeWithEnvelopeAndPermissions(toolName, input, gatewayCallId) {
|
|
1012
1236
|
if (!VALID_TOOLS.includes(toolName)) {
|
|
1013
1237
|
throw new types_js_1.AgentError(`Unknown tool: ${toolName}. Valid tools: ${VALID_TOOLS.join(', ')}`, 'UNKNOWN_TOOL', undefined, false);
|
|
@@ -1318,16 +1542,72 @@ class GatewayToolExecutor {
|
|
|
1318
1542
|
case 'mama_save': {
|
|
1319
1543
|
const saveInput = input;
|
|
1320
1544
|
const api = await getApi();
|
|
1321
|
-
|
|
1545
|
+
let trustedOptions;
|
|
1546
|
+
let effectiveSaveInput = saveInput;
|
|
1547
|
+
let hasContextPacketId;
|
|
1548
|
+
try {
|
|
1549
|
+
hasContextPacketId = getContextPacketIdForTrustedProvenance(saveInput) !== null;
|
|
1550
|
+
}
|
|
1551
|
+
catch (error) {
|
|
1552
|
+
if (error instanceof ContextPacketProvenanceError) {
|
|
1553
|
+
return {
|
|
1554
|
+
success: false,
|
|
1555
|
+
code: 'context_packet_denied',
|
|
1556
|
+
error: error.message,
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
throw error;
|
|
1560
|
+
}
|
|
1561
|
+
if (hasContextPacketId && !this.isMemoryDecisionSaveInput(saveInput)) {
|
|
1562
|
+
return {
|
|
1563
|
+
success: false,
|
|
1564
|
+
code: 'context_packet_denied',
|
|
1565
|
+
error: 'context_packet_id is only supported for trusted decision saves.',
|
|
1566
|
+
};
|
|
1567
|
+
}
|
|
1568
|
+
if (this.isMemoryDecisionSaveInput(saveInput) && hasContextPacketId) {
|
|
1569
|
+
if (!this.supportsTrustedSave(api)) {
|
|
1570
|
+
return {
|
|
1571
|
+
success: false,
|
|
1572
|
+
code: 'context_packet_denied',
|
|
1573
|
+
error: 'context_packet_id requires trusted save support.',
|
|
1574
|
+
};
|
|
1575
|
+
}
|
|
1576
|
+
try {
|
|
1577
|
+
const trustedBuild = await this.buildTrustedMemoryWriteOptions('mama_save', gatewayCallId, saveInput);
|
|
1578
|
+
trustedOptions = trustedBuild.options;
|
|
1579
|
+
if (!Array.isArray(saveInput.scopes) && trustedBuild.contextPacketScopes) {
|
|
1580
|
+
effectiveSaveInput = {
|
|
1581
|
+
...saveInput,
|
|
1582
|
+
scopes: trustedBuild.contextPacketScopes,
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
1585
|
+
}
|
|
1586
|
+
catch (error) {
|
|
1587
|
+
if (error instanceof ContextPacketProvenanceError) {
|
|
1588
|
+
return {
|
|
1589
|
+
success: false,
|
|
1590
|
+
code: 'context_packet_denied',
|
|
1591
|
+
error: error.message,
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
throw error;
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
else if (this.isMemoryDecisionSaveInput(saveInput) && this.supportsTrustedSave(api)) {
|
|
1598
|
+
trustedOptions = (await this.buildTrustedMemoryWriteOptions('mama_save', gatewayCallId))
|
|
1599
|
+
.options;
|
|
1600
|
+
}
|
|
1601
|
+
return await (0, mama_tool_handlers_js_1.handleSave)(api, effectiveSaveInput, this.sessionStore?.getHistory
|
|
1322
1602
|
? () => this.sessionStore.getHistory('current')
|
|
1323
|
-
: undefined,
|
|
1324
|
-
? this.buildTrustedMemoryWriteOptions('mama_save', gatewayCallId)
|
|
1325
|
-
: undefined);
|
|
1603
|
+
: undefined, trustedOptions);
|
|
1326
1604
|
}
|
|
1327
1605
|
case 'mama_search':
|
|
1328
1606
|
return await (0, mama_tool_handlers_js_1.handleSearch)(await getApi(), input);
|
|
1329
1607
|
case 'mama_recall':
|
|
1330
1608
|
return await this.handleMamaRecall(input);
|
|
1609
|
+
case 'context_compile':
|
|
1610
|
+
return await this.handleContextCompile(input);
|
|
1331
1611
|
case 'mama_update':
|
|
1332
1612
|
return await (0, mama_tool_handlers_js_1.handleUpdate)(await getApi(), input);
|
|
1333
1613
|
case 'mama_load_checkpoint':
|
|
@@ -1335,13 +1615,13 @@ class GatewayToolExecutor {
|
|
|
1335
1615
|
case 'mama_add': {
|
|
1336
1616
|
const api = await getApi();
|
|
1337
1617
|
return await this.handleMamaAdd(input, this.supportsTrustedIngest(api)
|
|
1338
|
-
? this.buildTrustedMemoryWriteOptions('mama_add', gatewayCallId)
|
|
1618
|
+
? (await this.buildTrustedMemoryWriteOptions('mama_add', gatewayCallId)).options
|
|
1339
1619
|
: undefined);
|
|
1340
1620
|
}
|
|
1341
1621
|
case 'mama_ingest': {
|
|
1342
1622
|
const api = await getApi();
|
|
1343
1623
|
return await this.handleMamaIngest(input, this.supportsTrustedIngest(api)
|
|
1344
|
-
? this.buildTrustedMemoryWriteOptions('mama_ingest', gatewayCallId)
|
|
1624
|
+
? (await this.buildTrustedMemoryWriteOptions('mama_ingest', gatewayCallId)).options
|
|
1345
1625
|
: undefined);
|
|
1346
1626
|
}
|
|
1347
1627
|
case 'report_publish': {
|
|
@@ -1352,20 +1632,6 @@ class GatewayToolExecutor {
|
|
|
1352
1632
|
if (this.reportPublisher) {
|
|
1353
1633
|
this.reportPublisher(slotsInput);
|
|
1354
1634
|
const slotNames = Object.keys(slotsInput);
|
|
1355
|
-
// Persist report summary to mama memory for Conductor querying
|
|
1356
|
-
const slotValues = Object.values(slotsInput).join(' ');
|
|
1357
|
-
const textSummary = slotValues
|
|
1358
|
-
.replace(/<[^>]+>/g, ' ')
|
|
1359
|
-
.replace(/\s+/g, ' ')
|
|
1360
|
-
.trim();
|
|
1361
|
-
const truncated = textSummary.length > 1500 ? textSummary.substring(0, 1500) + '...' : textSummary;
|
|
1362
|
-
this.auditedAutoSave('report_publish', {
|
|
1363
|
-
type: 'decision',
|
|
1364
|
-
topic: 'dashboard_briefing',
|
|
1365
|
-
decision: `Dashboard briefing (${new Date().toISOString().split('T')[0]}): ${truncated}`,
|
|
1366
|
-
reasoning: 'Auto-saved by dashboard agent after report_publish',
|
|
1367
|
-
scopes: [{ kind: 'global', id: 'system' }],
|
|
1368
|
-
});
|
|
1369
1635
|
return {
|
|
1370
1636
|
success: true,
|
|
1371
1637
|
message: `Dashboard updated: ${slotNames.join(', ')} (${slotNames.length} slots)`,
|
|
@@ -1378,37 +1644,21 @@ class GatewayToolExecutor {
|
|
|
1378
1644
|
if (!pagesInput || !Array.isArray(pagesInput)) {
|
|
1379
1645
|
throw new types_js_1.AgentError('wiki_publish requires pages array', 'TOOL_ERROR', undefined, false);
|
|
1380
1646
|
}
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
path: p.path,
|
|
1385
|
-
title: p.title,
|
|
1386
|
-
type: p.type || 'entity',
|
|
1387
|
-
content: p.content,
|
|
1388
|
-
sourceIds: [],
|
|
1389
|
-
compiledAt: now,
|
|
1390
|
-
confidence: p.confidence || 'medium',
|
|
1391
|
-
}));
|
|
1392
|
-
this.wikiPublisher(wikiPages);
|
|
1393
|
-
// Persist wiki compilation summary to mama memory for Conductor querying
|
|
1394
|
-
const pageSummary = pagesInput
|
|
1395
|
-
.slice(0, 20)
|
|
1396
|
-
.map((p) => `- ${p.title || p.path} (${p.type || 'page'})`)
|
|
1397
|
-
.join('\n');
|
|
1398
|
-
const wikiSummary = `Wiki compilation (${now.split('T')[0]}): ${pagesInput.length} pages\n${pageSummary}`;
|
|
1399
|
-
this.auditedAutoSave('wiki_publish', {
|
|
1400
|
-
type: 'decision',
|
|
1401
|
-
topic: 'wiki_compilation',
|
|
1402
|
-
decision: wikiSummary,
|
|
1403
|
-
reasoning: 'Auto-saved by wiki agent after wiki_publish',
|
|
1404
|
-
scopes: [{ kind: 'global', id: 'system' }],
|
|
1647
|
+
const adapter = this.wikiPublishAdapter ??
|
|
1648
|
+
(0, wiki_publish_adapter_js_1.createWikiPublishAdapter)({
|
|
1649
|
+
publisher: this.wikiPublisher,
|
|
1405
1650
|
});
|
|
1651
|
+
try {
|
|
1652
|
+
const publishResult = adapter.publish({ pages: pagesInput });
|
|
1406
1653
|
return {
|
|
1407
1654
|
success: true,
|
|
1408
|
-
message: `Wiki published: ${
|
|
1655
|
+
message: `Wiki published: ${publishResult.pagesPublished} pages`,
|
|
1656
|
+
artifactsStored: publishResult.artifactsStored,
|
|
1409
1657
|
};
|
|
1410
1658
|
}
|
|
1411
|
-
|
|
1659
|
+
catch (error) {
|
|
1660
|
+
throw new types_js_1.AgentError(error instanceof Error ? error.message : 'Wiki publish failed', 'TOOL_ERROR', undefined, false);
|
|
1661
|
+
}
|
|
1412
1662
|
}
|
|
1413
1663
|
// Kagemusha query tools — progressive business data exploration
|
|
1414
1664
|
case 'kagemusha_overview': {
|
|
@@ -2565,8 +2815,12 @@ class GatewayToolExecutor {
|
|
|
2565
2815
|
};
|
|
2566
2816
|
}
|
|
2567
2817
|
// Obsidian CLI syntax: obsidian <command> key=value ... [flags]
|
|
2568
|
-
//
|
|
2818
|
+
// Without vault=<name> the CLI targets the FOCUSED vault, so wiki writes
|
|
2819
|
+
// could land in whatever vault the owner has open. Pin it when configured.
|
|
2569
2820
|
const cliArgs = [command];
|
|
2821
|
+
if (this.obsidianVaultName) {
|
|
2822
|
+
cliArgs.push(`vault=${this.obsidianVaultName}`);
|
|
2823
|
+
}
|
|
2570
2824
|
for (const [key, value] of Object.entries(args || {})) {
|
|
2571
2825
|
if (value === 'true' && ['silent', 'overwrite', 'total'].includes(key)) {
|
|
2572
2826
|
cliArgs.push(key);
|
|
@@ -2600,13 +2854,95 @@ class GatewayToolExecutor {
|
|
|
2600
2854
|
};
|
|
2601
2855
|
}
|
|
2602
2856
|
}
|
|
2857
|
+
resolveCodeActSandboxRole(input, activeRole, registryNames) {
|
|
2858
|
+
const allowedResolution = this.normalizeCodeActToolPatterns(input.allowedTools, 'allowedTools', registryNames);
|
|
2859
|
+
if (allowedResolution.error) {
|
|
2860
|
+
return { error: allowedResolution.error };
|
|
2861
|
+
}
|
|
2862
|
+
const blockedResolution = this.normalizeCodeActToolPatterns(input.blockedTools, 'blockedTools', registryNames);
|
|
2863
|
+
if (blockedResolution.error) {
|
|
2864
|
+
return { error: blockedResolution.error };
|
|
2865
|
+
}
|
|
2866
|
+
if (!activeRole && !allowedResolution.patterns && !blockedResolution.patterns) {
|
|
2867
|
+
return {};
|
|
2868
|
+
}
|
|
2869
|
+
let effectiveToolNames = activeRole
|
|
2870
|
+
? registryNames.filter((toolName) => this.roleManager.isToolAllowed(activeRole, toolName))
|
|
2871
|
+
: [...registryNames];
|
|
2872
|
+
const allowedPatterns = allowedResolution.patterns;
|
|
2873
|
+
if (allowedPatterns) {
|
|
2874
|
+
effectiveToolNames = effectiveToolNames.filter((toolName) => this.matchesAnyCodeActToolPattern(toolName, allowedPatterns));
|
|
2875
|
+
}
|
|
2876
|
+
const blockedPatterns = blockedResolution.patterns;
|
|
2877
|
+
if (blockedPatterns) {
|
|
2878
|
+
effectiveToolNames = effectiveToolNames.filter((toolName) => !this.matchesAnyCodeActToolPattern(toolName, blockedPatterns));
|
|
2879
|
+
}
|
|
2880
|
+
return {
|
|
2881
|
+
role: {
|
|
2882
|
+
...activeRole,
|
|
2883
|
+
allowedTools: effectiveToolNames,
|
|
2884
|
+
blockedTools: undefined,
|
|
2885
|
+
allowedPaths: activeRole?.allowedPaths ?? [],
|
|
2886
|
+
systemControl: activeRole?.systemControl ?? false,
|
|
2887
|
+
sensitiveAccess: activeRole?.sensitiveAccess ?? false,
|
|
2888
|
+
},
|
|
2889
|
+
};
|
|
2890
|
+
}
|
|
2891
|
+
normalizeCodeActToolPatterns(value, fieldName, registryNames) {
|
|
2892
|
+
if (value === undefined) {
|
|
2893
|
+
return {};
|
|
2894
|
+
}
|
|
2895
|
+
if (!Array.isArray(value)) {
|
|
2896
|
+
return { error: `${fieldName} must be an array of gateway tool names.` };
|
|
2897
|
+
}
|
|
2898
|
+
const patterns = [];
|
|
2899
|
+
const seen = new Set();
|
|
2900
|
+
for (const item of value) {
|
|
2901
|
+
if (typeof item !== 'string' || item.trim().length === 0) {
|
|
2902
|
+
return { error: `${fieldName} must contain non-empty gateway tool names.` };
|
|
2903
|
+
}
|
|
2904
|
+
const pattern = item.trim();
|
|
2905
|
+
if (seen.has(pattern)) {
|
|
2906
|
+
continue;
|
|
2907
|
+
}
|
|
2908
|
+
if (!this.isKnownCodeActToolPattern(pattern, registryNames)) {
|
|
2909
|
+
return { error: `Unknown Code-Act tool pattern in ${fieldName}: ${pattern}` };
|
|
2910
|
+
}
|
|
2911
|
+
seen.add(pattern);
|
|
2912
|
+
patterns.push(pattern);
|
|
2913
|
+
}
|
|
2914
|
+
return { patterns };
|
|
2915
|
+
}
|
|
2916
|
+
isKnownCodeActToolPattern(pattern, registryNames) {
|
|
2917
|
+
return (pattern === '*' ||
|
|
2918
|
+
registryNames.some((toolName) => this.matchesCodeActToolPattern(toolName, pattern)));
|
|
2919
|
+
}
|
|
2920
|
+
matchesAnyCodeActToolPattern(toolName, patterns) {
|
|
2921
|
+
return patterns.some((pattern) => this.matchesCodeActToolPattern(toolName, pattern));
|
|
2922
|
+
}
|
|
2923
|
+
matchesCodeActToolPattern(toolName, pattern) {
|
|
2924
|
+
return this.roleManager.isToolAllowed({
|
|
2925
|
+
allowedTools: [pattern],
|
|
2926
|
+
allowedPaths: [],
|
|
2927
|
+
systemControl: false,
|
|
2928
|
+
sensitiveAccess: false,
|
|
2929
|
+
}, toolName);
|
|
2930
|
+
}
|
|
2603
2931
|
async executeCodeAct(input) {
|
|
2604
2932
|
const { CodeActSandbox, HostBridge } = await import('./code-act/index.js');
|
|
2605
2933
|
const sandbox = new CodeActSandbox();
|
|
2606
|
-
const bridge = new HostBridge(this);
|
|
2607
2934
|
const context = this.getActiveContext();
|
|
2608
2935
|
const tier = (context?.tier ?? 1);
|
|
2609
|
-
|
|
2936
|
+
const registryNames = HostBridge.getToolRegistry().map((meta) => meta.name);
|
|
2937
|
+
const sandboxRole = this.resolveCodeActSandboxRole(input, context?.role, registryNames);
|
|
2938
|
+
if (sandboxRole.error) {
|
|
2939
|
+
return {
|
|
2940
|
+
success: false,
|
|
2941
|
+
error: sandboxRole.error,
|
|
2942
|
+
};
|
|
2943
|
+
}
|
|
2944
|
+
const bridge = new HostBridge(this, this.roleManager);
|
|
2945
|
+
bridge.injectInto(sandbox, tier, sandboxRole.role);
|
|
2610
2946
|
const result = await sandbox.execute(input.code);
|
|
2611
2947
|
return {
|
|
2612
2948
|
success: result.success,
|
|
@@ -2659,15 +2995,19 @@ class GatewayToolExecutor {
|
|
|
2659
2995
|
error: 'Memory ingest API not available.',
|
|
2660
2996
|
};
|
|
2661
2997
|
}
|
|
2662
|
-
const
|
|
2663
|
-
const
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2998
|
+
const activeState = this.getExecutionState();
|
|
2999
|
+
const context = activeState.agentContext;
|
|
3000
|
+
const envelopeScopes = activeState.envelope?.scope.memory_scopes ?? null;
|
|
3001
|
+
const fallbackScopes = envelopeScopes && envelopeScopes.length > 0
|
|
3002
|
+
? envelopeScopes
|
|
3003
|
+
: context
|
|
3004
|
+
? (0, scope_context_js_1.deriveMemoryScopes)({
|
|
3005
|
+
source: context.source,
|
|
3006
|
+
channelId: context.session.channelId,
|
|
3007
|
+
userId: context.session.userId,
|
|
3008
|
+
projectId: process.env.MAMA_WORKSPACE || process.cwd(),
|
|
3009
|
+
})
|
|
3010
|
+
: [];
|
|
2671
3011
|
let scopes = fallbackScopes;
|
|
2672
3012
|
if (Array.isArray(input.scopes) && input.scopes.length > 0) {
|
|
2673
3013
|
const derivedIds = new Set(fallbackScopes.map((s) => `${s.kind}:${s.id}`));
|
|
@@ -2714,17 +3054,11 @@ class GatewayToolExecutor {
|
|
|
2714
3054
|
error: 'query is required and recallMemory API must be available',
|
|
2715
3055
|
};
|
|
2716
3056
|
}
|
|
2717
|
-
const
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
userId: context.session.userId,
|
|
2723
|
-
projectId: process.env.MAMA_WORKSPACE || process.cwd(),
|
|
2724
|
-
})
|
|
2725
|
-
: [];
|
|
2726
|
-
const inputScopes = Array.isArray(input.scopes) ? input.scopes : [];
|
|
2727
|
-
const scopes = inputScopes.length > 0 ? inputScopes : fallbackScopes;
|
|
3057
|
+
const scopeResolution = this.resolveMamaRecallScopes(input);
|
|
3058
|
+
if (scopeResolution.denial) {
|
|
3059
|
+
return scopeResolution.denial;
|
|
3060
|
+
}
|
|
3061
|
+
const scopes = scopeResolution.scopes;
|
|
2728
3062
|
if (scopes.length === 0) {
|
|
2729
3063
|
return {
|
|
2730
3064
|
success: false,
|
|
@@ -2736,7 +3070,7 @@ class GatewayToolExecutor {
|
|
|
2736
3070
|
scopes,
|
|
2737
3071
|
includeProfile: true,
|
|
2738
3072
|
});
|
|
2739
|
-
return { success: true, bundle };
|
|
3073
|
+
return { success: true, bundle: sanitizeMamaRecallBundle(bundle) };
|
|
2740
3074
|
}
|
|
2741
3075
|
catch (err) {
|
|
2742
3076
|
return {
|
|
@@ -2754,6 +3088,57 @@ class GatewayToolExecutor {
|
|
|
2754
3088
|
static isValidTool(toolName) {
|
|
2755
3089
|
return VALID_TOOLS.includes(toolName);
|
|
2756
3090
|
}
|
|
3091
|
+
async handleContextCompile(input) {
|
|
3092
|
+
if (!this.contextCompileService) {
|
|
3093
|
+
return {
|
|
3094
|
+
success: false,
|
|
3095
|
+
code: 'context_compile_unavailable',
|
|
3096
|
+
error: 'context_compile service is not available.',
|
|
3097
|
+
};
|
|
3098
|
+
}
|
|
3099
|
+
const ctx = this.mergeWithFallbackExecutionContext(this.executionContextStorage.getStore());
|
|
3100
|
+
// Fail closed: a Tier-3 designation in either source must block the call,
|
|
3101
|
+
// otherwise a non-Tier-3 fallback could mask a Tier-3 envelope.
|
|
3102
|
+
if (ctx?.agentContext?.tier === 3 || ctx?.envelope?.tier === 3) {
|
|
3103
|
+
return {
|
|
3104
|
+
success: false,
|
|
3105
|
+
code: 'permission_denied_tier3',
|
|
3106
|
+
error: 'context_compile is not allowed for Tier 3 agents.',
|
|
3107
|
+
};
|
|
3108
|
+
}
|
|
3109
|
+
if (!ctx?.envelope) {
|
|
3110
|
+
return {
|
|
3111
|
+
success: false,
|
|
3112
|
+
code: 'envelope_missing',
|
|
3113
|
+
error: 'context_compile requires an active worker envelope.',
|
|
3114
|
+
};
|
|
3115
|
+
}
|
|
3116
|
+
try {
|
|
3117
|
+
const result = await this.contextCompileService.compileAndPersistContext({
|
|
3118
|
+
caller: 'gateway',
|
|
3119
|
+
envelope: ctx.envelope,
|
|
3120
|
+
modelRunId: ctx.modelRunId ?? null,
|
|
3121
|
+
input,
|
|
3122
|
+
});
|
|
3123
|
+
return {
|
|
3124
|
+
success: true,
|
|
3125
|
+
packet: result.packet,
|
|
3126
|
+
packet_id: result.packet.packet_id,
|
|
3127
|
+
model_run_id: result.modelRunId,
|
|
3128
|
+
parent_model_run_id: result.parentModelRunId,
|
|
3129
|
+
};
|
|
3130
|
+
}
|
|
3131
|
+
catch (err) {
|
|
3132
|
+
const errorRecord = err && typeof err === 'object' ? err : undefined;
|
|
3133
|
+
const code = typeof errorRecord?.code === 'string' ? errorRecord.code : 'context_compile_failed';
|
|
3134
|
+
return {
|
|
3135
|
+
success: false,
|
|
3136
|
+
code,
|
|
3137
|
+
error: `context_compile failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
3138
|
+
...(errorRecord && 'details' in errorRecord ? { details: errorRecord.details } : {}),
|
|
3139
|
+
};
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
2757
3142
|
}
|
|
2758
3143
|
exports.GatewayToolExecutor = GatewayToolExecutor;
|
|
2759
3144
|
function isTruthyEnv(name) {
|
|
@@ -2799,6 +3184,51 @@ function getTrustedProvenanceRuntime() {
|
|
|
2799
3184
|
}
|
|
2800
3185
|
throw new types_js_1.AgentError(`Trusted provenance runtime unavailable: ${lastError instanceof Error ? lastError.message : String(lastError)}`, 'TOOL_ERROR', lastError instanceof Error ? lastError : undefined, false);
|
|
2801
3186
|
}
|
|
3187
|
+
async function getContextPacketLookupAdapter() {
|
|
3188
|
+
try {
|
|
3189
|
+
const dbManager = (await import('@jungjaehoon/mama-core/db-manager'));
|
|
3190
|
+
try {
|
|
3191
|
+
return dbManager.getAdapter();
|
|
3192
|
+
}
|
|
3193
|
+
catch (error) {
|
|
3194
|
+
if (typeof dbManager.initDB !== 'function') {
|
|
3195
|
+
throw error;
|
|
3196
|
+
}
|
|
3197
|
+
await dbManager.initDB();
|
|
3198
|
+
return dbManager.getAdapter();
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
catch (error) {
|
|
3202
|
+
throw new ContextPacketProvenanceError(`Context packet store unavailable: ${error instanceof Error ? error.message : String(error)}`);
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
function hasContextPacketIdInput(input) {
|
|
3206
|
+
if (!input || !('context_packet_id' in input)) {
|
|
3207
|
+
return false;
|
|
3208
|
+
}
|
|
3209
|
+
const value = input.context_packet_id;
|
|
3210
|
+
return value !== undefined && value !== null;
|
|
3211
|
+
}
|
|
3212
|
+
function getContextPacketIdForTrustedProvenance(input) {
|
|
3213
|
+
if (!input || !('context_packet_id' in input)) {
|
|
3214
|
+
return null;
|
|
3215
|
+
}
|
|
3216
|
+
const value = input.context_packet_id;
|
|
3217
|
+
if (value === undefined || value === null) {
|
|
3218
|
+
return null;
|
|
3219
|
+
}
|
|
3220
|
+
if (typeof value !== 'string') {
|
|
3221
|
+
throw new ContextPacketProvenanceError('context_packet_id must be a string when provided.');
|
|
3222
|
+
}
|
|
3223
|
+
const trimmed = value.trim();
|
|
3224
|
+
if (trimmed.length === 0) {
|
|
3225
|
+
throw new ContextPacketProvenanceError('context_packet_id must not be empty when provided.');
|
|
3226
|
+
}
|
|
3227
|
+
return trimmed;
|
|
3228
|
+
}
|
|
3229
|
+
function dedupeSourceRefs(refs) {
|
|
3230
|
+
return [...new Set(refs)];
|
|
3231
|
+
}
|
|
2802
3232
|
function normalizeMemoryScopes(value) {
|
|
2803
3233
|
if (!Array.isArray(value) || value.length === 0) {
|
|
2804
3234
|
return null;
|