@poe-platform/safe-bash 0.1.759 → 0.1.760

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 (32) hide show
  1. package/dist/image-ast/index.browser.js +26 -11
  2. package/dist/image-ast/index.js +26 -11
  3. package/dist/pdf-ast/ast.d.ts +8 -3
  4. package/dist/pdf-ast/index.js +30 -14
  5. package/dist/safe-bash/chunks/{chunk-AYPUGSOV.js → chunk-CRQDMBQA.js} +123 -8
  6. package/dist/safe-bash/command-chunks/{chunk-HVEAK3OS.js → chunk-MC4XXPQJ.js} +2 -2
  7. package/dist/safe-bash/command-chunks/{chunk-BAUGDXLZ.js → chunk-S3SCPBHC.js} +26 -11
  8. package/dist/safe-bash/command-chunks/{chunk-7JA44PVV.js → chunk-UCI6ZQFB.js} +1 -1
  9. package/dist/safe-bash/commands/python/index.browser.js +1 -1
  10. package/dist/safe-bash/commands/python/index.d.ts +1 -1
  11. package/dist/safe-bash/commands/python/llm-capability.d.ts +7 -3
  12. package/dist/safe-bash/commands/python/llm-capability.js +149 -10
  13. package/dist/safe-bash/core.browser.js +1 -1
  14. package/dist/safe-bash-command-ffmpeg/index.js +2929 -2921
  15. package/dist/safe-bash-command-gh/index.js +128 -27
  16. package/dist/safe-bash-command-imagemagick/index.js +2 -2
  17. package/dist/safe-bash-command-pandoc/command.js +3 -3
  18. package/dist/safe-bash-command-pandoc/index.js +3 -3
  19. package/dist/safe-bash-command-pdfimages/index.js +26 -11
  20. package/dist/safe-bash-command-pdfinfo/index.js +30 -14
  21. package/dist/safe-bash-command-pdftk/index.js +26 -11
  22. package/dist/safe-bash-command-pdftoppm/index.js +30 -14
  23. package/dist/safe-bash-command-pdftotext/index.js +26 -11
  24. package/dist/safe-bash-command-qpdf/index.js +26 -11
  25. package/dist/safe-bash-command-sips/index.js +2 -2
  26. package/dist/safe-bash-command-soffice/index.js +1 -1
  27. package/dist/safe-bash-command-ssconvert/index.js +26 -11
  28. package/dist/safe-bash-command-wkhtmltopdf/index.js +26 -11
  29. package/dist/safe-bash-io-engine/internal.d.ts +2 -2
  30. package/dist/safe-bash-mcp/index.d.ts +1 -1
  31. package/package.json +2 -2
  32. package/third-party/pdf-ast/THIRD_PARTY_NOTICES.md +8 -0
@@ -1,8 +1,12 @@
1
1
  import type { CommandContext } from '../../contracts/index.js';
2
2
  import type { LlmService } from '../llm/service.js';
3
3
  import type { PythonHostCapability } from './host-capabilities.js';
4
- /** Reuses the invocation's authorized service; Python receives only model data. */
5
- export declare function createPythonLlmCapability(context: Pick<CommandContext, 'fs' | 'cwd' | 'inputBudget'>, service: LlmService, options?: {
4
+ export interface PythonLlmCapabilityOptions {
6
5
  readonly maxStreamChunkBytes?: number;
7
- }): PythonHostCapability;
6
+ readonly maxBufferedResponseBytes?: number;
7
+ readonly maxBufferedEvents?: number;
8
+ readonly maxMetadataBytes?: number;
9
+ }
10
+ /** Reuses the invocation's authorized service; Python receives only model data. */
11
+ export declare function createPythonLlmCapability(context: Pick<CommandContext, 'fs' | 'cwd' | 'inputBudget'>, service: LlmService, options?: PythonLlmCapabilityOptions): PythonHostCapability;
8
12
  //# sourceMappingURL=llm-capability.d.ts.map
@@ -5,11 +5,112 @@ function record(value) {
5
5
  throw new TypeError('Expected a structured Python LLM request');
6
6
  return value;
7
7
  }
