@runfusion/fusion 0.12.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 +526 -157
- package/dist/client/assets/{AgentDetailView-B20ApPe1.js → AgentDetailView-B7j297GT.js} +4 -4
- package/dist/client/assets/AgentsView-Dvf_xUkx.js +522 -0
- package/dist/client/assets/{AgentsView-Bkk-uBij.css → AgentsView-V5GhlBYu.css} +1 -1
- package/dist/client/assets/{ChatView-oPMFwmoc.js → ChatView-BgUt38ty.js} +1 -1
- package/dist/client/assets/{DevServerView-DQrVLbK5.js → DevServerView-C2qTJch7.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-DVmy6sLM.js → DirectoryPicker-DRfhg9zz.js} +1 -1
- package/dist/client/assets/{DocumentsView-DHEv-Q2a.js → DocumentsView-j8ic1xUw.js} +1 -1
- package/dist/client/assets/{InsightsView-ByyY7GX7.js → InsightsView-CpAz3o0i.js} +3 -3
- package/dist/client/assets/{MemoryView-Udiu0u8R.js → MemoryView-BcQsi_JK.js} +2 -2
- package/dist/client/assets/{NodesView-CupS-GGc.js → NodesView-Bo_Yhr4N.js} +4 -4
- package/dist/client/assets/{PiExtensionsManager-DXs2xI8K.js → PiExtensionsManager-DHt2zFg8.js} +3 -3
- package/dist/client/assets/PluginManager-BQhBHWrB.js +1 -0
- package/dist/client/assets/{ResearchView-BG9Feaeb.js → ResearchView-CLyyqAWE.js} +1 -1
- package/dist/client/assets/{RoadmapsView-BTJtmBnF.js → RoadmapsView-tG7IdOoc.js} +2 -2
- package/dist/client/assets/{SettingsModal-eNCZiHa6.js → SettingsModal-CXUGeZ0_.js} +1 -1
- package/dist/client/assets/{SettingsModal-DZ_LaEhd.js → SettingsModal-UziTDnLh.js} +3 -3
- package/dist/client/assets/{SetupWizardModal-yf79TN1L.js → SetupWizardModal-BMJL6eNR.js} +1 -1
- package/dist/client/assets/{SkillMultiselect-DOj5vX4U.js → SkillMultiselect-ILMft-Kz.js} +1 -1
- package/dist/client/assets/{SkillsView-CgnCnikX.js → SkillsView-x4_YwBz6.js} +1 -1
- package/dist/client/assets/{TodoView-67BMyICY.js → TodoView-BBYcMbXE.js} +2 -2
- package/dist/client/assets/{folder-open-D11gjHGK.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-CBzPc3GA.js → list-checks-DFxQ9biT.js} +1 -1
- package/dist/client/assets/{star-BWcRk8nt.js → star-BKs1bgJN.js} +1 -1
- package/dist/client/assets/{upload-91TM4ljC.js → upload-Bb5Pidne.js} +1 -1
- package/dist/client/assets/{users-BAsI___L.js → users-BImNn91Q.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/extension.js +70 -23
- 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/dist/client/assets/AgentsView-ChN1tgQ0.js +0 -522
- package/dist/client/assets/PluginManager-BCpiZf4_.js +0 -1
- package/dist/client/assets/index-BLn1R7Ob.css +0 -1
- package/dist/client/assets/index-CLAHcGnI.js +0 -656
package/dist/client/index.html
CHANGED
|
@@ -92,11 +92,11 @@
|
|
|
92
92
|
}
|
|
93
93
|
})();
|
|
94
94
|
</script>
|
|
95
|
-
<script type="module" crossorigin src="/assets/index-
|
|
95
|
+
<script type="module" crossorigin src="/assets/index-DmSs2FGE.js"></script>
|
|
96
96
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-K0fH_qHe.js">
|
|
97
97
|
<link rel="modulepreload" crossorigin href="/assets/vendor-xterm-DzcZoU0P.js">
|
|
98
98
|
<link rel="stylesheet" crossorigin href="/assets/vendor-xterm-LZoznX6r.css">
|
|
99
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
99
|
+
<link rel="stylesheet" crossorigin href="/assets/index-B15xwijw.css">
|
|
100
100
|
</head>
|
|
101
101
|
<body>
|
|
102
102
|
<div id="root"></div>
|
package/dist/client/version.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"
|
|
1
|
+
{"version":"mon8x2sx-75359cb6"}
|
package/dist/extension.js
CHANGED
|
@@ -79,6 +79,7 @@ var init_settings_schema = __esm({
|
|
|
79
79
|
showGitHubStarButton: true,
|
|
80
80
|
modelOnboardingComplete: void 0,
|
|
81
81
|
useClaudeCli: void 0,
|
|
82
|
+
useDroidCli: void 0,
|
|
82
83
|
// Global baseline lanes for per-role model selection
|
|
83
84
|
executionGlobalProvider: void 0,
|
|
84
85
|
executionGlobalModelId: void 0,
|
|
@@ -2704,7 +2705,7 @@ var init_db = __esm({
|
|
|
2704
2705
|
"use strict";
|
|
2705
2706
|
init_sqlite_adapter();
|
|
2706
2707
|
init_types();
|
|
2707
|
-
SCHEMA_VERSION =
|
|
2708
|
+
SCHEMA_VERSION = 57;
|
|
2708
2709
|
SCHEMA_SQL = `
|
|
2709
2710
|
-- Tasks table with JSON columns for nested data
|
|
2710
2711
|
CREATE TABLE IF NOT EXISTS tasks (
|
|
@@ -4388,6 +4389,23 @@ CREATE INDEX IF NOT EXISTS idxTodoItemsSortOrder ON todo_items(listId, sortOrder
|
|
|
4388
4389
|
this.db.exec(`CREATE INDEX IF NOT EXISTS idxResearchExportsRunId ON research_exports(runId)`);
|
|
4389
4390
|
});
|
|
4390
4391
|
}
|
|
4392
|
+
if (version < 56) {
|
|
4393
|
+
this.applyMigration(56, () => {
|
|
4394
|
+
if (this.hasTable("chat_sessions")) {
|
|
4395
|
+
this.addColumnIfMissing("chat_sessions", "cliSessionFile", "TEXT");
|
|
4396
|
+
}
|
|
4397
|
+
});
|
|
4398
|
+
}
|
|
4399
|
+
if (version < 57) {
|
|
4400
|
+
this.applyMigration(57, () => {
|
|
4401
|
+
if (this.hasTable("ai_sessions")) {
|
|
4402
|
+
this.addColumnIfMissing("ai_sessions", "archived", "INTEGER DEFAULT 0");
|
|
4403
|
+
this.db.exec(
|
|
4404
|
+
"CREATE INDEX IF NOT EXISTS idxAiSessionsArchived ON ai_sessions(archived)"
|
|
4405
|
+
);
|
|
4406
|
+
}
|
|
4407
|
+
});
|
|
4408
|
+
}
|
|
4391
4409
|
}
|
|
4392
4410
|
/**
|
|
4393
4411
|
* Run a single migration step inside a transaction and bump the version.
|
|
@@ -38004,7 +38022,7 @@ function sanitizeTitle(raw) {
|
|
|
38004
38022
|
const firstLine = raw.split(/\r?\n/).map((l) => l.trim()).find((l) => l.length > 0);
|
|
38005
38023
|
if (!firstLine) return null;
|
|
38006
38024
|
let title = firstLine.replace(/^[-*]\s+/, "").replace(/^["'`]+|["'`]+$/g, "").trim();
|
|
38007
|
-
title = title.replace(/^(?:title|subject|here(?:'s| is)(?: the)? title|generated title)\s*[
|
|
38025
|
+
title = title.replace(/^(?:title|subject|here(?:'s| is)(?: the)? title|generated title)\s*[:-]\s*/i, "").trim();
|
|
38008
38026
|
title = title.replace(/\*\*([^*]+)\*\*/g, "$1").replace(/__([^_]+)__/g, "$1").replace(/(?<![*\w])\*([^*]+)\*(?![*\w])/g, "$1").replace(/(?<![_\w])_([^_]+)_(?![_\w])/g, "$1");
|
|
38009
38027
|
title = title.replace(/[.!?,;:]+$/, "").trim();
|
|
38010
38028
|
if (!title) return null;
|
|
@@ -49952,7 +49970,8 @@ var init_chat_store = __esm({
|
|
|
49952
49970
|
modelProvider: row.modelProvider ?? null,
|
|
49953
49971
|
modelId: row.modelId ?? null,
|
|
49954
49972
|
createdAt: row.createdAt,
|
|
49955
|
-
updatedAt: row.updatedAt
|
|
49973
|
+
updatedAt: row.updatedAt,
|
|
49974
|
+
cliSessionFile: row.cliSessionFile ?? null
|
|
49956
49975
|
};
|
|
49957
49976
|
}
|
|
49958
49977
|
/**
|
|
@@ -49989,7 +50008,8 @@ var init_chat_store = __esm({
|
|
|
49989
50008
|
modelProvider: input.modelProvider ?? null,
|
|
49990
50009
|
modelId: input.modelId ?? null,
|
|
49991
50010
|
createdAt: now,
|
|
49992
|
-
updatedAt: now
|
|
50011
|
+
updatedAt: now,
|
|
50012
|
+
cliSessionFile: null
|
|
49993
50013
|
};
|
|
49994
50014
|
this.db.prepare(`
|
|
49995
50015
|
INSERT INTO chat_sessions (id, agentId, title, status, projectId, modelProvider, modelId, createdAt, updatedAt)
|
|
@@ -50147,6 +50167,21 @@ var init_chat_store = __esm({
|
|
|
50147
50167
|
archiveSession(id) {
|
|
50148
50168
|
return this.updateSession(id, { status: "archived" });
|
|
50149
50169
|
}
|
|
50170
|
+
/**
|
|
50171
|
+
* Persist the pi/Claude CLI session file path for a chat. Called once,
|
|
50172
|
+
* after the SessionManager for the chat first creates its on-disk file,
|
|
50173
|
+
* so subsequent turns can reopen it via SessionManager.open.
|
|
50174
|
+
*
|
|
50175
|
+
* Does not bump updatedAt or emit events — this is internal plumbing,
|
|
50176
|
+
* not a user-visible state change.
|
|
50177
|
+
*
|
|
50178
|
+
* @param id - Session ID
|
|
50179
|
+
* @param cliSessionFile - Absolute path to the session file, or null to clear
|
|
50180
|
+
*/
|
|
50181
|
+
setCliSessionFile(id, cliSessionFile) {
|
|
50182
|
+
this.db.prepare("UPDATE chat_sessions SET cliSessionFile = ? WHERE id = ?").run(cliSessionFile, id);
|
|
50183
|
+
this.db.bumpLastModified();
|
|
50184
|
+
}
|
|
50150
50185
|
/**
|
|
50151
50186
|
* Delete a chat session and all its messages.
|
|
50152
50187
|
* Messages are cascade-deleted via foreign key constraint.
|
|
@@ -83696,25 +83731,21 @@ async function ensureNtfyHelpersReady() {
|
|
|
83696
83731
|
if (planningNtfyHelpers) {
|
|
83697
83732
|
return;
|
|
83698
83733
|
}
|
|
83699
|
-
|
|
83700
|
-
|
|
83701
|
-
|
|
83702
|
-
|
|
83703
|
-
|
|
83704
|
-
|
|
83705
|
-
|
|
83706
|
-
|
|
83707
|
-
|
|
83708
|
-
|
|
83709
|
-
|
|
83710
|
-
|
|
83711
|
-
|
|
83712
|
-
|
|
83713
|
-
|
|
83714
|
-
{ operation: "notification-service-detection" }
|
|
83715
|
-
);
|
|
83716
|
-
}
|
|
83717
|
-
} catch {
|
|
83734
|
+
const hasNotificationService = "NotificationService" in src_exports2 && typeof NotificationService === "function";
|
|
83735
|
+
const hasAllHelpers = "isNtfyEventEnabled" in src_exports2 && "buildNtfyClickUrl" in src_exports2 && "sendNtfyNotification" in src_exports2 && typeof isNtfyEventEnabled === "function" && typeof buildNtfyClickUrl === "function" && typeof sendNtfyNotification === "function";
|
|
83736
|
+
if (!hasAllHelpers) {
|
|
83737
|
+
return;
|
|
83738
|
+
}
|
|
83739
|
+
planningNtfyHelpers = {
|
|
83740
|
+
isNtfyEventEnabled,
|
|
83741
|
+
buildNtfyClickUrl,
|
|
83742
|
+
sendNtfyNotification
|
|
83743
|
+
};
|
|
83744
|
+
if (hasNotificationService) {
|
|
83745
|
+
diagnostics.info(
|
|
83746
|
+
"NotificationService abstraction detected in engine",
|
|
83747
|
+
{ operation: "notification-service-detection" }
|
|
83748
|
+
);
|
|
83718
83749
|
}
|
|
83719
83750
|
}
|
|
83720
83751
|
function safeParseJson(text, fallback, options) {
|
|
@@ -84504,6 +84535,7 @@ var init_planning = __esm({
|
|
|
84504
84535
|
init_sse_buffer();
|
|
84505
84536
|
init_ai_session_diagnostics();
|
|
84506
84537
|
init_src2();
|
|
84538
|
+
init_src2();
|
|
84507
84539
|
createFnAgent4 = createFnAgent2;
|
|
84508
84540
|
diagnostics = createSessionDiagnostics("planning");
|
|
84509
84541
|
PLANNING_SYSTEM_PROMPT = `You are a planning assistant for the fn task board system.
|
|
@@ -92836,6 +92868,7 @@ var init_register_agent_core_routes = __esm({
|
|
|
92836
92868
|
"use strict";
|
|
92837
92869
|
init_src();
|
|
92838
92870
|
init_api_error();
|
|
92871
|
+
init_src2();
|
|
92839
92872
|
}
|
|
92840
92873
|
});
|
|
92841
92874
|
|
|
@@ -92848,10 +92881,13 @@ var init_register_agent_runtime_routes = __esm({
|
|
|
92848
92881
|
});
|
|
92849
92882
|
|
|
92850
92883
|
// ../dashboard/src/routes/register-agent-reflection-rating-routes.ts
|
|
92884
|
+
var AgentReflectionServiceBinding;
|
|
92851
92885
|
var init_register_agent_reflection_rating_routes = __esm({
|
|
92852
92886
|
"../dashboard/src/routes/register-agent-reflection-rating-routes.ts"() {
|
|
92853
92887
|
"use strict";
|
|
92854
92888
|
init_api_error();
|
|
92889
|
+
init_src2();
|
|
92890
|
+
AgentReflectionServiceBinding = "AgentReflectionService" in src_exports2 && typeof AgentReflectionService === "function" ? AgentReflectionService : void 0;
|
|
92855
92891
|
}
|
|
92856
92892
|
});
|
|
92857
92893
|
|
|
@@ -92994,12 +93030,20 @@ var init_claude_cli_probe = __esm({
|
|
|
92994
93030
|
}
|
|
92995
93031
|
});
|
|
92996
93032
|
|
|
93033
|
+
// ../dashboard/src/droid-cli-probe.ts
|
|
93034
|
+
var init_droid_cli_probe = __esm({
|
|
93035
|
+
"../dashboard/src/droid-cli-probe.ts"() {
|
|
93036
|
+
"use strict";
|
|
93037
|
+
}
|
|
93038
|
+
});
|
|
93039
|
+
|
|
92997
93040
|
// ../dashboard/src/routes/register-auth-routes.ts
|
|
92998
93041
|
var init_register_auth_routes = __esm({
|
|
92999
93042
|
"../dashboard/src/routes/register-auth-routes.ts"() {
|
|
93000
93043
|
"use strict";
|
|
93001
93044
|
init_src();
|
|
93002
93045
|
init_claude_cli_probe();
|
|
93046
|
+
init_droid_cli_probe();
|
|
93003
93047
|
init_api_error();
|
|
93004
93048
|
init_usage();
|
|
93005
93049
|
init_project_store_resolver();
|
|
@@ -93860,6 +93904,7 @@ var init_insights_routes = __esm({
|
|
|
93860
93904
|
"../dashboard/src/insights-routes.ts"() {
|
|
93861
93905
|
"use strict";
|
|
93862
93906
|
init_api_error();
|
|
93907
|
+
init_src2();
|
|
93863
93908
|
}
|
|
93864
93909
|
});
|
|
93865
93910
|
|
|
@@ -97725,6 +97770,7 @@ var init_terminal_websocket_diagnostics = __esm({
|
|
|
97725
97770
|
|
|
97726
97771
|
// ../dashboard/src/chat.ts
|
|
97727
97772
|
import { EventEmitter as EventEmitter30 } from "node:events";
|
|
97773
|
+
import { SessionManager as SessionManager3 } from "@mariozechner/pi-coding-agent";
|
|
97728
97774
|
var defaultDiagnostics, _diagnostics, diagnostics7, RATE_LIMIT_WINDOW_MS6, MAX_REFERENCED_FILE_SIZE, ChatStreamManager, chatStreamManager;
|
|
97729
97775
|
var init_chat = __esm({
|
|
97730
97776
|
"../dashboard/src/chat.ts"() {
|
|
@@ -97732,6 +97778,7 @@ var init_chat = __esm({
|
|
|
97732
97778
|
init_src();
|
|
97733
97779
|
init_sse_buffer();
|
|
97734
97780
|
init_src2();
|
|
97781
|
+
init_src2();
|
|
97735
97782
|
defaultDiagnostics = {
|
|
97736
97783
|
log(message, ...args) {
|
|
97737
97784
|
console.log(`[chat] ${message}`, ...args);
|
|
@@ -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",
|