@gajae-code/coding-agent 0.17.4 → 0.17.5

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.
Files changed (84) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/types/config/autorouting-tier-map.d.ts +1031 -3
  3. package/dist/types/config/file-lock.d.ts +4 -2
  4. package/dist/types/config/model-registry.d.ts +3 -1
  5. package/dist/types/config/model-resolver.d.ts +1 -1
  6. package/dist/types/exec/bash-executor.d.ts +2 -0
  7. package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +11 -2
  8. package/dist/types/gjc-runtime/state-writer.d.ts +14 -1
  9. package/dist/types/harness-control-plane/control-endpoint.d.ts +4 -1
  10. package/dist/types/harness-control-plane/finalize.d.ts +14 -3
  11. package/dist/types/main.d.ts +1 -1
  12. package/dist/types/runtime-mcp/loader.d.ts +2 -0
  13. package/dist/types/runtime-mcp/manager.d.ts +13 -6
  14. package/dist/types/sdk/broker/broker.d.ts +4 -2
  15. package/dist/types/sdk/broker/ensure.d.ts +3 -0
  16. package/dist/types/sdk/broker/identity.d.ts +2 -0
  17. package/dist/types/sdk/broker/managed-task-dag.d.ts +1335 -0
  18. package/dist/types/sdk/broker/managed-task-verification.d.ts +37 -0
  19. package/dist/types/sdk/broker/spawn-authority.d.ts +8 -0
  20. package/dist/types/sdk/broker/startup-failure.d.ts +4 -0
  21. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +5 -1
  22. package/dist/types/sdk/prompt-deadline-flush.d.ts +2 -0
  23. package/dist/types/sdk/session.d.ts +3 -3
  24. package/dist/types/session/agent-session.d.ts +7 -2
  25. package/dist/types/task/types.d.ts +2 -0
  26. package/dist/types/tools/bash-interactive.d.ts +1 -0
  27. package/dist/types/tools/fetch.d.ts +10 -1
  28. package/dist/types/tools/subagent.d.ts +8 -1
  29. package/package.json +7 -7
  30. package/src/cli/public-command-registry.ts +8 -2
  31. package/src/cli/setup-cli.ts +1 -0
  32. package/src/cli/stats-cli.ts +11 -1
  33. package/src/config/autorouting-tier-map.ts +529 -3
  34. package/src/config/file-lock.ts +59 -14
  35. package/src/config/model-discovery-manager.ts +4 -4
  36. package/src/config/model-profile-activation.ts +83 -23
  37. package/src/config/model-registry.ts +72 -12
  38. package/src/config/model-resolver.ts +6 -1
  39. package/src/coordinator-mcp/question-state.ts +4 -1
  40. package/src/coordinator-mcp/server.ts +14 -6
  41. package/src/exec/bash-executor.ts +3 -0
  42. package/src/extensibility/gjc-plugins/runtime-adapters.ts +46 -8
  43. package/src/gjc-runtime/state-writer.ts +317 -6
  44. package/src/harness-control-plane/control-endpoint.ts +24 -6
  45. package/src/harness-control-plane/finalize.ts +312 -25
  46. package/src/harness-control-plane/owner.ts +323 -89
  47. package/src/internal-urls/docs-index.generated.ts +6 -4
  48. package/src/main.ts +69 -19
  49. package/src/modes/acp/acp-agent.ts +581 -37
  50. package/src/modes/components/gjc-bundle-settings.ts +21 -1
  51. package/src/modes/components/tool-status-header.ts +72 -6
  52. package/src/modes/controllers/runtime-mcp-command-controller.ts +1 -1
  53. package/src/runtime-mcp/loader.ts +6 -3
  54. package/src/runtime-mcp/manager.ts +177 -75
  55. package/src/sdk/broker/broker.ts +1057 -150
  56. package/src/sdk/broker/ensure.ts +21 -3
  57. package/src/sdk/broker/identity.ts +13 -0
  58. package/src/sdk/broker/managed-task-dag.ts +1927 -0
  59. package/src/sdk/broker/managed-task-verification.ts +642 -0
  60. package/src/sdk/broker/spawn-authority.ts +140 -7
  61. package/src/sdk/broker/startup-failure.ts +80 -1
  62. package/src/sdk/broker/transport.ts +1 -0
  63. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  64. package/src/sdk/bus/index.ts +22 -6
  65. package/src/sdk/bus/telegram-daemon-contract.ts +5 -1
  66. package/src/sdk/cli/session-cli.ts +18 -0
  67. package/src/sdk/host/session-runtime.test.ts +46 -0
  68. package/src/sdk/host/session-runtime.ts +13 -6
  69. package/src/sdk/lifecycle/service.ts +2 -0
  70. package/src/sdk/prompt-deadline-flush.ts +26 -4
  71. package/src/sdk/session.ts +587 -115
  72. package/src/session/agent-session.ts +40 -12
  73. package/src/session/internal/managed-session-scope.ts +10 -0
  74. package/src/session/internal/managed-session-storage.ts +30 -1
  75. package/src/setup/provider-presets.json +2 -1
  76. package/src/slash-commands/builtin-registry.ts +1 -1
  77. package/src/task/executor.ts +46 -17
  78. package/src/task/types.ts +2 -0
  79. package/src/tools/bash-interactive.ts +2 -0
  80. package/src/tools/bash.ts +20 -0
  81. package/src/tools/fetch.ts +21 -5
  82. package/src/tools/subagent-render.ts +24 -1
  83. package/src/tools/subagent.ts +27 -1
  84. package/src/utils/mupdf.ts +11 -4
