poe-code 3.0.429-beta.1 → 3.0.429

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poe-code",
3
- "version": "3.0.429-beta.1",
3
+ "version": "3.0.429",
4
4
  "description": "CLI tool to configure Poe API for developer workflows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -44,7 +44,7 @@ const MATCHERS = [
44
44
  matches: () => true
45
45
  }
46
46
  ];
47
- const TURNS_PER_YIELD = 256;
47
+ const TURNS_PER_YIELD = 64;
48
48
  const ESTIMATOR_SAMPLE_TARGET_CHARS = 16_384;
49
49
  const ESTIMATOR_SAMPLE_CHARS_PER_TURN = 1_024;
50
50
  const ESTIMATOR_DEFAULT_CHARS_PER_TOKEN = 4;
@@ -41,6 +41,7 @@ export async function loadTrace(reference, options) {
41
41
  };
42
42
  }
43
43
  const exactBreakdownsInFlight = new Map();
44
+ const EXACT_BREAKDOWN_START_DELAY_MS = 1_000;
44
45
  async function loadBreakdown(trace, filePath, identity, options) {
45
46
  const cacheDir = options.cacheDir ?? defaultTraceTokenCacheDir();
46
47
  if (filePath !== undefined && identity !== undefined) {
@@ -67,6 +68,7 @@ function scheduleExactBreakdown(trace, filePath, identity, cacheDir, options) {
67
68
  return;
68
69
  }
69
70
  const task = (async () => {
71
+ await new Promise((resolve) => setTimeout(resolve, EXACT_BREAKDOWN_START_DELAY_MS));
70
72
  const breakdown = await computeContextBreakdown(trace);
71
73
  await writeCachedBreakdown(options.fs, cacheDir, filePath, identity, breakdown);
72
74
  options.onExactBreakdown?.(breakdown);
@@ -8,6 +8,8 @@ const MAX_TRACE_META_CWD_WIDTH = 18;
8
8
  const MAX_SUBAGENT_AGENT_WIDTH = 13;
9
9
  const MAX_SUBAGENT_DESCRIPTION_WIDTH = 26;
10
10
  const COLLAPSED_TURN_LINES = 3;
11
+ const COLLAPSED_TURN_MAX_CHARS = (MAX_RENDER_WIDTH + 1) * COLLAPSED_TURN_LINES;
12
+ const MAX_MARKDOWN_TURN_CHARS = 65_536;
11
13
  const TURNS_PER_RENDER_YIELD = 256;
12
14
  const CATEGORY_ORDER = [
13
15
  "system-prompt",
@@ -251,15 +253,20 @@ function renderTurn(turn, theme) {
251
253
  const shouldCollapse = turn.role === "tool" || turn.role === "system";
252
254
  let sourceText = turn.text;
253
255
  let collapsedLines = 0;
256
+ let truncatedWithinLine = false;
254
257
  if (shouldCollapse) {
255
258
  const cut = lineEndIndex(sourceText, COLLAPSED_TURN_LINES);
256
259
  if (cut !== -1) {
257
260
  collapsedLines = countNewlines(sourceText, cut);
258
261
  sourceText = sourceText.slice(0, cut);
259
262
  }
263
+ if (sourceText.length > COLLAPSED_TURN_MAX_CHARS) {
264
+ sourceText = sourceText.slice(0, COLLAPSED_TURN_MAX_CHARS);
265
+ truncatedWithinLine = true;
266
+ }
260
267
  }
261
268
  const sanitizedText = sanitizeTraceText(sourceText);
262
- const text = turn.role === "assistant"
269
+ const text = turn.role === "assistant" && sanitizedText.length <= MAX_MARKDOWN_TURN_CHARS
263
270
  ? stripAnsi(renderMarkdown(sanitizedText)).trimEnd()
264
271
  : sanitizedText.trimEnd();
265
272
  const rawLines = text.length === 0 ? [""] : text.split("\n");
@@ -276,9 +283,16 @@ function renderTurn(turn, theme) {
276
283
  lines.push(`${linePrefix}${wrappedLine}`);
277
284
  });
278
285
  });
286
+ if (shouldCollapse && lines.length > COLLAPSED_TURN_LINES) {
287
+ lines.length = COLLAPSED_TURN_LINES;
288
+ truncatedWithinLine = true;
289
+ }
279
290
  if (remaining > 0) {
280
291
  lines[lines.length - 1] = `${lines[lines.length - 1]} ${theme.muted(`… +${remaining} lines`)}`;
281
292
  }
293
+ else if (truncatedWithinLine) {
294
+ lines[lines.length - 1] = `${lines[lines.length - 1]} ${theme.muted("…")}`;
295
+ }
282
296
  return lines;
283
297
  }
284
298
  function sortCategories(categories) {
@@ -42,6 +42,8 @@ const HELP_TEXT = [
42
42
  " --session-ttl-ms <ms> Expire sessions after this idle duration",
43
43
  " --max-streams-per-session <count>",
44
44
  " Maximum concurrent GET SSE streams per session",
45
+ " --max-stream-buffer-bytes <bytes>",
46
+ " Maximum buffered bytes per GET SSE stream (default: 1048576)",
45
47
  " --max-sse-event-history <count>",
46
48
  " Number of SSE events retained for Last-Event-ID replay",
47
49
  " --sse-keep-alive-ms <ms>",
@@ -196,6 +198,7 @@ function parseCliOptions(args) {
196
198
  "max-sessions": { type: "string" },
197
199
  "session-ttl-ms": { type: "string" },
198
200
  "max-streams-per-session": { type: "string" },
201
+ "max-stream-buffer-bytes": { type: "string" },
199
202
  "max-sse-event-history": { type: "string" },
200
203
  "sse-keep-alive-ms": { type: "string" },
201
204
  "max-concurrent-tool-calls": { type: "string" },
@@ -218,6 +221,7 @@ function parseCliOptions(args) {
218
221
  const maxSessions = parseOptionalInteger(values["max-sessions"], "--max-sessions", 1);
219
222
  const sessionTtlMs = parseOptionalInteger(values["session-ttl-ms"], "--session-ttl-ms", 1);
220
223
  const maxStreamsPerSession = parseOptionalInteger(values["max-streams-per-session"], "--max-streams-per-session", 1);
224
+ const maxStreamBufferBytes = parseOptionalInteger(values["max-stream-buffer-bytes"], "--max-stream-buffer-bytes", 0);
221
225
  const maxSseEventHistory = parseOptionalInteger(values["max-sse-event-history"], "--max-sse-event-history", 0);
222
226
  const sseKeepAliveMs = parseOptionalInteger(values["sse-keep-alive-ms"], "--sse-keep-alive-ms", 0);
223
227
  const maxConcurrentToolCalls = parseOptionalInteger(values["max-concurrent-tool-calls"], "--max-concurrent-tool-calls", 1);
@@ -244,6 +248,7 @@ function parseCliOptions(args) {
244
248
  ...(maxSessions === undefined ? {} : { maxSessions }),
245
249
  ...(sessionTtlMs === undefined ? {} : { sessionTtlMs }),
246
250
  ...(maxStreamsPerSession === undefined ? {} : { maxStreamsPerSession }),
251
+ ...(maxStreamBufferBytes === undefined ? {} : { maxStreamBufferBytes }),
247
252
  ...(maxSseEventHistory === undefined ? {} : { maxSseEventHistory }),
248
253
  ...(sseKeepAliveMs === undefined ? {} : { sseKeepAliveMs }),
249
254
  ...(maxConcurrentToolCalls === undefined ? {} : { maxConcurrentToolCalls }),
@@ -327,6 +332,9 @@ export async function runCli(args = process.argv.slice(2), dependencies = {}) {
327
332
  ...(options.maxStreamsPerSession === undefined
328
333
  ? {}
329
334
  : { maxStreamsPerSession: options.maxStreamsPerSession }),
335
+ ...(options.maxStreamBufferBytes === undefined
336
+ ? {}
337
+ : { maxStreamBufferBytes: options.maxStreamBufferBytes }),
330
338
  ...(options.maxSseEventHistory === undefined
331
339
  ? {}
332
340
  : { maxSseEventHistory: options.maxSseEventHistory }),
@@ -67,6 +67,7 @@ export interface StreamableHttpTransportOptions {
67
67
  maxSessions?: number;
68
68
  sessionTtlMs?: number;
69
69
  maxStreamsPerSession?: number;
70
+ maxStreamBufferBytes?: number;
70
71
  maxSseEventHistory?: number;
71
72
  sseKeepAliveMs?: number;
72
73
  maxConcurrentToolCalls?: number;
@@ -88,6 +89,7 @@ export declare class StreamableHttpTransport {
88
89
  private readonly maxSessions;
89
90
  private readonly sessionTtlMs;
90
91
  private readonly maxStreamsPerSession;
92
+ private readonly maxStreamBufferBytes;
91
93
  private readonly maxSseEventHistory;
92
94
  private readonly sseKeepAliveMs;
93
95
  private readonly maxConcurrentToolCalls;
@@ -129,6 +131,7 @@ export declare class StreamableHttpTransport {
129
131
  private stopSseKeepAliveIfIdle;
130
132
  private stopSseKeepAlive;
131
133
  private sendNotificationToSession;
134
+ private writeToLiveGetStream;
132
135
  private recordSseEvent;
133
136
  private replaySseEvents;
134
137
  private isJsonRequest;
@@ -29,6 +29,7 @@ export class StreamableHttpTransport {
29
29
  maxSessions;
30
30
  sessionTtlMs;
31
31
  maxStreamsPerSession;
32
+ maxStreamBufferBytes;
32
33
  maxSseEventHistory;
33
34
  sseKeepAliveMs;
34
35
  maxConcurrentToolCalls;
@@ -60,6 +61,9 @@ export class StreamableHttpTransport {
60
61
  this.sessionTtlMs = validateOptionalIntegerOption("sessionTtlMs", options.sessionTtlMs, 1);
61
62
  this.maxStreamsPerSession =
62
63
  validateOptionalIntegerOption("maxStreamsPerSession", options.maxStreamsPerSession, 1) ?? 1;
64
+ this.maxStreamBufferBytes =
65
+ validateOptionalIntegerOption("maxStreamBufferBytes", options.maxStreamBufferBytes, 0) ??
66
+ 1024 * 1024;
63
67
  this.maxSseEventHistory =
64
68
  validateOptionalIntegerOption("maxSseEventHistory", options.maxSseEventHistory, 0) ?? 100;
65
69
  this.sseKeepAliveMs =
@@ -583,7 +587,7 @@ export class StreamableHttpTransport {
583
587
  for (const streams of this.sseStreams.values()) {
584
588
  for (const response of streams) {
585
589
  if (!response.writableEnded) {
586
- response.write(": keepalive\n\n");
590
+ this.writeToLiveGetStream(response, ": keepalive\n\n");
587
591
  }
588
592
  }
589
593
  }
@@ -624,7 +628,16 @@ export class StreamableHttpTransport {
624
628
  latestResponse = response;
625
629
  }
626
630
  }
627
- latestResponse?.write(event);
631
+ if (latestResponse !== undefined) {
632
+ this.writeToLiveGetStream(latestResponse, event);
633
+ }
634
+ }
635
+ writeToLiveGetStream(response, data) {
636
+ if ((response.writableLength ?? 0) > this.maxStreamBufferBytes) {
637
+ response.end();
638
+ return;
639
+ }
640
+ response.write(data);
628
641
  }
629
642
  recordSseEvent(sessionId, id, data) {
630
643
  if (this.maxSseEventHistory <= 0) {
@@ -7,8 +7,8 @@ const builtinBindings = {
7
7
  cursorDown: ["down", "j"],
8
8
  top: ["home", "gg"],
9
9
  bottom: ["end", "G"],
10
- pageUp: ["Ctrl+u"],
11
- pageDown: ["Ctrl+d"],
10
+ pageUp: ["pageup", "Ctrl+u"],
11
+ pageDown: ["pagedown", "Ctrl+d"],
12
12
  focusNext: ["tab"],
13
13
  escape: ["escape"],
14
14
  confirm: ["return", "enter"],
@@ -1,3 +1,4 @@
1
+ import { stripAnsi } from "../../internal/strip-ansi.js";
1
2
  import { getExplorerStyles } from "../theme.js";
2
3
  import { fitToWidth, padEndCells } from "./text.js";
3
4
  export function renderModal(state, screen) {
@@ -12,7 +13,7 @@ export function renderModal(state, screen) {
12
13
  drawBox(screen, x, y, width, height, title(state), styles.borderFocused);
13
14
  const lines = modalLines(state);
14
15
  for (let row = 0; row < Math.min(lines.length, height - 2); row += 1) {
15
- screen.put(x + 2, y + 1 + row, fitToWidth(lines[row], width - 4, x + 2), row === 1 ? styles.accent : {});
16
+ screen.put(x + 2, y + 1 + row, fitToWidth(stripAnsi(lines[row]), width - 4, x + 2), row === 1 ? styles.accent : {});
16
17
  }
17
18
  }
18
19
  function modalLines(state) {