usebeeline 0.0.122 → 0.0.123
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/usebeeline.mjs +112 -54
- package/package.json +1 -1
package/dist/usebeeline.mjs
CHANGED
|
@@ -16005,39 +16005,28 @@ function modelSelectionTargets(selection) {
|
|
|
16005
16005
|
}
|
|
16006
16006
|
];
|
|
16007
16007
|
}
|
|
16008
|
-
function assertModelSelectionAdvertised(advertisedOptions, selection) {
|
|
16009
|
-
for (const target of modelSelectionTargets(selection)) {
|
|
16010
|
-
if (!target.value)
|
|
16011
|
-
continue;
|
|
16012
|
-
const axis = advertisedOptions.find((option) => target.categories.includes(option.category));
|
|
16013
|
-
if (!axis) {
|
|
16014
|
-
continue;
|
|
16015
|
-
}
|
|
16016
|
-
assertModelConfigAxisAllowed(axis.id, advertisedOptions);
|
|
16017
|
-
if (!axis.options.some((choice) => choice.id === target.value)) {
|
|
16018
|
-
throw new ModelSelectionUnavailableError({
|
|
16019
|
-
label: target.label,
|
|
16020
|
-
value: target.value,
|
|
16021
|
-
reason: "not-advertised"
|
|
16022
|
-
});
|
|
16023
|
-
}
|
|
16024
|
-
}
|
|
16025
|
-
}
|
|
16026
16008
|
function assertModelConfigAxisAllowed(configId, advertisedOptions) {
|
|
16027
16009
|
const axis = advertisedOptions.find((option) => option.id === configId);
|
|
16028
16010
|
if (!axis || !isAllowedAgentModelConfigCategory(axis.category)) {
|
|
16029
16011
|
throw new DisallowedModelConfigOptionError(configId);
|
|
16030
16012
|
}
|
|
16031
16013
|
}
|
|
16032
|
-
async function
|
|
16033
|
-
|
|
16014
|
+
async function applyAgentModelSelectionWithUpdatedCatalog(client, sessionId, advertisedOptions, selection) {
|
|
16015
|
+
let currentOptions = advertisedOptions;
|
|
16034
16016
|
for (const target of modelSelectionTargets(selection)) {
|
|
16035
16017
|
if (!target.value)
|
|
16036
16018
|
continue;
|
|
16037
|
-
const axis =
|
|
16019
|
+
const axis = currentOptions.find((option) => target.categories.includes(option.category));
|
|
16038
16020
|
if (!axis)
|
|
16039
16021
|
continue;
|
|
16040
|
-
assertModelConfigAxisAllowed(axis.id,
|
|
16022
|
+
assertModelConfigAxisAllowed(axis.id, currentOptions);
|
|
16023
|
+
if (!axis.options.some((choice) => choice.id === target.value)) {
|
|
16024
|
+
throw new ModelSelectionUnavailableError({
|
|
16025
|
+
label: target.label,
|
|
16026
|
+
value: target.value,
|
|
16027
|
+
reason: "not-advertised"
|
|
16028
|
+
});
|
|
16029
|
+
}
|
|
16041
16030
|
try {
|
|
16042
16031
|
if (axis.id === GROK_SESSION_MODEL_AXIS_ID) {
|
|
16043
16032
|
if (!client.setModel)
|
|
@@ -16048,7 +16037,10 @@ async function applyAgentModelSelection(client, sessionId, advertisedOptions, se
|
|
|
16048
16037
|
throw new Error(`Grok started with reasoning effort "${axis.currentValue ?? "unknown"}", not "${target.value}"`);
|
|
16049
16038
|
}
|
|
16050
16039
|
} else {
|
|
16051
|
-
await client.setConfigOption(sessionId, axis.id, target.value);
|
|
16040
|
+
const updated = await client.setConfigOption(sessionId, axis.id, target.value);
|
|
16041
|
+
const refreshed = filterAllowedModelConfigOptions(parseAdvertisedConfigOptions(updated, selection.model));
|
|
16042
|
+
if (refreshed.length > 0)
|
|
16043
|
+
currentOptions = refreshed;
|
|
16052
16044
|
}
|
|
16053
16045
|
} catch (error) {
|
|
16054
16046
|
throw new ModelSelectionUnavailableError({
|
|
@@ -16059,6 +16051,10 @@ async function applyAgentModelSelection(client, sessionId, advertisedOptions, se
|
|
|
16059
16051
|
});
|
|
16060
16052
|
}
|
|
16061
16053
|
}
|
|
16054
|
+
return currentOptions;
|
|
16055
|
+
}
|
|
16056
|
+
async function applyAgentModelSelection(client, sessionId, advertisedOptions, selection) {
|
|
16057
|
+
await applyAgentModelSelectionWithUpdatedCatalog(client, sessionId, advertisedOptions, selection);
|
|
16062
16058
|
}
|
|
16063
16059
|
|
|
16064
16060
|
// apps/body/dist/model-catalog.js
|
|
@@ -16109,27 +16105,34 @@ async function withAgentModelCatalog(agent, agentEnv, selection, inspect, limits
|
|
|
16109
16105
|
async function fetchAgentModelCatalog(agent, agentEnv, selection, limits = {}) {
|
|
16110
16106
|
return withAgentModelCatalog(agent, agentEnv, selection, async ({ client, sessionId, raw, catalog }) => ({
|
|
16111
16107
|
raw,
|
|
16112
|
-
catalog: await filterModelChoicesByLiveValidation(client, sessionId, catalog)
|
|
16108
|
+
catalog: await filterModelChoicesByLiveValidation(client, sessionId, catalog, selection?.model)
|
|
16113
16109
|
}), limits);
|
|
16114
16110
|
}
|
|
16115
|
-
async function filterModelChoicesByLiveValidation(client, sessionId, catalog) {
|
|
16111
|
+
async function filterModelChoicesByLiveValidation(client, sessionId, catalog, preferredModelId) {
|
|
16116
16112
|
const modelAxis = catalog.find((axis) => axis.category === "model");
|
|
16117
16113
|
if (!modelAxis)
|
|
16118
16114
|
return catalog;
|
|
16119
16115
|
const available = [];
|
|
16116
|
+
const preferred = preferredModelId ?? modelAxis.currentValue;
|
|
16117
|
+
let preferredCatalog;
|
|
16120
16118
|
for (const choice of modelAxis.options) {
|
|
16121
16119
|
try {
|
|
16122
|
-
await
|
|
16120
|
+
const updated = await applyAgentModelSelectionWithUpdatedCatalog(client, sessionId, catalog, {
|
|
16121
|
+
model: choice.id
|
|
16122
|
+
});
|
|
16123
16123
|
available.push(choice);
|
|
16124
|
+
if (choice.id === preferred)
|
|
16125
|
+
preferredCatalog = updated;
|
|
16124
16126
|
} catch {
|
|
16125
16127
|
}
|
|
16126
16128
|
}
|
|
16127
|
-
|
|
16129
|
+
const effective = preferredCatalog ?? catalog;
|
|
16130
|
+
return effective.map((axis) => axis.category === "model" ? { ...axis, options: available } : axis);
|
|
16128
16131
|
}
|
|
16129
16132
|
async function validateAgentModelSelection(agent, agentEnv, selection) {
|
|
16130
16133
|
return withAgentModelCatalog(agent, agentEnv, selection, async ({ client, sessionId, raw, catalog }) => {
|
|
16131
|
-
await
|
|
16132
|
-
return { raw, catalog };
|
|
16134
|
+
const applied = await applyAgentModelSelectionWithUpdatedCatalog(client, sessionId, catalog, selection);
|
|
16135
|
+
return { raw, catalog: applied };
|
|
16133
16136
|
});
|
|
16134
16137
|
}
|
|
16135
16138
|
|
|
@@ -16215,7 +16218,7 @@ async function syncAgentModelCatalog(input) {
|
|
|
16215
16218
|
const effectiveCatalog = input.startupUnavailable ? catalog : withEffectiveCurrentValues(catalog, selection);
|
|
16216
16219
|
const hash = modelCatalogHash(effectiveCatalog, selection, input.startupUnavailable);
|
|
16217
16220
|
const previous = await readFile(hashPath, "utf8").catch(() => "");
|
|
16218
|
-
if (previous.trim() === hash)
|
|
16221
|
+
if (!input.force && previous.trim() === hash)
|
|
16219
16222
|
return "unchanged";
|
|
16220
16223
|
await input.api.execute("postAgentModelCatalog", {
|
|
16221
16224
|
agentId: input.agentId,
|
|
@@ -31580,14 +31583,18 @@ export default async function (pi) {
|
|
|
31580
31583
|
label: labelOf(tool.name),
|
|
31581
31584
|
description: typeof tool.description === 'string' ? tool.description : tool.name,
|
|
31582
31585
|
parameters: schema,
|
|
31583
|
-
async execute(
|
|
31586
|
+
async execute(toolCallId, params, signal) {
|
|
31584
31587
|
const result = await callServer(
|
|
31585
31588
|
server,
|
|
31586
31589
|
{
|
|
31587
31590
|
jsonrpc: '2.0',
|
|
31588
31591
|
id: 1,
|
|
31589
31592
|
method: 'tools/call',
|
|
31590
|
-
params: {
|
|
31593
|
+
params: {
|
|
31594
|
+
name: tool.name,
|
|
31595
|
+
arguments: params ?? {},
|
|
31596
|
+
_meta: { beelineToolCallId: toolCallId },
|
|
31597
|
+
},
|
|
31591
31598
|
},
|
|
31592
31599
|
signal,
|
|
31593
31600
|
);
|
|
@@ -32082,6 +32089,7 @@ function beelineAgentMcpServer(config, api, context) {
|
|
|
32082
32089
|
{ name: "BEELINE_DAEMON_ROOM_ID", value: context.roomId },
|
|
32083
32090
|
{ name: "BEELINE_DAEMON_WORKSPACE_ID", value: context.workspaceId },
|
|
32084
32091
|
...context.cornerId ? [{ name: "BEELINE_DAEMON_CORNER_ID", value: context.cornerId }] : [],
|
|
32092
|
+
...context.agentMayCloseCorner ? [{ name: "BEELINE_CORNER_AGENT_CLOSE", value: "1" }] : [],
|
|
32085
32093
|
...context.reviewer ? [{ name: "BEELINE_CORNER_REVIEWER", value: "1" }] : [],
|
|
32086
32094
|
...context.attachRoot ? [{ name: "BEELINE_ATTACH_ROOT", value: context.attachRoot }] : [],
|
|
32087
32095
|
...context.attachScratchRoot ? [{ name: "BEELINE_ATTACH_SCRATCH_ROOT", value: context.attachScratchRoot }] : [],
|
|
@@ -34026,6 +34034,8 @@ function cornerReviewerInstruction(input) {
|
|
|
34026
34034
|
const headSha = input.headSha ?? "<head sha>";
|
|
34027
34035
|
return `Checks are green on PR #${number} at ${headSha}. Review it now with the beeline-review skill against that exact head. FAIL: reply \`@${author}\` with the confirmed findings to fix. PASS: call the approve_merge tool for ${headSha}, then reply \`@${author} approved ${headSha}, merge\`. Never merge yourself. Never say you are holding or waiting for checks.`;
|
|
34028
34036
|
}
|
|
34037
|
+
var CORNER_REVIEWER_SESSION_INSTRUCTION = "You are this Room's configured reviewer. The active turn prompt names the latest stable green PR head. Review and approve only that exact head; if no stable green head is named, end the turn without a verdict. Never merge yourself.";
|
|
34038
|
+
var CORNER_REVIEWER_UNSTABLE_HEAD_INSTRUCTION = "There is no stable green PR head for this active reviewer turn. Do not review or call approve_merge. End this turn without a verdict; the next green transition will wake you.";
|
|
34029
34039
|
function cornerSelfReviewerInstruction(input) {
|
|
34030
34040
|
if (!input.reviewerHandle || !input.agentHandle || !input.openedByAgent || input.agentHandle.replace(/^@/, "") !== input.reviewerHandle.replace(/^@/, ""))
|
|
34031
34041
|
return void 0;
|
|
@@ -34247,6 +34257,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
34247
34257
|
yoloMode = false;
|
|
34248
34258
|
/** The live parent-Room reviewer baked into the current session. */
|
|
34249
34259
|
reviewerHandle;
|
|
34260
|
+
/** Identity-only reviewer context; the exact PR head is refreshed inside each active turn. */
|
|
34261
|
+
reviewerInstructionInput;
|
|
34250
34262
|
/** The role-specific second-chance instruction for this session. */
|
|
34251
34263
|
cornerTurnEndNudge = CORNER_DELIVERY_NUDGE;
|
|
34252
34264
|
/** Repository state already given a delivery reminder, until that state changes. */
|
|
@@ -34421,17 +34433,8 @@ var MonolithCornerTurnLoop = class {
|
|
|
34421
34433
|
authorHandle: opener?.handle,
|
|
34422
34434
|
openedByAgent: !this.options.openedBy || this.options.openedBy === this.agent.publicKey
|
|
34423
34435
|
};
|
|
34424
|
-
|
|
34425
|
-
|
|
34426
|
-
const restore = await this.options.api.execute("getCornerRestoreState", {
|
|
34427
|
-
cornerId: this.options.cornerId
|
|
34428
|
-
});
|
|
34429
|
-
reviewerInstruction = cornerReviewerInstruction({
|
|
34430
|
-
...reviewerInput,
|
|
34431
|
-
pullRequestNumber: restore.lifecycle?.pr?.number,
|
|
34432
|
-
headSha: restore.lifecycle?.pr?.headSha
|
|
34433
|
-
});
|
|
34434
|
-
}
|
|
34436
|
+
const reviewerInstruction = cornerReviewerInstruction(reviewerInput) ? CORNER_REVIEWER_SESSION_INSTRUCTION : void 0;
|
|
34437
|
+
this.reviewerInstructionInput = reviewerInstruction ? reviewerInput : void 0;
|
|
34435
34438
|
const selfReviewerInstruction = cornerSelfReviewerInstruction(reviewerInput);
|
|
34436
34439
|
this.cornerTurnEndNudge = reviewerInstruction ?? selfReviewerInstruction ?? cornerMergeInstruction(configuration.yoloMode, configuration.reviewerHandle);
|
|
34437
34440
|
await mkdir14(this.options.worktreePath, { recursive: true });
|
|
@@ -34579,6 +34582,7 @@ var MonolithCornerTurnLoop = class {
|
|
|
34579
34582
|
roomId: this.options.parentRoomId,
|
|
34580
34583
|
workspaceId: this.options.workspaceId,
|
|
34581
34584
|
cornerId: this.options.cornerId,
|
|
34585
|
+
agentMayCloseCorner: Boolean(repository),
|
|
34582
34586
|
reviewer: Boolean(reviewerInstruction),
|
|
34583
34587
|
attachRoot: this.options.worktreePath,
|
|
34584
34588
|
// The whole per-session overlay, not an enumerated subset: see
|
|
@@ -34636,10 +34640,9 @@ var MonolithCornerTurnLoop = class {
|
|
|
34636
34640
|
"Work in this corner's writable workspace. Use write_scratch_file or ordinary tools to create files, then post_artifact with the path to send them back to the corner.",
|
|
34637
34641
|
"Do not initialize a repository, create a branch, commit, push, open a pull request, or wait for GitHub checks.",
|
|
34638
34642
|
// This lane has no pull request URL and no merge card, so its
|
|
34639
|
-
// attached final reply
|
|
34640
|
-
//
|
|
34641
|
-
|
|
34642
|
-
this.options.requesterHandle ? `Deliver the result as artifacts: post_artifact everything the objective asked for, then call close_corner. Finish the turn by replying with @${this.options.requesterHandle} and one line on what you posted; that attached reply is the requester-facing completion signal.` : `Deliver the result as artifacts: post_artifact everything the objective asked for, then call close_corner. Finish the turn by replying with one line on what you posted; that attached reply is the requester-facing completion signal.`
|
|
34643
|
+
// attached final reply reports delivery to the requester. The
|
|
34644
|
+
// corner remains open until a human explicitly closes it.
|
|
34645
|
+
this.options.requesterHandle ? `Deliver the result as artifacts: post_artifact everything the objective asked for. Finish the turn by replying with @${this.options.requesterHandle} and one line on what you posted. The corner stays open until a human explicitly closes it.` : `Deliver the result as artifacts: post_artifact everything the objective asked for. Finish the turn by replying with one line on what you posted. The corner stays open until a human explicitly closes it.`
|
|
34643
34646
|
]
|
|
34644
34647
|
].filter(Boolean).join("\n\n")
|
|
34645
34648
|
});
|
|
@@ -34652,6 +34655,41 @@ var MonolithCornerTurnLoop = class {
|
|
|
34652
34655
|
}
|
|
34653
34656
|
return opened.sessionId;
|
|
34654
34657
|
}
|
|
34658
|
+
/**
|
|
34659
|
+
* Resolve the review target at prompt time, not session activation time.
|
|
34660
|
+
*
|
|
34661
|
+
* A push can land after a reviewer session starts but before its first
|
|
34662
|
+
* prompt, or while that prompt is running. The active prompt and its bounded
|
|
34663
|
+
* second pass therefore each read the current green lifecycle head. The
|
|
34664
|
+
* server still compares approve_merge's SHA with the current head, so a push
|
|
34665
|
+
* after this read fails closed too.
|
|
34666
|
+
*/
|
|
34667
|
+
async activeReviewerInstruction() {
|
|
34668
|
+
const input = this.reviewerInstructionInput;
|
|
34669
|
+
if (!input)
|
|
34670
|
+
return void 0;
|
|
34671
|
+
try {
|
|
34672
|
+
const [restore, localHead] = await Promise.all([
|
|
34673
|
+
this.options.api.execute("getCornerRestoreState", {
|
|
34674
|
+
cornerId: this.options.cornerId
|
|
34675
|
+
}),
|
|
34676
|
+
execFileAsync4("git", ["-C", this.options.worktreePath, "rev-parse", "HEAD"]).then(({ stdout: stdout6 }) => stdout6.trim())
|
|
34677
|
+
]);
|
|
34678
|
+
const pr = restore.lifecycle?.pr;
|
|
34679
|
+
if (restore.lifecycle?.checks !== "passing" || !pr?.number || !pr.headSha || pr.headSha !== localHead)
|
|
34680
|
+
return CORNER_REVIEWER_UNSTABLE_HEAD_INSTRUCTION;
|
|
34681
|
+
return [
|
|
34682
|
+
"Current stable reviewer target for this active turn; it supersedes any older head in the trigger or transcript:",
|
|
34683
|
+
cornerReviewerInstruction({
|
|
34684
|
+
...input,
|
|
34685
|
+
pullRequestNumber: pr.number,
|
|
34686
|
+
headSha: pr.headSha
|
|
34687
|
+
})
|
|
34688
|
+
].join("\n");
|
|
34689
|
+
} catch {
|
|
34690
|
+
return CORNER_REVIEWER_UNSTABLE_HEAD_INSTRUCTION;
|
|
34691
|
+
}
|
|
34692
|
+
}
|
|
34655
34693
|
/** The scheduler seam: `queue-wait` closes when a slot buys a session. */
|
|
34656
34694
|
lifecycle(trace) {
|
|
34657
34695
|
return {
|
|
@@ -34757,10 +34795,11 @@ var MonolithCornerTurnLoop = class {
|
|
|
34757
34795
|
throw new Error("corner turn stopped for daemon handoff");
|
|
34758
34796
|
this.busy = true;
|
|
34759
34797
|
await this.syncBranch();
|
|
34760
|
-
const [conversation, roster, delivered] = await trace.measure("context-fetch", () => Promise.all([
|
|
34798
|
+
const [conversation, roster, delivered, activeReviewerInstruction] = await trace.measure("context-fetch", () => Promise.all([
|
|
34761
34799
|
api.execute("getRoomConversation", { roomId: cornerId, limit: 200 }),
|
|
34762
34800
|
this.roster(),
|
|
34763
|
-
this.attachmentDir && attachments.length ? deliverAttachments(attachments, join12(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : Promise.resolve([])
|
|
34801
|
+
this.attachmentDir && attachments.length ? deliverAttachments(attachments, join12(this.attachmentDir, requestId.replace(/[^\w-]/g, "_")), this.options.fetchImpl) : Promise.resolve([]),
|
|
34802
|
+
this.activeReviewerInstruction()
|
|
34764
34803
|
]));
|
|
34765
34804
|
const names = new Map(roster.members.map((member) => [member.identityId, member.name]));
|
|
34766
34805
|
const requestedBy = requester && !requester.name && names.get(requester.pubkey) ? { ...requester, name: names.get(requester.pubkey) } : requester;
|
|
@@ -34779,13 +34818,14 @@ var MonolithCornerTurnLoop = class {
|
|
|
34779
34818
|
${this.options.objective}`,
|
|
34780
34819
|
WarmTranscript.render(this.warmTranscript.select(this.sessionId, transcriptRows), "Corner transcript:", "New in the corner since your last turn (the earlier transcript is already in this session):"),
|
|
34781
34820
|
roomMentionDirectory(roster, this.agent.publicKey),
|
|
34821
|
+
activeReviewerInstruction,
|
|
34782
34822
|
[
|
|
34783
34823
|
...sourceMessageId ? [`Reaction target message id: ${sourceMessageId}`] : [],
|
|
34784
34824
|
`Newest trigger:
|
|
34785
34825
|
${trigger}`,
|
|
34786
34826
|
...attachmentPromptLines(attachments, delivered, this.acceptsImages())
|
|
34787
34827
|
].join("\n"),
|
|
34788
|
-
this.options.repository ? "Continue the objective. Obey the PR checks and human hold rules in your session instructions." : "Continue the objective. Attach completed files
|
|
34828
|
+
this.options.repository ? "Continue the objective. Obey the PR checks and human hold rules in your session instructions." : "Continue the objective. Attach completed files; only a human can close this corner.",
|
|
34789
34829
|
MAINTAIN_ASSIGNED_IDENTITY_DIRECTIVE
|
|
34790
34830
|
].filter(Boolean).join("\n\n");
|
|
34791
34831
|
const stream = new AgentTurnStream({
|
|
@@ -34926,7 +34966,9 @@ ${trigger}`,
|
|
|
34926
34966
|
this.lastDeliveryNudgeState = deliveryState;
|
|
34927
34967
|
replyBeforeNudge = durableReplyText(result.agentText);
|
|
34928
34968
|
await flushToolCalls(result.toolCalls, "");
|
|
34929
|
-
|
|
34969
|
+
if (this.reviewerInstructionInput)
|
|
34970
|
+
await this.syncBranch();
|
|
34971
|
+
result = await runPrompt(this.reviewerHandle ? await this.activeReviewerInstruction() ?? this.cornerTurnEndNudge : checksTurn ? CORNER_YOLO_MERGE_NUDGE : CORNER_DELIVERY_NUDGE);
|
|
34930
34972
|
trace.promptSettled();
|
|
34931
34973
|
explained = await this.explainEmpty(result);
|
|
34932
34974
|
}
|
|
@@ -35784,6 +35826,7 @@ var RoomRuntimeCoordinator = class {
|
|
|
35784
35826
|
});
|
|
35785
35827
|
this.options.daemonApi.setConfigChangedListener?.(() => {
|
|
35786
35828
|
void this.scheduler.suspendIdle().catch((error) => console.error("[body] config-change session restart failed", error));
|
|
35829
|
+
void Promise.resolve(this.options.onConfigChanged?.()).catch((error) => console.error("[body] config-change catalog refresh failed", error));
|
|
35787
35830
|
});
|
|
35788
35831
|
this.options.daemonApi.setHiccupRestartListener?.((attempt) => {
|
|
35789
35832
|
this.options.onHiccupRestart?.(attempt);
|
|
@@ -38211,8 +38254,6 @@ async function collectConnectWizard(prompts = clackPrompts, loadModels = loadCon
|
|
|
38211
38254
|
return (picked ?? "").trim();
|
|
38212
38255
|
};
|
|
38213
38256
|
const askEffort = async (catalog2, forHarness, model2, forProvider, forKey) => {
|
|
38214
|
-
if (!catalog2.effort)
|
|
38215
|
-
return void 0;
|
|
38216
38257
|
let axis = catalog2.effort;
|
|
38217
38258
|
if (model2 !== catalog2.currentValue) {
|
|
38218
38259
|
const reread = await loadModels({
|
|
@@ -38224,7 +38265,7 @@ async function collectConnectWizard(prompts = clackPrompts, loadModels = loadCon
|
|
|
38224
38265
|
}).catch(() => void 0);
|
|
38225
38266
|
axis = reread?.effort ?? axis;
|
|
38226
38267
|
}
|
|
38227
|
-
if (!axis
|
|
38268
|
+
if (!axis?.options.length)
|
|
38228
38269
|
return void 0;
|
|
38229
38270
|
const picked = await prompts.select({
|
|
38230
38271
|
message: brass("Choose reasoning effort"),
|
|
@@ -39394,10 +39435,27 @@ async function runStoredDaemon(pathOrPointer) {
|
|
|
39394
39435
|
scratchSweepTimer.unref();
|
|
39395
39436
|
let ready = false;
|
|
39396
39437
|
let connectorLoop;
|
|
39438
|
+
let catalogRefresh;
|
|
39439
|
+
const refreshCatalog = () => {
|
|
39440
|
+
catalogRefresh ??= syncAgentModelCatalog({
|
|
39441
|
+
api: daemonApi,
|
|
39442
|
+
agent,
|
|
39443
|
+
agentEnv: config.agentEnv,
|
|
39444
|
+
agentId: runtime.agent.publicKey,
|
|
39445
|
+
workspaceId: runtime.communityId,
|
|
39446
|
+
runtimeDir,
|
|
39447
|
+
...runtime.modelSelection ? { runtimeSelection: runtime.modelSelection } : {},
|
|
39448
|
+
force: true
|
|
39449
|
+
}).then(() => void 0).finally(() => {
|
|
39450
|
+
catalogRefresh = void 0;
|
|
39451
|
+
});
|
|
39452
|
+
return catalogRefresh;
|
|
39453
|
+
};
|
|
39397
39454
|
let stoppingStatus = "daemon stopped";
|
|
39398
39455
|
try {
|
|
39399
39456
|
const core = new ThinDaemonCore(runtime, configPath, config, {
|
|
39400
39457
|
daemonApi,
|
|
39458
|
+
onConfigChanged: refreshCatalog,
|
|
39401
39459
|
onHiccupRestart: (attempt) => {
|
|
39402
39460
|
const delay = hiccupBackoffMs(attempt);
|
|
39403
39461
|
console.warn(`[thin-core] hiccup restart attempt ${attempt}; exiting so systemd can start a fresh helper`);
|