@gethmy/agent 1.46.0 → 1.47.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/dist/cli.js +128 -17
- package/dist/index.js +128 -17
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3566,12 +3566,12 @@ var init_types = __esm(() => {
|
|
|
3566
3566
|
postSummary: true
|
|
3567
3567
|
},
|
|
3568
3568
|
claude: {
|
|
3569
|
-
model: "claude-opus-5",
|
|
3569
|
+
model: "claude-opus-5-5",
|
|
3570
3570
|
escalateModel: "claude-fable-5-1",
|
|
3571
3571
|
escalateAfterAttempts: 2,
|
|
3572
3572
|
tiers: {
|
|
3573
3573
|
simple: "claude-sonnet-5",
|
|
3574
|
-
advanced: "claude-opus-5",
|
|
3574
|
+
advanced: "claude-opus-5-5",
|
|
3575
3575
|
research: "claude-fable-5-1"
|
|
3576
3576
|
},
|
|
3577
3577
|
scoreBands: DEFAULT_SCORE_BANDS,
|
|
@@ -11595,6 +11595,15 @@ function resolveEffectiveAgentConfig(cfg, ws) {
|
|
|
11595
11595
|
const withWorkspace = ws ? mergeAgentConfig(DEFAULT_AGENT_CONFIG, workspaceConfigToPartial(ws)) : DEFAULT_AGENT_CONFIG;
|
|
11596
11596
|
return mergeAgentConfig(mergeAgentConfig(withWorkspace, cfg.agentOverrides), cfg.repoAgentOverrides);
|
|
11597
11597
|
}
|
|
11598
|
+
function withdrawnMapFrom(models) {
|
|
11599
|
+
const withdrawn = {};
|
|
11600
|
+
for (const m of models) {
|
|
11601
|
+
if (m.status === "withdrawn" && m.replaced_by) {
|
|
11602
|
+
withdrawn[m.id] = m.replaced_by;
|
|
11603
|
+
}
|
|
11604
|
+
}
|
|
11605
|
+
return withdrawn;
|
|
11606
|
+
}
|
|
11598
11607
|
var init_workspace_model_config = __esm(() => {
|
|
11599
11608
|
init_config_merge();
|
|
11600
11609
|
init_types();
|
|
@@ -14085,16 +14094,7 @@ class Pool {
|
|
|
14085
14094
|
const { config: wsConfig, platformDefaults } = await client.getWorkspaceModelConfig(workspaceId);
|
|
14086
14095
|
return layerPlatformDefaults(platformDefaults, wsConfig);
|
|
14087
14096
|
}) : undefined;
|
|
14088
|
-
const modelCatalog = daemonConfig ? new WorkspaceModelCache(async () =>
|
|
14089
|
-
const { models } = await client.getModelCatalog();
|
|
14090
|
-
const withdrawn = {};
|
|
14091
|
-
for (const m of models) {
|
|
14092
|
-
if (m.status === "withdrawn" && m.replaced_by) {
|
|
14093
|
-
withdrawn[m.id] = m.replaced_by;
|
|
14094
|
-
}
|
|
14095
|
-
}
|
|
14096
|
-
return withdrawn;
|
|
14097
|
-
}) : undefined;
|
|
14097
|
+
const modelCatalog = daemonConfig ? new WorkspaceModelCache(async () => withdrawnMapFrom((await client.getModelCatalog()).models)) : undefined;
|
|
14098
14098
|
const reportedConfig = daemonConfig ? new ReportedConfigCache(client, effectiveModelReport(config)) : undefined;
|
|
14099
14099
|
for (let i = 0;i < config.poolSize; i++) {
|
|
14100
14100
|
this.implWorkers.push(new Worker(i, config, client, this.identity, () => {
|
|
@@ -16230,6 +16230,93 @@ var init_reconcile = __esm(() => {
|
|
|
16230
16230
|
init_types();
|
|
16231
16231
|
});
|
|
16232
16232
|
|
|
16233
|
+
// src/startup-model.ts
|
|
16234
|
+
function describeStartupModel(config, layers, withdrawn) {
|
|
16235
|
+
const workspace = layers?.workspace ?? null;
|
|
16236
|
+
const platform = layers?.platform ?? null;
|
|
16237
|
+
const database = layerPlatformDefaults(platform, workspace);
|
|
16238
|
+
const claude = resolveEffectiveAgentConfig(config, database).claude;
|
|
16239
|
+
const pinned = ownObject(config.agentOverrides, "claude");
|
|
16240
|
+
const pinnedTiers = ownObject(pinned, "tiers");
|
|
16241
|
+
const pinnedModel = ownString(pinned, "model");
|
|
16242
|
+
let source = "built-in default";
|
|
16243
|
+
if (pinnedModel)
|
|
16244
|
+
source = "config.json";
|
|
16245
|
+
else if (workspace?.implement_model)
|
|
16246
|
+
source = "workspace";
|
|
16247
|
+
else if (platform?.implement_model)
|
|
16248
|
+
source = "platform";
|
|
16249
|
+
const warnings = [];
|
|
16250
|
+
const pins = [
|
|
16251
|
+
["claude.model", pinnedModel, database?.implement_model],
|
|
16252
|
+
[
|
|
16253
|
+
"claude.escalateModel",
|
|
16254
|
+
ownString(pinned, "escalateModel"),
|
|
16255
|
+
database?.escalate_model
|
|
16256
|
+
],
|
|
16257
|
+
...TIERS.map((tier) => [
|
|
16258
|
+
`claude.tiers.${tier}`,
|
|
16259
|
+
ownString(pinnedTiers, tier),
|
|
16260
|
+
database?.tiers?.[tier]
|
|
16261
|
+
])
|
|
16262
|
+
];
|
|
16263
|
+
for (const [key, local, db] of pins) {
|
|
16264
|
+
if (local && db && local !== db) {
|
|
16265
|
+
warnings.push(`config.json pins ${key} to "${local}", which overrides the database default "${db}" — remove it from config.json to follow the app's model settings`);
|
|
16266
|
+
}
|
|
16267
|
+
}
|
|
16268
|
+
const effective = [
|
|
16269
|
+
["claude.model", claude.model],
|
|
16270
|
+
["claude.escalateModel", claude.escalateModel],
|
|
16271
|
+
...TIERS.map((tier) => [`claude.tiers.${tier}`, claude.tiers[tier]])
|
|
16272
|
+
];
|
|
16273
|
+
for (const [key, id] of effective) {
|
|
16274
|
+
const replacement = withdrawn?.[id];
|
|
16275
|
+
if (replacement) {
|
|
16276
|
+
warnings.push(`${key} resolves to "${id}", which is withdrawn in the model catalog — runs use its replacement "${replacement}"; update the setting to match`);
|
|
16277
|
+
}
|
|
16278
|
+
}
|
|
16279
|
+
return {
|
|
16280
|
+
model: claude.model,
|
|
16281
|
+
escalateModel: claude.escalateModel,
|
|
16282
|
+
reviewModel: config.agent.claude.reviewModel,
|
|
16283
|
+
source,
|
|
16284
|
+
resolved: layers !== null && withdrawn !== null,
|
|
16285
|
+
warnings
|
|
16286
|
+
};
|
|
16287
|
+
}
|
|
16288
|
+
async function resolveStartupModel(config, client) {
|
|
16289
|
+
const [layers, withdrawn] = await Promise.all([
|
|
16290
|
+
client.getWorkspaceModelConfig(config.workspaceId).then(({ config: workspace, platformDefaults }) => ({
|
|
16291
|
+
workspace,
|
|
16292
|
+
platform: platformDefaults ?? null
|
|
16293
|
+
})).catch(() => null),
|
|
16294
|
+
client.getModelCatalog().then(({ models }) => withdrawnMapFrom(models)).catch(() => null)
|
|
16295
|
+
]);
|
|
16296
|
+
return describeStartupModel(config, layers, withdrawn);
|
|
16297
|
+
}
|
|
16298
|
+
function ownObject(source, key) {
|
|
16299
|
+
if (typeof source !== "object" || source === null)
|
|
16300
|
+
return {};
|
|
16301
|
+
const value = own(source, key);
|
|
16302
|
+
return typeof value === "object" && value !== null ? value : {};
|
|
16303
|
+
}
|
|
16304
|
+
function ownString(source, key) {
|
|
16305
|
+
const value = own(source, key);
|
|
16306
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
16307
|
+
}
|
|
16308
|
+
function startupModelLine(m) {
|
|
16309
|
+
const models = m.model === m.escalateModel ? m.model : `${m.model} → ${m.escalateModel} on retry/high · review ${m.reviewModel}`;
|
|
16310
|
+
const origin = m.resolved ? `from ${m.source}` : `from ${m.source}; database model settings unreachable, a pickup may resolve differently`;
|
|
16311
|
+
return `${models} (${origin})`;
|
|
16312
|
+
}
|
|
16313
|
+
var TIERS;
|
|
16314
|
+
var init_startup_model = __esm(() => {
|
|
16315
|
+
init_src();
|
|
16316
|
+
init_workspace_model_config();
|
|
16317
|
+
TIERS = ["simple", "advanced", "research"];
|
|
16318
|
+
});
|
|
16319
|
+
|
|
16233
16320
|
// src/startup-banner.ts
|
|
16234
16321
|
var exports_startup_banner = {};
|
|
16235
16322
|
__export(exports_startup_banner, {
|
|
@@ -16245,6 +16332,7 @@ function prettyBanner(config, version) {
|
|
|
16245
16332
|
let projectName;
|
|
16246
16333
|
let gitProvider;
|
|
16247
16334
|
let httpPort;
|
|
16335
|
+
let model;
|
|
16248
16336
|
let failed = false;
|
|
16249
16337
|
let rendered = false;
|
|
16250
16338
|
return {
|
|
@@ -16257,6 +16345,9 @@ function prettyBanner(config, version) {
|
|
|
16257
16345
|
setHttpPort(port) {
|
|
16258
16346
|
httpPort = port;
|
|
16259
16347
|
},
|
|
16348
|
+
setModel(resolved) {
|
|
16349
|
+
model = resolved;
|
|
16350
|
+
},
|
|
16260
16351
|
check(message) {
|
|
16261
16352
|
checks.push({ kind: "ok", message });
|
|
16262
16353
|
},
|
|
@@ -16278,6 +16369,7 @@ function prettyBanner(config, version) {
|
|
|
16278
16369
|
projectName,
|
|
16279
16370
|
gitProvider,
|
|
16280
16371
|
httpPort,
|
|
16372
|
+
model,
|
|
16281
16373
|
checks,
|
|
16282
16374
|
readyMessage: message
|
|
16283
16375
|
});
|
|
@@ -16287,12 +16379,13 @@ function prettyBanner(config, version) {
|
|
|
16287
16379
|
}
|
|
16288
16380
|
function jsonBanner(config, version) {
|
|
16289
16381
|
log45.info(TAG41, `Harmony Agent Daemon v${version} starting...`);
|
|
16290
|
-
log45.info(TAG41, `Project: ${config.projectId} | Pool: ${config.agent.poolSize} |
|
|
16382
|
+
log45.info(TAG41, `Project: ${config.projectId} | Pool: ${config.agent.poolSize} | Runner: ${config.agent.runner} | Pickup: ${config.agent.pickupColumns.join(", ")}`);
|
|
16291
16383
|
log45.info(TAG41, `Config: ${contextSourceLine(config)}`);
|
|
16292
16384
|
if (config.agent.review.enabled) {
|
|
16293
16385
|
log45.info(TAG41, `Review: enabled | Columns: ${config.agent.review.pickupColumns.join(", ")} | → ${config.agent.review.moveToColumn} / ${config.agent.review.failColumn}`);
|
|
16294
16386
|
}
|
|
16295
16387
|
let failed = false;
|
|
16388
|
+
let modelLogged = false;
|
|
16296
16389
|
return {
|
|
16297
16390
|
setProjectName(_name) {},
|
|
16298
16391
|
setGitProvider(provider) {
|
|
@@ -16301,6 +16394,10 @@ function jsonBanner(config, version) {
|
|
|
16301
16394
|
setHttpPort(port) {
|
|
16302
16395
|
log45.info(TAG41, `HTTP server on port ${port}`);
|
|
16303
16396
|
},
|
|
16397
|
+
setModel(resolved) {
|
|
16398
|
+
modelLogged = true;
|
|
16399
|
+
log45.info(TAG41, `Model: ${startupModelLine(resolved)}`);
|
|
16400
|
+
},
|
|
16304
16401
|
check(message) {
|
|
16305
16402
|
log45.info(TAG41, message);
|
|
16306
16403
|
},
|
|
@@ -16313,6 +16410,8 @@ function jsonBanner(config, version) {
|
|
|
16313
16410
|
async ready(message) {
|
|
16314
16411
|
if (failed)
|
|
16315
16412
|
return;
|
|
16413
|
+
if (!modelLogged)
|
|
16414
|
+
log45.info(TAG41, `Model: ${localModelLine(config)}`);
|
|
16316
16415
|
log45.info(TAG41, message);
|
|
16317
16416
|
}
|
|
16318
16417
|
};
|
|
@@ -16324,6 +16423,7 @@ function renderPretty(input) {
|
|
|
16324
16423
|
projectName,
|
|
16325
16424
|
gitProvider,
|
|
16326
16425
|
httpPort,
|
|
16426
|
+
model,
|
|
16327
16427
|
checks,
|
|
16328
16428
|
readyMessage
|
|
16329
16429
|
} = input;
|
|
@@ -16331,7 +16431,7 @@ function renderPretty(input) {
|
|
|
16331
16431
|
lines.push("");
|
|
16332
16432
|
lines.push(titleRule(`Harmony Agent Daemon v${version}`));
|
|
16333
16433
|
lines.push("");
|
|
16334
|
-
for (const row of configRows(config, projectName, gitProvider, httpPort)) {
|
|
16434
|
+
for (const row of configRows(config, projectName, gitProvider, httpPort, model)) {
|
|
16335
16435
|
lines.push(` ${dim(row.label.padEnd(9))} ${row.value}`);
|
|
16336
16436
|
}
|
|
16337
16437
|
lines.push("");
|
|
@@ -16345,7 +16445,7 @@ function renderPretty(input) {
|
|
|
16345
16445
|
return lines.join(`
|
|
16346
16446
|
`);
|
|
16347
16447
|
}
|
|
16348
|
-
function configRows(config, projectName, gitProvider, httpPort) {
|
|
16448
|
+
function configRows(config, projectName, gitProvider, httpPort, model) {
|
|
16349
16449
|
const rows = [];
|
|
16350
16450
|
const projectLabel = projectName ? `${projectName} (${shortenId(config.projectId)})` : shortenId(config.projectId);
|
|
16351
16451
|
rows.push({ label: "Project", value: projectLabel });
|
|
@@ -16354,8 +16454,7 @@ function configRows(config, projectName, gitProvider, httpPort) {
|
|
|
16354
16454
|
const reviewEnabled = config.agent.review.enabled;
|
|
16355
16455
|
const poolDesc = reviewEnabled ? `Pool ${config.agent.poolSize} impl + ${config.agent.review.poolSize} review` : `Pool ${config.agent.poolSize} impl`;
|
|
16356
16456
|
const flowDesc = reviewEnabled ? `Pickup ${config.agent.pickupColumns[0]} → ${config.agent.completion.moveToColumn} → ${config.agent.review.moveToColumn}` : `Pickup ${config.agent.pickupColumns.join(", ")}`;
|
|
16357
|
-
const
|
|
16358
|
-
const modelDesc = model === escalateModel ? model : `${model} → ${escalateModel} on retry/high · review ${reviewModel}`;
|
|
16457
|
+
const modelDesc = model ? startupModelLine(model) : localModelLine(config);
|
|
16359
16458
|
rows.push({
|
|
16360
16459
|
label: "Model",
|
|
16361
16460
|
value: `${modelDesc} · ${poolDesc} · ${flowDesc}`
|
|
@@ -16389,6 +16488,11 @@ function titleRule(title) {
|
|
|
16389
16488
|
const suffix = "─".repeat(Math.max(3, RULE_WIDTH - prefix.length - title.length - surround.length));
|
|
16390
16489
|
return dim(`${prefix}${title}${surround}${suffix}`);
|
|
16391
16490
|
}
|
|
16491
|
+
function localModelLine(config) {
|
|
16492
|
+
const { model, escalateModel, reviewModel } = config.agent.claude;
|
|
16493
|
+
const models = model === escalateModel ? model : `${model} → ${escalateModel} on retry/high · review ${reviewModel}`;
|
|
16494
|
+
return `${models} (local config only; database model settings not read)`;
|
|
16495
|
+
}
|
|
16392
16496
|
function runnerDesc(runner) {
|
|
16393
16497
|
return runner === "sdk" ? "sdk (Agent SDK)" : "cli (Claude CLI)";
|
|
16394
16498
|
}
|
|
@@ -16409,6 +16513,7 @@ function yellow(s) {
|
|
|
16409
16513
|
var TAG41 = "daemon", RULE_WIDTH = 70, ANSI;
|
|
16410
16514
|
var init_startup_banner = __esm(() => {
|
|
16411
16515
|
init_port_registry();
|
|
16516
|
+
init_startup_model();
|
|
16412
16517
|
ANSI = {
|
|
16413
16518
|
reset: "\x1B[0m",
|
|
16414
16519
|
dim: "\x1B[2m",
|
|
@@ -17766,6 +17871,11 @@ async function main() {
|
|
|
17766
17871
|
} catch (err) {
|
|
17767
17872
|
log50.warn(TAG46, `Could not report model config: ${err instanceof Error ? err.message : String(err)}`);
|
|
17768
17873
|
}
|
|
17874
|
+
const startupModel = await resolveStartupModel(config, client);
|
|
17875
|
+
banner.setModel(startupModel);
|
|
17876
|
+
for (const warning of startupModel.warnings) {
|
|
17877
|
+
banner.warn(warning);
|
|
17878
|
+
}
|
|
17769
17879
|
migrateConfigDir();
|
|
17770
17880
|
try {
|
|
17771
17881
|
migrateLegacyStateFile({
|
|
@@ -18088,6 +18198,7 @@ var init_src2 = __esm(() => {
|
|
|
18088
18198
|
init_recovery();
|
|
18089
18199
|
init_review_worktree();
|
|
18090
18200
|
init_startup_banner();
|
|
18201
|
+
init_startup_model();
|
|
18091
18202
|
init_state_migration();
|
|
18092
18203
|
init_state_store();
|
|
18093
18204
|
init_stream_parser_selftest();
|
package/dist/index.js
CHANGED
|
@@ -3565,12 +3565,12 @@ var init_types = __esm(() => {
|
|
|
3565
3565
|
postSummary: true
|
|
3566
3566
|
},
|
|
3567
3567
|
claude: {
|
|
3568
|
-
model: "claude-opus-5",
|
|
3568
|
+
model: "claude-opus-5-5",
|
|
3569
3569
|
escalateModel: "claude-fable-5-1",
|
|
3570
3570
|
escalateAfterAttempts: 2,
|
|
3571
3571
|
tiers: {
|
|
3572
3572
|
simple: "claude-sonnet-5",
|
|
3573
|
-
advanced: "claude-opus-5",
|
|
3573
|
+
advanced: "claude-opus-5-5",
|
|
3574
3574
|
research: "claude-fable-5-1"
|
|
3575
3575
|
},
|
|
3576
3576
|
scoreBands: DEFAULT_SCORE_BANDS,
|
|
@@ -11594,6 +11594,15 @@ function resolveEffectiveAgentConfig(cfg, ws) {
|
|
|
11594
11594
|
const withWorkspace = ws ? mergeAgentConfig(DEFAULT_AGENT_CONFIG, workspaceConfigToPartial(ws)) : DEFAULT_AGENT_CONFIG;
|
|
11595
11595
|
return mergeAgentConfig(mergeAgentConfig(withWorkspace, cfg.agentOverrides), cfg.repoAgentOverrides);
|
|
11596
11596
|
}
|
|
11597
|
+
function withdrawnMapFrom(models) {
|
|
11598
|
+
const withdrawn = {};
|
|
11599
|
+
for (const m of models) {
|
|
11600
|
+
if (m.status === "withdrawn" && m.replaced_by) {
|
|
11601
|
+
withdrawn[m.id] = m.replaced_by;
|
|
11602
|
+
}
|
|
11603
|
+
}
|
|
11604
|
+
return withdrawn;
|
|
11605
|
+
}
|
|
11597
11606
|
var init_workspace_model_config = __esm(() => {
|
|
11598
11607
|
init_config_merge();
|
|
11599
11608
|
init_types();
|
|
@@ -14084,16 +14093,7 @@ class Pool {
|
|
|
14084
14093
|
const { config: wsConfig, platformDefaults } = await client.getWorkspaceModelConfig(workspaceId);
|
|
14085
14094
|
return layerPlatformDefaults(platformDefaults, wsConfig);
|
|
14086
14095
|
}) : undefined;
|
|
14087
|
-
const modelCatalog = daemonConfig ? new WorkspaceModelCache(async () =>
|
|
14088
|
-
const { models } = await client.getModelCatalog();
|
|
14089
|
-
const withdrawn = {};
|
|
14090
|
-
for (const m of models) {
|
|
14091
|
-
if (m.status === "withdrawn" && m.replaced_by) {
|
|
14092
|
-
withdrawn[m.id] = m.replaced_by;
|
|
14093
|
-
}
|
|
14094
|
-
}
|
|
14095
|
-
return withdrawn;
|
|
14096
|
-
}) : undefined;
|
|
14096
|
+
const modelCatalog = daemonConfig ? new WorkspaceModelCache(async () => withdrawnMapFrom((await client.getModelCatalog()).models)) : undefined;
|
|
14097
14097
|
const reportedConfig = daemonConfig ? new ReportedConfigCache(client, effectiveModelReport(config)) : undefined;
|
|
14098
14098
|
for (let i = 0;i < config.poolSize; i++) {
|
|
14099
14099
|
this.implWorkers.push(new Worker(i, config, client, this.identity, () => {
|
|
@@ -16229,6 +16229,93 @@ var init_reconcile = __esm(() => {
|
|
|
16229
16229
|
init_types();
|
|
16230
16230
|
});
|
|
16231
16231
|
|
|
16232
|
+
// src/startup-model.ts
|
|
16233
|
+
function describeStartupModel(config, layers, withdrawn) {
|
|
16234
|
+
const workspace = layers?.workspace ?? null;
|
|
16235
|
+
const platform = layers?.platform ?? null;
|
|
16236
|
+
const database = layerPlatformDefaults(platform, workspace);
|
|
16237
|
+
const claude = resolveEffectiveAgentConfig(config, database).claude;
|
|
16238
|
+
const pinned = ownObject(config.agentOverrides, "claude");
|
|
16239
|
+
const pinnedTiers = ownObject(pinned, "tiers");
|
|
16240
|
+
const pinnedModel = ownString(pinned, "model");
|
|
16241
|
+
let source = "built-in default";
|
|
16242
|
+
if (pinnedModel)
|
|
16243
|
+
source = "config.json";
|
|
16244
|
+
else if (workspace?.implement_model)
|
|
16245
|
+
source = "workspace";
|
|
16246
|
+
else if (platform?.implement_model)
|
|
16247
|
+
source = "platform";
|
|
16248
|
+
const warnings = [];
|
|
16249
|
+
const pins = [
|
|
16250
|
+
["claude.model", pinnedModel, database?.implement_model],
|
|
16251
|
+
[
|
|
16252
|
+
"claude.escalateModel",
|
|
16253
|
+
ownString(pinned, "escalateModel"),
|
|
16254
|
+
database?.escalate_model
|
|
16255
|
+
],
|
|
16256
|
+
...TIERS.map((tier) => [
|
|
16257
|
+
`claude.tiers.${tier}`,
|
|
16258
|
+
ownString(pinnedTiers, tier),
|
|
16259
|
+
database?.tiers?.[tier]
|
|
16260
|
+
])
|
|
16261
|
+
];
|
|
16262
|
+
for (const [key, local, db] of pins) {
|
|
16263
|
+
if (local && db && local !== db) {
|
|
16264
|
+
warnings.push(`config.json pins ${key} to "${local}", which overrides the database default "${db}" — remove it from config.json to follow the app's model settings`);
|
|
16265
|
+
}
|
|
16266
|
+
}
|
|
16267
|
+
const effective = [
|
|
16268
|
+
["claude.model", claude.model],
|
|
16269
|
+
["claude.escalateModel", claude.escalateModel],
|
|
16270
|
+
...TIERS.map((tier) => [`claude.tiers.${tier}`, claude.tiers[tier]])
|
|
16271
|
+
];
|
|
16272
|
+
for (const [key, id] of effective) {
|
|
16273
|
+
const replacement = withdrawn?.[id];
|
|
16274
|
+
if (replacement) {
|
|
16275
|
+
warnings.push(`${key} resolves to "${id}", which is withdrawn in the model catalog — runs use its replacement "${replacement}"; update the setting to match`);
|
|
16276
|
+
}
|
|
16277
|
+
}
|
|
16278
|
+
return {
|
|
16279
|
+
model: claude.model,
|
|
16280
|
+
escalateModel: claude.escalateModel,
|
|
16281
|
+
reviewModel: config.agent.claude.reviewModel,
|
|
16282
|
+
source,
|
|
16283
|
+
resolved: layers !== null && withdrawn !== null,
|
|
16284
|
+
warnings
|
|
16285
|
+
};
|
|
16286
|
+
}
|
|
16287
|
+
async function resolveStartupModel(config, client) {
|
|
16288
|
+
const [layers, withdrawn] = await Promise.all([
|
|
16289
|
+
client.getWorkspaceModelConfig(config.workspaceId).then(({ config: workspace, platformDefaults }) => ({
|
|
16290
|
+
workspace,
|
|
16291
|
+
platform: platformDefaults ?? null
|
|
16292
|
+
})).catch(() => null),
|
|
16293
|
+
client.getModelCatalog().then(({ models }) => withdrawnMapFrom(models)).catch(() => null)
|
|
16294
|
+
]);
|
|
16295
|
+
return describeStartupModel(config, layers, withdrawn);
|
|
16296
|
+
}
|
|
16297
|
+
function ownObject(source, key) {
|
|
16298
|
+
if (typeof source !== "object" || source === null)
|
|
16299
|
+
return {};
|
|
16300
|
+
const value = own(source, key);
|
|
16301
|
+
return typeof value === "object" && value !== null ? value : {};
|
|
16302
|
+
}
|
|
16303
|
+
function ownString(source, key) {
|
|
16304
|
+
const value = own(source, key);
|
|
16305
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
16306
|
+
}
|
|
16307
|
+
function startupModelLine(m) {
|
|
16308
|
+
const models = m.model === m.escalateModel ? m.model : `${m.model} → ${m.escalateModel} on retry/high · review ${m.reviewModel}`;
|
|
16309
|
+
const origin = m.resolved ? `from ${m.source}` : `from ${m.source}; database model settings unreachable, a pickup may resolve differently`;
|
|
16310
|
+
return `${models} (${origin})`;
|
|
16311
|
+
}
|
|
16312
|
+
var TIERS;
|
|
16313
|
+
var init_startup_model = __esm(() => {
|
|
16314
|
+
init_src();
|
|
16315
|
+
init_workspace_model_config();
|
|
16316
|
+
TIERS = ["simple", "advanced", "research"];
|
|
16317
|
+
});
|
|
16318
|
+
|
|
16232
16319
|
// src/startup-banner.ts
|
|
16233
16320
|
var exports_startup_banner = {};
|
|
16234
16321
|
__export(exports_startup_banner, {
|
|
@@ -16244,6 +16331,7 @@ function prettyBanner(config, version) {
|
|
|
16244
16331
|
let projectName;
|
|
16245
16332
|
let gitProvider;
|
|
16246
16333
|
let httpPort;
|
|
16334
|
+
let model;
|
|
16247
16335
|
let failed = false;
|
|
16248
16336
|
let rendered = false;
|
|
16249
16337
|
return {
|
|
@@ -16256,6 +16344,9 @@ function prettyBanner(config, version) {
|
|
|
16256
16344
|
setHttpPort(port) {
|
|
16257
16345
|
httpPort = port;
|
|
16258
16346
|
},
|
|
16347
|
+
setModel(resolved) {
|
|
16348
|
+
model = resolved;
|
|
16349
|
+
},
|
|
16259
16350
|
check(message) {
|
|
16260
16351
|
checks.push({ kind: "ok", message });
|
|
16261
16352
|
},
|
|
@@ -16277,6 +16368,7 @@ function prettyBanner(config, version) {
|
|
|
16277
16368
|
projectName,
|
|
16278
16369
|
gitProvider,
|
|
16279
16370
|
httpPort,
|
|
16371
|
+
model,
|
|
16280
16372
|
checks,
|
|
16281
16373
|
readyMessage: message
|
|
16282
16374
|
});
|
|
@@ -16286,12 +16378,13 @@ function prettyBanner(config, version) {
|
|
|
16286
16378
|
}
|
|
16287
16379
|
function jsonBanner(config, version) {
|
|
16288
16380
|
log45.info(TAG41, `Harmony Agent Daemon v${version} starting...`);
|
|
16289
|
-
log45.info(TAG41, `Project: ${config.projectId} | Pool: ${config.agent.poolSize} |
|
|
16381
|
+
log45.info(TAG41, `Project: ${config.projectId} | Pool: ${config.agent.poolSize} | Runner: ${config.agent.runner} | Pickup: ${config.agent.pickupColumns.join(", ")}`);
|
|
16290
16382
|
log45.info(TAG41, `Config: ${contextSourceLine(config)}`);
|
|
16291
16383
|
if (config.agent.review.enabled) {
|
|
16292
16384
|
log45.info(TAG41, `Review: enabled | Columns: ${config.agent.review.pickupColumns.join(", ")} | → ${config.agent.review.moveToColumn} / ${config.agent.review.failColumn}`);
|
|
16293
16385
|
}
|
|
16294
16386
|
let failed = false;
|
|
16387
|
+
let modelLogged = false;
|
|
16295
16388
|
return {
|
|
16296
16389
|
setProjectName(_name) {},
|
|
16297
16390
|
setGitProvider(provider) {
|
|
@@ -16300,6 +16393,10 @@ function jsonBanner(config, version) {
|
|
|
16300
16393
|
setHttpPort(port) {
|
|
16301
16394
|
log45.info(TAG41, `HTTP server on port ${port}`);
|
|
16302
16395
|
},
|
|
16396
|
+
setModel(resolved) {
|
|
16397
|
+
modelLogged = true;
|
|
16398
|
+
log45.info(TAG41, `Model: ${startupModelLine(resolved)}`);
|
|
16399
|
+
},
|
|
16303
16400
|
check(message) {
|
|
16304
16401
|
log45.info(TAG41, message);
|
|
16305
16402
|
},
|
|
@@ -16312,6 +16409,8 @@ function jsonBanner(config, version) {
|
|
|
16312
16409
|
async ready(message) {
|
|
16313
16410
|
if (failed)
|
|
16314
16411
|
return;
|
|
16412
|
+
if (!modelLogged)
|
|
16413
|
+
log45.info(TAG41, `Model: ${localModelLine(config)}`);
|
|
16315
16414
|
log45.info(TAG41, message);
|
|
16316
16415
|
}
|
|
16317
16416
|
};
|
|
@@ -16323,6 +16422,7 @@ function renderPretty(input) {
|
|
|
16323
16422
|
projectName,
|
|
16324
16423
|
gitProvider,
|
|
16325
16424
|
httpPort,
|
|
16425
|
+
model,
|
|
16326
16426
|
checks,
|
|
16327
16427
|
readyMessage
|
|
16328
16428
|
} = input;
|
|
@@ -16330,7 +16430,7 @@ function renderPretty(input) {
|
|
|
16330
16430
|
lines.push("");
|
|
16331
16431
|
lines.push(titleRule(`Harmony Agent Daemon v${version}`));
|
|
16332
16432
|
lines.push("");
|
|
16333
|
-
for (const row of configRows(config, projectName, gitProvider, httpPort)) {
|
|
16433
|
+
for (const row of configRows(config, projectName, gitProvider, httpPort, model)) {
|
|
16334
16434
|
lines.push(` ${dim(row.label.padEnd(9))} ${row.value}`);
|
|
16335
16435
|
}
|
|
16336
16436
|
lines.push("");
|
|
@@ -16344,7 +16444,7 @@ function renderPretty(input) {
|
|
|
16344
16444
|
return lines.join(`
|
|
16345
16445
|
`);
|
|
16346
16446
|
}
|
|
16347
|
-
function configRows(config, projectName, gitProvider, httpPort) {
|
|
16447
|
+
function configRows(config, projectName, gitProvider, httpPort, model) {
|
|
16348
16448
|
const rows = [];
|
|
16349
16449
|
const projectLabel = projectName ? `${projectName} (${shortenId(config.projectId)})` : shortenId(config.projectId);
|
|
16350
16450
|
rows.push({ label: "Project", value: projectLabel });
|
|
@@ -16353,8 +16453,7 @@ function configRows(config, projectName, gitProvider, httpPort) {
|
|
|
16353
16453
|
const reviewEnabled = config.agent.review.enabled;
|
|
16354
16454
|
const poolDesc = reviewEnabled ? `Pool ${config.agent.poolSize} impl + ${config.agent.review.poolSize} review` : `Pool ${config.agent.poolSize} impl`;
|
|
16355
16455
|
const flowDesc = reviewEnabled ? `Pickup ${config.agent.pickupColumns[0]} → ${config.agent.completion.moveToColumn} → ${config.agent.review.moveToColumn}` : `Pickup ${config.agent.pickupColumns.join(", ")}`;
|
|
16356
|
-
const
|
|
16357
|
-
const modelDesc = model === escalateModel ? model : `${model} → ${escalateModel} on retry/high · review ${reviewModel}`;
|
|
16456
|
+
const modelDesc = model ? startupModelLine(model) : localModelLine(config);
|
|
16358
16457
|
rows.push({
|
|
16359
16458
|
label: "Model",
|
|
16360
16459
|
value: `${modelDesc} · ${poolDesc} · ${flowDesc}`
|
|
@@ -16388,6 +16487,11 @@ function titleRule(title) {
|
|
|
16388
16487
|
const suffix = "─".repeat(Math.max(3, RULE_WIDTH - prefix.length - title.length - surround.length));
|
|
16389
16488
|
return dim(`${prefix}${title}${surround}${suffix}`);
|
|
16390
16489
|
}
|
|
16490
|
+
function localModelLine(config) {
|
|
16491
|
+
const { model, escalateModel, reviewModel } = config.agent.claude;
|
|
16492
|
+
const models = model === escalateModel ? model : `${model} → ${escalateModel} on retry/high · review ${reviewModel}`;
|
|
16493
|
+
return `${models} (local config only; database model settings not read)`;
|
|
16494
|
+
}
|
|
16391
16495
|
function runnerDesc(runner) {
|
|
16392
16496
|
return runner === "sdk" ? "sdk (Agent SDK)" : "cli (Claude CLI)";
|
|
16393
16497
|
}
|
|
@@ -16408,6 +16512,7 @@ function yellow(s) {
|
|
|
16408
16512
|
var TAG41 = "daemon", RULE_WIDTH = 70, ANSI;
|
|
16409
16513
|
var init_startup_banner = __esm(() => {
|
|
16410
16514
|
init_port_registry();
|
|
16515
|
+
init_startup_model();
|
|
16411
16516
|
ANSI = {
|
|
16412
16517
|
reset: "\x1B[0m",
|
|
16413
16518
|
dim: "\x1B[2m",
|
|
@@ -17765,6 +17870,11 @@ async function main() {
|
|
|
17765
17870
|
} catch (err) {
|
|
17766
17871
|
log50.warn(TAG46, `Could not report model config: ${err instanceof Error ? err.message : String(err)}`);
|
|
17767
17872
|
}
|
|
17873
|
+
const startupModel = await resolveStartupModel(config, client);
|
|
17874
|
+
banner.setModel(startupModel);
|
|
17875
|
+
for (const warning of startupModel.warnings) {
|
|
17876
|
+
banner.warn(warning);
|
|
17877
|
+
}
|
|
17768
17878
|
migrateConfigDir();
|
|
17769
17879
|
try {
|
|
17770
17880
|
migrateLegacyStateFile({
|
|
@@ -18087,6 +18197,7 @@ var init_src2 = __esm(() => {
|
|
|
18087
18197
|
init_recovery();
|
|
18088
18198
|
init_review_worktree();
|
|
18089
18199
|
init_startup_banner();
|
|
18200
|
+
init_startup_model();
|
|
18090
18201
|
init_state_migration();
|
|
18091
18202
|
init_state_store();
|
|
18092
18203
|
init_stream_parser_selftest();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gethmy/agent",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.47.0",
|
|
4
4
|
"description": "Push-based agent daemon for Harmony — picks up assigned cards, builds them in isolated git worktrees, and opens PRs. It runs where you put it.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|