@m8t-stack/cli 0.2.72 → 0.2.74
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/cli.js +140 -40
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -81,6 +81,17 @@ var init_reasons = __esm({
|
|
|
81
81
|
}
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
+
// ../../packages/api-contract/dist/esm/delegated-identity.js
|
|
85
|
+
var SERVICE_APP_ROLE, END_USER_KEY_MAX_LENGTH, END_USER_KEY_PATTERN;
|
|
86
|
+
var init_delegated_identity = __esm({
|
|
87
|
+
"../../packages/api-contract/dist/esm/delegated-identity.js"() {
|
|
88
|
+
"use strict";
|
|
89
|
+
SERVICE_APP_ROLE = "Agents.Invoke";
|
|
90
|
+
END_USER_KEY_MAX_LENGTH = 200;
|
|
91
|
+
END_USER_KEY_PATTERN = new RegExp(`^[A-Za-z0-9._-]{1,${String(END_USER_KEY_MAX_LENGTH)}}$`);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
84
95
|
// ../../packages/api-contract/dist/esm/team.js
|
|
85
96
|
var init_team = __esm({
|
|
86
97
|
"../../packages/api-contract/dist/esm/team.js"() {
|
|
@@ -224,6 +235,7 @@ var init_esm = __esm({
|
|
|
224
235
|
init_response();
|
|
225
236
|
init_errors2();
|
|
226
237
|
init_reasons();
|
|
238
|
+
init_delegated_identity();
|
|
227
239
|
init_team();
|
|
228
240
|
init_me();
|
|
229
241
|
init_binding();
|
|
@@ -1370,7 +1382,7 @@ var init_enable_hosted_brain = __esm({
|
|
|
1370
1382
|
import { Builtins, Cli } from "clipanion";
|
|
1371
1383
|
|
|
1372
1384
|
// src/lib/package-version.ts
|
|
1373
|
-
var CLI_VERSION = "0.2.
|
|
1385
|
+
var CLI_VERSION = "0.2.74";
|
|
1374
1386
|
|
|
1375
1387
|
// src/lib/render-error.ts
|
|
1376
1388
|
init_errors();
|
|
@@ -15663,10 +15675,16 @@ import * as fs9 from "fs";
|
|
|
15663
15675
|
import * as path9 from "path";
|
|
15664
15676
|
var SEED_MANIFEST_PATH = ".m8t/seed-manifest.json";
|
|
15665
15677
|
var SEED_PATHS = ["skills", "references", "targets"];
|
|
15678
|
+
function isUpstream(v) {
|
|
15679
|
+
if (v === void 0) return true;
|
|
15680
|
+
if (!v || typeof v !== "object") return false;
|
|
15681
|
+
const u = v;
|
|
15682
|
+
return typeof u.repo === "string" && u.repo.length > 0 && typeof u.ref === "string" && u.ref.length > 0;
|
|
15683
|
+
}
|
|
15666
15684
|
function isLineage(v) {
|
|
15667
15685
|
if (!v || typeof v !== "object") return false;
|
|
15668
15686
|
const l = v;
|
|
15669
|
-
return typeof l.name === "string" && typeof l.refreshedToCommit === "string" && typeof l.refreshedToVersion === "string" && Array.isArray(l.ownedPaths) && l.ownedPaths.every((p) => typeof p === "string");
|
|
15687
|
+
return typeof l.name === "string" && typeof l.refreshedToCommit === "string" && typeof l.refreshedToVersion === "string" && Array.isArray(l.ownedPaths) && l.ownedPaths.every((p) => typeof p === "string") && isUpstream(l.upstream);
|
|
15670
15688
|
}
|
|
15671
15689
|
function parseSeedManifest(text) {
|
|
15672
15690
|
if (!text?.trim()) return null;
|
|
@@ -15684,6 +15702,11 @@ function parseSeedManifest(text) {
|
|
|
15684
15702
|
function buildSeedManifest(seeds) {
|
|
15685
15703
|
return { schemaVersion: 1, seeds };
|
|
15686
15704
|
}
|
|
15705
|
+
function carryUpstream(prior, lineage) {
|
|
15706
|
+
if (lineage.upstream) return lineage;
|
|
15707
|
+
const before = prior?.seeds.find((s) => s.name === lineage.name)?.upstream;
|
|
15708
|
+
return before ? { ...lineage, upstream: before } : lineage;
|
|
15709
|
+
}
|
|
15687
15710
|
function upsertLineage(manifest, lineage) {
|
|
15688
15711
|
const prior = manifest?.seeds ?? [];
|
|
15689
15712
|
const others = prior.filter((s) => s.name !== lineage.name);
|
|
@@ -15960,6 +15983,15 @@ async function syncAgentContent(args) {
|
|
|
15960
15983
|
await hydrateAgentsInto(args.root, pin.agents, args.deps);
|
|
15961
15984
|
return Object.values(pin.agents).map((a) => ({ persona: a.persona, repo: a.repo, ref: a.ref }));
|
|
15962
15985
|
}
|
|
15986
|
+
function upstreamForSeed(root, seedName) {
|
|
15987
|
+
try {
|
|
15988
|
+
const pin = parseReleasePin(fs12.readFileSync(path12.join(root, PIN_REL_PATH), "utf8"), PIN_REL_PATH);
|
|
15989
|
+
const agent = Object.values(pin.agents).find((a) => a.persona === seedName);
|
|
15990
|
+
return agent ? { repo: agent.repo, ref: agent.ref } : void 0;
|
|
15991
|
+
} catch {
|
|
15992
|
+
return void 0;
|
|
15993
|
+
}
|
|
15994
|
+
}
|
|
15963
15995
|
function agentContentHint(root, persona) {
|
|
15964
15996
|
try {
|
|
15965
15997
|
const pin = parseReleasePin(fs12.readFileSync(path12.join(root, PIN_REL_PATH), "utf8"), PIN_REL_PATH);
|
|
@@ -16034,7 +16066,8 @@ function writeSeedMarker(args) {
|
|
|
16034
16066
|
name: args.seedName,
|
|
16035
16067
|
refreshedToCommit: args.refreshedToCommit,
|
|
16036
16068
|
refreshedToVersion: args.version,
|
|
16037
|
-
ownedPaths: deriveOwnedPaths(args.seedDir)
|
|
16069
|
+
ownedPaths: deriveOwnedPaths(args.seedDir),
|
|
16070
|
+
...args.upstream ? { upstream: args.upstream } : {}
|
|
16038
16071
|
}]);
|
|
16039
16072
|
const dest = path13.join(args.destDir, SEED_MANIFEST_PATH);
|
|
16040
16073
|
fs13.mkdirSync(path13.dirname(dest), { recursive: true });
|
|
@@ -16658,7 +16691,15 @@ var BrainCreateCommand = class extends M8tCommand {
|
|
|
16658
16691
|
materializeBrainTree({ templateSrc, destDir: tmpDir, seedDir });
|
|
16659
16692
|
if (seedName && seedDir) {
|
|
16660
16693
|
const headSha = resolveScaffoldCommit(repoRoot, env);
|
|
16661
|
-
|
|
16694
|
+
const upstream = upstreamForSeed(repoRoot, seedName);
|
|
16695
|
+
writeSeedMarker({
|
|
16696
|
+
destDir: tmpDir,
|
|
16697
|
+
seedName,
|
|
16698
|
+
seedDir,
|
|
16699
|
+
refreshedToCommit: headSha,
|
|
16700
|
+
version: "(scaffold)",
|
|
16701
|
+
...upstream ? { upstream } : {}
|
|
16702
|
+
});
|
|
16662
16703
|
}
|
|
16663
16704
|
this.context.stdout.write(
|
|
16664
16705
|
seedName ? `${colors.dim("\u2192")} copied brain-template/ + overlaid seed ${colors.field(seedName)} to ${tmpDir}
|
|
@@ -21534,14 +21575,15 @@ async function refreshBrainRepo(args) {
|
|
|
21534
21575
|
const ownedNow = new Set(args.trees.ownedAtTheirs);
|
|
21535
21576
|
assertNoDanglingIndexRefs(finalPaths, (p) => ownedNow.has(p), indexBodies);
|
|
21536
21577
|
const newOwned = deriveOwnedPaths(args.trees.theirsDir);
|
|
21578
|
+
const priorManifest = args.priorManifest ?? (args.lineage ? { schemaVersion: 1, seeds: [args.lineage] } : null);
|
|
21537
21579
|
const nextManifest = upsertLineage(
|
|
21538
|
-
|
|
21539
|
-
{
|
|
21580
|
+
priorManifest,
|
|
21581
|
+
carryUpstream(priorManifest, {
|
|
21540
21582
|
name: args.seedName,
|
|
21541
21583
|
refreshedToCommit: args.targetCommit ?? "",
|
|
21542
21584
|
refreshedToVersion: args.version,
|
|
21543
21585
|
ownedPaths: newOwned
|
|
21544
|
-
}
|
|
21586
|
+
})
|
|
21545
21587
|
);
|
|
21546
21588
|
files.push({ path: SEED_MANIFEST_PATH, content: serializeSeedManifest(nextManifest) });
|
|
21547
21589
|
for (const sb of args.supersedeBranches ?? []) {
|
|
@@ -23303,6 +23345,7 @@ var PlatformEnableAutoUpdateCommand = class extends M8tCommand {
|
|
|
23303
23345
|
import { Command as Command42, Option as Option39 } from "clipanion";
|
|
23304
23346
|
|
|
23305
23347
|
// src/lib/app-reg.ts
|
|
23348
|
+
init_esm();
|
|
23306
23349
|
init_errors();
|
|
23307
23350
|
var APP_NAME = "m8t-webapp";
|
|
23308
23351
|
var AZURE_CLI_FIRST_PARTY_APP_ID = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
|
|
@@ -23403,6 +23446,52 @@ async function ensureExposeAnApi(appId, appObjectId) {
|
|
|
23403
23446
|
]);
|
|
23404
23447
|
}
|
|
23405
23448
|
}
|
|
23449
|
+
async function ensureServiceAppRole(appId, appObjectId) {
|
|
23450
|
+
const existingRoles = await azJson([
|
|
23451
|
+
"ad",
|
|
23452
|
+
"app",
|
|
23453
|
+
"show",
|
|
23454
|
+
"--id",
|
|
23455
|
+
appId,
|
|
23456
|
+
"--query",
|
|
23457
|
+
"appRoles",
|
|
23458
|
+
"--output",
|
|
23459
|
+
"json"
|
|
23460
|
+
]);
|
|
23461
|
+
if (!Array.isArray(existingRoles)) {
|
|
23462
|
+
throw new LocalCliError({
|
|
23463
|
+
code: "APP_REG_ROLES_UNREADABLE",
|
|
23464
|
+
message: `Could not read the existing app roles on app registration ${appId}.`,
|
|
23465
|
+
hint: "Re-run once you can read the app registration; writing the role now would risk replacing roles we cannot see."
|
|
23466
|
+
});
|
|
23467
|
+
}
|
|
23468
|
+
const already = existingRoles.find((r) => r.value === SERVICE_APP_ROLE);
|
|
23469
|
+
if (already && already.isEnabled !== false) return;
|
|
23470
|
+
const appRoles = already ? existingRoles.map((r) => r.value === SERVICE_APP_ROLE ? { ...r, isEnabled: true } : r) : [
|
|
23471
|
+
...existingRoles,
|
|
23472
|
+
{
|
|
23473
|
+
id: globalThis.crypto.randomUUID(),
|
|
23474
|
+
displayName: "Invoke agents",
|
|
23475
|
+
description: "Allows a service principal to call the gateway agent API.",
|
|
23476
|
+
value: SERVICE_APP_ROLE,
|
|
23477
|
+
allowedMemberTypes: ["Application"],
|
|
23478
|
+
isEnabled: true
|
|
23479
|
+
}
|
|
23480
|
+
];
|
|
23481
|
+
await runAz([
|
|
23482
|
+
"rest",
|
|
23483
|
+
"--method",
|
|
23484
|
+
"PATCH",
|
|
23485
|
+
// The OBJECT id, not the app id: Graph's /applications/{id} addresses the
|
|
23486
|
+
// object id, and an appId here is a 404.
|
|
23487
|
+
"--url",
|
|
23488
|
+
`https://graph.microsoft.com/v1.0/applications/${appObjectId}`,
|
|
23489
|
+
"--headers",
|
|
23490
|
+
"Content-Type=application/json",
|
|
23491
|
+
"--body",
|
|
23492
|
+
JSON.stringify({ appRoles })
|
|
23493
|
+
]);
|
|
23494
|
+
}
|
|
23406
23495
|
async function ensureAppReg(opts) {
|
|
23407
23496
|
if (opts.clientId) {
|
|
23408
23497
|
return { tenantId: opts.tenantId, clientId: opts.clientId, appObjectId: null };
|
|
@@ -23422,6 +23511,7 @@ async function ensureAppReg(opts) {
|
|
|
23422
23511
|
});
|
|
23423
23512
|
}
|
|
23424
23513
|
await ensureExposeAnApi(app.appId, objId);
|
|
23514
|
+
await ensureServiceAppRole(app.appId, objId);
|
|
23425
23515
|
return { tenantId: opts.tenantId, clientId: app.appId, appObjectId: objId };
|
|
23426
23516
|
}
|
|
23427
23517
|
const me = await azJson(
|
|
@@ -23533,6 +23623,7 @@ async function ensureAppReg(opts) {
|
|
|
23533
23623
|
})
|
|
23534
23624
|
]);
|
|
23535
23625
|
await ensureExposeAnApi(created.appId, created.id);
|
|
23626
|
+
await ensureServiceAppRole(created.appId, created.id);
|
|
23536
23627
|
return { tenantId: opts.tenantId, clientId: created.appId, appObjectId: created.id };
|
|
23537
23628
|
}
|
|
23538
23629
|
async function ensureGatewayRedirectUri(gatewayClientId, fqdn) {
|
|
@@ -29925,7 +30016,7 @@ ${colors.error("\u2717")} The GitHub App on disk is installed on ${colors.field(
|
|
|
29925
30016
|
// src/commands/bootstrap/launch.ts
|
|
29926
30017
|
var DEFAULT_RG = "rg-m8t-stack";
|
|
29927
30018
|
var DEFAULT_INSTALLER = "ghcr.io/m8t-labs/m8t-installer";
|
|
29928
|
-
var DEFAULT_INSTALLER_TAG = "v0.1.
|
|
30019
|
+
var DEFAULT_INSTALLER_TAG = "v0.1.59";
|
|
29929
30020
|
var ACI_NAME = "m8t-installer";
|
|
29930
30021
|
var MI_NAME = "m8t-installer-mi";
|
|
29931
30022
|
var BootstrapLaunchCommand = class extends M8tCommand {
|
|
@@ -30892,19 +30983,22 @@ async function resolveSeedContext(opts) {
|
|
|
30892
30983
|
if (!appCreds) return null;
|
|
30893
30984
|
let endpoint = opts.endpointOverride;
|
|
30894
30985
|
let subscriptionId = opts.subscriptionId;
|
|
30895
|
-
|
|
30986
|
+
let recorded = opts.brainsOverride;
|
|
30987
|
+
if (!endpoint || !opts.brainOverride && recorded === void 0) {
|
|
30896
30988
|
const state = await readBootstrapState();
|
|
30897
30989
|
if (!state) {
|
|
30898
30990
|
throw new LocalCliError({ code: "BOOTSTRAP_NO_STATE", message: "No bootstrap state found.", hint: "Run 'm8t bootstrap launch' first, or pass --endpoint." });
|
|
30899
30991
|
}
|
|
30900
30992
|
subscriptionId ??= state.subscriptionId;
|
|
30901
30993
|
const doc = await readStatusBlob({ saName: state.statusSaName, resourceGroup: state.resourceGroup, subscriptionId: state.subscriptionId });
|
|
30902
|
-
endpoint
|
|
30994
|
+
endpoint ??= doc.result?.foundryEndpoint;
|
|
30995
|
+
recorded ??= doc.result?.brains;
|
|
30903
30996
|
if (!endpoint) {
|
|
30904
30997
|
throw new LocalCliError({ code: "SEED_NO_ENDPOINT", message: "Could not resolve the Foundry endpoint from the install status.", hint: "Pass --endpoint <foundryEndpoint>." });
|
|
30905
30998
|
}
|
|
30906
30999
|
}
|
|
30907
|
-
const brainRepos = opts.brainOverride ? [opts.brainOverride] : [
|
|
31000
|
+
const brainRepos = opts.brainOverride ? [opts.brainOverride] : recorded ?? [];
|
|
31001
|
+
if (brainRepos.length === 0) return null;
|
|
30908
31002
|
return { endpoint, brainRepos, appCreds, subscriptionId };
|
|
30909
31003
|
}
|
|
30910
31004
|
var MEMORY_INDEX_PATH = "memory/MEMORY.md";
|
|
@@ -31051,7 +31145,12 @@ function spawnDetachedSeedWatch() {
|
|
|
31051
31145
|
}
|
|
31052
31146
|
}
|
|
31053
31147
|
async function reactiveSeedOnInstallComplete(args) {
|
|
31054
|
-
const ctx = await resolveSeedContext({
|
|
31148
|
+
const ctx = await resolveSeedContext({
|
|
31149
|
+
endpointOverride: args.endpoint,
|
|
31150
|
+
appCredsOverride: args.appCredsOverride,
|
|
31151
|
+
subscriptionId: args.subscriptionId,
|
|
31152
|
+
brainsOverride: args.brains
|
|
31153
|
+
});
|
|
31055
31154
|
if (!ctx) return;
|
|
31056
31155
|
const token = await (args.getFoundryTokenImpl ?? getFoundryToken)();
|
|
31057
31156
|
const { hadIntake, block } = await findOnboardingProfile({ endpoint: ctx.endpoint, token, fetchImpl: args.fetchImpl });
|
|
@@ -31081,8 +31180,7 @@ async function reactiveSeedOnInstallComplete(args) {
|
|
|
31081
31180
|
|
|
31082
31181
|
// src/lib/install-summary.ts
|
|
31083
31182
|
var DEFAULT_WORKERS = [
|
|
31084
|
-
{ name: "
|
|
31085
|
-
{ name: "ezra", label: "Ezra - Azure Expert", brain: "ezra-brain", executor: "ezra-executor" }
|
|
31183
|
+
{ name: "ezra", label: "Ezra - Azure Expert", brain: "ezra-brain" }
|
|
31086
31184
|
];
|
|
31087
31185
|
function renderInstallSummary(args) {
|
|
31088
31186
|
const open3 = args.webappUrl ? `${args.webappUrl} (or run: m8t open)` : "run: m8t open";
|
|
@@ -31094,11 +31192,11 @@ function renderInstallSummary(args) {
|
|
|
31094
31192
|
if (args.brainOrg) {
|
|
31095
31193
|
lines.push(" Your team:");
|
|
31096
31194
|
for (const w of DEFAULT_WORKERS) {
|
|
31097
|
-
lines.push(` \u2022 ${w.label} \xB7 brain: ${args.brainOrg}/${w.brain}
|
|
31195
|
+
lines.push(` \u2022 ${w.label} \xB7 brain: ${args.brainOrg}/${w.brain}`);
|
|
31098
31196
|
}
|
|
31099
31197
|
lines.push(
|
|
31100
31198
|
"",
|
|
31101
|
-
" Reach them: @
|
|
31199
|
+
" Reach them: @ezra (or /ezra) in your coding agent",
|
|
31102
31200
|
" \xB7 the webapp \xB7 or connect Telegram in the webapp (Channels)"
|
|
31103
31201
|
);
|
|
31104
31202
|
} else {
|
|
@@ -32192,7 +32290,7 @@ async function runCompanionInstallCommand(stdout, install) {
|
|
|
32192
32290
|
return 1;
|
|
32193
32291
|
}
|
|
32194
32292
|
stdout.write(
|
|
32195
|
-
`Desktop companions installed
|
|
32293
|
+
`Desktop companions installed - they are at the edge of your screen.
|
|
32196
32294
|
Version: ${state.version}
|
|
32197
32295
|
`
|
|
32198
32296
|
);
|
|
@@ -32352,7 +32450,7 @@ async function finalizeInstall(args, deps = defaultDeps2) {
|
|
|
32352
32450
|
args.stdout(renderInstallSummary({ webappUrl, brainOrg }) + "\n");
|
|
32353
32451
|
args.stdout(
|
|
32354
32452
|
`${colors.field("Optional local tooling for your coding agent:")}
|
|
32355
|
-
\u2022 Talk to your deployed workers from agent sessions (e.g. /
|
|
32453
|
+
\u2022 Talk to your deployed workers from agent sessions (e.g. /ezra) \u2014 install the m8t plugin: guides/install/m8t-plugin.md.
|
|
32356
32454
|
\u2022 Azure-capable MCP servers (microsoft/azure-skills, Microsoft Learn) \u2014 see the optional steps in guides/install.md.
|
|
32357
32455
|
\u2022 Deploy workers conversationally with the opt-in persona skills \u2014 see guides/workers.md.
|
|
32358
32456
|
\u2022 Make sure your m8t CLI is current: npm i -g @m8t-stack/cli@latest
|
|
@@ -32363,6 +32461,9 @@ ${colors.field("Then open a brand new chat/session")} \u2014 new skills + MCP se
|
|
|
32363
32461
|
try {
|
|
32364
32462
|
await deps.reactiveSeed({
|
|
32365
32463
|
endpoint: args.doc.result?.foundryEndpoint,
|
|
32464
|
+
// What the install RECORDED creating. Seeding a fixed roster instead used to
|
|
32465
|
+
// fail every default install against a brain that was never created.
|
|
32466
|
+
brains: args.doc.result?.brains,
|
|
32366
32467
|
subscriptionId: args.subscriptionId,
|
|
32367
32468
|
stdout: args.stdout
|
|
32368
32469
|
});
|
|
@@ -32384,14 +32485,14 @@ ${colors.field("Then open a brand new chat/session")} \u2014 new skills + MCP se
|
|
|
32384
32485
|
const alreadyHasCompanion = await deps.companionStatus().then((s) => s.state !== "not-installed").catch(() => true);
|
|
32385
32486
|
const pinned = alreadyHasCompanion ? void 0 : args.doc.result?.platformVersion;
|
|
32386
32487
|
args.stdout(
|
|
32387
|
-
(pinned === void 0 ? "Putting
|
|
32488
|
+
(pinned === void 0 ? "Putting your mates on your desktop \u2014 fetching the latest released build\n" : `Putting your mates on your desktop \u2014 fetching the build ${pinned} pins
|
|
32388
32489
|
`) + ` ${colors.hint("(about 120 MB; on a slow link this takes a few minutes)")}
|
|
32389
32490
|
`
|
|
32390
32491
|
);
|
|
32391
32492
|
try {
|
|
32392
32493
|
const companion = await deps.convergeCompanion(pinned);
|
|
32393
32494
|
if (companion.state === "installed") {
|
|
32394
|
-
args.stdout("Desktop companions installed
|
|
32495
|
+
args.stdout("Desktop companions installed - they are at the edge of your screen.\n\n");
|
|
32395
32496
|
} else if (companion.state === "not-released") {
|
|
32396
32497
|
args.stdout(
|
|
32397
32498
|
`${pinned === void 0 ? "The latest platform release carries no desktop companions." : `The release this platform is pinned to (${pinned}) carries no desktop companions.`}
|
|
@@ -34230,11 +34331,11 @@ function parseEvent(value) {
|
|
|
34230
34331
|
};
|
|
34231
34332
|
}
|
|
34232
34333
|
if (value.type === "roster") {
|
|
34233
|
-
if (!hasExactKeys(value, ["type", "origin", "mates"]) || !isGatewayOrigin(value.origin) || !Array.isArray(value.mates) || value.mates.length
|
|
34334
|
+
if (!hasExactKeys(value, ["type", "origin", "mates"]) || !isGatewayOrigin(value.origin) || !Array.isArray(value.mates) || value.mates.length === 0) {
|
|
34234
34335
|
return eventError();
|
|
34235
34336
|
}
|
|
34236
34337
|
const mates = value.mates.map(parseMate);
|
|
34237
|
-
if (new Set(mates.map(({ personaKey }) => personaKey)).size !==
|
|
34338
|
+
if (new Set(mates.map(({ personaKey }) => personaKey)).size !== mates.length || new Set(mates.map(({ agentName }) => agentName)).size !== mates.length) {
|
|
34238
34339
|
return eventError();
|
|
34239
34340
|
}
|
|
34240
34341
|
return { type: "roster", origin: value.origin, mates };
|
|
@@ -34425,7 +34526,8 @@ function resolveAgentName(agents, personaKey) {
|
|
|
34425
34526
|
const matches = agents.filter(
|
|
34426
34527
|
(agent) => agent.personaKey === personaKey && isAgentName(agent.name)
|
|
34427
34528
|
);
|
|
34428
|
-
if (matches.length
|
|
34529
|
+
if (matches.length === 0) return null;
|
|
34530
|
+
if (matches.length > 1) {
|
|
34429
34531
|
throw new PredispatchFailure("mate-unavailable");
|
|
34430
34532
|
}
|
|
34431
34533
|
const match = matches[0];
|
|
@@ -34434,6 +34536,11 @@ function resolveAgentName(agents, personaKey) {
|
|
|
34434
34536
|
}
|
|
34435
34537
|
return match.name;
|
|
34436
34538
|
}
|
|
34539
|
+
function requireAgentName(agents, personaKey) {
|
|
34540
|
+
const name = resolveAgentName(agents, personaKey);
|
|
34541
|
+
if (name === null) throw new PredispatchFailure("mate-unavailable");
|
|
34542
|
+
return name;
|
|
34543
|
+
}
|
|
34437
34544
|
function decodeConversationId(data) {
|
|
34438
34545
|
if (!isRecord3(data) || typeof data.id !== "string" || !OPAQUE_ID.test(data.id)) {
|
|
34439
34546
|
throw new PredispatchFailure("not-connected");
|
|
@@ -34598,22 +34705,15 @@ async function rosterCompanions(sink, deps = {}) {
|
|
|
34598
34705
|
const activeSince = new Date(
|
|
34599
34706
|
installed === null || installed > now ? now : installed
|
|
34600
34707
|
).toISOString();
|
|
34601
|
-
const
|
|
34602
|
-
{
|
|
34603
|
-
|
|
34604
|
-
agentName: resolveAgentName(agents, "startup-advisor"),
|
|
34605
|
-
displayName: "Stacey",
|
|
34606
|
-
portraitKey: "stacey",
|
|
34607
|
-
activeSince
|
|
34608
|
-
},
|
|
34609
|
-
{
|
|
34610
|
-
personaKey: "ezra",
|
|
34611
|
-
agentName: resolveAgentName(agents, "ezra"),
|
|
34612
|
-
displayName: "Ezra",
|
|
34613
|
-
portraitKey: "ezra",
|
|
34614
|
-
activeSince
|
|
34615
|
-
}
|
|
34708
|
+
const PRESENTABLE = [
|
|
34709
|
+
{ personaKey: "startup-advisor", displayName: "Stacey", portraitKey: "stacey" },
|
|
34710
|
+
{ personaKey: "ezra", displayName: "Ezra", portraitKey: "ezra" }
|
|
34616
34711
|
];
|
|
34712
|
+
const mates = PRESENTABLE.flatMap((mate) => {
|
|
34713
|
+
const agentName = resolveAgentName(agents, mate.personaKey);
|
|
34714
|
+
return agentName === null ? [] : [{ ...mate, agentName, activeSince }];
|
|
34715
|
+
});
|
|
34716
|
+
if (mates.length === 0) throw new PredispatchFailure("mate-unavailable");
|
|
34617
34717
|
const event = parseEvent({ type: "roster", origin, mates });
|
|
34618
34718
|
sink(event);
|
|
34619
34719
|
return event;
|
|
@@ -34745,7 +34845,7 @@ async function dispatchConversation(request, sink, deps, consume, readDesktopMar
|
|
|
34745
34845
|
token,
|
|
34746
34846
|
controller.signal
|
|
34747
34847
|
);
|
|
34748
|
-
const agentName =
|
|
34848
|
+
const agentName = requireAgentName(agents, request.personaKey);
|
|
34749
34849
|
const conversationId = await (deps.resolveConversationId ?? resolveConversationId)(
|
|
34750
34850
|
fetchImpl,
|
|
34751
34851
|
origin,
|
|
@@ -34856,7 +34956,7 @@ async function historyCompanionMessages(request, sink, deps = {}) {
|
|
|
34856
34956
|
token,
|
|
34857
34957
|
controller.signal
|
|
34858
34958
|
);
|
|
34859
|
-
const agentName =
|
|
34959
|
+
const agentName = requireAgentName(agents, request.personaKey);
|
|
34860
34960
|
const conversationId = await (deps.resolveConversationId ?? resolveConversationId)(
|
|
34861
34961
|
fetchImpl,
|
|
34862
34962
|
origin,
|