@pleri/olam-cli 0.1.81 → 0.1.82
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/dist/commands/implode.d.ts +86 -0
- package/dist/commands/implode.d.ts.map +1 -0
- package/dist/commands/implode.js +468 -0
- package/dist/commands/implode.js.map +1 -0
- package/dist/image-digests.json +3 -3
- package/dist/index.js +775 -404
- package/dist/index.js.map +1 -1
- package/host-cp/src/plan-orchestrator.mjs +71 -40
- package/host-cp/src/server.mjs +4 -43
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -95,12 +95,19 @@ export class PlanOrchestrator {
|
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
97
|
* Ring buffer of in-flight SSE events per conversationId.
|
|
98
|
-
* Populated while a turn is active; cleared
|
|
98
|
+
* Populated while a turn is active; cleared after all persona turn_complete events.
|
|
99
99
|
* Used by drainReplayBuffer to replay missed events on reconnect.
|
|
100
100
|
* @type {Map<string, Array<{event: string, data: object}>>}
|
|
101
101
|
*/
|
|
102
102
|
#activeTurns = new Map();
|
|
103
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Number of persona turn_complete events still pending per conversationId.
|
|
106
|
+
* Replay buffer is only cleared when this reaches 0.
|
|
107
|
+
* @type {Map<string, number>}
|
|
108
|
+
*/
|
|
109
|
+
#pendingPersonaCount = new Map();
|
|
110
|
+
|
|
104
111
|
/**
|
|
105
112
|
* Mutable current-chunk refs per conversationId.
|
|
106
113
|
* ChunkEmitter updates these; read_sidebar tool reads them.
|
|
@@ -328,7 +335,7 @@ export class PlanOrchestrator {
|
|
|
328
335
|
this.#activeTurns.delete(id);
|
|
329
336
|
this.#currentChunkRefs.delete(id);
|
|
330
337
|
|
|
331
|
-
const sessionDir = path.join(
|
|
338
|
+
const sessionDir = path.join(this.#planDir, id);
|
|
332
339
|
try { fs.rmSync(sessionDir, { recursive: true }); } catch { /* ok if missing */ }
|
|
333
340
|
|
|
334
341
|
return true;
|
|
@@ -406,9 +413,15 @@ export class PlanOrchestrator {
|
|
|
406
413
|
try { res.write(chunk); } catch { /* client disconnected */ }
|
|
407
414
|
}
|
|
408
415
|
|
|
409
|
-
// Clear buffer
|
|
416
|
+
// Clear buffer only when all pending personas have completed.
|
|
410
417
|
if (eventName === 'turn_complete') {
|
|
411
|
-
this.#
|
|
418
|
+
const pending = (this.#pendingPersonaCount.get(conversationId) ?? 1) - 1;
|
|
419
|
+
if (pending <= 0) {
|
|
420
|
+
this.#activeTurns.delete(conversationId);
|
|
421
|
+
this.#pendingPersonaCount.delete(conversationId);
|
|
422
|
+
} else {
|
|
423
|
+
this.#pendingPersonaCount.set(conversationId, pending);
|
|
424
|
+
}
|
|
412
425
|
}
|
|
413
426
|
}
|
|
414
427
|
|
|
@@ -748,17 +761,20 @@ export class PlanOrchestrator {
|
|
|
748
761
|
// ── Public API ────────────────────────────────────────────────────────────
|
|
749
762
|
|
|
750
763
|
/**
|
|
751
|
-
* Submit a user turn to
|
|
764
|
+
* Submit a user turn to one or more personas in parallel.
|
|
765
|
+
* When mentionedPersonas contains 2+ IDs, each receives its own AgentSession
|
|
766
|
+
* and streams tokens with per-persona attribution via SSE `persona` field.
|
|
752
767
|
* Returns immediately; tokens stream over SSE.
|
|
753
768
|
*
|
|
754
769
|
* @param {{
|
|
755
770
|
* conversationId: string,
|
|
756
771
|
* content: string,
|
|
757
772
|
* personaOverride?: string,
|
|
773
|
+
* mentionedPersonas?: string[],
|
|
758
774
|
* }} params
|
|
759
775
|
* @returns {Promise<{ turnId: string, persona: string }>}
|
|
760
776
|
*/
|
|
761
|
-
async submitTurn({ conversationId, content, personaOverride }) {
|
|
777
|
+
async submitTurn({ conversationId, content, personaOverride, mentionedPersonas }) {
|
|
762
778
|
const row = this.#db
|
|
763
779
|
.prepare(`SELECT id, title FROM plan_conversations WHERE id = ?`)
|
|
764
780
|
.get(conversationId);
|
|
@@ -771,8 +787,16 @@ export class PlanOrchestrator {
|
|
|
771
787
|
|
|
772
788
|
const now = Date.now();
|
|
773
789
|
|
|
774
|
-
//
|
|
790
|
+
// Determine which personas will receive this turn.
|
|
791
|
+
// Multi-persona: user @-mentioned 2+ personas explicitly.
|
|
792
|
+
// Single-persona: use explicit override or the conversation's active persona.
|
|
793
|
+
const personasToDispatch = (mentionedPersonas?.length ?? 0) > 1
|
|
794
|
+
? mentionedPersonas
|
|
795
|
+
: [personaOverride ?? this.getActivePersona(conversationId)];
|
|
796
|
+
|
|
797
|
+
// Open (or reset) the replay buffer; track how many turn_complete events are expected.
|
|
775
798
|
this.#activeTurns.set(conversationId, []);
|
|
799
|
+
this.#pendingPersonaCount.set(conversationId, personasToDispatch.length);
|
|
776
800
|
|
|
777
801
|
// Set title from first user message if still null.
|
|
778
802
|
if (row.title === null) {
|
|
@@ -781,7 +805,7 @@ export class PlanOrchestrator {
|
|
|
781
805
|
.run(deriveTitle(content), conversationId);
|
|
782
806
|
}
|
|
783
807
|
|
|
784
|
-
// Persist the user turn
|
|
808
|
+
// Persist the user turn once (regardless of how many personas respond).
|
|
785
809
|
this.#db
|
|
786
810
|
.prepare(
|
|
787
811
|
`INSERT INTO plan_turns (id, conversation_id, role, content, created_at)
|
|
@@ -789,41 +813,48 @@ export class PlanOrchestrator {
|
|
|
789
813
|
)
|
|
790
814
|
.run(randomUUID(), conversationId, content, now);
|
|
791
815
|
|
|
792
|
-
const
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
816
|
+
const isSinglePersona = personasToDispatch.length === 1;
|
|
817
|
+
|
|
818
|
+
// Dispatch to each persona. For multi-persona turns, skip rope enrichment —
|
|
819
|
+
// the user explicitly chose all participants, so no auto-delegation is needed.
|
|
820
|
+
await Promise.all(personasToDispatch.map(async (pId) => {
|
|
821
|
+
const onStubCall = (event) => {
|
|
822
|
+
this.#broadcast(conversationId, 'tool_stub_call', { persona: pId, ...event });
|
|
823
|
+
};
|
|
824
|
+
|
|
825
|
+
const { session, authStorage } = await this.#registry.getAgent(conversationId, pId, { onStubCall });
|
|
826
|
+
|
|
827
|
+
// Wire events on first use (idempotent because pi de-duplicates subscribers).
|
|
828
|
+
this.#wireSessionEvents(conversationId, pId, session);
|
|
829
|
+
|
|
830
|
+
// Refresh credential before each turn.
|
|
831
|
+
const token = await this.#fetchToken();
|
|
832
|
+
authStorage.setRuntimeApiKey('anthropic', token);
|
|
833
|
+
|
|
834
|
+
let promptContent = content;
|
|
835
|
+
if (isSinglePersona) {
|
|
836
|
+
// Pre-turn autoRope enrichment (Phase D): run any persona's autoRope rules
|
|
837
|
+
// before the caller's session sees the content. Keeps pm_gathering_context
|
|
838
|
+
// backward-compat; rope_start/rope_complete are emitted by RopeEngine.
|
|
839
|
+
promptContent = await this.#ropeEngine.autoDelegateIfNeeded({
|
|
840
|
+
conversationId,
|
|
841
|
+
callerPersonaId: pId,
|
|
842
|
+
content,
|
|
843
|
+
fetchToken: () => this.#fetchToken(),
|
|
844
|
+
});
|
|
845
|
+
}
|
|
817
846
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
847
|
+
session.prompt(promptContent).catch((err) => {
|
|
848
|
+
console.error(`[plan] prompt error ${conversationId}/${pId}:`, err.message);
|
|
849
|
+
this.#broadcast(conversationId, 'error', {
|
|
850
|
+
message: err.message,
|
|
851
|
+
code: err.code ?? 'PROMPT_ERROR',
|
|
852
|
+
});
|
|
823
853
|
});
|
|
824
|
-
});
|
|
854
|
+
}));
|
|
825
855
|
|
|
826
|
-
|
|
856
|
+
const turnId = randomUUID();
|
|
857
|
+
return { turnId, persona: personasToDispatch[0] };
|
|
827
858
|
}
|
|
828
859
|
|
|
829
860
|
/**
|
package/host-cp/src/server.mjs
CHANGED
|
@@ -114,12 +114,6 @@ const OLAM_REPO_HOST_PATH = process.env.OLAM_REPO_HOST_PATH ?? '';
|
|
|
114
114
|
const OLAM_GH_CONFIG_HOST_PATH = process.env.OLAM_GH_CONFIG_HOST_PATH ?? '';
|
|
115
115
|
const OLAM_UPGRADER_IMAGE = process.env.OLAM_UPGRADER_IMAGE ?? 'ghcr.io/pleri/olam-host-cp:latest';
|
|
116
116
|
const WORKSPACES_DIR = process.env.OLAM_WORKSPACES_DIR ?? '/data/workspaces';
|
|
117
|
-
// Bug 1 fix: plan.db must land in the bind-mounted /data dir, not the
|
|
118
|
-
// container-ephemeral /root/.olam. compose.yaml sets these to /data/plan.db
|
|
119
|
-
// and /data/plan. On bare-host installs the env vars are unset and the
|
|
120
|
-
// PlanOrchestrator falls back to ~/.olam defaults.
|
|
121
|
-
const PLAN_DB_PATH = process.env.OLAM_PLAN_DB_PATH ?? null;
|
|
122
|
-
const PLAN_DIR_PATH = process.env.OLAM_PLAN_DIR ?? null;
|
|
123
117
|
const WORLD_NAMES_PATH =
|
|
124
118
|
process.env.OLAM_WORLD_NAMES_PATH ??
|
|
125
119
|
(HOST_CP_MODE === 'container'
|
|
@@ -392,8 +386,6 @@ const worldsDbReconciler = startWorldsDbReconciler({
|
|
|
392
386
|
const planOrchestrator = new PlanOrchestrator({
|
|
393
387
|
authServiceUrl: AUTH_SERVICE_URL,
|
|
394
388
|
authServiceSecret: AUTH_SERVICE_SECRET,
|
|
395
|
-
...(PLAN_DB_PATH ? { planDbPath: PLAN_DB_PATH } : {}),
|
|
396
|
-
...(PLAN_DIR_PATH ? { planDirPath: PLAN_DIR_PATH } : {}),
|
|
397
389
|
});
|
|
398
390
|
|
|
399
391
|
/**
|
|
@@ -1452,40 +1444,6 @@ const server = http.createServer(async (req, res) => {
|
|
|
1452
1444
|
}
|
|
1453
1445
|
}
|
|
1454
1446
|
|
|
1455
|
-
if (planConvMatch && req.method === 'PATCH') {
|
|
1456
|
-
if (!await requirePlanCredential(res)) return;
|
|
1457
|
-
const id = decodeURIComponent(planConvMatch[1]);
|
|
1458
|
-
let body;
|
|
1459
|
-
try { body = await readRequestBody(req); } catch (err) {
|
|
1460
|
-
return jsonReply(res, 400, { error: 'invalid_json', message: err.message });
|
|
1461
|
-
}
|
|
1462
|
-
const updates = {};
|
|
1463
|
-
if (body && typeof body.title === 'string') updates.title = body.title.trim();
|
|
1464
|
-
if (body && typeof body.pinned === 'boolean') updates.pinned = body.pinned;
|
|
1465
|
-
if (Object.keys(updates).length === 0) {
|
|
1466
|
-
return jsonReply(res, 400, { error: 'no_valid_fields' });
|
|
1467
|
-
}
|
|
1468
|
-
try {
|
|
1469
|
-
const conv = planOrchestrator.patchConversation(id, updates);
|
|
1470
|
-
if (!conv) return jsonReply(res, 404, { error: 'not_found', id });
|
|
1471
|
-
return jsonReply(res, 200, conv);
|
|
1472
|
-
} catch (err) {
|
|
1473
|
-
return jsonReply(res, 500, { error: 'patch_failed', message: err.message });
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
|
|
1477
|
-
if (planConvMatch && req.method === 'DELETE') {
|
|
1478
|
-
if (!await requirePlanCredential(res)) return;
|
|
1479
|
-
const id = decodeURIComponent(planConvMatch[1]);
|
|
1480
|
-
try {
|
|
1481
|
-
const deleted = planOrchestrator.deleteConversation(id);
|
|
1482
|
-
if (!deleted) return jsonReply(res, 404, { error: 'not_found', id });
|
|
1483
|
-
return jsonReply(res, 204, null);
|
|
1484
|
-
} catch (err) {
|
|
1485
|
-
return jsonReply(res, 500, { error: 'delete_failed', message: err.message });
|
|
1486
|
-
}
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
1447
|
const planTurnMatch = /^\/api\/plan\/conversations\/([^/?#]+)\/turns$/.exec(url.pathname);
|
|
1490
1448
|
if (planTurnMatch && req.method === 'POST') {
|
|
1491
1449
|
if (!await requirePlanCredential(res)) return;
|
|
@@ -1501,8 +1459,11 @@ const server = http.createServer(async (req, res) => {
|
|
|
1501
1459
|
const personaOverride = (body && typeof body === 'object' && typeof body.personaOverride === 'string')
|
|
1502
1460
|
? body.personaOverride
|
|
1503
1461
|
: undefined;
|
|
1462
|
+
const mentionedPersonas = (body && typeof body === 'object' && Array.isArray(body.mentionedPersonas))
|
|
1463
|
+
? body.mentionedPersonas.filter((p) => typeof p === 'string')
|
|
1464
|
+
: undefined;
|
|
1504
1465
|
try {
|
|
1505
|
-
const result = await planOrchestrator.submitTurn({ conversationId, content, personaOverride });
|
|
1466
|
+
const result = await planOrchestrator.submitTurn({ conversationId, content, personaOverride, mentionedPersonas });
|
|
1506
1467
|
return jsonReply(res, 202, result);
|
|
1507
1468
|
} catch (err) {
|
|
1508
1469
|
if (err.code === 'NOT_FOUND') return jsonReply(res, 404, { error: 'not_found', id: conversationId });
|