@jungjaehoon/mama-os 0.40.0 → 0.42.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 +2 -2
- package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
- package/dist/agent/code-act/host-bridge.js +0 -22
- package/dist/agent/code-act/host-bridge.js.map +1 -1
- package/dist/agent/gateway-tool-executor.d.ts +6 -7
- package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
- package/dist/agent/gateway-tool-executor.js +49 -76
- package/dist/agent/gateway-tool-executor.js.map +1 -1
- package/dist/agent/gateway-tools.md +1 -3
- package/dist/agent/tool-registry.d.ts.map +1 -1
- package/dist/agent/tool-registry.js +6 -18
- package/dist/agent/tool-registry.js.map +1 -1
- package/dist/agent/types.d.ts +1 -8
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/graph-api.d.ts.map +1 -1
- package/dist/api/graph-api.js +23 -4
- package/dist/api/graph-api.js.map +1 -1
- package/dist/cli/commands/start.d.ts +45 -52
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +292 -202
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/config/types.d.ts.map +1 -1
- package/dist/cli/config/types.js +0 -2
- package/dist/cli/config/types.js.map +1 -1
- package/dist/cli/runtime/api-routes-init.d.ts +0 -3
- package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
- package/dist/cli/runtime/api-routes-init.js +8 -32
- package/dist/cli/runtime/api-routes-init.js.map +1 -1
- package/dist/cli/runtime/mama-core-init.d.ts.map +1 -1
- package/dist/cli/runtime/mama-core-init.js +2 -0
- package/dist/cli/runtime/mama-core-init.js.map +1 -1
- package/dist/connectors/private-connector-policy.d.ts +1 -3
- package/dist/connectors/private-connector-policy.d.ts.map +1 -1
- package/dist/connectors/private-connector-policy.js +1 -26
- package/dist/connectors/private-connector-policy.js.map +1 -1
- package/dist/gateways/context-injector.d.ts +10 -0
- package/dist/gateways/context-injector.d.ts.map +1 -1
- package/dist/gateways/context-injector.js.map +1 -1
- package/dist/gateways/message-router.d.ts +4 -0
- package/dist/gateways/message-router.d.ts.map +1 -1
- package/dist/gateways/message-router.js +88 -5
- package/dist/gateways/message-router.js.map +1 -1
- package/dist/multi-agent/dashboard-agent-persona.d.ts +1 -1
- package/dist/multi-agent/dashboard-agent-persona.d.ts.map +1 -1
- package/dist/multi-agent/dashboard-agent-persona.js +6 -7
- package/dist/multi-agent/dashboard-agent-persona.js.map +1 -1
- package/dist/operator/board-pipeline-render.d.ts +17 -0
- package/dist/operator/board-pipeline-render.d.ts.map +1 -0
- package/dist/operator/board-pipeline-render.js +73 -0
- package/dist/operator/board-pipeline-render.js.map +1 -0
- package/dist/operator/board-slot-instructions.d.ts +0 -8
- package/dist/operator/board-slot-instructions.d.ts.map +1 -1
- package/dist/operator/board-slot-instructions.js +3 -37
- package/dist/operator/board-slot-instructions.js.map +1 -1
- package/dist/operator/console-brief.d.ts +1 -1
- package/dist/operator/console-brief.d.ts.map +1 -1
- package/dist/operator/console-brief.js +5 -4
- package/dist/operator/console-brief.js.map +1 -1
- package/dist/operator/learning-context.d.ts +49 -0
- package/dist/operator/learning-context.d.ts.map +1 -0
- package/dist/operator/learning-context.js +129 -0
- package/dist/operator/learning-context.js.map +1 -0
- package/dist/operator/learning-markers.d.ts +19 -0
- package/dist/operator/learning-markers.d.ts.map +1 -0
- package/dist/operator/learning-markers.js +147 -0
- package/dist/operator/learning-markers.js.map +1 -0
- package/dist/operator/learning-read.d.ts +16 -0
- package/dist/operator/learning-read.d.ts.map +1 -0
- package/dist/operator/learning-read.js +18 -0
- package/dist/operator/learning-read.js.map +1 -0
- package/dist/operator/owner-event-inbox.d.ts +10 -1
- package/dist/operator/owner-event-inbox.d.ts.map +1 -1
- package/dist/operator/owner-event-inbox.js +22 -6
- package/dist/operator/owner-event-inbox.js.map +1 -1
- package/dist/operator/owner-event-loop.d.ts +4 -2
- package/dist/operator/owner-event-loop.d.ts.map +1 -1
- package/dist/operator/owner-event-loop.js +20 -3
- package/dist/operator/owner-event-loop.js.map +1 -1
- package/dist/operator/owner-event-outcome.d.ts +3 -3
- package/dist/operator/owner-event-outcome.d.ts.map +1 -1
- package/dist/operator/owner-event-outcome.js +66 -9
- package/dist/operator/owner-event-outcome.js.map +1 -1
- package/dist/operator/owner-event-policy.d.ts.map +1 -1
- package/dist/operator/owner-event-policy.js +18 -8
- package/dist/operator/owner-event-policy.js.map +1 -1
- package/dist/operator/owner-event-prompt.d.ts +4 -0
- package/dist/operator/owner-event-prompt.d.ts.map +1 -1
- package/dist/operator/owner-event-prompt.js +15 -5
- package/dist/operator/owner-event-prompt.js.map +1 -1
- package/dist/operator/report-context.d.ts +12 -0
- package/dist/operator/report-context.d.ts.map +1 -1
- package/dist/operator/report-context.js +60 -0
- package/dist/operator/report-context.js.map +1 -1
- package/dist/operator/task-ledger.d.ts +20 -1
- package/dist/operator/task-ledger.d.ts.map +1 -1
- package/dist/operator/task-ledger.js +58 -1
- package/dist/operator/task-ledger.js.map +1 -1
- package/dist/operator/temporal-worker.d.ts +0 -1
- package/dist/operator/temporal-worker.d.ts.map +1 -1
- package/dist/operator/temporal-worker.js +0 -29
- package/dist/operator/temporal-worker.js.map +1 -1
- package/dist/operator/turn-observer.d.ts +34 -0
- package/dist/operator/turn-observer.d.ts.map +1 -0
- package/dist/operator/turn-observer.js +79 -0
- package/dist/operator/turn-observer.js.map +1 -0
- package/dist/operator/worker-run.d.ts +1 -1
- package/dist/operator/worker-run.d.ts.map +1 -1
- package/dist/operator/worker-run.js +5 -4
- package/dist/operator/worker-run.js.map +1 -1
- package/dist/operator/workorder-consumer.d.ts +23 -2
- package/dist/operator/workorder-consumer.d.ts.map +1 -1
- package/dist/operator/workorder-consumer.js +99 -1
- package/dist/operator/workorder-consumer.js.map +1 -1
- package/dist/operator/workorder-hooks.d.ts +1 -7
- package/dist/operator/workorder-hooks.d.ts.map +1 -1
- package/dist/operator/workorder-hooks.js +1 -5
- package/dist/operator/workorder-hooks.js.map +1 -1
- package/dist/operator/workorder-publishers.d.ts +0 -7
- package/dist/operator/workorder-publishers.d.ts.map +1 -1
- package/dist/operator/workorder-publishers.js +0 -22
- package/dist/operator/workorder-publishers.js.map +1 -1
- package/package.json +1 -1
- package/dist/db/migrations/owner-event-board-refresh.d.ts +0 -10
- package/dist/db/migrations/owner-event-board-refresh.d.ts.map +0 -1
- package/dist/db/migrations/owner-event-board-refresh.js +0 -27
- package/dist/db/migrations/owner-event-board-refresh.js.map +0 -1
- package/dist/operator/briefs.d.ts +0 -50
- package/dist/operator/briefs.d.ts.map +0 -1
- package/dist/operator/briefs.js +0 -451
- package/dist/operator/briefs.js.map +0 -1
- package/dist/operator/owner-event-board-refresh.d.ts +0 -51
- package/dist/operator/owner-event-board-refresh.d.ts.map +0 -1
- package/dist/operator/owner-event-board-refresh.js +0 -260
- package/dist/operator/owner-event-board-refresh.js.map +0 -1
|
@@ -45,7 +45,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
45
45
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
46
|
};
|
|
47
47
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
-
exports.OPERATOR_REPORT_TOOL_POLICY = exports.
|
|
48
|
+
exports.OPERATOR_REPORT_TOOL_POLICY = exports.TURN_KIND_BLOCKED_TOOLS = exports.SCHEDULED_TURN_BLOCKED_TOOLS = exports.TURN_KIND_REQUIRED_TOOLS = exports.ADMINISTRATION_TOOLS = exports.ONE_AGENT_TURN_POLICY = void 0;
|
|
49
49
|
exports.workOrderActivityDetails = workOrderActivityDetails;
|
|
50
50
|
exports.createCorePrincipalRegistry = createCorePrincipalRegistry;
|
|
51
51
|
exports.createCorePrincipalResolver = createCorePrincipalResolver;
|
|
@@ -60,14 +60,13 @@ exports.causeEventIdsFromPayload = causeEventIdsFromPayload;
|
|
|
60
60
|
exports.workOrderEnvelopeScope = workOrderEnvelopeScope;
|
|
61
61
|
exports.temporalTaskBinding = temporalTaskBinding;
|
|
62
62
|
exports.buildOperatorReportAgentPolicy = buildOperatorReportAgentPolicy;
|
|
63
|
-
exports.
|
|
63
|
+
exports.isOutboundToolName = isOutboundToolName;
|
|
64
|
+
exports.buildTurnAgentPolicy = buildTurnAgentPolicy;
|
|
64
65
|
exports.bindCodeActParentModelRun = bindCodeActParentModelRun;
|
|
65
66
|
exports.finalizeCodeActParentModelRun = finalizeCodeActParentModelRun;
|
|
66
67
|
exports.failCodeActParentModelRun = failCodeActParentModelRun;
|
|
67
68
|
exports.buildSystemAgentProcessDefaults = buildSystemAgentProcessDefaults;
|
|
68
|
-
exports.buildOwnerEventBoardRefreshRuntime = buildOwnerEventBoardRefreshRuntime;
|
|
69
69
|
exports.resolveOwnerEventTerminalReceipt = resolveOwnerEventTerminalReceipt;
|
|
70
|
-
exports.buildOwnerWorkOrderRequestHandler = buildOwnerWorkOrderRequestHandler;
|
|
71
70
|
exports.startCommand = startCommand;
|
|
72
71
|
exports.buildStartOnboardingOutput = buildStartOnboardingOutput;
|
|
73
72
|
exports.runAgentLoop = runAgentLoop;
|
|
@@ -135,11 +134,12 @@ const query_tools_js_1 = require("../../connectors/trello/query-tools.js");
|
|
|
135
134
|
const console_brief_js_1 = require("../../operator/console-brief.js");
|
|
136
135
|
const task_ledger_js_1 = require("../../operator/task-ledger.js");
|
|
137
136
|
const board_refresh_gate_js_1 = require("../../operator/board-refresh-gate.js");
|
|
138
|
-
const workorder_publishers_js_1 = require("../../operator/workorder-publishers.js");
|
|
139
137
|
const owner_event_inbox_js_1 = require("../../operator/owner-event-inbox.js");
|
|
140
138
|
const owner_event_effects_js_1 = require("../../operator/owner-event-effects.js");
|
|
141
|
-
const owner_event_board_refresh_js_1 = require("../../operator/owner-event-board-refresh.js");
|
|
142
139
|
const owner_event_loop_js_1 = require("../../operator/owner-event-loop.js");
|
|
140
|
+
const board_pipeline_render_js_1 = require("../../operator/board-pipeline-render.js");
|
|
141
|
+
const learning_context_js_1 = require("../../operator/learning-context.js");
|
|
142
|
+
const learning_read_js_1 = require("../../operator/learning-read.js");
|
|
143
143
|
const owner_event_prompt_js_1 = require("../../operator/owner-event-prompt.js");
|
|
144
144
|
const owner_event_policy_js_1 = require("../../operator/owner-event-policy.js");
|
|
145
145
|
const leg_cadence_js_1 = require("../../operator/leg-cadence.js");
|
|
@@ -156,7 +156,6 @@ const principalRegistryLogger = new DebugLogger('PrincipalRegistry');
|
|
|
156
156
|
function workOrderActivityDetails(event) {
|
|
157
157
|
return event.briefHash ? { brief_hash: event.briefHash } : undefined;
|
|
158
158
|
}
|
|
159
|
-
const ownerWorkOrderLogger = new DebugLogger('OwnerWorkOrder');
|
|
160
159
|
const DISABLED_PRIVATE_CONNECTOR_POLICY = (0, private_connector_policy_js_1.resolvePrivateConnectorPolicy)({
|
|
161
160
|
ok: true,
|
|
162
161
|
config: {},
|
|
@@ -393,12 +392,18 @@ function causeEventIdsFromPayload(payload) {
|
|
|
393
392
|
}
|
|
394
393
|
function workOrderEnvelopeScope(input) {
|
|
395
394
|
const isTemporal = input.workKind === 'temporal';
|
|
396
|
-
|
|
395
|
+
// One principal for every turn; what differs per kind is WHICH connectors the run
|
|
396
|
+
// may read, and that is data: a recheck reads its task's connector or nothing, a
|
|
397
|
+
// wiki turn reads no PRIVATE connector (personal channels never feed public pages),
|
|
398
|
+
// the board and curation turns keep the lane's configured connectors.
|
|
399
|
+
const surface = exports.ONE_AGENT_TURN_POLICY.roleName;
|
|
397
400
|
const candidateConnectors = isTemporal
|
|
398
401
|
? input.temporalBinding
|
|
399
402
|
? [input.temporalBinding.connector]
|
|
400
403
|
: []
|
|
401
|
-
: input.
|
|
404
|
+
: input.workKind === 'wiki'
|
|
405
|
+
? input.laneConnectors.filter((name) => !input.privateConnectorPolicy.enabledPrivateConnectors.includes(name))
|
|
406
|
+
: input.laneConnectors;
|
|
402
407
|
return {
|
|
403
408
|
project_refs: [{ kind: 'project', id: input.projectId }],
|
|
404
409
|
// A temporal run reads its task's connector or nothing. Every other lane keeps the
|
|
@@ -426,6 +431,11 @@ function workOrderEnvelopeScope(input) {
|
|
|
426
431
|
},
|
|
427
432
|
]
|
|
428
433
|
: []),
|
|
434
|
+
// Same rule for a board reconcile: the run is bound to the channel whose delta it
|
|
435
|
+
// judges, and connector memories are scoped by the canonical channel key.
|
|
436
|
+
...(input.workKind === 'board' && input.reconcileChannelKey
|
|
437
|
+
? [{ kind: 'channel', id: input.reconcileChannelKey }]
|
|
438
|
+
: []),
|
|
429
439
|
],
|
|
430
440
|
allowed_destinations: [],
|
|
431
441
|
};
|
|
@@ -453,48 +463,115 @@ function buildCodeActRole(policy) {
|
|
|
453
463
|
sensitiveAccess: false,
|
|
454
464
|
};
|
|
455
465
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
466
|
+
/**
|
|
467
|
+
* One MAMA: every scheduled turn runs as the SAME principal the owner console and the
|
|
468
|
+
* event turn use. `roleName` is not a label - resolvePrivatePrincipalSurface switches on
|
|
469
|
+
* it and falls through to 'multi-agent-generic' for anything it does not know, which
|
|
470
|
+
* splits the advertised catalog from the execution envelope.
|
|
471
|
+
*/
|
|
472
|
+
exports.ONE_AGENT_TURN_POLICY = { roleName: 'owner_console' };
|
|
473
|
+
/** Owner-authored chat only: administration never runs unattended. */
|
|
474
|
+
exports.ADMINISTRATION_TOOLS = new Set([
|
|
475
|
+
'member_register',
|
|
476
|
+
'member_suspend',
|
|
477
|
+
'member_offboard',
|
|
478
|
+
'member_scope_grant',
|
|
479
|
+
'member_scope_revoke',
|
|
480
|
+
'console_brief_update',
|
|
481
|
+
'report_request',
|
|
482
|
+
]);
|
|
483
|
+
/**
|
|
484
|
+
* Per-turn-kind artifact tools, projected by the HOST. These exist only for scheduled
|
|
485
|
+
* turns and are deliberately absent from the chat grant: a chat turn never publishes a
|
|
486
|
+
* board slot or a wiki page and never files a temporal receipt. They are the tools the
|
|
487
|
+
* turn-kind section instructs the turn to use, so grant and instruction cannot drift.
|
|
488
|
+
*/
|
|
489
|
+
exports.TURN_KIND_REQUIRED_TOOLS = {
|
|
490
|
+
board: [
|
|
491
|
+
'agent_notices',
|
|
492
|
+
'contract_no_update',
|
|
493
|
+
'report_publish',
|
|
494
|
+
'task_external_correlation',
|
|
495
|
+
'task_external_bind',
|
|
496
|
+
'task_lifecycle_reconcile',
|
|
497
|
+
],
|
|
498
|
+
wiki: ['agent_notices', 'contract_no_update', 'wiki_publish'],
|
|
499
|
+
'memory-curation': ['agent_notices', 'contract_no_update'],
|
|
500
|
+
temporal: ['agent_notices', 'contract_no_update', 'task_temporal_reconcile'],
|
|
501
|
+
};
|
|
502
|
+
/**
|
|
503
|
+
* Blocked on EVERY unattended turn. Deliverable, image and Drive tools belong to the
|
|
504
|
+
* owner conversation, and the tier-2 Code-Act projection refuses them anyway - a tool
|
|
505
|
+
* that is advertised but never injected is a hallucinated-call generator. Member data and
|
|
506
|
+
* workspace file reads are owner-conversation material with no use in a scheduled turn.
|
|
507
|
+
*/
|
|
508
|
+
exports.SCHEDULED_TURN_BLOCKED_TOOLS = new Set([
|
|
509
|
+
// workspace file reads are an owner-conversation tool; no turn section instructs one
|
|
510
|
+
'Read',
|
|
511
|
+
// every outbound channel, not only Telegram: the grant is derived from the owner's
|
|
512
|
+
// (editable) role config, so a send tool added there must still never run unattended
|
|
513
|
+
'telegram_send',
|
|
514
|
+
'discord_send',
|
|
515
|
+
'slack_send',
|
|
516
|
+
'webchat_send',
|
|
517
|
+
'drive_upload',
|
|
518
|
+
'drive_list_drives',
|
|
519
|
+
'drive_browse',
|
|
520
|
+
'drive_find_folder',
|
|
521
|
+
'drive_download',
|
|
522
|
+
'ocr_image',
|
|
523
|
+
'create_fb_overlay',
|
|
524
|
+
'translate_conti',
|
|
525
|
+
'drive_translate_conti',
|
|
526
|
+
'member_candidates',
|
|
527
|
+
'member_list',
|
|
528
|
+
'member_scope_list',
|
|
529
|
+
]);
|
|
530
|
+
/**
|
|
531
|
+
* Per-turn-kind blocked lists, projected by the HOST. One principal and one brief do
|
|
532
|
+
* not mean one grant for every trigger: an unattended board or wiki turn has no owner
|
|
533
|
+
* in the loop, so it never holds a send, an upload, or a mutation outside its own
|
|
534
|
+
* artifact. Each entry names the artifact it protects.
|
|
535
|
+
*/
|
|
536
|
+
exports.TURN_KIND_BLOCKED_TOOLS = {
|
|
537
|
+
// board writes judgment slots and task lifecycle (reconcile mode creates rows for new
|
|
538
|
+
// items, which the action verifier's obligated set expects); it does not touch memory
|
|
539
|
+
// or the vault (obsidian is the wiki lane's write path)
|
|
540
|
+
board: new Set([
|
|
541
|
+
'wiki_publish',
|
|
542
|
+
'obsidian',
|
|
543
|
+
'mama_save',
|
|
544
|
+
'mama_update',
|
|
545
|
+
'task_temporal_reconcile',
|
|
546
|
+
]),
|
|
547
|
+
// wiki writes pages; the ledger, the board and memory are not its artifact
|
|
548
|
+
wiki: new Set([
|
|
549
|
+
'report_publish',
|
|
550
|
+
'mama_save',
|
|
551
|
+
'mama_update',
|
|
552
|
+
'task_create',
|
|
553
|
+
'task_update',
|
|
554
|
+
'task_temporal_reconcile',
|
|
555
|
+
]),
|
|
556
|
+
// curation writes memory; nothing else
|
|
557
|
+
'memory-curation': new Set([
|
|
558
|
+
'report_publish',
|
|
559
|
+
'wiki_publish',
|
|
560
|
+
'task_create',
|
|
561
|
+
'task_update',
|
|
562
|
+
'task_temporal_reconcile',
|
|
563
|
+
'obsidian',
|
|
564
|
+
]),
|
|
565
|
+
// recheck resolves ONE task through task_temporal_reconcile; generic mutation is out
|
|
566
|
+
temporal: new Set([
|
|
567
|
+
'report_publish',
|
|
568
|
+
'wiki_publish',
|
|
569
|
+
'mama_save',
|
|
570
|
+
'mama_update',
|
|
571
|
+
'task_create',
|
|
572
|
+
'task_update',
|
|
573
|
+
'obsidian',
|
|
574
|
+
]),
|
|
498
575
|
};
|
|
499
576
|
/**
|
|
500
577
|
* Packet-only reports receive no gateway tools. The host compiles current bounded authorities
|
|
@@ -563,27 +640,42 @@ function buildOperatorReportAgentPolicy(model, backend, privateConnectorPolicy)
|
|
|
563
640
|
briefProjectionPolicy: requiredPrivatePolicy,
|
|
564
641
|
};
|
|
565
642
|
}
|
|
566
|
-
|
|
643
|
+
/** Outbound effect by name: sends to a channel or uploads to a shared store. */
|
|
644
|
+
function isOutboundToolName(tool) {
|
|
645
|
+
return /(^|_)(send|upload)(_|$)/.test(tool);
|
|
646
|
+
}
|
|
647
|
+
function buildTurnAgentPolicy(kind, model, backend, privateConnectorPolicy, rawConnectorScope, ownerRole = types_js_1.DEFAULT_ROLES.definitions.owner_console) {
|
|
567
648
|
const requiredPrivatePolicy = requirePrivateConnectorPolicy(privateConnectorPolicy);
|
|
568
649
|
if (!rawConnectorScope) {
|
|
569
650
|
throw new Error('rawConnectorScope is required');
|
|
570
651
|
}
|
|
571
|
-
const
|
|
572
|
-
if (!
|
|
573
|
-
throw new Error(`Missing
|
|
652
|
+
const kindBlocked = exports.TURN_KIND_BLOCKED_TOOLS[kind];
|
|
653
|
+
if (!kindBlocked) {
|
|
654
|
+
throw new Error(`Missing turn-kind blocked list for '${kind}'`);
|
|
574
655
|
}
|
|
575
|
-
|
|
656
|
+
// Same downgrade the event turn applies: a run with no private binding advertises
|
|
657
|
+
// no private connector tools and gets the disabled brief projection.
|
|
576
658
|
const scopedSurface = requiredPrivatePolicy.enabledPrivateConnectors.some((name) => rawConnectorScope.includes(name))
|
|
577
|
-
?
|
|
659
|
+
? exports.ONE_AGENT_TURN_POLICY.roleName
|
|
578
660
|
: 'multi-agent-generic';
|
|
579
|
-
const
|
|
580
|
-
|
|
581
|
-
|
|
661
|
+
const blockedSet = new Set([
|
|
662
|
+
...exports.ADMINISTRATION_TOOLS,
|
|
663
|
+
...exports.SCHEDULED_TURN_BLOCKED_TOOLS,
|
|
664
|
+
...kindBlocked,
|
|
665
|
+
...(ownerRole.blockedTools ?? []),
|
|
666
|
+
// Shape rule on top of the named lists: the role config is owner-editable, so a
|
|
667
|
+
// send or upload tool that appears there tomorrow is still never unattended.
|
|
668
|
+
...ownerRole.allowedTools.filter((tool) => isOutboundToolName(tool)),
|
|
669
|
+
]);
|
|
670
|
+
const projectedRole = buildProjectedLaneRole(scopedSurface, uniqueToolList([...ownerRole.allowedTools, ...exports.TURN_KIND_REQUIRED_TOOLS[kind]]).filter((tool) => !blockedSet.has(tool)), requiredPrivatePolicy);
|
|
671
|
+
const blockedTools = [...new Set([...(projectedRole.blockedTools ?? []), ...blockedSet])];
|
|
672
|
+
// code_act is the transport, re-added at the front below; it is never an inner tool.
|
|
673
|
+
const innerTools = uniqueToolList(projectedRole.allowedTools).filter((tool) => !blockedSet.has(tool) && tool !== 'code_act');
|
|
582
674
|
const allowedTools = uniqueToolList(['code_act', ...innerTools]);
|
|
583
675
|
const agentContext = {
|
|
584
676
|
source: 'operator',
|
|
585
677
|
platform: 'cli',
|
|
586
|
-
roleName:
|
|
678
|
+
roleName: exports.ONE_AGENT_TURN_POLICY.roleName,
|
|
587
679
|
role: { ...projectedRole, allowedTools, blockedTools, model },
|
|
588
680
|
session: {
|
|
589
681
|
sessionId: `operator:worker:${kind}`,
|
|
@@ -655,104 +747,27 @@ function buildSystemAgentProcessDefaults(config) {
|
|
|
655
747
|
dangerouslySkipPermissions: config.multi_agent?.dangerouslySkipPermissions ?? true,
|
|
656
748
|
};
|
|
657
749
|
}
|
|
658
|
-
const OWNER_BOARD_FULL_REPAIR_CHANNEL = 'host:owner-workorder:board-full';
|
|
659
|
-
function buildOwnerEventBoardRefreshRuntime(operatorDb, taskLedger, now = Date.now) {
|
|
660
|
-
const ownerEventBoardRefreshLedger = new owner_event_board_refresh_js_1.OwnerEventBoardRefreshLedger(operatorDb, taskLedger, now);
|
|
661
|
-
const initialGeneration = (0, owner_event_board_refresh_js_1.resolveInitialBoardRepairGeneration)(now(), ownerEventBoardRefreshLedger.maxPendingGeneration());
|
|
662
|
-
return {
|
|
663
|
-
ownerEventBoardRefreshLedger,
|
|
664
|
-
boardRefreshGate: new board_refresh_gate_js_1.BoardRefreshGate({ initialGeneration }),
|
|
665
|
-
};
|
|
666
|
-
}
|
|
667
750
|
function resolveOwnerEventTerminalReceipt(batch, deps) {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
751
|
+
// Crash-recovery mirror of classifyOwnerEventOutcome. A ledger write that
|
|
752
|
+
// named this batch's events as its cause (evidence_effects) or a confirmed
|
|
753
|
+
// deliverable (drive_upload) is a durable outcome even if the run died after
|
|
754
|
+
// it - without this, a task created before a transport error is created again
|
|
755
|
+
// on retry. A confirmed telegram_send alone is not a receipt, and the effect
|
|
756
|
+
// ledger's (batch, action_key) idempotency makes that retry safe from a second
|
|
757
|
+
// send. A persisted Board acceptance is no longer a receipt.
|
|
758
|
+
const ledgerEffects = deps.taskLedger.effectsCausedBy(batch.eventIds, batch.createdAt);
|
|
759
|
+
const confirmedEffects = deps.ownerEventEffectLedger
|
|
760
|
+
.confirmedKinds(batch.id)
|
|
761
|
+
.filter((kind) => kind !== 'telegram_send');
|
|
762
|
+
const durable = [...new Set([...ledgerEffects, ...confirmedEffects])];
|
|
763
|
+
if (durable.length > 0) {
|
|
764
|
+
return { status: 'acted', tools: durable, ownerDecisionRequested: false };
|
|
678
765
|
}
|
|
679
766
|
if (deps.taskLedger.maxNoUpdateId(`owner-event:${batch.id}`) > 0) {
|
|
680
767
|
return { status: 'no_update', tools: [] };
|
|
681
768
|
}
|
|
682
769
|
return null;
|
|
683
770
|
}
|
|
684
|
-
/** Build the enqueue-and-ack handler shared by owner chat and owner-event turns. */
|
|
685
|
-
function buildOwnerWorkOrderRequestHandler(deps) {
|
|
686
|
-
const now = deps.now ?? Date.now;
|
|
687
|
-
const log = deps.log ?? ((line) => ownerWorkOrderLogger.info(line));
|
|
688
|
-
const logError = deps.logError ?? ((line, detail) => ownerWorkOrderLogger.error(line, detail));
|
|
689
|
-
return (kind, origin = { kind: 'owner_manual' }) => {
|
|
690
|
-
try {
|
|
691
|
-
const requestedAt = now();
|
|
692
|
-
let idempotencyKey;
|
|
693
|
-
let payload;
|
|
694
|
-
if (kind === 'board') {
|
|
695
|
-
if (!deps.boardRefreshGate) {
|
|
696
|
-
throw new Error('Board refresh gate is unavailable');
|
|
697
|
-
}
|
|
698
|
-
if (origin.kind === 'owner_event') {
|
|
699
|
-
if (!deps.ownerEventBoardRefreshLedger) {
|
|
700
|
-
throw new Error('Owner-event Board refresh ledger is unavailable');
|
|
701
|
-
}
|
|
702
|
-
const existing = deps.ownerEventBoardRefreshLedger.findAcceptance(origin.batchId);
|
|
703
|
-
if (existing) {
|
|
704
|
-
log(`[stage2] owner workorder already accepted: board#${existing.workOrderId}`);
|
|
705
|
-
return { accepted: true };
|
|
706
|
-
}
|
|
707
|
-
deps.boardRefreshGate.markChannelDirty(OWNER_BOARD_FULL_REPAIR_CHANNEL);
|
|
708
|
-
const accepted = deps.ownerEventBoardRefreshLedger.accept({
|
|
709
|
-
batchId: origin.batchId,
|
|
710
|
-
eventIds: origin.eventIds,
|
|
711
|
-
repair: deps.boardRefreshGate.captureFullRepair(),
|
|
712
|
-
});
|
|
713
|
-
log(`[stage2] owner workorder accepted: board#${accepted.workOrderId}`);
|
|
714
|
-
return { accepted: true };
|
|
715
|
-
}
|
|
716
|
-
// TG-06: host dirt is recorded before validation or enqueue can fail.
|
|
717
|
-
// The fixed synthetic channel never trusts model/event identifiers.
|
|
718
|
-
deps.boardRefreshGate.markChannelDirty(OWNER_BOARD_FULL_REPAIR_CHANNEL);
|
|
719
|
-
const repair = deps.boardRefreshGate.captureFullRepair();
|
|
720
|
-
idempotencyKey = (0, workorder_publishers_js_1.boardManualKey)(requestedAt);
|
|
721
|
-
payload = { mode: 'full', force: true, ...repair };
|
|
722
|
-
}
|
|
723
|
-
else if (kind === 'wiki') {
|
|
724
|
-
if (origin.kind === 'owner_event') {
|
|
725
|
-
idempotencyKey = (0, workorder_publishers_js_1.ownerEventWorkOrderKey)('wiki', origin.eventIds);
|
|
726
|
-
payload = { batchId: idempotencyKey, events: [...origin.eventIds] };
|
|
727
|
-
}
|
|
728
|
-
else {
|
|
729
|
-
idempotencyKey = (0, workorder_publishers_js_1.wikiBatchKey)('manual', requestedAt);
|
|
730
|
-
payload = { batchId: `${requestedAt}-manual`, events: ['manual'] };
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
else {
|
|
734
|
-
idempotencyKey =
|
|
735
|
-
origin.kind === 'owner_event'
|
|
736
|
-
? (0, workorder_publishers_js_1.ownerEventWorkOrderKey)('memory-curation', origin.eventIds)
|
|
737
|
-
: (0, workorder_publishers_js_1.promotionManualKey)(requestedAt);
|
|
738
|
-
payload = { scheduledAt: new Date(requestedAt).toISOString() };
|
|
739
|
-
}
|
|
740
|
-
(0, workorder_publishers_js_1.validateWorkOrderPayload)(kind, payload);
|
|
741
|
-
const wo = deps.taskLedger.enqueueWorkOrder({
|
|
742
|
-
workKind: kind,
|
|
743
|
-
idempotencyKey,
|
|
744
|
-
input: payload,
|
|
745
|
-
priority: 'high',
|
|
746
|
-
});
|
|
747
|
-
log(`[stage2] owner workorder enqueued: ${kind}#${wo.id}`);
|
|
748
|
-
return { accepted: true };
|
|
749
|
-
}
|
|
750
|
-
catch (err) {
|
|
751
|
-
logError(`[stage2] owner workorder enqueue failed (${kind}):`, err instanceof Error ? err.message : err);
|
|
752
|
-
return { accepted: false, reason: 'enqueue-failed' };
|
|
753
|
-
}
|
|
754
|
-
};
|
|
755
|
-
}
|
|
756
771
|
/**
|
|
757
772
|
* Execute start command
|
|
758
773
|
*/
|
|
@@ -864,8 +879,10 @@ async function runAgentLoop(config, options = {}) {
|
|
|
864
879
|
const temporalStartup = (0, temporal_runtime_js_1.preflightTemporalStartup)(process.env);
|
|
865
880
|
const runtimeBackend = requireRuntimeBackend(config.agent.backend);
|
|
866
881
|
const { connectorConfigLoadResult, privateConnectorPolicy } = (0, connector_bootstrap_js_1.resolveRuntimeConnectorBootstrap)((0, config_loader_js_1.loadConnectorConfig)());
|
|
882
|
+
// ONE owner role for every model turn: chat, event, and scheduled.
|
|
883
|
+
const ownerRole = config.roles?.definitions.owner_console ?? types_js_1.DEFAULT_ROLES.definitions.owner_console;
|
|
867
884
|
const temporalPolicy = temporalStartup.temporalFlag === 'on'
|
|
868
|
-
?
|
|
885
|
+
? buildTurnAgentPolicy('temporal', config.agent.model, runtimeBackend, privateConnectorPolicy, [], ownerRole)
|
|
869
886
|
: null;
|
|
870
887
|
const temporalEffectiveTools = temporalPolicy
|
|
871
888
|
? (0, tool_policy_js_1.projectCodeActToolPolicy)({
|
|
@@ -1316,7 +1333,9 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1316
1333
|
// delta reconcile scheduling; exact owner-event Board acceptance, boot
|
|
1317
1334
|
// recovery, manual refresh, and full verification share this runtime in all
|
|
1318
1335
|
// configurations.
|
|
1319
|
-
|
|
1336
|
+
// Host-owned Board repair gate. Generations are wall time: with the owner-event
|
|
1337
|
+
// intent ledger gone there is no persisted pending generation to seed above.
|
|
1338
|
+
const boardRefreshGate = new board_refresh_gate_js_1.BoardRefreshGate({ initialGeneration: Date.now() });
|
|
1320
1339
|
const ownerEventEffectLedger = new owner_event_effects_js_1.OwnerEventEffectLedger(operatorDb);
|
|
1321
1340
|
toolExecutor.setOwnerEventEffectLedger(ownerEventEffectLedger);
|
|
1322
1341
|
let stopOwnerEventRuntime = null;
|
|
@@ -1366,6 +1385,10 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1366
1385
|
resolveWorkerRequestTimeoutMs();
|
|
1367
1386
|
let workOrderConsumer = null;
|
|
1368
1387
|
const boardRepairNudge = { current: null };
|
|
1388
|
+
const pipelineSlotPublisher = {
|
|
1389
|
+
current: null,
|
|
1390
|
+
};
|
|
1391
|
+
const learningBlockRef = { current: null };
|
|
1369
1392
|
let temporalRuntime = null;
|
|
1370
1393
|
gateways.push({
|
|
1371
1394
|
stop: async () => {
|
|
@@ -1388,10 +1411,8 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1388
1411
|
});
|
|
1389
1412
|
{
|
|
1390
1413
|
const { WorkOrderConsumer } = await import('../../operator/workorder-consumer.js');
|
|
1391
|
-
|
|
1392
|
-
// Seed missing default briefs (user edits win) BEFORE the consumer exists -
|
|
1414
|
+
// Seed the ONE operating brief (user edits win) BEFORE the consumer exists -
|
|
1393
1415
|
// a normal install must never hit the brief-missing fail path.
|
|
1394
|
-
ensureBriefs();
|
|
1395
1416
|
(0, console_brief_js_1.ensureConsoleBrief)();
|
|
1396
1417
|
const { logActivity: logWorkOrderActivity } = await import('../../db/agent-store.js');
|
|
1397
1418
|
// Ops alarm sink (plan D4/E1/G8): constructed OUTSIDE any trigger-loop
|
|
@@ -1423,7 +1444,42 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1423
1444
|
workOrderConsumer = new WorkOrderConsumer({
|
|
1424
1445
|
ledger: taskLedger,
|
|
1425
1446
|
runner: workerRunner,
|
|
1426
|
-
|
|
1447
|
+
loadOwnerBrief: () => (0, console_brief_js_1.loadConsoleBrief)(),
|
|
1448
|
+
// Host-rendered pipeline: the ledger's own deadline_priority page, published through
|
|
1449
|
+
// the SAME report publisher report_publish uses (bound after the API routes exist).
|
|
1450
|
+
buildLearningBlock: async (wo) => {
|
|
1451
|
+
const build = learningBlockRef.current;
|
|
1452
|
+
if (!build) {
|
|
1453
|
+
return '';
|
|
1454
|
+
}
|
|
1455
|
+
const projectId = (0, reactive_config_js_1.resolveReactiveProjectRoot)(config, process.env);
|
|
1456
|
+
// Same binding the run's envelope gets: a recheck's lessons live under its task's channel.
|
|
1457
|
+
const temporalBinding = wo.workKind === 'temporal'
|
|
1458
|
+
? temporalTaskBinding(taskLedger, (0, temporal_worker_js_1.buildTemporalWorkerContext)(taskLedger, wo).taskId)
|
|
1459
|
+
: null;
|
|
1460
|
+
const scope = workOrderEnvelopeScope({
|
|
1461
|
+
workKind: wo.workKind,
|
|
1462
|
+
projectId,
|
|
1463
|
+
laneConnectors: codeActRawConnectors,
|
|
1464
|
+
temporalBinding,
|
|
1465
|
+
reconcileChannelKey: wo.workKind === 'board' && typeof wo.payload.channelKey === 'string'
|
|
1466
|
+
? wo.payload.channelKey
|
|
1467
|
+
: null,
|
|
1468
|
+
privateConnectorPolicy,
|
|
1469
|
+
});
|
|
1470
|
+
return build(wo.workKind, scope.memory_scopes, wo.workKind);
|
|
1471
|
+
},
|
|
1472
|
+
publishPipelineSlot: () => {
|
|
1473
|
+
const publish = pipelineSlotPublisher.current;
|
|
1474
|
+
if (!publish)
|
|
1475
|
+
throw new Error('pipeline slot publisher is not bound yet');
|
|
1476
|
+
const page = taskLedger.listPage({
|
|
1477
|
+
includeTerminal: false,
|
|
1478
|
+
order: 'deadline_priority',
|
|
1479
|
+
limit: board_pipeline_render_js_1.PIPELINE_SLOT_ROWS,
|
|
1480
|
+
});
|
|
1481
|
+
publish({ pipeline: (0, board_pipeline_render_js_1.renderPipelineSlot)(page.tasks, Date.now(), page.total) });
|
|
1482
|
+
},
|
|
1427
1483
|
noticeOwner: (summary) => messageRouter.enqueueOperatorNotice(summary),
|
|
1428
1484
|
opsAlarm,
|
|
1429
1485
|
runOptionsFor: async (wo) => {
|
|
@@ -1439,11 +1495,17 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1439
1495
|
temporalBinding = temporalTaskBinding(taskLedger, temporalContext.taskId);
|
|
1440
1496
|
}
|
|
1441
1497
|
const projectId = (0, reactive_config_js_1.resolveReactiveProjectRoot)(config, process.env);
|
|
1498
|
+
const reconcileChannelKey = wo.workKind === 'board' &&
|
|
1499
|
+
wo.payload.mode === 'reconcile' &&
|
|
1500
|
+
typeof wo.payload.channelKey === 'string'
|
|
1501
|
+
? wo.payload.channelKey
|
|
1502
|
+
: null;
|
|
1442
1503
|
const workOrderScope = workOrderEnvelopeScope({
|
|
1443
1504
|
workKind: wo.workKind,
|
|
1444
1505
|
projectId,
|
|
1445
1506
|
laneConnectors: codeActRawConnectors,
|
|
1446
1507
|
temporalBinding,
|
|
1508
|
+
reconcileChannelKey,
|
|
1447
1509
|
privateConnectorPolicy,
|
|
1448
1510
|
});
|
|
1449
1511
|
// Worker prompt selects the provider's supported tool path: Claude's
|
|
@@ -1451,7 +1513,7 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1451
1513
|
// spawn-default code-act path, where per-run envelope/capture overrides
|
|
1452
1514
|
// cannot reach (shadow-gate §8.2).
|
|
1453
1515
|
const { buildWorkerSystemPrompt } = await import('../../operator/worker-run.js');
|
|
1454
|
-
const workOrderPolicy =
|
|
1516
|
+
const workOrderPolicy = buildTurnAgentPolicy(wo.workKind, config.agent.model, runtimeBackend, privateConnectorPolicy, workOrderScope.raw_connectors, ownerRole);
|
|
1455
1517
|
const runOptions = attachWorkOrderAttemptContext({
|
|
1456
1518
|
systemPrompt: buildWorkerSystemPrompt(workOrderPolicy.gatewayToolsPrompt, runtimeBackend, wo.workKind),
|
|
1457
1519
|
agentContext: workOrderPolicy.agentContext,
|
|
@@ -1489,7 +1551,7 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1489
1551
|
if (envelopeBootstrap.envelopeAuthority && envelopeBootstrap.metadata.issuance !== 'off') {
|
|
1490
1552
|
const wallSeconds = Math.min(Math.max(Number(process.env.MAMA_REPORT_WALL_SECONDS) || 900, 60), 1800);
|
|
1491
1553
|
runOptions.envelope = await envelopeBootstrap.envelopeAuthority.buildAndPersist({
|
|
1492
|
-
agent_id:
|
|
1554
|
+
agent_id: 'mama-owner',
|
|
1493
1555
|
instance_id: (0, node_crypto_1.randomUUID)(),
|
|
1494
1556
|
// 'watch' = daemon-internal issuing source (closed EnvelopeSource
|
|
1495
1557
|
// union; enforcement authorizes on scope, never on source).
|
|
@@ -1511,7 +1573,7 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1511
1573
|
// keeps the operational trace queryable.
|
|
1512
1574
|
try {
|
|
1513
1575
|
logWorkOrderActivity(db, {
|
|
1514
|
-
agent_id:
|
|
1576
|
+
agent_id: 'mama-owner',
|
|
1515
1577
|
agent_version: 0,
|
|
1516
1578
|
type: `workorder_${event.type}`,
|
|
1517
1579
|
input_summary: `#${event.workOrderId}`,
|
|
@@ -1528,21 +1590,9 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1528
1590
|
catch {
|
|
1529
1591
|
/* telemetry only */
|
|
1530
1592
|
}
|
|
1531
|
-
if (event.type === 'complete' &&
|
|
1532
|
-
event.workKind === 'board' &&
|
|
1533
|
-
ownerEventBoardRefreshLedger.consumePostTerminalFollowup(event.workOrderId)) {
|
|
1534
|
-
boardRepairNudge.current?.();
|
|
1535
|
-
}
|
|
1536
1593
|
},
|
|
1537
1594
|
});
|
|
1538
1595
|
// (Consumer stop is folded into the operator-DB gateway above - ordering.)
|
|
1539
|
-
// Owner-issued workorders (workorder_request tool): enqueue+ack only.
|
|
1540
|
-
// Wired here - NOT inside any trigger-loop block (plan C11 class).
|
|
1541
|
-
toolExecutor.setWorkOrderRequestHandler(buildOwnerWorkOrderRequestHandler({
|
|
1542
|
-
taskLedger,
|
|
1543
|
-
boardRefreshGate,
|
|
1544
|
-
ownerEventBoardRefreshLedger,
|
|
1545
|
-
}));
|
|
1546
1596
|
}
|
|
1547
1597
|
const temporalTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
1548
1598
|
const temporalAssembly = (0, temporal_init_js_1.assembleDaemonTemporalRuntime)({
|
|
@@ -1571,6 +1621,25 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1571
1621
|
if (connectorSchedulerStop) {
|
|
1572
1622
|
gateways.push({ stop: () => Promise.resolve(connectorSchedulerStop()) });
|
|
1573
1623
|
}
|
|
1624
|
+
// Owner policy and lessons: bound BEFORE the consumer starts (bootAfterRoutes) and
|
|
1625
|
+
// independent of the trigger loop, so scheduled turns carry the block even when
|
|
1626
|
+
// MAMA_TRIGGER_LOOP=0.
|
|
1627
|
+
// Owner policy and lessons for a turn: one bounded read path for event, scheduled
|
|
1628
|
+
// and (via MamaApiClient) chat turns. Returns the rendered block or ''.
|
|
1629
|
+
const learningReader = (0, learning_read_js_1.cappedLearningReader)((params) => mamaCore.queryRelevantTruth({ query: params.query, scopes: params.scopes }), (line) => console.log(line));
|
|
1630
|
+
const buildLearningBlockFor = async (turn, scopes, query) => {
|
|
1631
|
+
try {
|
|
1632
|
+
const context = await (0, learning_context_js_1.buildLearningContext)({ scopes, query, readClaims: learningReader });
|
|
1633
|
+
const channelScopeId = scopes.find((scope) => scope.kind === 'channel')?.id ?? null;
|
|
1634
|
+
console.log((0, learning_context_js_1.formatLearningAuditLine)(turn, channelScopeId, context));
|
|
1635
|
+
return context.promptBlock;
|
|
1636
|
+
}
|
|
1637
|
+
catch (error) {
|
|
1638
|
+
console.error(`[learning] ${turn} block failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
1639
|
+
return '';
|
|
1640
|
+
}
|
|
1641
|
+
};
|
|
1642
|
+
learningBlockRef.current = buildLearningBlockFor;
|
|
1574
1643
|
// ── Trigger loop (M1, default-on): agent-evolved triggers on the live stream ──
|
|
1575
1644
|
// MAMA_TRIGGER_LOOP=0 is the explicit opt-out. Placed after initConnectors (which feeds
|
|
1576
1645
|
// connector_event_index) and after mama-core initDB. Read-only: recall/surface/log.
|
|
@@ -1661,6 +1730,21 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1661
1730
|
issuance: envelopeBootstrap.metadata.issuance,
|
|
1662
1731
|
hasAuthority: ownerEventEnvelopeAuthority !== undefined,
|
|
1663
1732
|
});
|
|
1733
|
+
// Scope-independent packet readers, shared by the report leg and the event turn.
|
|
1734
|
+
const reportContextDeps = {
|
|
1735
|
+
listTaskPage: (input) => taskLedger.listPage(input),
|
|
1736
|
+
readClaims: (scope) => mamaCore.queryRelevantTruth({ query: '', scopes: scope.memoryScopes }),
|
|
1737
|
+
readTrello: async (scope) => {
|
|
1738
|
+
if (!scope.rawConnectors.includes('trello')) {
|
|
1739
|
+
throw new Error('Trello is outside the owner-report read scope');
|
|
1740
|
+
}
|
|
1741
|
+
return (0, query_tools_js_1.getTrelloKanban)({ maxCardsPerList: 100 });
|
|
1742
|
+
},
|
|
1743
|
+
buildProvenanceLookup: provenance_lookup_js_1.buildProvenanceLookup,
|
|
1744
|
+
correlate: external_correlation_js_1.correlateTasksWithExternalItems,
|
|
1745
|
+
readChanges: (_scope, input, nowMs) => (0, changes_projection_js_1.readChanges)(taskLedger, input, nowMs),
|
|
1746
|
+
now: Date.now,
|
|
1747
|
+
};
|
|
1664
1748
|
const triggerLoop = new OperatorTriggerLoop({
|
|
1665
1749
|
backend: runtimeBackend,
|
|
1666
1750
|
delta: new ConnectorDeltaRepo(getAdapter(), (0, config_manager_js_1.expandPath)('~/.mama/operator/trigger-loop-cursors.json')),
|
|
@@ -1726,20 +1810,7 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1726
1810
|
],
|
|
1727
1811
|
};
|
|
1728
1812
|
})(),
|
|
1729
|
-
compileFullReportContext: async ({ readScope, windowEvidence, since }) => (0, report_context_js_1.compileOwnerReportContext)({ readScope, windowEvidence, since },
|
|
1730
|
-
listTaskPage: (input) => taskLedger.listPage(input),
|
|
1731
|
-
readClaims: (scope) => mamaCore.queryRelevantTruth({ query: '', scopes: scope.memoryScopes }),
|
|
1732
|
-
readTrello: async (scope) => {
|
|
1733
|
-
if (!scope.rawConnectors.includes('trello')) {
|
|
1734
|
-
throw new Error('Trello is outside the owner-report read scope');
|
|
1735
|
-
}
|
|
1736
|
-
return (0, query_tools_js_1.getTrelloKanban)({ maxCardsPerList: 100 });
|
|
1737
|
-
},
|
|
1738
|
-
buildProvenanceLookup: provenance_lookup_js_1.buildProvenanceLookup,
|
|
1739
|
-
correlate: external_correlation_js_1.correlateTasksWithExternalItems,
|
|
1740
|
-
readChanges: (_scope, input, nowMs) => (0, changes_projection_js_1.readChanges)(taskLedger, input, nowMs),
|
|
1741
|
-
now: Date.now,
|
|
1742
|
-
}),
|
|
1813
|
+
compileFullReportContext: async ({ readScope, windowEvidence, since }) => (0, report_context_js_1.compileOwnerReportContext)({ readScope, windowEvidence, since }, reportContextDeps),
|
|
1743
1814
|
// TG-06: composition supplies provenance immediately to the prepared
|
|
1744
1815
|
// delivery; this callback receives that durable artifact only after send success.
|
|
1745
1816
|
fullReportProvenance: () => lastReportProvenance,
|
|
@@ -1792,7 +1863,6 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1792
1863
|
// MAMA itself owns connector events. This is the same AgentLoop and
|
|
1793
1864
|
// owner operating policy as the owner console, on a durable per-channel
|
|
1794
1865
|
// background session. There is no separate Conductor persona.
|
|
1795
|
-
const ownerRole = config.roles?.definitions.owner_console ?? types_js_1.DEFAULT_ROLES.definitions.owner_console;
|
|
1796
1866
|
const ownerEventContext = (0, owner_event_policy_js_1.buildOwnerEventAgentContext)({
|
|
1797
1867
|
backend: runtimeBackend,
|
|
1798
1868
|
model: config.agent.model,
|
|
@@ -1800,8 +1870,24 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1800
1870
|
privateConnectorPolicy,
|
|
1801
1871
|
});
|
|
1802
1872
|
const ownerEventPromptEnhancer = new prompt_enhancer_js_1.PromptEnhancer();
|
|
1803
|
-
|
|
1873
|
+
// ONE expression for what an event turn may read: the envelope and the
|
|
1874
|
+
// packet are both built from it, so they can never disagree.
|
|
1875
|
+
const ownerEventReadScope = (batch) => {
|
|
1804
1876
|
const projectId = (0, reactive_config_js_1.resolveReactiveProjectRoot)(config, process.env);
|
|
1877
|
+
return {
|
|
1878
|
+
projectRefs: [{ kind: 'project', id: projectId }],
|
|
1879
|
+
rawConnectors: [
|
|
1880
|
+
...privateConnectorPolicy.projectRawConnectors('owner_console', codeActRawConnectors),
|
|
1881
|
+
],
|
|
1882
|
+
memoryScopes: uniqueMemoryScopes((0, scope_context_js_1.deriveMemoryScopes)({
|
|
1883
|
+
source: 'owner-event',
|
|
1884
|
+
channelId: batch.channelKey,
|
|
1885
|
+
projectId,
|
|
1886
|
+
})),
|
|
1887
|
+
};
|
|
1888
|
+
};
|
|
1889
|
+
const ownerEventIssueEnvelope = async (batch) => {
|
|
1890
|
+
const readScope = ownerEventReadScope(batch);
|
|
1805
1891
|
const wallSeconds = 300;
|
|
1806
1892
|
return ownerEventEnvelopeAuthority.buildAndPersist({
|
|
1807
1893
|
agent_id: 'mama-owner',
|
|
@@ -1810,15 +1896,9 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1810
1896
|
channel_id: batch.channelKey,
|
|
1811
1897
|
trigger_context: { user_text: '<MAMA owner event turn>' },
|
|
1812
1898
|
scope: {
|
|
1813
|
-
project_refs:
|
|
1814
|
-
raw_connectors:
|
|
1815
|
-
|
|
1816
|
-
],
|
|
1817
|
-
memory_scopes: uniqueMemoryScopes((0, scope_context_js_1.deriveMemoryScopes)({
|
|
1818
|
-
source: 'owner-event',
|
|
1819
|
-
channelId: batch.channelKey,
|
|
1820
|
-
projectId,
|
|
1821
|
-
})),
|
|
1899
|
+
project_refs: readScope.projectRefs,
|
|
1900
|
+
raw_connectors: readScope.rawConnectors,
|
|
1901
|
+
memory_scopes: readScope.memoryScopes,
|
|
1822
1902
|
allowed_destinations: reportChatId
|
|
1823
1903
|
? [{ kind: 'telegram', id: reportChatId }]
|
|
1824
1904
|
: [],
|
|
@@ -1832,8 +1912,16 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1832
1912
|
inbox: ownerEventInbox,
|
|
1833
1913
|
runner: agentLoop,
|
|
1834
1914
|
agentContext: ownerEventContext,
|
|
1835
|
-
|
|
1915
|
+
compilePacket: async (batch) => (0, report_context_js_1.serializeOwnerReportContext)(await (0, report_context_js_1.compileChannelPacket)({
|
|
1916
|
+
readScope: ownerEventReadScope(batch),
|
|
1917
|
+
channelKey: batch.channelKey,
|
|
1918
|
+
eventIds: batch.eventIds,
|
|
1919
|
+
since: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
1920
|
+
}, reportContextDeps)),
|
|
1921
|
+
buildPrompt: async (batch, packet) => (0, owner_event_prompt_js_1.buildOwnerEventPrompt)({
|
|
1836
1922
|
batch,
|
|
1923
|
+
packet,
|
|
1924
|
+
learning: await buildLearningBlockFor('event', ownerEventReadScope(batch).memoryScopes, batch.lines.join('\n').slice(0, 500)),
|
|
1837
1925
|
ownerBrief: (0, console_brief_js_1.projectConsoleBriefForPrompt)((0, console_brief_js_1.loadConsoleBrief)(), privateConnectorPolicy),
|
|
1838
1926
|
skillContent: await ownerEventPromptEnhancer.detectSkillMatch(batch.lines.join('\n')),
|
|
1839
1927
|
ownerTelegramChatId: reportChatId,
|
|
@@ -1842,7 +1930,6 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1842
1930
|
getNoUpdateMaxId: (scope) => taskLedger.maxNoUpdateId(scope),
|
|
1843
1931
|
getTerminalReceipt: (batch) => resolveOwnerEventTerminalReceipt(batch, {
|
|
1844
1932
|
ownerEventEffectLedger,
|
|
1845
|
-
ownerEventBoardRefreshLedger,
|
|
1846
1933
|
taskLedger,
|
|
1847
1934
|
}),
|
|
1848
1935
|
recordTriggerOutcome: (triggerId, outcome) => triggerRegistry.recordOutcome(triggerId, outcome),
|
|
@@ -1926,15 +2013,18 @@ async function runAgentLoop(config, options = {}) {
|
|
|
1926
2013
|
getAdapter,
|
|
1927
2014
|
privateConnectorPolicy,
|
|
1928
2015
|
rawConnectorScope: [
|
|
1929
|
-
...privateConnectorPolicy.projectRawConnectors(
|
|
2016
|
+
...privateConnectorPolicy.projectRawConnectors(exports.ONE_AGENT_TURN_POLICY.roleName, codeActRawConnectors),
|
|
1930
2017
|
],
|
|
1931
2018
|
sessionsDb: db,
|
|
1932
2019
|
workOrderConsumer: workOrderConsumer ?? undefined,
|
|
1933
2020
|
boardRefreshGate,
|
|
1934
|
-
ownerEventBoardRefreshLedger,
|
|
1935
2021
|
requestFullReport: () => triggerLoopFullReport.current?.() ?? { accepted: false, reason: 'unavailable' },
|
|
1936
2022
|
});
|
|
1937
2023
|
boardRepairNudge.current = apiRoutesHandle.requestBoardRepair;
|
|
2024
|
+
{
|
|
2025
|
+
const { createReportPublisher } = await import('../../api/report-handler.js');
|
|
2026
|
+
pipelineSlotPublisher.current = createReportPublisher(apiServer.reportStore, apiServer.reportSseClients);
|
|
2027
|
+
}
|
|
1938
2028
|
gateways.push({ stop: async () => apiRoutesHandle.stop() });
|
|
1939
2029
|
// ── Stage-2 boot pass (plan S2-T3): runtime assembly registered hooks;
|
|
1940
2030
|
// recovery/cleanup run after routes are ready, then the consumer starts.
|