thoth-agents 0.4.1 → 0.4.2

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.
@@ -19,6 +19,7 @@ import {
19
19
  CONFIRMED_OPENAI_SUBAGENT_PRESET,
20
20
  DEFAULT_MODELS,
21
21
  PI_SPECIALIST_ROLES,
22
+ SUBAGENT_NAMES,
22
23
  claudeCodeSubagentType,
23
24
  ensureConfigDir,
24
25
  findPackageRoot,
@@ -9341,6 +9342,37 @@ async function getModelOptions(harness) {
9341
9342
 
9342
9343
  // src/cli/tui/operations.ts
9343
9344
  import { existsSync as existsSync17, readFileSync as readFileSync14 } from "fs";
9345
+
9346
+ // src/cli/model-defaults.ts
9347
+ function getShippedModelRoles(harness) {
9348
+ if (harness === "opencode") {
9349
+ return ALL_AGENT_NAMES.map((role) => ({
9350
+ role,
9351
+ model: getDefaultOpenCodeModel(role),
9352
+ effort: { kind: "effort", value: getDefaultOpenCodeVariant(role) }
9353
+ }));
9354
+ }
9355
+ return SUBAGENT_NAMES.map((role) => {
9356
+ if (harness === "claude") {
9357
+ return {
9358
+ role,
9359
+ model: CLAUDE_CODE_SUBAGENT_DEFAULT_MODELS[role],
9360
+ effort: {
9361
+ kind: "effort",
9362
+ value: CLAUDE_CODE_SUBAGENT_DEFAULT_EFFORTS[role]
9363
+ }
9364
+ };
9365
+ }
9366
+ const preset = CONFIRMED_OPENAI_SUBAGENT_PRESET[role];
9367
+ return {
9368
+ role,
9369
+ model: harness === "pi" ? `openai-codex/${preset.model}` : preset.model,
9370
+ effort: { kind: "effort", value: preset.effort }
9371
+ };
9372
+ });
9373
+ }
9374
+
9375
+ // src/cli/tui/operations.ts
9344
9376
  var context = { cwd: process.cwd() };
9345
9377
  var codexContext = { cwd: process.cwd() };
9346
9378
  var claudeCodeContext = {
@@ -9354,15 +9386,7 @@ var opencodeModelRoles = ALL_AGENT_NAMES.map(
9354
9386
  effort: { kind: "effort", value: getDefaultOpenCodeVariant(role) }
9355
9387
  })
9356
9388
  );
9357
- var codexModelRoles = CODEX_ROLE_NAMES.map(
9358
- (role) => ({
9359
- role,
9360
- model: "gpt-5.4-mini"
9361
- })
9362
- );
9363
- var codexDefaultModels = new Map(
9364
- codexModelRoles.map((role) => [role.role, role.model])
9365
- );
9389
+ var codexModelRoles = getShippedModelRoles("codex");
9366
9390
  function codexInstallConfig(source, dryRun) {
9367
9391
  return {
9368
9392
  dryRun,
@@ -9378,20 +9402,22 @@ function codexInstallConfig(source, dryRun) {
9378
9402
  function getCodexModelRoles(source = codexContext) {
9379
9403
  try {
9380
9404
  const plan = buildCodexSetupPlan(codexInstallConfig(source, true));
9381
- return CODEX_ROLE_NAMES.map((role) => {
9382
- const item = plan.items.find(
9383
- (candidate) => candidate.action === "write-role-toml" && candidate.role === role
9384
- );
9385
- const content = item && existsSync17(item.targetPath) ? readFileSync14(item.targetPath, "utf8") : item?.content;
9386
- const effort = content ? parseRoleTomlEffort(content) : void 0;
9387
- return {
9388
- role,
9389
- model: (content ? parseRoleTomlModel(content) : void 0) ?? codexDefaultModels.get(role) ?? "gpt-5.4-mini",
9390
- effort: effort ? { kind: "effort", value: effort } : { kind: "inherit" }
9391
- };
9392
- });
9405
+ return getShippedModelRoles("codex").map(
9406
+ ({ role, model: defaultModel }) => {
9407
+ const item = plan.items.find(
9408
+ (candidate) => candidate.action === "write-role-toml" && candidate.role === role
9409
+ );
9410
+ const content = item && existsSync17(item.targetPath) ? readFileSync14(item.targetPath, "utf8") : item?.content;
9411
+ const effort = content ? parseRoleTomlEffort(content) : void 0;
9412
+ return {
9413
+ role,
9414
+ model: (content ? parseRoleTomlModel(content) : void 0) ?? defaultModel,
9415
+ effort: effort ? { kind: "effort", value: effort } : { kind: "inherit" }
9416
+ };
9417
+ }
9418
+ );
9393
9419
  } catch {
9394
- return codexModelRoles.map((role) => ({ ...role }));
9420
+ return getShippedModelRoles("codex");
9395
9421
  }
9396
9422
  }
9397
9423
  function getClaudeCodeModelRoles(_source = claudeCodeContext) {
@@ -9432,20 +9458,32 @@ function getOpenCodeModelRoles() {
9432
9458
  };
9433
9459
  });
9434
9460
  }
9435
- function buildTuiModelPlan(harness, roles) {
9461
+ function buildTuiModelPlan(harness, roles, source = context) {
9436
9462
  if (harness === "opencode") {
9437
- return buildOpenCodeModelPlan({ harness, dryRun: true, roles }, context);
9463
+ return buildOpenCodeModelPlan({ harness, dryRun: true, roles }, source);
9438
9464
  }
9439
9465
  if (harness === "claude") {
9440
- return buildClaudeCodeModelPlan(
9441
- { harness, dryRun: true, roles },
9442
- claudeCodeContext
9443
- );
9466
+ return buildClaudeCodeModelPlan({ harness, dryRun: true, roles }, source);
9444
9467
  }
9445
9468
  if (harness === "pi") {
9446
- return buildPiModelPlan({ harness, dryRun: true, roles }, context);
9469
+ return buildPiModelPlan({ harness, dryRun: true, roles }, source);
9447
9470
  }
9448
- return buildCodexModelPlan({ harness, dryRun: true, roles }, codexContext);
9471
+ return buildCodexModelPlan({ harness, dryRun: true, roles }, source);
9472
+ }
9473
+ function buildRestoreModelPlan(harness, options, source = context) {
9474
+ const roles = getShippedModelRoles(harness).map((role) => {
9475
+ const catalogId = harness === "codex" ? `openai/${role.model}` : harness === "pi" ? role.model.replace(/^openai-codex\//, "openai/") : role.model;
9476
+ const option = options.find((candidate) => candidate.id === role.model) ?? options.find((candidate) => candidate.catalogId === catalogId);
9477
+ return {
9478
+ ...role,
9479
+ ...option ? {
9480
+ provider: option.provider,
9481
+ catalogId: option.catalogId,
9482
+ availableEfforts: [...option.efforts]
9483
+ } : {}
9484
+ };
9485
+ });
9486
+ return buildTuiModelPlan(harness, roles, source);
9449
9487
  }
9450
9488
  var defaultTuiOperations = {
9451
9489
  status(harness, evidence) {
@@ -9501,6 +9539,9 @@ var defaultTuiOperations = {
9501
9539
  modelPlan(harness, roles) {
9502
9540
  return buildTuiModelPlan(harness, roles);
9503
9541
  },
9542
+ restoreModelPlan(harness, options) {
9543
+ return buildRestoreModelPlan(harness, options);
9544
+ },
9504
9545
  apply(plan) {
9505
9546
  if (plan.harness === "opencode") return applyOpenCodePlan(plan);
9506
9547
  if (plan.harness === "claude") return applyClaudeCodePlan(plan);
package/dist/cli/index.js CHANGED
@@ -59,7 +59,7 @@ import {
59
59
  normalizeEffortSelection,
60
60
  recordHarnessInstallCompletion,
61
61
  syncOpenCodeOwnedSkills
62
- } from "../chunk-2D7E7GMP.js";
62
+ } from "../chunk-WCLUZZHI.js";
63
63
  import "../chunk-62L3ORXN.js";
64
64
  import {
65
65
  piAdapter
@@ -0,0 +1,4 @@
1
+ import type { HarnessId } from '../harness/types';
2
+ import type { ModelRoleInput } from './operations/types';
3
+ /** Shipped recommendations, independent of installed configuration. */
4
+ export declare function getShippedModelRoles(harness: HarnessId): ModelRoleInput[];
@@ -2,7 +2,7 @@ import {
2
2
  defaultTuiOperations,
3
3
  effortChoicesForModel,
4
4
  listOperationHarnesses
5
- } from "../../chunk-2D7E7GMP.js";
5
+ } from "../../chunk-WCLUZZHI.js";
6
6
  import "../../chunk-62L3ORXN.js";
7
7
  import "../../chunk-2U5MBLLV.js";
8
8
  import "../../chunk-EFGSGPYM.js";
@@ -875,6 +875,7 @@ function App({
875
875
  const providerEvidenceRequest = useRef(0);
876
876
  const [plan, setPlan] = useState();
877
877
  const [result, setResult] = useState();
878
+ const [restoringDefaults, setRestoringDefaults] = useState(false);
878
879
  const [previewAction, setPreviewAction] = useState(
879
880
  "cancel"
880
881
  );
@@ -948,7 +949,7 @@ function App({
948
949
  const choiceSelected = selectedModelIndex < 0 ? 0 : selectedModelIndex;
949
950
  const dirtyRoles = rolesForModelPlan(modelRows);
950
951
  const rolesToApply = dirtyRoles.length > 0 ? dirtyRoles : rolesForModelPlan(modelRows, true);
951
- const modelActions = dirtyRoles.length > 0 ? ["Preview changes", "Apply", "Back"] : ["Apply", "Back"];
952
+ const modelActions = dirtyRoles.length > 0 ? ["Preview changes", "Apply", "Restore defaults", "Back"] : ["Apply", "Restore defaults", "Back"];
952
953
  const modelMenuItems = [
953
954
  ...modelRows.map((role) => ({
954
955
  id: role.role,
@@ -990,6 +991,7 @@ function App({
990
991
  }
991
992
  function openPlan(harness, action, backView = "harness") {
992
993
  setActiveHarness(harness);
994
+ setRestoringDefaults(false);
993
995
  setPlan(operations.plan(harness, action));
994
996
  setResult(void 0);
995
997
  setPreviewAction("cancel");
@@ -1037,6 +1039,7 @@ function App({
1037
1039
  setView("effortChoice");
1038
1040
  }
1039
1041
  function previewModelChanges(applyImmediately) {
1042
+ setRestoringDefaults(false);
1040
1043
  const nextPlan = operations.modelPlan(modelHarness, rolesToApply);
1041
1044
  setPlan(nextPlan);
1042
1045
  setPreviewAction(applyImmediately ? "apply" : "cancel");
@@ -1067,6 +1070,26 @@ function App({
1067
1070
  setResult(void 0);
1068
1071
  setView("preview");
1069
1072
  }
1073
+ function previewDefaultModels() {
1074
+ setPlan(operations.restoreModelPlan(modelHarness, modelOptions));
1075
+ setRestoringDefaults(true);
1076
+ setResult(void 0);
1077
+ setPreviewAction("cancel");
1078
+ setPreviewBackView("modelRoles");
1079
+ setView("preview");
1080
+ }
1081
+ function applyPreview() {
1082
+ if (!plan?.canApply || restoringDefaults && result?.applied) return;
1083
+ const applied = operations.apply(plan);
1084
+ setResult(applied);
1085
+ if (restoringDefaults && applied.applied) {
1086
+ setModelRoles(operations.modelRoles(modelHarness));
1087
+ setEditedModels({});
1088
+ setEditedEfforts({});
1089
+ setModelResult(void 0);
1090
+ setModelSelected(0);
1091
+ }
1092
+ }
1070
1093
  useInput((input, key) => {
1071
1094
  if (view === "modelEdit") {
1072
1095
  if (key.escape) {
@@ -1286,6 +1309,7 @@ function App({
1286
1309
  if (action === "Back") setView("manageHarness");
1287
1310
  if (action === "Preview changes") previewModelChanges(false);
1288
1311
  if (action === "Apply") previewModelChanges(true);
1312
+ if (action === "Restore defaults") previewDefaultModels();
1289
1313
  }
1290
1314
  return;
1291
1315
  }
@@ -1301,14 +1325,14 @@ function App({
1301
1325
  }
1302
1326
  if (input === "a" && plan?.canApply) {
1303
1327
  setPreviewAction("apply");
1304
- setResult(operations.apply(plan));
1328
+ applyPreview();
1305
1329
  }
1306
1330
  if (input === "c") goBack();
1307
1331
  if (key.return && plan) {
1308
1332
  if (previewAction === "cancel" || !plan.canApply) {
1309
1333
  goBack();
1310
1334
  } else {
1311
- setResult(operations.apply(plan));
1335
+ applyPreview();
1312
1336
  }
1313
1337
  }
1314
1338
  }
@@ -1465,10 +1489,11 @@ function App({
1465
1489
  /* @__PURE__ */ jsx8(
1466
1490
  Header,
1467
1491
  {
1468
- title: plan.title,
1492
+ title: restoringDefaults ? "Restore default models" : plan.title,
1469
1493
  subtitle: "Enter selects. Escape or c returns one level."
1470
1494
  }
1471
1495
  ),
1496
+ restoringDefaults ? /* @__PURE__ */ jsx8(Text8, { color: theme.warning, children: "Replace all managed role models and reasoning efforts with this package's defaults. Review the values and targets below. Apply writes changes; Cancel keeps your current settings." }) : null,
1472
1497
  /* @__PURE__ */ jsx8(
1473
1498
  PlanPreview,
1474
1499
  {
@@ -1,7 +1,7 @@
1
1
  import type { HarnessId, ProviderCapabilityEvidence, ProviderEvidenceInput } from '../../harness/types';
2
2
  import { type ClaudeCodeOperationContext } from '../operations/claude-code';
3
3
  import { type CodexOperationContext } from '../operations/codex';
4
- import type { HarnessStatusReport, ModelRoleInput, OperationApplyResult, OperationPlan } from '../operations/types';
4
+ import type { HarnessStatusReport, ModelRoleInput, OperationApplyResult, OperationContext, OperationPlan } from '../operations/types';
5
5
  import { type ModelOption } from './model-catalog';
6
6
  export type TuiAction = 'status' | 'list' | 'install' | 'update' | 'sync' | 'model';
7
7
  export interface TuiOperations {
@@ -11,6 +11,7 @@ export interface TuiOperations {
11
11
  modelOptions(harness: HarnessId): Promise<ModelOption[]>;
12
12
  plan(harness: HarnessId, action: Exclude<TuiAction, 'status' | 'list'>): OperationPlan;
13
13
  modelPlan(harness: HarnessId, roles: ModelRoleInput[]): OperationPlan;
14
+ restoreModelPlan(harness: HarnessId, options: readonly ModelOption[]): OperationPlan;
14
15
  apply(plan: OperationPlan): OperationApplyResult;
15
16
  }
16
17
  export declare const opencodeModelRoles: ModelRoleInput[];
@@ -19,4 +20,5 @@ export declare function getCodexModelRoles(source?: CodexOperationContext): Mode
19
20
  export declare function getClaudeCodeModelRoles(_source?: ClaudeCodeOperationContext): ModelRoleInput[];
20
21
  export declare function getPiModelRoles(): ModelRoleInput[];
21
22
  export declare function getOpenCodeModelRoles(): ModelRoleInput[];
23
+ export declare function buildRestoreModelPlan(harness: HarnessId, options: readonly ModelOption[], source?: OperationContext): OperationPlan;
22
24
  export declare const defaultTuiOperations: TuiOperations;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thoth-agents",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Adaptive multi-harness orchestration with seven roles, runtime-autonomous Spec Kit-compatible SDD routes, and external provider boundaries.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thoth-agents",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Adaptive multi-harness agent pack with seven roles and a runtime-autonomous Spec Kit-compatible SDD bundle for Claude Code.",
5
5
  "author": {
6
6
  "name": "thoth-agents"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thoth-agents",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Bundled Spec Kit-compatible SDD skills and MCP configuration; the seven-role global Codex layer requires thoth-agents CLI setup.",
5
5
  "skills": "./skills/",
6
6
  "mcpServers": "./codex.mcp.json"