nolo-cli 0.66.0-alpha.4 → 0.66.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/{_executeModel-UYF2UEIG.js → _executeModel-C63UG367.js} +13 -13
  2. package/{agentDeleteCommand-7SWSSU4X.js → agentDeleteCommand-AHCJ2KJ7.js} +6 -6
  3. package/{agentEmailCommands-UAF3YDG6.js → agentEmailCommands-JOMRC3W2.js} +15 -15
  4. package/{agentListCommands-473D3OB3.js → agentListCommands-6KB4IHQS.js} +8 -8
  5. package/{agentMachineCommands-NWHVKMP7.js → agentMachineCommands-SDRE2NTN.js} +6 -6
  6. package/{agentRecordCommands-G5ZQQNEC.js → agentRecordCommands-5YZGXSK7.js} +15 -15
  7. package/{agentRunCommand-ZTRT252J.js → agentRunCommand-AEY7AB2D.js} +15 -15
  8. package/{agentRuntimeLocal-3JLUMWN7.js → agentRuntimeLocal-COPOV7R7.js} +3 -3
  9. package/{agentSlice-RPMDYBLC.js → agentSlice-TV2HZX2H.js} +1 -1
  10. package/{appDeleteCommands-SCJZAMUA.js → appDeleteCommands-F6M2UEWG.js} +7 -7
  11. package/{appDeployCommands-RVBQZJUT.js → appDeployCommands-THWNABDT.js} +7 -7
  12. package/{appDeployStatusCommands-BUPLMNTO.js → appDeployStatusCommands-A4XSWHFX.js} +7 -7
  13. package/{appGetCommands-NQ34IZRG.js → appGetCommands-62FK5II3.js} +7 -7
  14. package/{appListCommands-KZHI5DQM.js → appListCommands-MQTHZLHV.js} +7 -7
  15. package/{chatQueueReduxAdapter-2Z6DYXAG.js → chatQueueReduxAdapter-BK5MJ4TA.js} +2 -2
  16. package/{chunk-RRY4U37C.js → chunk-7TSLWGZZ.js} +7 -7
  17. package/{chunk-FHAGENAS.js → chunk-AUKZOZFG.js} +1 -1
  18. package/{chunk-UZPQSVM6.js → chunk-B62OSA77.js} +1 -1
  19. package/{chunk-XOPPOOTE.js → chunk-FER25LZS.js} +4 -4
  20. package/{chunk-XCNSZUQA.js → chunk-FPUHDMMQ.js} +2 -2
  21. package/{chunk-76JYRUX4.js → chunk-G6LSVBWG.js} +1 -1
  22. package/{chunk-BWHZ4H2Q.js → chunk-HHR4KGYD.js} +7 -7
  23. package/{chunk-GVYMHBG3.js → chunk-I7SDLO23.js} +1 -1
  24. package/{chunk-RNYLWVME.js → chunk-IOZR6BLM.js} +3 -3
  25. package/{chunk-37XDGCY7.js → chunk-JWO3RQSH.js} +1 -1
  26. package/{chunk-ZSR7L46Q.js → chunk-K76ZXWUZ.js} +33 -23
  27. package/{chunk-4SCMOQRM.js → chunk-KFOJI4XK.js} +2 -2
  28. package/{chunk-J2WQUFGG.js → chunk-LNEAO4U2.js} +40 -24
  29. package/{chunk-6B2AUXKR.js → chunk-MW4F6TUJ.js} +5 -5
  30. package/{chunk-UMIARYFE.js → chunk-OXZDMKZW.js} +3 -3
  31. package/{chunk-P7OOB7QP.js → chunk-Q4OT2DC7.js} +1 -1
  32. package/{chunk-CTCW7U7N.js → chunk-Q6FF2MCK.js} +1 -1
  33. package/{chunk-YDNDUOB5.js → chunk-RIDW26NK.js} +1 -1
  34. package/{chunk-G2MPS44L.js → chunk-RXVVFYIF.js} +1 -1
  35. package/{chunk-PEZJEQAO.js → chunk-T7PQFKJU.js} +105 -35
  36. package/{chunk-HUZUAHZ6.js → chunk-TG3YNAWW.js} +2 -2
  37. package/{chunk-6AAQCFLQ.js → chunk-TWGLYE3V.js} +8 -8
  38. package/{chunk-6X5B2VF5.js → chunk-UFTOGLCE.js} +1 -1
  39. package/{chunk-RJ2SAFB5.js → chunk-V3ZKNK5D.js} +550 -1
  40. package/{chunk-5P6YOSF3.js → chunk-WTP5HY67.js} +4 -4
  41. package/{contentThunks-GMRDVLFD.js → contentThunks-GJEIIFO7.js} +3 -3
  42. package/{createAgentAutomationAction-CH6Q7JMD.js → createAgentAutomationAction-Q2NJFK36.js} +3 -3
  43. package/{createDialogAction-ARYHXJ2V.js → createDialogAction-M2XLDVIY.js} +4 -4
  44. package/{createPageAction-RAPK4J4H.js → createPageAction-YALT3K3T.js} +3 -3
  45. package/{dialogCommands-JAAYSIOE.js → dialogCommands-LM7MOWRV.js} +7 -7
  46. package/{dialogSlice-CJNADK2R.js → dialogSlice-UXLPONP7.js} +2 -2
  47. package/{docCreateCommands-U5OCW42O.js → docCreateCommands-VBWFWLUP.js} +6 -6
  48. package/{docDeleteCommands-6RAGSIKC.js → docDeleteCommands-B657OXLD.js} +7 -7
  49. package/{docReadCommands-ID6VUNQD.js → docReadCommands-STNB2GJG.js} +6 -6
  50. package/{docStore-6ZFYOHQT.js → docStore-VA4ZDSQB.js} +1 -1
  51. package/{docUpdateCommands-UIC4LWFG.js → docUpdateCommands-KFNCAZNJ.js} +6 -6
  52. package/{handleSendMessageAction-36NZDUHT.js → handleSendMessageAction-QY3N4ZWZ.js} +2 -2
  53. package/index.js +40 -40
  54. package/{machineCommands-25QIEYZQ.js → machineCommands-4CFWCR6F.js} +14 -14
  55. package/{machineWsRunDispatch-HWYVWOIE.js → machineWsRunDispatch-37NTQTHK.js} +14 -14
  56. package/package.json +1 -1
  57. package/{readlineWorkspace-22XWLYEH.js → readlineWorkspace-TNK2UNEK.js} +18 -18
  58. package/{runAgentClientLoop-NYNYXB5C.js → runAgentClientLoop-K27WYC5U.js} +11 -11
  59. package/{spaceCommands-VWJ2BUYK.js → spaceCommands-PBYDQ77V.js} +6 -6
  60. package/{streamAgentChatTurn-EK4UVC2Y.js → streamAgentChatTurn-CDS3RVB2.js} +12 -12
  61. package/{tools-U4GOB2KS.js → tools-WI4AE3VP.js} +8 -8
  62. package/{updateDialogTitleAction-EXREKMC5.js → updateDialogTitleAction-EDDSMWSX.js} +3 -3
