@yefengr/pi-reach 0.0.0-stage → 0.0.2

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 (129) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +110 -2
  3. package/dist/actions/handlers.d.ts +143 -0
  4. package/dist/actions/handlers.js +200 -0
  5. package/dist/actions/handlers.js.map +1 -0
  6. package/dist/actions/registry.d.ts +39 -0
  7. package/dist/actions/registry.js +58 -0
  8. package/dist/actions/registry.js.map +1 -0
  9. package/dist/actions/session_new_bridge.d.ts +35 -0
  10. package/dist/actions/session_new_bridge.js +88 -0
  11. package/dist/actions/session_new_bridge.js.map +1 -0
  12. package/dist/commands.d.ts +29 -0
  13. package/dist/commands.js +169 -0
  14. package/dist/commands.js.map +1 -0
  15. package/dist/config.d.ts +61 -0
  16. package/dist/config.js +115 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/index.d.ts +27 -0
  19. package/dist/index.js +618 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/pairing/crypto.d.ts +15 -0
  22. package/dist/pairing/crypto.js +72 -0
  23. package/dist/pairing/crypto.js.map +1 -0
  24. package/dist/pairing/identity-keyring.d.ts +22 -0
  25. package/dist/pairing/identity-keyring.js +94 -0
  26. package/dist/pairing/identity-keyring.js.map +1 -0
  27. package/dist/pairing/identity-lock.d.ts +14 -0
  28. package/dist/pairing/identity-lock.js +116 -0
  29. package/dist/pairing/identity-lock.js.map +1 -0
  30. package/dist/pairing/owner_storage.d.ts +61 -0
  31. package/dist/pairing/owner_storage.js +263 -0
  32. package/dist/pairing/owner_storage.js.map +1 -0
  33. package/dist/pairing/qr.d.ts +39 -0
  34. package/dist/pairing/qr.js +113 -0
  35. package/dist/pairing/qr.js.map +1 -0
  36. package/dist/pairing/storage.d.ts +36 -0
  37. package/dist/pairing/storage.js +263 -0
  38. package/dist/pairing/storage.js.map +1 -0
  39. package/dist/protocol/types.d.ts +225 -0
  40. package/dist/protocol/types.js +2 -0
  41. package/dist/protocol/types.js.map +1 -0
  42. package/dist/protocol/v2/codec.d.ts +6 -0
  43. package/dist/protocol/v2/codec.js +4 -0
  44. package/dist/protocol/v2/codec.js.map +1 -0
  45. package/dist/protocol/v2/index.d.ts +4 -0
  46. package/dist/protocol/v2/index.js +5 -0
  47. package/dist/protocol/v2/index.js.map +1 -0
  48. package/dist/protocol/v2/marker.d.ts +45 -0
  49. package/dist/protocol/v2/marker.js +47 -0
  50. package/dist/protocol/v2/marker.js.map +1 -0
  51. package/dist/protocol/v2/schemas.d.ts +3 -0
  52. package/dist/protocol/v2/schemas.js +4 -0
  53. package/dist/protocol/v2/schemas.js.map +1 -0
  54. package/dist/protocol/v2/session_state.d.ts +79 -0
  55. package/dist/protocol/v2/session_state.js +166 -0
  56. package/dist/protocol/v2/session_state.js.map +1 -0
  57. package/dist/runtime/endpoint_metadata.d.ts +14 -0
  58. package/dist/runtime/endpoint_metadata.js +18 -0
  59. package/dist/runtime/endpoint_metadata.js.map +1 -0
  60. package/dist/runtime/extension_owner.d.ts +12 -0
  61. package/dist/runtime/extension_owner.js +80 -0
  62. package/dist/runtime/extension_owner.js.map +1 -0
  63. package/dist/runtime/footer.d.ts +6 -0
  64. package/dist/runtime/footer.js +21 -0
  65. package/dist/runtime/footer.js.map +1 -0
  66. package/dist/runtime/owner_router.d.ts +16 -0
  67. package/dist/runtime/owner_router.js +41 -0
  68. package/dist/runtime/owner_router.js.map +1 -0
  69. package/dist/runtime/pairing_coordinator.d.ts +42 -0
  70. package/dist/runtime/pairing_coordinator.js +136 -0
  71. package/dist/runtime/pairing_coordinator.js.map +1 -0
  72. package/dist/runtime/relay_lifecycle.d.ts +64 -0
  73. package/dist/runtime/relay_lifecycle.js +275 -0
  74. package/dist/runtime/relay_lifecycle.js.map +1 -0
  75. package/dist/session/local_config.d.ts +7 -0
  76. package/dist/session/local_config.js +52 -0
  77. package/dist/session/local_config.js.map +1 -0
  78. package/dist/timeline/history.d.ts +30 -0
  79. package/dist/timeline/history.js +170 -0
  80. package/dist/timeline/history.js.map +1 -0
  81. package/dist/timeline/partial_delta.d.ts +2 -0
  82. package/dist/timeline/partial_delta.js +16 -0
  83. package/dist/timeline/partial_delta.js.map +1 -0
  84. package/dist/timeline/run_end.d.ts +16 -0
  85. package/dist/timeline/run_end.js +23 -0
  86. package/dist/timeline/run_end.js.map +1 -0
  87. package/dist/timeline/runtime.d.ts +89 -0
  88. package/dist/timeline/runtime.js +546 -0
  89. package/dist/timeline/runtime.js.map +1 -0
  90. package/dist/timeline/sequence.d.ts +7 -0
  91. package/dist/timeline/sequence.js +16 -0
  92. package/dist/timeline/sequence.js.map +1 -0
  93. package/dist/timeline/tool_lifecycle.d.ts +36 -0
  94. package/dist/timeline/tool_lifecycle.js +171 -0
  95. package/dist/timeline/tool_lifecycle.js.map +1 -0
  96. package/dist/timeline/user_delivery.d.ts +96 -0
  97. package/dist/timeline/user_delivery.js +360 -0
  98. package/dist/timeline/user_delivery.js.map +1 -0
  99. package/dist/timeline/user_delivery_binding.d.ts +43 -0
  100. package/dist/timeline/user_delivery_binding.js +107 -0
  101. package/dist/timeline/user_delivery_binding.js.map +1 -0
  102. package/dist/timeline/v2_service.d.ts +82 -0
  103. package/dist/timeline/v2_service.js +512 -0
  104. package/dist/timeline/v2_service.js.map +1 -0
  105. package/dist/transport/peer_channel.d.ts +34 -0
  106. package/dist/transport/peer_channel.js +116 -0
  107. package/dist/transport/peer_channel.js.map +1 -0
  108. package/dist/transport/relay_client.d.ts +54 -0
  109. package/dist/transport/relay_client.js +270 -0
  110. package/dist/transport/relay_client.js.map +1 -0
  111. package/dist/vendor/protocol/constants.d.ts +4 -0
  112. package/dist/vendor/protocol/constants.js +4 -0
  113. package/dist/vendor/protocol/encoding.d.ts +9 -0
  114. package/dist/vendor/protocol/encoding.js +66 -0
  115. package/dist/vendor/protocol/outer/codec.d.ts +13 -0
  116. package/dist/vendor/protocol/outer/codec.js +105 -0
  117. package/dist/vendor/protocol/outer/index.d.ts +4 -0
  118. package/dist/vendor/protocol/outer/index.js +4 -0
  119. package/dist/vendor/protocol/outer/types.d.ts +120 -0
  120. package/dist/vendor/protocol/outer/types.js +1 -0
  121. package/dist/vendor/protocol/session/codec.d.ts +41 -0
  122. package/dist/vendor/protocol/session/codec.js +236 -0
  123. package/dist/vendor/protocol/session/frames.d.ts +5220 -0
  124. package/dist/vendor/protocol/session/frames.js +83 -0
  125. package/dist/vendor/protocol/session/index.d.ts +3 -0
  126. package/dist/vendor/protocol/session/index.js +3 -0
  127. package/dist/vendor/protocol/session/schema.d.ts +858 -0
  128. package/dist/vendor/protocol/session/schema.js +256 -0
  129. package/package.json +74 -3
