pi-para 0.6.0 → 0.6.1

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 (208) hide show
  1. package/ARCHITECTURE.md +0 -9
  2. package/CHANGELOG.md +13 -0
  3. package/CONFIGURATION.md +0 -23
  4. package/README.md +1 -29
  5. package/SETUP.md +1 -1
  6. package/STRUCTURE.md +0 -9
  7. package/dist/atomic-write.d.ts +2 -0
  8. package/dist/atomic-write.d.ts.map +1 -0
  9. package/dist/atomic-write.js +18 -0
  10. package/dist/atomic-write.js.map +1 -0
  11. package/dist/capture.d.ts +34 -0
  12. package/dist/capture.d.ts.map +1 -0
  13. package/dist/capture.js +461 -0
  14. package/dist/capture.js.map +1 -0
  15. package/dist/cli-legacy.d.ts +4 -0
  16. package/dist/cli-legacy.d.ts.map +1 -0
  17. package/dist/cli-legacy.js +41 -0
  18. package/dist/cli-legacy.js.map +1 -0
  19. package/dist/cli.d.ts +8 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +427 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/commands.d.ts +15 -0
  24. package/dist/commands.d.ts.map +1 -0
  25. package/dist/commands.js +719 -0
  26. package/dist/commands.js.map +1 -0
  27. package/dist/config.d.ts +94 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +228 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/context.d.ts +63 -0
  32. package/dist/context.d.ts.map +1 -0
  33. package/dist/context.js +311 -0
  34. package/dist/context.js.map +1 -0
  35. package/dist/credentials.d.ts +27 -0
  36. package/dist/credentials.d.ts.map +1 -0
  37. package/dist/credentials.js +85 -0
  38. package/dist/credentials.js.map +1 -0
  39. package/dist/daemon.d.ts +49 -0
  40. package/dist/daemon.d.ts.map +1 -0
  41. package/dist/daemon.js +226 -0
  42. package/dist/daemon.js.map +1 -0
  43. package/dist/doctor.d.ts +20 -0
  44. package/dist/doctor.d.ts.map +1 -0
  45. package/dist/doctor.js +176 -0
  46. package/dist/doctor.js.map +1 -0
  47. package/dist/frontmatter.d.ts +59 -0
  48. package/dist/frontmatter.d.ts.map +1 -0
  49. package/dist/frontmatter.js +170 -0
  50. package/dist/frontmatter.js.map +1 -0
  51. package/dist/index.d.ts +21 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +342 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/ingest.d.ts +88 -0
  56. package/dist/ingest.d.ts.map +1 -0
  57. package/dist/ingest.js +105 -0
  58. package/dist/ingest.js.map +1 -0
  59. package/dist/link-discovery.d.ts +40 -0
  60. package/dist/link-discovery.d.ts.map +1 -0
  61. package/dist/link-discovery.js +122 -0
  62. package/dist/link-discovery.js.map +1 -0
  63. package/dist/link-utils.d.ts +30 -0
  64. package/dist/link-utils.d.ts.map +1 -0
  65. package/dist/link-utils.js +145 -0
  66. package/dist/link-utils.js.map +1 -0
  67. package/dist/lint.d.ts +39 -0
  68. package/dist/lint.d.ts.map +1 -0
  69. package/dist/lint.js +827 -0
  70. package/dist/lint.js.map +1 -0
  71. package/dist/maintainer.d.ts +24 -0
  72. package/dist/maintainer.d.ts.map +1 -0
  73. package/dist/maintainer.js +358 -0
  74. package/dist/maintainer.js.map +1 -0
  75. package/dist/model-resolver.d.ts +30 -0
  76. package/dist/model-resolver.d.ts.map +1 -0
  77. package/dist/model-resolver.js +71 -0
  78. package/dist/model-resolver.js.map +1 -0
  79. package/dist/paths.d.ts +20 -0
  80. package/dist/paths.d.ts.map +1 -0
  81. package/dist/paths.js +33 -0
  82. package/dist/paths.js.map +1 -0
  83. package/dist/processor.d.ts +14 -0
  84. package/dist/processor.d.ts.map +1 -0
  85. package/dist/processor.js +361 -0
  86. package/dist/processor.js.map +1 -0
  87. package/dist/qmd-providers.d.ts +12 -0
  88. package/dist/qmd-providers.d.ts.map +1 -0
  89. package/dist/qmd-providers.js +45 -0
  90. package/dist/qmd-providers.js.map +1 -0
  91. package/dist/query.d.ts +69 -0
  92. package/dist/query.d.ts.map +1 -0
  93. package/dist/query.js +120 -0
  94. package/dist/query.js.map +1 -0
  95. package/dist/raw.d.ts +57 -0
  96. package/dist/raw.d.ts.map +1 -0
  97. package/dist/raw.js +219 -0
  98. package/dist/raw.js.map +1 -0
  99. package/dist/redact.d.ts +21 -0
  100. package/dist/redact.d.ts.map +1 -0
  101. package/dist/redact.js +143 -0
  102. package/dist/redact.js.map +1 -0
  103. package/dist/repair.d.ts +11 -0
  104. package/dist/repair.d.ts.map +1 -0
  105. package/dist/repair.js +41 -0
  106. package/dist/repair.js.map +1 -0
  107. package/dist/scheduler/controls.d.ts +35 -0
  108. package/dist/scheduler/controls.d.ts.map +1 -0
  109. package/dist/scheduler/controls.js +98 -0
  110. package/dist/scheduler/controls.js.map +1 -0
  111. package/dist/scheduler/index.d.ts +48 -0
  112. package/dist/scheduler/index.d.ts.map +1 -0
  113. package/dist/scheduler/index.js +193 -0
  114. package/dist/scheduler/index.js.map +1 -0
  115. package/dist/scheduler/leases.d.ts +22 -0
  116. package/dist/scheduler/leases.d.ts.map +1 -0
  117. package/dist/scheduler/leases.js +74 -0
  118. package/dist/scheduler/leases.js.map +1 -0
  119. package/dist/scheduler/session-capture.d.ts +33 -0
  120. package/dist/scheduler/session-capture.d.ts.map +1 -0
  121. package/dist/scheduler/session-capture.js +108 -0
  122. package/dist/scheduler/session-capture.js.map +1 -0
  123. package/dist/scheduler/state.d.ts +56 -0
  124. package/dist/scheduler/state.d.ts.map +1 -0
  125. package/dist/scheduler/state.js +210 -0
  126. package/dist/scheduler/state.js.map +1 -0
  127. package/dist/scope.d.ts +54 -0
  128. package/dist/scope.d.ts.map +1 -0
  129. package/dist/scope.js +161 -0
  130. package/dist/scope.js.map +1 -0
  131. package/dist/scripts/bulk-link-fix.d.ts +9 -0
  132. package/dist/scripts/bulk-link-fix.d.ts.map +1 -0
  133. package/dist/scripts/bulk-link-fix.js +106 -0
  134. package/dist/scripts/bulk-link-fix.js.map +1 -0
  135. package/dist/session-tools.d.ts +33 -0
  136. package/dist/session-tools.d.ts.map +1 -0
  137. package/dist/session-tools.js +211 -0
  138. package/dist/session-tools.js.map +1 -0
  139. package/dist/settings.d.ts +19 -0
  140. package/dist/settings.d.ts.map +1 -0
  141. package/dist/settings.js +106 -0
  142. package/dist/settings.js.map +1 -0
  143. package/dist/setup.d.ts +29 -0
  144. package/dist/setup.d.ts.map +1 -0
  145. package/dist/setup.js +90 -0
  146. package/dist/setup.js.map +1 -0
  147. package/dist/state.d.ts +54 -0
  148. package/dist/state.d.ts.map +1 -0
  149. package/dist/state.js +176 -0
  150. package/dist/state.js.map +1 -0
  151. package/dist/status.d.ts +22 -0
  152. package/dist/status.d.ts.map +1 -0
  153. package/dist/status.js +93 -0
  154. package/dist/status.js.map +1 -0
  155. package/dist/store.d.ts +71 -0
  156. package/dist/store.d.ts.map +1 -0
  157. package/dist/store.js +282 -0
  158. package/dist/store.js.map +1 -0
  159. package/dist/summarize.d.ts +60 -0
  160. package/dist/summarize.d.ts.map +1 -0
  161. package/dist/summarize.js +266 -0
  162. package/dist/summarize.js.map +1 -0
  163. package/dist/tag-registry.d.ts +56 -0
  164. package/dist/tag-registry.d.ts.map +1 -0
  165. package/dist/tag-registry.js +146 -0
  166. package/dist/tag-registry.js.map +1 -0
  167. package/dist/templates/prompts.d.ts +51 -0
  168. package/dist/templates/prompts.d.ts.map +1 -0
  169. package/dist/templates/prompts.js +203 -0
  170. package/dist/templates/prompts.js.map +1 -0
  171. package/dist/tools.d.ts +26 -0
  172. package/dist/tools.d.ts.map +1 -0
  173. package/dist/tools.js +1198 -0
  174. package/dist/tools.js.map +1 -0
  175. package/dist/watcher.d.ts +25 -0
  176. package/dist/watcher.d.ts.map +1 -0
  177. package/dist/watcher.js +84 -0
  178. package/dist/watcher.js.map +1 -0
  179. package/dist/webui/client/dist/index.html +1885 -0
  180. package/dist/webui/server.d.ts +31 -0
  181. package/dist/webui/server.d.ts.map +1 -0
  182. package/dist/webui/server.js +566 -0
  183. package/dist/webui/server.js.map +1 -0
  184. package/dist/wiki-tool-guidance.d.ts +6 -0
  185. package/dist/wiki-tool-guidance.d.ts.map +1 -0
  186. package/dist/wiki-tool-guidance.js +70 -0
  187. package/dist/wiki-tool-guidance.js.map +1 -0
  188. package/dist/wiki.d.ts +108 -0
  189. package/dist/wiki.d.ts.map +1 -0
  190. package/dist/wiki.js +497 -0
  191. package/dist/wiki.js.map +1 -0
  192. package/package.json +2 -1
  193. package/scripts/build-assets.mjs +1 -13
  194. package/skills/setup/SKILL.md +1 -1
  195. package/src/cli.ts +0 -70
  196. package/src/config.ts +0 -25
  197. package/src/index.ts +1 -38
  198. package/src/templates/prompts.ts +0 -56
  199. package/scripts/gepa/dataset.py +0 -192
  200. package/scripts/gepa/lm_providers.py +0 -472
  201. package/scripts/gepa/metric.py +0 -279
  202. package/scripts/gepa/optimize.py +0 -367
  203. package/scripts/gepa/program.py +0 -99
  204. package/scripts/gepa/pyproject.toml +0 -19
  205. package/scripts/gepa/run-all.sh +0 -53
  206. package/scripts/gepa/wiki_reader.py +0 -113
  207. package/src/gepa/index.ts +0 -287
  208. package/src/gepa/optimized/capture-prompt.txt +0 -65
