nodal-agents 0.4.2 → 0.4.4

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 (130) hide show
  1. package/README.md +12 -12
  2. package/package.json +2 -1
  3. package/runner.js +247 -66
  4. package/web/.next/BUILD_ID +1 -1
  5. package/web/.next/build-manifest.json +2 -2
  6. package/web/.next/prerender-manifest.json +3 -3
  7. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js +3 -3
  8. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js.nft.json +1 -1
  9. package/web/.next/server/app/(dashboard)/agents/[id]/edit/page_client-reference-manifest.js +1 -1
  10. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js +2 -2
  11. package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page_client-reference-manifest.js +1 -1
  12. package/web/.next/server/app/(dashboard)/agents/page.js +2 -2
  13. package/web/.next/server/app/(dashboard)/agents/page_client-reference-manifest.js +1 -1
  14. package/web/.next/server/app/(dashboard)/approvals/page.js +2 -2
  15. package/web/.next/server/app/(dashboard)/approvals/page.js.nft.json +1 -1
  16. package/web/.next/server/app/(dashboard)/approvals/page_client-reference-manifest.js +1 -1
  17. package/web/.next/server/app/(dashboard)/automations/page.js +2 -2
  18. package/web/.next/server/app/(dashboard)/automations/page_client-reference-manifest.js +1 -1
  19. package/web/.next/server/app/(dashboard)/billing/page.js +2 -2
  20. package/web/.next/server/app/(dashboard)/billing/page_client-reference-manifest.js +1 -1
  21. package/web/.next/server/app/(dashboard)/chat/page.js +1 -1
  22. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  23. package/web/.next/server/app/(dashboard)/connectors/page.js +1 -1
  24. package/web/.next/server/app/(dashboard)/connectors/page.js.nft.json +1 -1
  25. package/web/.next/server/app/(dashboard)/connectors/page_client-reference-manifest.js +1 -1
  26. package/web/.next/server/app/(dashboard)/credentials/page.js +1 -1
  27. package/web/.next/server/app/(dashboard)/credentials/page.js.nft.json +1 -1
  28. package/web/.next/server/app/(dashboard)/credentials/page_client-reference-manifest.js +1 -1
  29. package/web/.next/server/app/(dashboard)/jobs/[id]/page.js +2 -2
  30. package/web/.next/server/app/(dashboard)/jobs/[id]/page_client-reference-manifest.js +1 -1
  31. package/web/.next/server/app/(dashboard)/jobs/page.js +2 -2
  32. package/web/.next/server/app/(dashboard)/jobs/page.js.nft.json +1 -1
  33. package/web/.next/server/app/(dashboard)/jobs/page_client-reference-manifest.js +1 -1
  34. package/web/.next/server/app/(dashboard)/llm-providers/page.js +1 -1
  35. package/web/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
  36. package/web/.next/server/app/(dashboard)/logs/page.js +2 -2
  37. package/web/.next/server/app/(dashboard)/logs/page_client-reference-manifest.js +1 -1
  38. package/web/.next/server/app/(dashboard)/mcp/page.js +1 -1
  39. package/web/.next/server/app/(dashboard)/mcp/page_client-reference-manifest.js +1 -1
  40. package/web/.next/server/app/(dashboard)/memories/page.js +2 -2
  41. package/web/.next/server/app/(dashboard)/memories/page_client-reference-manifest.js +1 -1
  42. package/web/.next/server/app/(dashboard)/page.js +4 -4
  43. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  44. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  45. package/web/.next/server/app/(dashboard)/settings/page.js +2 -2
  46. package/web/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  47. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js +1 -1
  48. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js.nft.json +1 -1
  49. package/web/.next/server/app/(dashboard)/skills/[id]/edit/page_client-reference-manifest.js +1 -1
  50. package/web/.next/server/app/(dashboard)/skills/new/page.js +2 -2
  51. package/web/.next/server/app/(dashboard)/skills/new/page.js.nft.json +1 -1
  52. package/web/.next/server/app/(dashboard)/skills/new/page_client-reference-manifest.js +1 -1
  53. package/web/.next/server/app/(dashboard)/skills/page.js +1 -1
  54. package/web/.next/server/app/(dashboard)/skills/page_client-reference-manifest.js +1 -1
  55. package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  56. package/web/.next/server/app/_global-error.html +1 -1
  57. package/web/.next/server/app/_global-error.rsc +2 -2
  58. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  59. package/web/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  60. package/web/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  61. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  62. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +2 -2
  63. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  64. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  65. package/web/.next/server/app/_not-found.html +1 -1
  66. package/web/.next/server/app/_not-found.rsc +2 -2
  67. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  68. package/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  69. package/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  70. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  71. package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  72. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  73. package/web/.next/server/app/api/oauth/[provider]/callback/route.js +1 -1
  74. package/web/.next/server/app/login/page_client-reference-manifest.js +1 -1
  75. package/web/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/onboarding.html +1 -1
  77. package/web/.next/server/app/onboarding.rsc +2 -2
  78. package/web/.next/server/app/onboarding.segments/_full.segment.rsc +2 -2
  79. package/web/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
  80. package/web/.next/server/app/onboarding.segments/_index.segment.rsc +2 -2
  81. package/web/.next/server/app/onboarding.segments/_tree.segment.rsc +1 -1
  82. package/web/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +1 -1
  83. package/web/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
  84. package/web/.next/server/chunks/3233.js +1 -1
  85. package/web/.next/server/chunks/3889.js +1 -0
  86. package/web/.next/server/chunks/5329.js +1 -0
  87. package/web/.next/server/chunks/593.js +1 -0
  88. package/web/.next/server/chunks/7231.js +1 -0
  89. package/web/.next/server/chunks/7741.js +1 -1
  90. package/web/.next/server/middleware-build-manifest.js +1 -1
  91. package/web/.next/server/pages/404.html +1 -1
  92. package/web/.next/server/pages/500.html +1 -1
  93. package/web/.next/server/server-reference-manifest.js +1 -1
  94. package/web/.next/server/server-reference-manifest.json +1 -1
  95. package/web/.next/static/chunks/{9123-20653d928e33410a.js → 9123-67530ba510c58003.js} +1 -1
  96. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-a2c267f563cd1a70.js +2 -0
  97. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/telegram/page-2d7cae43f5e6952a.js +1 -0
  98. package/web/.next/static/chunks/app/(dashboard)/agents/page-bed833ebdd3646fb.js +1 -0
  99. package/web/.next/static/chunks/app/(dashboard)/approvals/{page-79dea6e91956eeba.js → page-4b27762472802ce0.js} +1 -1
  100. package/web/.next/static/chunks/app/(dashboard)/automations/{page-3b863b7af8e2c1a3.js → page-9e5d2ce807ce1c37.js} +1 -1
  101. package/web/.next/static/chunks/app/(dashboard)/chat/page-8f81d7e3abb475a6.js +1 -0
  102. package/web/.next/static/chunks/app/(dashboard)/connectors/{page-4a437ba82f4086da.js → page-39b1d9560235d574.js} +1 -1
  103. package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/page-112bb22a9ec43be0.js +1 -0
  104. package/web/.next/static/chunks/app/(dashboard)/jobs/{page-94a311f688a255d8.js → page-44351170ed5f9180.js} +1 -1
  105. package/web/.next/static/chunks/app/(dashboard)/{layout-e1b0d4fad2926646.js → layout-53e69de869cba0d0.js} +1 -1
  106. package/web/.next/static/chunks/app/(dashboard)/llm-providers/{page-e5e2c4e2b783d37f.js → page-8f6ce47ba228e38b.js} +1 -1
  107. package/web/.next/static/chunks/app/(dashboard)/mcp/page-cdf057e468c6e92e.js +1 -0
  108. package/web/.next/static/chunks/app/(dashboard)/memories/page-e706ab4aa681fa99.js +1 -0
  109. package/web/.next/static/chunks/app/(dashboard)/{page-fb50e1576a3ab2e4.js → page-29cfae3bf701076e.js} +1 -1
  110. package/web/.next/static/chunks/app/(dashboard)/settings/page-312ae27ae71ea6d1.js +1 -0
  111. package/web/.next/static/chunks/app/(dashboard)/skills/[id]/edit/page-89a8a30db5eb96e1.js +1 -0
  112. package/web/.next/static/chunks/app/(dashboard)/skills/new/page-46a424b203591560.js +1 -0
  113. package/web/.next/static/chunks/app/(dashboard)/skills/page-edad7bbd3230fb7a.js +1 -0
  114. package/web/.next/server/chunks/1945.js +0 -1
  115. package/web/.next/server/chunks/4839.js +0 -1
  116. package/web/.next/server/chunks/8206.js +0 -1
  117. package/web/.next/server/chunks/8398.js +0 -1
  118. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-a8e293c54c818084.js +0 -2
  119. package/web/.next/static/chunks/app/(dashboard)/agents/[id]/telegram/page-7a94ae67b2c3c9c3.js +0 -1
  120. package/web/.next/static/chunks/app/(dashboard)/agents/page-b258b8975ac6450b.js +0 -1
  121. package/web/.next/static/chunks/app/(dashboard)/chat/page-4d965bb7ee3732db.js +0 -1
  122. package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/page-be20dcbf25c8f3ce.js +0 -1
  123. package/web/.next/static/chunks/app/(dashboard)/mcp/page-c071c54f76273ac4.js +0 -1
  124. package/web/.next/static/chunks/app/(dashboard)/memories/page-8ca0b34ad35eb1fa.js +0 -1
  125. package/web/.next/static/chunks/app/(dashboard)/settings/page-7b256e9c462e97f8.js +0 -1
  126. package/web/.next/static/chunks/app/(dashboard)/skills/[id]/edit/page-12930816795e8b20.js +0 -1
  127. package/web/.next/static/chunks/app/(dashboard)/skills/new/page-e3a19abaf7468db9.js +0 -1
  128. package/web/.next/static/chunks/app/(dashboard)/skills/page-43f1475a0bc9c45f.js +0 -1
  129. /package/web/.next/static/{ZuUX-HBTQOhLf0tFI6JQI → PV5qpGylrVW3jZ7zKHuhE}/_buildManifest.js +0 -0
  130. /package/web/.next/static/{ZuUX-HBTQOhLf0tFI6JQI → PV5qpGylrVW3jZ7zKHuhE}/_ssgManifest.js +0 -0