8
+ /** Count the wire representation before retaining/serializing host metadata. */
9
+ function jsonBytes(value, limit) {
10
+ if (limit === Infinity)
11
+ return 0;
12
+ let bytes = 0;
13
+ const ancestors = new Set();
14
+ const add = (size) => {
15
+ if (size > limit - bytes)
16
+ throw new RangeError('Python LLM serialized response limit exceeded');
17
+ bytes += size;
18
+ };
19
+ const string = (text) => {
20
+ add(2);
21
+ if (text.length > limit - bytes)
22
+ throw new RangeError('Python LLM serialized response limit exceeded');
23
+ for (let i = 0; i < text.length; i++) {
24
+ const point = text.codePointAt(i);
25
+ if (point > 65535) {
26
+ add(4);
27
+ i++;
28
+ }
29
+ else if (point === 34 || point === 92)
30
+ add(2);
31
+ else if (point < 32)
32
+ add([8, 9, 10, 12, 13].includes(point) ? 2 : 6);
33
+ else if (point >= 0xd800 && point <= 0xdfff)
34
+ add(6);
35
+ else
36
+ add(point < 128 ? 1 : point < 2048 ? 2 : 3);
37
+ }
38
+ };
39
+ const visit = (item) => {
40
+ if (typeof item === 'string') {
41
+ string(item);
42
+ return;
43
+ }
44
+ if (item === null || typeof item === 'boolean' || typeof item === 'number' && Number.isFinite(item)) {
45
+ add(JSON.stringify(item).length);
46
+ return;
47
+ }
48
+ if (!item || typeof item !== 'object' || ancestors.has(item))
49
+ throw new TypeError('Python LLM response must contain acyclic data');
50
+ ancestors.add(item);
51
+ add(2);
52
+ let entries = 0;
53
+ if (Array.isArray(item)) {
54
+ if (item.length > limit - bytes)
55
+ throw new RangeError('Python LLM serialized response limit exceeded');
56
+ for (let i = 0; i < item.length; i++) {
57
+ const descriptor = Object.getOwnPropertyDescriptor(item, String(i));
58
+ if (!descriptor || !('value' in descriptor))
59
+ throw new TypeError('Python LLM response must contain data');
60
+ if (entries++)
61
+ add(1);
62
+ visit(descriptor.value);
63
+ }
64
+ }
65
+ else {
66
+ for (const key in item) {
67
+ if (!Object.hasOwn(item, key))
68
+ continue;
69
+ const descriptor = Object.getOwnPropertyDescriptor(item, key);
70
+ if (!('value' in descriptor))
71
+ throw new TypeError('Python LLM response must contain data');
72
+ if (entries++)
73
+ add(1);
74
+ string(key);
75
+ add(1);
76
+ visit(descriptor.value);
77
+ }
78
+ }
79
+ ancestors.delete(item);
80
+ };
81
+ visit(value);
82
+ return bytes;
83
+ }
84
+ function* textFragments(text, limit) {
85
+ let start = 0, bytes = 0;
86
+ for (let i = 0; i < text.length;) {
87
+ const point = text.codePointAt(i);
88
+ const width = point < 128 ? 1 : point < 2048 ? 2 : point < 65536 ? 3 : 4;
89
+ if (width > limit)
90
+ throw new RangeError('Python LLM stream chunk limit cannot fit a Unicode scalar');
91
+ if (width > limit - bytes) {
92
+ yield text.slice(start, i);
93
+ start = i;
94
+ bytes = 0;
95
+ }
96
+ bytes += width;
97
+ i += point > 65535 ? 2 : 1;
98
+ }
99
+ if (start < text.length || !text.length)
100
+ yield text.slice(start);
101
+ }
8
102
  /** Reuses the invocation's authorized service; Python receives only model data. */
