@xopcai/xopc 0.0.206 → 0.0.207

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 (170) hide show
  1. package/README.md +7 -7
  2. package/README.zh-CN.md +7 -7
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/{activity-store-URW-e_me.js → activity-store-BmpM0zwM.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BLK6kRCJ.js → agent-avatar-dicebear-DhK5wi6_.js} +1 -1
  7. package/dist/gateway/static/root/assets/agents-Bc3Lc-n2.js +68 -0
  8. package/dist/gateway/static/root/assets/{api-C_MS4arC.js → api-CzaAcDOn.js} +1 -1
  9. package/dist/gateway/static/root/assets/{app-management-settings-panel-CnUN6BJk.js → app-management-settings-panel-Dqj5G_cd.js} +1 -1
  10. package/dist/gateway/static/root/assets/{appearance-settings-C8Nx8hZE.js → appearance-settings-Bm1uLGMi.js} +1 -1
  11. package/dist/gateway/static/root/assets/apps-page-BKtwU47-.js +1 -0
  12. package/dist/gateway/static/root/assets/{archive-plugin-C7FqeJZD.js → archive-plugin-CgnzBplN.js} +1 -1
  13. package/dist/gateway/static/root/assets/{attachment-load-DCYQgsYE.js → attachment-load-Cuybcmhn.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-page-ilGeRLDN.js +6 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-Bf1WROsh.js → binary-plugins-D6BBx6Ps.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-BPK08Pjv.js → block-editor-Dk1c3Spa.js} +3 -3
  17. package/dist/gateway/static/root/assets/browser-settings-page-BCu8AZbs.js +8 -0
  18. package/dist/gateway/static/root/assets/{browser-workflow-inputs-cqVoDHyp.js → browser-workflow-inputs-DvfIzCgV.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-workflows-page-Des1UTsS.js → browser-workflows-page-DZScuPlF.js} +2 -2
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel-BbWQBtTe.js +7 -0
  21. package/dist/gateway/static/root/assets/{capability-presets-api-D4MjqV2a.js → capability-presets-api-hoA8R_J1.js} +1 -1
  22. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BTVU46Yn.js +3 -0
  23. package/dist/gateway/static/root/assets/{channel-recipient-api-CcimZduy.js → channel-recipient-api-BS8I65NT.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-settings-BEQsC9a9.js +1 -0
  25. package/dist/gateway/static/root/assets/channels-status-swr-DRwbgtOT.js +1 -0
  26. package/dist/gateway/static/root/assets/chat-terminal-dock-BIPhWBDI.js +36 -0
  27. package/dist/gateway/static/root/assets/{chat-terminal-dock-B1njb2Cr.css → chat-terminal-dock-uQUnjRtf.css} +1 -1
  28. package/dist/gateway/static/root/assets/{connectors-api-CUvFu8jh.js → connectors-api-B_78jmvM.js} +1 -1
  29. package/dist/gateway/static/root/assets/{connectors-page-BJoHjWnu.js → connectors-page-w_3kpqbc.js} +2 -2
  30. package/dist/gateway/static/root/assets/{cron-expression-hFSZZpvM.js → cron-expression-BBheaBIr.js} +1 -1
  31. package/dist/gateway/static/root/assets/{date-picker-CKZ0gc-Y.js → date-picker-CDwj7UrT.js} +1 -1
  32. package/dist/gateway/static/root/assets/{dependency-picker-zv1oHtg4.js → dependency-picker-Dnrc2qZe.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-DY9ykMtD.js → desktop-pet-Bj_vUjXp.js} +1 -1
  34. package/dist/gateway/static/root/assets/{desktop-pet-settings-XiSmmt26.js → desktop-pet-settings-uiCwJJk4.js} +1 -1
  35. package/dist/gateway/static/root/assets/{directory-picker-path-field-CZkgk15r.js → directory-picker-path-field-D0zUQ-TO.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-debug-page-CTppsTEi.js → extension-debug-page-_GZ4y2da.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-page-CHRTUvAa.js → extension-page-scR96Edg.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-settings-page-z2UBx25A.js → extension-settings-page-CILsAwxx.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-config-api-DzFPJTnm.js → gateway-config-api-984O_4wM.js} +1 -1
  40. package/dist/gateway/static/root/assets/{gateway-config-swr-CGpoH1gU.js → gateway-config-swr-D4hvsdJA.js} +1 -1
  41. package/dist/gateway/static/root/assets/{gateway-settings-DBa2I6VM.js → gateway-settings-aF4eQHo3.js} +1 -1
  42. package/dist/gateway/static/root/assets/{gateway-startup-retry-Te-TREBt.js → gateway-startup-retry-Deo5-O87.js} +1 -1
  43. package/dist/gateway/static/root/assets/{heartbeat-settings-DyQGGdBu.js → heartbeat-settings-D5DrFWH6.js} +1 -1
  44. package/dist/gateway/static/root/assets/{home-page-EkT4eGeP.js → home-page-DiMWxngC.js} +2 -2
  45. package/dist/gateway/static/root/assets/{index-CrwXzRpA.js → index-DzKLVgY-.js} +47 -47
  46. package/dist/gateway/static/root/assets/index-wR5jX-lw.css +2 -0
  47. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-fb0zS8pk.js → keyboard-shortcuts-settings-DGmOlNcB.js} +1 -1
  48. package/dist/gateway/static/root/assets/local-app-workbench-page-De8vuwu1.js +2 -0
  49. package/dist/gateway/static/root/assets/{local-apps-page-DFdheruU.js → local-apps-page-CzS2sCxg.js} +1 -1
  50. package/dist/gateway/static/root/assets/{locale-store-CieddUjx.js → locale-store-C7xtkP3D.js} +1 -1
  51. package/dist/gateway/static/root/assets/logs-page-BI9stsVO.js +2 -0
  52. package/dist/gateway/static/root/assets/{management-settings-D3PsQ612.js → management-settings-Cpxs43JB.js} +1 -1
  53. package/dist/gateway/static/root/assets/{markdown-split-x5K52Thz.js → markdown-split-CQvFHxUa.js} +1 -1
  54. package/dist/gateway/static/root/assets/{markdown-view-Cjjey5Y6.js → markdown-view-BRwrSbwM.js} +1 -1
  55. package/dist/gateway/static/root/assets/{media-plugins-DNtEkRAh.js → media-plugins-Bs9MsiaM.js} +1 -1
  56. package/dist/gateway/static/root/assets/messages-Dxk5Rzj_.js +3 -0
  57. package/dist/gateway/static/root/assets/{notes-page-nWEqlwDw.js → notes-page-Dux_g6aZ.js} +1 -1
  58. package/dist/gateway/static/root/assets/notes-workbench-CGafcgJ8.js +4 -0
  59. package/dist/gateway/static/root/assets/{preview-open-alternatives-CXcIKVi9.js → preview-open-alternatives-fvhtN4Y2.js} +1 -1
  60. package/dist/gateway/static/root/assets/{product-open-page-CZLJudPk.js → product-open-page-f_jbg-9N.js} +1 -1
  61. package/dist/gateway/static/root/assets/{project-detail-page-Cf1v94LO.js → project-detail-page-C6mNsjYr.js} +1 -1
  62. package/dist/gateway/static/root/assets/{projects-page-BRMZkNht.js → projects-page-D1G6VIxR.js} +1 -1
  63. package/dist/gateway/static/root/assets/remote-access-hub-CIez6X0x.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-RYjduQV6.js → runtime-tools-settings-panel-zapSiJrv.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schema-form--1ZXg4qC.js → schema-form-CFyz8y5v.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-6irxQjHb.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-CRb0QTG2.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-71-8j3zt.js → settings-form-section-DCiK4TIq.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-C5Jn1l0q.js → settings-loading-skeleton-DFUJEv4G.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-TYYGe6kZ.js → settings-page-Cnp9Bdd0.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-jA5I-17g.js → setup-status-panel-BFMGTGBO.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-BMUQIGfk.js → share-preview-page-DA8nA4cz.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-CaKfvJzQ.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-BOBUcYr5.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-BzZT1SKg.js → skills-page-BJJACxzz.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-DnaBw5Ji.js → skills-page.utils--1-vOg3V.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-DqiPQgVI.js → system-settings-panel-DY0lIaXY.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-Ciuwe7AG.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-BP3_RpaY.js → theme-store-DoyRfkoi.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-BJkQ-vpu.js → use-autosave-DzIR5Lxf.js} +1 -1
  81. package/dist/gateway/static/root/assets/{user-context-page-BP8-sOPi.js → user-context-page-yf18T_BZ.js} +1 -1
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-C6c8e7Mx.js → voice-api-key-field-B7MZS8tS.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-CCNjWKql.js → work-discovery-overlay-zyX6yxxF.js} +1 -1
  84. package/dist/gateway/static/root/assets/work-discovery-page-2e5J0sIp.js +1 -0
  85. package/dist/gateway/static/root/assets/workflow-run-setup-panel-Cj1vPWRM.js +3 -0
  86. package/dist/gateway/static/root/assets/workflows-page-D37zWlWY.js +5 -0
  87. package/dist/gateway/static/root/assets/{working-directory-picker-modal-vWi33CZJ.js → working-directory-picker-modal-Bm7cox3y.js} +1 -1
  88. package/dist/gateway/static/root/index.html +10 -10
  89. package/dist/package.js +1 -1
  90. package/dist/src/agent/embedded/transcript-runtime.d.ts +2 -1
  91. package/dist/src/agent/embedded/transcript-runtime.js +38 -4
  92. package/dist/src/agent/inbound/inbound-loop.d.ts +1 -1
  93. package/dist/src/agent/memory/compaction-ledger.d.ts +11 -0
  94. package/dist/src/agent/memory/compaction-ledger.js +108 -0
  95. package/dist/src/agent/memory/compaction-serializer.d.ts +2 -0
  96. package/dist/src/agent/memory/compaction-serializer.js +52 -0
  97. package/dist/src/agent/memory/compaction-source-planner.d.ts +20 -0
  98. package/dist/src/agent/memory/compaction-source-planner.js +67 -0
  99. package/dist/src/agent/memory/compaction.d.ts +11 -5
  100. package/dist/src/agent/memory/compaction.js +245 -153
  101. package/dist/src/agent/prompt/sections/behavior.js +1 -1
  102. package/dist/src/agent/prompt/sections/memory-skills.js +4 -2
  103. package/dist/src/agent/prompt/sections/tooling.js +2 -0
  104. package/dist/src/agent/tool-manuals/xopc-use.d.ts +1 -1
  105. package/dist/src/agent/tool-manuals/xopc-use.js +1 -1
  106. package/dist/src/agent/tools/factory.js +5 -0
  107. package/dist/src/agent/tools/index.d.ts +1 -0
  108. package/dist/src/agent/tools/index.js +2 -1
  109. package/dist/src/agent/tools/session-recall-tool.d.ts +7 -0
  110. package/dist/src/agent/tools/session-recall-tool.js +82 -0
  111. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  112. package/dist/src/config/agent-profile.js +1 -1
  113. package/dist/src/config/schema.d.ts +1 -0
  114. package/dist/src/gateway/agents-admin.js +1 -1
  115. package/dist/src/gateway/heartbeat/service.js +1 -1
  116. package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
  117. package/dist/src/gateway/service/run-gateway-agent.js +3 -3
  118. package/dist/src/heartbeat/index.js +1 -1
  119. package/dist/src/session/compaction-types.d.ts +30 -0
  120. package/dist/src/session/compaction-types.js +35 -0
  121. package/dist/src/session/manager.d.ts +3 -0
  122. package/dist/src/session/session-context-for-llm.d.ts +4 -2
  123. package/dist/src/session/session-context-for-llm.js +2 -1
  124. package/dist/src/session/store.d.ts +10 -1
  125. package/dist/src/session/store.js +55 -23
  126. package/dist/src/session/types.d.ts +3 -2
  127. package/dist/src/storage/sqlite/index.d.ts +1 -1
  128. package/dist/src/storage/sqlite/index.js +2 -2
  129. package/dist/src/storage/sqlite/migrations/123_remove_v2_compaction_boundaries.sql +25 -0
  130. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  131. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  132. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  133. package/dist/src/storage/sqlite/schema.js +1 -1
  134. package/dist/src/storage/sqlite/transcript-repository.d.ts +24 -1
  135. package/dist/src/storage/sqlite/transcript-repository.js +78 -29
  136. package/dist/src/user-context/config.d.ts +4 -0
  137. package/dist/src/user-context/config.js +2 -0
  138. package/package.json +3 -3
  139. package/skills/THIRD_PARTY_NOTICES.md +1 -1
  140. package/skills/engineering/define-task/SKILL.md +48 -0
  141. package/skills/engineering/define-task/references/task-contract-rubric.md +15 -0
  142. package/dist/gateway/static/root/assets/agents-D5HVmdNx.js +0 -68
  143. package/dist/gateway/static/root/assets/apps-page-DKCA_LFY.js +0 -1
  144. package/dist/gateway/static/root/assets/automations-page-BEOE4ZKM.js +0 -6
  145. package/dist/gateway/static/root/assets/browser-settings-page-CLRmMdU9.js +0 -8
  146. package/dist/gateway/static/root/assets/capabilities-settings-panel-BNcVi4ar.js +0 -7
  147. package/dist/gateway/static/root/assets/capability-presets-settings-panel-uFwW2ah5.js +0 -3
  148. package/dist/gateway/static/root/assets/channels-settings-DSLP8OjS.js +0 -1
  149. package/dist/gateway/static/root/assets/channels-status-swr-D0OR6Ylw.js +0 -1
  150. package/dist/gateway/static/root/assets/chat-terminal-dock-wpi7abPg.js +0 -38
  151. package/dist/gateway/static/root/assets/index-BpLqHdfz.css +0 -2
  152. package/dist/gateway/static/root/assets/local-app-workbench-page-CCC3Cvb8.js +0 -2
  153. package/dist/gateway/static/root/assets/logs-page-B6jfkNDF.js +0 -2
  154. package/dist/gateway/static/root/assets/messages-CySMn8WL.js +0 -3
  155. package/dist/gateway/static/root/assets/notes-workbench-QstkgWsW.js +0 -4
  156. package/dist/gateway/static/root/assets/remote-access-hub-D55FTXZw.js +0 -1
  157. package/dist/gateway/static/root/assets/sessions-page-C5Yy6eIn.js +0 -1
  158. package/dist/gateway/static/root/assets/settings-advanced-gate-BqO_8bUh.js +0 -1
  159. package/dist/gateway/static/root/assets/shares-settings-Dru1a2rZ.js +0 -1
  160. package/dist/gateway/static/root/assets/skill-reload-api-C8iqS6kF.js +0 -1
  161. package/dist/gateway/static/root/assets/task-detail-page-DQP5vDr-.js +0 -1
  162. package/dist/gateway/static/root/assets/work-discovery-page-DL_Ie0s2.js +0 -1
  163. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DLO-dMSN.js +0 -3
  164. package/dist/gateway/static/root/assets/workflows-page-B4-k2FHB.js +0 -5
  165. package/dist/src/agent/memory/compaction-planner.d.ts +0 -16
  166. package/dist/src/agent/memory/compaction-planner.js +0 -168
  167. package/dist/src/agent/memory/summary-generator.d.ts +0 -46
  168. package/dist/src/agent/memory/summary-generator.js +0 -229
  169. package/skills/engineering/define-goal/SKILL.md +0 -41
  170. package/skills/engineering/define-goal/references/objective-rubric.md +0 -12