package/src/main.ts CHANGED
@@ -34,6 +34,7 @@ import {
34
34
  applyModelProfileRuntimeBindings,
35
35
  ModelProfileCredentialError,
36
36
  } from "./config/model-profile-activation";
37
+ import { UnknownModelProfileError } from "./config/model-profile-contract";
37
38
  import { ModelRegistry, ModelsConfigFile } from "./config/model-registry";
38
39
  import {
39
40
  parseModelString,
@@ -467,23 +468,33 @@ type StartupModelProfileArgs = {
467
468
  session: AgentSession;
468
469
  settings: Settings;
469
470
  modelRegistry: ModelRegistry;
470
- parsedArgs: Pick<Args, "default" | "model" | "mpreset" | "thinking">;
471
+ parsedArgs: Pick<Args, "continue" | "default" | "fork" | "model" | "mpreset" | "resume" | "thinking">;
471
472
  startupModel?: CreateAgentSessionOptions["model"];
472
473
  startupThinkingLevel?: CreateAgentSessionOptions["thinkingLevel"];
473
474
  preferCachedModels?: boolean;
474
475
  preferCachedDefaultProfile?: boolean;
475
476
  };
476
477
 
478
+ function staleDefaultProfileMessage(error: UnknownModelProfileError, profileCatalogRefreshUnavailable = false): string {
479
+ const refreshNotice = profileCatalogRefreshUnavailable
480
+ ? " The online profile catalog could not be refreshed; continuing with the last accepted catalog."
481
+ : "";
482
+ return `Configured modelProfile.default is stale: unknown model profile ${JSON.stringify(error.details.requestedProfile)}. Select a replacement in the UI. To clear it, remove modelProfile.default from the project's .gjc/config.yml or .gjc/settings.json if set there, or run gjc config reset modelProfile.default for the global setting.${refreshNotice}`;
483
+ }
484
+
477
485
  async function applyStartupModelProfilesWithPolicy(
478
486
  args: StartupModelProfileArgs,
479
487
  onCredentialError?: (error: ModelProfileCredentialError) => void,
488
+ onUnknownDefault?: (error: UnknownModelProfileError, profileCatalogRefreshUnavailable: boolean) => void,
480
489
  ): Promise<void> {
490
+ let profileCatalogRefreshUnavailable = false;
481
491
  const applyProfile = async (
482
492
  profileName: string,
483
493
  persistDefault: boolean,
484
494
  options: {
485
495
  thinkingLevelOverride?: CreateAgentSessionOptions["thinkingLevel"];
486
496
  tolerateCredentialError?: boolean;
497
+ tolerateUnknownDefault?: boolean;
487
498
  runtimeBindingsOnly?: boolean;
488
499
  } = {},
489
500
  ): Promise<boolean> => {
@@ -508,6 +519,14 @@ async function applyStartupModelProfilesWithPolicy(
508
519
  else process.stderr.write(`${chalk.yellow(`Warning: ${error.message}`)}\n`);
509
520
  return false;
510
521
  }
522
+ if (error instanceof UnknownModelProfileError && options.tolerateUnknownDefault) {
523
+ if (onUnknownDefault) onUnknownDefault(error, profileCatalogRefreshUnavailable);
524
+ else
525
+ process.stderr.write(
526
+ `${chalk.yellow(`Warning: ${staleDefaultProfileMessage(error, profileCatalogRefreshUnavailable)}`)}\n`,
527
+ );
528
+ return false;
529
+ }
511
530
  throw error;
512
531
  }
513
532
  };
@@ -515,8 +534,8 @@ async function applyStartupModelProfilesWithPolicy(
515
534
  // An explicit startup selector (--mpreset or --model) fully replaces the
516
535
  // persisted default profile for this session, so a failing default must not
517
536
  // abort a non-interactive run: it is reported as a warning and the explicit
518
- // selection proceeds. Without an explicit selector the historic fatal
519
- // contract is unchanged.
537
+ // selection proceeds. Without an explicit selector, failures remain fatal
538
+ // except for a stale default on input-free interactive startup.
520
539
  const tolerateDefaultProfileFailure = args.parsedArgs.mpreset !== undefined || args.parsedArgs.model !== undefined;
521
540
 
522
541
  // Capture the explicitly-selected startup model BEFORE profile activation can
@@ -527,7 +546,7 @@ async function applyStartupModelProfilesWithPolicy(
527
546
  const preferCachedProfiles =
528
547
  (args.preferCachedModels === true && args.parsedArgs.mpreset !== undefined) ||
529
548
  (args.preferCachedDefaultProfile === true && defaultProfile !== undefined);
530
- const applyConfiguredProfiles = async (): Promise<boolean> => {
549
+ const applyConfiguredProfiles = async (allowMissingDefault: boolean): Promise<boolean> => {
531
550
  let applied = true;
532
551
  if (defaultProfile) {
533
552
  applied =
@@ -536,6 +555,8 @@ async function applyStartupModelProfilesWithPolicy(
536
555
  ? args.settings.get("defaultThinkingLevel")
537
556
  : undefined,
538
557
  tolerateCredentialError: tolerateDefaultProfileFailure,
558
+ tolerateUnknownDefault:
559
+ allowMissingDefault && (onUnknownDefault !== undefined || tolerateDefaultProfileFailure),
539
560
  runtimeBindingsOnly: args.session.hasRecoveredDefaultFallbackChain(),
540
561
  })) && applied;
541
562
  }
@@ -549,12 +570,23 @@ async function applyStartupModelProfilesWithPolicy(
549
570
  let applied: boolean;
550
571
  let refreshedOnline = false;
551
572
  try {
552
- applied = await applyConfiguredProfiles();
573
+ applied = await applyConfiguredProfiles(false);
553
574
  } catch (error) {
554
575
  if (error instanceof ModelProfileCredentialError) throw error;
576
+ if (error instanceof UnknownModelProfileError) {
577
+ try {
578
+ await args.modelRegistry.refreshModelPresetProfilesFromRegistry();
579
+ } catch (refreshError) {
580
+ if (args.modelRegistry.getError()) throw refreshError;
581
+ profileCatalogRefreshUnavailable = true;
582
+ logger.warn("Failed to refresh model profile catalog before startup recovery", {
583
+ error: refreshError instanceof Error ? refreshError.message : String(refreshError),
584
+ });
585
+ }
586
+ }
555
587
  await args.modelRegistry.refresh("online-if-uncached", args.session.credentialSessionId);
556
588
  refreshedOnline = true;
557
- applied = await applyConfiguredProfiles();
589
+ applied = await applyConfiguredProfiles(true);
558
590
  }
559
591
  if (applied && !refreshedOnline)
560
592
  args.modelRegistry.refreshInBackground("online-if-uncached", args.session.credentialSessionId);
@@ -562,7 +594,7 @@ async function applyStartupModelProfilesWithPolicy(
562
594
  if (defaultProfile || args.parsedArgs.mpreset) {
563
595
  await args.modelRegistry.refresh("online-if-uncached", args.session.credentialSessionId);
564
596
  }
565
- await applyConfiguredProfiles();
597
+ await applyConfiguredProfiles(true);
566
598
  }
567
599
 
568
600
  // Explicit CLI --model/--thinking must win over any activated or skipped profile.
@@ -618,6 +650,20 @@ export function isStartupModelProfileCredentialRecoveryEligible(options: {
618
650
  );
619
651
  }
620
652
 
653
+ function isStartupModelProfileStaleDefaultRecoveryEligible(
654
+ options: Parameters<typeof isStartupModelProfileCredentialRecoveryEligible>[0] & {
655
+ parsedArgs: Pick<Args, "continue" | "fork" | "resume">;
656
+ },
657
+ ): boolean {
658
+ return (
659
+ isStartupModelProfileCredentialRecoveryEligible(options) &&
660
+ options.parsedArgs.continue !== true &&
661
+ options.parsedArgs.fork === undefined &&
662
+ ((options.parsedArgs.resume === undefined && options.resumeAction === undefined) ||
663
+ (options.parsedArgs.resume === true && options.resumeAction === "open-idle"))
664
+ );
665
+ }
666
+
621
667
  export async function applyStartupModelProfilesForRoot(
622
668
  args: StartupModelProfileArgs & {
623
669
  isInteractive: boolean;
@@ -627,19 +673,21 @@ export async function applyStartupModelProfilesForRoot(
627
673
  resumeAction: "continue-tail" | "open-idle" | undefined;
628
674
  },
629
675
  ): Promise<{ recoverableErrors: string[] }> {
630
- const policyArgs = { ...args, preferCachedModels: args.isInteractive };
631
- if (!isStartupModelProfileCredentialRecoveryEligible(args)) {
632
- try {
633
- await applyStartupModelProfilesWithPolicy(policyArgs);
634
- } catch (error) {
635
- await exitForStartupModelProfileError(args, error);
636
- }
637
- return { recoverableErrors: [] };
638
- }
639
-
676
+ const policyArgs = {
677
+ ...args,
678
+ preferCachedModels: args.isInteractive,
679
+ preferCachedDefaultProfile: args.isInteractive,
680
+ };
640
681
  const recoverableErrors: string[] = [];
682
+ const onCredentialError = isStartupModelProfileCredentialRecoveryEligible(args)
683
+ ? (error: ModelProfileCredentialError) => recoverableErrors.push(error.message)
684
+ : undefined;
685
+ const onUnknownDefault = isStartupModelProfileStaleDefaultRecoveryEligible(args)
686
+ ? (error: UnknownModelProfileError, profileCatalogRefreshUnavailable: boolean) =>
687
+ recoverableErrors.push(staleDefaultProfileMessage(error, profileCatalogRefreshUnavailable))
688
+ : undefined;
641
689
  try {
642
- await applyStartupModelProfilesWithPolicy(policyArgs, error => recoverableErrors.push(error.message));
690
+ await applyStartupModelProfilesWithPolicy(policyArgs, onCredentialError, onUnknownDefault);
643
691
  } catch (error) {
644
692
  await exitForStartupModelProfileError(args, error);
645
693
  }
@@ -669,7 +717,9 @@ async function applyDeferredStartupModelProfilesForRoot(
669
717
  const onCredentialError = isStartupModelProfileCredentialRecoveryEligible(args)
670
718
  ? (error: ModelProfileCredentialError) => recoverableErrors.push(error.message)
671
719
  : undefined;
672
- await applyStartupModelProfilesWithPolicy({ ...args, preferCachedModels: true }, onCredentialError);
720
+ await applyStartupModelProfilesWithPolicy({ ...args, preferCachedModels: true }, onCredentialError, error =>
721
+ recoverableErrors.push(staleDefaultProfileMessage(error)),
722
+ );
673
723
  return { recoverableErrors };
674
724
  }
675
725