@mrrlin-dev/mcp 0.4.64 → 0.4.66
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/bin.cjs +264 -80
- package/package.json +3 -3
package/dist/bin.cjs
CHANGED
|
@@ -21566,6 +21566,37 @@ function isExternalAgentsWrapper(table) {
|
|
|
21566
21566
|
return false;
|
|
21567
21567
|
}
|
|
21568
21568
|
async function verifyProviderReadiness(provider, run3, opts = {}) {
|
|
21569
|
+
if (provider === "agy") {
|
|
21570
|
+
let cliResult2;
|
|
21571
|
+
try {
|
|
21572
|
+
cliResult2 = run3(["--version"]);
|
|
21573
|
+
if (cliResult2.status === 0) {
|
|
21574
|
+
return {
|
|
21575
|
+
ready: true,
|
|
21576
|
+
checks: { cli: true, version: true, auth: false, mcpReachable: false },
|
|
21577
|
+
details: []
|
|
21578
|
+
};
|
|
21579
|
+
} else if (cliResult2.status === null) {
|
|
21580
|
+
return {
|
|
21581
|
+
ready: false,
|
|
21582
|
+
checks: { cli: false, version: false, auth: false, mcpReachable: false },
|
|
21583
|
+
details: ["cli: `agy` binary not found on PATH"]
|
|
21584
|
+
};
|
|
21585
|
+
} else {
|
|
21586
|
+
return {
|
|
21587
|
+
ready: false,
|
|
21588
|
+
checks: { cli: true, version: false, auth: false, mcpReachable: false },
|
|
21589
|
+
details: [`cli: \`agy --version\` exited with code ${cliResult2.status}`]
|
|
21590
|
+
};
|
|
21591
|
+
}
|
|
21592
|
+
} catch (_e) {
|
|
21593
|
+
return {
|
|
21594
|
+
ready: false,
|
|
21595
|
+
checks: { cli: false, version: false, auth: false, mcpReachable: false },
|
|
21596
|
+
details: ["cli: `agy` binary not found on PATH"]
|
|
21597
|
+
};
|
|
21598
|
+
}
|
|
21599
|
+
}
|
|
21569
21600
|
const checks = { cli: false, version: false, auth: false, mcpReachable: false };
|
|
21570
21601
|
const details = [];
|
|
21571
21602
|
let cliResult;
|
|
@@ -37215,7 +37246,7 @@ var mrrlinOperatorSettingsSchema = external_exports.object({
|
|
|
37215
37246
|
// claude-director-and-runner design.md D4/D6: the operator's one selected agent-provider seat,
|
|
37216
37247
|
// governing Director chat, the execution runner, and consensus/arbiter reviewer exclusion alike.
|
|
37217
37248
|
// Not null, defaults to 'codex' at the DB layer, so every row already has a real value.
|
|
37218
|
-
agentProvider: external_exports.enum(["codex", "claude"]).default("codex"),
|
|
37249
|
+
agentProvider: external_exports.enum(["codex", "claude", "agy"]).default("codex"),
|
|
37219
37250
|
createdAt: external_exports.string().datetime(),
|
|
37220
37251
|
updatedAt: external_exports.string().datetime()
|
|
37221
37252
|
});
|
|
@@ -37223,7 +37254,7 @@ var mrrlinOperatorSettingsUpdateSchema = external_exports.object({
|
|
|
37223
37254
|
consensusEnabled: external_exports.boolean().optional(),
|
|
37224
37255
|
autonomyPaused: external_exports.boolean().optional(),
|
|
37225
37256
|
activeProjectSlug: external_exports.string().min(1).nullable().optional(),
|
|
37226
|
-
agentProvider: external_exports.enum(["codex", "claude"]).optional()
|
|
37257
|
+
agentProvider: external_exports.enum(["codex", "claude", "agy"]).optional()
|
|
37227
37258
|
}).strict().refine((value) => Object.keys(value).length > 0, {
|
|
37228
37259
|
message: "OperatorSettingsUpdate requires at least one field"
|
|
37229
37260
|
});
|
|
@@ -37238,7 +37269,7 @@ var operatorPresenceRequestSchema = external_exports.object({ projectSlug: exter
|
|
|
37238
37269
|
var mrrlinConsensusConfigSchema = external_exports.object({ consensusEnabled: external_exports.boolean() });
|
|
37239
37270
|
var consensusConfigResponseSchema = external_exports.object({ data: mrrlinConsensusConfigSchema });
|
|
37240
37271
|
var mrrlinAgentProviderConfigSchema = external_exports.object({
|
|
37241
|
-
agentProvider: external_exports.enum(["codex", "claude"])
|
|
37272
|
+
agentProvider: external_exports.enum(["codex", "claude", "agy"])
|
|
37242
37273
|
});
|
|
37243
37274
|
var agentProviderConfigResponseSchema = external_exports.object({ data: mrrlinAgentProviderConfigSchema });
|
|
37244
37275
|
var agentPoolSnapshotSchema = external_exports.object({
|
|
@@ -37273,6 +37304,40 @@ var agentCapabilitiesSchema = external_exports.object({
|
|
|
37273
37304
|
sandboxModes: external_exports.array(external_exports.enum(["read-only", "workspace-write", "danger-full-access"])),
|
|
37274
37305
|
poolProviderLabels: external_exports.array(external_exports.string())
|
|
37275
37306
|
});
|
|
37307
|
+
var AGENT_CAPABILITIES = {
|
|
37308
|
+
codex: {
|
|
37309
|
+
listsModels: true,
|
|
37310
|
+
readsRateLimits: true,
|
|
37311
|
+
models: [],
|
|
37312
|
+
modelCatalog: [],
|
|
37313
|
+
sandboxModes: ["read-only", "workspace-write", "danger-full-access"],
|
|
37314
|
+
poolProviderLabels: ["openai"]
|
|
37315
|
+
},
|
|
37316
|
+
claude: {
|
|
37317
|
+
listsModels: false,
|
|
37318
|
+
readsRateLimits: false,
|
|
37319
|
+
// Aliases the Claude CLI documents for `--model` (`claude --help`), and what each resolved to
|
|
37320
|
+
// on 2026-09-04 per the CLI's own `system.init.model` frame. Keep in step with
|
|
37321
|
+
// packages/agent-client/src/providers/claude/models.ts — the parity test enforces equality.
|
|
37322
|
+
models: ["fable", "opus", "sonnet", "haiku"],
|
|
37323
|
+
modelCatalog: [
|
|
37324
|
+
{ id: "fable", displayName: "Fable 5.1", description: "claude-fable-5-1" },
|
|
37325
|
+
{ id: "opus", displayName: "Opus 5", description: "claude-opus-5" },
|
|
37326
|
+
{ id: "sonnet", displayName: "Sonnet 5", description: "claude-sonnet-5" },
|
|
37327
|
+
{ id: "haiku", displayName: "Haiku 4.5", description: "claude-haiku-4-5-20251001" }
|
|
37328
|
+
],
|
|
37329
|
+
sandboxModes: ["read-only", "workspace-write", "danger-full-access"],
|
|
37330
|
+
poolProviderLabels: ["anthropic"]
|
|
37331
|
+
},
|
|
37332
|
+
agy: {
|
|
37333
|
+
listsModels: false,
|
|
37334
|
+
readsRateLimits: false,
|
|
37335
|
+
models: [],
|
|
37336
|
+
modelCatalog: [],
|
|
37337
|
+
sandboxModes: ["workspace-write"],
|
|
37338
|
+
poolProviderLabels: ["antigravity"]
|
|
37339
|
+
}
|
|
37340
|
+
};
|
|
37276
37341
|
var providerReadinessResultSchema = external_exports.object({
|
|
37277
37342
|
ready: external_exports.boolean(),
|
|
37278
37343
|
checks: external_exports.object({
|
|
@@ -37285,7 +37350,8 @@ var providerReadinessResultSchema = external_exports.object({
|
|
|
37285
37350
|
});
|
|
37286
37351
|
var providerReadinessSchema = external_exports.object({
|
|
37287
37352
|
codex: providerReadinessResultSchema,
|
|
37288
|
-
claude: providerReadinessResultSchema
|
|
37353
|
+
claude: providerReadinessResultSchema,
|
|
37354
|
+
agy: providerReadinessResultSchema
|
|
37289
37355
|
});
|
|
37290
37356
|
var providerReadinessResponseSchema = external_exports.object({
|
|
37291
37357
|
data: external_exports.object({ readiness: providerReadinessSchema.nullable() })
|
|
@@ -37384,7 +37450,7 @@ var mrrlinAsyncJobSchema = external_exports.object({
|
|
|
37384
37450
|
updatedAt: external_exports.string(),
|
|
37385
37451
|
// model-tier-planning-and-arbiter task 1.8: the seat minted at claim (or inherited from a
|
|
37386
37452
|
// prior attempt on this same lease); NULL only before the first beginAttempt call pins it.
|
|
37387
|
-
agentSeat: external_exports.enum(["codex", "claude"]).nullable().default(null)
|
|
37453
|
+
agentSeat: external_exports.enum(["codex", "claude", "agy"]).nullable().default(null)
|
|
37388
37454
|
}).strict();
|
|
37389
37455
|
var asyncJobResponseSchema = external_exports.object({ data: mrrlinAsyncJobSchema });
|
|
37390
37456
|
var asyncJobMaybeResponseSchema = external_exports.object({ data: mrrlinAsyncJobSchema.nullable() });
|
|
@@ -37404,7 +37470,7 @@ var mrrlinAsyncJobBeginAttemptSchema = external_exports.object({
|
|
|
37404
37470
|
requestedHash: external_exports.string().min(1),
|
|
37405
37471
|
// task 1.8: the caller has already resolved (inherited or minted) a seat for this job by the
|
|
37406
37472
|
// time it begins an attempt — required, not optional, so persistence can never be skipped.
|
|
37407
|
-
agentSeat: external_exports.enum(["codex", "claude"])
|
|
37473
|
+
agentSeat: external_exports.enum(["codex", "claude", "agy"])
|
|
37408
37474
|
});
|
|
37409
37475
|
var mrrlinAsyncJobTerminalizeSchema = external_exports.object({
|
|
37410
37476
|
leaseId: external_exports.string().min(1),
|
|
@@ -38010,7 +38076,7 @@ var mrrlinTaskSchema = external_exports.object({
|
|
|
38010
38076
|
// Output-optional (not .default) so existing task fixtures/mocks need no churn; DB rows always
|
|
38011
38077
|
// resolve it via taskRowToTask. Null reads as the pre-existing default provider and is never
|
|
38012
38078
|
// backfilled -- it is NOT a mismatch against whatever provider is currently selected.
|
|
38013
|
-
directorThreadProvider: external_exports.enum(["codex", "claude"]).nullable().optional(),
|
|
38079
|
+
directorThreadProvider: external_exports.enum(["codex", "claude", "agy"]).nullable().optional(),
|
|
38014
38080
|
// agnostic-delivery: asserted before the work, not the deliverable-gate's differently-meaning
|
|
38015
38081
|
// `attemptOutcome` asserted after it (design.md). Required at spec approval (task 3.2's API
|
|
38016
38082
|
// gate), never at creation -- null on every task until then, forever on legacy tasks. Shape-only
|
|
@@ -38358,7 +38424,7 @@ var mrrlinTaskUpdateSchema = external_exports.object({
|
|
|
38358
38424
|
category: taxonomyCategorySchema.optional(),
|
|
38359
38425
|
directorSessionId: external_exports.string().min(1).optional(),
|
|
38360
38426
|
directorThreadId: external_exports.string().min(1).nullable().optional(),
|
|
38361
|
-
directorThreadProvider: external_exports.enum(["codex", "claude"]).nullable().optional(),
|
|
38427
|
+
directorThreadProvider: external_exports.enum(["codex", "claude", "agy"]).nullable().optional(),
|
|
38362
38428
|
declaredOutcome: mrrlinDeclaredOutcomeSchema.nullable().optional(),
|
|
38363
38429
|
dueDate: external_exports.string().date().nullable().optional(),
|
|
38364
38430
|
impact: mrrlinTaskImpactSchema.optional(),
|
|
@@ -38679,7 +38745,7 @@ var mrrlinRunPrerequisiteSchema = external_exports.object({
|
|
|
38679
38745
|
});
|
|
38680
38746
|
var mrrlinExecutionRunSchema = external_exports.object({
|
|
38681
38747
|
actor: external_exports.string().min(1),
|
|
38682
|
-
agentSeat: external_exports.enum(["codex", "claude"]).nullable(),
|
|
38748
|
+
agentSeat: external_exports.enum(["codex", "claude", "agy"]).nullable(),
|
|
38683
38749
|
baseSha: external_exports.string().min(1).nullable(),
|
|
38684
38750
|
branch: external_exports.string().min(1).nullable(),
|
|
38685
38751
|
blockingReason: mrrlinRunBlockingReasonCodeSchema.nullable(),
|
|
@@ -38739,7 +38805,7 @@ var mrrlinTaskStateSchema = external_exports.object({
|
|
|
38739
38805
|
// claude-director-and-runner design.md D5: which provider's CLI produced retiredThreadId.
|
|
38740
38806
|
// Output-optional so existing task_state fixtures/mocks need no churn; null reads as the
|
|
38741
38807
|
// pre-existing default provider and is never backfilled.
|
|
38742
|
-
retiredThreadProvider: external_exports.enum(["codex", "claude"]).nullable().optional(),
|
|
38808
|
+
retiredThreadProvider: external_exports.enum(["codex", "claude", "agy"]).nullable().optional(),
|
|
38743
38809
|
updatedAt: external_exports.string().datetime()
|
|
38744
38810
|
});
|
|
38745
38811
|
var mrrlinTaskStateUpsertSchema = external_exports.object({
|
|
@@ -38781,7 +38847,7 @@ var mrrlinExecutionRunCreateSchema = external_exports.object({
|
|
|
38781
38847
|
worktreeId: external_exports.string().min(1).optional()
|
|
38782
38848
|
});
|
|
38783
38849
|
var mrrlinExecutionRunUpdateSchema = external_exports.object({
|
|
38784
|
-
agentSeat: external_exports.enum(["codex", "claude"]).nullable().optional(),
|
|
38850
|
+
agentSeat: external_exports.enum(["codex", "claude", "agy"]).nullable().optional(),
|
|
38785
38851
|
baseSha: external_exports.string().min(1).nullable().optional(),
|
|
38786
38852
|
branch: external_exports.string().min(1).nullable().optional(),
|
|
38787
38853
|
blockingReason: mrrlinRunBlockingReasonCodeSchema.nullable().optional(),
|
|
@@ -40355,8 +40421,33 @@ var ClaudeAgentHandle = class {
|
|
|
40355
40421
|
}
|
|
40356
40422
|
};
|
|
40357
40423
|
|
|
40424
|
+
// ../../packages/agent-client/dist/providers/agy/adapter.js
|
|
40425
|
+
var AgyProviderAdapter = class {
|
|
40426
|
+
id = "agy";
|
|
40427
|
+
capabilities() {
|
|
40428
|
+
return AGENT_CAPABILITIES.agy;
|
|
40429
|
+
}
|
|
40430
|
+
// Stub adapter: real process spawning and JSONL stdio streaming will be implemented in agy-stdio-streaming
|
|
40431
|
+
async acquireWarm() {
|
|
40432
|
+
return {
|
|
40433
|
+
startThread: () => Promise.resolve({ threadId: "mock-thread-id" }),
|
|
40434
|
+
resumeThread: () => Promise.resolve({ threadId: "mock-thread-id" }),
|
|
40435
|
+
startTurn: () => Promise.resolve({ turnId: "mock-turn-id" }),
|
|
40436
|
+
interruptTurn: () => Promise.resolve(),
|
|
40437
|
+
onEvent: () => () => {
|
|
40438
|
+
},
|
|
40439
|
+
onActivity: () => () => {
|
|
40440
|
+
},
|
|
40441
|
+
listModels: () => Promise.resolve([]),
|
|
40442
|
+
readRateLimits: () => Promise.resolve(null)
|
|
40443
|
+
};
|
|
40444
|
+
}
|
|
40445
|
+
releaseWarm() {
|
|
40446
|
+
}
|
|
40447
|
+
};
|
|
40448
|
+
|
|
40358
40449
|
// ../../packages/agent-client/dist/registry.js
|
|
40359
|
-
var KNOWN_PROVIDERS = { codex: true, claude: true };
|
|
40450
|
+
var KNOWN_PROVIDERS = { codex: true, claude: true, agy: true };
|
|
40360
40451
|
var KNOWN_PROVIDER_IDS = Object.keys(KNOWN_PROVIDERS);
|
|
40361
40452
|
function readProviderFromEnv(env) {
|
|
40362
40453
|
const raw = env.MRRLIN_AGENT_PROVIDER;
|
|
@@ -40377,6 +40468,9 @@ function resolveProvider(env, persisted) {
|
|
|
40377
40468
|
if (id === "claude") {
|
|
40378
40469
|
return new ClaudeProviderAdapter();
|
|
40379
40470
|
}
|
|
40471
|
+
if (id === "agy") {
|
|
40472
|
+
return new AgyProviderAdapter();
|
|
40473
|
+
}
|
|
40380
40474
|
throw new Error(`not-yet-wired: ${id}`);
|
|
40381
40475
|
}
|
|
40382
40476
|
|
|
@@ -40720,6 +40814,8 @@ async function mintResolvedSeat(provider, opts) {
|
|
|
40720
40814
|
const providerId = provider.id;
|
|
40721
40815
|
let strongModel;
|
|
40722
40816
|
let weakModel;
|
|
40817
|
+
let pinRetired;
|
|
40818
|
+
let retiredPin;
|
|
40723
40819
|
const strongEnvValue = process.env[providerId === "codex" ? CODEX_STRONG_MODEL_ENV : CLAUDE_STRONG_MODEL_ENV]?.trim();
|
|
40724
40820
|
if (opts?.handle && capabilities.listsModels) {
|
|
40725
40821
|
try {
|
|
@@ -40733,6 +40829,8 @@ async function mintResolvedSeat(provider, opts) {
|
|
|
40733
40829
|
strongModel = picked;
|
|
40734
40830
|
if (strongEnvValue) {
|
|
40735
40831
|
logFallback(providerId, "strong", "live-default (env pin retired)", strongModel);
|
|
40832
|
+
pinRetired = true;
|
|
40833
|
+
retiredPin = strongEnvValue;
|
|
40736
40834
|
}
|
|
40737
40835
|
} else {
|
|
40738
40836
|
throw new Error("empty model list");
|
|
@@ -40780,7 +40878,8 @@ async function mintResolvedSeat(provider, opts) {
|
|
|
40780
40878
|
return {
|
|
40781
40879
|
id: providerId,
|
|
40782
40880
|
capabilities,
|
|
40783
|
-
models: { strong: strongModel, weak: weakModel }
|
|
40881
|
+
models: { strong: strongModel, weak: weakModel },
|
|
40882
|
+
...pinRetired ? { pinRetired: true, retiredPin } : {}
|
|
40784
40883
|
};
|
|
40785
40884
|
}
|
|
40786
40885
|
|
|
@@ -42846,7 +42945,7 @@ Do NOT derail the current task - if the operator has an in-flight question, answ
|
|
|
42846
42945
|
}
|
|
42847
42946
|
|
|
42848
42947
|
// src/_generated/version.ts
|
|
42849
|
-
var PKG_VERSION = "0.4.
|
|
42948
|
+
var PKG_VERSION = "0.4.66";
|
|
42850
42949
|
|
|
42851
42950
|
// src/api-base-url-migrate.ts
|
|
42852
42951
|
var import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
@@ -46215,11 +46314,12 @@ async function runProviderReadinessCycle(deps) {
|
|
|
46215
46314
|
try {
|
|
46216
46315
|
const verify = deps.verify ?? verifyProviderReadiness;
|
|
46217
46316
|
const runnerFor = deps.runnerFor ?? defaultRunnerFor;
|
|
46218
|
-
const [codex, claude] = await Promise.all([
|
|
46317
|
+
const [codex, claude, agy] = await Promise.all([
|
|
46219
46318
|
verify("codex", runnerFor("codex")),
|
|
46220
|
-
verify("claude", runnerFor("claude"))
|
|
46319
|
+
verify("claude", runnerFor("claude")),
|
|
46320
|
+
verify("agy", runnerFor("agy"))
|
|
46221
46321
|
]);
|
|
46222
|
-
await deps.push({ codex, claude });
|
|
46322
|
+
await deps.push({ codex, claude, agy });
|
|
46223
46323
|
} catch (err) {
|
|
46224
46324
|
deps.onError?.(err);
|
|
46225
46325
|
}
|
|
@@ -46260,7 +46360,7 @@ function setSelectedProvider(value) {
|
|
|
46260
46360
|
// src/execution-consumer.ts
|
|
46261
46361
|
var import_node_child_process13 = require("node:child_process");
|
|
46262
46362
|
var import_node_crypto7 = __toESM(require("node:crypto"), 1);
|
|
46263
|
-
var
|
|
46363
|
+
var import_node_path21 = __toESM(require("node:path"), 1);
|
|
46264
46364
|
var import_node_util = require("node:util");
|
|
46265
46365
|
|
|
46266
46366
|
// src/consensus/deliverable-gate-outcome.ts
|
|
@@ -47867,6 +47967,132 @@ function effortDisabled(env = process.env) {
|
|
|
47867
47967
|
return (env.MRRLIN_EXEC_EFFORT_DISABLE ?? "").trim() === "1";
|
|
47868
47968
|
}
|
|
47869
47969
|
|
|
47970
|
+
// src/operator-token.ts
|
|
47971
|
+
var import_node_fs13 = require("node:fs");
|
|
47972
|
+
var import_node_os10 = __toESM(require("node:os"), 1);
|
|
47973
|
+
var import_node_path20 = __toESM(require("node:path"), 1);
|
|
47974
|
+
function operatorDir() {
|
|
47975
|
+
const base = process.env.CODEX_HOME ? import_node_path20.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path20.default.join(import_node_os10.default.homedir(), ".mrrlin");
|
|
47976
|
+
return base;
|
|
47977
|
+
}
|
|
47978
|
+
function operatorTokenPath() {
|
|
47979
|
+
return import_node_path20.default.join(operatorDir(), "operator-token");
|
|
47980
|
+
}
|
|
47981
|
+
function readOperatorToken() {
|
|
47982
|
+
try {
|
|
47983
|
+
const token = (0, import_node_fs13.readFileSync)(operatorTokenPath(), "utf8").trim();
|
|
47984
|
+
return token.length > 0 ? token : null;
|
|
47985
|
+
} catch {
|
|
47986
|
+
return null;
|
|
47987
|
+
}
|
|
47988
|
+
}
|
|
47989
|
+
function persistOperatorToken(token) {
|
|
47990
|
+
const dir = operatorDir();
|
|
47991
|
+
(0, import_node_fs13.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
47992
|
+
(0, import_node_fs13.writeFileSync)(operatorTokenPath(), `${token.trim()}
|
|
47993
|
+
`, { encoding: "utf8", mode: 384 });
|
|
47994
|
+
}
|
|
47995
|
+
function agentCredentialPath() {
|
|
47996
|
+
return import_node_path20.default.join(operatorDir(), "agent-credential");
|
|
47997
|
+
}
|
|
47998
|
+
function persistAgentSecret(secret) {
|
|
47999
|
+
const dir = operatorDir();
|
|
48000
|
+
(0, import_node_fs13.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
48001
|
+
(0, import_node_fs13.writeFileSync)(agentCredentialPath(), `${secret.trim()}
|
|
48002
|
+
`, { encoding: "utf8", mode: 384 });
|
|
48003
|
+
}
|
|
48004
|
+
function readAgentSecret() {
|
|
48005
|
+
const fromEnv = process.env.MRRLIN_AGENT_SECRET?.trim();
|
|
48006
|
+
if (fromEnv) return fromEnv;
|
|
48007
|
+
try {
|
|
48008
|
+
const raw = (0, import_node_fs13.readFileSync)(agentCredentialPath(), "utf8").trim();
|
|
48009
|
+
return raw || void 0;
|
|
48010
|
+
} catch {
|
|
48011
|
+
return void 0;
|
|
48012
|
+
}
|
|
48013
|
+
}
|
|
48014
|
+
|
|
48015
|
+
// src/pin-retirement-notifier.ts
|
|
48016
|
+
var notifiedPins = /* @__PURE__ */ new Set();
|
|
48017
|
+
var inFlightPins = /* @__PURE__ */ new Set();
|
|
48018
|
+
function getDedupKey(providerId, pinnedModel) {
|
|
48019
|
+
return pinnedModel ? `${providerId}:${pinnedModel}` : providerId;
|
|
48020
|
+
}
|
|
48021
|
+
async function notifyPinRetirement(info, opts) {
|
|
48022
|
+
if (info.providerId === "claude") {
|
|
48023
|
+
return;
|
|
48024
|
+
}
|
|
48025
|
+
const dedupKey = getDedupKey(info.providerId, info.pinnedModel);
|
|
48026
|
+
if (notifiedPins.has(dedupKey) || inFlightPins.has(dedupKey)) {
|
|
48027
|
+
return;
|
|
48028
|
+
}
|
|
48029
|
+
inFlightPins.add(dedupKey);
|
|
48030
|
+
try {
|
|
48031
|
+
const apiBaseUrl = opts?.apiBaseUrl ?? process.env.MRRLIN_API_BASE_URL ?? "http://127.0.0.1:8787";
|
|
48032
|
+
const projectSlug = info.projectSlug ?? process.env.MRRLIN_REPORT_PROJECT_SLUG?.trim() ?? "mrrlin";
|
|
48033
|
+
const token = opts?.token !== void 0 ? opts.token : process.env.MRRLIN_API_TOKEN?.trim() || readOperatorToken();
|
|
48034
|
+
const fetchImpl = opts?.fetch ?? globalThis.fetch;
|
|
48035
|
+
const endpoint = `${apiBaseUrl.replace(/\/+$/, "")}/projects/${encodeURIComponent(
|
|
48036
|
+
projectSlug
|
|
48037
|
+
)}/tasks`;
|
|
48038
|
+
const headers = {
|
|
48039
|
+
"content-type": "application/json",
|
|
48040
|
+
"x-mrrlin-actor": "mrrlin-bridge",
|
|
48041
|
+
"x-mrrlin-director-session-id": "pin-retirement-signal"
|
|
48042
|
+
};
|
|
48043
|
+
if (token) {
|
|
48044
|
+
headers.authorization = `Bearer ${token}`;
|
|
48045
|
+
}
|
|
48046
|
+
const body = {
|
|
48047
|
+
title: `[Bug] Retired strong-model pin: ${info.providerId} (${info.pinnedModel})`,
|
|
48048
|
+
type: "bug",
|
|
48049
|
+
category: "bug",
|
|
48050
|
+
subcategory: "reported",
|
|
48051
|
+
domain: "code",
|
|
48052
|
+
impact: "medium",
|
|
48053
|
+
notes: `The pinned strong model "${info.pinnedModel}" for provider "${info.providerId}" was not found in the provider's live model list (retired by provider). Falling back to live default model "${info.fallbackModel}". Please update the operator pin in ~/.mrrlin/ecosystem.config.cjs or the corresponding environment variable (MRRLIN_${info.providerId.toUpperCase()}_STRONG_MODEL).`,
|
|
48054
|
+
operatorSeedRequest: `The pinned strong model "${info.pinnedModel}" for provider "${info.providerId}" has been retired. Fallback in use: "${info.fallbackModel}". Update the strong model pin.`,
|
|
48055
|
+
autonomyLevel: "human_review",
|
|
48056
|
+
autonomyReason: "Needs human review before automation."
|
|
48057
|
+
};
|
|
48058
|
+
const response = await fetchImpl(endpoint, {
|
|
48059
|
+
method: "POST",
|
|
48060
|
+
headers,
|
|
48061
|
+
body: JSON.stringify(body)
|
|
48062
|
+
});
|
|
48063
|
+
if (response.ok) {
|
|
48064
|
+
notifiedPins.add(dedupKey);
|
|
48065
|
+
} else {
|
|
48066
|
+
console.warn(
|
|
48067
|
+
`[pin-retirement-notifier] received non-2xx status (${response.status}) from ${endpoint}`
|
|
48068
|
+
);
|
|
48069
|
+
}
|
|
48070
|
+
} catch (err) {
|
|
48071
|
+
console.warn(
|
|
48072
|
+
`[pin-retirement-notifier] failed to report retirement for provider "${info.providerId}":`,
|
|
48073
|
+
err
|
|
48074
|
+
);
|
|
48075
|
+
} finally {
|
|
48076
|
+
inFlightPins.delete(dedupKey);
|
|
48077
|
+
}
|
|
48078
|
+
}
|
|
48079
|
+
async function notifyPinRetirementIfRetired(seat, opts) {
|
|
48080
|
+
if (!seat.pinRetired) {
|
|
48081
|
+
return;
|
|
48082
|
+
}
|
|
48083
|
+
const pinnedModel = seat.retiredPin ?? (seat.id === "codex" ? process.env.MRRLIN_CODEX_STRONG_MODEL : seat.id === "claude" ? process.env.MRRLIN_CLAUDE_STRONG_MODEL : void 0) ?? "unknown";
|
|
48084
|
+
const fallbackModel = seat.models?.strong ?? "unknown";
|
|
48085
|
+
await notifyPinRetirement(
|
|
48086
|
+
{
|
|
48087
|
+
providerId: seat.id,
|
|
48088
|
+
pinnedModel,
|
|
48089
|
+
fallbackModel,
|
|
48090
|
+
projectSlug: opts?.projectSlug
|
|
48091
|
+
},
|
|
48092
|
+
opts
|
|
48093
|
+
);
|
|
48094
|
+
}
|
|
48095
|
+
|
|
47870
48096
|
// src/execution-consumer.ts
|
|
47871
48097
|
var DEFAULT_STALE_SECONDS = 300;
|
|
47872
48098
|
var DEFAULT_MAX_LEASE_RECLAIMS = 3;
|
|
@@ -48594,6 +48820,7 @@ async function driveRun(deps, projectSlug, runId) {
|
|
|
48594
48820
|
resolvedProviderId = claimed.agentSeat;
|
|
48595
48821
|
} else {
|
|
48596
48822
|
const seat = await mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()));
|
|
48823
|
+
void notifyPinRetirementIfRetired(seat, { projectSlug });
|
|
48597
48824
|
resolvedProviderId = seat.id;
|
|
48598
48825
|
await deps.client.updateExecutionRun(projectSlug, runId, { agentSeat: seat.id }).catch((err) => {
|
|
48599
48826
|
console.warn(
|
|
@@ -49861,8 +50088,8 @@ async function runBackstopSweep(deps, drive = (slug, id) => driveRun(deps, slug,
|
|
|
49861
50088
|
function isRunRecoverableByThisBridge(run3, worktreeRoot) {
|
|
49862
50089
|
if (!worktreeRoot) return true;
|
|
49863
50090
|
if (!run3.worktreeId) return false;
|
|
49864
|
-
const relative =
|
|
49865
|
-
return relative === "" || relative.length > 0 && !relative.startsWith("..") && !
|
|
50091
|
+
const relative = import_node_path21.default.relative(import_node_path21.default.resolve(worktreeRoot), import_node_path21.default.resolve(run3.worktreeId));
|
|
50092
|
+
return relative === "" || relative.length > 0 && !relative.startsWith("..") && !import_node_path21.default.isAbsolute(relative);
|
|
49866
50093
|
}
|
|
49867
50094
|
async function deployGateHandoff(deps, projectSlug, task, runId, reason, leaseId) {
|
|
49868
50095
|
await deps.client.updateExecutionRun(projectSlug, runId, { status: "failed", finishedAt: (/* @__PURE__ */ new Date()).toISOString(), leaseId: leaseId ?? void 0 }).catch(() => {
|
|
@@ -49911,9 +50138,9 @@ function getAsyncToolDescriptor(toolName) {
|
|
|
49911
50138
|
}
|
|
49912
50139
|
|
|
49913
50140
|
// src/bridge-log.ts
|
|
49914
|
-
var
|
|
50141
|
+
var import_node_fs14 = require("node:fs");
|
|
49915
50142
|
var import_promises7 = require("node:fs/promises");
|
|
49916
|
-
var
|
|
50143
|
+
var import_node_path22 = require("node:path");
|
|
49917
50144
|
|
|
49918
50145
|
// src/redact.ts
|
|
49919
50146
|
var REDACTED = "[REDACTED]";
|
|
@@ -50189,14 +50416,14 @@ function resolvePromptsEnabled(env = process.env) {
|
|
|
50189
50416
|
}
|
|
50190
50417
|
function createBridgeLogger(stateDir, env = process.env) {
|
|
50191
50418
|
if (!resolveBridgeLogEnabled(env)) return NOOP_LOGGER;
|
|
50192
|
-
const logsDir = (0,
|
|
50419
|
+
const logsDir = (0, import_node_path22.join)(stateDir, "logs");
|
|
50193
50420
|
try {
|
|
50194
|
-
(0,
|
|
50421
|
+
(0, import_node_fs14.mkdirSync)(logsDir, { recursive: true });
|
|
50195
50422
|
} catch {
|
|
50196
50423
|
return NOOP_LOGGER;
|
|
50197
50424
|
}
|
|
50198
50425
|
const includePrompts = resolvePromptsEnabled(env);
|
|
50199
|
-
const fileFor = () => (0,
|
|
50426
|
+
const fileFor = () => (0, import_node_path22.join)(logsDir, `bridge-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.jsonl`);
|
|
50200
50427
|
const MAX_TRACKED_SESSIONS = 64;
|
|
50201
50428
|
const contextSlugBySession = /* @__PURE__ */ new Map();
|
|
50202
50429
|
const rememberContextSlug = (sessionId, payload) => {
|
|
@@ -50237,10 +50464,10 @@ function createBridgeLogger(stateDir, env = process.env) {
|
|
|
50237
50464
|
return { isGap, isNewTurn };
|
|
50238
50465
|
};
|
|
50239
50466
|
const gainDay = (sessionId) => {
|
|
50240
|
-
const sessionsPath = (0,
|
|
50467
|
+
const sessionsPath = (0, import_node_path22.join)(logsDir, ".sessions.json");
|
|
50241
50468
|
let sessionsObj = {};
|
|
50242
50469
|
try {
|
|
50243
|
-
const parsed = JSON.parse((0,
|
|
50470
|
+
const parsed = JSON.parse((0, import_node_fs14.readFileSync)(sessionsPath, "utf8"));
|
|
50244
50471
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) sessionsObj = parsed;
|
|
50245
50472
|
} catch {
|
|
50246
50473
|
sessionsObj = {};
|
|
@@ -50250,8 +50477,8 @@ function createBridgeLogger(stateDir, env = process.env) {
|
|
|
50250
50477
|
if (idsToday.includes(sessionId)) return;
|
|
50251
50478
|
sessionsObj[day] = [...idsToday, sessionId];
|
|
50252
50479
|
const tmpPath = `${sessionsPath}.tmp`;
|
|
50253
|
-
(0,
|
|
50254
|
-
(0,
|
|
50480
|
+
(0, import_node_fs14.writeFileSync)(tmpPath, JSON.stringify(sessionsObj));
|
|
50481
|
+
(0, import_node_fs14.renameSync)(tmpPath, sessionsPath);
|
|
50255
50482
|
};
|
|
50256
50483
|
const write = (dir, rec) => {
|
|
50257
50484
|
try {
|
|
@@ -50342,7 +50569,7 @@ function createBridgeLogger(stateDir, env = process.env) {
|
|
|
50342
50569
|
...recordingObligationUnresolved ? { recordingObligationUnresolved } : {},
|
|
50343
50570
|
...recordingObligationMultiResolve ? { recordingObligationMultiResolve } : {}
|
|
50344
50571
|
}) + "\n";
|
|
50345
|
-
(0,
|
|
50572
|
+
(0, import_node_fs14.appendFileSync)(fileFor(), line);
|
|
50346
50573
|
if (rec.sessionId !== null) gainDay(rec.sessionId);
|
|
50347
50574
|
} catch {
|
|
50348
50575
|
}
|
|
@@ -50355,7 +50582,7 @@ function createBridgeLogger(stateDir, env = process.env) {
|
|
|
50355
50582
|
};
|
|
50356
50583
|
}
|
|
50357
50584
|
async function findSessionDays(stateDir, sessionId) {
|
|
50358
|
-
const sessionsPath = (0,
|
|
50585
|
+
const sessionsPath = (0, import_node_path22.join)(stateDir, "logs", ".sessions.json");
|
|
50359
50586
|
let sessionsObj;
|
|
50360
50587
|
try {
|
|
50361
50588
|
const parsed = JSON.parse(await (0, import_promises7.readFile)(sessionsPath, "utf8"));
|
|
@@ -50537,12 +50764,12 @@ async function runAsyncBackstopSweep(deps, drive = (slug, jobId) => driveAsyncJo
|
|
|
50537
50764
|
}
|
|
50538
50765
|
|
|
50539
50766
|
// src/state-dir.ts
|
|
50540
|
-
var
|
|
50541
|
-
var
|
|
50767
|
+
var import_node_os11 = __toESM(require("node:os"), 1);
|
|
50768
|
+
var import_node_path23 = __toESM(require("node:path"), 1);
|
|
50542
50769
|
function resolveStateDir(env = process.env) {
|
|
50543
50770
|
const codexHome = env.CODEX_HOME;
|
|
50544
|
-
if (codexHome) return
|
|
50545
|
-
return
|
|
50771
|
+
if (codexHome) return import_node_path23.default.join(codexHome, "mrrlin", "director-bridge");
|
|
50772
|
+
return import_node_path23.default.join(import_node_os11.default.homedir(), ".mrrlin", "director-bridge");
|
|
50546
50773
|
}
|
|
50547
50774
|
|
|
50548
50775
|
// src/consensus/deliverable-gate.ts
|
|
@@ -50797,51 +51024,6 @@ function agentIdleMs(provider) {
|
|
|
50797
51024
|
return seconds * 1e3;
|
|
50798
51025
|
}
|
|
50799
51026
|
|
|
50800
|
-
// src/operator-token.ts
|
|
50801
|
-
var import_node_fs14 = require("node:fs");
|
|
50802
|
-
var import_node_os11 = __toESM(require("node:os"), 1);
|
|
50803
|
-
var import_node_path23 = __toESM(require("node:path"), 1);
|
|
50804
|
-
function operatorDir() {
|
|
50805
|
-
const base = process.env.CODEX_HOME ? import_node_path23.default.join(process.env.CODEX_HOME, "mrrlin") : import_node_path23.default.join(import_node_os11.default.homedir(), ".mrrlin");
|
|
50806
|
-
return base;
|
|
50807
|
-
}
|
|
50808
|
-
function operatorTokenPath() {
|
|
50809
|
-
return import_node_path23.default.join(operatorDir(), "operator-token");
|
|
50810
|
-
}
|
|
50811
|
-
function readOperatorToken() {
|
|
50812
|
-
try {
|
|
50813
|
-
const token = (0, import_node_fs14.readFileSync)(operatorTokenPath(), "utf8").trim();
|
|
50814
|
-
return token.length > 0 ? token : null;
|
|
50815
|
-
} catch {
|
|
50816
|
-
return null;
|
|
50817
|
-
}
|
|
50818
|
-
}
|
|
50819
|
-
function persistOperatorToken(token) {
|
|
50820
|
-
const dir = operatorDir();
|
|
50821
|
-
(0, import_node_fs14.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
50822
|
-
(0, import_node_fs14.writeFileSync)(operatorTokenPath(), `${token.trim()}
|
|
50823
|
-
`, { encoding: "utf8", mode: 384 });
|
|
50824
|
-
}
|
|
50825
|
-
function agentCredentialPath() {
|
|
50826
|
-
return import_node_path23.default.join(operatorDir(), "agent-credential");
|
|
50827
|
-
}
|
|
50828
|
-
function persistAgentSecret(secret) {
|
|
50829
|
-
const dir = operatorDir();
|
|
50830
|
-
(0, import_node_fs14.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
50831
|
-
(0, import_node_fs14.writeFileSync)(agentCredentialPath(), `${secret.trim()}
|
|
50832
|
-
`, { encoding: "utf8", mode: 384 });
|
|
50833
|
-
}
|
|
50834
|
-
function readAgentSecret() {
|
|
50835
|
-
const fromEnv = process.env.MRRLIN_AGENT_SECRET?.trim();
|
|
50836
|
-
if (fromEnv) return fromEnv;
|
|
50837
|
-
try {
|
|
50838
|
-
const raw = (0, import_node_fs14.readFileSync)(agentCredentialPath(), "utf8").trim();
|
|
50839
|
-
return raw || void 0;
|
|
50840
|
-
} catch {
|
|
50841
|
-
return void 0;
|
|
50842
|
-
}
|
|
50843
|
-
}
|
|
50844
|
-
|
|
50845
51027
|
// src/thread-index.ts
|
|
50846
51028
|
var import_node_fs15 = require("node:fs");
|
|
50847
51029
|
var import_node_path24 = __toESM(require("node:path"), 1);
|
|
@@ -57007,6 +57189,7 @@ function createBridgeMessageHandler(deps) {
|
|
|
57007
57189
|
return;
|
|
57008
57190
|
}
|
|
57009
57191
|
const compactionSeat = await mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()));
|
|
57192
|
+
void notifyPinRetirementIfRetired(compactionSeat);
|
|
57010
57193
|
const result = await deps.runCompaction({
|
|
57011
57194
|
history,
|
|
57012
57195
|
provider: compactionSeat.id,
|
|
@@ -57378,6 +57561,7 @@ function createBridgeMessageHandler(deps) {
|
|
|
57378
57561
|
}
|
|
57379
57562
|
pendingTurnSessions.add(directorSessionId);
|
|
57380
57563
|
const turnSeat = await mintResolvedSeat(resolveProvider(process.env, getSelectedProvider()));
|
|
57564
|
+
void notifyPinRetirementIfRetired(turnSeat);
|
|
57381
57565
|
const turnProviderCapabilities = turnSeat.capabilities;
|
|
57382
57566
|
const codexClient = await deps.acquireCodex(turnSeat.id);
|
|
57383
57567
|
let thread = deps.threads.get(directorSessionId);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mrrlin-dev/mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.66",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mrrlin-mcp": "dist/bin.cjs"
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"@mrrlin/agent-client": "0.0.0",
|
|
26
26
|
"@mrrlin/director-e2e": "0.0.0",
|
|
27
27
|
"@mrrlin/tsconfig": "0.0.0",
|
|
28
|
-
"@mrrlin/
|
|
29
|
-
"@mrrlin/
|
|
28
|
+
"@mrrlin/wiki": "0.0.0",
|
|
29
|
+
"@mrrlin/schemas": "0.0.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@iarna/toml": "^2.2.5",
|