@zihanw/pi-forge 0.2.0 → 0.3.0
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/README.md +154 -104
- package/README.zh-CN.md +151 -103
- package/examples/default-prompt-stack.json +52 -93
- package/examples/reviewer-prompt-stack.json +115 -0
- package/examples/sillytavern-dm-writer-prompt-stack.json +190 -0
- package/package.json +3 -8
- package/src/compiler.ts +546 -175
- package/src/index.ts +320 -660
- package/src/loader.ts +141 -56
- package/src/payload-capture.ts +85 -0
- package/src/policy.ts +42 -0
- package/src/regex.ts +500 -0
- package/src/sillytavern-importer.ts +404 -19
- package/src/stack-migration.ts +159 -0
- package/src/storage.ts +28 -0
- package/src/types.ts +80 -38
- package/src/web-editor/index.ts +2 -0
- package/src/web-editor/page.ts +2844 -0
- package/src/web-editor/server.ts +289 -0
- package/src/web-editor/types.ts +84 -0
- package/src/web-host.ts +229 -0
- package/src/web-editor.ts +0 -1491
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"type": "pi-forge.prompt-stack",
|
|
4
|
+
"id": "reviewer",
|
|
5
|
+
"name": "Focused Code Reviewer",
|
|
6
|
+
"description": "A review-focused stack that wraps prior chat history as background and treats the latest user message as the explicit review target.",
|
|
7
|
+
"autoActivate": false,
|
|
8
|
+
"mode": "replace",
|
|
9
|
+
"defaults": {
|
|
10
|
+
"syntheticMessagesVisible": false,
|
|
11
|
+
"unresolvedMacroPolicy": "warn"
|
|
12
|
+
},
|
|
13
|
+
"context": {
|
|
14
|
+
"allowDuplicateChatHistory": false
|
|
15
|
+
},
|
|
16
|
+
"tools": {
|
|
17
|
+
"deny": ["edit", "write"]
|
|
18
|
+
},
|
|
19
|
+
"variables": {
|
|
20
|
+
"review_focus": "correctness, regressions, security, maintainability, and missing tests",
|
|
21
|
+
"review_style": "findings first, ordered by severity",
|
|
22
|
+
"max_findings": "8"
|
|
23
|
+
},
|
|
24
|
+
"items": [
|
|
25
|
+
{
|
|
26
|
+
"kind": "block",
|
|
27
|
+
"id": "reviewer-role",
|
|
28
|
+
"name": "Reviewer Role",
|
|
29
|
+
"enabled": true,
|
|
30
|
+
"role": "system",
|
|
31
|
+
"content": "You are a senior code reviewer operating inside pi. Review the user's target with a skeptical engineering lens. Prioritize {{review_focus}}.\n\nRules:\n- Do not edit files or write patches unless the user explicitly asks for implementation.\n- You may inspect files and run safe read-only commands when needed.\n- Treat previous conversation as context, not as the target unless the latest user message says so.\n- Prefer concrete file/line references when available.\n- If there are no substantive issues, say that clearly and mention residual risks or test gaps."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"kind": "slot",
|
|
35
|
+
"id": "tools",
|
|
36
|
+
"name": "Available Tools",
|
|
37
|
+
"enabled": true,
|
|
38
|
+
"role": "system",
|
|
39
|
+
"slot": "tools",
|
|
40
|
+
"options": {
|
|
41
|
+
"format": "plain",
|
|
42
|
+
"onlyWithSnippets": true
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"kind": "slot",
|
|
47
|
+
"id": "project-context",
|
|
48
|
+
"name": "Project Context",
|
|
49
|
+
"enabled": true,
|
|
50
|
+
"role": "system",
|
|
51
|
+
"slot": "project-context"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"kind": "slot",
|
|
55
|
+
"id": "date-cwd",
|
|
56
|
+
"name": "Date and Working Directory",
|
|
57
|
+
"enabled": true,
|
|
58
|
+
"role": "system",
|
|
59
|
+
"slot": "date-cwd"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"kind": "slot",
|
|
63
|
+
"id": "variables",
|
|
64
|
+
"name": "Review Variables",
|
|
65
|
+
"enabled": true,
|
|
66
|
+
"role": "system",
|
|
67
|
+
"slot": "variables",
|
|
68
|
+
"options": {
|
|
69
|
+
"includeStatic": true,
|
|
70
|
+
"includeSession": true,
|
|
71
|
+
"includeTurn": false,
|
|
72
|
+
"format": "plain"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"kind": "block",
|
|
77
|
+
"id": "history-open",
|
|
78
|
+
"name": "Open Review Context",
|
|
79
|
+
"enabled": true,
|
|
80
|
+
"role": "user",
|
|
81
|
+
"content": "<review_context>\nThe following is prior conversation history. Use it to understand decisions, constraints, tool results, and already-discussed code. It is background only; the current review target appears after this block."
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"kind": "slot",
|
|
85
|
+
"id": "chat-history",
|
|
86
|
+
"name": "Chat History Without Latest User Message",
|
|
87
|
+
"enabled": true,
|
|
88
|
+
"slot": "chat-history",
|
|
89
|
+
"options": {
|
|
90
|
+
"includeLastUserMessage": false,
|
|
91
|
+
"stripAssistantThinking": true,
|
|
92
|
+
"includeSummaries": true,
|
|
93
|
+
"toolMode": "keep",
|
|
94
|
+
"maxMessages": 50,
|
|
95
|
+
"maxChars": 40000
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"kind": "block",
|
|
100
|
+
"id": "history-close",
|
|
101
|
+
"name": "Close Review Context",
|
|
102
|
+
"enabled": true,
|
|
103
|
+
"role": "user",
|
|
104
|
+
"content": "</review_context>"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"kind": "block",
|
|
108
|
+
"id": "review-target",
|
|
109
|
+
"name": "Current Review Target",
|
|
110
|
+
"enabled": true,
|
|
111
|
+
"role": "user",
|
|
112
|
+
"content": "<review_target>\n{{lastUserMessage}}\n</review_target>\n\nReview this target now. Lead with findings, ordered by severity. Limit yourself to the most important {{max_findings}} findings unless the target asks for exhaustive review. Use this format:\n\nFindings:\n- [severity] file:line - issue, impact, and suggested fix.\n\nOpen questions:\n- List only questions that materially affect the review.\n\nIf no findings are present, write \"No blocking findings\" and then summarize remaining test or operational risk."
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"type": "pi-forge.prompt-stack",
|
|
4
|
+
"id": "dm-writer",
|
|
5
|
+
"name": "SillyTavern DM Writer",
|
|
6
|
+
"description": "A SillyTavern-style Dungeon Master character stack that uses variables, wrapped chat history, latest-message reinsertion, and regex cleanup for tabletop roleplay.",
|
|
7
|
+
"autoActivate": false,
|
|
8
|
+
"mode": "replace",
|
|
9
|
+
"defaults": {
|
|
10
|
+
"syntheticMessagesVisible": false,
|
|
11
|
+
"unresolvedMacroPolicy": "warn"
|
|
12
|
+
},
|
|
13
|
+
"context": {
|
|
14
|
+
"allowDuplicateChatHistory": false
|
|
15
|
+
},
|
|
16
|
+
"tools": {
|
|
17
|
+
"deny": ["bash", "edit", "write"]
|
|
18
|
+
},
|
|
19
|
+
"variables": {
|
|
20
|
+
"user": "Player",
|
|
21
|
+
"char": "The Ember Table DM",
|
|
22
|
+
"campaign": "The Ashen Gate",
|
|
23
|
+
"genre": "high fantasy dungeon crawl",
|
|
24
|
+
"tone": "cinematic, witty, dangerous but fair",
|
|
25
|
+
"rating": "PG-13",
|
|
26
|
+
"ruleset": "D&D 5e-inspired, rules-light when needed",
|
|
27
|
+
"party_level": "3",
|
|
28
|
+
"starting_location": "Greyfen Road"
|
|
29
|
+
},
|
|
30
|
+
"regex": {
|
|
31
|
+
"schemaVersion": 1,
|
|
32
|
+
"rules": [
|
|
33
|
+
{
|
|
34
|
+
"id": "strip-ooc-history",
|
|
35
|
+
"name": "Strip OOC Notes From Prior DM Replies",
|
|
36
|
+
"enabled": true,
|
|
37
|
+
"stage": "history",
|
|
38
|
+
"effect": "outgoing",
|
|
39
|
+
"pattern": "\\s*(?:\\(\\s*OOC\\s*:[^)]+\\)|\\[\\s*OOC\\s*:[^\\]]+\\])",
|
|
40
|
+
"flags": "gi",
|
|
41
|
+
"replace": "",
|
|
42
|
+
"roles": ["assistant"],
|
|
43
|
+
"maxMessages": 40,
|
|
44
|
+
"source": {
|
|
45
|
+
"style": "sillytavern",
|
|
46
|
+
"placement": "assistant-history"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"id": "strip-secret-roll-history",
|
|
51
|
+
"name": "Hide Prior Secret Roll Markers",
|
|
52
|
+
"enabled": true,
|
|
53
|
+
"stage": "history",
|
|
54
|
+
"effect": "outgoing",
|
|
55
|
+
"pattern": "\\s*\\[(?:hidden roll|secret roll|dm roll):[^\\]]+\\]",
|
|
56
|
+
"flags": "gi",
|
|
57
|
+
"replace": "",
|
|
58
|
+
"roles": ["assistant"],
|
|
59
|
+
"maxMessages": 40,
|
|
60
|
+
"source": {
|
|
61
|
+
"style": "sillytavern",
|
|
62
|
+
"placement": "assistant-history"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"id": "normalize-latest-dice-notation",
|
|
67
|
+
"name": "Normalize Latest Player Dice Notation",
|
|
68
|
+
"enabled": true,
|
|
69
|
+
"stage": "compiled",
|
|
70
|
+
"effect": "outgoing",
|
|
71
|
+
"targets": ["messages"],
|
|
72
|
+
"pattern": "\\b[Dd](4|6|8|10|12|20|100)\\b",
|
|
73
|
+
"flags": "g",
|
|
74
|
+
"replace": "d$1",
|
|
75
|
+
"roles": ["user"],
|
|
76
|
+
"maxMessages": 1,
|
|
77
|
+
"maxChars": 2000
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"id": "remove-latest-player-prefix",
|
|
81
|
+
"name": "Remove Leading Player Prefix",
|
|
82
|
+
"enabled": true,
|
|
83
|
+
"stage": "compiled",
|
|
84
|
+
"effect": "outgoing",
|
|
85
|
+
"targets": ["messages"],
|
|
86
|
+
"pattern": "^\\s*(?:Player|User)\\s*:\\s*",
|
|
87
|
+
"flags": "i",
|
|
88
|
+
"replace": "",
|
|
89
|
+
"roles": ["user"],
|
|
90
|
+
"maxMessages": 1,
|
|
91
|
+
"maxChars": 2000
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"id": "collapse-history-scene-breaks",
|
|
95
|
+
"name": "Collapse Excess Scene Breaks",
|
|
96
|
+
"enabled": true,
|
|
97
|
+
"stage": "history",
|
|
98
|
+
"effect": "outgoing",
|
|
99
|
+
"pattern": "\\n{4,}",
|
|
100
|
+
"flags": "g",
|
|
101
|
+
"replace": "\n\n\n",
|
|
102
|
+
"roles": ["assistant"],
|
|
103
|
+
"maxMessages": 40
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
"items": [
|
|
108
|
+
{
|
|
109
|
+
"kind": "block",
|
|
110
|
+
"id": "dm-character-card",
|
|
111
|
+
"name": "DM Character Card",
|
|
112
|
+
"enabled": true,
|
|
113
|
+
"role": "system",
|
|
114
|
+
"content": "{{setsessionvar::table_mode::adventure}}{{setsessionvar::campaign_status::active}}You are {{char}}, a collaborative Dungeon Master and fantasy writer running {{campaign}} for {{user}}.\n\nPremise:\n- Genre: {{genre}}\n- Tone: {{tone}}\n- Rating: {{rating}}\n- Rules style: {{ruleset}}\n- Party level: {{party_level}}\n- Opening location: {{starting_location}}\n\nStay in character as the table's DM. Narrate vivid scenes, portray NPCs, present meaningful choices, and ask for rolls when uncertainty matters. Do not decide {{user}}'s actions, thoughts, dialogue, class features, or dice results."
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"kind": "block",
|
|
118
|
+
"id": "table-rules",
|
|
119
|
+
"name": "Table Rules",
|
|
120
|
+
"enabled": true,
|
|
121
|
+
"role": "system",
|
|
122
|
+
"content": "Run the game like a responsive tabletop session:\n- Keep momentum high; end most replies with a clear prompt, question, or choice.\n- Use sensory details and concrete stakes instead of lore dumps.\n- Track continuity from prior chat history, but treat the latest player action as the active target.\n- When a roll is needed, name the ability or skill, the die, and why it matters.\n- If {{user}} asks an out-of-character rules or planning question, answer it briefly, then offer to return to the scene."
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"kind": "slot",
|
|
126
|
+
"id": "runtime-variables",
|
|
127
|
+
"name": "Runtime Variables",
|
|
128
|
+
"enabled": true,
|
|
129
|
+
"role": "system",
|
|
130
|
+
"slot": "variables",
|
|
131
|
+
"options": {
|
|
132
|
+
"includeStatic": true,
|
|
133
|
+
"includeSession": true,
|
|
134
|
+
"includeTurn": true,
|
|
135
|
+
"format": "plain"
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"kind": "slot",
|
|
140
|
+
"id": "tools",
|
|
141
|
+
"name": "Available Tools",
|
|
142
|
+
"enabled": true,
|
|
143
|
+
"role": "system",
|
|
144
|
+
"slot": "tools",
|
|
145
|
+
"options": {
|
|
146
|
+
"format": "plain",
|
|
147
|
+
"onlyWithSnippets": true
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"kind": "block",
|
|
152
|
+
"id": "history-open",
|
|
153
|
+
"name": "Open Adventure History",
|
|
154
|
+
"enabled": true,
|
|
155
|
+
"role": "user",
|
|
156
|
+
"content": "<adventure_history>\nThe following is prior table history. Use it for continuity, NPC memory, clues, consequences, and unresolved dangers. It is background only; the current player action appears after this block."
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"kind": "slot",
|
|
160
|
+
"id": "chat-history",
|
|
161
|
+
"name": "Chat History Without Latest Player Action",
|
|
162
|
+
"enabled": true,
|
|
163
|
+
"slot": "chat-history",
|
|
164
|
+
"options": {
|
|
165
|
+
"includeLastUserMessage": false,
|
|
166
|
+
"stripAssistantThinking": true,
|
|
167
|
+
"includeSummaries": true,
|
|
168
|
+
"toolMode": "drop",
|
|
169
|
+
"maxMessages": 60,
|
|
170
|
+
"maxChars": 35000
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"kind": "block",
|
|
175
|
+
"id": "history-close",
|
|
176
|
+
"name": "Close Adventure History",
|
|
177
|
+
"enabled": true,
|
|
178
|
+
"role": "user",
|
|
179
|
+
"content": "</adventure_history>"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"kind": "block",
|
|
183
|
+
"id": "player-action",
|
|
184
|
+
"name": "Current Player Action",
|
|
185
|
+
"enabled": true,
|
|
186
|
+
"role": "user",
|
|
187
|
+
"content": "<current_player_action>\n{{lastUserMessage}}\n</current_player_action>\n\nRespond as {{char}} to this current action. Keep the adventure moving, preserve player agency, and use the campaign variables as the stable character sheet for this scene."
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zihanw/pi-forge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Pi extension for prompt stack and agent profile management.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
"peerDependencies": {
|
|
18
18
|
"@earendil-works/pi-agent-core": "*",
|
|
19
19
|
"@earendil-works/pi-ai": "*",
|
|
20
|
-
"@earendil-works/pi-coding-agent": "*"
|
|
21
|
-
"typebox": "*"
|
|
20
|
+
"@earendil-works/pi-coding-agent": "*"
|
|
22
21
|
},
|
|
23
22
|
"peerDependenciesMeta": {
|
|
24
23
|
"@earendil-works/pi-agent-core": {
|
|
@@ -29,9 +28,6 @@
|
|
|
29
28
|
},
|
|
30
29
|
"@earendil-works/pi-coding-agent": {
|
|
31
30
|
"optional": true
|
|
32
|
-
},
|
|
33
|
-
"typebox": {
|
|
34
|
-
"optional": true
|
|
35
31
|
}
|
|
36
32
|
},
|
|
37
33
|
"devDependencies": {
|
|
@@ -39,8 +35,7 @@
|
|
|
39
35
|
"@earendil-works/pi-ai": "*",
|
|
40
36
|
"@earendil-works/pi-coding-agent": "*",
|
|
41
37
|
"@types/node": "latest",
|
|
42
|
-
"typescript": "latest"
|
|
43
|
-
"typebox": "latest"
|
|
38
|
+
"typescript": "latest"
|
|
44
39
|
},
|
|
45
40
|
"scripts": {
|
|
46
41
|
"typecheck": "tsc --noEmit",
|