flavor-code 1.3.10 → 1.3.12
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/dist/agent/types.d.ts +3 -0
- package/dist/{app-YSBW7GXH.js → app-Z7D7XPVE.js} +118 -206
- package/dist/{chunk-KKIBYDJI.js → chunk-2BF7CVWZ.js} +5 -7
- package/dist/{chunk-T2ARW6CZ.js → chunk-EZNIDHFZ.js} +1 -1
- package/dist/{chunk-IG4Z23CL.js → chunk-JFKRX2KG.js} +7 -0
- package/dist/{chunk-Y3DPUAEJ.js → chunk-QC5OYQTB.js} +508 -39
- package/dist/cli.js +6 -6
- package/dist/config/schema.d.ts +12 -0
- package/dist/desktop/main.js +297 -38
- package/dist/desktop-renderer/assets/index-CE6mw-at.js +154 -0
- package/dist/desktop-renderer/assets/index-DHTr_Acb.css +1 -0
- package/dist/desktop-renderer/assets/{interactive-terminal-BwS6MvIe.js → interactive-terminal-DcaRc1vO.js} +1 -1
- package/dist/desktop-renderer/index.html +2 -2
- package/dist/{load-GKA7P6RJ.js → load-LTTKVPJZ.js} +1 -1
- package/dist/models/anthropic.d.ts +7 -0
- package/dist/models/openai.d.ts +3 -0
- package/dist/models/structured.d.ts +13 -4
- package/dist/models/types.d.ts +19 -0
- package/dist/production.d.ts +2 -0
- package/dist/sdk/index.js +3 -3
- package/dist/tools/runtime.d.ts +5 -0
- package/dist/ui/char-width.d.ts +12 -0
- package/dist/ui/commands.d.ts +7 -3
- package/dist/ui/session.d.ts +5 -0
- package/dist/ui/thinking-line.d.ts +42 -0
- package/dist/ui/transcript.d.ts +2 -0
- package/package.json +1 -1
- package/dist/desktop-renderer/assets/index-CdeAi527.css +0 -1
- package/dist/desktop-renderer/assets/index-bFGsR_uj.js +0 -154
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
redactConfig,
|
|
13
13
|
setProjectMcpServerDisabled,
|
|
14
14
|
updateProtectedFile
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-JFKRX2KG.js";
|
|
16
16
|
import {
|
|
17
17
|
AuditLogger,
|
|
18
18
|
appendUsageLog,
|
|
@@ -1082,6 +1082,231 @@ function packageVersion() {
|
|
|
1082
1082
|
throw new Error("package.json with a version field was not found");
|
|
1083
1083
|
}
|
|
1084
1084
|
|
|
1085
|
+
// src/ui/char-width.ts
|
|
1086
|
+
function charWidth(codePoint) {
|
|
1087
|
+
if (codePoint === 8203 || // ZERO WIDTH SPACE
|
|
1088
|
+
codePoint === 8204 || // ZERO WIDTH NON-JOINER
|
|
1089
|
+
codePoint === 8205 || // ZERO WIDTH JOINER
|
|
1090
|
+
codePoint === 65279 || // BOM / ZERO WIDTH NO-BREAK SPACE
|
|
1091
|
+
codePoint >= 768 && codePoint <= 879 || // Combining Diacritical Marks
|
|
1092
|
+
codePoint >= 1155 && codePoint <= 1161 || // Cyrillic combining marks
|
|
1093
|
+
codePoint >= 1425 && codePoint <= 1469 || // Hebrew combining marks
|
|
1094
|
+
codePoint >= 1552 && codePoint <= 1562 || // Arabic combining marks
|
|
1095
|
+
codePoint >= 1611 && codePoint <= 1631 || // Arabic combining marks
|
|
1096
|
+
codePoint >= 1648 && codePoint <= 1648 || // Arabic combining marks
|
|
1097
|
+
codePoint >= 1750 && codePoint <= 1756 || // Arabic combining marks
|
|
1098
|
+
codePoint >= 1759 && codePoint <= 1764 || // Arabic combining marks
|
|
1099
|
+
codePoint >= 1767 && codePoint <= 1768 || // Arabic combining marks
|
|
1100
|
+
codePoint >= 1770 && codePoint <= 1773 || // Arabic combining marks
|
|
1101
|
+
codePoint >= 1809 && codePoint <= 1809 || // Syriac combining marks
|
|
1102
|
+
codePoint >= 1840 && codePoint <= 1866 || // Syriac combining marks
|
|
1103
|
+
codePoint >= 1958 && codePoint <= 1968 || // Thaana combining marks
|
|
1104
|
+
codePoint >= 2304 && codePoint <= 2306 || // Devanagari combining marks
|
|
1105
|
+
codePoint >= 2362 && codePoint <= 2362 || // Devanagari combining marks
|
|
1106
|
+
codePoint >= 2364 && codePoint <= 2364 || // Devanagari combining marks
|
|
1107
|
+
codePoint >= 2369 && codePoint <= 2376 || // Devanagari combining marks
|
|
1108
|
+
codePoint >= 2381 && codePoint <= 2381 || // Devanagari combining marks
|
|
1109
|
+
codePoint >= 2385 && codePoint <= 2391 || // Devanagari combining marks
|
|
1110
|
+
codePoint >= 2402 && codePoint <= 2403 || // Devanagari combining marks
|
|
1111
|
+
codePoint >= 2433 && codePoint <= 2433 || // Bengali combining marks
|
|
1112
|
+
codePoint >= 2492 && codePoint <= 2492 || // Bengali combining marks
|
|
1113
|
+
codePoint >= 2497 && codePoint <= 2500 || // Bengali combining marks
|
|
1114
|
+
codePoint >= 2509 && codePoint <= 2509 || // Bengali combining marks
|
|
1115
|
+
codePoint >= 2530 && codePoint <= 2531 || // Bengali combining marks
|
|
1116
|
+
codePoint >= 2561 && codePoint <= 2562 || // Gurmukhi combining marks
|
|
1117
|
+
codePoint >= 2620 && codePoint <= 2620 || // Gurmukhi combining marks
|
|
1118
|
+
codePoint >= 2625 && codePoint <= 2626 || // Gurmukhi combining marks
|
|
1119
|
+
codePoint >= 2631 && codePoint <= 2632 || // Gurmukhi combining marks
|
|
1120
|
+
codePoint >= 2635 && codePoint <= 2637 || // Gurmukhi combining marks
|
|
1121
|
+
codePoint >= 2672 && codePoint <= 2673 || // Gurmukhi combining marks
|
|
1122
|
+
codePoint >= 2689 && codePoint <= 2690 || // Gujarati combining marks
|
|
1123
|
+
codePoint >= 2748 && codePoint <= 2748 || // Gujarati combining marks
|
|
1124
|
+
codePoint >= 2753 && codePoint <= 2757 || // Gujarati combining marks
|
|
1125
|
+
codePoint >= 2759 && codePoint <= 2760 || // Gujarati combining marks
|
|
1126
|
+
codePoint >= 2765 && codePoint <= 2765 || // Gujarati combining marks
|
|
1127
|
+
codePoint >= 2786 && codePoint <= 2787 || // Gujarati combining marks
|
|
1128
|
+
codePoint >= 2817 && codePoint <= 2817 || // Oriya combining marks
|
|
1129
|
+
codePoint >= 2876 && codePoint <= 2876 || // Oriya combining marks
|
|
1130
|
+
codePoint >= 2879 && codePoint <= 2879 || // Oriya combining marks
|
|
1131
|
+
codePoint >= 2881 && codePoint <= 2883 || // Oriya combining marks
|
|
1132
|
+
codePoint >= 2893 && codePoint <= 2893 || // Oriya combining marks
|
|
1133
|
+
codePoint >= 2902 && codePoint <= 2902 || // Oriya combining marks
|
|
1134
|
+
codePoint >= 2946 && codePoint <= 2946 || // Tamil combining marks
|
|
1135
|
+
codePoint >= 3008 && codePoint <= 3008 || // Tamil combining marks
|
|
1136
|
+
codePoint >= 3021 && codePoint <= 3021 || // Tamil combining marks
|
|
1137
|
+
codePoint >= 3134 && codePoint <= 3136 || // Telugu combining marks
|
|
1138
|
+
codePoint >= 3142 && codePoint <= 3144 || // Telugu combining marks
|
|
1139
|
+
codePoint >= 3146 && codePoint <= 3149 || // Telugu combining marks
|
|
1140
|
+
codePoint >= 3157 && codePoint <= 3158 || // Telugu combining marks
|
|
1141
|
+
codePoint >= 3260 && codePoint <= 3260 || // Kannada combining marks
|
|
1142
|
+
codePoint >= 3263 && codePoint <= 3263 || // Kannada combining marks
|
|
1143
|
+
codePoint >= 3270 && codePoint <= 3270 || // Kannada combining marks
|
|
1144
|
+
codePoint >= 3276 && codePoint <= 3277 || // Kannada combining marks
|
|
1145
|
+
codePoint >= 3298 && codePoint <= 3299 || // Kannada combining marks
|
|
1146
|
+
codePoint >= 3393 && codePoint <= 3395 || // Malayalam combining marks
|
|
1147
|
+
codePoint >= 3405 && codePoint <= 3405 || // Malayalam combining marks
|
|
1148
|
+
codePoint >= 3530 && codePoint <= 3530 || // Sinhala combining marks
|
|
1149
|
+
codePoint >= 3538 && codePoint <= 3540 || // Sinhala combining marks
|
|
1150
|
+
codePoint >= 3542 && codePoint <= 3542 || // Sinhala combining marks
|
|
1151
|
+
codePoint >= 3633 && codePoint <= 3633 || // Thai combining marks
|
|
1152
|
+
codePoint >= 3636 && codePoint <= 3642 || // Thai combining marks
|
|
1153
|
+
codePoint >= 3655 && codePoint <= 3662 || // Thai combining marks
|
|
1154
|
+
codePoint >= 3761 && codePoint <= 3761 || // Lao combining marks
|
|
1155
|
+
codePoint >= 3764 && codePoint <= 3769 || // Lao combining marks
|
|
1156
|
+
codePoint >= 3771 && codePoint <= 3772 || // Lao combining marks
|
|
1157
|
+
codePoint >= 3784 && codePoint <= 3789 || // Lao combining marks
|
|
1158
|
+
codePoint >= 3864 && codePoint <= 3865 || // Tibetan combining marks
|
|
1159
|
+
codePoint >= 3893 && codePoint <= 3893 || // Tibetan combining marks
|
|
1160
|
+
codePoint >= 3895 && codePoint <= 3895 || // Tibetan combining marks
|
|
1161
|
+
codePoint >= 3897 && codePoint <= 3897 || // Tibetan combining marks
|
|
1162
|
+
codePoint >= 3953 && codePoint <= 3966 || // Tibetan combining marks
|
|
1163
|
+
codePoint >= 3968 && codePoint <= 3972 || // Tibetan combining marks
|
|
1164
|
+
codePoint >= 3974 && codePoint <= 3975 || // Tibetan combining marks
|
|
1165
|
+
codePoint >= 3984 && codePoint <= 3991 || // Tibetan combining marks
|
|
1166
|
+
codePoint >= 3993 && codePoint <= 4028 || // Tibetan combining marks
|
|
1167
|
+
codePoint >= 4038 && codePoint <= 4038 || // Tibetan combining marks
|
|
1168
|
+
codePoint >= 4146 && codePoint <= 4151 || // Myanmar combining marks
|
|
1169
|
+
codePoint >= 4153 && codePoint <= 4154 || // Myanmar combining marks
|
|
1170
|
+
codePoint >= 4157 && codePoint <= 4158 || // Myanmar combining marks
|
|
1171
|
+
codePoint >= 4184 && codePoint <= 4185 || // Myanmar combining marks
|
|
1172
|
+
codePoint >= 4190 && codePoint <= 4192 || // Myanmar combining marks
|
|
1173
|
+
codePoint >= 4209 && codePoint <= 4212 || // Myanmar combining marks
|
|
1174
|
+
codePoint >= 4226 && codePoint <= 4226 || // Myanmar combining marks
|
|
1175
|
+
codePoint >= 4229 && codePoint <= 4230 || // Myanmar combining marks
|
|
1176
|
+
codePoint >= 4237 && codePoint <= 4237 || // Myanmar combining marks
|
|
1177
|
+
codePoint >= 4957 && codePoint <= 4959 || // Ethiopic combining marks
|
|
1178
|
+
codePoint >= 5906 && codePoint <= 5908 || // Tagalog combining marks
|
|
1179
|
+
codePoint >= 5938 && codePoint <= 5940 || // Hanunoo combining marks
|
|
1180
|
+
codePoint >= 5970 && codePoint <= 5971 || // Buhid combining marks
|
|
1181
|
+
codePoint >= 6002 && codePoint <= 6003 || // Tagbanwa combining marks
|
|
1182
|
+
codePoint >= 6068 && codePoint <= 6069 || // Khmer combining marks
|
|
1183
|
+
codePoint >= 6071 && codePoint <= 6077 || // Khmer combining marks
|
|
1184
|
+
codePoint >= 6086 && codePoint <= 6086 || // Khmer combining marks
|
|
1185
|
+
codePoint >= 6089 && codePoint <= 6099 || // Khmer combining marks
|
|
1186
|
+
codePoint >= 6109 && codePoint <= 6109 || // Khmer combining marks
|
|
1187
|
+
codePoint >= 6155 && codePoint <= 6157 || // Mongolian combining marks
|
|
1188
|
+
codePoint >= 6313 && codePoint <= 6313 || // Mongolian combining marks
|
|
1189
|
+
codePoint >= 6432 && codePoint <= 6434 || // Limbu combining marks
|
|
1190
|
+
codePoint >= 6439 && codePoint <= 6440 || // Limbu combining marks
|
|
1191
|
+
codePoint >= 6450 && codePoint <= 6450 || // Limbu combining marks
|
|
1192
|
+
codePoint >= 6457 && codePoint <= 6459 || // Limbu combining marks
|
|
1193
|
+
codePoint >= 6679 && codePoint <= 6680 || // Buginese combining marks
|
|
1194
|
+
codePoint >= 6912 && codePoint <= 6915 || // Balinese combining marks
|
|
1195
|
+
codePoint >= 6964 && codePoint <= 6964 || // Balinese combining marks
|
|
1196
|
+
codePoint >= 6966 && codePoint <= 6970 || // Balinese combining marks
|
|
1197
|
+
codePoint >= 6972 && codePoint <= 6972 || // Balinese combining marks
|
|
1198
|
+
codePoint >= 6978 && codePoint <= 6978 || // Balinese combining marks
|
|
1199
|
+
codePoint >= 7019 && codePoint <= 7027 || // Balinese combining marks
|
|
1200
|
+
codePoint >= 7616 && codePoint <= 7679 || // Combining Diacritical Marks Supplement
|
|
1201
|
+
codePoint >= 8400 && codePoint <= 8432 || // Combining Diacritical Marks for Symbols
|
|
1202
|
+
codePoint >= 11503 && codePoint <= 11505 || // Coptic combining marks
|
|
1203
|
+
codePoint >= 11647 && codePoint <= 11647 || // Tifinagh combining marks
|
|
1204
|
+
codePoint >= 11744 && codePoint <= 11775 || // Cyrillic Extended-A combining marks
|
|
1205
|
+
codePoint >= 42607 && codePoint <= 42610 || // Cyrillic Extended-B combining marks
|
|
1206
|
+
codePoint >= 42612 && codePoint <= 42621 || // Cyrillic Extended-B combining marks
|
|
1207
|
+
codePoint >= 42654 && codePoint <= 42655 || // Cyrillic Extended-B combining marks
|
|
1208
|
+
codePoint >= 42736 && codePoint <= 42737 || // Bamum combining marks
|
|
1209
|
+
codePoint >= 43010 && codePoint <= 43010 || // Syloti Nagri combining marks
|
|
1210
|
+
codePoint >= 43014 && codePoint <= 43014 || // Syloti Nagri combining marks
|
|
1211
|
+
codePoint >= 43019 && codePoint <= 43019 || // Syloti Nagri combining marks
|
|
1212
|
+
codePoint >= 43045 && codePoint <= 43046 || // Syloti Nagri combining marks
|
|
1213
|
+
codePoint >= 43204 && codePoint <= 43204 || // Saurashtra combining marks
|
|
1214
|
+
codePoint >= 43232 && codePoint <= 43249 || // Devanagari Extended combining marks
|
|
1215
|
+
codePoint >= 43302 && codePoint <= 43309 || // Kayah Li combining marks
|
|
1216
|
+
codePoint >= 43335 && codePoint <= 43345 || // Rejang combining marks
|
|
1217
|
+
codePoint >= 43392 && codePoint <= 43394 || // Javanese combining marks
|
|
1218
|
+
codePoint >= 43443 && codePoint <= 43443 || // Javanese combining marks
|
|
1219
|
+
codePoint >= 43446 && codePoint <= 43449 || // Javanese combining marks
|
|
1220
|
+
codePoint >= 43452 && codePoint <= 43452 || // Javanese combining marks
|
|
1221
|
+
codePoint >= 43561 && codePoint <= 43566 || // Cham combining marks
|
|
1222
|
+
codePoint >= 43569 && codePoint <= 43570 || // Cham combining marks
|
|
1223
|
+
codePoint >= 43573 && codePoint <= 43574 || // Cham combining marks
|
|
1224
|
+
codePoint >= 43587 && codePoint <= 43587 || // Cham combining marks
|
|
1225
|
+
codePoint >= 43596 && codePoint <= 43596 || // Cham combining marks
|
|
1226
|
+
codePoint >= 43696 && codePoint <= 43696 || // Tai Viet combining marks
|
|
1227
|
+
codePoint >= 43698 && codePoint <= 43700 || // Tai Viet combining marks
|
|
1228
|
+
codePoint >= 43703 && codePoint <= 43704 || // Tai Viet combining marks
|
|
1229
|
+
codePoint >= 43710 && codePoint <= 43711 || // Tai Viet combining marks
|
|
1230
|
+
codePoint >= 43713 && codePoint <= 43713 || // Tai Viet combining marks
|
|
1231
|
+
codePoint >= 44005 && codePoint <= 44005 || // Meetei Mayek combining marks
|
|
1232
|
+
codePoint >= 44008 && codePoint <= 44008 || // Meetei Mayek combining marks
|
|
1233
|
+
codePoint >= 44013 && codePoint <= 44013 || // Meetei Mayek combining marks
|
|
1234
|
+
codePoint >= 64286 && codePoint <= 64286 || // Hebrew combining marks
|
|
1235
|
+
codePoint >= 65024 && codePoint <= 65039 || // Variation Selectors
|
|
1236
|
+
codePoint >= 65056 && codePoint <= 65071 || // Combining Half Marks
|
|
1237
|
+
codePoint >= 917760 && codePoint <= 917999) {
|
|
1238
|
+
return 0;
|
|
1239
|
+
}
|
|
1240
|
+
if (codePoint >= 4352 && codePoint <= 4447 || // Hangul Jamo
|
|
1241
|
+
codePoint >= 9001 && codePoint <= 9002 || // Left/Right-pointing angle bracket
|
|
1242
|
+
codePoint >= 11904 && codePoint <= 12350 || // CJK Radicals Supplement, Kangxi Radicals, CJK Symbols
|
|
1243
|
+
codePoint >= 12352 && codePoint <= 13247 || // Hiragana, Katakana, Bopomofo, Hangul Compatibility, Kanbun, CJK Strokes, Enclosed CJK
|
|
1244
|
+
codePoint >= 13312 && codePoint <= 19903 || // CJK Unified Ideographs Extension A
|
|
1245
|
+
codePoint >= 19968 && codePoint <= 42191 || // CJK Unified Ideographs, Yi Syllables, Yi Radicals
|
|
1246
|
+
codePoint >= 43360 && codePoint <= 43388 || // Hangul Jamo Extended-A
|
|
1247
|
+
codePoint >= 44032 && codePoint <= 55203 || // Hangul Syllables
|
|
1248
|
+
codePoint >= 63744 && codePoint <= 64255 || // CJK Compatibility Ideographs
|
|
1249
|
+
codePoint >= 65040 && codePoint <= 65049 || // Vertical forms
|
|
1250
|
+
codePoint >= 65072 && codePoint <= 65135 || // CJK Compatibility Forms, Small Form Variants
|
|
1251
|
+
codePoint >= 65281 && codePoint <= 65376 || // Fullwidth Forms
|
|
1252
|
+
codePoint >= 65504 && codePoint <= 65510 || // Fullwidth Signs
|
|
1253
|
+
codePoint >= 110592 && codePoint <= 111359 || // Kana Supplement, Kana Extended-A, Small Kana Extension
|
|
1254
|
+
codePoint >= 126980 && codePoint <= 126980 || // Mahjong tile
|
|
1255
|
+
codePoint >= 127183 && codePoint <= 127183 || // Playing card
|
|
1256
|
+
codePoint >= 127232 && codePoint <= 129535 || // Enclosed Alphanumeric Supplement, Emoticons, Transport, etc.
|
|
1257
|
+
codePoint >= 129536 && codePoint <= 129647 || // Chess Symbols
|
|
1258
|
+
codePoint >= 129648 && codePoint <= 129791 || // Symbols and Pictographs Extended-A
|
|
1259
|
+
codePoint >= 131072 && codePoint <= 196605 || // CJK Unified Ideographs Extension B–G, CJK Compatibility Supplement
|
|
1260
|
+
codePoint >= 196608 && codePoint <= 262141) {
|
|
1261
|
+
return 2;
|
|
1262
|
+
}
|
|
1263
|
+
return 1;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
// src/ui/thinking-line.ts
|
|
1267
|
+
var THINKING_SCROLL_CELLS_PER_SEC = 16;
|
|
1268
|
+
var THINKING_EASE = 0.18;
|
|
1269
|
+
var THINKING_MAX_STEP_MS = 250;
|
|
1270
|
+
var THINKING_MAX_STORED_CHARS = 4e3;
|
|
1271
|
+
function normalizeThinkingText(text) {
|
|
1272
|
+
return text.replace(/\s+/gu, " ").trim();
|
|
1273
|
+
}
|
|
1274
|
+
function thinkingDisplayWidth(text) {
|
|
1275
|
+
let width = 0;
|
|
1276
|
+
for (const character of text) width += charWidth(character.codePointAt(0) ?? 32);
|
|
1277
|
+
return width;
|
|
1278
|
+
}
|
|
1279
|
+
function sliceThinkingByWidth(text, startCell, cellCount) {
|
|
1280
|
+
let out = "";
|
|
1281
|
+
let cell = 0;
|
|
1282
|
+
for (const character of text) {
|
|
1283
|
+
const w = charWidth(character.codePointAt(0) ?? 32);
|
|
1284
|
+
if (cell + w > startCell && cell < startCell + cellCount) out += character;
|
|
1285
|
+
cell += w;
|
|
1286
|
+
if (cell >= startCell + cellCount) break;
|
|
1287
|
+
}
|
|
1288
|
+
return out;
|
|
1289
|
+
}
|
|
1290
|
+
function thinkingWindow(text, previousStart, options) {
|
|
1291
|
+
const normalized = normalizeThinkingText(text);
|
|
1292
|
+
const width = Math.max(1, Math.floor(options.width));
|
|
1293
|
+
const total = thinkingDisplayWidth(normalized);
|
|
1294
|
+
if (total <= width) return { text: normalized, start: 0 };
|
|
1295
|
+
const maxStart = total - width;
|
|
1296
|
+
const from = Math.min(Math.max(0, previousStart), maxStart);
|
|
1297
|
+
const cellsPerSecond = options.cellsPerSecond ?? THINKING_SCROLL_CELLS_PER_SEC;
|
|
1298
|
+
const ease = options.ease ?? THINKING_EASE;
|
|
1299
|
+
const dt = Math.max(0, Math.min(options.dtMs, THINKING_MAX_STEP_MS));
|
|
1300
|
+
const lag = maxStart - from;
|
|
1301
|
+
const step = Math.max(cellsPerSecond * dt / 1e3, lag * ease);
|
|
1302
|
+
const start = Math.min(maxStart, Math.floor(from + step));
|
|
1303
|
+
return { text: sliceThinkingByWidth(normalized, start, width), start };
|
|
1304
|
+
}
|
|
1305
|
+
function appendThinkingText(previous, delta) {
|
|
1306
|
+
const next = (previous ?? "") + delta;
|
|
1307
|
+
return next.length > THINKING_MAX_STORED_CHARS ? next.slice(-THINKING_MAX_STORED_CHARS) : next;
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1085
1310
|
// src/ui/transcript.ts
|
|
1086
1311
|
function createTranscriptState() {
|
|
1087
1312
|
return { completed: [], nextId: 1 };
|
|
@@ -1178,6 +1403,9 @@ function transcriptReducer(state, action) {
|
|
|
1178
1403
|
if (event.type === "text") {
|
|
1179
1404
|
return { ...state, active: addText(withoutModelActivity(state.active), event.text) };
|
|
1180
1405
|
}
|
|
1406
|
+
if (event.type === "thinking") {
|
|
1407
|
+
return { ...state, active: attachThinking(state.active, event.text) };
|
|
1408
|
+
}
|
|
1181
1409
|
if (event.type === "tool-start") return upsertStatus({ ...state, active: withoutModelActivity(state.active) }, {
|
|
1182
1410
|
kind: "status",
|
|
1183
1411
|
id: `tool:${event.id}`,
|
|
@@ -1478,6 +1706,18 @@ function finishActive(state) {
|
|
|
1478
1706
|
...state.taskSnapshot === void 0 ? {} : { taskSnapshot: state.taskSnapshot }
|
|
1479
1707
|
};
|
|
1480
1708
|
}
|
|
1709
|
+
function attachThinking(turn, text) {
|
|
1710
|
+
const blocks = [...turn.blocks];
|
|
1711
|
+
const index = blocks.findIndex((block2) => block2.kind === "status" && block2.activity === "model" && block2.state === "running");
|
|
1712
|
+
if (index < 0) return turn;
|
|
1713
|
+
const block = blocks[index];
|
|
1714
|
+
if (block === void 0 || block.kind !== "status") return turn;
|
|
1715
|
+
blocks[index] = {
|
|
1716
|
+
...block,
|
|
1717
|
+
thinkingText: appendThinkingText(block.thinkingText, text)
|
|
1718
|
+
};
|
|
1719
|
+
return { ...turn, blocks };
|
|
1720
|
+
}
|
|
1481
1721
|
function withoutModelActivity(turn, id) {
|
|
1482
1722
|
const blocks = turn.blocks.filter((block) => block.kind !== "status" || block.activity !== "model" || id !== void 0 && block.id !== id);
|
|
1483
1723
|
if (blocks.length === turn.blocks.length) return turn;
|
|
@@ -2996,7 +3236,8 @@ var MVP_COMMANDS = [
|
|
|
2996
3236
|
"fork",
|
|
2997
3237
|
"pals",
|
|
2998
3238
|
"chat",
|
|
2999
|
-
"co-work"
|
|
3239
|
+
"co-work",
|
|
3240
|
+
"tool"
|
|
3000
3241
|
];
|
|
3001
3242
|
var COMMAND_DESCRIPTIONS = {
|
|
3002
3243
|
model: "Switch the active model",
|
|
@@ -3034,16 +3275,24 @@ var COMMAND_DESCRIPTIONS = {
|
|
|
3034
3275
|
fork: "Continue context from a prior session node",
|
|
3035
3276
|
pals: "List, rename, or inspect active Flavor pals",
|
|
3036
3277
|
chat: "Send a task to another Flavor pal",
|
|
3037
|
-
"co-work": "Coordinate a shared goal with another Flavor pal"
|
|
3278
|
+
"co-work": "Coordinate a shared goal with another Flavor pal",
|
|
3279
|
+
tool: "Run a registered managed tool with a JSON object"
|
|
3038
3280
|
};
|
|
3039
|
-
function parseSlashCommand(input, dynamicCommands = [], skillCommands = []) {
|
|
3281
|
+
function parseSlashCommand(input, dynamicCommands = [], skillCommands = [], managedTools = []) {
|
|
3040
3282
|
const trimmed = input.trim();
|
|
3041
3283
|
if (!trimmed.startsWith("/")) return null;
|
|
3042
|
-
const
|
|
3284
|
+
const match = /^(\S+)(?:\s+([\s\S]*))?$/u.exec(trimmed.slice(1));
|
|
3285
|
+
const rawName = match?.[1] ?? "";
|
|
3286
|
+
const rawArguments = match?.[2] ?? "";
|
|
3287
|
+
const args = rawArguments.length === 0 ? [] : rawArguments.split(/\s+/u);
|
|
3043
3288
|
const name = rawName.toLowerCase();
|
|
3044
3289
|
if (!MVP_COMMANDS.includes(name) && dynamicCommands.includes(name)) {
|
|
3045
3290
|
return { name: "plugin", command: name, args };
|
|
3046
3291
|
}
|
|
3292
|
+
if (!MVP_COMMANDS.includes(name)) {
|
|
3293
|
+
const managedTool = managedTools.find((tool) => tool.toLowerCase() === name);
|
|
3294
|
+
if (managedTool !== void 0) return { name: "managed-tool", tool: managedTool, input: rawArguments };
|
|
3295
|
+
}
|
|
3047
3296
|
if (!MVP_COMMANDS.includes(name) && skillCommands.includes(name)) {
|
|
3048
3297
|
return { name: "skill", skill: name, prompt: args.join(" ") };
|
|
3049
3298
|
}
|
|
@@ -3065,6 +3314,15 @@ function parseSlashCommand(input, dynamicCommands = [], skillCommands = []) {
|
|
|
3065
3314
|
}
|
|
3066
3315
|
return { name, mode: normalized };
|
|
3067
3316
|
}
|
|
3317
|
+
if (name === "tool") {
|
|
3318
|
+
const [requested] = args;
|
|
3319
|
+
const managedTool = requested === void 0 ? void 0 : managedTools.find((candidate) => candidate.toLowerCase() === requested.toLowerCase());
|
|
3320
|
+
if (managedTool === void 0) {
|
|
3321
|
+
return { name: "invalid", command: name, message: "Use /tool <registered-tool> [JSON object]." };
|
|
3322
|
+
}
|
|
3323
|
+
const inputStart = rawArguments.search(/\s/u);
|
|
3324
|
+
return { name: "managed-tool", tool: managedTool, input: inputStart < 0 ? "" : rawArguments.slice(inputStart).trimStart() };
|
|
3325
|
+
}
|
|
3068
3326
|
if (name === "audit") {
|
|
3069
3327
|
const toolFilter = args.length > 0 ? args.join(" ") : void 0;
|
|
3070
3328
|
return { name, toolFilter };
|
|
@@ -3292,6 +3550,7 @@ var HELP = [
|
|
|
3292
3550
|
"/review [focus] review uncommitted changes before committing",
|
|
3293
3551
|
"/evolve <signals|suggest|improve <id>|verify <name>|reload <name>|test|revert <name>|done <id>> self-improvement loop",
|
|
3294
3552
|
"/mcp [status|tools|reconnect|enable|disable] manage MCP servers",
|
|
3553
|
+
"/tool <registered-tool> [JSON object] run a registered tool (or use /<tool-name>)",
|
|
3295
3554
|
"/ide show VS Code connection and cursor/selection",
|
|
3296
3555
|
"/pals [--verbose|rename <alias>|info <alias-or-uuid>]",
|
|
3297
3556
|
"/chat <alias-or-uuid> <goal> send a task that starts on the receiving pal",
|
|
@@ -3563,7 +3822,12 @@ var FlavorSession = class {
|
|
|
3563
3822
|
} catch {
|
|
3564
3823
|
}
|
|
3565
3824
|
}
|
|
3566
|
-
const command = parseSlashCommand(
|
|
3825
|
+
const command = parseSlashCommand(
|
|
3826
|
+
prompt,
|
|
3827
|
+
this.#services.pluginCommands().map(({ name }) => name),
|
|
3828
|
+
skillNames,
|
|
3829
|
+
this.#services.managedToolCommands().map(({ name }) => name)
|
|
3830
|
+
);
|
|
3567
3831
|
if (command !== null) await this.#dispatch(command, controller.signal);
|
|
3568
3832
|
else for await (const event of this.#services.run(prompt, controller.signal, {
|
|
3569
3833
|
getSteeringMessages: () => this.#drainMessages("steer", true).map((item) => item.text),
|
|
@@ -3665,6 +3929,8 @@ var FlavorSession = class {
|
|
|
3665
3929
|
this.#notice(`Main permissions set to ${command.mode}. Child approvals use bubble mode unless plan mode is active.`);
|
|
3666
3930
|
} else if (command.name === "plugin") {
|
|
3667
3931
|
this.#notice(format(await this.#services.runPluginCommand(command.command, command.args, signal)));
|
|
3932
|
+
} else if (command.name === "managed-tool") {
|
|
3933
|
+
this.#notice(format(await this.#services.runManagedTool(command.tool, command.input, signal)));
|
|
3668
3934
|
} else if (command.name === "skill") {
|
|
3669
3935
|
for await (const event of this.#services.runSkill(command.skill, command.prompt, signal)) this.#services.output(event);
|
|
3670
3936
|
} else if (command.name === "loop") {
|
|
@@ -6315,7 +6581,12 @@ function providerValidMessages(input) {
|
|
|
6315
6581
|
const calls = original.toolCalls.filter((call) => call.id && call.name && availableResults.has(call.id));
|
|
6316
6582
|
calls.forEach((call) => announced.add(call.id));
|
|
6317
6583
|
if (!original.content && calls.length === 0) continue;
|
|
6318
|
-
output.push({
|
|
6584
|
+
output.push({
|
|
6585
|
+
role: "assistant",
|
|
6586
|
+
content: original.content,
|
|
6587
|
+
...calls.length === 0 ? {} : { toolCalls: calls.map((call) => ({ ...call })) },
|
|
6588
|
+
...original.thinkingBlocks === void 0 ? {} : { thinkingBlocks: original.thinkingBlocks.map((block) => ({ ...block })) }
|
|
6589
|
+
});
|
|
6319
6590
|
continue;
|
|
6320
6591
|
}
|
|
6321
6592
|
if (original.role === "tool") {
|
|
@@ -6536,9 +6807,10 @@ function withStructuredOutput(options) {
|
|
|
6536
6807
|
throw new Error("Structured output retry delays must be non-negative integers");
|
|
6537
6808
|
}
|
|
6538
6809
|
}
|
|
6539
|
-
const
|
|
6810
|
+
const generatedTool = options.modelInputSchema === void 0 ? modelToolFromZod(options.name, options.description, options.schema) : { name: options.name, description: options.description, inputSchema: options.modelInputSchema };
|
|
6811
|
+
const tool = options.modelStrict === void 0 ? generatedTool : { ...generatedTool, strict: options.modelStrict };
|
|
6540
6812
|
const maxAttempts = retry.maxRetries + 1;
|
|
6541
|
-
const
|
|
6813
|
+
const validationSchema = jsonSchemaFromZod(options.schema);
|
|
6542
6814
|
const model = {
|
|
6543
6815
|
async *stream(request) {
|
|
6544
6816
|
let candidate;
|
|
@@ -6611,7 +6883,7 @@ function withStructuredOutput(options) {
|
|
|
6611
6883
|
}
|
|
6612
6884
|
}
|
|
6613
6885
|
if (candidateCount === 1 && candidate !== null && typeof candidate === "object") {
|
|
6614
|
-
candidate = coerceByJsonSchema(candidate,
|
|
6886
|
+
candidate = coerceByJsonSchema(candidate, validationSchema);
|
|
6615
6887
|
}
|
|
6616
6888
|
if (candidateCount !== 1) {
|
|
6617
6889
|
attemptError = {
|
|
@@ -6683,7 +6955,13 @@ function withStructuredOutput(options) {
|
|
|
6683
6955
|
return model;
|
|
6684
6956
|
}
|
|
6685
6957
|
function strictJsonSchema(schema) {
|
|
6686
|
-
return
|
|
6958
|
+
return strictJsonSchemaObject(jsonSchemaFromZod(schema));
|
|
6959
|
+
}
|
|
6960
|
+
function jsonSchemaFromZod(schema) {
|
|
6961
|
+
return z7.toJSONSchema(schema);
|
|
6962
|
+
}
|
|
6963
|
+
function strictJsonSchemaObject(schema) {
|
|
6964
|
+
return ensureStrictSchema(schema);
|
|
6687
6965
|
}
|
|
6688
6966
|
function extractJsonObject(text) {
|
|
6689
6967
|
const trimmed = text.trim();
|
|
@@ -6731,6 +7009,7 @@ function coerceByJsonSchema(value, schema) {
|
|
|
6731
7009
|
const node = schema;
|
|
6732
7010
|
const branches = [
|
|
6733
7011
|
...Array.isArray(node.anyOf) ? node.anyOf : [],
|
|
7012
|
+
...Array.isArray(node.oneOf) ? node.oneOf : [],
|
|
6734
7013
|
...Array.isArray(node.allOf) ? node.allOf : []
|
|
6735
7014
|
].filter((branch) => branch !== null && typeof branch === "object");
|
|
6736
7015
|
const types = [];
|
|
@@ -6750,40 +7029,108 @@ function coerceByJsonSchema(value, schema) {
|
|
|
6750
7029
|
if (lowered === "true") return true;
|
|
6751
7030
|
if (lowered === "false") return false;
|
|
6752
7031
|
}
|
|
7032
|
+
if (types.includes("object") && !types.includes("string") && typeof value === "string") {
|
|
7033
|
+
const trimmed = value.trim();
|
|
7034
|
+
if (trimmed.startsWith("{")) {
|
|
7035
|
+
try {
|
|
7036
|
+
const parsed = JSON.parse(trimmed);
|
|
7037
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
7038
|
+
return coerceByJsonSchema(parsed, node);
|
|
7039
|
+
}
|
|
7040
|
+
} catch {
|
|
7041
|
+
}
|
|
7042
|
+
}
|
|
7043
|
+
}
|
|
7044
|
+
if (types.includes("array") && !Array.isArray(value) && value !== null && value !== void 0 && !types.some((type) => matchesJsonSchemaType(value, type))) {
|
|
7045
|
+
const arraySchema = [node, ...branches].find((candidate) => {
|
|
7046
|
+
const type = candidate.type;
|
|
7047
|
+
return type === "array" || Array.isArray(type) && type.includes("array");
|
|
7048
|
+
});
|
|
7049
|
+
if (typeof value === "string" && value.trim().startsWith("[")) {
|
|
7050
|
+
try {
|
|
7051
|
+
const parsed = JSON.parse(value.trim());
|
|
7052
|
+
if (Array.isArray(parsed)) return coerceByJsonSchema(parsed, arraySchema ?? node);
|
|
7053
|
+
} catch {
|
|
7054
|
+
}
|
|
7055
|
+
}
|
|
7056
|
+
return [arraySchema?.items === void 0 ? value : coerceByJsonSchema(value, arraySchema.items)];
|
|
7057
|
+
}
|
|
6753
7058
|
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
6754
|
-
const
|
|
7059
|
+
const objectSchema = [node, ...branches].find((candidate) => candidate.type === "object" || candidate.properties !== void 0);
|
|
7060
|
+
const properties = objectSchema?.properties;
|
|
6755
7061
|
if (properties !== void 0) {
|
|
6756
7062
|
const output = {};
|
|
7063
|
+
const required2 = new Set(Array.isArray(objectSchema?.required) ? objectSchema.required : []);
|
|
6757
7064
|
for (const [key, child] of Object.entries(value)) {
|
|
6758
|
-
|
|
7065
|
+
const childSchema = properties[key];
|
|
7066
|
+
if (child === null && childSchema !== void 0 && !required2.has(key) && !jsonSchemaAllowsNull(childSchema)) {
|
|
7067
|
+
continue;
|
|
7068
|
+
}
|
|
7069
|
+
output[key] = childSchema !== void 0 ? coerceByJsonSchema(child, childSchema) : child;
|
|
6759
7070
|
}
|
|
6760
7071
|
return output;
|
|
6761
7072
|
}
|
|
6762
7073
|
}
|
|
6763
|
-
if (types.includes("array") && Array.isArray(value)
|
|
6764
|
-
|
|
7074
|
+
if (types.includes("array") && Array.isArray(value)) {
|
|
7075
|
+
const arraySchema = [node, ...branches].find((candidate) => {
|
|
7076
|
+
const type = candidate.type;
|
|
7077
|
+
return type === "array" || Array.isArray(type) && type.includes("array");
|
|
7078
|
+
});
|
|
7079
|
+
if (arraySchema?.items !== void 0) {
|
|
7080
|
+
return value.map((item) => coerceByJsonSchema(item, arraySchema.items));
|
|
7081
|
+
}
|
|
6765
7082
|
}
|
|
6766
7083
|
return value;
|
|
6767
7084
|
}
|
|
7085
|
+
function matchesJsonSchemaType(value, type) {
|
|
7086
|
+
if (type === "null") return value === null;
|
|
7087
|
+
if (type === "array") return Array.isArray(value);
|
|
7088
|
+
if (type === "object") return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
7089
|
+
if (type === "integer") return typeof value === "number" && Number.isInteger(value);
|
|
7090
|
+
if (type === "number") return typeof value === "number";
|
|
7091
|
+
return typeof value === type;
|
|
7092
|
+
}
|
|
7093
|
+
function jsonSchemaAllowsNull(schema) {
|
|
7094
|
+
if (schema === null || typeof schema !== "object") return false;
|
|
7095
|
+
const node = schema;
|
|
7096
|
+
if (node.type === "null" || Array.isArray(node.type) && node.type.includes("null")) return true;
|
|
7097
|
+
return [node.anyOf, node.oneOf].some((branches) => Array.isArray(branches) && branches.some((branch) => jsonSchemaAllowsNull(branch)));
|
|
7098
|
+
}
|
|
6768
7099
|
function modelToolFromZod(name, description, schema) {
|
|
6769
7100
|
return { name, description, inputSchema: strictJsonSchema(schema) };
|
|
6770
7101
|
}
|
|
6771
7102
|
function ensureStrictSchema(schema) {
|
|
7103
|
+
const output = { ...schema };
|
|
7104
|
+
for (const keyword of ["anyOf", "oneOf", "allOf", "prefixItems"]) {
|
|
7105
|
+
const branches = schema[keyword];
|
|
7106
|
+
if (Array.isArray(branches)) {
|
|
7107
|
+
output[keyword] = branches.map((branch) => typeof branch === "object" && branch !== null ? ensureStrictSchema(branch) : branch);
|
|
7108
|
+
}
|
|
7109
|
+
}
|
|
7110
|
+
if (typeof schema.items === "object" && schema.items !== null) {
|
|
7111
|
+
output.items = ensureStrictSchema(schema.items);
|
|
7112
|
+
}
|
|
7113
|
+
for (const keyword of ["$defs", "definitions"]) {
|
|
7114
|
+
const definitions = schema[keyword];
|
|
7115
|
+
if (typeof definitions === "object" && definitions !== null && !Array.isArray(definitions)) {
|
|
7116
|
+
output[keyword] = Object.fromEntries(Object.entries(definitions).map(([key, definition]) => [
|
|
7117
|
+
key,
|
|
7118
|
+
typeof definition === "object" && definition !== null ? ensureStrictSchema(definition) : definition
|
|
7119
|
+
]));
|
|
7120
|
+
}
|
|
7121
|
+
}
|
|
6772
7122
|
if (schema.type !== "object" || typeof schema.properties !== "object" || schema.properties === null) {
|
|
6773
|
-
return
|
|
7123
|
+
return output;
|
|
6774
7124
|
}
|
|
6775
|
-
const
|
|
6776
|
-
const requiredSet = new Set(required2);
|
|
7125
|
+
const requiredSet = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
6777
7126
|
const properties = {};
|
|
6778
7127
|
for (const [key, value] of Object.entries(schema.properties)) {
|
|
6779
7128
|
const child = typeof value === "object" && value !== null ? ensureStrictSchema(value) : value;
|
|
6780
|
-
if (requiredSet.has(key)) properties[key] = child;
|
|
6781
|
-
else {
|
|
6782
|
-
|
|
6783
|
-
requiredSet.add(key);
|
|
6784
|
-
}
|
|
7129
|
+
if (requiredSet.has(key) || jsonSchemaAllowsNull(child)) properties[key] = child;
|
|
7130
|
+
else properties[key] = { anyOf: [child, { type: "null" }] };
|
|
7131
|
+
requiredSet.add(key);
|
|
6785
7132
|
}
|
|
6786
|
-
return { ...
|
|
7133
|
+
return { ...output, additionalProperties: false, required: [...requiredSet], properties };
|
|
6787
7134
|
}
|
|
6788
7135
|
function repairMessages(messages, tool, original, candidate, error) {
|
|
6789
7136
|
const details = [
|
|
@@ -6962,6 +7309,7 @@ var AgentLoop = class {
|
|
|
6962
7309
|
}
|
|
6963
7310
|
let assistantText = "";
|
|
6964
7311
|
const collectedToolCalls = [];
|
|
7312
|
+
const collectedThinking = [];
|
|
6965
7313
|
let completed = false;
|
|
6966
7314
|
let reactiveRetried = false;
|
|
6967
7315
|
let attempt = 1;
|
|
@@ -6999,6 +7347,7 @@ var AgentLoop = class {
|
|
|
6999
7347
|
}
|
|
7000
7348
|
assistantText = "";
|
|
7001
7349
|
collectedToolCalls.length = 0;
|
|
7350
|
+
collectedThinking.length = 0;
|
|
7002
7351
|
completed = false;
|
|
7003
7352
|
let terminalError;
|
|
7004
7353
|
let providerError = false;
|
|
@@ -7019,6 +7368,10 @@ var AgentLoop = class {
|
|
|
7019
7368
|
assistantText += event.text;
|
|
7020
7369
|
accumulatedText += event.text;
|
|
7021
7370
|
yield event;
|
|
7371
|
+
} else if (event.type === "thinking") {
|
|
7372
|
+
yield event;
|
|
7373
|
+
} else if (event.type === "thinking-block") {
|
|
7374
|
+
collectedThinking.push({ text: event.text, ...event.signature === void 0 ? {} : { signature: event.signature } });
|
|
7022
7375
|
} else if (event.type === "tool-call") {
|
|
7023
7376
|
collectedToolCalls.push({ kind: "valid", id: event.id, name: event.name, input: event.input });
|
|
7024
7377
|
} else if (event.type === "invalid-tool-call") {
|
|
@@ -7153,19 +7506,11 @@ var AgentLoop = class {
|
|
|
7153
7506
|
});
|
|
7154
7507
|
continue;
|
|
7155
7508
|
}
|
|
7156
|
-
const validation = collected.kind === "valid" ? this.#options.runtime.
|
|
7509
|
+
const validation = collected.kind === "valid" ? this.#options.runtime.normalize(collected) : { ok: false, error: collected.error };
|
|
7157
7510
|
if (validation.ok) {
|
|
7158
7511
|
toolCalls.push({ id: collected.id, name: collected.name, input: validation.input });
|
|
7159
7512
|
continue;
|
|
7160
7513
|
}
|
|
7161
|
-
if (collected.kind === "valid") {
|
|
7162
|
-
const coerced = coerceByJsonSchema(collected.input, strictJsonSchema(definition.inputSchema));
|
|
7163
|
-
const revalidation = this.#options.runtime.validate({ ...collected, input: coerced });
|
|
7164
|
-
if (revalidation.ok) {
|
|
7165
|
-
toolCalls.push({ id: collected.id, name: collected.name, input: revalidation.input });
|
|
7166
|
-
continue;
|
|
7167
|
-
}
|
|
7168
|
-
}
|
|
7169
7514
|
const repairModelId = this.#options.fallbackModelId ?? this.#options.modelId;
|
|
7170
7515
|
const invalidOutput = collected.kind === "invalid" ? collected.rawInput : serializeToolInput(collected.input);
|
|
7171
7516
|
const structured = withStructuredOutput({
|
|
@@ -7174,6 +7519,8 @@ var AgentLoop = class {
|
|
|
7174
7519
|
name: definition.name,
|
|
7175
7520
|
description: definition.description,
|
|
7176
7521
|
schema: definition.inputSchema,
|
|
7522
|
+
...definition.modelInputSchema === void 0 ? {} : { modelInputSchema: definition.modelInputSchema },
|
|
7523
|
+
...definition.modelStrict === void 0 ? {} : { modelStrict: definition.modelStrict },
|
|
7177
7524
|
beforeAttempt: async ({ attempt: repairAttempt, maxAttempts: repairMaxAttempts, messageCount }) => {
|
|
7178
7525
|
const before = await this.#options.hooks.emit({
|
|
7179
7526
|
version: 1,
|
|
@@ -7372,7 +7719,8 @@ var AgentLoop = class {
|
|
|
7372
7719
|
const assistantMessage = {
|
|
7373
7720
|
role: "assistant",
|
|
7374
7721
|
content: assistantText,
|
|
7375
|
-
toolCalls: toolCalls.map(({ id, name, input }) => ({ id, name, input }))
|
|
7722
|
+
toolCalls: toolCalls.map(({ id, name, input }) => ({ id, name, input })),
|
|
7723
|
+
...collectedThinking.length === 0 ? {} : { thinkingBlocks: collectedThinking.map((block) => ({ ...block })) }
|
|
7376
7724
|
};
|
|
7377
7725
|
this.#options.context.appendMany([assistantMessage, ...stagedMessages]);
|
|
7378
7726
|
for (const { call, result } of stagedResults) {
|
|
@@ -7654,12 +8002,24 @@ var ToolRuntime = class {
|
|
|
7654
8002
|
throw error;
|
|
7655
8003
|
}
|
|
7656
8004
|
}
|
|
8005
|
+
/**
|
|
8006
|
+
* Validates a call and applies the same conservative provider-argument
|
|
8007
|
+
* normalization used by the agent loop before falling back to repair.
|
|
8008
|
+
*/
|
|
8009
|
+
normalize(call) {
|
|
8010
|
+
const validation = this.validate(call);
|
|
8011
|
+
if (validation.ok || validation.error.code === "unknown_tool") return validation;
|
|
8012
|
+
const tool = this.#tools.get(call.name);
|
|
8013
|
+
if (tool === void 0) return validation;
|
|
8014
|
+
const input = coerceByJsonSchema(call.input, jsonSchemaFromZod(tool.inputSchema));
|
|
8015
|
+
return this.validate({ ...call, input });
|
|
8016
|
+
}
|
|
7657
8017
|
async #execute(call, context) {
|
|
7658
8018
|
const tool = this.#tools.get(call.name);
|
|
7659
8019
|
if (tool === void 0) return { ok: false, error: { code: "unknown_tool", message: `Unknown tool: ${call.name}` } };
|
|
7660
8020
|
const signal = context.signal ?? new AbortController().signal;
|
|
7661
8021
|
const toolCallId = call.id ?? randomUUID7();
|
|
7662
|
-
const validation = this.
|
|
8022
|
+
const validation = this.normalize(call);
|
|
7663
8023
|
if (!validation.ok) {
|
|
7664
8024
|
return this.#fail(toolCallId, call.name, call.input, context.agent, validation.error.code, validation.error.message);
|
|
7665
8025
|
}
|
|
@@ -9388,6 +9748,7 @@ var PluginHost = class {
|
|
|
9388
9748
|
description: contribution.description,
|
|
9389
9749
|
inputSchema: z13.unknown(),
|
|
9390
9750
|
...contribution.modelInputSchema === void 0 ? {} : { modelInputSchema: contribution.modelInputSchema },
|
|
9751
|
+
...contribution.modelInputSchema === void 0 ? {} : { modelStrict: false },
|
|
9391
9752
|
...contribution.readOnly === void 0 ? {} : { readOnly: contribution.readOnly },
|
|
9392
9753
|
paths: () => [],
|
|
9393
9754
|
execute: (input, _signal, toolContext) => session.invoke("tool", contribution.name, [
|
|
@@ -12616,6 +12977,7 @@ var CLAUDE_CLIENT_HEADERS = {
|
|
|
12616
12977
|
"x-app": "cli"
|
|
12617
12978
|
};
|
|
12618
12979
|
var DEFAULT_MAX_OUTPUT_TOKENS = 32768;
|
|
12980
|
+
var DEFAULT_THINKING_BUDGET = 8192;
|
|
12619
12981
|
var MAX_CACHE_MARKERS = 4;
|
|
12620
12982
|
function collectCacheMarkers(system, messages) {
|
|
12621
12983
|
const markers = [];
|
|
@@ -12674,9 +13036,26 @@ function formatCacheUsage(model, snapshot4, shape) {
|
|
|
12674
13036
|
...shape === void 0 ? {} : { requestMessages: shape.messages, requestMarkers: shape.markers }
|
|
12675
13037
|
});
|
|
12676
13038
|
}
|
|
13039
|
+
function stripThinkingBlocks(messages) {
|
|
13040
|
+
for (const message2 of messages) {
|
|
13041
|
+
if (message2.role !== "assistant" || !Array.isArray(message2.content)) continue;
|
|
13042
|
+
const blocks = message2.content;
|
|
13043
|
+
if (!blocks.some((block) => block?.type === "thinking")) continue;
|
|
13044
|
+
message2.content = blocks.filter((block) => block?.type !== "thinking");
|
|
13045
|
+
}
|
|
13046
|
+
}
|
|
13047
|
+
function isThinkingParamRejected(error) {
|
|
13048
|
+
const status = error?.status;
|
|
13049
|
+
if (status !== void 0 && status !== 400) return false;
|
|
13050
|
+
const message2 = error instanceof Error ? error.message : String(error ?? "");
|
|
13051
|
+
return /\bthinking\b/iu.test(message2) && /(budget_tokens|expected|not supported|unsupported|unknown|invalid|extra inputs|unrecognized)/iu.test(message2);
|
|
13052
|
+
}
|
|
12677
13053
|
var AnthropicModelAdapter = class {
|
|
12678
13054
|
client;
|
|
12679
13055
|
maxOutputTokens;
|
|
13056
|
+
thinkingBudget;
|
|
13057
|
+
/** Set once an endpoint rejects the `thinking` parameter; later requests stop sending it. */
|
|
13058
|
+
#thinkingRejected = false;
|
|
12680
13059
|
debugUsage;
|
|
12681
13060
|
constructor(options) {
|
|
12682
13061
|
const maxOutputTokens = options.maxOutputTokens ?? DEFAULT_MAX_OUTPUT_TOKENS;
|
|
@@ -12684,6 +13063,7 @@ var AnthropicModelAdapter = class {
|
|
|
12684
13063
|
throw new Error("maxOutputTokens must be a positive integer");
|
|
12685
13064
|
}
|
|
12686
13065
|
this.maxOutputTokens = maxOutputTokens;
|
|
13066
|
+
this.thinkingBudget = options.thinkingBudget ?? DEFAULT_THINKING_BUDGET;
|
|
12687
13067
|
this.debugUsage = options.debugUsage ?? isEnvTruthy(process.env.FLAVOR_DEBUG_USAGE);
|
|
12688
13068
|
this.client = options.client ?? new Anthropic({
|
|
12689
13069
|
...options.apiKey === void 0 ? {} : { apiKey: options.apiKey },
|
|
@@ -12691,6 +13071,16 @@ var AnthropicModelAdapter = class {
|
|
|
12691
13071
|
...options.headers === void 0 ? {} : { defaultHeaders: options.headers }
|
|
12692
13072
|
});
|
|
12693
13073
|
}
|
|
13074
|
+
/**
|
|
13075
|
+
* Extended-thinking request parameter when enabled, otherwise undefined.
|
|
13076
|
+
* Anthropic requires the budget to fit inside max_tokens with a 1024 floor.
|
|
13077
|
+
*/
|
|
13078
|
+
#thinkingParam() {
|
|
13079
|
+
if (this.#thinkingRejected || this.thinkingBudget <= 0) return void 0;
|
|
13080
|
+
const budget = Math.min(this.thinkingBudget, this.maxOutputTokens - 1);
|
|
13081
|
+
if (budget < 1024) return void 0;
|
|
13082
|
+
return { type: "enabled", budget_tokens: budget };
|
|
13083
|
+
}
|
|
12694
13084
|
#logUsage(request, snapshot4, shape) {
|
|
12695
13085
|
const line = formatCacheUsage(request.model, snapshot4, shape);
|
|
12696
13086
|
if (this.debugUsage) {
|
|
@@ -12746,7 +13136,13 @@ var AnthropicModelAdapter = class {
|
|
|
12746
13136
|
}
|
|
12747
13137
|
messages.push({ role: "user", content: results });
|
|
12748
13138
|
} else if (message2.role === "assistant" && message2.toolCalls?.length) {
|
|
13139
|
+
const echoThinking = this.#thinkingRejected ? [] : (message2.thinkingBlocks ?? []).filter((block) => block.signature !== void 0);
|
|
12749
13140
|
const content = [
|
|
13141
|
+
...echoThinking.map((block) => ({
|
|
13142
|
+
type: "thinking",
|
|
13143
|
+
thinking: block.text,
|
|
13144
|
+
signature: block.signature
|
|
13145
|
+
})),
|
|
12750
13146
|
...modelContentText(message2.content) ? [{ type: "text", text: modelContentText(message2.content) }] : [],
|
|
12751
13147
|
...message2.toolCalls.map((call) => ({
|
|
12752
13148
|
type: "tool_use",
|
|
@@ -12808,18 +13204,56 @@ var AnthropicModelAdapter = class {
|
|
|
12808
13204
|
stream: true,
|
|
12809
13205
|
messages,
|
|
12810
13206
|
...system ? { system } : {},
|
|
13207
|
+
...(() => {
|
|
13208
|
+
const thinking = this.#thinkingParam();
|
|
13209
|
+
return thinking === void 0 ? {} : { thinking };
|
|
13210
|
+
})(),
|
|
12811
13211
|
tools: [...request.tools].sort((a, b) => a.name.localeCompare(b.name)).map((tool) => ({
|
|
12812
13212
|
name: tool.name,
|
|
12813
13213
|
description: tool.description,
|
|
12814
13214
|
input_schema: { ...tool.inputSchema, type: "object" }
|
|
12815
13215
|
}))
|
|
12816
13216
|
};
|
|
12817
|
-
|
|
13217
|
+
let stream;
|
|
13218
|
+
try {
|
|
13219
|
+
stream = await this.client.messages.create(body, { signal: request.signal });
|
|
13220
|
+
} catch (error) {
|
|
13221
|
+
if (this.thinkingBudget > 0 && !this.#thinkingRejected && isThinkingParamRejected(error)) {
|
|
13222
|
+
this.#thinkingRejected = true;
|
|
13223
|
+
delete body.thinking;
|
|
13224
|
+
stripThinkingBlocks(body.messages);
|
|
13225
|
+
stream = await this.client.messages.create(body, { signal: request.signal });
|
|
13226
|
+
} else {
|
|
13227
|
+
throw error;
|
|
13228
|
+
}
|
|
13229
|
+
}
|
|
13230
|
+
const thinkingBuffers = /* @__PURE__ */ new Map();
|
|
12818
13231
|
for await (const event of stream) {
|
|
12819
13232
|
if (event.type === "message_start") {
|
|
12820
13233
|
hasUsage = event.message?.usage !== void 0;
|
|
12821
13234
|
inputTokens = updateInputUsage(inputUsage, event.message?.usage);
|
|
12822
13235
|
outputTokens = event.message?.usage?.output_tokens ?? outputTokens;
|
|
13236
|
+
} else if (event.type === "content_block_start" && event.content_block?.type === "thinking" && event.index !== void 0) {
|
|
13237
|
+
thinkingBuffers.set(event.index, { text: "" });
|
|
13238
|
+
} else if (event.type === "content_block_delta" && event.delta?.type === "thinking_delta") {
|
|
13239
|
+
if (event.index !== void 0 && event.delta.thinking) {
|
|
13240
|
+
const pending = thinkingBuffers.get(event.index);
|
|
13241
|
+
if (pending) pending.text += event.delta.thinking;
|
|
13242
|
+
}
|
|
13243
|
+
if (event.delta.thinking) yield { type: "thinking", text: event.delta.thinking };
|
|
13244
|
+
} else if (event.type === "content_block_delta" && event.delta?.type === "signature_delta" && event.index !== void 0) {
|
|
13245
|
+
const pending = thinkingBuffers.get(event.index);
|
|
13246
|
+
if (pending) pending.signature = (pending.signature ?? "") + (event.delta.signature ?? "");
|
|
13247
|
+
} else if (event.type === "content_block_stop" && event.index !== void 0 && thinkingBuffers.has(event.index)) {
|
|
13248
|
+
const pending = thinkingBuffers.get(event.index);
|
|
13249
|
+
if (pending.text.length > 0 || pending.signature !== void 0) {
|
|
13250
|
+
yield {
|
|
13251
|
+
type: "thinking-block",
|
|
13252
|
+
text: pending.text,
|
|
13253
|
+
...pending.signature === void 0 ? {} : { signature: pending.signature }
|
|
13254
|
+
};
|
|
13255
|
+
}
|
|
13256
|
+
thinkingBuffers.delete(event.index);
|
|
12823
13257
|
} else if (event.type === "content_block_start" && event.content_block?.type === "tool_use" && event.index !== void 0 && event.content_block.id && event.content_block.name) {
|
|
12824
13258
|
pendingTools.set(event.index, {
|
|
12825
13259
|
id: event.content_block.id,
|
|
@@ -13022,12 +13456,14 @@ function formatOpenAIUsage(model, breakdown) {
|
|
|
13022
13456
|
var OpenAIModelAdapter = class {
|
|
13023
13457
|
client;
|
|
13024
13458
|
debugUsage;
|
|
13459
|
+
thinkingEffort;
|
|
13025
13460
|
constructor(options) {
|
|
13026
13461
|
this.client = options.client ?? new OpenAI({
|
|
13027
13462
|
...options.apiKey === void 0 ? {} : { apiKey: options.apiKey },
|
|
13028
13463
|
...options.baseURL === void 0 ? {} : { baseURL: options.baseURL }
|
|
13029
13464
|
});
|
|
13030
13465
|
this.debugUsage = options.debugUsage ?? isEnvTruthy(process.env.FLAVOR_DEBUG_USAGE);
|
|
13466
|
+
this.thinkingEffort = options.thinkingEffort;
|
|
13031
13467
|
}
|
|
13032
13468
|
#logUsage(model, breakdown) {
|
|
13033
13469
|
if (breakdown === void 0) return;
|
|
@@ -13049,6 +13485,7 @@ var OpenAIModelAdapter = class {
|
|
|
13049
13485
|
const body = {
|
|
13050
13486
|
model: request.model,
|
|
13051
13487
|
input: (await Promise.all(request.messages.map(toInput))).flat(),
|
|
13488
|
+
...this.thinkingEffort === void 0 ? {} : { reasoning: { effort: this.thinkingEffort } },
|
|
13052
13489
|
tools: [...request.tools].sort((a, b) => a.name.localeCompare(b.name)).map((tool) => ({
|
|
13053
13490
|
type: "function",
|
|
13054
13491
|
name: tool.name,
|
|
@@ -13081,6 +13518,8 @@ var OpenAIModelAdapter = class {
|
|
|
13081
13518
|
}
|
|
13082
13519
|
} else if (event.type === "response.output_text.delta" && event.delta) {
|
|
13083
13520
|
yield { type: "text", text: event.delta };
|
|
13521
|
+
} else if ((event.type === "response.reasoning_summary_text.delta" || event.type === "response.reasoning_text.delta") && event.delta) {
|
|
13522
|
+
yield { type: "thinking", text: event.delta };
|
|
13084
13523
|
} else if (event.type === "response.function_call_arguments.done" && event.output_index !== void 0 && event.name) {
|
|
13085
13524
|
const callId = callIds.get(event.output_index);
|
|
13086
13525
|
if (callId && !emittedCalls.has(event.output_index)) {
|
|
@@ -17795,7 +18234,7 @@ function compileDefinition(record, scope2, workspace) {
|
|
|
17795
18234
|
name: record.name,
|
|
17796
18235
|
description: record.description,
|
|
17797
18236
|
inputSchema,
|
|
17798
|
-
modelInputSchema: record.inputSchema,
|
|
18237
|
+
modelInputSchema: strictJsonSchemaObject(record.inputSchema),
|
|
17799
18238
|
modelStrict: true,
|
|
17800
18239
|
...record.agents === void 0 ? {} : { agents: record.agents },
|
|
17801
18240
|
paths: () => [],
|
|
@@ -20859,6 +21298,7 @@ async function createProductionRuntime(options) {
|
|
|
20859
21298
|
managedTools.push(tool);
|
|
20860
21299
|
}
|
|
20861
21300
|
if (harnessCreated) harness.replaceMainTools(tools);
|
|
21301
|
+
options.onToolsChange?.();
|
|
20862
21302
|
};
|
|
20863
21303
|
tools.push(...createManagedToolManagementTools({
|
|
20864
21304
|
store: managedToolStore,
|
|
@@ -22188,6 +22628,25 @@ ${renderMemoryDocument(entries)}`;
|
|
|
22188
22628
|
signal.throwIfAborted();
|
|
22189
22629
|
return awaitWithSignal(Promise.resolve(handler(args, { workspace, signal })), signal);
|
|
22190
22630
|
},
|
|
22631
|
+
managedToolCommands: () => managedTools.map(({ name, description }) => ({ name, description })).sort((left, right) => left.name.localeCompare(right.name)),
|
|
22632
|
+
runManagedTool: async (name, rawInput, signal) => {
|
|
22633
|
+
const tool = managedTools.find((candidate) => sameToolName(candidate.name, name));
|
|
22634
|
+
if (tool === void 0) throw new Error(`Registered tool "${name}" is no longer available.`);
|
|
22635
|
+
signal.throwIfAborted();
|
|
22636
|
+
const input = normalizeToolCallInput(rawInput);
|
|
22637
|
+
const call = { name: tool.name, input };
|
|
22638
|
+
const validation = harness.main.runtime.normalize(call);
|
|
22639
|
+
if (!validation.ok) throw new Error(`Invalid input for registered tool "${tool.name}": ${validation.error.message}`);
|
|
22640
|
+
harness.main.runtime.beginTurn();
|
|
22641
|
+
const result = await harness.main.runtime.execute(
|
|
22642
|
+
{ name: tool.name, input: validation.input },
|
|
22643
|
+
{ agent: "main", ownerId: "main", signal }
|
|
22644
|
+
);
|
|
22645
|
+
if (!result.ok) {
|
|
22646
|
+
throw new Error(`Registered tool "${tool.name}" failed (${result.error?.code ?? "unknown"}): ${result.error?.message ?? "Unknown error"}`);
|
|
22647
|
+
}
|
|
22648
|
+
return result.output !== void 0 ? result.output : result.content;
|
|
22649
|
+
},
|
|
22191
22650
|
output: emitOutput,
|
|
22192
22651
|
questions,
|
|
22193
22652
|
async login() {
|
|
@@ -22238,8 +22697,12 @@ ${renderMemoryDocument(entries)}`;
|
|
|
22238
22697
|
};
|
|
22239
22698
|
registry.register(next.providerId, next.apiType === "anthropic" ? new AnthropicModelAdapter({
|
|
22240
22699
|
...adapterOptions,
|
|
22700
|
+
...providerConfig?.thinkingBudget === void 0 ? {} : { thinkingBudget: providerConfig.thinkingBudget },
|
|
22241
22701
|
...providerConfig?.claudeClient === true ? { headers: CLAUDE_CLIENT_HEADERS } : {}
|
|
22242
|
-
}) : new OpenAIModelAdapter(
|
|
22702
|
+
}) : new OpenAIModelAdapter({
|
|
22703
|
+
...adapterOptions,
|
|
22704
|
+
...providerConfig?.thinkingEffort === void 0 ? {} : { thinkingEffort: providerConfig.thinkingEffort }
|
|
22705
|
+
}));
|
|
22243
22706
|
effectiveLlm = next;
|
|
22244
22707
|
mainModel = `${next.providerId}:${next.defaultModel}`;
|
|
22245
22708
|
childModel = `${next.providerId}:${next.cheapModel}`;
|
|
@@ -22825,8 +23288,12 @@ async function registerConfiguredAdapters(providers, registry, environment, diag
|
|
|
22825
23288
|
};
|
|
22826
23289
|
const adapter = apiProtocol === "anthropic" ? new AnthropicModelAdapter({
|
|
22827
23290
|
...adapterOptions,
|
|
23291
|
+
...runtimeProvider.thinkingBudget === void 0 ? {} : { thinkingBudget: runtimeProvider.thinkingBudget },
|
|
22828
23292
|
...runtimeProvider.claudeClient === true ? { headers: CLAUDE_CLIENT_HEADERS } : {}
|
|
22829
|
-
}) : new OpenAIModelAdapter(
|
|
23293
|
+
}) : new OpenAIModelAdapter({
|
|
23294
|
+
...adapterOptions,
|
|
23295
|
+
...runtimeProvider.thinkingEffort === void 0 ? {} : { thinkingEffort: runtimeProvider.thinkingEffort }
|
|
23296
|
+
});
|
|
22830
23297
|
const cacheProfile = resolveCacheProfile({ apiType: apiProtocol, baseURL: runtimeProvider.baseURL });
|
|
22831
23298
|
if (apiProtocol === "openai" && isDashScopeBaseURL(runtimeProvider.baseURL)) {
|
|
22832
23299
|
diagnostics.push(
|
|
@@ -23191,6 +23658,8 @@ export {
|
|
|
23191
23658
|
executeShell,
|
|
23192
23659
|
packageVersion,
|
|
23193
23660
|
SkillRegistry,
|
|
23661
|
+
charWidth,
|
|
23662
|
+
thinkingWindow,
|
|
23194
23663
|
createTranscriptState,
|
|
23195
23664
|
transcriptReducer,
|
|
23196
23665
|
WorkspaceCheckpointStore,
|