dsh-deeppilot 0.9.15 → 0.9.17

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/lib/index.d.ts CHANGED
@@ -1,5 +1,35 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
2
  import { Context } from "@deepseek-ai/cordis";
3
+ /**
4
+ * 输入框 `@` 引用候选(PROTOCOL.md「输入框引用扩展」)。
5
+ *
6
+ * 数据来源都是 DSH 官方 Remote,经 `typertGateway` 以 owner 身份调用,与 Web 端同一条发现链路:
7
+ * - 文件:`fileReferences/list {agentId, query}` → `[{path, kind}]`,由主机挂载的提供方
8
+ * (如 `dsh-file-reference-local`)在该会话工作目录里排序给出。只给路径,不读文件内容。
9
+ * - 会话:`sessionReferenceResolver/candidates {agentId, query}` → 带规范 mention
10
+ * `@[label](dsh-session:…)` 的候选;手机发送时原样放进提示词,主机负责改写与注入快照。
11
+ *
12
+ * 两类服务都是可选挂载(兼容下限 0.2.1-rc.5 没有保证),所以每次按当前服务是否存在判定,
13
+ * 一类缺席不影响另一类。会话候选不下发工作目录,只给 `sameWorkspace`,避免把本机路径带到手机。
14
+ */
15
+ interface FileReferenceItem {
16
+ path: string;
17
+ kind: 'file' | 'directory';
18
+ }
19
+ interface SessionReferenceItem {
20
+ sessionId: string;
21
+ label: string;
22
+ mention: string;
23
+ sameWorkspace: boolean;
24
+ }
25
+ interface ReferenceSource<T> {
26
+ available: boolean;
27
+ items: T[];
28
+ }
29
+ interface ReferenceCandidates {
30
+ files: ReferenceSource<FileReferenceItem>;
31
+ sessions: ReferenceSource<SessionReferenceItem>;
32
+ }
3
33
  declare const DEVICE_SCOPES: readonly ['sessions.read', 'prompt.send', 'sessions.manage', 'interactions.respond', 'notifications.register', 'schedule.manage'];
4
34
  type DeviceScope = (typeof DEVICE_SCOPES)[number];
5
35
  /**
@@ -352,6 +382,8 @@ interface HostSchedulePatch {
352
382
  interface WelcomeCapabilities {
353
383
  /** 会话命令目录、执行、权限与原生日志导出入口。缺省不支持。 */
354
384
  commands?: boolean;
385
+ /** 输入框 `@` 引用候选:c2s.session.references 可用(文件或会话引用至少一类)。缺省不支持。 */
386
+ references?: boolean;
355
387
  historyPaging: boolean;
356
388
  replay: boolean;
357
389
  approvals: boolean;
@@ -406,6 +438,26 @@ interface WelcomeCapabilities {
406
438
  * see binary-frame.ts). Plugin-level, independent of the host. Absent ⇒ the
407
439
  * client must keep requesting base64 text frames. */
408
440
  binaryFrames?: boolean;
441
+ /** Bridge honours `watchSessions` on c2s.auth.prove and c2s.session.watch:
442
+ * a connection that declared an interest set only receives
443
+ * s2c.session.event / s2c.session.queue (live and replayed) for sessions it
444
+ * opened or watches. Plugin-level. Absent ⇒ the client gets every
445
+ * session's events, as before. */
446
+ sessionInterest?: boolean;
447
+ /** Bridge compresses downlink frames over 8 KB as binary format 2
448
+ * (`[2][deflate-raw(envelope JSON)]`) once the client listed "deflate-raw"
449
+ * in `acceptEncoding` on c2s.auth.prove. Plugin-level. Absent ⇒ the field is
450
+ * ignored and every JSON frame stays a text frame. */
451
+ compressedFrames?: boolean;
452
+ /** Bridge answers c2s.session.open carrying `sinceSeq` with an incremental
453
+ * tail (`incremental: true`) holding only rows changed after that seq, or
454
+ * with a full tail when it cannot prove the delta complete. Plugin-level. */
455
+ incrementalTail?: boolean;
456
+ /** Bridge includes `routes` (current LAN endpoints with their certificate
457
+ * fingerprint, and the public Funnel URL) in s2c.welcome so the client can
458
+ * prefer the LAN on the same network and fall back to Funnel elsewhere.
459
+ * Plugin-level. */
460
+ routeHints?: boolean;
409
461
  }
