pi-para 0.5.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.
- package/CHANGELOG.md +214 -0
- package/README.md +305 -0
- package/SETUP.md +171 -0
- package/dist/capture.d.ts +34 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.js +461 -0
- package/dist/capture.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +405 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +15 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +786 -0
- package/dist/commands.js.map +1 -0
- package/dist/context.d.ts +61 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +289 -0
- package/dist/context.js.map +1 -0
- package/dist/daemon.d.ts +49 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +226 -0
- package/dist/daemon.js.map +1 -0
- package/dist/frontmatter.d.ts +59 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +170 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/gepa/dataset.d.ts +36 -0
- package/dist/gepa/dataset.d.ts.map +1 -0
- package/dist/gepa/dataset.js +148 -0
- package/dist/gepa/dataset.js.map +1 -0
- package/dist/gepa/evaluator.d.ts +51 -0
- package/dist/gepa/evaluator.d.ts.map +1 -0
- package/dist/gepa/evaluator.js +317 -0
- package/dist/gepa/evaluator.js.map +1 -0
- package/dist/gepa/index.d.ts +66 -0
- package/dist/gepa/index.d.ts.map +1 -0
- package/dist/gepa/index.js +240 -0
- package/dist/gepa/index.js.map +1 -0
- package/dist/gepa/llm.d.ts +35 -0
- package/dist/gepa/llm.d.ts.map +1 -0
- package/dist/gepa/llm.js +268 -0
- package/dist/gepa/llm.js.map +1 -0
- package/dist/gepa/optimized/capture-prompt.txt +65 -0
- package/dist/gepa/optimizer.d.ts +29 -0
- package/dist/gepa/optimizer.d.ts.map +1 -0
- package/dist/gepa/optimizer.js +249 -0
- package/dist/gepa/optimizer.js.map +1 -0
- package/dist/gepa/targets.d.ts +39 -0
- package/dist/gepa/targets.d.ts.map +1 -0
- package/dist/gepa/targets.js +326 -0
- package/dist/gepa/targets.js.map +1 -0
- package/dist/gepa/types.d.ts +168 -0
- package/dist/gepa/types.d.ts.map +1 -0
- package/dist/gepa/types.js +124 -0
- package/dist/gepa/types.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +294 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest.d.ts +88 -0
- package/dist/ingest.d.ts.map +1 -0
- package/dist/ingest.js +105 -0
- package/dist/ingest.js.map +1 -0
- package/dist/link-discovery.d.ts +40 -0
- package/dist/link-discovery.d.ts.map +1 -0
- package/dist/link-discovery.js +122 -0
- package/dist/link-discovery.js.map +1 -0
- package/dist/link-utils.d.ts +30 -0
- package/dist/link-utils.d.ts.map +1 -0
- package/dist/link-utils.js +145 -0
- package/dist/link-utils.js.map +1 -0
- package/dist/lint.d.ts +39 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +827 -0
- package/dist/lint.js.map +1 -0
- package/dist/maintainer.d.ts +24 -0
- package/dist/maintainer.d.ts.map +1 -0
- package/dist/maintainer.js +358 -0
- package/dist/maintainer.js.map +1 -0
- package/dist/processor.d.ts +14 -0
- package/dist/processor.d.ts.map +1 -0
- package/dist/processor.js +361 -0
- package/dist/processor.js.map +1 -0
- package/dist/query.d.ts +69 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +107 -0
- package/dist/query.js.map +1 -0
- package/dist/raw.d.ts +57 -0
- package/dist/raw.d.ts.map +1 -0
- package/dist/raw.js +219 -0
- package/dist/raw.js.map +1 -0
- package/dist/redact.d.ts +21 -0
- package/dist/redact.d.ts.map +1 -0
- package/dist/redact.js +143 -0
- package/dist/redact.js.map +1 -0
- package/dist/scope.d.ts +54 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +161 -0
- package/dist/scope.js.map +1 -0
- package/dist/scripts/bulk-link-fix.d.ts +9 -0
- package/dist/scripts/bulk-link-fix.d.ts.map +1 -0
- package/dist/scripts/bulk-link-fix.js +106 -0
- package/dist/scripts/bulk-link-fix.js.map +1 -0
- package/dist/session-tools.d.ts +33 -0
- package/dist/session-tools.d.ts.map +1 -0
- package/dist/session-tools.js +211 -0
- package/dist/session-tools.js.map +1 -0
- package/dist/state.d.ts +54 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +176 -0
- package/dist/state.js.map +1 -0
- package/dist/store.d.ts +56 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +227 -0
- package/dist/store.js.map +1 -0
- package/dist/summarize.d.ts +56 -0
- package/dist/summarize.d.ts.map +1 -0
- package/dist/summarize.js +231 -0
- package/dist/summarize.js.map +1 -0
- package/dist/tag-registry.d.ts +56 -0
- package/dist/tag-registry.d.ts.map +1 -0
- package/dist/tag-registry.js +146 -0
- package/dist/tag-registry.js.map +1 -0
- package/dist/templates/prompts.d.ts +63 -0
- package/dist/templates/prompts.d.ts.map +1 -0
- package/dist/templates/prompts.js +260 -0
- package/dist/templates/prompts.js.map +1 -0
- package/dist/tools.d.ts +26 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +1033 -0
- package/dist/tools.js.map +1 -0
- package/dist/watcher.d.ts +25 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +84 -0
- package/dist/watcher.js.map +1 -0
- package/dist/webui/client/dist/index.html +1885 -0
- package/dist/webui/server.d.ts +31 -0
- package/dist/webui/server.d.ts.map +1 -0
- package/dist/webui/server.js +566 -0
- package/dist/webui/server.js.map +1 -0
- package/dist/wiki.d.ts +103 -0
- package/dist/wiki.d.ts.map +1 -0
- package/dist/wiki.js +428 -0
- package/dist/wiki.js.map +1 -0
- package/package.json +142 -0
- package/scripts/gepa/__pycache__/dataset.cpython-313.pyc +0 -0
- package/scripts/gepa/__pycache__/lm_providers.cpython-313.pyc +0 -0
- package/scripts/gepa/__pycache__/metric.cpython-313.pyc +0 -0
- package/scripts/gepa/__pycache__/program.cpython-313.pyc +0 -0
- package/scripts/gepa/__pycache__/wiki_reader.cpython-313.pyc +0 -0
- package/scripts/gepa/dataset.py +192 -0
- package/scripts/gepa/lm_providers.py +472 -0
- package/scripts/gepa/metric.py +279 -0
- package/scripts/gepa/optimize.py +367 -0
- package/scripts/gepa/program.py +99 -0
- package/scripts/gepa/pyproject.toml +19 -0
- package/scripts/gepa/run-all.sh +53 -0
- package/scripts/gepa/uv.lock +2241 -0
- package/scripts/gepa/wiki_reader.py +113 -0
- package/skills/para/SKILL.md +77 -0
- package/skills/setup/SKILL.md +20 -0
- package/src/capture.ts +563 -0
- package/src/cli.ts +416 -0
- package/src/commands.ts +878 -0
- package/src/context.ts +390 -0
- package/src/daemon.ts +288 -0
- package/src/frontmatter.ts +219 -0
- package/src/gepa/index.ts +287 -0
- package/src/gepa/optimized/capture-prompt.txt +65 -0
- package/src/index.ts +384 -0
- package/src/ingest.ts +177 -0
- package/src/link-discovery.ts +170 -0
- package/src/link-utils.ts +169 -0
- package/src/lint.ts +1018 -0
- package/src/maintainer.ts +404 -0
- package/src/processor.ts +415 -0
- package/src/python/__pycache__/minimax_lm.cpython-312.pyc +0 -0
- package/src/python/minimax_lm.py +198 -0
- package/src/python/rlm_capture.py +215 -0
- package/src/query.ts +148 -0
- package/src/raw.ts +276 -0
- package/src/redact.ts +159 -0
- package/src/scope.ts +214 -0
- package/src/scripts/bulk-link-fix.ts +126 -0
- package/src/session-tools.ts +260 -0
- package/src/state.ts +271 -0
- package/src/store.ts +288 -0
- package/src/summarize.ts +273 -0
- package/src/tag-registry.ts +157 -0
- package/src/templates/index.md +17 -0
- package/src/templates/prompts.ts +274 -0
- package/src/templates/schema.md +116 -0
- package/src/tools.ts +1293 -0
- package/src/watcher.ts +101 -0
- package/src/webui/client/dist/index.html +1885 -0
- package/src/webui/server.ts +765 -0
- package/src/wiki.ts +550 -0
package/package.json
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-para",
|
|
3
|
+
"version": "0.5.2",
|
|
4
|
+
"description": "PARA Knowledge Base Extension for pi \u2014 persistent, LLM-curated personal wiki",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./wiki": {
|
|
14
|
+
"types": "./dist/wiki.d.ts",
|
|
15
|
+
"import": "./dist/wiki.js"
|
|
16
|
+
},
|
|
17
|
+
"./store": {
|
|
18
|
+
"types": "./dist/store.d.ts",
|
|
19
|
+
"import": "./dist/store.js"
|
|
20
|
+
},
|
|
21
|
+
"./frontmatter": {
|
|
22
|
+
"types": "./dist/frontmatter.d.ts",
|
|
23
|
+
"import": "./dist/frontmatter.js"
|
|
24
|
+
},
|
|
25
|
+
"./raw": {
|
|
26
|
+
"types": "./dist/raw.d.ts",
|
|
27
|
+
"import": "./dist/raw.js"
|
|
28
|
+
},
|
|
29
|
+
"./scope": {
|
|
30
|
+
"types": "./dist/scope.d.ts",
|
|
31
|
+
"import": "./dist/scope.js"
|
|
32
|
+
},
|
|
33
|
+
"./lint": {
|
|
34
|
+
"types": "./dist/lint.d.ts",
|
|
35
|
+
"import": "./dist/lint.js"
|
|
36
|
+
},
|
|
37
|
+
"./query": {
|
|
38
|
+
"types": "./dist/query.d.ts",
|
|
39
|
+
"import": "./dist/query.js"
|
|
40
|
+
},
|
|
41
|
+
"./ingest": {
|
|
42
|
+
"types": "./dist/ingest.d.ts",
|
|
43
|
+
"import": "./dist/ingest.js"
|
|
44
|
+
},
|
|
45
|
+
"./summarize": {
|
|
46
|
+
"types": "./dist/summarize.d.ts",
|
|
47
|
+
"import": "./dist/summarize.js"
|
|
48
|
+
},
|
|
49
|
+
"./link-utils": {
|
|
50
|
+
"types": "./dist/link-utils.d.ts",
|
|
51
|
+
"import": "./dist/link-utils.js"
|
|
52
|
+
},
|
|
53
|
+
"./tag-registry": {
|
|
54
|
+
"types": "./dist/tag-registry.d.ts",
|
|
55
|
+
"import": "./dist/tag-registry.js"
|
|
56
|
+
},
|
|
57
|
+
"./link-discovery": {
|
|
58
|
+
"types": "./dist/link-discovery.d.ts",
|
|
59
|
+
"import": "./dist/link-discovery.js"
|
|
60
|
+
},
|
|
61
|
+
"./redact": {
|
|
62
|
+
"types": "./dist/redact.d.ts",
|
|
63
|
+
"import": "./dist/redact.js"
|
|
64
|
+
},
|
|
65
|
+
"./context": {
|
|
66
|
+
"types": "./dist/context.d.ts",
|
|
67
|
+
"import": "./dist/context.js"
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"pi": {
|
|
71
|
+
"extensions": [
|
|
72
|
+
"./src/index.ts"
|
|
73
|
+
],
|
|
74
|
+
"skills": [
|
|
75
|
+
"./skills"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
"files": [
|
|
79
|
+
"dist",
|
|
80
|
+
"src",
|
|
81
|
+
"scripts",
|
|
82
|
+
"CHANGELOG.md",
|
|
83
|
+
"README.md",
|
|
84
|
+
"skills",
|
|
85
|
+
"SETUP.md"
|
|
86
|
+
],
|
|
87
|
+
"scripts": {
|
|
88
|
+
"clean": "rm -rf dist",
|
|
89
|
+
"build": "tsc -p tsconfig.json && mkdir -p dist/webui/client/dist && cp src/webui/client/dist/index.html dist/webui/client/dist/index.html && mkdir -p dist/gepa/optimized && cp -r src/gepa/optimized/*.txt dist/gepa/optimized/ 2>/dev/null || true",
|
|
90
|
+
"check": "tsc --noEmit",
|
|
91
|
+
"test": "vitest --run",
|
|
92
|
+
"fix-links": "tsx src/scripts/bulk-link-fix.ts",
|
|
93
|
+
"fix-links:dry": "tsx src/scripts/bulk-link-fix.ts --dry-run"
|
|
94
|
+
},
|
|
95
|
+
"dependencies": {
|
|
96
|
+
"qmd-engine": "^2.3.3",
|
|
97
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
98
|
+
"better-sqlite3": "^11.9.1",
|
|
99
|
+
"yaml": "^2.8.2"
|
|
100
|
+
},
|
|
101
|
+
"peerDependencies": {
|
|
102
|
+
"@mariozechner/pi-agent-core": "^0.70.2",
|
|
103
|
+
"@mariozechner/pi-ai": "^0.70.2",
|
|
104
|
+
"@mariozechner/pi-coding-agent": "^0.70.2",
|
|
105
|
+
"@mariozechner/pi-tui": "^0.70.2",
|
|
106
|
+
"typebox": "^1.1.24"
|
|
107
|
+
},
|
|
108
|
+
"peerDependenciesMeta": {},
|
|
109
|
+
"devDependencies": {
|
|
110
|
+
"@mariozechner/pi-agent-core": "^0.70.2",
|
|
111
|
+
"@mariozechner/pi-ai": "^0.70.2",
|
|
112
|
+
"@mariozechner/pi-coding-agent": "^0.70.2",
|
|
113
|
+
"@mariozechner/pi-tui": "^0.70.2",
|
|
114
|
+
"@types/node": "^24.3.0",
|
|
115
|
+
"tsx": "^4.21.0",
|
|
116
|
+
"typebox": "^1.1.34",
|
|
117
|
+
"typescript": "^5.7.3",
|
|
118
|
+
"vitest": "^3.2.4"
|
|
119
|
+
},
|
|
120
|
+
"keywords": [
|
|
121
|
+
"pi",
|
|
122
|
+
"extension",
|
|
123
|
+
"para",
|
|
124
|
+
"knowledge-base",
|
|
125
|
+
"wiki"
|
|
126
|
+
],
|
|
127
|
+
"license": "MIT",
|
|
128
|
+
"repository": {
|
|
129
|
+
"type": "git",
|
|
130
|
+
"url": "git+https://github.com/picassio/pi-para.git"
|
|
131
|
+
},
|
|
132
|
+
"homepage": "https://github.com/picassio/pi-para#readme",
|
|
133
|
+
"bugs": {
|
|
134
|
+
"url": "https://github.com/picassio/pi-para/issues"
|
|
135
|
+
},
|
|
136
|
+
"publishConfig": {
|
|
137
|
+
"access": "public"
|
|
138
|
+
},
|
|
139
|
+
"bin": {
|
|
140
|
+
"pi-para-daemon": "./dist/cli.js"
|
|
141
|
+
}
|
|
142
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""Build trainset/valset from real wiki pages.
|
|
2
|
+
|
|
3
|
+
Each example pairs a synthetic task context (derived from the page topic)
|
|
4
|
+
with the actual page body as expected output. The proxy module runs the
|
|
5
|
+
instruction on the task context; the metric scores how well the output
|
|
6
|
+
matches the gold page.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import random
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
import dspy
|
|
15
|
+
|
|
16
|
+
from wiki_reader import WikiPage, load_all_pages, get_wiki_stats
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# -- Task context generators --------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def _capture_context(page: WikiPage) -> str:
|
|
22
|
+
"""Generate a synthetic capture-style task context from a wiki page."""
|
|
23
|
+
scope_str = ", ".join(page.scope) if page.scope else "unknown"
|
|
24
|
+
tags_str = ", ".join(page.tags[:5]) if page.tags else ""
|
|
25
|
+
# Simulate what a session about this topic would look like
|
|
26
|
+
return (
|
|
27
|
+
f"A coding session about '{page.title}' in the {scope_str} project. "
|
|
28
|
+
f"Topics covered: {tags_str}. "
|
|
29
|
+
f"Extract and organize the key knowledge from this session into a wiki page."
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _ingest_context(page: WikiPage) -> str:
|
|
34
|
+
"""Generate a synthetic ingest-style task context."""
|
|
35
|
+
return (
|
|
36
|
+
f"Ingest the following source material about '{page.title}' "
|
|
37
|
+
f"into the PARA wiki. Organize into a structured page with "
|
|
38
|
+
f"proper frontmatter, sections, and cross-references."
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _query_context(page: WikiPage) -> str:
|
|
43
|
+
"""Generate a synthetic query-style task context."""
|
|
44
|
+
return (
|
|
45
|
+
f"The user asked about '{page.title}'. "
|
|
46
|
+
f"Search results returned pages related to: {', '.join(page.scope)}. "
|
|
47
|
+
f"Synthesize a helpful answer citing specific wiki pages."
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _maintenance_context(page: WikiPage) -> str:
|
|
52
|
+
"""Generate a synthetic maintenance-style task context."""
|
|
53
|
+
link_count = len(page.links)
|
|
54
|
+
return (
|
|
55
|
+
f"Review the wiki page '{page.title}' ({page.category}/{page.slug}). "
|
|
56
|
+
f"It has {link_count} outgoing links, scope [{', '.join(page.scope)}], "
|
|
57
|
+
f"tags [{', '.join(page.tags[:5])}]. "
|
|
58
|
+
f"Check for correct categorization, missing links, and content quality."
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _tool_context(page: WikiPage) -> str:
|
|
63
|
+
"""Generate a task context for tool instruction optimization."""
|
|
64
|
+
return (
|
|
65
|
+
f"A user wants to work with the wiki page '{page.title}' "
|
|
66
|
+
f"in category '{page.category}', scope [{', '.join(page.scope)}]. "
|
|
67
|
+
f"Guide them on how to use wiki tools effectively."
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _skill_context(page: WikiPage) -> str:
|
|
72
|
+
"""Generate a task context for skill optimization."""
|
|
73
|
+
return (
|
|
74
|
+
f"Working on a task related to '{page.title}' in the {', '.join(page.scope)} project. "
|
|
75
|
+
f"Apply the PARA knowledge management methodology to this work."
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# Target type → context generator
|
|
80
|
+
CONTEXT_GENERATORS = {
|
|
81
|
+
"capture": _capture_context,
|
|
82
|
+
"ingest": _ingest_context,
|
|
83
|
+
"query": _query_context,
|
|
84
|
+
"maintenance": _maintenance_context,
|
|
85
|
+
"tool": _tool_context,
|
|
86
|
+
"skill": _skill_context,
|
|
87
|
+
"system": _capture_context, # system prompts use capture-style context
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# -- Dataset builder -----------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
def build_dataset(
|
|
94
|
+
wiki_dir: str,
|
|
95
|
+
target_type: str = "capture",
|
|
96
|
+
max_examples: int = 50,
|
|
97
|
+
val_ratio: float = 0.4,
|
|
98
|
+
seed: int = 42,
|
|
99
|
+
) -> tuple[list[dspy.Example], list[dspy.Example]]:
|
|
100
|
+
"""Build train/val datasets from real wiki pages.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
wiki_dir: Path to wiki directory (e.g. ~/.pi/wiki)
|
|
104
|
+
target_type: Type of target being optimized (capture, ingest, query, etc.)
|
|
105
|
+
max_examples: Maximum total examples
|
|
106
|
+
val_ratio: Fraction of examples for validation
|
|
107
|
+
seed: Random seed for reproducible splits
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
(trainset, valset) — lists of dspy.Example
|
|
111
|
+
"""
|
|
112
|
+
pages = load_all_pages(wiki_dir)
|
|
113
|
+
|
|
114
|
+
if not pages:
|
|
115
|
+
raise ValueError(f"No wiki pages found in {wiki_dir}")
|
|
116
|
+
|
|
117
|
+
# Filter to pages with substantial content (at least 200 chars body)
|
|
118
|
+
good_pages = [p for p in pages if len(p.body) >= 200]
|
|
119
|
+
|
|
120
|
+
if len(good_pages) < 4:
|
|
121
|
+
raise ValueError(f"Need at least 4 pages with content, found {len(good_pages)}")
|
|
122
|
+
|
|
123
|
+
# Shuffle deterministically
|
|
124
|
+
rng = random.Random(seed)
|
|
125
|
+
rng.shuffle(good_pages)
|
|
126
|
+
|
|
127
|
+
# Limit to max_examples
|
|
128
|
+
good_pages = good_pages[:max_examples]
|
|
129
|
+
|
|
130
|
+
# Get context generator for this target type
|
|
131
|
+
gen_context = CONTEXT_GENERATORS.get(target_type, _capture_context)
|
|
132
|
+
|
|
133
|
+
# Build examples
|
|
134
|
+
examples = []
|
|
135
|
+
for page in good_pages:
|
|
136
|
+
task_context = gen_context(page)
|
|
137
|
+
|
|
138
|
+
# Gold output: the actual page body (truncated to keep examples manageable)
|
|
139
|
+
expected_output = page.body[:3000] if len(page.body) > 3000 else page.body
|
|
140
|
+
|
|
141
|
+
example = dspy.Example(
|
|
142
|
+
task_context=task_context,
|
|
143
|
+
expected_output=expected_output,
|
|
144
|
+
# Metadata for the metric
|
|
145
|
+
expected_category=page.category,
|
|
146
|
+
expected_scope=",".join(page.scope),
|
|
147
|
+
expected_slug=page.slug,
|
|
148
|
+
expected_title=page.title,
|
|
149
|
+
page_link_count=str(len(page.links)),
|
|
150
|
+
).with_inputs("task_context")
|
|
151
|
+
|
|
152
|
+
examples.append(example)
|
|
153
|
+
|
|
154
|
+
# Split into train/val
|
|
155
|
+
split_idx = max(1, int(len(examples) * (1 - val_ratio)))
|
|
156
|
+
trainset = examples[:split_idx]
|
|
157
|
+
valset = examples[split_idx:]
|
|
158
|
+
|
|
159
|
+
# Ensure minimum sizes
|
|
160
|
+
if len(trainset) < 2:
|
|
161
|
+
trainset = examples[:max(2, len(examples) // 2)]
|
|
162
|
+
valset = examples[len(trainset):]
|
|
163
|
+
if len(valset) < 2:
|
|
164
|
+
valset = trainset[-2:] # share a few from train if needed
|
|
165
|
+
|
|
166
|
+
return trainset, valset
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def get_wiki_context(wiki_dir: str) -> str:
|
|
170
|
+
"""Build a wiki context string for the metric/evaluator."""
|
|
171
|
+
stats = get_wiki_stats(wiki_dir)
|
|
172
|
+
pages = load_all_pages(wiki_dir)
|
|
173
|
+
|
|
174
|
+
# Build a brief summary of existing pages for context
|
|
175
|
+
page_summaries = []
|
|
176
|
+
for p in pages[:30]: # Top 30 pages
|
|
177
|
+
first_line = ""
|
|
178
|
+
for line in p.body.split("\n"):
|
|
179
|
+
line = line.strip()
|
|
180
|
+
if line and not line.startswith("#"):
|
|
181
|
+
first_line = line[:100]
|
|
182
|
+
break
|
|
183
|
+
page_summaries.append(f" - [[{p.slug}]] ({p.category}): {p.title}")
|
|
184
|
+
|
|
185
|
+
context = f"""Wiki has {stats['total_pages']} pages across categories: {stats['categories']}.
|
|
186
|
+
Scopes: {', '.join(stats['unique_scopes'][:10])}.
|
|
187
|
+
Avg links/page: {stats['avg_links_per_page']}.
|
|
188
|
+
|
|
189
|
+
Existing pages:
|
|
190
|
+
{chr(10).join(page_summaries)}"""
|
|
191
|
+
|
|
192
|
+
return context
|