@@ -176,6 +176,545 @@ function shouldFetchAgentRuntimeRecordRemotely(dbKey) {
176
176
  return /^agent(-pub)?-/.test(dbKey);
177
177
  }
178
178
 
179
+ // packages/agent-runtime/dialogReadProjection.ts
180
+ var DEFAULT_READ_DIALOG_MAX_RESPONSE_CHARS = 32e3;
181
+ var MIN_RESPONSE_BUDGET_CHARS = 1024;
182
+ var DEFAULT_MAX_MESSAGE_CHARS = 8e3;
183
+ var DEFAULT_MAX_FIELD_CHARS = 2e3;
184
+ var DEFAULT_MAX_META_CHARS = 6e3;
185
+ var MAX_TOOL_CALLS_PER_PROJECTED_MESSAGE = 20;
186
+ var MAX_CONTENT_PARTS_PER_PROJECTED_MESSAGE = 40;
187
+ var ESTIMATE_MAX_DEPTH = 12;
188
+ var HARD_CAP_MAX_ITERATIONS = 64;
189
+ var FIELD_TRUNCATION_MARKER = "\u2026[truncated";
190
+ function resolveBudget(options) {
191
+ const positive = (value, fallback) => typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
192
+ const maxResponseChars = Math.max(
193
+ MIN_RESPONSE_BUDGET_CHARS,
194
+ positive(options?.maxResponseChars, DEFAULT_READ_DIALOG_MAX_RESPONSE_CHARS)
195
+ );
196
+ return {
197
+ maxResponseChars,
198
+ maxMessageChars: Math.min(
199
+ positive(options?.maxMessageChars, DEFAULT_MAX_MESSAGE_CHARS),
200
+ maxResponseChars
201
+ ),
202
+ maxFieldChars: positive(options?.maxFieldChars, DEFAULT_MAX_FIELD_CHARS),
203
+ maxMetaChars: positive(options?.maxMetaChars, DEFAULT_MAX_META_CHARS),
204
+ maxMessages: options?.maxMessages
205
+ };
206
+ }
207
+ function estimateJsonChars(value, depth = 0) {
208
+ if (value === null || value === void 0) return 4;
209
+ const type = typeof value;
210
+ if (type === "string") return value.length + 2;
211
+ if (type === "number") {
212
+ const text = String(value);
213
+ return text.length > 0 ? text.length : 1;
214
+ }
215
+ if (type === "boolean") return value ? 4 : 5;
216
+ if (type !== "object") return 8;
217
+ if (depth >= ESTIMATE_MAX_DEPTH) return 16;
218
+ if (Array.isArray(value)) {
219
+ let total2 = 2;
220
+ for (const item of value) total2 += estimateJsonChars(item, depth + 1) + 1;
221
+ return total2;
222
+ }
223
+ let total = 2;
224
+ for (const [key, item] of Object.entries(value)) {
225
+ total += key.length + 4 + estimateJsonChars(item, depth + 1);
226
+ }
227
+ return total;
228
+ }
229
+ function truncateHead(text, maxChars) {
230
+ if (text.length <= maxChars) return text;
231
+ return `${text.slice(0, Math.max(1, maxChars))}${FIELD_TRUNCATION_MARKER} +${text.length - maxChars} chars]`;
232
+ }
233
+ function boundValueDeep(value, maxFieldChars, depth = 0) {
234
+ if (typeof value === "string") return truncateHead(value, maxFieldChars);
235
+ if (value === null || value === void 0) return value;
236
+ if (typeof value !== "object") return value;
237
+ if (depth >= ESTIMATE_MAX_DEPTH) return FIELD_TRUNCATION_MARKER + " depth]";
238
+ if (Array.isArray(value)) {
239
+ return value.map((item) => boundValueDeep(item, maxFieldChars, depth + 1));
240
+ }
241
+ const out = {};
242
+ for (const [key, item] of Object.entries(value)) {
243
+ out[key] = boundValueDeep(item, maxFieldChars, depth + 1);
244
+ }
245
+ return out;
246
+ }
247
+ function projectMeta(meta, maxMetaChars) {
248
+ const originalChars = estimateJsonChars(meta);
249
+ if (originalChars <= maxMetaChars) {
250
+ return { meta, truncated: false, originalChars, returnedChars: originalChars };
251
+ }
252
+ const bounded = boundValueDeep(meta, Math.min(DEFAULT_MAX_FIELD_CHARS, maxMetaChars));
253
+ const returnedChars = estimateJsonChars(bounded);
254
+ if (returnedChars <= maxMetaChars) {
255
+ return { meta: bounded, truncated: true, originalChars, returnedChars };
256
+ }
257
+ return {
258
+ meta: { projectionTruncated: true, estimatedOriginalChars: originalChars },
259
+ truncated: true,
260
+ originalChars,
261
+ returnedChars: estimateJsonChars({ projectionTruncated: true, estimatedOriginalChars: originalChars })
262
+ };
263
+ }
264
+ function projectDialogMetaForAgent(meta, options) {
265
+ const budget = resolveBudget(options);
266
+ const maxMetaChars = Math.min(budget.maxMetaChars, Math.floor(budget.maxResponseChars / 2));
267
+ const projected = projectMeta(meta, maxMetaChars);
268
+ return { meta: projected.meta, truncated: projected.truncated };
269
+ }
270
+ function asRecord(message) {
271
+ return message && typeof message === "object" ? { ...message } : { value: message };
272
+ }
273
+ function buildEnvelopeStub(src, originalChars) {
274
+ return {
275
+ role: src.role ?? src.authorRole ?? null,
276
+ ...typeof src.id === "string" ? { id: src.id } : {},
277
+ ...typeof src.createdAt === "string" ? { createdAt: src.createdAt } : {},
278
+ projectionTruncated: true,
279
+ estimatedOriginalChars: originalChars
280
+ };
281
+ }
282
+ function projectDialogMessage(message, budget) {
283
+ const originalChars = estimateJsonChars(message);
284
+ if (originalChars <= budget.maxMessageChars) {
285
+ return { message, originalChars, returnedChars: originalChars, projected: false };
286
+ }
287
+ const out = asRecord(message);
288
+ const src = message && typeof message === "object" ? message : out;
289
+ let projected = false;
290
+ let contentPartsTotal;
291
+ let contentPartsReturned;
292
+ let toolCallsTotal;
293
+ let toolCallsReturned;
294
+ if (typeof src.content === "string") {
295
+ const bounded = truncateHead(src.content, budget.maxFieldChars);
296
+ if (bounded !== src.content) {
297
+ out.content = bounded;
298
+ projected = true;
299
+ }
300
+ } else if (Array.isArray(src.content)) {
301
+ const total = src.content.length;
302
+ if (total > MAX_CONTENT_PARTS_PER_PROJECTED_MESSAGE) {
303
+ out.content = [
304
+ ...src.content.slice(0, MAX_CONTENT_PARTS_PER_PROJECTED_MESSAGE).map((part) => boundValueDeep(part, budget.maxFieldChars)),
305
+ // 合法 typed text part:不得向 content 数组混入裸字符串标记。
306
+ { type: "text", text: `${FIELD_TRUNCATION_MARKER} +${total - MAX_CONTENT_PARTS_PER_PROJECTED_MESSAGE} content parts]` }
307
+ ];
308
+ contentPartsTotal = total;
309
+ contentPartsReturned = MAX_CONTENT_PARTS_PER_PROJECTED_MESSAGE;
310
+ projected = true;
311
+ } else {
312
+ const boundedParts = src.content.map((part) => boundValueDeep(part, budget.maxFieldChars));
313
+ if (estimateJsonChars(boundedParts) < estimateJsonChars(src.content)) {
314
+ out.content = boundedParts;
315
+ projected = true;
316
+ contentPartsTotal = total;
317
+ contentPartsReturned = total;
318
+ }
319
+ }
320
+ }
321
+ if (typeof src.reasoning_content === "string") {
322
+ const bounded = truncateHead(src.reasoning_content, budget.maxFieldChars);
323
+ if (bounded !== src.reasoning_content) {
324
+ out.reasoning_content = bounded;
325
+ projected = true;
326
+ }
327
+ }
328
+ if (Array.isArray(src.tool_calls)) {
329
+ const total = src.tool_calls.length;
330
+ let calls = src.tool_calls;
331
+ if (total > MAX_TOOL_CALLS_PER_PROJECTED_MESSAGE) {
332
+ calls = calls.slice(0, MAX_TOOL_CALLS_PER_PROJECTED_MESSAGE);
333
+ toolCallsTotal = total;
334
+ toolCallsReturned = MAX_TOOL_CALLS_PER_PROJECTED_MESSAGE;
335
+ projected = true;
336
+ }
337
+ const boundedCalls = calls.map((call) => {
338
+ if (!call || typeof call !== "object" || Array.isArray(call)) {
339
+ return call;
340
+ }
341
+ const next = { ...call };
342
+ if (next.function && typeof next.function === "object" && !Array.isArray(next.function)) {
343
+ next.function = { ...next.function };
344
+ if (typeof next.function.arguments === "string") {
345
+ next.function.arguments = truncateHead(
346
+ next.function.arguments,
347
+ budget.maxFieldChars
348
+ );
349
+ }
350
+ }
351
+ return next;
352
+ });
353
+ if (estimateJsonChars(boundedCalls) < estimateJsonChars(src.tool_calls)) {
354
+ out.tool_calls = boundedCalls;
355
+ projected = true;
356
+ if (toolCallsReturned === void 0) {
357
+ toolCallsTotal = total;
358
+ toolCallsReturned = total;
359
+ }
360
+ }
361
+ }
362
+ for (const key of ["tool_result_metadata", "metadata"]) {
363
+ const value = src[key];
364
+ if (value && typeof value === "object") {
365
+ const bounded = boundValueDeep(value, budget.maxFieldChars);
366
+ if (estimateJsonChars(bounded) < estimateJsonChars(value)) {
367
+ out[key] = bounded;
368
+ projected = true;
369
+ }
370
+ }
371
+ }
372
+ let returnedChars = estimateJsonChars(out);
373
+ const stubThreshold = Math.max(
374
+ Math.floor(budget.maxMessageChars * 1.15),
375
+ budget.maxFieldChars
376
+ );
377
+ if (returnedChars > stubThreshold) {
378
+ const stub = buildEnvelopeStub(src, originalChars);
379
+ const stubChars = estimateJsonChars(stub);
380
+ if (stubChars < returnedChars) {
381
+ return {
382
+ message: stub,
383
+ originalChars,
384
+ returnedChars: stubChars,
385
+ projected: true
386
+ };
387
+ }
388
+ }
389
+ if (projected) {
390
+ out.projection = {
391
+ truncated: true,
392
+ originalChars,
393
+ returnedChars,
394
+ ...contentPartsTotal !== void 0 ? { contentPartsTotal, contentPartsReturned } : {},
395
+ ...toolCallsTotal !== void 0 ? { toolCallsTotal, toolCallsReturned } : {}
396
+ };
397
+ returnedChars = estimateJsonChars(out);
398
+ }
399
+ return { message: out, originalChars, returnedChars, projected };
400
+ }
401
+ var CONTINUATION_HINT = 'To continue safely: re-run readDialog with a smaller limit, or use mode="status" for meta + runtimeCheckpoint only. Oversized messages keep head slices of content/reasoning_content/tool_calls with per-message projection stats.';
402
+ function buildStats(args) {
403
+ return {
404
+ truncated: args.truncated,
405
+ messagesTotal: args.total,
406
+ messagesTotalKnown: args.totalKnown ?? true,
407
+ messagesReturned: args.returned,
408
+ estimatedOriginalChars: args.estimatedOriginalChars,
409
+ estimatedReturnedChars: args.estimatedReturnedChars,
410
+ omittedChars: Math.max(0, args.estimatedOriginalChars - args.estimatedReturnedChars),
411
+ continuation: args.truncated ? CONTINUATION_HINT : ""
412
+ };
413
+ }
414
+ function projectDialogReadForAgent(args) {
415
+ const budget = resolveBudget(args.options);
416
+ const messages = Array.isArray(args.messages) ? args.messages : [];
417
+ const maxMetaChars = Math.min(budget.maxMetaChars, Math.floor(budget.maxResponseChars / 2));
418
+ const metaProjection = projectMeta(args.meta, maxMetaChars);
419
+ const messagesOverhead = 64;
420
+ const envelopeOverhead = Math.min(1024, Math.max(256, Math.floor(budget.maxResponseChars / 8)));
421
+ const statsOverhead = estimateJsonChars({
422
+ truncated: true,
423
+ messagesTotal: messages.length,
424
+ messagesReturned: messages.length,
425
+ estimatedOriginalChars: 88888888,
426
+ estimatedReturnedChars: 88888888,
427
+ omittedChars: 88888888,
428
+ continuation: CONTINUATION_HINT
429
+ });
430
+ const budgetForMessages = Math.max(
431
+ budget.maxResponseChars - metaProjection.returnedChars - messagesOverhead - statsOverhead - envelopeOverhead,
432
+ 128
433
+ );
434
+ const kept = [];
435
+ let estimatedOriginalChars = metaProjection.originalChars;
436
+ let returnedChars = metaProjection.returnedChars + messagesOverhead;
437
+ let anyProjected = false;
438
+ let index = messages.length;
439
+ while (index > 0) {
440
+ const message = messages[index - 1];
441
+ const projectedMessage = projectDialogMessage(message, budget);
442
+ estimatedOriginalChars += projectedMessage.originalChars + 1;
443
+ if (returnedChars + projectedMessage.returnedChars <= budgetForMessages) {
444
+ kept.push(projectedMessage);
445
+ returnedChars += projectedMessage.returnedChars + 1;
446
+ anyProjected = anyProjected || projectedMessage.projected;
447
+ index -= 1;
448
+ continue;
449
+ }
450
+ index -= 1;
451
+ while (index > 0) {
452
+ index -= 1;
453
+ estimatedOriginalChars += estimateJsonChars(messages[index]) + 1;
454
+ }
455
+ break;
456
+ }
457
+ while (index > 1) {
458
+ index -= 1;
459
+ estimatedOriginalChars += estimateJsonChars(messages[index - 1]) + 1;
460
+ }
461
+ if (kept.length === 0 && messages.length > 0) {
462
+ const newest = messages[messages.length - 1];
463
+ let projectedMessage = projectDialogMessage(newest, budget);
464
+ if (projectedMessage.returnedChars + returnedChars > budgetForMessages) {
465
+ const stub = buildEnvelopeStub(
466
+ newest && typeof newest === "object" ? newest : { value: newest },
467
+ projectedMessage.originalChars
468
+ );
469
+ projectedMessage = {
470
+ message: stub,
471
+ originalChars: projectedMessage.originalChars,
472
+ returnedChars: estimateJsonChars(stub),
473
+ projected: true
474
+ };
475
+ }
476
+ kept.push(projectedMessage);
477
+ returnedChars += projectedMessage.returnedChars + 1;
478
+ anyProjected = true;
479
+ }
480
+ kept.reverse();
481
+ const truncated = metaProjection.truncated || anyProjected || kept.length < messages.length;
482
+ let stats = buildStats({
483
+ truncated,
484
+ total: messages.length,
485
+ returned: kept.length,
486
+ estimatedOriginalChars,
487
+ estimatedReturnedChars: returnedChars + estimateJsonChars({
488
+ truncated,
489
+ messagesTotal: messages.length,
490
+ messagesReturned: kept.length,
491
+ estimatedOriginalChars,
492
+ estimatedReturnedChars: returnedChars,
493
+ omittedChars: Math.max(0, estimatedOriginalChars - returnedChars),
494
+ continuation: truncated ? CONTINUATION_HINT : ""
495
+ })
496
+ });
497
+ let result = { meta: metaProjection.meta, messages: kept.map((e) => e.message), stats };
498
+ let guard = HARD_CAP_MAX_ITERATIONS;
499
+ while (JSON.stringify(result).length > budget.maxResponseChars && kept.length > 0 && guard-- > 0) {
500
+ kept.shift();
501
+ stats = buildStats({
502
+ truncated: true,
503
+ total: messages.length,
504
+ returned: kept.length,
505
+ estimatedOriginalChars,
506
+ estimatedReturnedChars: returnedChars
507
+ });
508
+ result = { meta: metaProjection.meta, messages: kept.map((e) => e.message), stats };
509
+ }
510
+ if (JSON.stringify(result).length > budget.maxResponseChars) {
511
+ const miniMeta = metaProjection.truncated ? metaProjection.meta : { projectionTruncated: true, estimatedOriginalChars: metaProjection.originalChars };
512
+ result = {
513
+ meta: miniMeta,
514
+ messages: [],
515
+ stats: { ...stats, continuation: "", messagesReturned: 0 }
516
+ };
517
+ if (JSON.stringify(result).length > budget.maxResponseChars) {
518
+ result = {
519
+ meta: { projectionTruncated: true },
520
+ messages: [],
521
+ stats: { ...stats, continuation: "", messagesReturned: 0 }
522
+ };
523
+ }
524
+ }
525
+ return result;
526
+ }
527
+ function createStreamingDialogReadProjector(options) {
528
+ const budget = resolveBudget(options);
529
+ const maxMetaChars = Math.min(budget.maxMetaChars, Math.floor(budget.maxResponseChars / 2));
530
+ const limit = typeof budget.maxMessages === "number" && budget.maxMessages > 0 ? Math.floor(budget.maxMessages) : void 0;
531
+ const kept = [];
532
+ let totalSeen = 0;
533
+ let totalOriginalChars = 0;
534
+ let keptChars = 0;
535
+ let anyProjected = false;
536
+ const evictOldest = () => {
537
+ const evicted = kept.shift();
538
+ if (evicted) keptChars -= evicted.returnedChars + 1;
539
+ };
540
+ return {
541
+ addMessage(message) {
542
+ totalSeen += 1;
543
+ const projectedMessage = projectDialogMessage(message, budget);
544
+ totalOriginalChars += projectedMessage.originalChars + 1;
545
+ kept.push({
546
+ message: projectedMessage.message,
547
+ returnedChars: projectedMessage.returnedChars,
548
+ originalChars: projectedMessage.originalChars,
549
+ projected: projectedMessage.projected
550
+ });
551
+ keptChars += projectedMessage.returnedChars + 1;
552
+ anyProjected = anyProjected || projectedMessage.projected;
553
+ while (limit !== void 0 && kept.length > limit) evictOldest();
554
+ const messagesBudget = budget.maxResponseChars - Math.floor(budget.maxResponseChars / 4);
555
+ while (keptChars > messagesBudget && kept.length > 1) evictOldest();
556
+ if (keptChars > messagesBudget && kept.length === 1) {
557
+ const only = kept[0];
558
+ const stubSource = only.message && typeof only.message === "object" ? only.message : { value: only.message };
559
+ const stub = buildEnvelopeStub(stubSource, only.originalChars);
560
+ const stubChars = estimateJsonChars(stub);
561
+ if (stubChars < only.returnedChars) {
562
+ keptChars -= only.returnedChars;
563
+ kept[0] = { message: stub, returnedChars: stubChars, originalChars: only.originalChars, projected: true };
564
+ keptChars += stubChars;
565
+ anyProjected = true;
566
+ }
567
+ }
568
+ },
569
+ finish(meta) {
570
+ const metaProjection = projectMeta(meta, maxMetaChars);
571
+ const estimatedOriginalChars = metaProjection.originalChars + totalOriginalChars;
572
+ const keptProjected = anyProjected || kept.some((entry) => entry.projected);
573
+ const truncated = metaProjection.truncated || keptProjected || totalSeen > kept.length;
574
+ const estimatedReturnedChars = metaProjection.returnedChars + keptChars + 64;
575
+ let stats = buildStats({
576
+ truncated,
577
+ total: totalSeen,
578
+ returned: kept.length,
579
+ estimatedOriginalChars,
580
+ estimatedReturnedChars
581
+ });
582
+ let result = { meta: metaProjection.meta, messages: kept.map((e) => e.message), stats };
583
+ let guard = HARD_CAP_MAX_ITERATIONS;
584
+ while (JSON.stringify(result).length > budget.maxResponseChars && kept.length > 0 && guard-- > 0) {
585
+ const evicted = kept.shift();
586
+ if (evicted) keptChars -= evicted.returnedChars + 1;
587
+ stats = buildStats({
588
+ truncated: true,
589
+ total: totalSeen,
590
+ returned: kept.length,
591
+ estimatedOriginalChars,
592
+ estimatedReturnedChars: metaProjection.returnedChars + keptChars + 64
593
+ });
594
+ result = { meta: metaProjection.meta, messages: kept.map((e) => e.message), stats };
595
+ }
596
+ if (JSON.stringify(result).length > budget.maxResponseChars) {
597
+ result = {
598
+ meta: metaProjection.truncated ? metaProjection.meta : { projectionTruncated: true, estimatedOriginalChars: metaProjection.originalChars },
599
+ messages: [],
600
+ stats: { ...stats, continuation: "", messagesReturned: 0 }
601
+ };
602
+ if (JSON.stringify(result).length > budget.maxResponseChars) {
603
+ result = {
604
+ meta: { projectionTruncated: true },
605
+ messages: [],
606
+ stats: { ...stats, continuation: "", messagesReturned: 0 }
607
+ };
608
+ }
609
+ }
610
+ return result;
611
+ }
612
+ };
613
+ }
614
+ function boundSummaryText(text, maxChars = 200) {
615
+ return truncateHead(text, maxChars);
616
+ }
617
+ function buildDialogReadEnvelope(args) {
618
+ const budget = resolveBudget(args.options);
619
+ let meta;
620
+ let messages;
621
+ let stats;
622
+ if (args.stats) {
623
+ meta = projectDialogMetaForAgent(args.meta, args.options).meta;
624
+ messages = Array.isArray(args.messages) ? args.messages : [];
625
+ stats = { ...args.stats };
626
+ } else {
627
+ const projected = projectDialogReadForAgent({
628
+ meta: args.meta,
629
+ messages: args.messages,
630
+ options: args.options
631
+ });
632
+ meta = projected.meta;
633
+ messages = projected.messages;
634
+ stats = projected.stats;
635
+ }
636
+ let extras = { ...args.envelope ?? {} };
637
+ let summary = { ...args.summary ?? {} };
638
+ let summaryDropped = false;
639
+ let hintDropped = false;
640
+ let metaStubbed = false;
641
+ let extrasDropped = false;
642
+ const assemble = () => {
643
+ stats = { ...stats, messagesReturned: messages.length };
644
+ if (Object.prototype.hasOwnProperty.call(extras, "messagesCount")) {
645
+ extras = { ...extras, messagesCount: messages.length };
646
+ }
647
+ const env = { ...extras, ...stats, meta, messages };
648
+ if (Object.keys(summary).length > 0) env.summary = summary;
649
+ return env;
650
+ };
651
+ let envelope = assemble();
652
+ let serialized = JSON.stringify(envelope);
653
+ for (; ; ) {
654
+ if (serialized.length <= budget.maxResponseChars) break;
655
+ if (!summaryDropped && Object.keys(summary).length > 0) {
656
+ summary = {};
657
+ summaryDropped = true;
658
+ } else if (!hintDropped && stats.continuation) {
659
+ stats = { ...stats, continuation: "" };
660
+ hintDropped = true;
661
+ } else if (messages.length > 0) {
662
+ messages = messages.slice(1);
663
+ stats = { ...stats, messagesReturned: messages.length, truncated: true };
664
+ } else if (!metaStubbed) {
665
+ meta = { projectionTruncated: true };
666
+ metaStubbed = true;
667
+ } else if (!extrasDropped) {
668
+ extrasDropped = true;
669
+ const minimalExtras = {};
670
+ for (const key of ["source", "dialogId", "dialogKey"]) {
671
+ if (extras[key] !== void 0) minimalExtras[key] = extras[key];
672
+ }
673
+ extras = minimalExtras;
674
+ } else {
675
+ envelope = { projectionTruncated: true, messages: [] };
676
+ serialized = JSON.stringify(envelope);
677
+ break;
678
+ }
679
+ envelope = assemble();
680
+ serialized = JSON.stringify(envelope);
681
+ }
682
+ return {
683
+ envelope,
684
+ serialized,
685
+ maxResponseChars: budget.maxResponseChars,
686
+ withinBudget: serialized.length <= budget.maxResponseChars
687
+ };
688
+ }
689
+ var BRIDGE_STREAM_MAX_CHARS = 262144;
690
+ async function readTextStreamUpToChars(stream, maxChars) {
691
+ if (!stream) return { text: "", truncated: false };
692
+ const reader = stream.getReader();
693
+ const decoder = new TextDecoder();
694
+ let text = "";
695
+ let truncated = false;
696
+ for (; ; ) {
697
+ const { done, value } = await reader.read();
698
+ if (done) break;
699
+ if (value) text += decoder.decode(value, { stream: true });
700
+ if (text.length >= maxChars) {
701
+ truncated = true;
702
+ try {
703
+ await reader.cancel();
704
+ } catch {
705
+ }
706
+ break;
707
+ }
708
+ }
709
+ text += decoder.decode();
710
+ if (truncated) {
711
+ text += `
712
+
713
+ [bridged output truncated at ${maxChars} chars; narrow the request or use readDialog mode="status"]`;
714
+ }
715
+ return { text, truncated };
716
+ }
717
+
179
718
  // packages/ai/agent/agentSelectionPriority.ts