@@ -0,0 +1,108 @@
1
+ import { HANDOVER_ITEM_KINDS } from "../../session/compaction-types.js";
2
+ import { createHash } from "node:crypto";
3
+ import { z } from "zod";
4
+ //#region src/agent/memory/compaction-ledger.ts
5
+ const RawHandoverItemSchema = z.object({
6
+ kind: z.enum(HANDOVER_ITEM_KINDS),
7
+ text: z.string().min(1),
8
+ status: z.enum([
9
+ "active",
10
+ "completed",
11
+ "superseded"
12
+ ]),
13
+ sourceSeqs: z.array(z.number().int().positive()).min(1),
14
+ identifiers: z.array(z.string()).default([])
15
+ }).strict();
16
+ const RawHandoverSchema = z.object({ items: z.array(RawHandoverItemSchema).max(120) }).strict();
17
+ function extractJsonObject(text) {
18
+ const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1]?.trim();
19
+ if (fenced) return fenced;
20
+ const start = text.indexOf("{");
21
+ const end = text.lastIndexOf("}");
22
+ if (start < 0 || end <= start) throw new Error("Compaction model did not return a JSON object");
23
+ return text.slice(start, end + 1);
24
+ }
25
+ function itemId(kind, text, seqs) {
26
+ return createHash("sha256").update(`${kind}\0${text.trim()}\0${[...seqs].sort((a, b) => a - b).join(",")}`).digest("hex").slice(0, 20);
27
+ }
28
+ function parseCompactionHandover(params) {
29
+ const parsed = RawHandoverSchema.parse(JSON.parse(extractJsonObject(params.text)));
30
+ const sourceBySeq = new Map(params.allowedSources.map((source) => [source.seq, source]));
31
+ const items = parsed.items.map((item) => {
32
+ const seqs = [...new Set(item.sourceSeqs)].sort((a, b) => a - b);
33
+ const sources = seqs.map((seq) => {
34
+ const source = sourceBySeq.get(seq);
35
+ if (!source || seq > params.sourceThroughSeq) throw new Error(`Compaction handover references unavailable source seq ${seq}`);
36
+ return {
37
+ entryId: source.entryId,
38
+ seq
39
+ };
40
+ });
41
+ const text = item.text.trim();
42
+ return {
43
+ id: itemId(item.kind, text, seqs),
44
+ kind: item.kind,
45
+ text,
46
+ status: item.status,
47
+ sources,
48
+ identifiers: [...new Set(item.identifiers.map((value) => value.trim()).filter(Boolean))]
49
+ };
50
+ });
51
+ return {
52
+ version: 1,
53
+ sourceThroughSeq: params.sourceThroughSeq,
54
+ ...params.previousBoundaryId ? { previousBoundaryId: params.previousBoundaryId } : {},
55
+ items: [...new Map(items.map((item) => [item.id, item])).values()]
56
+ };
57
+ }
58
+ const SUMMARY_GROUPS = [
59
+ {
60
+ heading: "Decisions",
61
+ kinds: ["objective", "decision"]
62
+ },
63
+ {
64
+ heading: "Pending user asks",
65
+ kinds: ["pending_user_ask"]
66
+ },
67
+ {
68
+ heading: "Open TODOs",
69
+ kinds: ["todo", "next_action"]
70
+ },
71
+ {
72
+ heading: "Constraints and rules",
73
+ kinds: ["constraint"]
74
+ },
75
+ {
76
+ heading: "Tool operations and results",
77
+ kinds: [
78
+ "file_change",
79
+ "tool_outcome",
80
+ "failure"
81
+ ]
82
+ },
83
+ {
84
+ heading: "Recent state",
85
+ kinds: ["current_state"]
86
+ }
87
+ ];
88
+ function renderCompactionHandover(handover) {
89
+ const active = handover.items.filter((item) => item.status === "active");
90
+ const sections = SUMMARY_GROUPS.map(({ heading, kinds }) => {
91
+ const items = active.filter((item) => kinds.includes(item.kind));
92
+ return `## ${heading}\n${items.length > 0 ? items.map((item) => `- ${item.text}`).join("\n") : "None"}`;
93
+ });
94
+ const identifiers = [...new Set(active.flatMap((item) => item.identifiers))];
95
+ sections.splice(4, 0, `## Exact identifiers\n${identifiers.length > 0 ? identifiers.map((value) => `- \`${value}\``).join("\n") : "None"}`);
96
+ return sections.join("\n\n");
97
+ }
98
+ function handoverForPrompt(handover) {
99
+ return { items: handover?.items.map((item) => ({
100
+ kind: item.kind,
101
+ text: item.text,
102
+ status: item.status,
103
+ sourceSeqs: item.sources.map((source) => source.seq),
104
+ identifiers: item.identifiers
105
+ })) ?? [] };
106
+ }
107
+ //#endregion
108
+ export { handoverForPrompt, parseCompactionHandover, renderCompactionHandover };
@@ -0,0 +1,2 @@
1
+ import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
+ export declare function serializeMessageForCompaction(message: AgentMessage): string;
@@ -0,0 +1,52 @@
1
+ import { readAgentMessageContent } from "./agent-message-access.js";
2
+ //#region src/agent/memory/compaction-serializer.ts
3
+ function safeJson(value) {
4
+ try {
5
+ return JSON.stringify(value);
6
+ } catch {
7
+ return String(value);
8
+ }
9
+ }
10
+ function valueRecord(value) {
11
+ return value && typeof value === "object" ? value : void 0;
12
+ }
13
+ function serializeContentBlock(block) {
14
+ const record = valueRecord(block);
15
+ if (!record) return safeJson(block);
16
+ const type = String(record.type ?? "unknown");
17
+ if (type === "text") return String(record.text ?? "");
18
+ if (type === "toolCall") return [
19
+ "[Tool call]",
20
+ `name: ${String(record.name ?? "unknown")}`,
21
+ `id: ${String(record.id ?? record.toolCallId ?? "unknown")}`,
22
+ `arguments: ${safeJson(record.arguments ?? record.args ?? {})}`
23
+ ].join("\n");
24
+ if (type === "image" || type === "audio" || type === "video" || type === "file") {
25
+ const metadata = { ...record };
26
+ delete metadata.data;
27
+ delete metadata.bytes;
28
+ delete metadata.base64;
29
+ return `[${type} content]\nmetadata: ${safeJson(metadata)}`;
30
+ }
31
+ if (type === "thinking" || type === "reasoning" || type === "reasoning_details") return "[Assistant private reasoning omitted from compaction input]";
32
+ return `[${type} block]\n${safeJson(record)}`;
33
+ }
34
+ function serializeMessageForCompaction(message) {
35
+ const record = message;
36
+ const raw = readAgentMessageContent(message);
37
+ const content = typeof raw === "string" ? raw : Array.isArray(raw) ? raw.map(serializeContentBlock).filter(Boolean).join("\n\n") : safeJson(raw);
38
+ const metadata = [];
39
+ if (message.role === "toolResult") {
40
+ metadata.push(`tool: ${String(record.toolName ?? "unknown")}`);
41
+ metadata.push(`toolCallId: ${String(record.toolCallId ?? "unknown")}`);
42
+ metadata.push(`status: ${record.isError === true ? "error" : "success"}`);
43
+ if (record.details != null) metadata.push(`details: ${safeJson(record.details)}`);
44
+ }
45
+ return [
46
+ `### ${message.role}`,
47
+ ...metadata,
48
+ content
49
+ ].filter(Boolean).join("\n");
50
+ }
51
+ //#endregion
52
+ export { serializeMessageForCompaction };
@@ -0,0 +1,20 @@
1
+ import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
+ import type { TranscriptSourceEntry } from '../../storage/sqlite/transcript-repository.js';
3
+ export interface CompactionSourcePlan {
4
+ sourceEntries: TranscriptSourceEntry[];
5
+ keptEntries: TranscriptSourceEntry[];
6
+ keptMessages: AgentMessage[];
7
+ allMessages: AgentMessage[];
8
+ sourceThroughSeq: number;
9
+ }
10
+ export declare function planCompactionSource(params: {
11
+ entries: readonly TranscriptSourceEntry[];
12
+ minMessagesBeforeCompact: number;
13
+ recentTurnsPreserve: number;
14
+ keepRecentTokens: number;
15
+ force: boolean;
16
+ }): CompactionSourcePlan | null;
17
+ export declare function estimateCompactionSourceTokens(plan: CompactionSourcePlan): {
18
+ before: number;
19
+ kept: number;
20
+ };
@@ -0,0 +1,67 @@
1
+ import { buildSessionContextForLlm, isRuntimeOnlyTranscriptMessage, isTranscriptCompactionEntry, isTranscriptContextEntry, isTranscriptCustomMessageEntry, isTranscriptCustomStateEntry, isTranscriptLabelEntry, isTranscriptMetadataEntry, isTranscriptSummaryMessageEntry } from "../../session/session-context-for-llm.js";
2
+ import { estimateMessagesTokens, estimateTextTokens } from "./context-budget.js";
3
+ //#region src/agent/memory/compaction-source-planner.ts
4
+ function isModelSource(entry) {
5
+ const row = entry.row;
6
+ return !isTranscriptCompactionEntry(row) && !isTranscriptContextEntry(row) && !isTranscriptCustomStateEntry(row) && !isTranscriptSummaryMessageEntry(row) && !isTranscriptLabelEntry(row) && !isTranscriptMetadataEntry(row) && !isRuntimeOnlyTranscriptMessage(row);
7
+ }
8
+ function isTurnStart(entry) {
9
+ return entry.row.role === "user" || isTranscriptCustomMessageEntry(entry.row);
10
+ }
11
+ function estimateEntryTokens(entry) {
12
+ try {
13
+ return estimateTextTokens(JSON.stringify(entry.row)) + 12;
14
+ } catch {
15
+ return 12;
16
+ }
17
+ }
18
+ function findNthTurnFromEnd(entries, count) {
19
+ let found = 0;
20
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
21
+ if (!isTurnStart(entries[index])) continue;
22
+ found += 1;
23
+ if (found === count) return index;
24
+ }
25
+ return 0;
26
+ }
27
+ function findTurnAtOrBefore(entries, start) {
28
+ for (let index = Math.min(start, entries.length - 1); index >= 0; index -= 1) if (isTurnStart(entries[index])) return index;
29
+ return 0;
30
+ }
31
+ function findRecentTokenBoundary(entries, keepRecentTokens) {
32
+ let tokens = 0;
33
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
34
+ tokens += estimateEntryTokens(entries[index]);
35
+ if (tokens >= keepRecentTokens) return findTurnAtOrBefore(entries, index);
36
+ }
37
+ return 0;
38
+ }
39
+ function planCompactionSource(params) {
40
+ const rawEntries = params.entries.filter(isModelSource);
41
+ const allMessages = buildSessionContextForLlm(rawEntries.map((entry) => entry.row));
42
+ if (!params.force && allMessages.length < params.minMessagesBeforeCompact || params.force && allMessages.length < 2) return null;
43
+ const turnBoundary = findNthTurnFromEnd(rawEntries, params.recentTurnsPreserve);
44
+ const tokenBoundary = findRecentTokenBoundary(rawEntries, params.keepRecentTokens);
45
+ let splitAt = Math.min(turnBoundary, tokenBoundary);
46
+ if (splitAt <= 0 && params.force) splitAt = findNthTurnFromEnd(rawEntries, 1);
47
+ if (splitAt <= 0) return null;
48
+ const sourceEntries = rawEntries.slice(0, splitAt);
49
+ const keptEntries = rawEntries.slice(splitAt);
50
+ const keptMessages = buildSessionContextForLlm(keptEntries.map((entry) => entry.row));
51
+ if (sourceEntries.length === 0 || keptMessages.length === 0) return null;
52
+ return {
53
+ sourceEntries,
54
+ keptEntries,
55
+ keptMessages,
56
+ allMessages,
57
+ sourceThroughSeq: sourceEntries.at(-1).seq
58
+ };
59
+ }
60
+ function estimateCompactionSourceTokens(plan) {
61
+ return {
62
+ before: estimateMessagesTokens(plan.allMessages),
63
+ kept: estimateMessagesTokens(plan.keptMessages)
64
+ };
65
+ }
66
+ //#endregion
67
+ export { estimateCompactionSourceTokens, planCompactionSource };
@@ -1,14 +1,19 @@
1
1
  import type { AgentMessage } from '@earendil-works/pi-agent-core';
