@ouispec/agent-worker 0.10.0 → 0.11.0

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 (44) hide show
  1. package/README.md +1 -1
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/orchestrator.d.ts.map +1 -1
  5. package/dist/orchestrator.js +176 -73
  6. package/dist/orchestrator.js.map +1 -1
  7. package/dist/prompt/clock.d.ts +17 -7
  8. package/dist/prompt/clock.d.ts.map +1 -1
  9. package/dist/prompt/clock.js +4 -16
  10. package/dist/prompt/clock.js.map +1 -1
  11. package/dist/prompt/rules/base.d.ts.map +1 -1
  12. package/dist/prompt/rules/base.js +1 -0
  13. package/dist/prompt/rules/base.js.map +1 -1
  14. package/dist/prompt/rules/ui-control.js +1 -1
  15. package/dist/prompt/spoken-input.d.ts +6 -12
  16. package/dist/prompt/spoken-input.d.ts.map +1 -1
  17. package/dist/prompt/spoken-input.js +7 -19
  18. package/dist/prompt/spoken-input.js.map +1 -1
  19. package/dist/runtime/turn-runner.d.ts.map +1 -1
  20. package/dist/runtime/turn-runner.js +4 -2
  21. package/dist/runtime/turn-runner.js.map +1 -1
  22. package/dist/runtime/types.d.ts +17 -2
  23. package/dist/runtime/types.d.ts.map +1 -1
  24. package/dist/step-messages.d.ts +23 -0
  25. package/dist/step-messages.d.ts.map +1 -0
  26. package/dist/step-messages.js +51 -0
  27. package/dist/step-messages.js.map +1 -0
  28. package/dist/stop/partial.d.ts.map +1 -1
  29. package/dist/stop/partial.js +2 -1
  30. package/dist/stop/partial.js.map +1 -1
  31. package/dist/types.d.ts +9 -1
  32. package/dist/types.d.ts.map +1 -1
  33. package/dist/ui/page-state-at-end.d.ts +40 -0
  34. package/dist/ui/page-state-at-end.d.ts.map +1 -0
  35. package/dist/ui/{newest-page-state.js → page-state-at-end.js} +30 -31
  36. package/dist/ui/page-state-at-end.js.map +1 -0
  37. package/package.json +2 -2
  38. package/dist/prompt/user-text.d.ts +0 -19
  39. package/dist/prompt/user-text.d.ts.map +0 -1
  40. package/dist/prompt/user-text.js +0 -20
  41. package/dist/prompt/user-text.js.map +0 -1
  42. package/dist/ui/newest-page-state.d.ts +0 -25
  43. package/dist/ui/newest-page-state.d.ts.map +0 -1
  44. package/dist/ui/newest-page-state.js.map +0 -1
package/README.md CHANGED
@@ -17,7 +17,7 @@ A missing value fails when the adapter is created, and the error names it. Nothi
17
17
 
18
18
  Optional tuning, with its defaults:
19
19
  - `maxRounds`: 12
20
- - `maxTokens`: 4096
20
+ - `maxTokens`: 32,000 per model response, thinking included. A step cut off there before it says or calls anything runs once more, told to plan less; if that is cut off too, the person is told and the turn ends with `stopReason: 'output_limit'`.
21
21
  - `temperature`: 0.3
22
22
  - `toolTimeoutMs`: 30 s
