@fased/fased 0.1.53 → 0.1.54

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 (150) hide show
  1. package/dist/agents/current-model-catalog.js +27 -0
  2. package/dist/agents/model-catalog-source.js +4 -4
  3. package/dist/agents/model-forward-compat.js +19 -1
  4. package/dist/agents/model-metadata.js +13 -5
  5. package/dist/agents/pi-embedded-runner/agent-messages.js +15 -0
  6. package/dist/agents/pi-embedded-runner/compact.js +2 -1
  7. package/dist/agents/pi-embedded-runner/model.js +2 -7
  8. package/dist/agents/pi-embedded-runner/run/attempt.js +4 -5
  9. package/dist/brand.js +1 -1
  10. package/dist/build-info.json +3 -3
  11. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  12. package/dist/cli/program/register.agent.js +17 -0
  13. package/dist/commands/agents.commands.models.js +63 -0
  14. package/dist/commands/agents.js +1 -0
  15. package/dist/commands/models/list.registry.js +1 -1
  16. package/dist/commands/openai-codex-model-default.js +1 -1
  17. package/dist/config/defaults.js +1 -1
  18. package/dist/control-ui/assets/{app-WIDYwhr-.js → app-BKlu6OKz.js} +1792 -1760
  19. package/dist/control-ui/assets/chat-model-ref-B9sWop67.js +2 -0
  20. package/dist/control-ui/assets/{index-K3ysLeTN.js → index-nrFcGMv-.js} +3 -3
  21. package/dist/control-ui/assets/{providers-rQMhp1fb.js → providers-BQFrRqym.js} +2 -2
  22. package/dist/control-ui/index.html +1 -1
  23. package/dist/cron/isolated-agent/run.js +9 -3
  24. package/dist/cron/normalize.js +10 -0
  25. package/dist/gateway/protocol/schema/agents-models-skills.js +1 -0
  26. package/dist/gateway/protocol/schema/cron.js +7 -0
  27. package/dist/gateway/server-methods/models.js +1 -1
  28. package/dist/light-update-status.js +11 -11
  29. package/dist/plugin-sdk/{accounts-BZrfqJmO.js → accounts-DW9OS5Ll.js} +1 -1
  30. package/dist/plugin-sdk/{actions-7_zTh8zC.js → actions-DQUXohRr.js} +2 -2
  31. package/dist/plugin-sdk/{active-listener-D8NVRD8J.js → active-listener-BZQWZPF7.js} +1 -1
  32. package/dist/plugin-sdk/{audio-preflight-BrVWUkoP.js → audio-preflight-t4mmHsI2.js} +26 -26
  33. package/dist/plugin-sdk/{audit-2iRlVyQF.js → audit-BZk_6Buw.js} +1 -1
  34. package/dist/plugin-sdk/{channel-access-BCf1rJsn.js → channel-access-CN5HiWdb.js} +1 -1
  35. package/dist/plugin-sdk/{channel-access-configure-B-Z51Qsd.js → channel-access-configure-B7Kkvx9K.js} +1 -1
  36. package/dist/plugin-sdk/channel-plugin-common.d.ts +2 -2
  37. package/dist/plugin-sdk/channel-plugin-common.js +4 -4
  38. package/dist/plugin-sdk/{chunk-BREC9ijl.js → chunk-B2ffJ-LR.js} +1 -1
  39. package/dist/plugin-sdk/{chunk-items-BLRCltGL.js → chunk-items-jOdkyP53.js} +1 -1
  40. package/dist/plugin-sdk/command-status.js +26 -26
  41. package/dist/plugin-sdk/{commands-registry-D3-bFLsz.js → commands-registry-BWb4NcfW.js} +2 -2
  42. package/dist/plugin-sdk/{common-BlqMqEqn.js → common-C4XrB73N.js} +1 -1
  43. package/dist/plugin-sdk/{config-442EDe7Z.js → config-rySyVtKs.js} +48 -70
  44. package/dist/plugin-sdk/{config-schema-DV0zctd2.js → config-schema-BaybPPrJ.js} +96 -72
  45. package/dist/plugin-sdk/device-pair.d.ts +1 -1
  46. package/dist/plugin-sdk/discord.d.ts +3 -3
  47. package/dist/plugin-sdk/discord.js +19 -19
  48. package/dist/plugin-sdk/{handle-action-pNaP87Dr.js → handle-action-CGF-Qnp0.js} +13 -13
  49. package/dist/plugin-sdk/{helpers-B994qqVW.js → helpers-DgRMfCnT.js} +1 -1
  50. package/dist/plugin-sdk/{image-ops-Doq8nZQw.js → image-ops-CcBfoMLW.js} +1 -1
  51. package/dist/plugin-sdk/index.d.ts +4 -4
  52. package/dist/plugin-sdk/index.js +28 -28
  53. package/dist/plugin-sdk/{login-CK2zTIJA.js → login-DpDQyM7r.js} +3 -3
  54. package/dist/plugin-sdk/{login-qr-u8Mn1mCp.js → login-qr-COaSAPY5.js} +3 -3
  55. package/dist/plugin-sdk/{manager-CeJNf2bH.js → manager-Cqz30lA3.js} +2 -2
  56. package/dist/plugin-sdk/{markdown-tables-DeZztrY6.js → markdown-tables-BOG5sSQQ.js} +1 -1
  57. package/dist/plugin-sdk/{media-CgUAEfhs.js → media-Bu-nJpPs.js} +2 -2
  58. package/dist/plugin-sdk/{monitor-D-APtCpn.js → monitor-DL6oEVo8.js} +31 -31
  59. package/dist/plugin-sdk/{monitor-CEtMJuFX.js → monitor-II_NIq3G.js} +30 -30
  60. package/dist/plugin-sdk/{openresponses-http-g1Iz0xB2.js → openresponses-http-vkHBBpGY.js} +26 -26
  61. package/dist/plugin-sdk/{optional-runtime-dependency-D0BdXz1C.js → optional-runtime-dependency-DEojVNfv.js} +1 -1
  62. package/dist/plugin-sdk/{outbound-attachment-oxhGO33g.js → outbound-attachment-ivAHpWnn.js} +2 -2
  63. package/dist/plugin-sdk/{outbound-DXGuFrdx.js → outbound-mf2y6KuY.js} +6 -6
  64. package/dist/plugin-sdk/{pairing-message-C29ixrvn.js → pairing-message-CqYG12t-.js} +1 -1
  65. package/dist/plugin-sdk/{pairing-message-D3WPVg_j.d.ts → pairing-message-CvJ6Qa1Q.d.ts} +1 -1
  66. package/dist/plugin-sdk/{pairing-store-1kcsOWRs.js → pairing-store-D-21Sphe.js} +2 -2
  67. package/dist/plugin-sdk/{pi-model-discovery-l-xqaEd0.js → pi-model-discovery-B6gD1clF.js} +1 -1
  68. package/dist/plugin-sdk/{pi-model-discovery-runtime-CibV8F8G.js → pi-model-discovery-runtime-3yDxS3ro.js} +2 -2
  69. package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +1 -1
  70. package/dist/plugin-sdk/{pw-ai-9qEBW5-k.js → pw-ai-CMplwiwf.js} +3 -3
  71. package/dist/plugin-sdk/{replies-BX3L8fX7.js → replies-wiI4veI7.js} +2 -2
  72. package/dist/plugin-sdk/{resolve-outbound-target-D0AK10E7.js → resolve-outbound-target-bm9RUK5q.js} +1 -1
  73. package/dist/plugin-sdk/{resolve-route-UO6XLYH3.js → resolve-route-ekGNc6os.js} +1 -1
  74. package/dist/plugin-sdk/{retry-policy-C5N8JiHL.js → retry-policy-BvlC2SPh.js} +1 -1
  75. package/dist/plugin-sdk/{runtime-Dnzwux3G.js → runtime-ClSakPxR.js} +3 -3
  76. package/dist/plugin-sdk/{runtime-dependency-BDDpVKBO.js → runtime-dependency-yAWxH4El.js} +2 -2
  77. package/dist/plugin-sdk/sat-runtime.d.ts +2 -2
  78. package/dist/plugin-sdk/sat-runtime.js +5 -5
  79. package/dist/plugin-sdk/{send-DcsYRH2f.js → send-C7x6gzSl.js} +7 -7
  80. package/dist/plugin-sdk/{send-bcKv8F5E.js → send-CgyS75Av.js} +8 -8
  81. package/dist/plugin-sdk/{send-DGEgo_6f.js → send-D264hFVb.js} +5 -5
  82. package/dist/plugin-sdk/{send-D5rgCP1r.js → send-D58yEeH4.js} +6 -6
  83. package/dist/plugin-sdk/{send-B4XLsTL0.js → send-DrAtUGLM.js} +6 -6
  84. package/dist/plugin-sdk/{session-BoGNOlwv.js → session-DyMtb5YQ.js} +2 -2
  85. package/dist/plugin-sdk/{skill-commands-Be8s4TGQ.js → skill-commands-Q80wCyry.js} +2 -2
  86. package/dist/plugin-sdk/{slack-74qForpW.js → slack-C-I6q3NB.js} +38 -38
  87. package/dist/plugin-sdk/{slack-actions-TNnAXiUx.js → slack-actions-dGE_t_Un.js} +11 -11
  88. package/dist/plugin-sdk/slack.d.ts +3 -3
  89. package/dist/plugin-sdk/slack.js +9 -9
  90. package/dist/plugin-sdk/{sticker-cache-CrYayLff.js → sticker-cache-DCrDTYIi.js} +3 -3
  91. package/dist/plugin-sdk/{tables-Ch4js2qy.js → tables-0mhUOh5v.js} +1 -1
  92. package/dist/plugin-sdk/{targets-BGfRUJPE.js → targets-znKHngSk.js} +1 -1
  93. package/dist/plugin-sdk/{telegram-actions-BGy4AEvF.js → telegram-actions-GBYY8-x9.js} +29 -29
  94. package/dist/plugin-sdk/telegram.d.ts +3 -3
  95. package/dist/plugin-sdk/telegram.js +8 -8
  96. package/dist/plugin-sdk/{thread-bindings.lifecycle-_uQ2EF17.js → thread-bindings.lifecycle-ClzPBK70.js} +3 -3
  97. package/dist/plugin-sdk/{thread-bindings.state-DUg0s_1X.js → thread-bindings.state-Ha01nmrq.js} +2 -2
  98. package/dist/plugin-sdk/{tmp-fased-dir-BrbXGSkl.d.ts → tmp-fased-dir-C_xfeEN9.d.ts} +1 -1
  99. package/dist/plugin-sdk/{types-DlKIHIqA.d.ts → types-BI2njxWJ.d.ts} +2 -1
  100. package/dist/plugin-sdk/{types-BJdDoTQF.d.ts → types-DV5TNhMK.d.ts} +1 -1
  101. package/dist/plugin-sdk/{wallet-status-M6aK3abH.js → wallet-status-CyovJojz.js} +26 -11
  102. package/dist/plugin-sdk/{web-r1KFR44s.js → web-CJMfhGFY.js} +31 -31
  103. package/dist/plugin-sdk/{whatsapp-actions-CID_tqAX.js → whatsapp-actions-0ZbGo5ZV.js} +13 -13
  104. package/dist/plugin-sdk/{whatsapp-heartbeat-Bk-aZVMa.js → whatsapp-heartbeat-DGTsuvQ8.js} +2 -2
  105. package/dist/plugin-sdk/whatsapp.d.ts +3 -3
  106. package/dist/plugin-sdk/whatsapp.js +12 -12
  107. package/dist/plugin-sdk/{wsl-C_STtED7.js → wsl-D5jDUlms.js} +3 -3
  108. package/dist/providers/huggingface-models.js +0 -30
  109. package/dist/providers/opencode-zen-shared.js +0 -1
  110. package/dist/providers/refresh.js +4 -7
  111. package/dist/providers/registry.js +17 -3
  112. package/dist/providers/vercel-ai-gateway-models.js +0 -35
  113. package/dist/shared/model-thinking.js +3 -0
  114. package/extensions/acpx/package.json +1 -1
  115. package/extensions/bluebubbles/package.json +1 -1
  116. package/extensions/copilot-proxy/package.json +1 -1
  117. package/extensions/diagnostics-otel/package.json +1 -1
  118. package/extensions/fased-federation/package.json +1 -1
  119. package/extensions/google-gemini-cli-auth/package.json +1 -1
  120. package/extensions/imessage/package.json +1 -1
  121. package/extensions/irc/package.json +1 -1
  122. package/extensions/line/package.json +1 -1
  123. package/extensions/llm-task/package.json +1 -1
  124. package/extensions/lobster/package.json +1 -1
  125. package/extensions/matrix/CHANGELOG.md +6 -0
  126. package/extensions/matrix/package.json +1 -1
  127. package/extensions/mattermost/package.json +1 -1
  128. package/extensions/memory-core/package.json +2 -2
  129. package/extensions/memory-lancedb/package.json +1 -1
  130. package/extensions/minimax-portal-auth/package.json +1 -1
  131. package/extensions/msteams/CHANGELOG.md +6 -0
  132. package/extensions/msteams/package.json +1 -1
  133. package/extensions/nextcloud-talk/package.json +1 -1
  134. package/extensions/nostr/CHANGELOG.md +6 -0
  135. package/extensions/nostr/package.json +1 -1
  136. package/extensions/open-prose/package.json +1 -1
  137. package/extensions/sat-mining/package.json +1 -1
  138. package/extensions/signal/package.json +1 -1
  139. package/extensions/synology-chat/package.json +1 -1
  140. package/extensions/tlon/package.json +1 -1
  141. package/extensions/twitch/CHANGELOG.md +6 -0
  142. package/extensions/twitch/package.json +1 -1
  143. package/extensions/voice-call/CHANGELOG.md +6 -0
  144. package/extensions/voice-call/package.json +1 -1
  145. package/extensions/zalo/CHANGELOG.md +6 -0
  146. package/extensions/zalo/package.json +1 -1
  147. package/extensions/zalouser/CHANGELOG.md +6 -0
  148. package/extensions/zalouser/package.json +1 -1
  149. package/package.json +1 -1
  150. package/dist/control-ui/assets/chat-model-ref-NT82zapt.js +0 -2