2
2
  import { type Api, type Model } from '@earendil-works/pi-ai/compat';
3
+ import type { CompactionAudit, CompactionHandover } from '../../session/compaction-types.js';
4
+ import type { TranscriptSourceEntry } from '../../storage/sqlite/transcript-repository.js';
3
5
  export interface CompactionResult {
4
6
  summary: string;
7
+ messages: AgentMessage[];
5
8
  firstKeptIndex: number;
6
9
  tokensBefore: number;
7
10
  tokensAfter: number;
8
11
  compacted: boolean;
9
- plannerVersion?: number;
12
+ plannerVersion?: 3;
10
13
  summaryModelRef?: string;
11
14
  qualityAudit?: 'passed' | 'disabled';
15
+ handover?: CompactionHandover;
16
+ audit?: CompactionAudit;
12
17
  compactedUsage?: {
13
18
  input: number;
14
19
  output: number;
@@ -27,6 +32,7 @@ export interface CompactionConfig {
27
32
  summaryTimeoutMs: number;
28
33
  summaryRetries: number;
29
34
  qualityGuard: boolean;
35
+ gapAudit: boolean;
30
36
  accumulateUsage: boolean;
31
37
  }
32
38
  export interface CompactionExecutionOptions {
@@ -45,10 +51,10 @@ export declare class SessionCompactor {
45
51
  private readonly config;
46
52
  constructor(config?: Partial<CompactionConfig>);
47
53
  getConfig(): Readonly<CompactionConfig>;
48
- compact(messages: AgentMessage[], model: Model<Api>, instructions?: string, force?: boolean, options?: CompactionExecutionOptions): Promise<CompactionResult>;
49
- private generateSummary;
50
- private callSummaryModels;
51
- applyCompaction(messages: AgentMessage[], result: CompactionResult): AgentMessage[];
54
+ compact(entries: readonly TranscriptSourceEntry[], model: Model<Api>, instructions?: string, force?: boolean, options?: CompactionExecutionOptions): Promise<CompactionResult>;
52
55
  estimateTotalTokens(messages: AgentMessage[]): number;
56
+ private generateHandover;
57
+ private auditHandover;
58
+ private callHandoverModels;
53
59
  }
54
60
  export {};