23
23
  - `turnDeadlineMs`: 14 min (keep it below your host's own limit)
package/dist/index.d.ts CHANGED
@@ -62,7 +62,7 @@ export type { HttpEmitAdapterConfig } from './emit/http-adapter.js';
62
62
  export { createAgentTurnRunner, categorizeError, payloadRefusal, TURN_DEADLINE_EXCEEDED } from './runtime/turn-runner.js';
63
63
  export type { AgentTurnRunner, TurnOutcome, CategorizedError } from './runtime/turn-runner.js';
64
64
  export { assertAgentRuntimeConfig } from './runtime/config.js';
65
- export type { AgentRuntimeConfig, LambdaAgentConfig, AgentTurnPayload, HistoryRequest } from './runtime/types.js';
65
+ export type { AgentRuntimeConfig, LambdaAgentConfig, AgentTurnPayload, HistoryRequest, TurnHistory } from './runtime/types.js';
66
66
  export { createLambdaAgentHandler } from './lambda/handler.js';
67
67
  export { startContainerAgentWorker } from './container/server.js';
68
68
  export type { ContainerAgentConfig, ContainerAgentWorker } from './container/server.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAmC,MAAM,YAAY,CAAC;AAkFtH;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,eAAe,CAAC,CA4uD1B"}
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAmC,MAAM,YAAY,CAAC;AAqGtH;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,iBAAiB,EACzB,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,eAAe,CAAC,CAu1D1B"}
@@ -28,10 +28,10 @@ import { evaluateToolPolicySafe } from './authz/tool-policy.js';
28
28
  import { createToolInputValidator } from './tools/input-validation.js';
29
29
  import { readClientPage, withoutClientUI } from './ui/snapshot.js';
30
30
  import { KNOWLEDGE_TOOL, knowledgeTool, readClientKnowledge, withClientKnowledge } from './ui/knowledge.js';
31
- import { withNewestPageStateOnly } from './ui/newest-page-state.js';
32
- import { withClock } from './prompt/clock.js';
33
- import { withSpokenInput } from './prompt/spoken-input.js';
34
- import { withUserText } from './prompt/user-text.js';
31
+ import { answerWithoutState, withStatesAtEnd } from './ui/page-state-at-end.js';
32
+ import { stepMessages as forStep, STEP_NOTE_CLOSE, STEP_NOTE_OPEN } from './step-messages.js';
33
+ import { clockText, readClientTimeZone } from './prompt/clock.js';
34
+ import { readClientMessageInput, spokenInputText } from './prompt/spoken-input.js';
35
35
  import { AttachmentGuard } from './attachments/guard.js';
36
36
  import { ATTACHMENT_DATA_NOTE, turnAttachmentParts, withReferenceLines, withTurnAttachments, withoutLeftOut } from './attachments/content.js';
37
37
  import { attachmentTools } from './attachments/tools.js';
@@ -47,7 +47,24 @@ import { approvalRequirement, APPROVAL_TOOL_NOTE } from './approvals/requirement
47
47
  import { buildApprovalPreview, declaredTitle } from './approvals/preview.js';
48
48
  import { approvalMarker, approvedExpiredMarker, expiredNote, markedResult, notRunResult, ranNote, refusedNote, resolveContinuation, unavailableNote, waitingCalls, withdrawnMarker, } from './approvals/continuation.js';
49
49
  const DEFAULT_MAX_ROUNDS = 12;
50
- const DEFAULT_MAX_TOKENS = 4096;
50
+ /**
51
+ * The most one step may write. A model that thinks before it answers (Claude
52
+ * Sonnet 5.5 does unless told not to) spends its thinking from this budget
53
+ * before it says or calls anything. At 4,096, a request that needed planning
54
+ * (a five-part animation, dev, 2026-10-08) used all of it thinking, twice, and
55
+ * the turn ended having said and done nothing.
56
+ */
57
+ const DEFAULT_MAX_TOKENS = 32_000;
58
+ /**
59
+ * How many times a step cut off at the output limit, having said and called
60
+ * nothing, is run again. Its output is discarded, and the step that replaces it
61
+ * is told to plan less before it acts.
62
+ */
63
+ const OUTPUT_LIMIT_RETRIES = 1;
64
+ /** What a step cut off at the output limit, having said and called nothing, is told when it runs again. */
65
+ const OUTPUT_LIMIT_NOTE = 'Your last attempt at this step reached the output limit while you were still working out what to do, before you said or called anything, so it was discarded. Plan less before acting: say in one sentence what you will do first, make those calls, and take the rest in later steps.';
66
+ /** What the person is told when every attempt at a step was cut off that way. */
67
+ const OUTPUT_LIMIT_REPLY = 'I ran out of room while working out how to do this, before I could start, so nothing was changed. Could you ask for it one part at a time?';
51
68
  const DEFAULT_TEMPERATURE = 0.3;
52
69
  const DEFAULT_TOOL_TIMEOUT_MS = 30_000;
53
70
  const DEFAULT_UI_RESULT_TIMEOUT_MS = 20_000;
@@ -122,8 +139,8 @@ export async function runAgentTurn(config, input) {
122
139
  // Whether the page can be seen (ADR-0245 §2.5): nothing that changes it runs while it cannot.
123
140
  const sight = createPageSight();
124
141
  const uiCounts = { describes: 0, reads: 0, acts: 0, guides: 0 };
125
- // Earlier answers' page states replaced, summed over the turn's steps.
126
- let pageStatesNotRepeated = 0;
142
+ // Answers whose page state was moved to the end of what the model reads, summed over the turn's steps.
143
+ let pageStatesMoved = 0;
127
144
  // The knowledge the client sent for its page goes after the host's prompt.
128
145
  const knowledge = readClientKnowledge(input.context ?? null);
129
146
  // ─── Files (ADR-0252 §2.11, §2.12) ─────────────────────────────────────────
@@ -1076,11 +1093,18 @@ export async function runAgentTurn(config, input) {
1076
1093
  // The system prompt has to travel as a message rather than the top-level
1077
1094
  // `system` field, because only a message carries `providerOptions`.
1078
1095
  //
1079
- // Two breakpoints, both on content that is append-only:
1096
+ // Three breakpoints, each on content that is append-only:
1080
1097
  // 1. system (+ tools) — identical for every round of a segment, and for
1081
1098
  // every turn on the same page.
1082
1099
  // 2. the end of the incoming history — stable across the rounds that follow
1083
1100
  // it, since a round appends rather than rewrites.
1101
+ // 3. the end of the conversation as each step sends it, moved forward every
1102
+ // step, so the next step reads this one's calls and answers from the
1103
+ // cache. With only the first two, everything after the user's message
1104
+ // went uncached at every step: on dev a turn's UI answers (up to tens of
1105
+ // thousands of tokens each) were paid in full again on every later step.
1106
+ // What a step alone is told (its notes) goes after the third, so it never
1107
+ // changes a prefix (step-messages.ts).
1084
1108
  //
1085
1109
  // Caching is a PREFIX match: one byte earlier in the prefix invalidates
1086
1110
  // everything after it. Nothing volatile may move ahead of these points — no
@@ -1169,27 +1193,25 @@ export async function runAgentTurn(config, input) {
1169
1193
  const stoppedBeforeModel = stopOf(abortController.signal);
1170
1194
  if (stoppedBeforeModel)
1171
1195
  return await finishStopped(stoppedBeforeModel, { expired, continued });
1172
- // Convert history to AI SDK CoreMessage format. The page the user is on
1173
- // travels with their message, not in the system prompt: it changes on every
1174
- // page, and in the system prompt it would invalidate the cached prefix. An
1175
- // approved call that ran is the result of the call the model made (see
1196
+ // Convert history to AI SDK CoreMessage format. Everything before the end
1197
+ // of the conversation is sent exactly as it was sent before, so the prompt
1198
+ // cache reads it (step-messages.ts). What is true only now — the page's
1199
+ // index and values, the user's clock, a note on calls whose approval
1200
+ // expired, the host's step context — is not added to the user's message,
1201
+ // where the next turn would send that message without it and write the
1202
+ // conversation from there to the cache again: the index goes after the
1203
+ // system prompt, the rest after the conversation (`stepTail`). An approved
1204
+ // call that ran is the result of the call the model made (see
1176
1205
  // continueApproval).
1177
- // The date and time on the user's clock travel with their message too: a
1178
- // model has no clock, and the changing minute must stay out of the cached
1179
- // system prompt (prompt/clock.ts).
1180
- // A message the person spoke says so straight after their words: it may hold a mis-heard word
1181
- // (prompt/spoken-input.ts). A click on an approval card is not a message, so it says nothing.
1182
1206
  const turnFilesGiven = !!fileArea && (input.attachments?.length ?? 0) > 0;
1183
1207
  const messages = [
1184
- ...withClock(withPageState(withNote(withSpokenInput(convertHistoryToCoreMessages(
1208
+ ...convertHistoryToCoreMessages(
1185
1209
  // An approved call's outcome, and an expired one's, is a later result of the call already in the
1186
1210
  // history: it takes that call's place.
1187
1211
  [...(input.history ?? []), ...expired.outcomes, ...(continued?.outcome ? [continued.outcome] : [])], [input.content, continued?.note].filter(Boolean).join('\n\n'),
1188
1212
  // The turn's own message, when the history already holds it: its files are given below,
1189
1213
  // each with its line, so the history's copy of the message does not name them again.
1190
- turnFilesGiven && input.history?.at(-1)?.role === 'user' ? input.history.length - 1 : null), input.approval ? null : (input.context ?? null)),
1191
- // Said on the user's message whether or not the host's history already holds that message.
1192
- expired.outcomes.length > 0 ? expiredNote(expired) : null), client, config.ui?.maxObservationChars ?? DEFAULT_PAGE_STATE_CHARS, config.ui?.maxIndexChars ?? DEFAULT_INDEX_CHARS), input.context ?? null),
1214
+ turnFilesGiven && input.history?.at(-1)?.role === 'user' ? input.history.length - 1 : null),
1193
1215
  ...(continued?.messages ?? []),
1194
1216
  ];
1195
1217
  // The turn's files go with its message, after everything said about it (ADR-0252 §2.11).
@@ -1231,11 +1253,69 @@ export async function runAgentTurn(config, input) {
1231
1253
  // `instructions` takes `string | SystemModelMessage | SystemModelMessage[]`,
1232
1254
  // and the message form carries `providerOptions`, so the breakpoint travels
1233
1255
  // with it. (`system` is the deprecated alias for the same type.)
1234
- const instructions = {
1256
+ const systemMessage = {
1235
1257
  role: 'system',
1236
1258
  content: systemPrompt,
1237
1259
  ...(cachePoint ? { providerOptions: cachePoint } : {}),
1238
1260
  };
1261
+ // What the page offers, after the system prompt with a breakpoint of its own:
1262
+ // it is the same for every step and every turn on the same page, so it is
1263
+ // read from the cache, and when the page changes only it and what follows are
1264
+ // written again. A change during the turn reaches the model in the answer
1265
+ // that made it (ui-tools.ts `forModel`).
1266
+ const pageIndex = client && client.page.length > 0
1267
+ ? {
1268
+ role: 'system',
1269
+ content: [
1270
+ '<page_index>',
1271
+ `The user's screen offers these surfaces and actions. Run an action with ${UI_ACT_TOOL}; ${UI_DESCRIBE_TOOL} says what one takes.`,
1272
+ indexText(client.page, config.ui?.maxIndexChars ?? DEFAULT_INDEX_CHARS),
1273
+ '</page_index>',
1274
+ ].join('\n'),
1275
+ ...(cachePoint ? { providerOptions: cachePoint } : {}),
1276
+ }
1277
+ : null;
1278
+ const instructions = pageIndex ? [systemMessage, pageIndex] : systemMessage;
1279
+ // ─── What is true now, after the conversation (step-messages.ts) ───────────
1280
+ // The turn's own message: answers after it are this turn's, and only those
1281
+ // are newer than the page the turn began on.
1282
+ const turnMessageAt = messages.map((m) => m.role).lastIndexOf('user');
1283
+ const turnClock = clockText(new Date(), readClientTimeZone(input.context ?? null));
1284
+ const turnSpoken = input.approval ? null : readClientMessageInput(input.context ?? null);
1285
+ const turnPageValues = client && client.page.length > 0
1286
+ ? [
1287
+ observationsText(client.observations, config.ui?.maxObservationChars ?? DEFAULT_PAGE_STATE_CHARS, {
1288
+ schemas: observationSchemas(client.page),
1289
+ }),
1290
+ client.fit?.observations?.length ? `Not shown: ${fitNotes(client.fit.observations).join(' ')}` : null,
1291
+ ]
1292
+ : null;
1293
+ /** The page's state from this turn's newest answer that carried one; until then, as the user's screen sent it. */
1294
+ let newestAnswerState;
1295
+ const stepTail = (notes) => [
1296
+ ...(turnPageValues
1297
+ ? [
1298
+ [
1299
+ '<page_state>',
1300
+ sight.blind()
1301
+ ? `Not current: an answer came without the page's state (${sight.blind()}). These values are from before it, so read the page before you change anything.`
1302
+ : newestAnswerState !== undefined
1303
+ ? 'The page as it is now, from the newest answer that carried its state.'
1304
+ : 'The page as it was when the user sent their message.',
1305
+ `Current values: ${newestAnswerState !== undefined ? JSON.stringify(newestAnswerState) : turnPageValues[0]}`,
1306
+ ...(newestAnswerState === undefined && turnPageValues[1] ? [turnPageValues[1]] : []),
1307
+ '</page_state>',
1308
+ ].join('\n'),
1309
+ ]
1310
+ : []),
1311
+ turnClock,
1312
+ // A message the person spoke may hold a mis-heard word (prompt/spoken-input.ts). A click on an
1313
+ // approval card is not a message, so it says nothing.
1314
+ ...(turnSpoken ? [spokenInputText(turnSpoken)] : []),
1315
+ ...(expired.outcomes.length > 0 ? [expiredNote(expired)] : []),
1316
+ ...(input.stepContext?.trim() ? [input.stepContext.trim()] : []),
1317
+ ...(notes.length > 0 ? [[STEP_NOTE_OPEN, ...notes, STEP_NOTE_CLOSE].join('\n')] : []),
1318
+ ];
1239
1319
  const withCachePoint = (msgs) => !cachePoint ? msgs : [
1240
1320
  ...msgs.slice(0, -1),
1241
1321
  ...msgs.slice(-1).map((m) => ({
@@ -1248,6 +1328,10 @@ export async function runAgentTurn(config, input) {
1248
1328
  let segments = 0;
1249
1329
  let responseMessageCount = 0;
1250
1330
  const usageTotals = { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0 };
1331
+ // A step cut off at the output limit having said and called nothing (DEFAULT_MAX_TOKENS).
1332
+ let outputLimitRetries = 0;
1333
+ let outputLimitNote = null;
1334
+ let outputLimited = false;
1251
1335
  for (;;) {
1252
1336
  segments++;
1253
1337
  const aiTools = assembleTools();
@@ -1319,15 +1403,20 @@ export async function runAgentTurn(config, input) {
1319
1403
  }
1320
1404
  : {}),
1321
1405
  };
1322
- // The policy's note goes after the system prompt, for this step only.
1323
- // ai carries an instructions override forward to later steps, so a step
1324
- // without a note sets the plain instructions back.
1325
- // So does the turn's record, once a call has not succeeded.
1326
- const notes = [note, forced ? `This step: call ${UI_ACT_TOOL} with action "${forced}".` : null, ledger.note()].filter((n) => !!n);
1327
- // The page's state on the newest answer only: an earlier page is not the page now.
1328
- const trimmed = messages ? withNewestPageStateOnly(messages) : null;
1329
- if (trimmed)
1330
- pageStatesNotRepeated += trimmed.replaced;
1406
+ // The policy's note, the forced action and the turn's record (once a call
1407
+ // has not succeeded) are for this step only. They go at the end of what
1408
+ // the model reads, after the moving cache breakpoint, never in the system
1409
+ // prompt: a note there changed the prefix of the whole conversation, so
1410
+ // the step that carried one, and the step after it, wrote the conversation
1411
+ // to the cache again instead of reading it.
1412
+ const notes = [note, forced ? `This step: call ${UI_ACT_TOOL} with action "${forced}".` : null, ledger.note(), outputLimitNote].filter((n) => !!n);
1413
+ // Every answer gives its page state up the same way; the newest of this turn's is read at the end.
1414
+ const trimmed = messages ? withStatesAtEnd(messages, turnMessageAt) : null;
1415
+ if (trimmed) {
1416
+ pageStatesMoved += trimmed.moved;
1417
+ if (trimmed.newest !== undefined)
1418
+ newestAnswerState = trimmed.newest;
1419
+ }
1331
1420
  // The files this step would carry, within the turn's and the conversation's caps (ADR-0252 §2.11).
1332
1421
  const leftOutNow = fileGuard.beforeStep();
1333
1422
  if (leftOutNow.length > 0) {
@@ -1337,16 +1426,14 @@ export async function runAgentTurn(config, input) {
1337
1426
  });
1338
1427
  }
1339
1428
  const leftOut = fileGuard.leftOutParts();
1340
- const stepMessages = leftOut.length > 0 && messages ? withoutLeftOut(trimmed?.messages ?? messages, leftOut) : trimmed?.messages;
1429
+ const stepMessages = leftOut.length > 0 && messages ? withoutLeftOut(trimmed?.messages ?? messages, leftOut) : trimmed?.messages ?? messages;
1341
1430
  return {
1342
1431
  ...constraints,
1343
- ...(stepMessages ? { messages: stepMessages } : {}),
1344
- instructions: notes.length
1345
- ? [instructions, ...notes.map((content) => ({ role: 'system', content }))]
1346
- : instructions,
1432
+ ...(stepMessages ? { messages: forStep(stepMessages, stepTail(notes), cachePoint) } : {}),
1433
+ instructions,
1347
1434
  };
1348
1435
  },
1349
- onStepEnd: async ({ text, toolCalls, usage: stepUsage }) => {
1436
+ onStepEnd: async ({ text, toolCalls, usage: stepUsage, finishReason }) => {
1350
1437
  stepTextReported += text?.length ?? 0;
1351
1438
  if (text && (toolCalls?.length ?? 0) > 0)
1352
1439
  roundBreaks.push(stepTextReported);
@@ -1365,6 +1452,12 @@ export async function runAgentTurn(config, input) {
1365
1452
  textLength: text?.length ?? 0,
1366
1453
  toolCallCount: toolCalls?.length ?? 0,
1367
1454
  totalTextEmitted,
1455
+ finishReason,
1456
+ outputTokens: stepUsage?.outputTokens ?? 0,
1457
+ // How this step's input was billed: read from the cache, written to it, or neither.
1458
+ inputTokens: stepUsage?.inputTokens ?? 0,
1459
+ cacheReadTokens: stepUsage?.inputTokenDetails?.cacheReadTokens ?? 0,
1460
+ cacheWriteTokens: stepUsage?.inputTokenDetails?.cacheWriteTokens ?? 0,
1368
1461
  });
1369
1462
  },
1370
1463
  });
@@ -1408,8 +1501,33 @@ export async function runAgentTurn(config, input) {
1408
1501
  usageTotals.outputTokens += segmentUsage?.outputTokens ?? 0;
1409
1502
  usageTotals.cacheReadTokens += segmentUsage?.inputTokenDetails?.cacheReadTokens ?? 0;
1410
1503
  usageTotals.cacheWriteTokens += segmentUsage?.inputTokenDetails?.cacheWriteTokens ?? 0;
1411
- responseMessageCount += response.messages.length;
1412
- conversation = [...conversation, ...response.messages];
1504
+ // A step cut off at the output limit before it said or called anything
1505
+ // ends the stream as if the turn were done. Its output (thinking, at most)
1506
+ // is discarded: each step's messages are its own, so the conversation
1507
+ // takes the segment's earlier steps only. It runs again, told to plan
1508
+ // less, in a new segment; if that is cut off too, the person is told.
1509
+ const last = steps.at(-1);
1510
+ const cutOff = last?.finishReason === 'length' && !last.text && (last.toolCalls?.length ?? 0) === 0;
1511
+ const kept = cutOff ? steps.slice(0, -1).flatMap((step) => step.response.messages) : response.messages;
1512
+ responseMessageCount += kept.length;
1513
+ conversation = [...conversation, ...kept];
1514
+ if (cutOff) {
1515
+ const retry = outputLimitRetries < OUTPUT_LIMIT_RETRIES && allSteps.length < maxRounds;
1516
+ log('warn', 'agent:llm', 'Step cut off at the output limit before it said or did anything', {
1517
+ turnId,
1518
+ segment: segments,
1519
+ maxTokens,
1520
+ outputTokens: last.usage?.outputTokens ?? 0,
1521
+ reasoningTokens: last.usage?.outputTokenDetails?.reasoningTokens ?? 0,
1522
+ retry,
1523
+ });
1524
+ if (retry) {
1525
+ outputLimitRetries++;
1526
+ outputLimitNote = OUTPUT_LIMIT_NOTE;
1527
+ continue;
1528
+ }
1529
+ outputLimited = true;
1530
+ }
1413
1531
  }
1414
1532
  catch (err) {
1415
1533
  if (!stopOf(abortController.signal))
@@ -1419,6 +1537,14 @@ export async function runAgentTurn(config, input) {
1419
1537
  // the page offers reaches it in each answer, so the turn runs as one segment.
1420
1538
  break;
1421
1539
  }
1540
+ // Every attempt was cut off: the person hears so, rather than nothing.
1541
+ if (outputLimited && !stopOf(abortController.signal)) {
1542
+ const reply = (streamedText ? ROUND_BREAK : '') + OUTPUT_LIMIT_REPLY;
1543
+ roundBreaks.length = 0;
1544
+ streamedText += reply;
1545
+ tokenBuffer += reply;
1546
+ await flushTokenBuffer();
1547
+ }
1422
1548
  // ─── Stopped, or ending ────────────────────────────────────────────────────
1423
1549
  // Decided here with nothing awaited in between: either the stop was heard
1424
1550
  // before this point and the turn takes its stop path, or the turn has begun
@@ -1436,6 +1562,9 @@ export async function runAgentTurn(config, input) {
1436
1562
  if (approvalHold) {
1437
1563
  stopReason = 'awaiting_approval';
1438
1564
  }
1565
+ else if (outputLimited) {
1566
+ stopReason = 'output_limit';
1567
+ }
1439
1568
  else if (steps.length >= maxRounds) {
1440
1569
  stopReason = 'step_count';
1441
1570
  }
@@ -1487,7 +1616,7 @@ export async function runAgentTurn(config, input) {
1487
1616
  // What bounds the model: the page's index as it reads it, against the most it is given
1488
1617
  // before the furthest surfaces are listed by id only.
1489
1618
  indexChars: indexText(client.page, Infinity).length,
1490
- pageStatesNotRepeated,
1619
+ pageStatesMoved,
1491
1620
  maxIndexChars: config.ui?.maxIndexChars ?? DEFAULT_INDEX_CHARS,
1492
1621
  },
1493
1622
  }
@@ -1495,7 +1624,11 @@ export async function runAgentTurn(config, input) {
1495
1624
  ...(fileArea ? { attachments: fileGuard.usage() } : {}),
1496
1625
  });
1497
1626
  // The turn's messages, in the host's format, for it to store.
1498
- const newMessages = [...expired.persisted, ...(continued?.persisted ?? []), ...convertResponseToTurnMessages({ steps }, executedToolResults)];
1627
+ const newMessages = [
1628
+ ...expired.persisted,
1629
+ ...(continued?.persisted ?? []),
1630
+ ...convertResponseToTurnMessages({ steps: outputLimited ? [...steps, { text: OUTPUT_LIMIT_REPLY, toolCalls: [] }] : steps }, executedToolResults),
1631
+ ];
1499
1632
  // The host stores the turn before the client hears it is complete: a message sent the moment
1500
1633
  // it completes must be answered from a history that holds this turn.
1501
1634
  if (config.beforeTurnComplete) {
@@ -1699,37 +1832,6 @@ export async function runAgentTurn(config, input) {
1699
1832
  };
1700
1833
  }
1701
1834
  }
1702
- /** Put a note for the model on the turn's user message, after what the user said. */
1703
- function withNote(messages, note) {
1704
- const last = messages[messages.length - 1];
1705
- if (!note || !last || last.role !== 'user')
1706
- return messages;
1707
- return [...messages.slice(0, -1), withUserText(last, note)];
1708
- }
1709
- /**
1710
- * Put the client's page on the user's message: what it offers, as an index of
1711
- * its actions, and its latest observations. The model reads it as part of what
1712
- * the user said, where it is true for this message only. The index has its own
1713
- * budget, so it never crowds the page's state out (ADR-0245 §2.2).
1714
- */
1715
- function withPageState(messages, client, maxChars, maxIndexChars) {
1716
- if (!client || client.page.length === 0)
1717
- return messages;
1718
- const last = messages[messages.length - 1];
1719
- if (!last || last.role !== 'user')
1720
- return messages;
1721
- const observations = observationsText(client.observations, maxChars, { schemas: observationSchemas(client.page) });
1722
- const notShown = client.fit?.observations?.length ? fitNotes(client.fit.observations) : [];
1723
- const pageState = [
1724
- '<page_state>',
1725
- `The user's screen offers these surfaces and actions. Run an action with ${UI_ACT_TOOL}; ${UI_DESCRIBE_TOOL} says what one takes.`,
1726
- indexText(client.page, maxIndexChars),
1727
- `Current values: ${observations}`,
1728
- ...(notShown.length ? [`Not shown: ${notShown.join(' ')}`] : []),
1729
- '</page_state>',
1730
- ].join('\n');
1731
- return [...messages.slice(0, -1), withUserText(last, pageState)];
1732
- }
1733
1835
  /**
1734
1836
  * Convert our TurnHistoryMessage[] to AI SDK CoreMessage[].
1735
1837
  * The AI SDK handles each provider's message format internally.
@@ -1946,7 +2048,8 @@ function convertResponseToTurnMessages(result, executedToolResults) {
1946
2048
  const tracked = executedToolResults[resultIdx++];
1947
2049
  turnMessages.push({
1948
2050
  role: 'tool',
1949
- content: tracked.result,
2051
+ // Stored as the model is sent it, so the history sends it the same way every turn.
2052
+ content: answerWithoutState(tracked.result),
1950
2053
  toolCallId: tracked.toolCallId,
1951
2054
  name: tracked.toolName,
1952
2055
  });