@qoniai/qoni 0.4.2 → 0.4.3

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/CHANGELOG.md CHANGED
@@ -6,6 +6,16 @@ This project follows semantic versioning. Before `1.0.0`, minor versions may
6
6
  include SDK API changes, while patch versions are reserved for backward
7
7
  compatible fixes.
8
8
 
9
+ ## 0.4.3 - 2026-09-09
10
+
11
+ ### Fixed
12
+
13
+ - Treat malformed or empty screenshot data URIs as undecodable instead of
14
+ emitting invalid screenshot bytes or interrupting `wait()`. Preserve the
15
+ existing progress/raw fallback with screenshot capture enabled or disabled.
16
+ - Keep valid padded, unpadded, whitespace-containing and URL-safe base64
17
+ screenshots compatible.
18
+
9
19
  ## 0.4.2 - 2026-09-09
10
20
 
11
21
  ### Fixed
package/README.md CHANGED
@@ -161,6 +161,8 @@ console.log(result.output);
161
161
 
162
162
  `run()` returns a `RunHandle` typed to the product: `qoni.deepResearch.run()` is a `RunHandle<DeepResearchEvent>`, so its events are narrowed to what Deep Research actually emits. `capture: { screenshots: true }` opts into per-step screenshots, decoded to bytes for you. `wait()` drives the run to its terminal state and settles the result (`result.raw` carries cost, step counts, token usage).
163
163
 
164
+ Undecodable or empty screenshot data URIs never interrupt `wait()` or invoke `onScreenshot`, regardless of capture settings. They follow the existing progress fallback when a human-readable message is available; `onWireEvent` always retains the original payload, including frames with no progress text.
165
+
164
166
  > **Best practice — match `event.type` against the `QoniEventTypes` constants.**
165
167
  > Each product handle is typed to its own event set, so in TypeScript a case
166
168
  > for another product's event is a compile error and autocomplete shows only
package/README.zh-CN.md CHANGED
@@ -154,6 +154,8 @@ console.log(result.output);
154
154
 
155
155
  `run()` 返回一个 `RunHandle`。核心事件(状态、动作、交互、完成)始终默认推送;`capture: { screenshots: true }` 开启逐步截图,并且 SDK 已经把图片解码成字节。`wait()` 把任务跑到终态,并从权威 run envelope 结算结果(成本、步数、token 用量都在 `result.raw` 上)。
156
156
 
157
+ 无论是否开启 capture,不可解码或空的截图 data URI 都不会中断 `wait()`,也不会触发 `onScreenshot`。有可读消息时按既有契约降级为 progress;`onWireEvent` 始终保留原始 payload,包括没有 progress 文本的帧。
158
+
157
159
  需要逐步控制时,直接消费事件流,`switch (event.type)` 用 `QoniEventTypes` 常量匹配。每个产品的 handle 按产品分型(`qoni.deepResearch.run()` 出来是 `RunHandle<DeepResearchEvent>`),TS 里写错产品的事件会编译报错、补全只列本产品的。内部细节(supervisor 编排、子 agent 点击/输入、telemetry)统一折叠成 `QoniEventTypes.Progress`;匹配到 `case` 后 `event.data` 就是该类型的固定形状。原始 wire 类型不导出。
158
160
 
159
161
  ```ts
package/dist/index.cjs CHANGED
@@ -397,8 +397,14 @@ function decodeDataUri(uri) {
397
397
  const match = /^data:([^;,]*)?(;base64)?,(.*)$/s.exec(uri);
398
398
  if (!match) return void 0;
399
399
  const [, mime, isBase64, body] = match;
400
- const bytes = isBase64 ? new Uint8Array(Buffer.from(body, "base64")) : new TextEncoder().encode(decodeURIComponent(body));
401
- return { bytes, mime: mime || "application/octet-stream" };
400
+ const encoded = isBase64 ? body.replace(/\s/g, "") : body;
401
+ if (isBase64 && (!/^[A-Za-z0-9+/_-]+={0,2}$/.test(encoded) || encoded.length % 4 === 1 || encoded.includes("=") && encoded.length % 4 !== 0)) return void 0;
402
+ try {
403
+ const bytes = isBase64 ? new Uint8Array(Buffer.from(encoded, "base64")) : new TextEncoder().encode(decodeURIComponent(encoded));
404
+ return bytes.length ? { bytes, mime: mime || "application/octet-stream" } : void 0;
405
+ } catch {
406
+ return void 0;
407
+ }
402
408
  }
403
409
  function asString(value) {
404
410
  return typeof value === "string" && value ? value : void 0;