@runfusion/fusion 0.11.0 → 0.13.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/dist/bin.js +1644 -509
- package/dist/client/assets/{AgentDetailView-DQBjJSPJ.js → AgentDetailView-B7j297GT.js} +4 -4
- package/dist/client/assets/AgentsView-Dvf_xUkx.js +522 -0
- package/dist/client/assets/{AgentsView-xm_3NO4M.css → AgentsView-V5GhlBYu.css} +1 -1
- package/dist/client/assets/ChatView-BgUt38ty.js +1 -0
- package/dist/client/assets/{DevServerView-BVixhlF0.js → DevServerView-C2qTJch7.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-tvBgHxa7.js → DirectoryPicker-DRfhg9zz.js} +1 -1
- package/dist/client/assets/{DocumentsView-DVw_wT6V.js → DocumentsView-j8ic1xUw.js} +1 -1
- package/dist/client/assets/{InsightsView-G3MZhwSx.js → InsightsView-CpAz3o0i.js} +3 -3
- package/dist/client/assets/{MemoryView-Bl9gx2Dw.js → MemoryView-BcQsi_JK.js} +2 -2
- package/dist/client/assets/{NodesView-dwVhD4V2.js → NodesView-Bo_Yhr4N.js} +4 -4
- package/dist/client/assets/{PiExtensionsManager-CEHp6_Mj.js → PiExtensionsManager-DHt2zFg8.js} +3 -3
- package/dist/client/assets/{PluginManager-Dx0mcwat.js → PluginManager-BQhBHWrB.js} +1 -1
- package/dist/client/assets/ResearchView-BzRdUzNq.css +1 -0
- package/dist/client/assets/{ResearchView-BvlLYC_1.js → ResearchView-CLyyqAWE.js} +1 -1
- package/dist/client/assets/{RoadmapsView-DdYXssP2.js → RoadmapsView-tG7IdOoc.js} +2 -2
- package/dist/client/assets/{SettingsModal-CGWipm3s.js → SettingsModal-CXUGeZ0_.js} +1 -1
- package/dist/client/assets/{SettingsModal-CriZP5Lp.css → SettingsModal-DcGFm6NR.css} +1 -1
- package/dist/client/assets/SettingsModal-UziTDnLh.js +31 -0
- package/dist/client/assets/{SetupWizardModal-CKsJduYM.js → SetupWizardModal-BMJL6eNR.js} +1 -1
- package/dist/client/assets/SkillMultiselect-DDHJnrkn.css +1 -0
- package/dist/client/assets/SkillMultiselect-ILMft-Kz.js +1 -0
- package/dist/client/assets/SkillsView-x4_YwBz6.js +1 -0
- package/dist/client/assets/{TodoView-ByXJ90yL.js → TodoView-BBYcMbXE.js} +2 -2
- package/dist/client/assets/{folder-open-CxOUgHDf.js → folder-open-DDdJt8aE.js} +1 -1
- package/dist/client/assets/index-B15xwijw.css +1 -0
- package/dist/client/assets/index-DmSs2FGE.js +661 -0
- package/dist/client/assets/{list-checks--sf9u9ox.js → list-checks-DFxQ9biT.js} +1 -1
- package/dist/client/assets/{star-CF1f2iPu.js → star-BKs1bgJN.js} +1 -1
- package/dist/client/assets/{upload-rOBd4OhB.js → upload-Bb5Pidne.js} +1 -1
- package/dist/client/assets/{users-De-vFat1.js → users-BImNn91Q.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/theme-data.css +1 -1
- package/dist/client/version.json +1 -1
- package/dist/extension.js +548 -96
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/pi-claude-cli/src/__tests__/prompt-builder.test.ts +36 -0
- package/dist/pi-claude-cli/src/prompt-builder.ts +19 -28
- package/package.json +1 -1
- package/skill/fusion/references/cli-commands.md +14 -0
- package/skill/fusion/references/engine-tools.md +1 -0
- package/dist/client/assets/AgentsView-DlA0yHBg.js +0 -522
- package/dist/client/assets/ChatView-DK5CmiAk.js +0 -1
- package/dist/client/assets/ResearchView-BVJFgfat.css +0 -1
- package/dist/client/assets/SettingsModal-Bgjg_4CD.js +0 -31
- package/dist/client/assets/SkillsView-C4Tz7CxC.js +0 -1
- package/dist/client/assets/index-BCz4ye4p.css +0 -1
- package/dist/client/assets/index-D7gT6mCr.js +0 -656
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion/pi-claude-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Fusion vendored fork: pi coding-agent extension that routes LLM calls through the Claude Code CLI. Forked from rchern/pi-claude-cli (MIT). See UPSTREAM.md.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": true,
|
|
@@ -1145,6 +1145,42 @@ describe("buildResumePrompt", () => {
|
|
|
1145
1145
|
expect(buildResumePrompt(context)).toBe("Hello from blocks");
|
|
1146
1146
|
});
|
|
1147
1147
|
|
|
1148
|
+
// Regression: multi-iteration tool loops re-anchor on the LAST assistant
|
|
1149
|
+
// turn, not the (only) user message at index 0. Previously this dumped the
|
|
1150
|
+
// entire transcript into a "user" prompt every iteration, ballooning the
|
|
1151
|
+
// resumed session.
|
|
1152
|
+
it("returns ONLY the trailing tool result during a multi-iteration tool loop", () => {
|
|
1153
|
+
const context = {
|
|
1154
|
+
messages: [
|
|
1155
|
+
{ role: "user", content: "Find foo" },
|
|
1156
|
+
{
|
|
1157
|
+
role: "assistant",
|
|
1158
|
+
content: [{ type: "toolCall", name: "find", arguments: { pattern: "foo" } }],
|
|
1159
|
+
},
|
|
1160
|
+
{ role: "toolResult", toolName: "find", content: "no matches (turn 1)" },
|
|
1161
|
+
{
|
|
1162
|
+
role: "assistant",
|
|
1163
|
+
content: [{ type: "toolCall", name: "find", arguments: { pattern: "foo" } }],
|
|
1164
|
+
},
|
|
1165
|
+
{ role: "toolResult", toolName: "find", content: "no matches (turn 2)" },
|
|
1166
|
+
],
|
|
1167
|
+
};
|
|
1168
|
+
const result = buildResumePrompt(context) as string;
|
|
1169
|
+
expect(result).toContain("no matches (turn 2)");
|
|
1170
|
+
expect(result).not.toContain("no matches (turn 1)");
|
|
1171
|
+
expect(result).not.toContain("Find foo");
|
|
1172
|
+
});
|
|
1173
|
+
|
|
1174
|
+
it("returns empty string mid-loop when only an assistant turn exists since the last delta", () => {
|
|
1175
|
+
const context = {
|
|
1176
|
+
messages: [
|
|
1177
|
+
{ role: "user", content: "Hi" },
|
|
1178
|
+
{ role: "assistant", content: "Working..." },
|
|
1179
|
+
],
|
|
1180
|
+
};
|
|
1181
|
+
expect(buildResumePrompt(context)).toBe("");
|
|
1182
|
+
});
|
|
1183
|
+
|
|
1148
1184
|
it("handles images in the final user message by returning ContentBlock[]", () => {
|
|
1149
1185
|
const context = {
|
|
1150
1186
|
messages: [
|
|
@@ -166,44 +166,36 @@ function buildCustomToolResultPrompt(messages: PiMessage[]): string | null {
|
|
|
166
166
|
/**
|
|
167
167
|
* Build a prompt for a resumed session.
|
|
168
168
|
*
|
|
169
|
-
* When resuming via --resume, the CLI already has the full conversation history
|
|
170
|
-
*
|
|
171
|
-
*
|
|
169
|
+
* When resuming via --resume, the CLI already has the full conversation history
|
|
170
|
+
* up through (and including) the most recent assistant turn that it produced.
|
|
171
|
+
* We only need to send the *delta* since that turn: any trailing tool results
|
|
172
|
+
* for the last assistant tool_use, and/or a new user message.
|
|
172
173
|
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
174
|
+
* Why anchor on the last assistant message (not the last user message)?
|
|
175
|
+
* Pi's tool-use loop appends `[user, assistant(toolUse), toolResult,
|
|
176
|
+
* assistant(toolUse), toolResult, ...]` — the only `user` entry stays at index
|
|
177
|
+
* 0 across many provider invocations. Anchoring on the last user message and
|
|
178
|
+
* walking forward (the prior implementation) re-sent the entire transcript on
|
|
179
|
+
* every tool-loop iteration, so each --resume turn appended a duplicate of the
|
|
180
|
+
* original query plus a growing stack of tool results to the on-disk session.
|
|
176
181
|
*
|
|
177
|
-
*
|
|
182
|
+
* Returns "" when there's nothing new to send (e.g. only an assistant message
|
|
183
|
+
* exists in the context — can happen mid-shutdown).
|
|
178
184
|
*/
|
|
179
185
|
export function buildResumePrompt(context: PiContext): string | AnthropicContentBlock[] {
|
|
180
186
|
const messages = context.messages;
|
|
181
187
|
if (messages.length === 0) return "";
|
|
182
188
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
// Collect new messages: everything from the last assistant turn onwards
|
|
188
|
-
// (tool results from the last assistant + the new user message)
|
|
189
|
-
const newMessages: PiMessage[] = [];
|
|
190
|
-
|
|
191
|
-
// Walk backwards from finalUserIndex to find where new content starts.
|
|
192
|
-
// Include trailing toolResult messages that follow the last assistant turn.
|
|
193
|
-
let startIdx = finalUserIndex;
|
|
194
|
-
for (let i = finalUserIndex - 1; i >= 0; i--) {
|
|
195
|
-
if (messages[i].role === "toolResult") {
|
|
196
|
-
startIdx = i;
|
|
197
|
-
} else {
|
|
189
|
+
let lastAssistantIdx = -1;
|
|
190
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
191
|
+
if (messages[i].role === "assistant") {
|
|
192
|
+
lastAssistantIdx = i;
|
|
198
193
|
break;
|
|
199
194
|
}
|
|
200
195
|
}
|
|
196
|
+
const newMessages = messages.slice(lastAssistantIdx + 1);
|
|
197
|
+
if (newMessages.length === 0) return "";
|
|
201
198
|
|
|
202
|
-
for (let i = startIdx; i < messages.length; i++) {
|
|
203
|
-
newMessages.push(messages[i]);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// If there are only tool results + one user message, build a combined prompt
|
|
207
199
|
const parts: string[] = [];
|
|
208
200
|
for (const msg of newMessages) {
|
|
209
201
|
if (msg.role === "toolResult") {
|
|
@@ -217,7 +209,6 @@ export function buildResumePrompt(context: PiContext): string | AnthropicContent
|
|
|
217
209
|
}
|
|
218
210
|
parts.push(toolResultContentToText(msg.content));
|
|
219
211
|
} else if (msg.role === "user") {
|
|
220
|
-
// Check for images in the final user message
|
|
221
212
|
if (contentHasImages(msg.content)) {
|
|
222
213
|
const textSoFar = parts.join("\n");
|
|
223
214
|
const userContent = buildFinalUserContent(msg.content);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
|
|
6
6
|
"homepage": "https://github.com/Runfusion/Fusion#readme",
|
|
@@ -40,6 +40,20 @@ fn task logs FN-001 --limit 50 # Limit log lines
|
|
|
40
40
|
fn task logs FN-001 --type tool # Filter by log type
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
## Research
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
fn research create --query "question" # Create research run
|
|
47
|
+
fn research create --query "question" --wait # Wait for completion
|
|
48
|
+
fn research list # List runs
|
|
49
|
+
fn research ls --status failed --limit 20 # Filter by status
|
|
50
|
+
fn research show RR-001 # Show one run
|
|
51
|
+
fn research export RR-001 --format json # Export to JSON
|
|
52
|
+
fn research export RR-001 --output ./run.md # Export to specific path
|
|
53
|
+
fn research cancel RR-001 # Cancel active run
|
|
54
|
+
fn research retry RR-001 # Retry failed/cancelled run
|
|
55
|
+
```
|
|
56
|
+
|
|
43
57
|
## Mission Management
|
|
44
58
|
|
|
45
59
|
```bash
|
|
@@ -55,4 +55,5 @@ These tools are **not** part of the pi extension's user-invokable `extension.ts`
|
|
|
55
55
|
|
|
56
56
|
| Tool | Purpose | Parameters |
|
|
57
57
|
|---|---|---|
|
|
58
|
+
| `fn_identity` | Return loaded soul/instructions/memory summary for this heartbeat tick (must be called first) | none |
|
|
58
59
|
| `fn_heartbeat_done` | Signal end of heartbeat run with optional summary | `summary?` (string) |
|