package/dist/store.js ADDED
@@ -0,0 +1,282 @@
1
+ /**
2
+ * qmd store lifecycle — manages the qmd-engine store instance.
3
+ *
4
+ * Handles store creation/opening, search with scope filtering,
5
+ * re-indexing after wiki changes, and embedding lifecycle.
6
+ */
7
+ import { readFileSync, existsSync } from "node:fs";
8
+ import { homedir } from "node:os";
9
+ import { join } from "node:path";
10
+ import { parse as parseYaml } from "yaml";
11
+ import { createStore, extractSnippet } from "qmd-engine";
12
+ import { parseFrontmatter } from "./frontmatter.js";
13
+ import { buildQmdProvidersFromParaConfig } from "./qmd-providers.js";
14
+ import { matchesScope } from "./scope.js";
15
+ // -- PARA context descriptions -----------------------------------------------
16
+ const PARA_CONTEXTS = {
17
+ "projects/": "Active projects with defined goals and end dates",
18
+ "areas/": "Ongoing responsibilities and standards",
19
+ "resources/": "Reference material and how-to guides",
20
+ "archives/": "Completed or deprecated items",
21
+ };
22
+ const RAW_CONTEXT = "Immutable source material: articles, documents, notes. Not synthesized.";
23
+ // -- Pending embed tracking --------------------------------------------------
24
+ const pendingEmbeds = new WeakMap();
25
+ // -- qmd provider config -----------------------------------------------------
26
+ /**
27
+ * qmd-engine currently falls back to node-llama-cpp when no API provider is
28
+ * configured. pi-para never uses local LLMs, so provide an inert API endpoint
29
+ * whenever neither pi-para profiles nor legacy provider config exists. BM25
30
+ * search works without calling this endpoint; accidental vector/chat calls fail
31
+ * fast instead of downloading/building local models.
32
+ */
33
+ const NO_LOCAL_PROVIDERS = {
34
+ embed: {
35
+ url: "http://127.0.0.1:9",
36
+ model: "disabled-local-llm",
37
+ },
38
+ };
39
+ // -- qmd config loading ------------------------------------------------------
40
+ /**
41
+ * Read providers from ~/.config/qmd/index.yml.
42
+ * Returns undefined if no config file or no providers configured.
43
+ */
44
+ function loadQmdProviders() {
45
+ const configPath = join(homedir(), ".config", "qmd", "index.yml");
46
+ if (!existsSync(configPath))
47
+ return undefined;
48
+ try {
49
+ const content = readFileSync(configPath, "utf-8");
50
+ const config = parseYaml(content);
51
+ return config?.providers;
52
+ }
53
+ catch {
54
+ return undefined;
55
+ }
56
+ }
57
+ // -- Functions ---------------------------------------------------------------
58
+ /**
59
+ * Open and configure a qmd store for the wiki directory.
60
+ *
61
+ * Creates the store with two collections:
62
+ * - wiki: all .md files except raw/
63
+ * - raw: .md files under raw/, not included in default queries
64
+ *
65
+ * Adds PARA category contexts and runs update() for BM25. When requested,
66
+ * also schedules embed() in the background.
67
+ */
68
+ export async function openStore(wikiDir, opts = {}) {
69
+ // Prefer pi-para's in-memory provider profiles. Legacy QMD YAML remains a
70
+ // fallback for migrated installs and tests that do not pass paraConfig.
71
+ const configuredProviders = opts.paraConfig
72
+ ? opts.paraConfig.qmd.providerConfig === "legacy-qmd-compatible"
73
+ ? loadQmdProviders()
74
+ : await buildQmdProvidersFromParaConfig(opts.paraConfig, {
75
+ secretsPath: opts.secretsPath,
76
+ authStorage: opts.authStorage,
77
+ })
78
+ : loadQmdProviders();
79
+ const providers = configuredProviders ?? NO_LOCAL_PROVIDERS;
80
+ const store = await createStore({
81
+ dbPath: join(wikiDir, ".qmd.sqlite"),
82
+ config: {
83
+ collections: {
84
+ wiki: {
85
+ path: wikiDir,
86
+ pattern: "**/*.md",
87
+ ignore: ["raw/**"],
88
+ },
89
+ raw: {
90
+ path: join(wikiDir, "raw"),
91
+ pattern: "**/*.md",
92
+ includeByDefault: false,
93
+ },
94
+ },
95
+ providers: providers,
96
+ },
97
+ });
98
+ // Add PARA category contexts to the wiki collection
99
+ for (const [prefix, description] of Object.entries(PARA_CONTEXTS)) {
100
+ await store.addContext("wiki", prefix, description);
101
+ }
102
+ // Add context for the raw collection root
103
+ await store.addContext("raw", "/", RAW_CONTEXT);
104
+ // Sync filesystem -> BM25 index (fast, search ready immediately)
105
+ await store.update();
106
+ if (opts.backgroundEmbed !== false && opts.paraConfig?.qmd.embedEnabled !== false) {
107
+ // Schedule embedding in background (non-blocking).
108
+ // BM25 search works immediately; hybrid search improves once embed completes.
109
+ // Suppress console.error from qmd's internal embed failures.
110
+ const origError = console.error;
111
+ const embedPromise = store.embed().then(() => {
112
+ pendingEmbeds.delete(store);
113
+ }).catch(() => {
114
+ // Embedding failures are non-fatal — hybrid search degrades to BM25
115
+ pendingEmbeds.delete(store);
116
+ }).finally(() => {
117
+ console.error = origError;
118
+ });
119
+ // Temporarily suppress embed error noise during background embed
120
+ console.error = (...args) => {
121
+ const msg = String(args[0] ?? "");
122
+ if (msg.includes("embed error") || msg.includes("fetch failed"))
123
+ return;
124
+ origError(...args);
125
+ };
126
+ pendingEmbeds.set(store, embedPromise);
127
+ }
128
+ return store;
129
+ }
130
+ /**
131
+ * Close the store. Awaits any pending embed operation (with timeout) first.
132
+ */
133
+ export async function closeStore(store) {
134
+ const pending = pendingEmbeds.get(store);
135
+ if (pending) {
136
+ // Wait for pending embed with a short timeout — don't hang forever
137
+ const timeout = new Promise((resolve) => {
138
+ const timer = setTimeout(resolve, 5_000);
139
+ timer.unref?.();
140
+ });
141
+ await Promise.race([pending, timeout]);
142
+ pendingEmbeds.delete(store);
143
+ }
144
+ await store.close();
145
+ }
146
+ /**
147
+ * Search the wiki with scope and category filtering.
148
+ *
149
+ * Uses vector search when an embedding index is available, merged with BM25
150
+ * lexical search for exact keyword matches. Each result's frontmatter is parsed
151
+ * to apply scope/category/archive filters.
152
+ */
153
+ export async function searchWiki(store, query, opts) {
154
+ const limit = opts.limit ?? 10;
155
+ // Build metadata filter for SQL-level filtering (qmd v2.2.0+)
156
+ // Note: we can only use metadata.category here, NOT scope.
157
+ // Scope filtering must remain as post-filter because:
158
+ // - Pages with scope:["global"] must match ANY project scope
159
+ // - Pages in the scope.include list need OR matching
160
+ // - The exclude list needs post-filter negation
161
+ // SQL-level scope filter would miss global pages.
162
+ const metadata = {};
163
+ if (opts.category) {
164
+ metadata.category = opts.category;
165
+ }
166
+ const fetchLimit = opts.scope ? limit * 3 : limit;
167
+ const lexResults = await store.searchLex(query, {
168
+ limit: fetchLimit,
169
+ collection: "wiki",
170
+ metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
171
+ graphBoost: opts.graphBoost ?? true,
172
+ });
173
+ const rawResults = await mergeLexAndVectorResults(store, query, lexResults, fetchLimit);
174
+ const results = [];
175
+ for (const result of rawResults) {
176
+ // Parse category and slug from the display path (e.g. "projects/auth-refactor.md")
177
+ const parsed = parseDisplayPath(result.displayPath);
178
+ if (!parsed)
179
+ continue;
180
+ const { category, slug } = parsed;
181
+ // Exclude archives unless explicitly requested (post-filter fallback
182
+ // for pages without frontmatter metadata)
183
+ if (category === "archives" && !opts.includeArchives) {
184
+ continue;
185
+ }
186
+ // Parse frontmatter from body
187
+ const body = result.body ?? "";
188
+ const { frontmatter } = parseFrontmatter(body);
189
+ // Scope post-filter fallback for pages without metadata
190
+ if (opts.scope && !matchesScope(frontmatter.scope, opts.scope)) {
191
+ continue;
192
+ }
193
+ // Extract a snippet for display
194
+ const snippetResult = extractSnippet(body, query);
195
+ const snippet = snippetResult.snippet;
196
+ results.push({
197
+ page: {
198
+ category,
199
+ slug,
200
+ title: frontmatter.title || result.title || slug,
201
+ path: `${category}/${slug}.md`,
202
+ },
203
+ score: result.score,
204
+ snippet,
205
+ frontmatter,
206
+ });
207
+ if (results.length >= limit)
208
+ break;
209
+ }
210
+ return results;
211
+ }
212
+ async function mergeLexAndVectorResults(store, query, lexResults, limit) {
213
+ let vecResults = [];
214
+ try {
215
+ const status = await store.getStatus();
216
+ const llm = store.internal.llm;
217
+ const embedModel = llm?.embedModelName;
218
+ if (status.hasVectorIndex && llm && embedModel) {
219
+ vecResults = await store.internal.searchVec(query, embedModel, limit, "wiki", llm);
220
+ }
221
+ }
222
+ catch {
223
+ // Semantic search is best-effort; lexical BM25 remains the reliable fallback.
224
+ }
225
+ const merged = new Map();
226
+ for (const result of lexResults) {
227
+ merged.set(result.displayPath, { ...result, score: result.score * 0.85 });
228
+ }
229
+ for (const result of vecResults) {
230
+ const existing = merged.get(result.displayPath);
231
+ if (!existing || result.score > existing.score) {
232
+ merged.set(result.displayPath, result);
233
+ }
234
+ }
235
+ return [...merged.values()].sort((a, b) => b.score - a.score).slice(0, limit * 2);
236
+ }
237
+ /**
238
+ * Re-index the store (fast filesystem scan). Makes new/changed
239
+ * content BM25-searchable immediately. Call after wiki writes.
240
+ */
241
+ export async function reindex(store) {
242
+ await store.update();
243
+ }
244
+ /**
245
+ * Generate vector embeddings for new/changed pages.
246
+ * Slow — call only at startup (via openStore) or shutdown.
247
+ */
248
+ export async function embedIfNeeded(store) {
249
+ await store.embed();
250
+ }
251
+ // -- Helpers -----------------------------------------------------------------
252
+ /** Valid PARA categories for path parsing. */
253
+ const VALID_CATEGORIES = new Set([
254
+ "projects",
255
+ "areas",
256
+ "resources",
257
+ "archives",
258
+ ]);
259
+ /**
260
+ * Parse a qmd display path into category + slug.
261
+ * Display paths from searchLex include the collection prefix:
262
+ * "wiki/resources/ssl-certs.md" or "wiki/schema.md"
263
+ * Returns null for root-level files (schema.md, index.md, etc.) — they
264
+ * still appear in search results but aren't PageRef-able.
265
+ */
266
+ function parseDisplayPath(displayPath) {
267
+ const parts = displayPath.split("/");
268
+ // Display paths are: collection/category/slug.md (3+ parts)
269
+ // or collection/file.md (2 parts, root-level files like schema.md)
270
+ if (parts.length < 3)
271
+ return null;
272
+ // Skip collection prefix (parts[0] = "wiki")
273
+ const category = parts[1];
274
+ if (!VALID_CATEGORIES.has(category))
275
+ return null;
276
+ const filename = parts.slice(2).join("/");
277
+ if (!filename.endsWith(".md"))
278
+ return null;
279
+ const slug = filename.slice(0, -3);
280
+ return { category: category, slug };
281
+ }
282
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAAE,+BAA+B,EAA2B,MAAM,oBAAoB,CAAC;AAC9F,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA4C1C,+EAA+E;AAE/E,MAAM,aAAa,GAA2B;IAC5C,WAAW,EAAE,kDAAkD;IAC/D,QAAQ,EAAE,wCAAwC;IAClD,YAAY,EAAE,sCAAsC;IACpD,WAAW,EAAE,+BAA+B;CAC7C,CAAC;AAEF,MAAM,WAAW,GAAG,yEAAyE,CAAC;AAE9F,+EAA+E;AAE/E,MAAM,aAAa,GAAG,IAAI,OAAO,EAA2B,CAAC;AAE7D,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,kBAAkB,GAAuB;IAC7C,KAAK,EAAE;QACL,GAAG,EAAE,oBAAoB;QACzB,KAAK,EAAE,oBAAoB;KAC5B;CACF,CAAC;AAEF,+EAA+E;AAE/E;;;GAGG;AACH,SAAS,gBAAgB;IACvB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IAClE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IAE9C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAA4C,CAAC;QAC7E,OAAO,MAAM,EAAE,SAAS,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe,EAAE,OAAyB,EAAE;IAC1E,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,mBAAmB,GAAG,IAAI,CAAC,UAAU;QACzC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,cAAc,KAAK,uBAAuB;YAC9D,CAAC,CAAC,gBAAgB,EAAE;YACpB,CAAC,CAAC,MAAM,+BAA+B,CAAC,IAAI,CAAC,UAAU,EAAE;gBACvD,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC;QACJ,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACvB,MAAM,SAAS,GAAG,mBAAmB,IAAI,kBAAkB,CAAC;IAE5D,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC;QAC9B,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC;QACpC,MAAM,EAAE;YACN,WAAW,EAAE;gBACX,IAAI,EAAE;oBACJ,IAAI,EAAE,OAAO;oBACb,OAAO,EAAE,SAAS;oBAClB,MAAM,EAAE,CAAC,QAAQ,CAAC;iBACnB;gBACD,GAAG,EAAE;oBACH,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC;oBAC1B,OAAO,EAAE,SAAS;oBAClB,gBAAgB,EAAE,KAAK;iBACxB;aACF;YACD,SAAS,EAAE,SAA0C;SACtD;KACF,CAAC,CAAC;IAEH,oDAAoD;IACpD,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QAClE,MAAM,KAAK,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;IACtD,CAAC;IAED,0CAA0C;IAC1C,MAAM,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;IAEhD,iEAAiE;IACjE,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;IAErB,IAAI,IAAI,CAAC,eAAe,KAAK,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;QAClF,mDAAmD;QACnD,8EAA8E;QAC9E,6DAA6D;QAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC;QAChC,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;YAC3C,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACZ,oEAAoE;YACpE,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;YACd,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;QAC5B,CAAC,CAAC,CAAC;QACH,iEAAiE;QACjE,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE;YACrC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAClC,IAAI,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC;gBAAE,OAAO;YACxE,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;QACrB,CAAC,CAAC;QACF,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAe;IAC9C,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,OAAO,EAAE,CAAC;QACZ,mEAAmE;QACnE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAC5C,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACxC,KAAgC,CAAC,KAAK,EAAE,EAAE,CAAC;QAC9C,CAAC,CAAC,CAAC;QACH,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACvC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAe,EACf,KAAa,EACb,IAAuB;IAEvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;IAE/B,8DAA8D;IAC9D,2DAA2D;IAC3D,sDAAsD;IACtD,6DAA6D;IAC7D,qDAAqD;IACrD,gDAAgD;IAChD,kDAAkD;IAClD,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IACpC,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAElD,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE;QAC9C,KAAK,EAAE,UAAU;QACjB,UAAU,EAAE,MAAM;QAClB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;QACjE,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;KACpC,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,MAAM,wBAAwB,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IACxF,MAAM,OAAO,GAAuB,EAAE,CAAC;IAEvC,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,mFAAmF;QACnF,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM;YAAE,SAAS;QAEtB,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;QAElC,qEAAqE;QACrE,0CAA0C;QAC1C,IAAI,QAAQ,KAAK,UAAU,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YACrD,SAAS;QACX,CAAC;QAED,8BAA8B;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QAC/B,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAE/C,wDAAwD;QACxD,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/D,SAAS;QACX,CAAC;QAED,gCAAgC;QAChC,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC;QAEtC,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE;gBACJ,QAAQ;gBACR,IAAI;gBACJ,KAAK,EAAE,WAAW,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI;gBAChD,IAAI,EAAE,GAAG,QAAQ,IAAI,IAAI,KAAK;aAC/B;YACD,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO;YACP,WAAW;SACZ,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK;YAAE,MAAM;IACrC,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,KAAe,EACf,KAAa,EACb,UAAgC,EAChC,KAAa;IAEb,IAAI,UAAU,GAAyB,EAAE,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;QACvC,MAAM,GAAG,GAAI,KAAK,CAAC,QAAyC,CAAC,GAAG,CAAC;QACjE,MAAM,UAAU,GAAI,GAA+C,EAAE,cAAc,CAAC;QACpF,IAAI,MAAM,CAAC,cAAc,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;YAC/C,UAAU,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAU,CAAyB,CAAC;QACpH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,8EAA8E;IAChF,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,EAA8B,CAAC;IACrD,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAChD,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;AACpF,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAe;IAC3C,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAe;IACjD,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;AACtB,CAAC;AAED,+EAA+E;AAE/E,8CAA8C;AAC9C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAS;IACvC,UAAU;IACV,OAAO;IACP,WAAW;IACX,UAAU;CACX,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,SAAS,gBAAgB,CACvB,WAAmB;IAEnB,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAErC,4DAA4D;IAC5D,mEAAmE;IACnE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAElC,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,EAAE,QAAQ,EAAE,QAAwB,EAAE,IAAI,EAAE,CAAC;AACtD,CAAC"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Wiki summarization — adapts pi's compaction approach for wiki knowledge.
3
+ *
4
+ * Produces structured wiki summaries in the standard format:
5
+ * Topic, Key Facts, Insights, Connections, Open Questions, Sources.
6
+ *
7
+ * Supports ingest, session, page, and iterative summarization modes.
8
+ *
9
+ * Functions here generate prompt strings — they do NOT call the LLM.
10
+ * The caller (capture.ts, tools.ts) passes the prompt to a standalone Agent.
11
+ */
12
+ import type { WikiPage } from "./wiki.js";
13
+ import type { ParaCategory } from "./wiki.js";
14
+ import type { ProjectScope } from "./scope.js";
15
+ export interface SummarizeOptions {
16
+ mode: "ingest" | "session" | "page" | "iterative";
17
+ existingContent?: string;
18
+ scope: ProjectScope;
19
+ category?: ParaCategory;
20
+ }
21
+ /**
22
+ * Serialize session messages for wiki capture.
23
+ *
24
+ * Converts AgentMessage[] to a text representation that prevents the LLM
25
+ * from treating it as a conversation to continue. Uses pi's convertToLlm +
26
+ * serializeConversation when the messages contain pi-specific types
27
+ * (bashExecution, compactionSummary, branchSummary, etc.). Falls back to
28
+ * a compatible reimplementation for plain user/assistant/toolResult messages.
29
+ *
30
+ * @param messages - AgentMessage[] from @earendil-works/pi-agent-core
31
+ * @returns Serialized text in [User]: / [Assistant]: / [Tool result]: format
32
+ */
33
+ export declare function serializeSessionForWiki(messages: unknown[]): string;
34
+ /**
35
+ * Generate a wiki-format summary prompt from raw content.
36
+ *
37
+ * Returns the prompt string to send to the LLM. The caller passes this
38
+ * to a standalone Agent or includes it in a tool result for the session agent.
39
+ *
40
+ * @param content - Source text, serialized conversation, or page content
41
+ * @param options - Summarization mode and context
42
+ * @returns Prompt string for the LLM
43
+ */
44
+ export declare function generateSummary(content: string, options: SummarizeOptions): string;
45
+ /**
46
+ * Generate an overview prompt from multiple wiki pages.
47
+ *
48
+ * Used by /wiki-summarize and wiki_summarize tool to produce high-level
49
+ * overviews of a category or the entire wiki.
50
+ *
51
+ * @param pages - Wiki pages to summarize
52
+ * @param scope - Current project scope for context
53
+ * @returns Prompt string for the LLM
54
+ */
55
+ export interface OverviewPromptOptions {
56
+ depth?: "brief" | "detailed";
57
+ maxChars?: number;
58
+ }
59
+ export declare function generateOverviewPrompt(pages: WikiPage[], scope: ProjectScope, options?: OverviewPromptOptions): string;
60
+ //# sourceMappingURL=summarize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize.d.ts","sourceRoot":"","sources":["../src/summarize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAc/C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAuGD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,OAAO,EAAE,GAClB,MAAM,CAYR;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,GACxB,MAAM,CA2DR;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAOD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,QAAQ,EAAE,EACjB,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,qBAA0B,GAClC,MAAM,CAgCR"}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Wiki summarization — adapts pi's compaction approach for wiki knowledge.
3
+ *
4
+ * Produces structured wiki summaries in the standard format:
5
+ * Topic, Key Facts, Insights, Connections, Open Questions, Sources.
6
+ *
7
+ * Supports ingest, session, page, and iterative summarization modes.
8
+ *
9
+ * Functions here generate prompt strings — they do NOT call the LLM.
10
+ * The caller (capture.ts, tools.ts) passes the prompt to a standalone Agent.
11
+ */
12
+ import { convertToLlm, serializeConversation, } from "@earendil-works/pi-coding-agent";
13
+ import { SUMMARIZE_SYSTEM_PROMPT, ITERATIVE_UPDATE_PROMPT, OVERVIEW_PROMPT, CAPTURE_PROMPT, } from "./templates/prompts.js";
14
+ // -- Constants ---------------------------------------------------------------
15
+ /** Maximum characters for a tool result in serialized output. */
16
+ const TOOL_RESULT_MAX_CHARS = 2000;
17
+ // -- Fallback serialization --------------------------------------------------
18
+ /**
19
+ * Truncate text to a maximum character length for summarization.
20
+ * Keeps the beginning and appends a truncation marker.
21
+ */
22
+ function truncateForSummary(text, maxChars) {
23
+ if (text.length <= maxChars)
24
+ return text;
25
+ const truncatedChars = text.length - maxChars;
26
+ return `${text.slice(0, maxChars)}\n\n[... ${truncatedChars} more characters truncated]`;
27
+ }
28
+ /**
29
+ * Extract text content from a message content field.
30
+ * Handles both string and array-of-blocks shapes.
31
+ */
32
+ function extractTextContent(content) {
33
+ if (typeof content === "string")
34
+ return content;
35
+ if (!Array.isArray(content))
36
+ return "";
37
+ return content
38
+ .filter((c) => typeof c === "object" &&
39
+ c !== null &&
40
+ "type" in c &&
41
+ c.type === "text" &&
42
+ "text" in c)
43
+ .map((c) => c.text)
44
+ .join("");
45
+ }
46
+ /**
47
+ * Fallback serialization that mirrors pi's serializeConversation format.
48
+ * Used when @earendil-works/pi-coding-agent is not available.
49
+ *
50
+ * Formats: [User]:, [Assistant]:, [Assistant thinking]:,
51
+ * [Assistant tool calls]:, [Tool result]:
52
+ */
53
+ function serializeMessagesFallback(messages) {
54
+ const parts = [];
55
+ for (const msg of messages) {
56
+ if (typeof msg !== "object" || msg === null || !("role" in msg))
57
+ continue;
58
+ const m = msg;
59
+ if (m.role === "user") {
60
+ const text = extractTextContent(m.content);
61
+ if (text)
62
+ parts.push(`[User]: ${text}`);
63
+ }
64
+ else if (m.role === "assistant") {
65
+ const content = m.content;
66
+ if (!Array.isArray(content))
67
+ continue;
68
+ const textParts = [];
69
+ const thinkingParts = [];
70
+ const toolCalls = [];
71
+ for (const block of content) {
72
+ if (typeof block !== "object" || block === null || !("type" in block))
73
+ continue;
74
+ const b = block;
75
+ if (b.type === "text" && typeof b.text === "string") {
76
+ textParts.push(b.text);
77
+ }
78
+ else if (b.type === "thinking" && typeof b.thinking === "string") {
79
+ thinkingParts.push(b.thinking);
80
+ }
81
+ else if (b.type === "toolCall" && typeof b.name === "string") {
82
+ const args = (b.arguments ?? {});
83
+ const argsStr = Object.entries(args)
84
+ .map(([k, v]) => `${k}=${JSON.stringify(v)}`)
85
+ .join(", ");
86
+ toolCalls.push(`${b.name}(${argsStr})`);
87
+ }
88
+ }
89
+ if (thinkingParts.length > 0) {
90
+ parts.push(`[Assistant thinking]: ${thinkingParts.join("\n")}`);
91
+ }
92
+ if (textParts.length > 0) {
93
+ parts.push(`[Assistant]: ${textParts.join("\n")}`);
94
+ }
95
+ if (toolCalls.length > 0) {
96
+ parts.push(`[Assistant tool calls]: ${toolCalls.join("; ")}`);
97
+ }
98
+ }
99
+ else if (m.role === "toolResult") {
100
+ const text = extractTextContent(m.content);
101
+ if (text) {
102
+ parts.push(`[Tool result]: ${truncateForSummary(text, TOOL_RESULT_MAX_CHARS)}`);
103
+ }
104
+ }
105
+ }
106
+ return parts.join("\n\n");
107
+ }
108
+ // -- Public API --------------------------------------------------------------
109
+ /**
110
+ * Serialize session messages for wiki capture.
111
+ *
112
+ * Converts AgentMessage[] to a text representation that prevents the LLM
113
+ * from treating it as a conversation to continue. Uses pi's convertToLlm +
114
+ * serializeConversation when the messages contain pi-specific types
115
+ * (bashExecution, compactionSummary, branchSummary, etc.). Falls back to
116
+ * a compatible reimplementation for plain user/assistant/toolResult messages.
117
+ *
118
+ * @param messages - AgentMessage[] from @earendil-works/pi-agent-core
119
+ * @returns Serialized text in [User]: / [Assistant]: / [Tool result]: format
120
+ */
121
+ export function serializeSessionForWiki(messages) {
122
+ // Use pi's convertToLlm to handle custom message types (bashExecution,
123
+ // compactionSummary, branchSummary, etc.), then serialize the resulting
124
+ // standard LLM messages.
125
+ try {
126
+ const llmMessages = convertToLlm(messages);
127
+ return serializeConversation(llmMessages);
128
+ }
129
+ catch {
130
+ // If convertToLlm fails (e.g., unexpected message shapes), fall back
131
+ // to our reimplementation that handles the base roles.
132
+ return serializeMessagesFallback(messages);
133
+ }
134
+ }
135
+ /**
136
+ * Generate a wiki-format summary prompt from raw content.
137
+ *
138
+ * Returns the prompt string to send to the LLM. The caller passes this
139
+ * to a standalone Agent or includes it in a tool result for the session agent.
140
+ *
141
+ * @param content - Source text, serialized conversation, or page content
142
+ * @param options - Summarization mode and context
143
+ * @returns Prompt string for the LLM
144
+ */
145
+ export function generateSummary(content, options) {
146
+ const scopeInfo = `Current scope: ${options.scope.name} (tags: ${options.scope.include.join(", ")})`;
147
+ const categoryHint = options.category ? `\nSuggested PARA category: ${options.category}` : "";
148
+ switch (options.mode) {
149
+ case "ingest":
150
+ return [
151
+ SUMMARIZE_SYSTEM_PROMPT,
152
+ "",
153
+ scopeInfo,
154
+ categoryHint,
155
+ "",
156
+ "Produce a wiki page from the following source material:",
157
+ "",
158
+ "<source-content>",
159
+ content,
160
+ "</source-content>",
161
+ ].join("\n");
162
+ case "session":
163
+ return [
164
+ CAPTURE_PROMPT,
165
+ content,
166
+ "</session-conversation>",
167
+ ].join("\n");
168
+ case "page":
169
+ return [
170
+ SUMMARIZE_SYSTEM_PROMPT,
171
+ "",
172
+ scopeInfo,
173
+ "",
174
+ "Summarize the following wiki page into a concise overview:",
175
+ "",
176
+ "<page-content>",
177
+ content,
178
+ "</page-content>",
179
+ ].join("\n");
180
+ case "iterative":
181
+ if (!options.existingContent) {
182
+ // No existing content — treat as a fresh page
183
+ return generateSummary(content, { ...options, mode: "ingest" });
184
+ }
185
+ return [
186
+ ITERATIVE_UPDATE_PROMPT,
187
+ "",
188
+ scopeInfo,
189
+ categoryHint,
190
+ "",
191
+ "<existing-page>",
192
+ options.existingContent,
193
+ "</existing-page>",
194
+ "",
195
+ "<new-content>",
196
+ content,
197
+ "</new-content>",
198
+ ].join("\n");
199
+ }
200
+ }
201
+ const DEFAULT_BRIEF_OVERVIEW_MAX_CHARS = 28_000;
202
+ const DEFAULT_DETAILED_OVERVIEW_MAX_CHARS = 80_000;
203
+ const BRIEF_EXCERPT_CHARS = 180;
204
+ const DETAILED_BODY_CHARS = 2_000;
205
+ export function generateOverviewPrompt(pages, scope, options = {}) {
206
+ const depth = options.depth ?? "brief";
207
+ const maxChars = options.maxChars ?? (depth === "detailed" ? DEFAULT_DETAILED_OVERVIEW_MAX_CHARS : DEFAULT_BRIEF_OVERVIEW_MAX_CHARS);
208
+ const scopeInfo = `Current scope: ${scope.name} (tags: ${scope.include.join(", ")})`;
209
+ const header = [
210
+ OVERVIEW_PROMPT,
211
+ "",
212
+ scopeInfo,
213
+ `Total pages: ${pages.length}`,
214
+ `Input mode: ${depth === "detailed" ? "bounded detailed excerpts" : "compact metadata/excerpts"}`,
215
+ "",
216
+ ].join("\n");
217
+ const entries = [];
218
+ let usedChars = header.length;
219
+ let omitted = 0;
220
+ for (const page of pages) {
221
+ const entry = depth === "detailed" ? detailedPageEntry(page) : briefPageEntry(page);
222
+ if (usedChars + entry.length + 2 > maxChars) {
223
+ omitted++;
224
+ continue;
225
+ }
226
+ entries.push(entry);
227
+ usedChars += entry.length + 2;
228
+ }
229
+ const omittedNote = omitted > 0
230
+ ? `\n\n[${omitted} page(s) omitted to keep wiki_summarize within the context budget. Use a category, page path, or depth=\"detailed\" on a narrower target for more detail.]`
231
+ : "";
232
+ return `${header}${entries.join("\n\n")}${omittedNote}`;
233
+ }
234
+ function briefPageEntry(page) {
235
+ const fm = page.frontmatter;
236
+ const excerpt = firstUsefulExcerpt(page.body, BRIEF_EXCERPT_CHARS);
237
+ return [
238
+ `- ${fm.title} (${page.category}/${page.slug})`,
239
+ ` PARA: ${fm.para} | Scope: ${fm.scope.join(", ")} | Tags: ${fm.tags.join(", ") || "-"} | Updated: ${fm.updated ?? "-"}`,
240
+ excerpt ? ` Excerpt: ${excerpt}` : undefined,
241
+ fm.links?.length ? ` Links: ${fm.links.slice(0, 8).map((link) => `[[${link}]]`).join(", ")}` : undefined,
242
+ ].filter(Boolean).join("\n");
243
+ }
244
+ function detailedPageEntry(page) {
245
+ const fm = page.frontmatter;
246
+ return [
247
+ `### ${fm.title} (${page.category}/${page.slug})`,
248
+ `PARA: ${fm.para} | Scope: ${fm.scope.join(", ")} | Tags: ${fm.tags.join(", ")}`,
249
+ `Updated: ${fm.updated ?? "-"} | Links: ${(fm.links ?? []).slice(0, 12).map((link) => `[[${link}]]`).join(", ") || "-"}`,
250
+ "",
251
+ truncateForSummary(page.body, DETAILED_BODY_CHARS),
252
+ ].join("\n");
253
+ }
254
+ function firstUsefulExcerpt(body, maxChars) {
255
+ const cleaned = body
256
+ .split(/\r?\n/)
257
+ .map((line) => line.trim())
258
+ .filter((line) => line && !line.startsWith("#") && !/^[-*]\s*\[?\[?/.test(line))
259
+ .join(" ")
260
+ .replace(/\s+/g, " ")
261
+ .trim();
262
+ if (!cleaned)
263
+ return "";
264
+ return cleaned.length <= maxChars ? cleaned : `${cleaned.slice(0, maxChars - 1)}…`;
265
+ }
266
+ //# sourceMappingURL=summarize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize.js","sourceRoot":"","sources":["../src/summarize.ts"],"names":[],"mappings":"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"}