9
103
  export function createPythonLlmCapability(context, service, options = {}) {
10
104
  const chunkBytes = options.maxStreamChunkBytes ?? 16384;
11
105
  if (!Number.isSafeInteger(chunkBytes) || chunkBytes < 1)
12
106
  throw new RangeError('Invalid Python LLM stream chunk limit');
107
+ const bufferedLimit = options.maxBufferedResponseBytes ?? Infinity;
108
+ const eventLimit = options.maxBufferedEvents ?? bufferedLimit;
109
+ const metadataLimit = options.maxMetadataBytes ?? bufferedLimit;
110
+ for (const limit of [bufferedLimit, eventLimit, metadataLimit]) {
111
+ if (limit !== Infinity && (!Number.isSafeInteger(limit) || limit < 1))
112
+ throw new RangeError('Invalid Python LLM host limit');
113
+ }
13
114
  const prepare = async (value, signal) => {
14
115
  const payload = record(value);
15
116
  for (const key of ['template', 'conversation']) {
@@ -73,8 +174,16 @@ export function createPythonLlmCapability(context, service, options = {}) {
73
174
  yield { type: 'bytes', data: Array.from(event.data.subarray(offset, offset + chunkBytes)) };
74
175
  }
75
176
  }
76
- else
177
+ else if (event.type === 'text') {
178
+ for (const text of textFragments(event.text, chunkBytes)) {
179
+ request.signal.throwIfAborted();
180
+ yield { type: 'text', text };
181
+ }
182
+ }
183
+ else {
184
+ jsonBytes(event.response, metadataLimit);
77
185
  yield event;
186
+ }
78
187
  }
79
188
  };
80
189
  return {
@@ -93,19 +202,49 @@ export function createPythonLlmCapability(context, service, options = {}) {
93
202
  }
94
203
  if (operation.operation !== 'complete')
95
204
  throw new TypeError('Unsupported Python LLM operation');
96
- const text = [], data = [];
205
+ const request = await prepare(payload, signal);
206
+ const bounded = { ...request, maxOutputBytes: Math.min(request.maxOutputBytes ?? Infinity, bufferedLimit) };
207
+ let text = '', textBytes = 0, dataBytes = 0, received = 0;
208
+ const data = [];
97
209
  let response = {};
98
- for await (const value of events(payload, { signal })) {
99
- const event = record(value);
100
- if (event.type === 'text')
101
- text.push(event.text);
102
- else if (event.type === 'bytes')
210
+ let envelopeBytes = jsonBytes({ text: '', data: [] }, bufferedLimit);
211
+ const admit = (size) => {
212
+ if (size > bufferedLimit - envelopeBytes - textBytes - dataBytes)
213
+ throw new RangeError('Python LLM buffered response limit exceeded');
214
+ };
215
+ for await (const event of service.stream(bounded)) {
216
+ bounded.signal.throwIfAborted();
217
+ if (++received > eventLimit)
218
+ throw new RangeError('Python LLM buffered event limit exceeded');
219
+ if (event.type === 'text') {
220
+ const size = bufferedLimit === Infinity || !event.text ? 0 : jsonBytes(event.text, bufferedLimit - envelopeBytes - textBytes - dataBytes + 2) - 2;
221
+ admit(size);
222
+ textBytes += size;
223
+ if (event.text)
224
+ text += event.text;
225
+ }
226
+ else if (event.type === 'bytes') {
227
+ let size = 0;
228
+ if (bufferedLimit !== Infinity)
229
+ for (let i = 0; i < event.data.length; i++) {
230
+ size += String(event.data[i]).length + (data.length || i ? 1 : 0);
231
+ admit(size);
232
+ }
233
+ dataBytes += size;
103
234
  for (const byte of event.data)
104
235
  data.push(byte);
105
- else if (event.type === 'response')
106
- response = { ...record(event.response) };
236
+ }
237
+ else {
238
+ jsonBytes(event.response, metadataLimit);
239
+ const details = record(event.response);
240
+ const size = jsonBytes({ ...details, text: '', data: [] }, bufferedLimit);
241
+ if (size > bufferedLimit - textBytes - dataBytes)
242
+ throw new RangeError('Python LLM buffered response limit exceeded');
243
+ envelopeBytes = size;
244
+ response = { ...details };
245
+ }
107
246
  }
108
- return { ...response, text: text.join(''), data };
247
+ return { ...response, text, data };
109
248
  },
110
249
  stream: events,
111
250
  };
@@ -158,7 +158,7 @@ import {
158
158
  sha256,
159
159
  sha384,
160
160
  sha512
161
- } from "./chunks/chunk-AYPUGSOV.js";
161
+ } from "./chunks/chunk-CRQDMBQA.js";
162
162
  import {
163
163
  PythonFailure,
164
164
  inspectPythonCapabilities