180
719
  function parseAgentTimestamp(value) {
181
720
  if (typeof value === "number" && Number.isFinite(value)) return value;
@@ -278,7 +817,7 @@ function buildNoloWorkspaceOpenAiTools(args) {
278
817
  limit: { type: "integer", description: "Maximum dialogs to return." },
279
818
  space: stringToolParam("Optional space id or URL.")
280
819
  });
281
- add("readDialog", `Read one persisted dialog (metadata + messages) by full dbKey (dialog-<userId>-<id>) or URL. Use listDialogs first if target is unclear; a bare id resolves against the current user, pass user for someone else's dialog. Reading an agent run's dialog is fine at any time, but do not poll a still-running one through the full transcript: if controlAgentRun is available prefer it for live runs, otherwise use mode="status" for a compact snapshot, and pull the full transcript once the run is done/failed/cancelled.`, {
820
+ add("readDialog", `Read one persisted dialog (metadata + messages) by full dbKey (dialog-<userId>-<id>) or URL. Use listDialogs first if target is unclear; a bare id resolves against the current user, pass user for someone else's dialog. Reading an agent run's dialog is fine at any time, but do not poll a still-running one through the full transcript: if controlAgentRun is available prefer it for live runs, otherwise use mode="status" for a compact snapshot, and pull the full transcript once the run is done/failed/cancelled. The response is budgeted: reasoning_content, tool_calls arguments, tool result content and metadata are head-truncated with projection stats (truncated, messagesTotal/messagesReturned, estimatedOriginalChars/omittedChars). For review or verification, read mode="status" plus the final verdict and take diffs from the worktree instead of pulling the full execution transcript.`, {
282
821
  dialog: stringToolParam("Dialog dbKey (dialog-<userId>-<id>), dialog URL, or bare id (resolved against user/current account)."),
283
822
  mode: {
284
823
  type: "string",
@@ -614,6 +1153,9 @@ function buildNoloWorkspaceCommandArgs(call) {
614
1153
  const cliArgs = ["dialog", statusMode ? "status" : "read", dialog];
615
1154
  const limit = statusMode ? null : noloPositiveIntegerString(args.limit);
616
1155
  if (limit) cliArgs.push(limit);
1156
+ if (!statusMode) {
1157
+ cliArgs.push("--max-response-chars", String(DEFAULT_READ_DIALOG_MAX_RESPONSE_CHARS));
1158
+ }
617
1159
  const user = noloStringArg(args.user ?? args.userId ?? args.owner);
618
1160
  if (user) cliArgs.push("--user", user);
619
1161
  const server = noloStringArg(args.server ?? args.serverBase ?? args.serverUrl);
@@ -719,6 +1261,13 @@ export {
719
1261
  AGENT_SELECTION_PRIORITY_INSTRUCTIONS,
720
1262
  buildAgentRuntimeAgentLookupKeys,
721
1263
  shouldFetchAgentRuntimeRecordRemotely,
1264
+ DEFAULT_READ_DIALOG_MAX_RESPONSE_CHARS,
1265
+ projectDialogReadForAgent,
1266
+ createStreamingDialogReadProjector,
1267
+ boundSummaryText,
1268
+ buildDialogReadEnvelope,
1269
+ BRIDGE_STREAM_MAX_CHARS,
1270
+ readTextStreamUpToChars,
722
1271
  NOLO_WORKSPACE_TOOL_NAMES,
723
1272
  buildNoloWorkspaceOpenAiTools,
724
1273
  noloPositiveIntegerString,
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  createCliLocalRuntimeAdapter,
3
3
  summarizeEndpoint
4
- } from "./chunk-BWHZ4H2Q.js";
4
+ } from "./chunk-HHR4KGYD.js";
5
5
  import {
6
6
  clipMultilineText
7
- } from "./chunk-J2WQUFGG.js";
7
+ } from "./chunk-LNEAO4U2.js";
8
8
  import {
9
9
  runLocalAgentTurn
10
- } from "./chunk-ZSR7L46Q.js";
10
+ } from "./chunk-K76ZXWUZ.js";
11
11
  import {
12
12
  applyToolSurfaceConstraints
13
- } from "./chunk-RJ2SAFB5.js";
13
+ } from "./chunk-V3ZKNK5D.js";
14
14
  import {
15
15
  resolveLocalRuntimeEnvFromPolicy
16
16
  } from "./chunk-3JQ2NRYU.js";
@@ -7,14 +7,14 @@ import {
7
7
  updateContentPinned,
8
8
  updateContentTitle,
9
9
  uploadAndAddFileToSpace
10
- } from "./chunk-YDNDUOB5.js";
10
+ } from "./chunk-RIDW26NK.js";
11
11
  import "./chunk-ZJ7UHBJS.js";
12
- import "./chunk-6AAQCFLQ.js";
12
+ import "./chunk-TWGLYE3V.js";
13
13
  import "./chunk-EVBFYPDC.js";
14
14
  import "./chunk-HQUORJTM.js";
15
15
  import "./chunk-YYLHWIW6.js";
16
16
  import "./chunk-AGGIDPCZ.js";
17
- import "./chunk-UMIARYFE.js";
17
+ import "./chunk-OXZDMKZW.js";
18
18
  import "./chunk-76JAMDUT.js";
19
19
  import "./chunk-5RGU3J7P.js";
20
20
  import "./chunk-6YTOJY35.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  addContentToSpace
3
- } from "./chunk-YDNDUOB5.js";
3
+ } from "./chunk-RIDW26NK.js";
4
4
  import "./chunk-ZJ7UHBJS.js";
