paseo-dsh-direct 0.2.5 → 0.2.7

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/README.md CHANGED
@@ -15,6 +15,13 @@ In Paseo, open **Settings → Plugins → Install Plugin** and paste either the
15
15
  | `0.2.x` | `npm:paseo-dsh-direct` | `https://github.com/Jecvay/paseo-dsh-direct` |
16
16
  | `0.1.x` | `npm:paseo-dsh-direct@dsh-0.1` | CLI only: `paseo plugin install https://github.com/Jecvay/paseo-dsh-direct --ref release/0.1` |
17
17
 
18
+ To update, run on the daemon machine (the app's plugin menu has no update entry):
19
+
20
+ ```bash
21
+ paseo plugin update paseo-dsh-direct --check # see if a new version exists
22
+ paseo plugin update paseo-dsh-direct --yes # update to the latest
23
+ ```
24
+
18
25
  More: [compatibility](docs/en/compatibility.md) · [CLI and local install, environment variables](docs/en/installation.md)
19
26
 
20
27
  ## Why "Direct"
package/README.zh.md CHANGED
@@ -15,6 +15,13 @@
15
15
  | `0.2.x` | `npm:paseo-dsh-direct` | `https://github.com/Jecvay/paseo-dsh-direct` |
16
16
  | `0.1.x` | `npm:paseo-dsh-direct@dsh-0.1` | 只能用命令行:`paseo plugin install https://github.com/Jecvay/paseo-dsh-direct --ref release/0.1` |
17
17
 
18
+ 更新插件在 daemon 所在机器上运行(App 的插件菜单里没有更新入口):
19
+
20
+ ```bash
21
+ paseo plugin update paseo-dsh-direct --check # 看有没有新版本
22
+ paseo plugin update paseo-dsh-direct --yes # 更新到最新
23
+ ```
24
+
18
25
  更多:[兼容性说明](docs/compatibility.md) · [命令行安装、本地目录安装、环境变量](docs/plugin-guide.md)
19
26
 
20
27
  ## 为什么叫 Direct
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paseo-dsh-direct",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "DeepSeek Harness Direct Provider Plugin for Paseo",
5
5
  "repository": {
6
6
  "type": "git",
@@ -379,6 +379,24 @@ export async function launchDshBridge(options: LaunchBridgeOptions): Promise<Dsh
379
379
  }
380
380
  }
381
381
 
382
+ /**
383
+ * Parse one stdout line from the bridge process. `undefined` means the line is
384
+ * not a protocol message: dsh also writes its own logs to stdout (for example
385
+ * the model-catalog line the deepseek-account provider emits), and such a line
386
+ * must not fail the bridge.
387
+ */
388
+ export function parseBridgeLine(line: string): RpcResponse | RpcNotification | undefined {
389
+ let value: unknown;
390
+ try {
391
+ value = JSON.parse(line);
392
+ } catch {
393
+ return undefined;
394
+ }
395
+ return typeof value === "object" && value !== null && !Array.isArray(value)
396
+ ? (value as RpcResponse | RpcNotification)
397
+ : undefined;
398
+ }
399
+
382
400
  class JsonlBridgeClient implements DshBridge {
383
401
  initialized!: BridgeInitializeResult;
384
402
  readonly executable: string;
@@ -517,11 +535,12 @@ class JsonlBridgeClient implements DshBridge {
517
535
 
518
536
  private acceptLine(line: string): void {
519
537
  if (!line.trim()) return;
520
- let message: RpcResponse | RpcNotification;
521
- try {
522
- message = JSON.parse(line) as RpcResponse | RpcNotification;
523
- } catch {
524
- this.fail(new Error(`DSH bridge wrote invalid JSON: ${line.slice(0, 200)}`));
538
+ const message = parseBridgeLine(line);
539
+ if (message === undefined) {
540
+ // stdout carries the protocol, but dsh writes its own logs there too.
541
+ // Forward the line to stderr and keep the bridge alive instead of
542
+ // failing every provider snapshot on one log line.
543
+ process.stderr.write(`[paseo-dsh-direct] ignored dsh stdout: ${line.slice(0, 2000)}\n`);
525
544
  return;
526
545
  }
527
546
  if ("id" in message) {
@@ -263,20 +263,8 @@ export class TimelineProjector {
263
263
  projected.push(timeline(this.paseoSessionId, item, timestamp));
264
264
  }
265
265
  });
266
- const usage = objectValue(data.usage) ?? objectValue(message.usage);
267
- if (usage) {
268
- projected.push({
269
- type: "session.usage",
270
- sessionId: this.paseoSessionId,
271
- usage: {
272
- inputTokens: numberValue(usage.inputTokens) ?? numberValue(usage.input_tokens),
273
- cachedInputTokens:
274
- numberValue(usage.cachedInputTokens) ?? numberValue(usage.cached_input_tokens),
275
- outputTokens: numberValue(usage.outputTokens) ?? numberValue(usage.output_tokens),
276
- totalCostUsd: numberValue(usage.totalCostUsd) ?? numberValue(usage.total_cost_usd),
277
- },
278
- });
279
- }
266
+ // No session.usage here: Paseo replaces `lastUsage` whole, and a per-message
267
+ // reading would overwrite the bridge's complete one with fewer fields.
280
268
  return projected;
281
269
  }
282
270