package/runner.js CHANGED
@@ -1106,7 +1106,10 @@ var init_connector_catalog = __esm({
1106
1106
  function findModelCatalogEntry(provider, modelId) {
1107
1107
  return MODEL_CATALOG[provider]?.find((e) => e.modelId === modelId);
1108
1108
  }
1109
- var MODEL_CATALOG;
1109
+ function modelContextWindow(provider, modelId) {
1110
+ return findModelCatalogEntry(provider, modelId)?.contextWindow ?? DEFAULT_CONTEXT_WINDOW;
1111
+ }
1112
+ var MODEL_CATALOG, DEFAULT_CONTEXT_WINDOW;
1110
1113
  var init_model_catalog = __esm({
1111
1114
  "../../packages/shared/src/model-catalog.ts"() {
1112
1115
  "use strict";
@@ -1115,127 +1118,167 @@ var init_model_catalog = __esm({
1115
1118
  {
1116
1119
  modelId: "claude-opus-4-8",
1117
1120
  label: "Claude Opus 4.8",
1118
- capabilities: { tools: true, forcedToolChoice: true }
1121
+ capabilities: { tools: true, forcedToolChoice: true },
1122
+ contextWindow: 2e5
1119
1123
  },
1120
1124
  {
1121
1125
  modelId: "claude-sonnet-4-6",
1122
1126
  label: "Claude Sonnet 4.6",
1123
- capabilities: { tools: true, forcedToolChoice: true }
1127
+ capabilities: { tools: true, forcedToolChoice: true },
1128
+ contextWindow: 2e5
1124
1129
  },
1125
1130
  {
1126
1131
  modelId: "claude-haiku-4-5-20251001",
1127
1132
  label: "Claude Haiku 4.5",
1128
- capabilities: { tools: true, forcedToolChoice: true }
1133
+ capabilities: { tools: true, forcedToolChoice: true },
1134
+ contextWindow: 2e5
1129
1135
  }
1130
1136
  ],
1131
1137
  openai: [
1132
- { modelId: "gpt-5", label: "GPT-5", capabilities: { tools: true, forcedToolChoice: true } },
1138
+ {
1139
+ modelId: "gpt-5",
1140
+ label: "GPT-5",
1141
+ capabilities: { tools: true, forcedToolChoice: true },
1142
+ contextWindow: 4e5
1143
+ },
1133
1144
  {
1134
1145
  modelId: "gpt-5-mini",
1135
1146
  label: "GPT-5 mini",
1136
- capabilities: { tools: true, forcedToolChoice: true }
1147
+ capabilities: { tools: true, forcedToolChoice: true },
1148
+ contextWindow: 4e5
1137
1149
  }
1138
1150
  ],
1139
1151
  google: [
1140
1152
  {
1141
1153
  modelId: "gemini-2.0-flash",
1142
1154
  label: "Gemini 2.0 Flash",
1143
- capabilities: { tools: true, forcedToolChoice: true }
1155
+ capabilities: { tools: true, forcedToolChoice: true },
1156
+ contextWindow: 1048576
1144
1157
  },
1145
1158
  {
1146
1159
  modelId: "gemini-2.5-pro",
1147
1160
  label: "Gemini 2.5 Pro",
1148
- capabilities: { tools: true, forcedToolChoice: true }
1161
+ capabilities: { tools: true, forcedToolChoice: true },
1162
+ contextWindow: 1048576
1149
1163
  }
1150
1164
  ],
1151
1165
  groq: [
1152
1166
  {
1153
1167
  modelId: "llama-3.3-70b-versatile",
1154
1168
  label: "Llama 3.3 70B",
1155
- capabilities: { tools: true, forcedToolChoice: true }
1169
+ capabilities: { tools: true, forcedToolChoice: true },
1170
+ contextWindow: 131072
1156
1171
  }
1157
1172
  ],
1158
1173
  mistral: [
1159
1174
  {
1160
1175
  modelId: "mistral-large-latest",
1161
1176
  label: "Mistral Large",
1162
- capabilities: { tools: true, forcedToolChoice: true }
1177
+ capabilities: { tools: true, forcedToolChoice: true },
1178
+ contextWindow: 131072
1163
1179
  }
1164
1180
  ],
1165
1181
  // OpenRouter models are namespaced by sub-vendor (anthropic/, deepseek/, …).
1166
1182
  // The UI groups them by that vendor (see modelGroupLabel). Tested + working
1167
- // routes; all accept a forced tool_choice.
1183
+ // routes. `forcedToolChoice` is per-model: most accept tool_choice:'required';
1184
+ // MiniMax M3 does not (some of its OpenRouter endpoints reject the forced
1185
+ // value), so it runs on 'auto' + the runtime floor.
1168
1186
  openrouter: [
1169
1187
  // Anthropic
1170
1188
  {
1171
1189
  modelId: "anthropic/claude-haiku-4.5",
1172
1190
  label: "Claude Haiku 4.5",
1173
- capabilities: { tools: true, forcedToolChoice: true }
1191
+ capabilities: { tools: true, forcedToolChoice: true },
1192
+ contextWindow: 2e5
1174
1193
  },
1175
1194
  {
1176
1195
  modelId: "anthropic/claude-opus-4.7",
1177
1196
  label: "Claude Opus 4.7",
1178
- capabilities: { tools: true, forcedToolChoice: true }
1197
+ capabilities: { tools: true, forcedToolChoice: true },
1198
+ contextWindow: 1e6
1179
1199
  },
1180
1200
  {
1181
1201
  modelId: "anthropic/claude-opus-4.7-fast",
1182
1202
  label: "Claude Opus 4.7 (fast)",
1183
- capabilities: { tools: true, forcedToolChoice: true }
1203
+ capabilities: { tools: true, forcedToolChoice: true },
1204
+ contextWindow: 1e6
1184
1205
  },
1185
1206
  {
1186
1207
  modelId: "anthropic/claude-opus-4.8",
1187
1208
  label: "Claude Opus 4.8",
1188
- capabilities: { tools: true, forcedToolChoice: true }
1209
+ capabilities: { tools: true, forcedToolChoice: true },
1210
+ contextWindow: 1e6
1189
1211
  },
1190
1212
  {
1191
1213
  modelId: "anthropic/claude-opus-4.8-fast",
1192
1214
  label: "Claude Opus 4.8 (fast)",
1193
- capabilities: { tools: true, forcedToolChoice: true }
1215
+ capabilities: { tools: true, forcedToolChoice: true },
1216
+ contextWindow: 1e6
1194
1217
  },
1195
1218
  {
1196
1219
  modelId: "anthropic/claude-sonnet-4.6",
1197
1220
  label: "Claude Sonnet 4.6",
1198
- capabilities: { tools: true, forcedToolChoice: true }
1221
+ capabilities: { tools: true, forcedToolChoice: true },
1222
+ contextWindow: 1e6
1199
1223
  },
1200
1224
  // DeepSeek
1201
1225
  {
1202
1226
  modelId: "deepseek/deepseek-v3.2",
1203
1227
  label: "DeepSeek V3.2",
1204
- capabilities: { tools: true, forcedToolChoice: true }
1228
+ capabilities: { tools: true, forcedToolChoice: true },
1229
+ contextWindow: 131072
1205
1230
  },
1206
1231
  {
1207
1232
  modelId: "deepseek/deepseek-v4-flash",
1208
1233
  label: "DeepSeek V4 Flash",
1209
- capabilities: { tools: true, forcedToolChoice: true }
1234
+ capabilities: { tools: true, forcedToolChoice: true },
1235
+ contextWindow: 1048576
1210
1236
  },
1211
1237
  {
1212
1238
  modelId: "deepseek/deepseek-v4-pro",
1213
1239
  label: "DeepSeek V4 Pro",
1214
- capabilities: { tools: true, forcedToolChoice: true }
1240
+ capabilities: { tools: true, forcedToolChoice: true },
1241
+ contextWindow: 1048576
1215
1242
  },
1216
1243
  // Google
1217
1244
  {
1218
1245
  modelId: "google/gemini-3.1-flash-lite-preview",
1219
1246
  label: "Gemini 3.1 Flash Lite (preview)",
1220
- capabilities: { tools: true, forcedToolChoice: true }
1247
+ capabilities: { tools: true, forcedToolChoice: true },
1248
+ contextWindow: 1048576
1221
1249
  },
1222
1250
  {
1223
1251
  modelId: "google/gemini-3.1-pro-preview",
1224
1252
  label: "Gemini 3.1 Pro (preview)",
1225
- capabilities: { tools: true, forcedToolChoice: true }
1253
+ capabilities: { tools: true, forcedToolChoice: true },
1254
+ contextWindow: 1048576
1226
1255
  },
1227
1256
  {
1228
1257
  modelId: "google/gemini-3.5-flash",
1229
1258
  label: "Gemini 3.5 Flash",
1230
- capabilities: { tools: true, forcedToolChoice: true }
1259
+ capabilities: { tools: true, forcedToolChoice: true },
1260
+ contextWindow: 1048576
1231
1261
  },
1232
1262
  {
1233
1263
  modelId: "google/gemma-4-31b-it",
1234
1264
  label: "Gemma 4 31B-IT",
1235
- capabilities: { tools: true, forcedToolChoice: true }
1265
+ capabilities: { tools: true, forcedToolChoice: true },
1266
+ contextWindow: 262144
1267
+ },
1268
+ // MiniMax
1269
+ {
1270
+ modelId: "minimax/minimax-m3",
1271
+ label: "MiniMax M3",
1272
+ // A reasoning model. Some of its OpenRouter endpoints reject a FORCED
1273
+ // tool_choice ('required') → we send 'auto' (forcedToolChoice:false).
1274
+ // reasoning:true makes the provider return reasoning_details so the runner
1275
+ // can round-trip them across tool-call turns.
1276
+ capabilities: { tools: true, forcedToolChoice: false, reasoning: true },
1277
+ contextWindow: 1048576
1236
1278
  }
1237
1279
  ]
1238
1280
  };
1281
+ DEFAULT_CONTEXT_WINDOW = 128e3;
1239
1282
  }
1240
1283
  });
1241
1284
 
@@ -10946,7 +10989,8 @@ function buildGroqModel(config) {
10946
10989
  }
10947
10990
 
10948
10991
  // ../../packages/llm/src/providers/openrouter.ts
10949
- import { createOpenAICompatible as createOpenAICompatible2 } from "@ai-sdk/openai-compatible";
10992
+ init_src();
10993
+ import { createOpenRouter } from "@openrouter/ai-sdk-provider";
10950
10994
  import { wrapLanguageModel } from "ai";
10951
10995
 
10952
10996
  // ../../packages/llm/src/providers/parsers.ts
@@ -11174,15 +11218,21 @@ function buildOpenRouterModel(config) {
11174
11218
  throw new ProviderConfigError("openrouter provider requires an apiKey");
11175
11219
  }
11176
11220
  const baseURL = config.baseURL ?? PROVIDER_PRESETS.openrouter.defaultBaseURL;
11177
- const provider = createOpenAICompatible2({
11178
- name: "openrouter",
11179
- baseURL,
11221
+ const provider = createOpenRouter({
11180
11222
  apiKey: config.apiKey,
11223
+ baseURL,
11224
+ // 'strict' is the documented mode for the first-party OpenRouter API
11225
+ // ('compatible' is for 3rd-party proxies). We hit openrouter.ai directly.
11226
+ compatibility: "strict",
11181
11227
  // Normalise non-spec responses (e.g. DeepSeek V4 returning function.arguments
11182
- // as an object instead of a JSON string) before AI SDK's Zod schema sees them.
11228
+ // as an object instead of a JSON string) before the SDK's Zod schema sees them.
11183
11229
  fetch: createTolerantFetch()
11184
11230
  });
11185
- const base = provider(config.model);
11231
+ const isReasoning = findModelCatalogEntry("openrouter", config.model)?.capabilities.reasoning;
11232
+ const base = provider.chat(
11233
+ config.model,
11234
+ isReasoning ? { extraBody: { reasoning: { enabled: true } } } : void 0
11235
+ );
11186
11236
  const middleware = middlewareForFamily(detectAgenticFamily(config.model));
11187
11237
  if (middleware) {
11188
11238
  return wrapLanguageModel({ model: base, middleware });
@@ -27426,13 +27476,17 @@ async function completeJob(db, jobId, result, toolsUsed = [], stats, messages) {
27426
27476
  }
27427
27477
  }).where(eq4(agentJobs.id, jobId));
27428
27478
  }
27429
- async function failJob(db, jobId, errorCode, stats) {
27479
+ async function failJob(db, jobId, errorCode, stats, messages) {
27430
27480
  const now = /* @__PURE__ */ new Date();
27431
27481
  await db.update(agentJobs).set({
27432
27482
  status: "failed",
27433
27483
  error: errorCode,
27434
27484
  completedAt: now,
27435
27485
  updatedAt: now,
27486
+ // Persist the transcript on failure (mirrors completeJob) so a failed job
27487
+ // is DIAGNOSABLE, not opaque. The resume/guard failure paths used to lose
27488
+ // it entirely. Omitted ⇒ the stored messages are left untouched.
27489
+ ...messages ? { messages } : {},
27436
27490
  ...stats && {
27437
27491
  inputTokens: stats.inputTokens,
27438
27492
  outputTokens: stats.outputTokens,
@@ -27654,6 +27708,40 @@ function truncateForContext(value) {
27654
27708
 
27655
27709
  [... truncated: ${dropped} chars dropped (total ${value.length}) ...]`;
27656
27710
  }
27711
+ var EVICTED_TOOL_RESULT_MARKER = "[earlier tool result elided to fit the context window \u2014 re-run the tool if you need this data again]";
27712
+ function compactOldToolResults(messages, keepRecentToolMessages) {
27713
+ const toolMsgIdx = [];
27714
+ messages.forEach((m, i) => {
27715
+ if (m.role === "tool") toolMsgIdx.push(i);
27716
+ });
27717
+ const evictCount = toolMsgIdx.length - keepRecentToolMessages;
27718
+ if (evictCount <= 0) return { messages: [...messages], evicted: 0 };
27719
+ const evictIdx = new Set(toolMsgIdx.slice(0, evictCount));
27720
+ let evicted = 0;
27721
+ const out = messages.map((m, i) => {
27722
+ if (!evictIdx.has(i) || m.role !== "tool" || !Array.isArray(m.content)) return m;
27723
+ const content = m.content.map((p) => {
27724
+ if (p.type !== "tool-result") return p;
27725
+ if (p.output.type === "text" && p.output.value === EVICTED_TOOL_RESULT_MARKER) return p;
27726
+ evicted += 1;
27727
+ return { ...p, output: { type: "text", value: EVICTED_TOOL_RESULT_MARKER } };
27728
+ });
27729
+ return { ...m, content };
27730
+ });
27731
+ return { messages: out, evicted };
27732
+ }
27733
+ function describeLlmError(err) {
27734
+ if (!(err instanceof Error)) return "unknown_error";
27735
+ const e = err;
27736
+ const body = typeof e.responseBody === "string" && e.responseBody.trim().length > 0 ? e.responseBody : "";
27737
+ const dataStr = !body && e.data != null ? JSON.stringify(e.data) : "";
27738
+ const detail = body || dataStr;
27739
+ if (detail) {
27740
+ const status = typeof e.statusCode === "number" ? `${e.statusCode} ` : "";
27741
+ return `${status}${err.message}: ${detail}`.slice(0, 400);
27742
+ }
27743
+ return err.message.slice(0, 200);
27744
+ }
27657
27745
  function stableStringify(value) {
27658
27746
  return JSON.stringify(value, (_key, val) => {
27659
27747
  if (val && typeof val === "object" && !Array.isArray(val)) {
@@ -27692,6 +27780,7 @@ async function executeJob(jobId, deps, _runnerEnv) {
27692
27780
  });
27693
27781
  return { status: "failed", error: "chain_limit_exceeded" };
27694
27782
  }
27783
+ let messages = Array.isArray(job.messages) ? job.messages : [];
27695
27784
  let inputTokens = job.inputTokens ?? 0;
27696
27785
  let outputTokens = job.outputTokens ?? 0;
27697
27786
  let turn = job.turn ?? 0;
@@ -27704,13 +27793,13 @@ async function executeJob(jobId, deps, _runnerEnv) {
27704
27793
  });
27705
27794
  await setJobStatus(db, jobId, "processing");
27706
27795
  if (!job.agentId) {
27707
- await failJob(db, jobId, "agent_not_found", runStats());
27796
+ await failJob(db, jobId, "agent_not_found", runStats(), messages);
27708
27797
  return { status: "failed", error: "agent_not_found" };
27709
27798
  }
27710
27799
  const agentRows = await db.select().from(agents).where(eq4(agents.id, job.agentId)).limit(1);
27711
27800
  const agentRow = agentRows[0];
27712
27801
  if (!agentRow || !agentRow.active) {
27713
- await failJob(db, jobId, "agent_not_found", runStats());
27802
+ await failJob(db, jobId, "agent_not_found", runStats(), messages);
27714
27803
  return { status: "failed", error: "agent_not_found" };
27715
27804
  }
27716
27805
  const agent = {
@@ -27728,7 +27817,7 @@ async function executeJob(jobId, deps, _runnerEnv) {
27728
27817
  const wsRows = await db.select({ label: agentWorkspaces.label, path: agentWorkspaces.path }).from(agentWorkspaces).where(eq4(agentWorkspaces.agentId, agentRow.id)).orderBy(agentWorkspaces.position, agentWorkspaces.label);
27729
27818
  const agentWorkspacesList = wsRows;
27730
27819
  if (!agentRow.llmKeyId) {
27731
- await failJob(db, jobId, "agent_no_llm_configured", runStats());
27820
+ await failJob(db, jobId, "agent_no_llm_configured", runStats(), messages);
27732
27821
  return { status: "failed", error: "agent_no_llm_configured" };
27733
27822
  }
27734
27823
  {
@@ -27743,7 +27832,7 @@ async function executeJob(jobId, deps, _runnerEnv) {
27743
27832
  );
27744
27833
  if (!resolved.ok) {
27745
27834
  const code = resolved.reason === "agent_no_llm_configured" ? "agent_no_llm_configured" : `llm_key_invalid:${resolved.detail}`;
27746
- await failJob(db, jobId, code, runStats());
27835
+ await failJob(db, jobId, code, runStats(), messages);
27747
27836
  return { status: "failed", error: code };
27748
27837
  }
27749
27838
  llmClient = resolved.client;
@@ -27778,7 +27867,7 @@ async function executeJob(jobId, deps, _runnerEnv) {
27778
27867
  let toolDefs;
27779
27868
  const memoryBuiltins = ALWAYS_ON_TOOLS.filter((n) => n !== "return_result").map((n) => registry.get(n)).filter((t) => t !== void 0);
27780
27869
  const capabilityTools = [];
27781
- if (agentRow.telegramBotToken) {
27870
+ if (agentRow.telegramBotToken && job.chatId) {
27782
27871
  capabilityTools.push(createTelegramSendMessageTool());
27783
27872
  }
27784
27873
  const mcpClosers = [];
@@ -27931,7 +28020,7 @@ async function executeJob(jobId, deps, _runnerEnv) {
27931
28020
  }
27932
28021
  } catch (err) {
27933
28022
  const errorCode = err instanceof Error ? err.message : "whitelist_computation_failed";
27934
- await failJob(db, jobId, errorCode, runStats());
28023
+ await failJob(db, jobId, errorCode, runStats(), messages);
27935
28024
  return { status: "failed", error: errorCode };
27936
28025
  }
27937
28026
  const ruleRows = await db.select().from(approvalRules).where(eq4(approvalRules.entityId, job.entityId ?? ""));
@@ -27950,7 +28039,6 @@ async function executeJob(jobId, deps, _runnerEnv) {
27950
28039
  const mcpToolNames = await listWorkspaceMcpToolNames(db, job.entityId ?? "");
27951
28040
  authoringToolsSuffix = mcpToolNames.length > 0 ? ` When a skill needs an MCP tool, reference one of these EXACT names available in this workspace (built-in and connector tools are bare snake_case and need no namespace): ${mcpToolNames.join(", ")}.` : " This workspace has no MCP servers connected yet \u2014 a skill should only reference built-in tools (bare snake_case) or none.";
27952
28041
  }
27953
- let messages = Array.isArray(job.messages) ? job.messages : [];
27954
28042
  if (messages.length === 0) {
27955
28043
  messages = [{ role: "user", content: job.task }];
27956
28044
  }
@@ -28092,6 +28180,18 @@ async function executeJob(jobId, deps, _runnerEnv) {
28092
28180
  const n = raw ? Number(raw) : NaN;
28093
28181
  return Number.isFinite(n) && n > 0 ? n : DEFAULT_LIMITS.maxTotalTokensPerJob;
28094
28182
  })();
28183
+ const compactionThreshold = (() => {
28184
+ const ctxWindow = modelContextWindow(llmClient.config.provider, llmClient.config.model);
28185
+ const fracRaw = Number(process.env["LLM_COMPACTION_FRACTION"]);
28186
+ const frac = Number.isFinite(fracRaw) && fracRaw > 0 && fracRaw < 1 ? fracRaw : 0.7;
28187
+ const absRaw = Number(process.env["LLM_COMPACTION_TOKENS"]);
28188
+ const abs = Number.isFinite(absRaw) && absRaw > 0 ? absRaw : 12e4;
28189
+ return Math.min(Math.floor(frac * ctxWindow), abs);
28190
+ })();
28191
+ const compactionKeepRecentToolMsgs = (() => {
28192
+ const raw = Number(process.env["LLM_COMPACTION_KEEP_TURNS"]);
28193
+ return Number.isFinite(raw) && raw >= 1 ? Math.floor(raw) : 3;
28194
+ })();
28095
28195
  const recentTurnSignatures = [];
28096
28196
  const maxNoProgressRepeats = (() => {
28097
28197
  const raw = process.env["MAX_NO_PROGRESS_REPEATS"];
@@ -28112,7 +28212,7 @@ async function executeJob(jobId, deps, _runnerEnv) {
28112
28212
  return { status: "cancelled" };
28113
28213
  }
28114
28214
  if (turn > DEFAULT_LIMITS.maxTurns) {
28115
- await failJob(db, jobId, "turn_limit_exceeded", runStats());
28215
+ await failJob(db, jobId, "turn_limit_exceeded", runStats(), messages);
28116
28216
  return { status: "failed", error: "turn_limit_exceeded" };
28117
28217
  }
28118
28218
  validateMessageStructure(messages);
@@ -28141,9 +28241,21 @@ async function executeJob(jobId, deps, _runnerEnv) {
28141
28241
  outputTokens += Number.isFinite(completionT) ? completionT : 0;
28142
28242
  if (inputTokens + outputTokens > maxTotalTokensPerJob) {
28143
28243
  trace("token_budget_exceeded", { turn, inputTokens, outputTokens, maxTotalTokensPerJob });
28144
- await failJob(db, jobId, "token_budget_exceeded", runStats());
28244
+ await failJob(db, jobId, "token_budget_exceeded", runStats(), messages);
28145
28245
  return { status: "failed", error: "token_budget_exceeded" };
28146
28246
  }
28247
+ if (promptT > compactionThreshold) {
28248
+ const ev = compactOldToolResults(messages, compactionKeepRecentToolMsgs);
28249
+ if (ev.evicted > 0) {
28250
+ messages = ev.messages;
28251
+ trace("context_compacted", {
28252
+ turn,
28253
+ promptTokens: promptT,
28254
+ threshold: compactionThreshold,
28255
+ evictedToolResults: ev.evicted
28256
+ });
28257
+ }
28258
+ }
28147
28259
  const rawToolCalls = response.toolCalls ?? [];
28148
28260
  trace("llm_call_done", {
28149
28261
  turn,
@@ -28155,17 +28267,21 @@ async function executeJob(jobId, deps, _runnerEnv) {
28155
28267
  consecutiveDeliveryOnlyTurns = isDeliveryOnlyTurn ? consecutiveDeliveryOnlyTurns + 1 : 0;
28156
28268
  if (consecutiveDeliveryOnlyTurns > DEFAULT_LIMITS.maxConsecutiveDeliveryTurns) {
28157
28269
  trace("delivery_spam_guard", { turn, consecutiveDeliveryOnlyTurns });
28158
- await failJob(db, jobId, "delivery_spam_guard", runStats());
28270
+ await failJob(db, jobId, "delivery_spam_guard", runStats(), messages);
28159
28271
  return { status: "failed", error: "delivery_spam_guard" };
28160
28272
  }
28273
+ const reasoningParts = response.reasoning ?? [];
28161
28274
  const assistantMsg = {
28162
28275
  role: "assistant",
28163
- content: rawToolCalls.length > 0 ? rawToolCalls.map((tc) => ({
28164
- type: "tool-call",
28165
- toolCallId: tc.toolCallId,
28166
- toolName: tc.toolName,
28167
- input: tc.input
28168
- })) : response.text || ""
28276
+ content: rawToolCalls.length > 0 ? [
28277
+ ...reasoningParts,
28278
+ ...rawToolCalls.map((tc) => ({
28279
+ type: "tool-call",
28280
+ toolCallId: tc.toolCallId,
28281
+ toolName: tc.toolName,
28282
+ input: tc.input
28283
+ }))
28284
+ ] : reasoningParts.length > 0 ? [...reasoningParts, { type: "text", text: response.text || "" }] : response.text || ""
28169
28285
  };
28170
28286
  messages = [...messages, assistantMsg];
28171
28287
  const returnResultCall = rawToolCalls.find((tc) => tc.toolName === "return_result");
@@ -28188,7 +28304,7 @@ async function executeJob(jobId, deps, _runnerEnv) {
28188
28304
  continue;
28189
28305
  }
28190
28306
  trace("telegram_not_delivered", { turn, via: "text_branch" });
28191
- await failJob(db, jobId, "telegram_not_delivered", runStats());
28307
+ await failJob(db, jobId, "telegram_not_delivered", runStats(), messages);
28192
28308
  return { status: "failed", error: "telegram_not_delivered" };
28193
28309
  }
28194
28310
  await completeJob(db, jobId, textContent, toolsUsed, runStats(), messages);
@@ -28200,7 +28316,8 @@ async function executeJob(jobId, deps, _runnerEnv) {
28200
28316
  messages = messages.slice(0, -1);
28201
28317
  continue;
28202
28318
  }
28203
- await failJob(db, jobId, "no_tool_calls_no_text", runStats());
28319
+ messages = messages.slice(0, -1);
28320
+ await failJob(db, jobId, "no_tool_calls_no_text", runStats(), messages);
28204
28321
  return { status: "failed", error: "no_tool_calls_no_text" };
28205
28322
  }
28206
28323
  const rawCallBlocks = rawToolCalls.map((tc) => ({
@@ -28235,7 +28352,13 @@ async function executeJob(jobId, deps, _runnerEnv) {
28235
28352
  toolsUsed = [.../* @__PURE__ */ new Set([...toolsUsed, call.name])];
28236
28353
  const toolDef = toolMap.get(call.name);
28237
28354
  if (!toolDef) {
28238
- await failJob(db, jobId, `whitelist_violation:${call.name}`, runStats());
28355
+ await failJob(
28356
+ db,
28357
+ jobId,
28358
+ `whitelist_violation:${call.name}`,
28359
+ runStats(),
28360
+ messages
28361
+ );
28239
28362
  return { status: "failed", error: `whitelist_violation:${call.name}` };
28240
28363
  }
28241
28364
  if (call.name.startsWith("assign_")) {
@@ -28470,7 +28593,7 @@ async function executeJob(jobId, deps, _runnerEnv) {
28470
28593
  continue;
28471
28594
  }
28472
28595
  trace("unresolved_tool_failure", { turn, stuck });
28473
- await failJob(db, jobId, "unresolved_tool_failure", runStats());
28596
+ await failJob(db, jobId, "unresolved_tool_failure", runStats(), messages);
28474
28597
  return { status: "failed", error: "unresolved_tool_failure" };
28475
28598
  }
28476
28599
  const taskRows = await db.select({ id: agentTasks.id }).from(agentTasks).where(eq4(agentTasks.rootJobId, jobId));
@@ -28495,7 +28618,7 @@ async function executeJob(jobId, deps, _runnerEnv) {
28495
28618
  continue;
28496
28619
  }
28497
28620
  trace("telegram_not_delivered", { turn, via: "return_result_branch" });
28498
- await failJob(db, jobId, "telegram_not_delivered", runStats());
28621
+ await failJob(db, jobId, "telegram_not_delivered", runStats(), messages);
28499
28622
  return { status: "failed", error: "telegram_not_delivered" };
28500
28623
  }
28501
28624
  const finalResult = "";
@@ -28545,7 +28668,7 @@ async function executeJob(jobId, deps, _runnerEnv) {
28545
28668
  }
28546
28669
  if (recentTurnSignatures.length === maxNoProgressRepeats && recentTurnSignatures.every((s) => s === turnSignature)) {
28547
28670
  trace("no_progress_detected", { turn, repeats: recentTurnSignatures.length });
28548
- await failJob(db, jobId, "no_progress_detected", runStats());
28671
+ await failJob(db, jobId, "no_progress_detected", runStats(), messages);
28549
28672
  return { status: "failed", error: "no_progress_detected" };
28550
28673
  }
28551
28674
  }
@@ -28561,30 +28684,36 @@ async function executeJob(jobId, deps, _runnerEnv) {
28561
28684
  } catch (err) {
28562
28685
  trace("catch", {
28563
28686
  errName: err instanceof Error ? err.name : "unknown",
28564
- errMsg: err instanceof Error ? err.message.slice(0, 200) : String(err)
28687
+ errMsg: describeLlmError(err)
28565
28688
  });
28566
28689
  if (err instanceof ToolCallLimitExceededError) {
28567
- await failJob(db, jobId, err.code, runStats());
28690
+ await failJob(db, jobId, err.code, runStats(), messages);
28568
28691
  return { status: "failed", error: err.code };
28569
28692
  }
28570
28693
  if (err instanceof ChainLimitExceededError) {
28571
- await failJob(db, jobId, err.code, runStats());
28694
+ await failJob(db, jobId, err.code, runStats(), messages);
28572
28695
  return { status: "failed", error: err.code };
28573
28696
  }
28574
28697
  if (err instanceof DelegationDepthExceededError) {
28575
- await failJob(db, jobId, err.code, runStats());
28698
+ await failJob(db, jobId, err.code, runStats(), messages);
28576
28699
  return { status: "failed", error: err.code };
28577
28700
  }
28578
28701
  if (err instanceof QuotaExhaustedError) {
28579
- await failJob(db, jobId, "quota_exhausted", runStats());
28702
+ await failJob(db, jobId, "quota_exhausted", runStats(), messages);
28580
28703
  return { status: "failed", error: "quota_exhausted" };
28581
28704
  }
28582
28705
  if (err instanceof AllProvidersFailedError) {
28583
- await failJob(db, jobId, err.code, runStats());
28706
+ await failJob(db, jobId, err.code, runStats(), messages);
28584
28707
  return { status: "failed", error: err.code };
28585
28708
  }
28586
28709
  if (err instanceof MessageStructureError) {
28587
- await failJob(db, jobId, `message_structure_invalid:${err.code}`, runStats());
28710
+ await failJob(
28711
+ db,
28712
+ jobId,
28713
+ `message_structure_invalid:${err.code}`,
28714
+ runStats(),
28715
+ messages
28716
+ );
28588
28717
  return { status: "failed", error: `message_structure_invalid:${err.code}` };
28589
28718
  }
28590
28719
  if (err instanceof Error) {
@@ -28594,12 +28723,12 @@ async function executeJob(jobId, deps, _runnerEnv) {
28594
28723
  if (unavailableMatch) {
28595
28724
  const toolName = unavailableMatch[1] ?? "unknown_tool";
28596
28725
  const code = `whitelist_violation:${toolName}`;
28597
- await failJob(db, jobId, code, runStats());
28726
+ await failJob(db, jobId, code, runStats(), messages);
28598
28727
  return { status: "failed", error: code };
28599
28728
  }
28600
28729
  }
28601
- const errorCode = err instanceof Error ? err.message.slice(0, 200) : "unknown_error";
28602
- await failJob(db, jobId, errorCode, runStats());
28730
+ const errorCode = describeLlmError(err);
28731
+ await failJob(db, jobId, errorCode, runStats(), messages);
28603
28732
  return { status: "failed", error: errorCode };
28604
28733
  } finally {
28605
28734
  for (const close of mcpClosers) {
@@ -29208,6 +29337,7 @@ var CHAT_TOOLS = {
29208
29337
  inputSchema: z89.object({ instruction: z89.string().min(1).max(4e3) })
29209
29338
  }
29210
29339
  };
29340
+ var ESCALATION_RECHECK = "Re-read your previous reply. If it committed to performing an action \u2014 running, launching, sending, fetching, creating, configuring, delegating, or any task or tool use \u2014 then your text ALONE did nothing: call the run_task tool NOW with a clear, self-contained instruction. If your reply was pure conversation, a question, or simply recalling a fact, do not call any tool \u2014 the conversation is complete.";
29211
29341
  async function runChatTurn(opts) {
29212
29342
  const { deps, entityId, agentId, conversationId, message } = opts;
29213
29343
  const db = deps.db;
@@ -29249,8 +29379,43 @@ async function runChatTurn(opts) {
29249
29379
  origin: "dashboard",
29250
29380
  surface: "chat"
29251
29381
  });
29252
- const rows = await db.select({ role: chatMessages.role, content: chatMessages.content }).from(chatMessages).where(eq4(chatMessages.conversationId, conversationId)).orderBy(desc(chatMessages.createdAt)).limit(HISTORY_LIMIT);
29253
- const messages = rows.reverse().map((r) => ({ role: r.role, content: r.content }));
29382
+ const rows = await db.select({
29383
+ role: chatMessages.role,
29384
+ content: chatMessages.content,
29385
+ jobId: chatMessages.jobId,
29386
+ jobTask: agentJobs.task
29387
+ }).from(chatMessages).leftJoin(agentJobs, eq4(chatMessages.jobId, agentJobs.id)).where(eq4(chatMessages.conversationId, conversationId)).orderBy(desc(chatMessages.createdAt)).limit(HISTORY_LIMIT);
29388
+ const messages = [];
29389
+ for (const r of rows.reverse()) {
29390
+ if (r.role === "assistant" && r.jobId) {
29391
+ const toolCallId = `hist-${r.jobId}`;
29392
+ messages.push({
29393
+ role: "assistant",
29394
+ content: [
29395
+ ...r.content ? [{ type: "text", text: r.content }] : [],
29396
+ {
29397
+ type: "tool-call",
29398
+ toolCallId,
29399
+ toolName: "run_task",
29400
+ input: { instruction: r.jobTask ?? "" }
29401
+ }
29402
+ ]
29403
+ });
29404
+ messages.push({
29405
+ role: "tool",
29406
+ content: [
29407
+ {
29408
+ type: "tool-result",
29409
+ toolCallId,
29410
+ toolName: "run_task",
29411
+ output: { type: "text", value: "Task dispatched." }
29412
+ }
29413
+ ]
29414
+ });
29415
+ } else {
29416
+ messages.push({ role: r.role, content: r.content });
29417
+ }
29418
+ }
29254
29419
  let text22 = "";
29255
29420
  let runTask;
29256
29421
  try {
@@ -29261,7 +29426,23 @@ async function runChatTurn(opts) {
29261
29426
  });
29262
29427
  text22 = (response.text ?? "").trim();
29263
29428
  runTask = (response.toolCalls ?? []).find((tc) => tc.toolName === "run_task");
29264
- } catch {
29429
+ } catch (err) {
29430
+ console.warn(`[run-chat-turn] tools call failed (${agentRow.slug}):`, err.message);
29431
+ }
29432
+ if (!runTask && text22) {
29433
+ try {
29434
+ const recheck = await llmClient.generateText({
29435
+ system: systemPrompt,
29436
+ messages: [
29437
+ ...messages,
29438
+ { role: "assistant", content: text22 },
29439
+ { role: "user", content: ESCALATION_RECHECK }
29440
+ ],
29441
+ tools: CHAT_TOOLS
29442
+ });
29443
+ runTask = (recheck.toolCalls ?? []).find((tc) => tc.toolName === "run_task");
29444
+ } catch {
29445
+ }
29265
29446
  }
29266
29447
  if (runTask) {
29267
29448
  const instruction = String(runTask.input?.instruction ?? "").trim() || message;
@@ -1 +1 @@
1
- ZuUX-HBTQOhLf0tFI6JQI
1
+ PV5qpGylrVW3jZ7zKHuhE
@@ -4,8 +4,8 @@
4
4
  ],
5
5
  "devFiles": [],
6
6
  "lowPriorityFiles": [
7
- "static/ZuUX-HBTQOhLf0tFI6JQI/_buildManifest.js",
8
- "static/ZuUX-HBTQOhLf0tFI6JQI/_ssgManifest.js"
7
+ "static/PV5qpGylrVW3jZ7zKHuhE/_buildManifest.js",
8
+ "static/PV5qpGylrVW3jZ7zKHuhE/_ssgManifest.js"
9
9
  ],
10
10
  "rootMainFiles": [
11
11
  "static/chunks/webpack-3741bf0a7636d65e.js",
@@ -78,8 +78,8 @@
78
78
  "dynamicRoutes": {},
79
79
  "notFoundRoutes": [],
80
80
  "preview": {
81
- "previewModeId": "3ee52df782a2df2a4ee50789902ca7be",
82
- "previewModeSigningKey": "89ca14b4b6d0a92f00c85b444ae7555c09e000f7447bbab9332647fa03c9e2ae",
83
- "previewModeEncryptionKey": "c5e0ed4849dcf791d73cc1bb97004c7e4b13127cb4b820419f39aa7aea22021e"
81
+ "previewModeId": "ab66490d94469ea63e5777d5e5465b39",
82
+ "previewModeSigningKey": "3b725fc347ffafb5d6ab5906e8f5f39cb4523c75a6a3769d4e6779e014736265",
83
+ "previewModeEncryptionKey": "356915c85cb0a6b84c6f46dc1bceb092c3ed009fbca03946585cea052e5c754c"
84
84
  }
85
85
  }