5
- import "./chunk-6AAQCFLQ.js";
5
+ import "./chunk-TWGLYE3V.js";
6
6
  import "./chunk-EVBFYPDC.js";
7
7
  import "./chunk-HQUORJTM.js";
8
8
  import "./chunk-YYLHWIW6.js";
9
9
  import "./chunk-AGGIDPCZ.js";
10
- import "./chunk-UMIARYFE.js";
10
+ import "./chunk-OXZDMKZW.js";
11
11
  import "./chunk-76JAMDUT.js";
12
12
  import "./chunk-5RGU3J7P.js";
13
13
  import "./chunk-6YTOJY35.js";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  createDialogAction,
3
3
  isLocalOwnerDialogAgents
4
- } from "./chunk-4SCMOQRM.js";
5
- import "./chunk-YDNDUOB5.js";
4
+ } from "./chunk-KFOJI4XK.js";
5
+ import "./chunk-RIDW26NK.js";
6
6
  import "./chunk-ZJ7UHBJS.js";
7
- import "./chunk-6AAQCFLQ.js";
7
+ import "./chunk-TWGLYE3V.js";
8
8
  import "./chunk-EVBFYPDC.js";
9
9
  import "./chunk-HQUORJTM.js";
10
10
  import "./chunk-YYLHWIW6.js";