410
462
  type SessionStatus = "running" | "idle" | "error" | "unknown";
411
463
  /**
@@ -480,8 +532,8 @@ type MessageRole = 'user' | 'assistant' | 'tool' | 'system' | 'error';
480
532
  type ToolState = 'running' | 'ok' | 'error';
481
533
  /**
482
534
  * 文件编辑类工具调用的改动内容(v2 追加式扩展,见 PROTOCOL.md「工具改动对比」)。
483
- * Bridge 把宿主 `str_replace_editor` 的参数名(old_str/new_str/file_text/insert_line)
484
- * 归一化成这里的字段,手机端不依赖宿主工具参数命名。`oldText` / `newText` 各自超过
535
+ * Bridge 把宿主 `edit`(old_string/new_string)、`write`(content)与 `str_replace_editor`
536
+ * (old_str/new_str/file_text/insert_line)的参数名归一化成这里的字段,手机端不依赖宿主工具参数命名。`oldText` / `newText` 各自超过
485
537
  * 16 KiB(UTF-8)时都不发,只带 `truncated: true`。
486
538
  */
487
539
  interface ToolEditProjection {
@@ -493,6 +545,22 @@ interface ToolEditProjection {
493
545
  insertLine?: number;
494
546
  truncated?: boolean;
495
547
  }
548
+ /**
549
+ * 工具调用的操作对象(v2 追加式扩展,见 PROTOCOL.md「Message 投影 · tool.target」)。
550
+ * Bridge 从宿主工具参数里挑出「对什么做」:文件路径、命令、搜索式、网址或其他对象名,
551
+ * 参数名不外泄。工具结果合并回调用行后 `summary` 会被结果摘要替换,`target` 保留,
552
+ * 客户端据此在调用完成后仍能显示「读取 A.swift」而不是文件正文片段。
553
+ * `kind` 是开放词表:客户端遇到未知值按 `text` 处理。
554
+ */
555
+ interface ToolTargetProjection {
556
+ kind: 'path' | 'command' | 'pattern' | 'url' | 'text';
557
+ /** 主值;UTF-8 上限 1 KiB。路径超长时砍开头(保留文件名),其余砍结尾加「…」。 */
558
+ value: string;
559
+ /** 范围:搜索所在目录(`pattern` 专用);UTF-8 上限 1 KiB,规则同路径。 */
560
+ scope?: string;
561
+ /** 宿主给的人类可读说明(如 bash 的 description);UTF-8 上限 256 B。 */
562
+ label?: string;
563
+ }
496
564
  /** Provenance of host-injected context; present only on `role: "system"` rows.
497
565
  * Mirrors the durable DSH message source (`dsh-llm` MessageSource): `label`
498
566
  * names the producer (plugin name, skill name, instruction paths…), `form` is
@@ -527,6 +595,7 @@ interface MessageProjection {
527
595
  state: ToolState;
528
596
  summary: string;
529
597
  edit?: ToolEditProjection;
598
+ target?: ToolTargetProjection;
530
599
  };
531
600
  attachments?: MessageAttachment[];
532
601
  /** Present only on system rows: provenance of the injected context.
@@ -588,6 +657,16 @@ interface PendingSnapshotPayload {
588
657
  approvals: PendingApprovalPayload[];
589
658
  questions: PendingQuestionPayload[];
590
659
  }
660
+ /**
661
+ * 宿主持久化图片引用(ImageAttachmentRef)的原样对象。
662
+ *
663
+ * 只要求 `attachmentId`;其余字段(mediaType/bytes/width/height/name/
664
+ * originalDimensions…)由宿主生成、由宿主读取时自行核对,这里原样保留、不做
665
+ * 字段裁剪,免得宿主以后新增必填字段时被插件悄悄丢掉。
666
+ */
667
+ type HostImageRef = Readonly<Record<string, unknown> & {
668
+ attachmentId: string;
669
+ }>;
591
670
  interface CommandsApiLike {
592
671
  list(req: RpcRequestLike<{
593
672
  sessionId: string;
@@ -612,6 +691,13 @@ interface CommandsApiLike {
612
691
  format?: SessionExportFormat;
613
692
  }>, signal: AbortSignal): Promise<Response>;
614
693
  }
694
+ /** 输入框 `@` 引用候选(文件 + 会话),见 reference-api.ts。 */
695
+ interface ReferencesApiLike {
696
+ list(req: RpcRequestLike<{
697
+ sessionId: string;
698
+ query: string;
699
+ }>, signal?: AbortSignal): Promise<RpcResponseLike<ReferenceCandidates>>;
700
+ }
615
701
  interface RpcOk<T> {
616
702
  ok: true;
617
703
  value: T;
@@ -685,10 +771,16 @@ interface SessionsApiLike {
685
771
  cancel?(req: RpcRequestLike<{
686
772
  sessionId: string;
687
773
  }>): Promise<RpcResponseLike<Record<string, unknown> | undefined>>;
688
- /** Reads one durable image back after the host verifies the session log references its id. */
774
+ /**
775
+ * Reads one durable image back. DSH ≤ 0.2.1 reads `attachmentId` and checks the
776
+ * session log itself; DSH 0.2.2+ reads the full `attachment` reference and no
777
+ * longer checks the session, so HostBridge sends both and only supplies a
778
+ * reference it saw projected in that session.
779
+ */
689
780
  attachment?(req: RpcRequestLike<{
690
781
  sessionId: string;
691
782
  attachmentId: string;
783
+ attachment?: HostImageRef;
692
784
  }>): Promise<RpcResponseLike<{
693
785
  attachment: {
694
786
  mediaType?: string;
@@ -1077,6 +1169,8 @@ interface ApiProxyLike {
1077
1169
  /** 真实宿主反射声明了助手流帧时才为 true;旧代理缺省关闭。 */
1078
1170
  readonly assistantStreamAvailable?: boolean;
1079
1171
  commands?: CommandsApiLike;
1172
+ /** 主机挂载了文件引用或会话引用服务之一时存在;两者都缺席为 undefined。 */
1173
+ references?: ReferencesApiLike;
1080
1174
  sessions: SessionsApiLike;
1081
1175
  workspace?: WorkspaceApiLike;
1082
1176
  schedule?: ScheduleApiLike;
@@ -1122,6 +1216,14 @@ interface BridgeSink {
1122
1216
  * every push/replay delivery; unknown broadcast types are denied.
1123
1217
  */
1124
1218
  canReceive(scope: DeviceScope): boolean;
1219
+ /**
1220
+ * Interest filter (capability `sessionInterest`): whether this sink wants a
1221
+ * frame it is already permitted to receive. Connections that declared an
1222
+ * interest set drop other sessions' events here. Absent ⇒ wants everything.
1223
+ * The bridge consults it when sizing a replay window; sinks apply it again
1224
+ * on every push.
1225
+ */
1226
+ accepts?(type: string, payload: unknown): boolean;
1125
1227
  }
1126
1228
  /**
1127
1229
  * Offline push fan-out (F-9 离线推送). The bridge forwards every
@@ -1219,6 +1321,13 @@ export declare class HostBridge {
1219
1321
  private readonly log?;
1220
1322
  readonly id: number;
1221
1323
  private summaries;
1324
+ /**
1325
+ * 列表推送节流(连接传输第二批 P5)。每个会话最近一次推出去的摘要指纹,
1326
+ * 用来丢掉内容完全相同的重复推送;只改了 `stats` 的变化按 SUMMARY_STATS_THROTTLE_MS
1327
+ * 合并,状态、标题、任务清单、待处理标记、活动描述的变化照旧立即推。
1328
+ */
1329
+ private readonly summaryPushed;
1330
+ private readonly summaryStatsTimers;
1222
1331
  private activeTools;
1223
1332
  private approvals;
1224
1333
  private questions;
@@ -1242,6 +1351,8 @@ export declare class HostBridge {
1242
1351
  private abort;
1243
1352
  private started;
1244
1353
  private disposed;
1354
+ /** attachmentId → 宿主完整图片引用,供 attachmentData 补全 DSH 0.2.2+ 的读图参数。 */
1355
+ private readonly imageRefs;
1245
1356
  readonly promptDeliveries: DispatchJournal<{
1246
1357
  sessionId: string;
1247
1358
  content: unknown;
@@ -1307,6 +1418,12 @@ export declare class HostBridge {
1307
1418
  * reader without interactions.respond never gets the missed approval
1308
1419
  * frames back (R1/P2).
1309
1420
  */
1421
+ /**
1422
+ * 按序补发游标之后的帧。先按权限与关注集合筛出该 sink 真正会收到的帧,
1423
+ * 估算字节数超过 REPLAY_RESYNC_BYTES 时改发 `s2c.resync`:补发是同步一次性
1424
+ * 写出的,经 Funnel 时插件这侧看不到积压,大补发会把之后所有请求响应堵在
1425
+ * 链路上(实测 450 帧堵 37 秒)。重新同步让客户端只拉列表和正在看的会话。
1426
+ */
1310
1427
  resumeFrom(cursor: number, target?: BridgeSink): boolean;
1311
1428
  refreshLiveActivities(): void;
1312
1429
  private record;
@@ -1345,6 +1462,8 @@ export declare class HostBridge {
1345
1462
  private applyProjection;
1346
1463
  private bumpPendingFlags;
1347
1464
  private pushSummary;
1465
+ private noteSummaryPushed;
1466
+ private forgetSummaryPush;
1348
1467
  listSessions(): SessionSummary[];
1349
1468
  /**
1350
1469
  * Archived rows from the last sessions.list, newest first. Served only on
@@ -1361,7 +1480,7 @@ export declare class HostBridge {
1361
1480
  /** Resolve only the exact invocation in this session; never guess from the latest tool. */
1362
1481
  private loadApprovalArguments;
1363
1482
  /** Tail history for an opened session; pushes s2c.session.tail to the sink. */
1364
- openSession(sink: BridgeSink, sessionId: string, tailCount: number): Promise<boolean>;
1483
+ openSession(sink: BridgeSink, sessionId: string, tailCount: number, sinceSeq?: number): Promise<boolean>;
1365
1484
  /**
1366
1485
  * Pull one session's projection baseline and fold every key
1367
1486
  * through applyProjection — unknown keys are ignored there, `null` means the
@@ -1374,12 +1493,28 @@ export declare class HostBridge {
1374
1493
  messages: MessageProjection[];
1375
1494
  hasMore: boolean;
1376
1495
  } | null>;
1377
- /** Result of one attachment read-back for the phone. */
1496
+ /**
1497
+ * Result of one attachment read-back for the phone.
1498
+ *
1499
+ * 宿主读图参数有两代:DSH ≤ 0.2.1 收 `{sessionId, attachmentId}` 并自己在会话日志里
1500
+ * 找引用;DSH 0.2.2 起改收 `{sessionId, attachment: 完整引用}`,且不再核对会话。
1501
+ * 控制器是直接注入的实例、不经参数 schema 校验,所以两代字段一起传:旧宿主读前者,
1502
+ * 新宿主读后者。完整引用来自 imageRefs(本会话投影过的图片);找不到时不带
1503
+ * `attachment`,旧宿主照常自查,新宿主读不到即回 null(E_NOT_FOUND)——手机因此
1504
+ * 读不到不属于该会话的图片。
1505
+ */
1378
1506
  attachmentData(sessionId: string, attachmentId: string): Promise<{
1379
1507
  mediaType?: string;
1380
1508
  data: string;
1381
1509
  } | null>;
1510
+ /** 图片引用回查用的原始历史页:只取事件,不投影、不推给手机。 */
1511
+ private readHistoryEvents;
1382
1512
  commandOperation(operation: 'list' | 'execute' | 'permissions' | 'feedback', payload: Record<string, unknown>): Promise<SessionManagementResult<unknown>>;
1513
+ /**
1514
+ * 输入框 `@` 引用候选。两类候选的单类失败已在 reference-api 内吸收为空列表,
1515
+ * 这里只处理「两类都不可用」与代理层意外异常。
1516
+ */
1517
+ referenceCandidates(sessionId: string, query: string, signal?: AbortSignal): Promise<SessionManagementResult<ReferenceCandidates>>;
1383
1518
  exportSession(sessionId: string, signal: AbortSignal, format?: SessionExportFormat): Promise<Response>;
1384
1519
  /** 由会话目录决定技能可见性;不读取正文,也不把本机路径发给移动端。 */
1385
1520
  sessionSkills(sessionId: string): Promise<SessionManagementResult<{