@@ -147,6 +147,33 @@ const OPENAI_MODELS = [
147
147
  })
148
148
  ];
149
149
  const OPENAI_CODEX_MODELS = [
150
+ model({
151
+ id: "gpt-5.6-sol",
152
+ name: "GPT-5.6 Sol",
153
+ reasoning: true,
154
+ input: ["text", "image"],
155
+ contextWindow: 105e4,
156
+ maxTokens: 128e3,
157
+ api: "openai-codex-responses"
158
+ }),
159
+ model({
160
+ id: "gpt-5.6-terra",
161
+ name: "GPT-5.6 Terra",
162
+ reasoning: true,
163
+ input: ["text", "image"],
164
+ contextWindow: 105e4,
165
+ maxTokens: 128e3,
166
+ api: "openai-codex-responses"
167
+ }),
168
+ model({
169
+ id: "gpt-5.6-luna",
170
+ name: "GPT-5.6 Luna",
171
+ reasoning: true,
172
+ input: ["text", "image"],
173
+ contextWindow: 105e4,
174
+ maxTokens: 128e3,
175
+ api: "openai-codex-responses"
176
+ }),
150
177
  model({
151
178
  id: "gpt-5.5",
152
179
  name: "GPT-5.5 Codex",
@@ -1,4 +1,4 @@
1
- import { isOpenAISignInRuntimeModelSupported, isStandardProviderCatalogEntry, listProviderBrandManifests } from "../providers/registry.js";
1
+ import { isOpenAISignInCatalogModel, isStandardProviderCatalogEntry, listProviderBrandManifests } from "../providers/registry.js";
2
2
  import { MODEL_APIS } from "../config/types.models.js";
3
3
  import { buildModelCatalogMergeKey, mergeModelCatalogRowsByAuthority, normalizeModelCatalogModelId, normalizeModelCatalogProviderId, normalizeProviderCatalogRows } from "./model-catalog-normalized.js";
4
4
  import { CURRENT_MODEL_PROVIDER_CATALOG, listCurrentModelCatalogRows } from "./current-model-catalog.js";
@@ -28,7 +28,7 @@ function isSupportedRuntimeCatalogModel(provider, id) {
28
28
  if (provider !== "openai-codex") {
29
29
  return true;
30
30
  }
31
- return isOpenAISignInRuntimeModelSupported(id);
31
+ return isOpenAISignInCatalogModel(id);
32
32
  }
33
33
  function configuredProviderCatalogRows(cfg) {
34
34
  return Object.entries(cfg.models?.providers ?? {}).flatMap(([provider, providerConfig]) => normalizeProviderCatalogRows({
@@ -112,9 +112,9 @@ function providerConfigForRow(cfg, row) {
112
112
  return cfg.models?.providers?.[row.provider] ?? CURRENT_MODEL_PROVIDER_CATALOG[row.provider];
113
113
  }
114
114
  function buildFasedModelCatalogRows(params) {
115
+ const reviewedRows = [...listCurrentModelCatalogRows(), ...providerPluginCatalogRows(params.providerPluginProviders)].filter((row) => isSupportedRuntimeCatalogModel(row.provider, row.id));
115
116
  const discoveredRows = mergeModelCatalogRowsByAuthority([
116
- ...listCurrentModelCatalogRows(),
117
- ...providerPluginCatalogRows(params.providerPluginProviders),
117
+ ...reviewedRows,
118
118
  ...runtimeCatalogRows({
119
119
  models: params.runtimeModels ?? [],
120
120
  onEntryError: params.onRuntimeEntryError
@@ -1,4 +1,5 @@
1
1
  import { DEFAULT_CONTEXT_TOKENS } from "./defaults.js";
2
+ import { cloneCurrentModelProvider } from "./current-model-catalog.js";
2
3
  import { normalizeProviderId } from "./model-selection.js";
3
4
  import { normalizeModelCompat } from "./model-compat.js";
4
5
 
@@ -68,6 +69,23 @@ function cloneFirstTemplateModel(params) {
68
69
  }
69
70
  return undefined;
70
71
  }
72
+ function resolveCurrentOpenAIModel(provider, modelId) {
73
+ const normalizedProvider = normalizeProviderId(provider);
74
+ if (normalizedProvider !== "openai" && normalizedProvider !== "openai-codex") {
75
+ return undefined;
76
+ }
77
+ const trimmedModelId = modelId.trim();
78
+ const current = cloneCurrentModelProvider(normalizedProvider)?.models?.find((entry) => entry.id.toLowerCase() === trimmedModelId.toLowerCase());
79
+ if (!current) {
80
+ return undefined;
81
+ }
82
+ return normalizeModelCompat({
83
+ ...current,
84
+ id: trimmedModelId,
85
+ provider: normalizedProvider,
86
+ baseUrl: normalizedProvider === "openai-codex" ? "https://chatgpt.com/backend-api" : "https://api.openai.com/v1"
87
+ });
88
+ }
71
89
  function buildOpenAIResponsesPatch(params) {
72
90
  return {
73
91
  api: "openai-responses",
@@ -393,7 +411,7 @@ function resolveZaiGlm5ForwardCompatModel(provider, modelId, modelRegistry) {
393
411
  });
394
412
  }
395
413
  function resolveForwardCompatModel(provider, modelId, modelRegistry) {
396
- return resolveOpenAIGptForwardCompatModel(provider, modelId, modelRegistry) ?? resolveOpenAICodexForwardCompatModel(provider, modelId, modelRegistry) ?? resolveAnthropicOpus46ForwardCompatModel(provider, modelId, modelRegistry) ?? resolveAnthropicSonnet46ForwardCompatModel(provider, modelId, modelRegistry) ?? resolveZaiGlm5ForwardCompatModel(provider, modelId, modelRegistry) ?? resolveGoogleGeminiCli31ForwardCompatModel(provider, modelId, modelRegistry);
414
+ return resolveCurrentOpenAIModel(provider, modelId) ?? resolveOpenAIGptForwardCompatModel(provider, modelId, modelRegistry) ?? resolveOpenAICodexForwardCompatModel(provider, modelId, modelRegistry) ?? resolveAnthropicOpus46ForwardCompatModel(provider, modelId, modelRegistry) ?? resolveAnthropicSonnet46ForwardCompatModel(provider, modelId, modelRegistry) ?? resolveZaiGlm5ForwardCompatModel(provider, modelId, modelRegistry) ?? resolveGoogleGeminiCli31ForwardCompatModel(provider, modelId, modelRegistry);
397
415
  }
398
416
 
399
417
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { resolveModelThinkingCapability } from "../shared/model-thinking.js";
2
- import { lookupProviderManifestModelCapability } from "../providers/registry.js";
2
+ import { getProviderBrandManifestForRoute, lookupProviderManifestModelCapability } from "../providers/registry.js";
3
3
  import { isPrivateNetworkBaseUrl } from "../utils/private-network-url.js";
4
4
  import { lookupRefreshedModelCapability } from "../providers/refreshed-model-capabilities.js";
5
5
 
@@ -41,6 +41,14 @@ function resolveAuthMode(params) {
41
41
  if (params.providerConfig?.auth) {
42
42
  return params.providerConfig.auth;
43
43
  }
44
+ const providerRoute = params.provider.trim().toLowerCase();
45
+ const method = getProviderBrandManifestForRoute(providerRoute)?.methods.find((entry) => entry.route.trim().toLowerCase() === providerRoute || entry.statusRoute?.trim().toLowerCase() === providerRoute || entry.configProviderId?.trim().toLowerCase() === providerRoute);
46
+ if (method?.kind === "oauth" || method?.kind === "device") {
47
+ return "oauth";
48
+ }
49
+ if (method?.kind === "token") {
50
+ return "token";
51
+ }
44
52
  return "api-key";
45
53
  }
46
54
  function addFeature(features, feature, enabled) {
@@ -56,15 +64,15 @@ function deriveModelMetadata(params) {
56
64
  const api = params.model.api ?? providerConfig?.api;
57
65
  const refreshed = lookupRefreshedModelCapability(provider, modelId);
58
66
  const manifestCapabilities = lookupProviderManifestModelCapability(provider, modelId);
59
- const input = refreshed?.input ?? params.model.input ?? ["text"];
67
+ const input = params.model.input ?? refreshed?.input ?? ["text"];
60
68
  const capabilities = manifestCapabilities || params.model.capabilities || refreshed?.capabilities ? {
69
+ ...refreshed?.capabilities,
61
70
  ...manifestCapabilities,
62
- ...params.model.capabilities,
63
- ...refreshed?.capabilities
71
+ ...params.model.capabilities
64
72
  } : undefined;
65
73
  const capabilityConfidence = capabilities || refreshed || manifestCapabilities ? "declared" : "unknown";
66
74
  const shouldInferApiCapabilities = !(LOCAL_DYNAMIC_PROVIDERS.has(provider) && capabilityConfidence === "unknown");
67
- const reasoning = refreshed?.reasoning ?? params.model.reasoning;
75
+ const reasoning = params.model.reasoning ?? refreshed?.reasoning;
68
76
  const thinking = resolveModelThinkingCapability({
69
77
  provider,
70
78
  model: modelId,
@@ -0,0 +1,15 @@
1
+ //#region src/agents/pi-embedded-runner/agent-messages.ts
2
+ function replaceAgentMessages(agent, messages) {
3
+ if (agent.state) {
4
+ agent.state.messages = messages;
5
+ return;
6
+ }
7
+ if (typeof agent.replaceMessages === "function") {
8
+ agent.replaceMessages(messages);
9
+ return;
10
+ }
11
+ throw new Error("Agent runtime does not expose mutable message state");
12
+ }
13
+
14
+ //#endregion
15
+ export { replaceAgentMessages };
@@ -38,6 +38,7 @@ import { applySkillEnvOverrides, applySkillEnvOverridesFromSnapshot } from "../s
38
38
  import { loadWorkspaceSkillEntries, resolveSkillsPromptForRun } from "../skills/workspace.js";
39
39
  import "../skills.js";
40
40
  import { resolveTranscriptPolicy } from "../transcript-policy.js";
41
+ import { replaceAgentMessages } from "./agent-messages.js";
41
42
  import { EMBEDDED_COMPACTION_TIMEOUT_MS, compactWithSafetyTimeout } from "./compaction-safety-timeout.js";
42
43
  import { buildEmbeddedExtensionFactories } from "./extensions.js";
43
44
  import { describeUnknownError, mapThinkingLevel } from "./utils.js";
@@ -467,7 +468,7 @@ async function compactEmbeddedPiSessionDirect(params) {
467
468
  const truncated = limitHistoryTurns(validated, getDmHistoryLimitFromSessionKey(params.sessionKey, params.config));
468
469
  const limited = transcriptPolicy.repairToolUseResultPairing ? sanitizeToolUseResultPairing(truncated) : truncated;
469
470
  if (limited.length > 0) {
470
- session.agent.replaceMessages(limited);
471
+ replaceAgentMessages(session.agent, limited);
471
472
  }
472
473
  const hookRunner = getGlobalHookRunner();
473
474
  const hookCtx = {
@@ -1,3 +1,4 @@
1
+ import { isOpenAISignInRuntimeModelSupported } from "../../providers/registry.js";
1
2
  import { DEFAULT_CONTEXT_TOKENS } from "../defaults.js";
2
3
  import { isPrivateNetworkBaseUrl } from "../../utils/private-network-url.js";
3
4
  import { resolveFasedAgentAgentDir } from "../agent-paths.js";
@@ -10,12 +11,6 @@ import { attachModelProviderRequestTransport, sanitizeConfiguredModelProviderReq
10
11
 
11
12
  //#region src/agents/pi-embedded-runner/model.ts
12
13
  const OPENAI_CODEX_PROVIDER_ID = "openai-codex";
13
- const OPENAI_CODEX_SUPPORTED_MODEL_IDS = new Set([
14
- "gpt-5.5",
15
- "gpt-5.4",
16
- "gpt-5.4-mini",
17
- "gpt-5.3-codex"
18
- ]);
19
14
  function buildInlineProviderModels(providers) {
20
15
  return Object.entries(providers).flatMap(([providerId, entry]) => {
21
16
  const trimmed = providerId.trim();
@@ -59,7 +54,7 @@ function resolveModel(provider, modelId, agentDir, cfg) {
59
54
  const modelRegistry = discoverModels(authStorage, resolvedAgentDir);
60
55
  const normalizedProvider = normalizeProviderId(provider);
61
56
  const runtimeModelId = modelId.trim();
62
- if (normalizedProvider === OPENAI_CODEX_PROVIDER_ID && !OPENAI_CODEX_SUPPORTED_MODEL_IDS.has(runtimeModelId.toLowerCase())) {
57
+ if (normalizedProvider === OPENAI_CODEX_PROVIDER_ID && !isOpenAISignInRuntimeModelSupported(runtimeModelId)) {
63
58
  return {
64
59
  error: `Unsupported OpenAI-Codex sign-in model: ${runtimeModelId}`,
65
60
  authStorage,
@@ -42,6 +42,7 @@ import { applySkillEnvOverrides, applySkillEnvOverridesFromSnapshot } from "../.
42
42
  import { loadWorkspaceSkillEntries, resolveSkillsPromptForRun } from "../../skills/workspace.js";
43
43
  import "../../skills.js";
44
44
  import { resolveTranscriptPolicy } from "../../transcript-policy.js";
45
+ import { replaceAgentMessages } from "../agent-messages.js";
45
46
  import { appendCacheTtlTimestamp, shouldAppendCacheTtlTimestampAfterAttempt } from "../cache-ttl.js";
46
47
  import { buildEmbeddedExtensionFactories } from "../extensions.js";
47
48
  import { dropThinkingBlocks } from "../thinking.js";
@@ -79,7 +80,6 @@ import "../../pi-embedded-helpers.js";
79
80
  import os from "node:os";
80
81
  import fs from "node:fs/promises";
81
82
  import { DefaultResourceLoader, SessionManager, createAgentSession } from "@mariozechner/pi-coding-agent";
82
- import { streamSimple } from "@mariozechner/pi-ai/compat";
83
83
 
84
84
  //#region src/agents/pi-embedded-runner/run/attempt.ts
85
85
  function trimWhitespaceFromToolCallNamesInMessage(message) {
@@ -621,7 +621,6 @@ async function runEmbeddedAttempt(params) {
621
621
  modelApi: params.model.api,
622
622
  workspaceDir: params.workspaceDir
623
623
  });
624
- activeSession.agent.streamFn = streamSimple;
625
624
  applyExtraParamsToAgent(activeSession.agent, params.config, params.provider, params.modelId, params.streamParams, params.thinkLevel, sessionAgentId);
626
625
  if (cacheTrace) {
627
626
  cacheTrace.recordStage("session:loaded", {
@@ -697,7 +696,7 @@ async function runEmbeddedAttempt(params) {
697
696
  const limited = transcriptPolicy.repairToolUseResultPairing ? sanitizeToolUseResultPairing(truncated) : truncated;
698
697
  cacheTrace?.recordStage("session:limited", { messages: limited });
699
698
  if (params.omitPriorMessages || limited.length > 0) {
700
- activeSession.agent.replaceMessages(limited);
699
+ replaceAgentMessages(activeSession.agent, limited);
701
700
  }
702
701
  } catch (err) {
703
702
  await flushPendingToolResultsAfterIdle({
@@ -887,13 +886,13 @@ async function runEmbeddedAttempt(params) {
887
886
  sessionManager.resetLeaf();
888
887
  }
889
888
  const sessionContext = sessionManager.buildSessionContext();
890
- activeSession.agent.replaceMessages(sessionContext.messages);
889
+ replaceAgentMessages(activeSession.agent, sessionContext.messages);
891
890
  log.warn(`Removed orphaned user message to prevent consecutive user turns. ` + `runId=${params.runId} sessionId=${params.sessionId}`);
892
891
  }
893
892
  try {
894
893
  const didPruneImages = pruneProcessedHistoryImages(activeSession.messages);
895
894
  if (didPruneImages) {
896
- activeSession.agent.replaceMessages(activeSession.messages);
895
+ replaceAgentMessages(activeSession.agent, activeSession.messages);
897
896
  }
898
897
  const imageResult = await detectAndLoadPromptImages({
899
898
  prompt: effectivePrompt,
package/dist/brand.js CHANGED
@@ -2,7 +2,7 @@
2
2
  const FASED_BRAND_NAME = "Fased";
3
3
  const FASED_AGENT_NAME = "Fased Agent";
4
4
  const FASED_CONTROL_NAME = "Fased Control";
5
- const FASED_PRODUCT_VERSION = "0.1.53";
5
+ const FASED_PRODUCT_VERSION = "0.1.54";
6
6
  const FASED_DISPLAY_VERSION = `v${FASED_PRODUCT_VERSION}`;
7
7
  function formatFasedDisplayLine() {
8
8
  return `${FASED_AGENT_NAME} ${FASED_DISPLAY_VERSION}`;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.53",
3
- "commit": "21fc3eb6d5d55b3f7c005e5b55fa428cca192c78",
4
- "builtAt": "2026-07-12T13:49:16.566Z"
2
+ "version": "0.1.54",
3
+ "commit": "0e4f7276a6ff611b7a7c084cbdbac6246a020621",
4
+ "builtAt": "2026-07-12T17:54:54.055Z"
5
5
  }
@@ -1 +1 @@
1
- 82debccdfd783f21ff1a88adc89970827b00fe7edd5c226994849712e5a7b98d
1
+ f0c7aea72356480469af9d337d9985c17460e758b57c1538c6f2e6cd058015ac
@@ -13,6 +13,7 @@ import { agentsAddCommand } from "../../commands/agents.commands.add.js";
13
13
  import { agentsDeleteCommand } from "../../commands/agents.commands.delete.js";
14
14
  import { agentsSetIdentityCommand } from "../../commands/agents.commands.identity.js";
15
15
  import { agentsListCommand } from "../../commands/agents.commands.list.js";
16
+ import { agentsModelsSetCommand } from "../../commands/agents.commands.models.js";
16
17
  import "../../commands/agents.js";
17
18
 
18
19
  //#region src/cli/program/register.agent.ts
@@ -53,6 +54,22 @@ ${theme.muted("Docs:")} ${formatDocsLink("/cli/agent", "docs.fased.ai/cli/agent"
53
54
  }, defaultRuntime);
54
55
  });
55
56
  });
57
+ const agentModels = agents.command("models").description("Configure models for one Agent");
58
+ agentModels.command("set").description("Set the Agent primary, fallback, and task-role models").option("--agent <id>", "Agent id (defaults to the current default Agent)").option("--primary <provider/model>", "Primary model").option("--fallback <provider/model>", "Fallback model (repeatable)", collectOption).option("--cheap-check <provider/model>", "Cheap/check task model").option("--strong <provider/model>", "Strong task model").option("--escalation <provider/model>", "Escalation task model").option("--coding <provider/model>", "Coding task model").option("--summarizer <provider/model>", "Summarizer task model").option("--json", "Output JSON summary", false).action(async (opts) => {
59
+ await runCommandWithRuntime(defaultRuntime, async () => {
60
+ await agentsModelsSetCommand({
61
+ agent: opts.agent,
62
+ primary: opts.primary,
63
+ fallbacks: Array.isArray(opts.fallback) ? opts.fallback : undefined,
64
+ cheapCheck: opts.cheapCheck,
65
+ strong: opts.strong,
66
+ escalation: opts.escalation,
67
+ coding: opts.coding,
68
+ summarizer: opts.summarizer,
69
+ json: Boolean(opts.json)
70
+ }, defaultRuntime);
71
+ });
72
+ });
56
73
  agents.command("bind").description("Add routing bindings for an agent").option("--agent <id>", "Agent id (defaults to current default agent)").option("--bind <channel[:accountId]>", "Binding to add (repeatable). If omitted, accountId is resolved by channel defaults/hooks.", collectOption, []).option("--json", "Output JSON summary", false).action(async (opts) => {
57
74
  await runCommandWithRuntime(defaultRuntime, async () => {
58
75
  await agentsBindCommand({
@@ -0,0 +1,63 @@
1
+ import { resolveAgentModelFallbackValues, resolveAgentModelPrimaryValue } from "../config/model-input.js";
2
+ import { defaultRuntime } from "../runtime.js";
3
+ import { normalizeAgentId } from "../routing/session-key.js";
4
+ import { listAgentEntries, resolveDefaultAgentId } from "../agents/agent-scope.js";
5
+ import { writeConfigFile } from "../config/io.js";
6
+ import "../config/config.js";
7
+ import { applyAgentConfig } from "./agents.config.js";
8
+ import { logConfigUpdated } from "../config/logging.js";
9
+ import { requireValidConfig } from "./agents.command-shared.js";
10
+
11
+ //#region src/commands/agents.commands.models.ts
12
+ function clean(value) {
13
+ const trimmed = value?.trim();
14
+ return trimmed || undefined;
15
+ }
16
+ async function agentsModelsSetCommand(opts, runtime = defaultRuntime) {
17
+ const cfg = await requireValidConfig(runtime);
18
+ if (!cfg) {
19
+ return;
20
+ }
21
+ const agentId = normalizeAgentId(clean(opts.agent) ?? resolveDefaultAgentId(cfg));
22
+ const current = listAgentEntries(cfg).find((entry) => normalizeAgentId(entry.id) === agentId);
23
+ const primary = clean(opts.primary) ?? resolveAgentModelPrimaryValue(current?.model);
24
+ const fallbacks = opts.fallbacks !== undefined ? [...new Set(opts.fallbacks.map((entry) => entry.trim()).filter(Boolean))] : resolveAgentModelFallbackValues(current?.model);
25
+ const taskModels = {
26
+ ...current?.taskModels,
27
+ ...opts.cheapCheck !== undefined ? { cheapCheck: clean(opts.cheapCheck) } : {},
28
+ ...opts.strong !== undefined ? { strong: clean(opts.strong) } : {},
29
+ ...opts.escalation !== undefined ? { escalation: clean(opts.escalation) } : {},
30
+ ...opts.coding !== undefined ? { coding: clean(opts.coding) } : {},
31
+ ...opts.summarizer !== undefined ? { summarizer: clean(opts.summarizer) } : {}
32
+ };
33
+ const normalizedTaskModels = Object.fromEntries(Object.entries(taskModels).filter((entry) => Boolean(entry[1])));
34
+ if (!primary && fallbacks.length === 0 && Object.keys(normalizedTaskModels).length === 0) {
35
+ runtime.error("Set at least one model with --primary, --fallback, or a task-role option.");
36
+ runtime.exit(1);
37
+ return;
38
+ }
39
+ const model = primary ? fallbacks.length > 0 ? {
40
+ primary,
41
+ fallbacks
42
+ } : primary : { fallbacks };
43
+ const next = applyAgentConfig(cfg, {
44
+ agentId,
45
+ model,
46
+ taskModels: normalizedTaskModels,
47
+ activeModelProvider: null,
48
+ modelProviders: null
49
+ });
50
+ await writeConfigFile(next);
51
+ if (!opts.json) {
52
+ logConfigUpdated(runtime);
53
+ }
54
+ const payload = {
55
+ agentId,
56
+ model,
57
+ taskModels: normalizedTaskModels
58
+ };
59
+ runtime.log(opts.json ? JSON.stringify(payload, null, 2) : `Agent models updated: ${agentId}`);
60
+ }
61
+
62
+ //#endregion
63
+ export { agentsModelsSetCommand };
@@ -6,5 +6,6 @@ import { agentsAddCommand } from "./agents.commands.add.js";
6
6
  import { agentsDeleteCommand } from "./agents.commands.delete.js";
7
7
  import { agentsSetIdentityCommand } from "./agents.commands.identity.js";
8
8
  import { agentsListCommand } from "./agents.commands.list.js";
9
+ import { agentsModelsSetCommand } from "./agents.commands.models.js";
9
10
 
10
11
  export { agentsListCommand };
@@ -133,7 +133,7 @@ function toModelRow(params) {
133
133
  cfg,
134
134
  authStore
135
135
  }) : undefined);
136
- const available = availableKeys !== undefined ? availableKeys.has(modelKey(model.provider, model.id)) : authIndex?.hasProviderAuth(model.provider) ?? false;
136
+ const available = availableKeys !== undefined ? availableKeys.has(modelKey(model.provider, model.id)) || model.catalogSource !== "runtime" && (authIndex?.hasProviderAuth(model.provider) ?? false) : authIndex?.hasProviderAuth(model.provider) ?? false;
137
137
  const aliasTags = aliases.length > 0 ? [`alias:${aliases.join(",")}`] : [];
138
138
  const mergedTags = new Set(tags);
139
139
  if (aliasTags.length > 0) {
@@ -1,5 +1,5 @@
1
1
  //#region src/commands/openai-codex-model-default.ts
2
- const OPENAI_CODEX_DEFAULT_MODEL = "openai-codex/gpt-5.5";
2
+ const OPENAI_CODEX_DEFAULT_MODEL = "openai-codex/gpt-5.6-sol";
3
3
  function shouldSetOpenAICodexModel(model) {
4
4
  const trimmed = model?.trim();
5
5
  if (!trimmed) {
@@ -9,7 +9,7 @@ let defaultWarnState = { warned: false };
9
9
  const DEFAULT_MODEL_ALIASES = {
10
10
  opus: "anthropic/claude-opus-4-8",
11
11
  sonnet: "anthropic/claude-sonnet-5",
12
- gpt: "openai/gpt-5.5",
12
+ gpt: "openai/gpt-5.6",
13
13
  "gpt-mini": "openai/gpt-5.4-mini",
14
14
  gemini: "google/gemini-3.5-flash",
15
15
  "gemini-flash": "google/gemini-3-flash-preview",