11
11
  import "./chunk-AGGIDPCZ.js";
12
- import "./chunk-UMIARYFE.js";
12
+ import "./chunk-OXZDMKZW.js";
13
13
  import "./chunk-76JAMDUT.js";
14
14
  import "./chunk-5RGU3J7P.js";
15
15
  import "./chunk-6YTOJY35.js";
@@ -14,16 +14,16 @@ import {
14
14
  import {
15
15
  addContentToSpace,
16
16
  client_default
17
- } from "./chunk-YDNDUOB5.js";
17
+ } from "./chunk-RIDW26NK.js";
18
18
  import {
19
19
  getCurrentSpaceId
20
20
  } from "./chunk-ZJ7UHBJS.js";
21
- import "./chunk-6AAQCFLQ.js";
21
+ import "./chunk-TWGLYE3V.js";
22
22
  import "./chunk-EVBFYPDC.js";
23
23
  import "./chunk-HQUORJTM.js";
24
24
  import "./chunk-YYLHWIW6.js";
25
25
  import "./chunk-AGGIDPCZ.js";
26
- import "./chunk-UMIARYFE.js";
26
+ import "./chunk-OXZDMKZW.js";
27
27
  import "./chunk-76JAMDUT.js";
28
28
  import "./chunk-5RGU3J7P.js";
29
29
  import "./chunk-6YTOJY35.js";