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.
- package/README.md +12 -12
- package/package.json +2 -1
- package/runner.js +247 -66
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js +3 -3
- package/web/.next/server/app/(dashboard)/agents/[id]/edit/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/agents/[id]/edit/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page.js +2 -2
- package/web/.next/server/app/(dashboard)/agents/[id]/telegram/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/agents/page.js +2 -2
- package/web/.next/server/app/(dashboard)/agents/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/approvals/page.js +2 -2
- package/web/.next/server/app/(dashboard)/approvals/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/approvals/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/automations/page.js +2 -2
- package/web/.next/server/app/(dashboard)/automations/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/billing/page.js +2 -2
- package/web/.next/server/app/(dashboard)/billing/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/chat/page.js +1 -1
- package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/connectors/page.js +1 -1
- package/web/.next/server/app/(dashboard)/connectors/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/connectors/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/credentials/page.js +1 -1
- package/web/.next/server/app/(dashboard)/credentials/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/credentials/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/jobs/[id]/page.js +2 -2
- package/web/.next/server/app/(dashboard)/jobs/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/jobs/page.js +2 -2
- package/web/.next/server/app/(dashboard)/jobs/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/jobs/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/llm-providers/page.js +1 -1
- package/web/.next/server/app/(dashboard)/llm-providers/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/logs/page.js +2 -2
- package/web/.next/server/app/(dashboard)/logs/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/mcp/page.js +1 -1
- package/web/.next/server/app/(dashboard)/mcp/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/memories/page.js +2 -2
- package/web/.next/server/app/(dashboard)/memories/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page.js +4 -4
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/settings/page.js +2 -2
- package/web/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/[id]/edit/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/skills/[id]/edit/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/new/page.js +2 -2
- package/web/.next/server/app/(dashboard)/skills/new/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/skills/new/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/page.js +1 -1
- package/web/.next/server/app/(dashboard)/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +1 -1
- package/web/.next/server/app/_global-error.rsc +2 -2
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
- package/web/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +2 -2
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/server/app/_not-found.rsc +2 -2
- package/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/api/oauth/[provider]/callback/route.js +1 -1
- package/web/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/onboarding.html +1 -1
- package/web/.next/server/app/onboarding.rsc +2 -2
- package/web/.next/server/app/onboarding.segments/_full.segment.rsc +2 -2
- package/web/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/onboarding.segments/_index.segment.rsc +2 -2
- package/web/.next/server/app/onboarding.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
- package/web/.next/server/chunks/3233.js +1 -1
- package/web/.next/server/chunks/3889.js +1 -0
- package/web/.next/server/chunks/5329.js +1 -0
- package/web/.next/server/chunks/593.js +1 -0
- package/web/.next/server/chunks/7231.js +1 -0
- package/web/.next/server/chunks/7741.js +1 -1
- package/web/.next/server/middleware-build-manifest.js +1 -1
- package/web/.next/server/pages/404.html +1 -1
- package/web/.next/server/pages/500.html +1 -1
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/static/chunks/{9123-20653d928e33410a.js → 9123-67530ba510c58003.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-a2c267f563cd1a70.js +2 -0
- package/web/.next/static/chunks/app/(dashboard)/agents/[id]/telegram/page-2d7cae43f5e6952a.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/agents/page-bed833ebdd3646fb.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/approvals/{page-79dea6e91956eeba.js → page-4b27762472802ce0.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/automations/{page-3b863b7af8e2c1a3.js → page-9e5d2ce807ce1c37.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/chat/page-8f81d7e3abb475a6.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/connectors/{page-4a437ba82f4086da.js → page-39b1d9560235d574.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/page-112bb22a9ec43be0.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/jobs/{page-94a311f688a255d8.js → page-44351170ed5f9180.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/{layout-e1b0d4fad2926646.js → layout-53e69de869cba0d0.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/llm-providers/{page-e5e2c4e2b783d37f.js → page-8f6ce47ba228e38b.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/mcp/page-cdf057e468c6e92e.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/memories/page-e706ab4aa681fa99.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/{page-fb50e1576a3ab2e4.js → page-29cfae3bf701076e.js} +1 -1
- package/web/.next/static/chunks/app/(dashboard)/settings/page-312ae27ae71ea6d1.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/skills/[id]/edit/page-89a8a30db5eb96e1.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/skills/new/page-46a424b203591560.js +1 -0
- package/web/.next/static/chunks/app/(dashboard)/skills/page-edad7bbd3230fb7a.js +1 -0
- package/web/.next/server/chunks/1945.js +0 -1
- package/web/.next/server/chunks/4839.js +0 -1
- package/web/.next/server/chunks/8206.js +0 -1
- package/web/.next/server/chunks/8398.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/agents/[id]/edit/page-a8e293c54c818084.js +0 -2
- package/web/.next/static/chunks/app/(dashboard)/agents/[id]/telegram/page-7a94ae67b2c3c9c3.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/agents/page-b258b8975ac6450b.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/chat/page-4d965bb7ee3732db.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/jobs/[id]/page-be20dcbf25c8f3ce.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/mcp/page-c071c54f76273ac4.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/memories/page-8ca0b34ad35eb1fa.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/settings/page-7b256e9c462e97f8.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/skills/[id]/edit/page-12930816795e8b20.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/skills/new/page-e3a19abaf7468db9.js +0 -1
- package/web/.next/static/chunks/app/(dashboard)/skills/page-43f1475a0bc9c45f.js +0 -1
- /package/web/.next/static/{ZuUX-HBTQOhLf0tFI6JQI → PV5qpGylrVW3jZ7zKHuhE}/_buildManifest.js +0 -0
- /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
|
-
|
|
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
|
-
{
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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 ?
|
|
28164
|
-
|
|
28165
|
-
|
|
28166
|
-
|
|
28167
|
-
|
|
28168
|
-
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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(
|
|
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
|
|
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({
|
|
29253
|
-
|
|
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;
|
package/web/.next/BUILD_ID
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
PV5qpGylrVW3jZ7zKHuhE
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
],
|
|
5
5
|
"devFiles": [],
|
|
6
6
|
"lowPriorityFiles": [
|
|
7
|
-
"static/
|
|
8
|
-
"static/
|
|
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": "
|
|
82
|
-
"previewModeSigningKey": "
|
|
83
|
-
"previewModeEncryptionKey": "
|
|
81
|
+
"previewModeId": "ab66490d94469ea63e5777d5e5465b39",
|
|
82
|
+
"previewModeSigningKey": "3b725fc347ffafb5d6ab5906e8f5f39cb4523c75a6a3769d4e6779e014736265",
|
|
83
|
+
"previewModeEncryptionKey": "356915c85cb0a6b84c6f46dc1bceb092c3ed009fbca03946585cea052e5c754c"
|
|
84
84
|
}
|
|
85
85
|
}
|