deepclause-pi 0.1.3
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/LICENSE +21 -0
- package/README.md +255 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +59 -0
- package/dist/context.d.ts +3 -0
- package/dist/context.js +38 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +809 -0
- package/dist/planner.d.ts +45 -0
- package/dist/planner.js +223 -0
- package/dist/runtime.d.ts +30 -0
- package/dist/runtime.js +282 -0
- package/dist/workspace.d.ts +12 -0
- package/dist/workspace.js +116 -0
- package/docs/AUTHORING_GUIDE_ANALYSIS.md +172 -0
- package/docs/DC_PLAN_PROPOSAL.md +423 -0
- package/package.json +58 -0
- package/src/assets/AGENTS.md +435 -0
- package/src/assets/deep_research.dml +55 -0
- package/src/config.ts +74 -0
- package/src/context.ts +50 -0
- package/src/index.ts +857 -0
- package/src/planner.ts +265 -0
- package/src/runtime.ts +364 -0
- package/src/workspace.ts +127 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeepClause
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# DeepClause for pi
|
|
2
|
+
|
|
3
|
+
Run [DeepClause](https://github.com/deepclause/deepclause-sdk) DML programs inside [pi](https://github.com/badlogic/pi-mono).
|
|
4
|
+
|
|
5
|
+
DeepClause for pi is a runtime-only integration. Pi supplies the selected model, existing credentials, active session context, terminal UI, cancellation, and usage accounting. DeepClause supplies deterministic DML execution, Prolog constraints, task orchestration, backtracking, and a deliberately small runtime-tool boundary.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- Node.js 22 or newer
|
|
10
|
+
- pi 0.84 or newer
|
|
11
|
+
- A model configured and selected in pi
|
|
12
|
+
- `curl` for the bundled deep-research example
|
|
13
|
+
|
|
14
|
+
The extension does not request API keys or modify provider environment variables.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
Install directly from GitHub:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
pi install git:github.com/deepclause/deepclause-pi
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
For a project-local installation:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
pi install git:github.com/deepclause/deepclause-pi -l
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Restart pi after installation. Run `/dc` to initialize the current workspace and verify the active model and runtime status.
|
|
31
|
+
|
|
32
|
+
For a project-local (`-l`) installation, start pi from the directory containing `.pi/settings.json`. Pi does not discover a project package from a parent directory when launched inside a nested subdirectory. The startup screen should list DeepClause under **Extensions** and `/dc-run` should appear in slash-command completion. If the extension is absent, an input beginning with `/dc-run` is forwarded to the model as ordinary text instead of executing the command.
|
|
33
|
+
|
|
34
|
+
To try an unpublished checkout during development:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
pi -e ./deepclause-pi/src/index.ts
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Commands
|
|
41
|
+
|
|
42
|
+
| Command | Description |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `/dc` | Initialize the workspace non-destructively and show help, model, paths, and status. |
|
|
45
|
+
| `/dc-list` | List authored skills and generated plans. |
|
|
46
|
+
| `/dc-plan <request> [--name=slug]` | Create a validated executable DML plan using pi's current context, skills, and active tools. |
|
|
47
|
+
| `/dc-run <skill> [args]` | Run a named skill such as `example` or `deep_research`. |
|
|
48
|
+
| `/dc-run <path> [args]` | Run a DML file below `.pi/deepclause/`. |
|
|
49
|
+
| `/dc-tool enable\|disable\|status` | Control the default-off `dc_run` tool callable by pi's model. |
|
|
50
|
+
| `/dc-cancel` | Cancel the active DeepClause execution. |
|
|
51
|
+
|
|
52
|
+
Run options:
|
|
53
|
+
|
|
54
|
+
- `--context=turn|branch|isolated` overrides session-context import for one run.
|
|
55
|
+
- `--verbose` or `-v` displays lifecycle events.
|
|
56
|
+
- `--debug` or `-d` displays complete event payloads and SDK model diagnostics.
|
|
57
|
+
|
|
58
|
+
Examples:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
/dc-run example --debug
|
|
62
|
+
/dc-run deep_research "What are the practical impacts of small language models?" --verbose
|
|
63
|
+
/dc-run skills/my_skill.dml "first argument" --context=isolated
|
|
64
|
+
/dc-plan inspect this repository and propose a safe ESM migration --name=esm-migration
|
|
65
|
+
/dc-run plans/esm_migration.dml
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Workspace layout
|
|
69
|
+
|
|
70
|
+
The first `/dc` or `/dc-run` creates missing files under the active workspace:
|
|
71
|
+
|
|
72
|
+
```text
|
|
73
|
+
.pi/deepclause/
|
|
74
|
+
├── config.json
|
|
75
|
+
├── AGENTS.md
|
|
76
|
+
├── DML_REFERENCE.md
|
|
77
|
+
├── skills/
|
|
78
|
+
│ ├── example.dml
|
|
79
|
+
│ └── deep_research.dml
|
|
80
|
+
└── plans/
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Existing files are never overwritten silently. The extension neither creates nor reads `.deepclause/`.
|
|
84
|
+
|
|
85
|
+
`AGENTS.md` teaches pi how to author and conservatively edit DML. `DML_REFERENCE.md` is the bundled language/runtime reference. Add user-maintained programs to `skills/`; `/dc-plan` writes generated executable programs to `plans/`. Pi can edit either with its normal coding tools.
|
|
86
|
+
|
|
87
|
+
## Session context
|
|
88
|
+
|
|
89
|
+
Configure the default mode in `.pi/deepclause/config.json`:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"version": 1,
|
|
94
|
+
"contextMode": "turn",
|
|
95
|
+
"branchMessageLimit": 20,
|
|
96
|
+
"gasLimit": 100000,
|
|
97
|
+
"maxTokens": 16384,
|
|
98
|
+
"verbose": false,
|
|
99
|
+
"modelToolEnabled": false
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- `turn` imports the current request and relevant immediate context. This is the default.
|
|
104
|
+
- `branch` imports a bounded set of messages from the active pi branch, including compacted history.
|
|
105
|
+
- `isolated` imports no pi conversation.
|
|
106
|
+
|
|
107
|
+
Pi remains the sole persistent session owner. Executions stop when their pi session closes or changes, and results are rendered into the current session.
|
|
108
|
+
|
|
109
|
+
## Opt-in model tool
|
|
110
|
+
|
|
111
|
+
The model-callable `dc_run` tool is disabled by default. Enable it explicitly for the current workspace:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
/dc-tool enable
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The change takes effect immediately and persists in `.pi/deepclause/config.json`; no reload is required. Use `/dc-tool status` to inspect it and `/dc-tool disable` to remove it from pi's active tools.
|
|
118
|
+
|
|
119
|
+
When active, pi can call `dc_run` with an existing `skill`, optional positional `args`, and an optional `turn`, `branch`, or `isolated` context override. The tool reuses the same path isolation, active model, cancellation, session context, events, and runtime policy as `/dc-run`. It rejects concurrent execution, cannot compile natural language into DML, and cannot escape `.pi/deepclause/`. Any DML request for `pi_bash` still requires explicit user approval.
|
|
120
|
+
|
|
121
|
+
Contextual plans containing `pi_agent_step` cannot be invoked through `dc_run`. They must be started explicitly by the user with `/dc-run`, which displays a confirmation first.
|
|
122
|
+
|
|
123
|
+
## Contextual executable plans
|
|
124
|
+
|
|
125
|
+
`/dc-plan` starts a normal pi agent turn. The planner can inspect the workspace and account for project instructions, loaded skills, the selected model, and currently active built-in or extension tools. It does not ask the model to emit raw DML. Instead, a transaction-scoped `dc_plan_commit` tool accepts a typed plan specification; the extension validates it, deterministically assembles DML, validates the generated program with the SDK parser, previews it for confirmation, and writes it without overwriting an existing plan.
|
|
126
|
+
|
|
127
|
+
The resulting `.dml` file is the plan. Steps use one of two executors:
|
|
128
|
+
|
|
129
|
+
- `dml` — contained reasoning through ordinary typed DML tasks.
|
|
130
|
+
- `pi` — a bounded `pi_agent_step` that runs as a normal pi turn with current session context and loaded skills.
|
|
131
|
+
|
|
132
|
+
For each pi step, only the exact tools named in the committed plan are temporarily active. They must still be installed and active when execution begins; existing tool policies, UI, and approvals remain authoritative. DeepClause control tools cannot be requested recursively. The prior active-tool set is restored after success, failure, or cancellation.
|
|
133
|
+
|
|
134
|
+
## Runtime tools and approval
|
|
135
|
+
|
|
136
|
+
The extension never exposes pi's general tool registry directly to ordinary DML. The optional `dc_run` tool runs an existing DML program; inside that runtime, only these host operations are registered:
|
|
137
|
+
|
|
138
|
+
- `pi_workspace_list(RelativePath)` — read-only, one-level workspace listing. Absolute paths, traversal, and resolved symlink escapes are rejected.
|
|
139
|
+
- `pi_bash(Command)` — runs an explicitly approved shell command in the active workspace.
|
|
140
|
+
- `pi_bash(Executable, Args)` — runs an explicitly approved executable with a separate argv list, avoiding shell interpolation.
|
|
141
|
+
|
|
142
|
+
Every `pi_bash` call has a 60-second timeout, inherits cancellation, and is denied when interactive approval is unavailable.
|
|
143
|
+
|
|
144
|
+
User-approved contextual plans additionally receive the internal `pi_agent_step` bridge. That bridge delegates a bounded instruction to a normal pi turn rather than invoking arbitrary tools itself, preserving policies from pi and other extensions.
|
|
145
|
+
|
|
146
|
+
DML can wrap these runtime operations in higher-level tool predicates. It can also wrap the SDK's internal `ask_user` operation. During `/dc-run`, `ask_user` opens pi's native, cancellable input UI and returns the response to the DML task loop.
|
|
147
|
+
|
|
148
|
+
```prolog
|
|
149
|
+
tool(user_feedback(Prompt, Response), "Ask the user for feedback") :-
|
|
150
|
+
exec(ask_user(prompt: Prompt), Result),
|
|
151
|
+
get_dict(user_response, Result, Response).
|
|
152
|
+
|
|
153
|
+
tool(bing_search(Query, Results), "Search Bing RSS with curl") :-
|
|
154
|
+
format(string(QueryArg), "q=~w", [Query]),
|
|
155
|
+
exec(pi_bash("curl", [
|
|
156
|
+
"--fail", "--silent", "--show-error", "--location", "--get",
|
|
157
|
+
"--data-urlencode", QueryArg,
|
|
158
|
+
"https://www.bing.com/search?format=rss&count=8"
|
|
159
|
+
]), Result),
|
|
160
|
+
get_dict(stdout, Result, Results).
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
DML predicates remain visible to `task/N` agent loops, while their nested `exec/2` calls are still checked against the host runtime whitelist.
|
|
164
|
+
|
|
165
|
+
## Bundled examples
|
|
166
|
+
|
|
167
|
+
### `example.dml`
|
|
168
|
+
|
|
169
|
+
Demonstrates:
|
|
170
|
+
|
|
171
|
+
- CLP(FD) constraint solving
|
|
172
|
+
- Read-only workspace listing
|
|
173
|
+
- Approval-gated bash execution
|
|
174
|
+
- Typed task output through pi's active model
|
|
175
|
+
- Runtime progress, tool, usage, and answer events
|
|
176
|
+
|
|
177
|
+
Run `/dc-run example --debug` and approve the harmless displayed `printf` command.
|
|
178
|
+
|
|
179
|
+
### `deep_research.dml`
|
|
180
|
+
|
|
181
|
+
Demonstrates model-callable DML tool predicates:
|
|
182
|
+
|
|
183
|
+
1. The model creates three focused research queries.
|
|
184
|
+
2. `user_feedback/2` presents the plan through pi's input UI.
|
|
185
|
+
3. The model revises or accepts the plan.
|
|
186
|
+
4. `bing_search/2` invokes approved `curl` requests against Bing RSS.
|
|
187
|
+
5. The model synthesizes a cited Markdown report from the returned result snippets.
|
|
188
|
+
|
|
189
|
+
The example does not use SDK web search, URL fetch, file writing, or unrestricted pi tools. Each curl request requires explicit approval.
|
|
190
|
+
|
|
191
|
+
## Event presentation
|
|
192
|
+
|
|
193
|
+
Every run displays a live panel containing the skill, active model, context mode, elapsed time, phase, output, recent events, and token usage. Runtime events map into pi as follows:
|
|
194
|
+
|
|
195
|
+
- `task_activity` → progress
|
|
196
|
+
- `stream` → model text
|
|
197
|
+
- `tool_call` → tool activity
|
|
198
|
+
- `input_required` → native pi input prompt
|
|
199
|
+
- `usage` → usage totals
|
|
200
|
+
- `answer` → command result
|
|
201
|
+
- `error` → concise error notification
|
|
202
|
+
|
|
203
|
+
The SDK supports incremental text callbacks inside `task/N`. The current pi adapter uses pi's completion API, so model text presently arrives as one completed stream chunk; task, tool, input, and usage events remain live.
|
|
204
|
+
|
|
205
|
+
## Authoring a skill
|
|
206
|
+
|
|
207
|
+
New workspaces receive a comprehensive `.pi/deepclause/AGENTS.md` authoring guide distilled from the SDK language reference, runtime implementation, examples, compiler prompts, and planning benchmarks. It teaches pi to design DML as deterministic Prolog orchestration around typed model tasks, narrow tools, explicit progress, constraints, and safe fallback.
|
|
208
|
+
|
|
209
|
+
The evidence and design decisions behind it are recorded in [docs/AUTHORING_GUIDE_ANALYSIS.md](docs/AUTHORING_GUIDE_ANALYSIS.md).
|
|
210
|
+
|
|
211
|
+
The design and security rationale for `/dc-plan` are recorded in [docs/DC_PLAN_PROPOSAL.md](docs/DC_PLAN_PROPOSAL.md).
|
|
212
|
+
|
|
213
|
+
The guide covers:
|
|
214
|
+
|
|
215
|
+
- `agent_main/0` through `agent_main/3`, typed `task/N` and isolated `prompt/N`
|
|
216
|
+
- memory, interpolation, dicts, model-callable DML tools, and pi's restricted host tools
|
|
217
|
+
- backtracking, CLP constraints, failure handling, command approval, and validation workflow
|
|
218
|
+
- architecture patterns for research, constrained planning, workspace engineering, compliance gates, interactive expert systems, data pipelines, and generate-review-repair workflows
|
|
219
|
+
|
|
220
|
+
A minimal skill accepts one slash-command argument:
|
|
221
|
+
|
|
222
|
+
```prolog
|
|
223
|
+
agent_main(Topic) :-
|
|
224
|
+
system("You are a concise analyst."),
|
|
225
|
+
format(string(Request), "Explain ~w and store the final text in Summary.", [Topic]),
|
|
226
|
+
task(Request, string(Summary)),
|
|
227
|
+
answer(Summary).
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Before creating or modifying DML, consult `.pi/deepclause/AGENTS.md` and `.pi/deepclause/DML_REFERENCE.md`. DeepClause compilation is intentionally unavailable in this integration; authored content must already be valid DML.
|
|
231
|
+
|
|
232
|
+
## Development
|
|
233
|
+
|
|
234
|
+
```sh
|
|
235
|
+
git clone https://github.com/deepclause/deepclause-pi.git
|
|
236
|
+
cd deepclause-pi
|
|
237
|
+
npm install
|
|
238
|
+
npm run check
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
The package depends on `deepclause-sdk` 0.0.87 and uses pi packages as peer dependencies. The source extension entry point is declared in the `pi.extensions` package field, matching pi's TypeScript extension-loading convention.
|
|
242
|
+
|
|
243
|
+
## Scope
|
|
244
|
+
|
|
245
|
+
- No Markdown-to-DML compiler
|
|
246
|
+
- No dynamic per-skill slash commands
|
|
247
|
+
- No independent DeepClause session or execution-log store
|
|
248
|
+
- No direct DML access to pi's full tool registry
|
|
249
|
+
- No model-callable execution unless the user enables `dc_run` for the workspace
|
|
250
|
+
- No silent mutation of user files
|
|
251
|
+
- No workspace path escape
|
|
252
|
+
|
|
253
|
+
## License
|
|
254
|
+
|
|
255
|
+
MIT. See [LICENSE](LICENSE).
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type ContextMode = "turn" | "branch" | "isolated";
|
|
2
|
+
export interface DeepClauseConfig {
|
|
3
|
+
version: 1;
|
|
4
|
+
contextMode: ContextMode;
|
|
5
|
+
branchMessageLimit: number;
|
|
6
|
+
gasLimit: number;
|
|
7
|
+
maxTokens: number;
|
|
8
|
+
verbose: boolean;
|
|
9
|
+
modelToolEnabled: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare const DEFAULT_CONFIG: DeepClauseConfig;
|
|
12
|
+
export declare function loadConfig(path: string): Promise<DeepClauseConfig>;
|
|
13
|
+
export declare function setModelToolEnabled(configPath: string, enabled: boolean): Promise<DeepClauseConfig>;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
export const DEFAULT_CONFIG = {
|
|
3
|
+
version: 1,
|
|
4
|
+
contextMode: "turn",
|
|
5
|
+
branchMessageLimit: 20,
|
|
6
|
+
gasLimit: 100_000,
|
|
7
|
+
maxTokens: 16_384,
|
|
8
|
+
verbose: false,
|
|
9
|
+
modelToolEnabled: false,
|
|
10
|
+
};
|
|
11
|
+
const isContextMode = (value) => value === "turn" || value === "branch" || value === "isolated";
|
|
12
|
+
export async function loadConfig(path) {
|
|
13
|
+
let value;
|
|
14
|
+
try {
|
|
15
|
+
value = JSON.parse(await readFile(path, "utf8"));
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (error.code === "ENOENT")
|
|
19
|
+
return DEFAULT_CONFIG;
|
|
20
|
+
throw new Error(`Invalid DeepClause config: ${error instanceof Error ? error.message : String(error)}`);
|
|
21
|
+
}
|
|
22
|
+
if (!value || typeof value !== "object")
|
|
23
|
+
throw new Error("DeepClause config must be a JSON object");
|
|
24
|
+
const config = value;
|
|
25
|
+
const contextMode = config.contextMode ?? DEFAULT_CONFIG.contextMode;
|
|
26
|
+
if (!isContextMode(contextMode))
|
|
27
|
+
throw new Error("contextMode must be turn, branch, or isolated");
|
|
28
|
+
const positiveInteger = (key, fallback) => {
|
|
29
|
+
const candidate = config[key] ?? fallback;
|
|
30
|
+
if (!Number.isInteger(candidate) || Number(candidate) <= 0) {
|
|
31
|
+
throw new Error(`${key} must be a positive integer`);
|
|
32
|
+
}
|
|
33
|
+
return Number(candidate);
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
version: 1,
|
|
37
|
+
contextMode,
|
|
38
|
+
branchMessageLimit: positiveInteger("branchMessageLimit", DEFAULT_CONFIG.branchMessageLimit),
|
|
39
|
+
gasLimit: positiveInteger("gasLimit", DEFAULT_CONFIG.gasLimit),
|
|
40
|
+
maxTokens: positiveInteger("maxTokens", DEFAULT_CONFIG.maxTokens),
|
|
41
|
+
verbose: config.verbose === true,
|
|
42
|
+
modelToolEnabled: config.modelToolEnabled === true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export async function setModelToolEnabled(configPath, enabled) {
|
|
46
|
+
let existing = {};
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(await readFile(configPath, "utf8"));
|
|
49
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
50
|
+
existing = parsed;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (error.code !== "ENOENT") {
|
|
54
|
+
throw new Error(`Invalid DeepClause config: ${error instanceof Error ? error.message : String(error)}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
await writeFile(configPath, `${JSON.stringify({ ...existing, modelToolEnabled: enabled }, null, 2)}\n`, "utf8");
|
|
58
|
+
return loadConfig(configPath);
|
|
59
|
+
}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
function textContent(content) {
|
|
2
|
+
if (typeof content === "string")
|
|
3
|
+
return content;
|
|
4
|
+
if (!Array.isArray(content))
|
|
5
|
+
return "";
|
|
6
|
+
return content
|
|
7
|
+
.filter((block) => Boolean(block) && typeof block === "object")
|
|
8
|
+
.filter((block) => block.type === "text" && typeof block.text === "string")
|
|
9
|
+
.map((block) => block.text)
|
|
10
|
+
.join("\n");
|
|
11
|
+
}
|
|
12
|
+
function entryToMessage(entry) {
|
|
13
|
+
if (entry.type === "compaction" && typeof entry.summary === "string") {
|
|
14
|
+
return { role: "system", content: `Compacted pi session context:\n${entry.summary}` };
|
|
15
|
+
}
|
|
16
|
+
if (entry.type !== "message" || !entry.message)
|
|
17
|
+
return undefined;
|
|
18
|
+
if (entry.message.role !== "user" && entry.message.role !== "assistant")
|
|
19
|
+
return undefined;
|
|
20
|
+
const content = textContent(entry.message.content).trim();
|
|
21
|
+
return content ? { role: entry.message.role, content } : undefined;
|
|
22
|
+
}
|
|
23
|
+
export function buildInitialMessages(entries, mode, branchMessageLimit) {
|
|
24
|
+
if (mode === "isolated")
|
|
25
|
+
return [];
|
|
26
|
+
const messages = entries
|
|
27
|
+
.map(entryToMessage)
|
|
28
|
+
.filter((message) => message !== undefined);
|
|
29
|
+
if (mode === "branch")
|
|
30
|
+
return messages.slice(-branchMessageLimit);
|
|
31
|
+
const immediate = [];
|
|
32
|
+
for (let index = messages.length - 1; index >= 0 && immediate.length < 2; index--) {
|
|
33
|
+
const message = messages[index];
|
|
34
|
+
if (message)
|
|
35
|
+
immediate.unshift(message);
|
|
36
|
+
}
|
|
37
|
+
return immediate;
|
|
38
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { type ContextMode } from "./config.js";
|
|
3
|
+
export interface ParsedRun {
|
|
4
|
+
target: string;
|
|
5
|
+
args: string[];
|
|
6
|
+
contextMode?: ContextMode;
|
|
7
|
+
verbose: boolean;
|
|
8
|
+
debug: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface ParsedPlan {
|
|
11
|
+
request: string;
|
|
12
|
+
name?: string;
|
|
13
|
+
debug: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function splitArguments(input: string): string[];
|
|
16
|
+
export declare function parseRun(input: string): ParsedRun;
|
|
17
|
+
export declare function parsePlan(input: string): ParsedPlan;
|
|
18
|
+
export default function deepClauseExtension(pi: ExtensionAPI): void;
|
|
19
|
+
export {};
|