@@ -0,0 +1,170 @@
1
+ import { encodeServerFrameV2, getUtf8ByteLengthV2, MAX_FRAGMENT_DECODE_BYTES, MAX_HISTORY_CHUNK_BYTES, MAX_WINDOW_DECODE_BYTES, TimelineEventSchema, } from "../protocol/v2/index.js";
2
+ const DEFAULT_EVENTS_PER_PAGE = 80;
3
+ export class TimelineHistoryPager {
4
+ sessionManager;
5
+ recoverFn;
6
+ constructor(sessionManager, recoverFn) {
7
+ this.sessionManager = sessionManager;
8
+ this.recoverFn = recoverFn;
9
+ }
10
+ sync(request) {
11
+ const invalidRequest = this.validateRequest(request);
12
+ if (invalidRequest)
13
+ return [invalidRequest];
14
+ const snapshot = this.captureSnapshot();
15
+ if (!snapshot)
16
+ return [this.protocolError(request, "reset_required", "session has no current snapshot head")];
17
+ const initialScopeMismatch = this.snapshotInvalidReason(snapshot, request.leafId);
18
+ if (initialScopeMismatch)
19
+ return [this.reset(request, initialScopeMismatch)];
20
+ let records;
21
+ try {
22
+ records = this.recoverRecords(snapshot);
23
+ }
24
+ catch {
25
+ return [this.protocolError(request, "internal_error", "history recovery failed")];
26
+ }
27
+ const changed = this.snapshotInvalidReason(snapshot, request.leafId);
28
+ if (changed)
29
+ return [this.reset(request, changed)];
30
+ const headSeq = records.length;
31
+ const before = request.before ?? headSeq + 1;
32
+ if (before > headSeq + 1)
33
+ return [this.protocolError(request, "invalid_cursor", "history boundary is beyond the current head")];
34
+ const window = this.selectWindow(records, before, request.limit ?? DEFAULT_EVENTS_PER_PAGE);
35
+ if (window.kind === "error")
36
+ return [this.protocolError(request, "too_large", window.message)];
37
+ const nextBefore = window.records[0]?.event.event_seq;
38
+ const eos = window.records.length === 0 || nextBefore === 1;
39
+ try {
40
+ return this.fragmentWindow(request, snapshot, window.records, eos ? undefined : nextBefore);
41
+ }
42
+ catch (error) {
43
+ return [this.protocolError(request, "too_large", error instanceof Error ? error.message : "history chunk construction failed")];
44
+ }
45
+ }
46
+ validateRequest(request) {
47
+ if (request.before !== null && (!Number.isSafeInteger(request.before) || request.before < 1))
48
+ return this.protocolError(request, "invalid_cursor", "history boundary must be a positive safe integer or null");
49
+ if (request.limit !== undefined && (!Number.isInteger(request.limit) || request.limit < 1 || request.limit > 80))
50
+ return this.protocolError(request, "invalid_cursor", "history limit must be an integer from 1 through 80");
51
+ return null;
52
+ }
53
+ captureSnapshot() {
54
+ const sessionId = this.sessionManager.getSessionId();
55
+ const leafId = this.sessionManager.getLeafId() ?? null;
56
+ const branch = this.sessionManager.getBranch();
57
+ if (branch.length > 0 && branch.at(-1)?.id !== leafId)
58
+ return null;
59
+ return { sessionId, leafId, branchEntryIds: branch.map((entry) => entry.id) };
60
+ }
61
+ snapshotInvalidReason(snapshot, requestedLeafId) {
62
+ if (this.sessionManager.getSessionId() !== snapshot.sessionId)
63
+ return "session_replaced";
64
+ if (requestedLeafId !== snapshot.leafId)
65
+ return "branch_changed";
66
+ const currentLeafId = this.sessionManager.getLeafId() ?? null;
67
+ if (currentLeafId !== snapshot.leafId)
68
+ return "branch_changed";
69
+ const currentIds = this.sessionManager.getBranch().map((entry) => entry.id);
70
+ if (!sameIds(currentIds, snapshot.branchEntryIds))
71
+ return "branch_changed";
72
+ const frozenIds = snapshot.leafId === null ? currentIds : this.sessionManager.getBranch(snapshot.leafId).map((entry) => entry.id);
73
+ return sameIds(frozenIds, snapshot.branchEntryIds) ? null : "branch_changed";
74
+ }
75
+ recoverRecords(snapshot) {
76
+ const records = [];
77
+ const eventIds = new Set();
78
+ const sequences = new Set();
79
+ for (const rawEvent of this.recoverFn(this.sessionManager)) {
80
+ const parsed = TimelineEventSchema.safeParse(rawEvent);
81
+ if (!parsed.success || parsed.data.event_seq === undefined)
82
+ throw new Error("recovery returned an unsequenced timeline event");
83
+ const event = parsed.data;
84
+ if (event.session_id !== snapshot.sessionId || event.leaf_id !== snapshot.leafId)
85
+ throw new Error("recovery returned an event outside the snapshot scope");
86
+ if (eventIds.has(event.event_id) || sequences.has(event.event_seq))
87
+ throw new Error("recovery returned duplicate timeline identity");
88
+ eventIds.add(event.event_id);
89
+ sequences.add(event.event_seq);
90
+ records.push({ event, bytes: getUtf8ByteLengthV2(event) });
91
+ }
92
+ records.sort((left, right) => left.event.event_seq - right.event.event_seq);
93
+ if (records.some((record, index) => record.event.event_seq !== index + 1))
94
+ throw new Error("recovery returned a non-dense timeline sequence");
95
+ return records;
96
+ }
97
+ selectWindow(records, before, limit) {
98
+ const lower = Math.max(1, before - limit);
99
+ const requested = records.filter((record) => record.event.event_seq >= lower && record.event.event_seq < before);
100
+ const selected = [];
101
+ let bytes = 0;
102
+ for (let index = requested.length - 1; index >= 0; index -= 1) {
103
+ const record = requested[index];
104
+ if (record.bytes > MAX_WINDOW_DECODE_BYTES)
105
+ return { kind: "error", message: `event ${record.event.event_id} exceeds ${MAX_WINDOW_DECODE_BYTES} bytes` };
106
+ if (bytes + record.bytes > MAX_WINDOW_DECODE_BYTES)
107
+ break;
108
+ selected.unshift(record);
109
+ bytes += record.bytes;
110
+ }
111
+ return { kind: "ok", records: selected };
112
+ }
113
+ fragmentWindow(request, snapshot, records, nextBefore) {
114
+ const tailOverhead = this.finalFrameBytes(request, snapshot, { events: [], fragments: [] }, nextBefore) - this.nonFinalFrameBytes(request, snapshot, { events: [], fragments: [] });
115
+ const items = [];
116
+ for (const record of records) {
117
+ const fullFrame = this.makeChunk(request, snapshot, { events: [record.event], fragments: [] }, true, nextBefore);
118
+ if (getUtf8ByteLengthV2(fullFrame) <= MAX_HISTORY_CHUNK_BYTES) {
119
+ items.push({ kind: "event", event: record.event });
120
+ continue;
121
+ }
122
+ const encoded = new TextEncoder().encode(JSON.stringify(record.event));
123
+ let index = 0;
124
+ for (let offset = 0; offset < encoded.byteLength; offset += MAX_FRAGMENT_DECODE_BYTES) {
125
+ const slice = encoded.slice(offset, offset + MAX_FRAGMENT_DECODE_BYTES);
126
+ items.push({ kind: "fragment", eventId: record.event.event_id, index, dataBase64: Buffer.from(slice).toString("base64"), final: offset + slice.byteLength >= encoded.byteLength });
127
+ index += 1;
128
+ }
129
+ }
130
+ const payloads = [];
131
+ let current = { events: [], fragments: [] };
132
+ for (const item of items) {
133
+ const repeatedFragment = item.kind === "fragment" && current.fragments.some((fragment) => fragment.event_id === item.eventId);
134
+ const candidate = appendItem(current, item);
135
+ if (!repeatedFragment && this.nonFinalFrameBytes(request, snapshot, candidate) + tailOverhead <= MAX_HISTORY_CHUNK_BYTES) {
136
+ current = candidate;
137
+ continue;
138
+ }
139
+ if (current.events.length === 0 && current.fragments.length === 0)
140
+ throw new HistoryTooLargeError("history item cannot fit in a 512 KiB chunk");
141
+ payloads.push(current);
142
+ current = appendItem({ events: [], fragments: [] }, item);
143
+ }
144
+ if (current.events.length > 0 || current.fragments.length > 0 || payloads.length === 0)
145
+ payloads.push(current);
146
+ return payloads.map((payload, chunkIndex) => {
147
+ const final = chunkIndex === payloads.length - 1;
148
+ const frame = this.makeChunk(request, snapshot, payload, final, nextBefore, chunkIndex);
149
+ if (getUtf8ByteLengthV2(frame) > MAX_HISTORY_CHUNK_BYTES)
150
+ throw new HistoryTooLargeError("history chunk exceeds 512 KiB");
151
+ encodeServerFrameV2(frame);
152
+ return frame;
153
+ });
154
+ }
155
+ makeChunk(request, snapshot, payload, final, nextBefore, chunkIndex = 0) {
156
+ const tail = final ? nextBefore === undefined ? { final_chunk: true, eos: true } : { final_chunk: true, eos: false, next_before: nextBefore } : { final_chunk: false };
157
+ return { protocol_version: 2, type: "session_history_chunk", target_channel_id: request.targetChannelId, in_reply_to: request.requestId, session_id: snapshot.sessionId, leaf_id: snapshot.leafId, chunk_index: chunkIndex, events: payload.events, fragments: payload.fragments, ...tail };
158
+ }
159
+ nonFinalFrameBytes(request, snapshot, payload) { return getUtf8ByteLengthV2(this.makeChunk(request, snapshot, payload, false, undefined)); }
160
+ finalFrameBytes(request, snapshot, payload, nextBefore) { return getUtf8ByteLengthV2(this.makeChunk(request, snapshot, payload, true, nextBefore)); }
161
+ protocolError(request, code, message) { return { protocol_version: 2, type: "protocol_error", target_channel_id: request.targetChannelId, in_reply_to: request.requestId, code, message }; }
162
+ reset(request, reason) { return { protocol_version: 2, type: "reset", target_channel_id: request.targetChannelId, session_id: this.sessionManager.getSessionId(), leaf_id: this.sessionManager.getLeafId() ?? null, reason }; }
163
+ }
164
+ class HistoryTooLargeError extends Error {
165
+ constructor(message) { super(message); this.name = "HistoryTooLargeError"; }
166
+ }
167
+ function sameIds(left, right) { return left.length === right.length && left.every((id, index) => id === right[index]); }
168
+ function appendItem(payload, item) { if (item.kind === "event")
169
+ return { events: [...payload.events, item.event], fragments: [...payload.fragments] }; return { events: [...payload.events], fragments: [...payload.fragments, { event_id: item.eventId, index: item.index, data_base64: item.dataBase64, final: item.final }] }; }
170
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/timeline/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ /** 按字符上限切分流式增量,不拆开 UTF-16 代理对。 */
2
+ export declare function partialDeltaChunks(delta: string): string[];
@@ -0,0 +1,16 @@
1
+ const MAX_PARTIAL_DELTA_CHARS = 64 * 1024;
2
+ /** 按字符上限切分流式增量,不拆开 UTF-16 代理对。 */
3
+ export function partialDeltaChunks(delta) {
4
+ const chunks = [];
5
+ for (let offset = 0; offset < delta.length;) {
6
+ let end = Math.min(delta.length, offset + MAX_PARTIAL_DELTA_CHARS);
7
+ const finalCodeUnit = delta.charCodeAt(end - 1);
8
+ const nextCodeUnit = delta.charCodeAt(end);
9
+ if (end < delta.length && finalCodeUnit >= 0xD800 && finalCodeUnit <= 0xDBFF && nextCodeUnit >= 0xDC00 && nextCodeUnit <= 0xDFFF)
10
+ end -= 1;
11
+ chunks.push(delta.slice(offset, end));
12
+ offset = end;
13
+ }
14
+ return chunks;
15
+ }
16
+ //# sourceMappingURL=partial_delta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"partial_delta.js","sourceRoot":"","sources":["../../src/timeline/partial_delta.ts"],"names":[],"mappings":"AAAA,MAAM,uBAAuB,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1C,kCAAkC;AAClC,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC;QAC5C,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,CAAC,CAAC;QACnE,MAAM,aAAa,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAChD,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,aAAa,IAAI,MAAM,IAAI,aAAa,IAAI,MAAM,IAAI,YAAY,IAAI,MAAM,IAAI,YAAY,IAAI,MAAM;YAAE,GAAG,IAAI,CAAC,CAAC;QAC3I,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,CAAC;IACf,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type MarkerV2, type TimelineEvent } from "../protocol/v2/index.js";
2
+ export type RunEndStatus = "complete" | "interrupted" | "error";
3
+ export type RunEndMarker = Extract<MarkerV2, {
4
+ kind: "run_end";
5
+ }>;
6
+ /** 以本次运行最后一条 assistant 消息的 stopReason 决定结束状态;没有 assistant 输出即视为被中断。 */
7
+ export declare function runEndStatus(messages: readonly unknown[] | undefined): RunEndStatus;
8
+ export declare function runEndMarker(groupId: string, status: RunEndStatus): RunEndMarker;
9
+ export declare function isRunEndMarker(marker: MarkerV2): marker is RunEndMarker;
10
+ /** run_end 没有对应的 Pi 消息,marker 条目本身就是正式事件,时间取条目写入时间。 */
11
+ export declare function runEndEvent(marker: RunEndMarker, base: {
12
+ event_id: string;
13
+ session_id: string;
14
+ leaf_id: string | null;
15
+ timestamp: number;
16
+ }): TimelineEvent;
@@ -0,0 +1,23 @@
1
+ import { MarkerSchemaV2, TimelineEventSchema } from "../protocol/v2/index.js";
2
+ /** 以本次运行最后一条 assistant 消息的 stopReason 决定结束状态;没有 assistant 输出即视为被中断。 */
3
+ export function runEndStatus(messages) {
4
+ const assistant = [...(messages ?? [])].reverse().find((message) => typeof message === "object" && message !== null && message.role === "assistant");
5
+ if (!assistant)
6
+ return "interrupted";
7
+ if (assistant.stopReason === "error")
8
+ return "error";
9
+ if (assistant.stopReason === "aborted")
10
+ return "interrupted";
11
+ return "complete";
12
+ }
13
+ export function runEndMarker(groupId, status) {
14
+ return MarkerSchemaV2.parse({ version: 2, group_id: groupId, kind: "run_end", status });
15
+ }
16
+ export function isRunEndMarker(marker) {
17
+ return marker.kind === "run_end";
18
+ }
19
+ /** run_end 没有对应的 Pi 消息,marker 条目本身就是正式事件,时间取条目写入时间。 */
20
+ export function runEndEvent(marker, base) {
21
+ return TimelineEventSchema.parse({ ...base, group_id: marker.group_id, kind: "run_end", status: marker.status });
22
+ }
23
+ //# sourceMappingURL=run_end.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run_end.js","sourceRoot":"","sources":["../../src/timeline/run_end.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAqC,MAAM,yBAAyB,CAAC;AAKjH,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,QAAwC;IACnE,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,EAA0D,EAAE,CACzH,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAK,OAA8B,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;IAC3G,IAAI,CAAC,SAAS;QAAE,OAAO,aAAa,CAAC;IACrC,IAAI,SAAS,CAAC,UAAU,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IACrD,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,aAAa,CAAC;IAC7D,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,MAAoB;IAChE,OAAO,cAAc,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAiB,CAAC;AAC1G,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAgB;IAC7C,OAAO,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC;AACnC,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,WAAW,CACzB,MAAoB,EACpB,IAAyF;IAEzF,OAAO,mBAAmB,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AACnH,CAAC"}
@@ -0,0 +1,89 @@
1
+ import type { MessageUpdateEvent, SessionManager, ToolExecutionEndEvent, ToolExecutionStartEvent, ToolExecutionUpdateEvent } from "@earendil-works/pi-coding-agent";
2
+ import { type JsonValue, type TimelineEvent, type TimelinePartial } from "../protocol/v2/index.js";
3
+ export declare const TIMELINE_MARKER: "pi-reach:timeline-v2";
4
+ type MessageRole = "user" | "assistant" | "toolResult";
5
+ export type Correlation = {
6
+ /** 内部投递令牌只在内存回调链中流转,不写入 marker 或协议帧。 */
7
+ deliveryToken?: string;
8
+ clientRequestId?: string;
9
+ channelId?: string;
10
+ requestId?: string;
11
+ origin: "pwa" | "extension" | "unknown";
12
+ delivery: "normal" | "queued" | "unknown";
13
+ senderRef?: string;
14
+ };
15
+ type SessionEntry = ReturnType<SessionManager["getBranch"]>[number];
16
+ export type TimelineStarted = {
17
+ eventId: string;
18
+ groupId: string;
19
+ role: MessageRole;
20
+ correlation: Correlation;
21
+ blocks: JsonValue[];
22
+ };
23
+ export type TimelineRuntimeOptions = {
24
+ onStarted?: (started: TimelineStarted) => void;
25
+ onPublished?: (event: TimelineEvent, correlation: Correlation) => void;
26
+ onPartial?: (partial: TimelinePartial, correlation: Correlation) => void;
27
+ };
28
+ export declare class TimelineRuntime {
29
+ private readonly correlations;
30
+ private readonly messageCorrelations;
31
+ private readonly pending;
32
+ private readonly pendingByRole;
33
+ private readonly published;
34
+ private readonly toolAssociations;
35
+ private sessionManager;
36
+ private epoch;
37
+ private stateRevision;
38
+ private activeGroupId;
39
+ private active;
40
+ private readonly onStarted?;
41
+ private readonly onPublished?;
42
+ private readonly onPartial?;
43
+ constructor(options?: TimelineRuntimeOptions);
44
+ attach(sessionManager: SessionManager): void;
45
+ resetSession(sessionManager: SessionManager): void;
46
+ private resetState;
47
+ get sessionId(): string | null;
48
+ get leafId(): string | null;
49
+ get currentEpoch(): number;
50
+ get currentGroupId(): string | null;
51
+ getPublishedEvents(): readonly TimelineEvent[];
52
+ getCorrelation(message: object): Correlation | undefined;
53
+ publishSessionEntry(entry: SessionEntry, sessionManager: SessionManager): TimelineEvent | null;
54
+ runWithCorrelation<T>(correlation: Correlation, callback: () => T): T;
55
+ currentCorrelation(): Correlation | undefined;
56
+ onAgentStart(): void;
57
+ /** 为本次运行的组写入 run_end marker,并在同组正式消息发布之后推送。 */
58
+ onAgentEnd(messages?: readonly unknown[]): void;
59
+ onMessageStart(message: unknown, sessionManager: SessionManager): TimelineStarted | null;
60
+ onMessageUpdate(event: MessageUpdateEvent, sessionManager: SessionManager): void;
61
+ onMessageEnd(message: unknown, sessionManager: SessionManager): void;
62
+ private publishWhenVisible;
63
+ onToolExecutionStart(event: ToolExecutionStartEvent, sessionManager: SessionManager): void;
64
+ onToolExecutionUpdate(event: ToolExecutionUpdateEvent, sessionManager: SessionManager): void;
65
+ onToolExecutionEnd(event: ToolExecutionEndEvent, sessionManager: SessionManager): void;
66
+ private publishToolPartial;
67
+ recover(sessionManager: SessionManager): TimelineEvent[];
68
+ private findPending;
69
+ private messageIdentity;
70
+ private publish;
71
+ private publishPartial;
72
+ private correlationFor;
73
+ private buildMarker;
74
+ private parseMarker;
75
+ private correlationFromMarker;
76
+ private roleForMarker;
77
+ private scanTargetAfterMarker;
78
+ private toTimelineEvent;
79
+ private toSystemEvent;
80
+ private asMessageRecord;
81
+ private messageRole;
82
+ private timestamp;
83
+ private userBlocks;
84
+ private assistantBlocks;
85
+ private textFromContent;
86
+ private nonEmpty;
87
+ private base64Length;
88
+ }
89
+ export {};