@runfusion/fusion 0.24.0 → 0.26.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 +6 -0
- package/dist/bin.js +18646 -15669
- package/dist/client/assets/AgentDetailView-Cv-vgOj3.js +18 -0
- package/dist/client/assets/{AgentsView-BkB9FiMT.js → AgentsView-D6Zi5zfP.js} +4 -4
- package/dist/client/assets/ChatView-CAHjY9uO.js +1 -0
- package/dist/client/assets/{DevServerView-BkvtjZBa.js → DevServerView--_WBvIDQ.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-BK-KbnhP.js → DirectoryPicker-xedtR-Rd.js} +1 -1
- package/dist/client/assets/{DocumentsView-BEg1CQAk.js → DocumentsView-Bg2oaZks.js} +1 -1
- package/dist/client/assets/{EvalsView-Berf9bQm.js → EvalsView-B3uOCXfr.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-jcInE50G.js → ExperimentalAgentOnboardingModal-Bx6yXVS5.js} +1 -1
- package/dist/client/assets/{InsightsView-BX5bSF1J.js → InsightsView-Q1zvtF4F.js} +1 -1
- package/dist/client/assets/MemoryView-xcN_eouf.js +2 -0
- package/dist/client/assets/MemoryView-zaXewZzi.css +1 -0
- package/dist/client/assets/{NodesView-DLUOBLf6.js → NodesView-RxXg58_Q.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-COlJf0Kx.js → PiExtensionsManager-Cc8aAZXg.js} +2 -2
- package/dist/client/assets/PluginManager-BEkyBajl.js +1 -0
- package/dist/client/assets/{ResearchView-BzCcDAS4.css → ResearchView-BEI4ZSGs.css} +1 -1
- package/dist/client/assets/ResearchView-CERNf7sJ.js +1 -0
- package/dist/client/assets/{SettingsModal-yRqM4DV8.js → SettingsModal-B1r0yASu.js} +1 -1
- package/dist/client/assets/SettingsModal-BLsac7CJ.js +31 -0
- package/dist/client/assets/SettingsModal-Cis-4Lot.css +1 -0
- package/dist/client/assets/{SetupWizardModal-uUZk3TKT.js → SetupWizardModal-D1q548_L.js} +1 -1
- package/dist/client/assets/{SkillsView-CP8JX0P_.js → SkillsView-ClLM6u6p.js} +1 -1
- package/dist/client/assets/StashRecoveryView-B_8WIQEo.css +1 -0
- package/dist/client/assets/StashRecoveryView-ze0pEZ5U.js +1 -0
- package/dist/client/assets/{TodoView-DCRIkDZ-.js → TodoView-CTmIfy2M.js} +1 -1
- package/dist/client/assets/{dashboard-view-lR7YYmSC.js → dashboard-view-4xAN3yO5.js} +2 -2
- package/dist/client/assets/{folder-open-DHjELt8-.js → folder-open-BZuKESeq.js} +1 -1
- package/dist/client/assets/index-Bdw6llW6.js +692 -0
- package/dist/client/assets/index-CZGlyJuS.css +1 -0
- package/dist/client/assets/{star-DYesq1AV.js → star-D75YKEq-.js} +1 -1
- package/dist/client/assets/{upload-DTWF3Db5.js → upload-BYYTgWFj.js} +1 -1
- package/dist/client/assets/{users--syrel4l.js → users-RS90Aii3.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +5640 -3618
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/manifest.json +6 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +26 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/manifest.test.ts +20 -0
- package/dist/plugins/fusion-plugin-cli-printing-press/src/index.ts +14 -0
- package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +9 -11
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +30 -0
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +3 -28
- package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +899 -895
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +68 -71
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +47 -50
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +155 -109
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/src/index.ts +49 -3
- package/dist/plugins/fusion-plugin-reports/src/report-schema.ts +38 -0
- package/dist/plugins/fusion-plugin-reports/src/store/__tests__/report-schema.test.ts +66 -0
- package/dist/plugins/fusion-plugin-reports/src/store/__tests__/report-store.test.ts +177 -0
- package/dist/plugins/fusion-plugin-reports/src/store/report-store.ts +341 -0
- package/dist/plugins/fusion-plugin-reports/src/store/report-types.ts +77 -0
- package/dist/plugins/fusion-plugin-roadmap/{src/dashboard/RoadmapsView.css → bundled.css} +13 -219
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +29535 -0
- package/dist/plugins/fusion-plugin-roadmap/package.json +4 -41
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +2 -3
- package/dist/client/assets/AgentDetailView-gy_5SUj2.js +0 -18
- package/dist/client/assets/ChatView-B_-B8fqu.js +0 -1
- package/dist/client/assets/MemoryView-CKElJY_3.js +0 -2
- package/dist/client/assets/MemoryView-DiajLXby.css +0 -1
- package/dist/client/assets/PluginManager-CfW55BF4.js +0 -1
- package/dist/client/assets/ResearchView-B256Lr8I.js +0 -1
- package/dist/client/assets/SettingsModal-BeA_nQtW.js +0 -31
- package/dist/client/assets/SettingsModal-DzsLquBu.css +0 -1
- package/dist/client/assets/index-CQyVRLOb.js +0 -692
- package/dist/client/assets/index-CxA2Nn0_.css +0 -1
- package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.css +0 -58
- package/dist/plugins/fusion-plugin-dependency-graph/src/DependencyGraph.tsx +0 -301
- package/dist/plugins/fusion-plugin-dependency-graph/src/GraphHighlight.css +0 -27
- package/dist/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.css +0 -157
- package/dist/plugins/fusion-plugin-dependency-graph/src/GraphTaskNode.tsx +0 -126
- package/dist/plugins/fusion-plugin-dependency-graph/src/GraphToolbar.css +0 -35
- package/dist/plugins/fusion-plugin-dependency-graph/src/GraphToolbar.tsx +0 -36
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraph.highlighting.test.tsx +0 -112
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraph.persistence.test.tsx +0 -115
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/DependencyGraph.test.tsx +0 -128
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.drag.test.tsx +0 -82
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphTaskNode.test.tsx +0 -307
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/GraphToolbar.test.tsx +0 -60
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/edges.test.tsx +0 -75
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/filtering.test.tsx +0 -62
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/filters.test.ts +0 -78
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/graphPositionStorage.test.ts +0 -95
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/host-integration.test.ts +0 -74
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/index.test.ts +0 -58
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/interactions.test.tsx +0 -121
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/layout.test.ts +0 -70
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/persistence.test.tsx +0 -89
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useGraphData.test.ts +0 -86
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useGraphInteraction.test.ts +0 -167
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useGraphPositions.test.ts +0 -66
- package/dist/plugins/fusion-plugin-dependency-graph/src/__tests__/useNodeDrag.test.ts +0 -81
- package/dist/plugins/fusion-plugin-dependency-graph/src/dashboard-interop.d.ts +0 -35
- package/dist/plugins/fusion-plugin-dependency-graph/src/dashboard-view.tsx +0 -19
- package/dist/plugins/fusion-plugin-dependency-graph/src/edges.tsx +0 -70
- package/dist/plugins/fusion-plugin-dependency-graph/src/filters.ts +0 -8
- package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/__tests__/useDependencyChain.test.ts +0 -53
- package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/useDependencyChain.ts +0 -60
- package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/useGraphPositions.ts +0 -45
- package/dist/plugins/fusion-plugin-dependency-graph/src/hooks/useNodeDrag.ts +0 -114
- package/dist/plugins/fusion-plugin-dependency-graph/src/index.ts +0 -24
- package/dist/plugins/fusion-plugin-dependency-graph/src/layout.ts +0 -91
- package/dist/plugins/fusion-plugin-dependency-graph/src/styles/drag.css +0 -15
- package/dist/plugins/fusion-plugin-dependency-graph/src/types.ts +0 -21
- package/dist/plugins/fusion-plugin-dependency-graph/src/useGraphData.ts +0 -17
- package/dist/plugins/fusion-plugin-dependency-graph/src/useGraphInteraction.ts +0 -292
- package/dist/plugins/fusion-plugin-dependency-graph/src/utils/graphPositionStorage.ts +0 -65
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/api-client.test.ts +0 -101
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/index.test.ts +0 -92
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/roadmap-routes.test.ts +0 -48
- package/dist/plugins/fusion-plugin-roadmap/src/__tests__/roadmap-suggestions.test.ts +0 -31
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/RoadmapsView.tsx +0 -2559
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/__tests__/RoadmapsView.test.tsx +0 -1144
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/__tests__/useRoadmaps.test.ts +0 -1756
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/api.ts +0 -70
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/test-setup.ts +0 -7
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/types.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useConfirm.ts +0 -8
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useRoadmaps.ts +0 -1188
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard/useViewportMode.ts +0 -20
- package/dist/plugins/fusion-plugin-roadmap/src/dashboard-view.tsx +0 -6
- package/dist/plugins/fusion-plugin-roadmap/src/index.ts +0 -74
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-routes.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-schema.ts +0 -41
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-suggestions.d.ts +0 -15
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-suggestions.ts +0 -15
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.d.ts +0 -283
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.js +0 -21
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/roadmap-types.ts +0 -310
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.d.ts +0 -5
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.js +0 -361
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-routes.ts +0 -408
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.d.ts +0 -68
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.js +0 -300
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/routes/roadmap-suggestions.ts +0 -381
- package/dist/plugins/fusion-plugin-roadmap/src/server/index.d.ts +0 -3
- package/dist/plugins/fusion-plugin-roadmap/src/server/index.ts +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-handoff.test.ts +0 -445
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-ordering.test.ts +0 -334
- package/dist/plugins/fusion-plugin-roadmap/src/store/__tests__/roadmap-store.test.ts +0 -1318
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-handoff.ts +0 -163
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.d.ts +0 -37
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.js +0 -188
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-ordering.ts +0 -311
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.d.ts +0 -299
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.d.ts.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.js +0 -765
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.js.map +0 -1
- package/dist/plugins/fusion-plugin-roadmap/src/store/roadmap-store.ts +0 -1001
|
@@ -16797,7 +16797,7 @@ var init_models = __esm({
|
|
|
16797
16797
|
});
|
|
16798
16798
|
|
|
16799
16799
|
// ../../node_modules/.pnpm/@mariozechner+pi-ai@0.72.1_@modelcontextprotocol+sdk@1.28.0_zod@4.3.6__ws@8.20.0_zod@4.3.6/node_modules/@mariozechner/pi-ai/dist/utils/event-stream.js
|
|
16800
|
-
var EventStream,
|
|
16800
|
+
var EventStream, AssistantMessageEventStream;
|
|
16801
16801
|
var init_event_stream = __esm({
|
|
16802
16802
|
"../../node_modules/.pnpm/@mariozechner+pi-ai@0.72.1_@modelcontextprotocol+sdk@1.28.0_zod@4.3.6__ws@8.20.0_zod@4.3.6/node_modules/@mariozechner/pi-ai/dist/utils/event-stream.js"() {
|
|
16803
16803
|
EventStream = class {
|
|
@@ -16857,7 +16857,7 @@ var init_event_stream = __esm({
|
|
|
16857
16857
|
return this.finalResultPromise;
|
|
16858
16858
|
}
|
|
16859
16859
|
};
|
|
16860
|
-
|
|
16860
|
+
AssistantMessageEventStream = class extends EventStream {
|
|
16861
16861
|
constructor() {
|
|
16862
16862
|
super((event) => event.type === "done" || event.type === "error", (event) => {
|
|
16863
16863
|
if (event.type === "done") {
|
|
@@ -18600,7 +18600,7 @@ var init_openai_codex_responses = __esm({
|
|
|
18600
18600
|
"in_progress"
|
|
18601
18601
|
]);
|
|
18602
18602
|
streamOpenAICodexResponses = (model, context, options) => {
|
|
18603
|
-
const stream2 = new
|
|
18603
|
+
const stream2 = new AssistantMessageEventStream();
|
|
18604
18604
|
(async () => {
|
|
18605
18605
|
const output = {
|
|
18606
18606
|
role: "assistant",
|
|
@@ -26131,7 +26131,7 @@ var init_anthropic = __esm({
|
|
|
26131
26131
|
"content_block_stop"
|
|
26132
26132
|
]);
|
|
26133
26133
|
streamAnthropic = (model, context, options) => {
|
|
26134
|
-
const stream2 = new
|
|
26134
|
+
const stream2 = new AssistantMessageEventStream();
|
|
26135
26135
|
(async () => {
|
|
26136
26136
|
const output = {
|
|
26137
26137
|
role: "assistant",
|
|
@@ -34474,7 +34474,7 @@ var init_azure_openai_responses = __esm({
|
|
|
34474
34474
|
DEFAULT_AZURE_API_VERSION = "v1";
|
|
34475
34475
|
AZURE_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set(["openai", "openai-codex", "opencode", "azure-openai-responses"]);
|
|
34476
34476
|
streamAzureOpenAIResponses = (model, context, options) => {
|
|
34477
|
-
const stream2 = new
|
|
34477
|
+
const stream2 = new AssistantMessageEventStream();
|
|
34478
34478
|
(async () => {
|
|
34479
34479
|
const deploymentName = resolveDeploymentName(model, options);
|
|
34480
34480
|
const output = {
|
|
@@ -74649,7 +74649,7 @@ var init_google = __esm({
|
|
|
74649
74649
|
init_simple_options();
|
|
74650
74650
|
toolCallCounter = 0;
|
|
74651
74651
|
streamGoogle = (model, context, options) => {
|
|
74652
|
-
const stream2 = new
|
|
74652
|
+
const stream2 = new AssistantMessageEventStream();
|
|
74653
74653
|
(async () => {
|
|
74654
74654
|
const output = {
|
|
74655
74655
|
role: "assistant",
|
|
@@ -75078,7 +75078,7 @@ var init_google_vertex = __esm({
|
|
|
75078
75078
|
};
|
|
75079
75079
|
toolCallCounter2 = 0;
|
|
75080
75080
|
streamGoogleVertex = (model, context, options) => {
|
|
75081
|
-
const stream2 = new
|
|
75081
|
+
const stream2 = new AssistantMessageEventStream();
|
|
75082
75082
|
(async () => {
|
|
75083
75083
|
const output = {
|
|
75084
75084
|
role: "assistant",
|
|
@@ -127353,7 +127353,7 @@ var init_mistral = __esm({
|
|
|
127353
127353
|
MISTRAL_TOOL_CALL_ID_LENGTH = 9;
|
|
127354
127354
|
MAX_MISTRAL_ERROR_BODY_CHARS = 4e3;
|
|
127355
127355
|
streamMistral = (model, context, options) => {
|
|
127356
|
-
const stream2 = new
|
|
127356
|
+
const stream2 = new AssistantMessageEventStream();
|
|
127357
127357
|
(async () => {
|
|
127358
127358
|
const output = createOutput(model);
|
|
127359
127359
|
try {
|
|
@@ -127946,7 +127946,7 @@ var init_openai_completions = __esm({
|
|
|
127946
127946
|
init_simple_options();
|
|
127947
127947
|
init_transform_messages();
|
|
127948
127948
|
streamOpenAICompletions = (model, context, options) => {
|
|
127949
|
-
const stream2 = new
|
|
127949
|
+
const stream2 = new AssistantMessageEventStream();
|
|
127950
127950
|
(async () => {
|
|
127951
127951
|
const output = {
|
|
127952
127952
|
role: "assistant",
|
|
@@ -128337,7 +128337,7 @@ var init_openai_responses = __esm({
|
|
|
128337
128337
|
init_simple_options();
|
|
128338
128338
|
OPENAI_TOOL_CALL_PROVIDERS = /* @__PURE__ */ new Set(["openai", "openai-codex", "opencode"]);
|
|
128339
128339
|
streamOpenAIResponses = (model, context, options) => {
|
|
128340
|
-
const stream2 = new
|
|
128340
|
+
const stream2 = new AssistantMessageEventStream();
|
|
128341
128341
|
(async () => {
|
|
128342
128342
|
const output = {
|
|
128343
128343
|
role: "assistant",
|
|
@@ -128415,645 +128415,21 @@ var init_openai_responses = __esm({
|
|
|
128415
128415
|
}
|
|
128416
128416
|
});
|
|
128417
128417
|
|
|
128418
|
-
// ../plugin-sdk/
|
|
128418
|
+
// ../plugin-sdk/src/index.ts
|
|
128419
128419
|
function definePlugin(plugin2) {
|
|
128420
128420
|
return plugin2;
|
|
128421
128421
|
}
|
|
128422
128422
|
|
|
128423
|
-
// ../../plugins/fusion-plugin-droid-runtime/
|
|
128423
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/cli-spawn.ts
|
|
128424
128424
|
function resolveCliSettings(settings2) {
|
|
128425
128425
|
const binaryPath = typeof settings2?.droidBinaryPath === "string" && settings2.droidBinaryPath.trim().length > 0 ? settings2.droidBinaryPath.trim() : "droid";
|
|
128426
128426
|
const model = typeof settings2?.droidModel === "string" ? settings2.droidModel : void 0;
|
|
128427
128427
|
return { binaryPath, model };
|
|
128428
128428
|
}
|
|
128429
128429
|
|
|
128430
|
-
// ../../plugins/fusion-plugin-droid-runtime/
|
|
128430
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/provider.ts
|
|
128431
128431
|
import { createInterface } from "node:readline";
|
|
128432
128432
|
|
|
128433
|
-
// ../../plugins/fusion-plugin-droid-runtime/dist/prompt-builder.js
|
|
128434
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
128435
|
-
import { resolve, join, dirname } from "node:path";
|
|
128436
|
-
import { homedir } from "node:os";
|
|
128437
|
-
|
|
128438
|
-
// ../../plugins/fusion-plugin-droid-runtime/dist/tool-mapping.js
|
|
128439
|
-
var TOOL_MAPPINGS = [
|
|
128440
|
-
{ claude: "Read", pi: "read", args: { file_path: "path" } },
|
|
128441
|
-
{ claude: "Write", pi: "write", args: { file_path: "path" } },
|
|
128442
|
-
{
|
|
128443
|
-
claude: "Edit",
|
|
128444
|
-
pi: "edit",
|
|
128445
|
-
args: { file_path: "path", old_string: "oldText", new_string: "newText" }
|
|
128446
|
-
},
|
|
128447
|
-
{ claude: "Bash", pi: "bash", args: {} },
|
|
128448
|
-
{ claude: "Grep", pi: "grep", args: { head_limit: "limit" } },
|
|
128449
|
-
{ claude: "Glob", pi: "find", args: {} }
|
|
128450
|
-
];
|
|
128451
|
-
var CUSTOM_TOOLS_MCP_PREFIX = "mcp__custom-tools__";
|
|
128452
|
-
var BUILT_IN_PI_NAMES = new Set(TOOL_MAPPINGS.map((m2) => m2.pi));
|
|
128453
|
-
function isCustomToolName(piName) {
|
|
128454
|
-
return !BUILT_IN_PI_NAMES.has(piName);
|
|
128455
|
-
}
|
|
128456
|
-
function isPiKnownDroidTool(claudeName) {
|
|
128457
|
-
if (claudeName.startsWith(CUSTOM_TOOLS_MCP_PREFIX))
|
|
128458
|
-
return true;
|
|
128459
|
-
return claudeName.toLowerCase() in DROID_TO_PI_NAME;
|
|
128460
|
-
}
|
|
128461
|
-
var DROID_TO_PI_NAME = {};
|
|
128462
|
-
var PI_TO_DROID_NAME = {};
|
|
128463
|
-
var DROID_TO_PI_ARGS = {};
|
|
128464
|
-
var PI_TO_DROID_ARGS = {};
|
|
128465
|
-
for (const m2 of TOOL_MAPPINGS) {
|
|
128466
|
-
DROID_TO_PI_NAME[m2.claude.toLowerCase()] = m2.pi;
|
|
128467
|
-
PI_TO_DROID_NAME[m2.pi] = m2.claude;
|
|
128468
|
-
DROID_TO_PI_ARGS[m2.claude.toLowerCase()] = m2.args;
|
|
128469
|
-
const reverseArgs = {};
|
|
128470
|
-
for (const [from, to] of Object.entries(m2.args)) {
|
|
128471
|
-
reverseArgs[to] = from;
|
|
128472
|
-
}
|
|
128473
|
-
PI_TO_DROID_ARGS[m2.pi] = reverseArgs;
|
|
128474
|
-
}
|
|
128475
|
-
PI_TO_DROID_NAME["glob"] = "Glob";
|
|
128476
|
-
function mapDroidToolNameToPi(claudeName) {
|
|
128477
|
-
if (claudeName.startsWith(CUSTOM_TOOLS_MCP_PREFIX)) {
|
|
128478
|
-
return claudeName.slice(CUSTOM_TOOLS_MCP_PREFIX.length);
|
|
128479
|
-
}
|
|
128480
|
-
return DROID_TO_PI_NAME[claudeName.toLowerCase()] ?? claudeName;
|
|
128481
|
-
}
|
|
128482
|
-
function mapPiToolNameToDroid(piName) {
|
|
128483
|
-
return PI_TO_DROID_NAME[piName] ?? piName;
|
|
128484
|
-
}
|
|
128485
|
-
function translateDroidArgsToPi(claudeToolName, args) {
|
|
128486
|
-
const renames = DROID_TO_PI_ARGS[claudeToolName.toLowerCase()];
|
|
128487
|
-
if (!renames || Object.keys(renames).length === 0)
|
|
128488
|
-
return args;
|
|
128489
|
-
const result = {};
|
|
128490
|
-
for (const [key, value] of Object.entries(args)) {
|
|
128491
|
-
const newKey = renames[key] ?? key;
|
|
128492
|
-
result[newKey] = value;
|
|
128493
|
-
}
|
|
128494
|
-
return result;
|
|
128495
|
-
}
|
|
128496
|
-
function translatePiArgsToDroid(piToolName, args) {
|
|
128497
|
-
const renames = PI_TO_DROID_ARGS[piToolName];
|
|
128498
|
-
if (!renames || Object.keys(renames).length === 0)
|
|
128499
|
-
return args;
|
|
128500
|
-
const result = {};
|
|
128501
|
-
for (const [key, value] of Object.entries(args)) {
|
|
128502
|
-
const newKey = renames[key] ?? key;
|
|
128503
|
-
result[newKey] = value;
|
|
128504
|
-
}
|
|
128505
|
-
return result;
|
|
128506
|
-
}
|
|
128507
|
-
|
|
128508
|
-
// ../../plugins/fusion-plugin-droid-runtime/dist/prompt-builder.js
|
|
128509
|
-
var placeholderImageCount = 0;
|
|
128510
|
-
function translateImageBlock(piBlock) {
|
|
128511
|
-
const block = piBlock;
|
|
128512
|
-
if (typeof block.data === "string" && typeof block.mimeType === "string") {
|
|
128513
|
-
return {
|
|
128514
|
-
type: "image",
|
|
128515
|
-
source: {
|
|
128516
|
-
type: "base64",
|
|
128517
|
-
media_type: block.mimeType,
|
|
128518
|
-
data: block.data
|
|
128519
|
-
}
|
|
128520
|
-
};
|
|
128521
|
-
}
|
|
128522
|
-
return null;
|
|
128523
|
-
}
|
|
128524
|
-
function buildFinalUserContent(content) {
|
|
128525
|
-
if (typeof content === "string") {
|
|
128526
|
-
return [{ type: "text", text: content }];
|
|
128527
|
-
}
|
|
128528
|
-
if (!Array.isArray(content)) {
|
|
128529
|
-
return [{ type: "text", text: "" }];
|
|
128530
|
-
}
|
|
128531
|
-
const blocks = [];
|
|
128532
|
-
for (const rawBlock of content) {
|
|
128533
|
-
const block = rawBlock;
|
|
128534
|
-
if (block.type === "text") {
|
|
128535
|
-
blocks.push({ type: "text", text: typeof block.text === "string" ? block.text : "" });
|
|
128536
|
-
} else if (block.type === "image") {
|
|
128537
|
-
const translated = translateImageBlock(block);
|
|
128538
|
-
if (translated) {
|
|
128539
|
-
blocks.push(translated);
|
|
128540
|
-
} else {
|
|
128541
|
-
blocks.push({
|
|
128542
|
-
type: "text",
|
|
128543
|
-
text: "[An image was shared here but could not be included]"
|
|
128544
|
-
});
|
|
128545
|
-
placeholderImageCount++;
|
|
128546
|
-
}
|
|
128547
|
-
}
|
|
128548
|
-
}
|
|
128549
|
-
return blocks;
|
|
128550
|
-
}
|
|
128551
|
-
function contentHasImages(content) {
|
|
128552
|
-
if (typeof content === "string" || !Array.isArray(content))
|
|
128553
|
-
return false;
|
|
128554
|
-
return content.some((block) => block.type === "image");
|
|
128555
|
-
}
|
|
128556
|
-
function buildCustomToolResultPrompt(messages) {
|
|
128557
|
-
if (messages.length < 3)
|
|
128558
|
-
return null;
|
|
128559
|
-
const last = messages[messages.length - 1];
|
|
128560
|
-
if (last.role !== "toolResult")
|
|
128561
|
-
return null;
|
|
128562
|
-
if (!last.toolName || !isCustomToolName(last.toolName))
|
|
128563
|
-
return null;
|
|
128564
|
-
let userMessage = null;
|
|
128565
|
-
for (let i2 = messages.length - 3; i2 >= 0; i2--) {
|
|
128566
|
-
const msg = messages[i2];
|
|
128567
|
-
if (msg.role === "user") {
|
|
128568
|
-
userMessage = userContentToText(msg.content);
|
|
128569
|
-
break;
|
|
128570
|
-
}
|
|
128571
|
-
}
|
|
128572
|
-
if (!userMessage)
|
|
128573
|
-
return null;
|
|
128574
|
-
const toolResult = toolResultContentToText(last.content);
|
|
128575
|
-
return `${userMessage}
|
|
128576
|
-
|
|
128577
|
-
[The ${last.toolName} tool was called and returned the following result]
|
|
128578
|
-
${toolResult}
|
|
128579
|
-
|
|
128580
|
-
Respond to the user using the tool result above.`;
|
|
128581
|
-
}
|
|
128582
|
-
function buildResumePrompt(context) {
|
|
128583
|
-
const messages = context.messages;
|
|
128584
|
-
if (messages.length === 0)
|
|
128585
|
-
return "";
|
|
128586
|
-
let lastAssistantIdx = -1;
|
|
128587
|
-
for (let i2 = messages.length - 1; i2 >= 0; i2--) {
|
|
128588
|
-
if (messages[i2].role === "assistant") {
|
|
128589
|
-
lastAssistantIdx = i2;
|
|
128590
|
-
break;
|
|
128591
|
-
}
|
|
128592
|
-
}
|
|
128593
|
-
const newMessages = messages.slice(lastAssistantIdx + 1);
|
|
128594
|
-
if (newMessages.length === 0)
|
|
128595
|
-
return "";
|
|
128596
|
-
const parts = [];
|
|
128597
|
-
for (const msg of newMessages) {
|
|
128598
|
-
if (msg.role === "toolResult") {
|
|
128599
|
-
if (msg.toolName && isCustomToolName(msg.toolName)) {
|
|
128600
|
-
parts.push(`TOOL RESULT (${msg.toolName}):`);
|
|
128601
|
-
} else {
|
|
128602
|
-
const claudeToolName = msg.toolName ? mapPiToolNameToDroid(msg.toolName) : "unknown";
|
|
128603
|
-
parts.push(`TOOL RESULT (${claudeToolName}):`);
|
|
128604
|
-
}
|
|
128605
|
-
parts.push(toolResultContentToText(msg.content));
|
|
128606
|
-
} else if (msg.role === "user") {
|
|
128607
|
-
if (contentHasImages(msg.content)) {
|
|
128608
|
-
const textSoFar = parts.join("\n");
|
|
128609
|
-
const userContent = buildFinalUserContent(msg.content);
|
|
128610
|
-
const result = [];
|
|
128611
|
-
if (textSoFar) {
|
|
128612
|
-
result.push({ type: "text", text: textSoFar });
|
|
128613
|
-
}
|
|
128614
|
-
result.push(...userContent);
|
|
128615
|
-
return result;
|
|
128616
|
-
}
|
|
128617
|
-
parts.push(userContentToText(msg.content));
|
|
128618
|
-
}
|
|
128619
|
-
}
|
|
128620
|
-
return parts.join("\n") || "";
|
|
128621
|
-
}
|
|
128622
|
-
function buildPrompt(context) {
|
|
128623
|
-
placeholderImageCount = 0;
|
|
128624
|
-
const customToolPrompt = buildCustomToolResultPrompt(context.messages);
|
|
128625
|
-
if (customToolPrompt) {
|
|
128626
|
-
if (placeholderImageCount > 0) {
|
|
128627
|
-
console.warn(`[droid-cli] ${placeholderImageCount} image(s) in conversation history could not be included in the prompt`);
|
|
128628
|
-
}
|
|
128629
|
-
return customToolPrompt;
|
|
128630
|
-
}
|
|
128631
|
-
const finalUserIndex = findFinalUserMessageIndex(context.messages);
|
|
128632
|
-
const finalUserMsg = finalUserIndex >= 0 ? context.messages[finalUserIndex] : void 0;
|
|
128633
|
-
const finalUserHasImages = finalUserMsg !== void 0 && finalUserMsg.role === "user" && contentHasImages(finalUserMsg.content);
|
|
128634
|
-
const anyToolResultHasImages = context.messages.some((m2) => m2.role === "toolResult" && toolResultHasImages(m2.content));
|
|
128635
|
-
if (finalUserHasImages || anyToolResultHasImages) {
|
|
128636
|
-
const historyParts = [];
|
|
128637
|
-
const toolResultImageBlocks = [];
|
|
128638
|
-
for (let i2 = 0; i2 < context.messages.length; i2++) {
|
|
128639
|
-
if (i2 === finalUserIndex)
|
|
128640
|
-
continue;
|
|
128641
|
-
const message = context.messages[i2];
|
|
128642
|
-
if (message.role === "user") {
|
|
128643
|
-
historyParts.push("USER:");
|
|
128644
|
-
historyParts.push(userContentToText(message.content));
|
|
128645
|
-
} else if (message.role === "assistant") {
|
|
128646
|
-
historyParts.push("ASSISTANT:");
|
|
128647
|
-
historyParts.push(contentToText(message.content));
|
|
128648
|
-
} else if (message.role === "toolResult") {
|
|
128649
|
-
if (message.toolName && isCustomToolName(message.toolName)) {
|
|
128650
|
-
historyParts.push(`TOOL RESULT (${message.toolName}):`);
|
|
128651
|
-
} else {
|
|
128652
|
-
const claudeToolName = message.toolName ? mapPiToolNameToDroid(message.toolName) : "unknown";
|
|
128653
|
-
historyParts.push(`TOOL RESULT (${claudeToolName}):`);
|
|
128654
|
-
}
|
|
128655
|
-
historyParts.push(toolResultContentToText(message.content));
|
|
128656
|
-
if (Array.isArray(message.content)) {
|
|
128657
|
-
for (const rawBlock of message.content) {
|
|
128658
|
-
const block = rawBlock;
|
|
128659
|
-
if (block.type === "image") {
|
|
128660
|
-
const translated = translateImageBlock(block);
|
|
128661
|
-
if (translated) {
|
|
128662
|
-
toolResultImageBlocks.push(translated);
|
|
128663
|
-
placeholderImageCount--;
|
|
128664
|
-
}
|
|
128665
|
-
}
|
|
128666
|
-
}
|
|
128667
|
-
}
|
|
128668
|
-
}
|
|
128669
|
-
}
|
|
128670
|
-
const finalUserContent = finalUserMsg?.role === "user" ? buildFinalUserContent(finalUserMsg.content) : [];
|
|
128671
|
-
const result = [];
|
|
128672
|
-
const historyText = historyParts.join("\n");
|
|
128673
|
-
if (historyText) {
|
|
128674
|
-
result.push({ type: "text", text: historyText });
|
|
128675
|
-
}
|
|
128676
|
-
result.push(...toolResultImageBlocks);
|
|
128677
|
-
result.push(...finalUserContent);
|
|
128678
|
-
if (placeholderImageCount > 0) {
|
|
128679
|
-
console.warn(`[droid-cli] ${placeholderImageCount} image(s) in conversation history could not be included in the prompt`);
|
|
128680
|
-
}
|
|
128681
|
-
return result;
|
|
128682
|
-
}
|
|
128683
|
-
const parts = [];
|
|
128684
|
-
for (const message of context.messages) {
|
|
128685
|
-
if (message.role === "user") {
|
|
128686
|
-
parts.push("USER:");
|
|
128687
|
-
parts.push(userContentToText(message.content));
|
|
128688
|
-
} else if (message.role === "assistant") {
|
|
128689
|
-
parts.push("ASSISTANT:");
|
|
128690
|
-
parts.push(contentToText(message.content));
|
|
128691
|
-
} else if (message.role === "toolResult") {
|
|
128692
|
-
if (message.toolName && isCustomToolName(message.toolName)) {
|
|
128693
|
-
parts.push(`TOOL RESULT (${message.toolName}):`);
|
|
128694
|
-
} else {
|
|
128695
|
-
const claudeToolName = message.toolName ? mapPiToolNameToDroid(message.toolName) : "unknown";
|
|
128696
|
-
parts.push(`TOOL RESULT (${claudeToolName}):`);
|
|
128697
|
-
}
|
|
128698
|
-
parts.push(toolResultContentToText(message.content));
|
|
128699
|
-
}
|
|
128700
|
-
}
|
|
128701
|
-
if (placeholderImageCount > 0) {
|
|
128702
|
-
console.warn(`[droid-cli] ${placeholderImageCount} image(s) in conversation history could not be included in the prompt`);
|
|
128703
|
-
}
|
|
128704
|
-
return parts.join("\n") || "";
|
|
128705
|
-
}
|
|
128706
|
-
function findFinalUserMessageIndex(messages) {
|
|
128707
|
-
for (let i2 = messages.length - 1; i2 >= 0; i2--) {
|
|
128708
|
-
if (messages[i2].role === "user")
|
|
128709
|
-
return i2;
|
|
128710
|
-
}
|
|
128711
|
-
return -1;
|
|
128712
|
-
}
|
|
128713
|
-
function buildSystemPrompt(context, cwd) {
|
|
128714
|
-
const parts = [];
|
|
128715
|
-
if (context.systemPrompt) {
|
|
128716
|
-
parts.push(rewriteCustomToolReferences(context.systemPrompt, context.tools));
|
|
128717
|
-
}
|
|
128718
|
-
const agentsPath = resolveAgentsMdPath(cwd);
|
|
128719
|
-
if (agentsPath) {
|
|
128720
|
-
try {
|
|
128721
|
-
const content = readFileSync(agentsPath, "utf-8");
|
|
128722
|
-
const sanitized = sanitizeAgentsContent(content);
|
|
128723
|
-
parts.push(sanitized);
|
|
128724
|
-
} catch {
|
|
128725
|
-
}
|
|
128726
|
-
}
|
|
128727
|
-
if (context.messages?.some((m2) => m2.role === "toolResult")) {
|
|
128728
|
-
parts.push("IMPORTANT: The conversation history below contains tool results from previously executed tools. Use these results to answer the user's question. Do NOT attempt to re-call tools that already have results.");
|
|
128729
|
-
}
|
|
128730
|
-
const customToolsAddendum = buildCustomToolsAddendum(context.tools);
|
|
128731
|
-
if (customToolsAddendum) {
|
|
128732
|
-
parts.push(customToolsAddendum);
|
|
128733
|
-
}
|
|
128734
|
-
return parts.join("\n\n");
|
|
128735
|
-
}
|
|
128736
|
-
var BUILT_IN_PI_TOOLS = /* @__PURE__ */ new Set([
|
|
128737
|
-
"read",
|
|
128738
|
-
"write",
|
|
128739
|
-
"edit",
|
|
128740
|
-
"bash",
|
|
128741
|
-
"grep",
|
|
128742
|
-
"find"
|
|
128743
|
-
]);
|
|
128744
|
-
function rewriteCustomToolReferences(prompt, tools) {
|
|
128745
|
-
if (!prompt || !tools || tools.length === 0) {
|
|
128746
|
-
return prompt;
|
|
128747
|
-
}
|
|
128748
|
-
let result = prompt;
|
|
128749
|
-
for (const tool of tools) {
|
|
128750
|
-
if (BUILT_IN_PI_TOOLS.has(tool.name))
|
|
128751
|
-
continue;
|
|
128752
|
-
const escaped = tool.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
128753
|
-
const pattern = new RegExp(`(?<![A-Za-z0-9_])(?<!mcp__custom-tools__)${escaped}(?![A-Za-z0-9_])`, "g");
|
|
128754
|
-
result = result.replace(pattern, `mcp__custom-tools__${tool.name}`);
|
|
128755
|
-
}
|
|
128756
|
-
return result;
|
|
128757
|
-
}
|
|
128758
|
-
function buildCustomToolsAddendum(tools) {
|
|
128759
|
-
if (!tools || tools.length === 0)
|
|
128760
|
-
return "";
|
|
128761
|
-
const customNames = tools.map((t2) => t2.name).filter((name) => !BUILT_IN_PI_TOOLS.has(name));
|
|
128762
|
-
if (customNames.length === 0)
|
|
128763
|
-
return "";
|
|
128764
|
-
const lines = customNames.sort().map((name) => `- \`${name}\` is exposed as \`mcp__custom-tools__${name}\``);
|
|
128765
|
-
return [
|
|
128766
|
-
"## Custom tool naming (MCP)",
|
|
128767
|
-
"",
|
|
128768
|
-
"The following pi extension tools are available under MCP-prefixed",
|
|
128769
|
-
"names. When a system prompt or task instruction asks you to call one",
|
|
128770
|
-
"of these by its short name, call the MCP-prefixed name directly.",
|
|
128771
|
-
"",
|
|
128772
|
-
...lines
|
|
128773
|
-
].join("\n");
|
|
128774
|
-
}
|
|
128775
|
-
function userContentToText(content) {
|
|
128776
|
-
if (typeof content === "string")
|
|
128777
|
-
return content;
|
|
128778
|
-
if (!Array.isArray(content))
|
|
128779
|
-
return "";
|
|
128780
|
-
const texts = [];
|
|
128781
|
-
for (const rawBlock of content) {
|
|
128782
|
-
const block = rawBlock;
|
|
128783
|
-
if (block.type === "text") {
|
|
128784
|
-
texts.push(typeof block.text === "string" ? block.text : "");
|
|
128785
|
-
} else if (block.type === "image") {
|
|
128786
|
-
texts.push("[An image was shared here but could not be included]");
|
|
128787
|
-
placeholderImageCount++;
|
|
128788
|
-
}
|
|
128789
|
-
}
|
|
128790
|
-
return texts.join("\n");
|
|
128791
|
-
}
|
|
128792
|
-
function contentToText(content) {
|
|
128793
|
-
if (typeof content === "string")
|
|
128794
|
-
return content;
|
|
128795
|
-
if (!Array.isArray(content))
|
|
128796
|
-
return "";
|
|
128797
|
-
return content.map((rawBlock) => {
|
|
128798
|
-
const block = rawBlock;
|
|
128799
|
-
if (block.type === "text")
|
|
128800
|
-
return typeof block.text === "string" ? block.text : "";
|
|
128801
|
-
if (block.type === "thinking")
|
|
128802
|
-
return "";
|
|
128803
|
-
if (block.type === "toolCall") {
|
|
128804
|
-
const name = typeof block.name === "string" ? block.name : "";
|
|
128805
|
-
const rawArgs = block.arguments;
|
|
128806
|
-
const argsObject = rawArgs && typeof rawArgs === "object" ? rawArgs : void 0;
|
|
128807
|
-
const isCustom = isCustomToolName(name);
|
|
128808
|
-
if (isCustom) {
|
|
128809
|
-
const argsStr2 = argsObject ? JSON.stringify(argsObject) : typeof rawArgs === "string" ? JSON.stringify(rawArgs) : "{}";
|
|
128810
|
-
return `[Used ${name} tool with args: ${argsStr2}]`;
|
|
128811
|
-
}
|
|
128812
|
-
const claudeName = mapPiToolNameToDroid(name);
|
|
128813
|
-
const claudeArgs = argsObject ? translatePiArgsToDroid(name, argsObject) : void 0;
|
|
128814
|
-
const argsStr = claudeArgs ? JSON.stringify(claudeArgs) : typeof rawArgs === "string" ? JSON.stringify(rawArgs) : "{}";
|
|
128815
|
-
return `[Prior tool call \u2014 already executed; result follows in TOOL RESULT (${claudeName}):] args=${argsStr}`;
|
|
128816
|
-
}
|
|
128817
|
-
return `[${String(block.type)}]`;
|
|
128818
|
-
}).join("\n");
|
|
128819
|
-
}
|
|
128820
|
-
function toolResultContentToText(content) {
|
|
128821
|
-
if (typeof content === "string")
|
|
128822
|
-
return content;
|
|
128823
|
-
if (!Array.isArray(content))
|
|
128824
|
-
return "";
|
|
128825
|
-
const texts = [];
|
|
128826
|
-
for (const rawBlock of content) {
|
|
128827
|
-
const block = rawBlock;
|
|
128828
|
-
if (block.type === "text") {
|
|
128829
|
-
texts.push(typeof block.text === "string" ? block.text : "");
|
|
128830
|
-
} else if (block.type === "image") {
|
|
128831
|
-
texts.push("[An image was shared here but could not be included]");
|
|
128832
|
-
placeholderImageCount++;
|
|
128833
|
-
}
|
|
128834
|
-
}
|
|
128835
|
-
return texts.join("\n");
|
|
128836
|
-
}
|
|
128837
|
-
function toolResultHasImages(content) {
|
|
128838
|
-
if (typeof content === "string" || !Array.isArray(content))
|
|
128839
|
-
return false;
|
|
128840
|
-
return content.some((block) => block.type === "image");
|
|
128841
|
-
}
|
|
128842
|
-
function resolveAgentsMdPath(cwd) {
|
|
128843
|
-
let current = resolve(cwd);
|
|
128844
|
-
while (true) {
|
|
128845
|
-
const candidate = join(current, "AGENTS.md");
|
|
128846
|
-
if (existsSync(candidate))
|
|
128847
|
-
return candidate;
|
|
128848
|
-
const parent = dirname(current);
|
|
128849
|
-
if (parent === current)
|
|
128850
|
-
break;
|
|
128851
|
-
current = parent;
|
|
128852
|
-
}
|
|
128853
|
-
const globalHome = process.env.HOME || process.env.USERPROFILE || homedir();
|
|
128854
|
-
const globalPath = join(globalHome, ".pi", "agent", "AGENTS.md");
|
|
128855
|
-
if (existsSync(globalPath))
|
|
128856
|
-
return globalPath;
|
|
128857
|
-
return void 0;
|
|
128858
|
-
}
|
|
128859
|
-
function sanitizeAgentsContent(content) {
|
|
128860
|
-
let sanitized = content;
|
|
128861
|
-
sanitized = sanitized.replace(/~\/\.pi\b/gi, "~/.claude");
|
|
128862
|
-
sanitized = sanitized.replace(/(^|[\s'"`])\.pi\//g, "$1.claude/");
|
|
128863
|
-
sanitized = sanitized.replace(/\b\.pi\b/gi, ".claude");
|
|
128864
|
-
return sanitized;
|
|
128865
|
-
}
|
|
128866
|
-
|
|
128867
|
-
// ../../plugins/fusion-plugin-droid-runtime/dist/process-manager.js
|
|
128868
|
-
import { execSync, spawn } from "node:child_process";
|
|
128869
|
-
import { writeFileSync, unlinkSync } from "node:fs";
|
|
128870
|
-
import { join as join2 } from "node:path";
|
|
128871
|
-
import { tmpdir } from "node:os";
|
|
128872
|
-
function debugLog(message) {
|
|
128873
|
-
if (process.env.PI_DROID_CLI_DEBUG !== "1")
|
|
128874
|
-
return;
|
|
128875
|
-
console.error(`[droid-cli] ${message}`);
|
|
128876
|
-
}
|
|
128877
|
-
function buildDroidSpawnArgs(modelId, systemPrompt, options) {
|
|
128878
|
-
const args = [
|
|
128879
|
-
"-p",
|
|
128880
|
-
"--input-format",
|
|
128881
|
-
"stream-json",
|
|
128882
|
-
"--output-format",
|
|
128883
|
-
"stream-json",
|
|
128884
|
-
"--verbose",
|
|
128885
|
-
"--include-partial-messages",
|
|
128886
|
-
"--model",
|
|
128887
|
-
modelId
|
|
128888
|
-
];
|
|
128889
|
-
if (options?.resumeSessionId) {
|
|
128890
|
-
args.push("--resume", options.resumeSessionId);
|
|
128891
|
-
} else if (options?.newSessionId) {
|
|
128892
|
-
args.push("--session-id", options.newSessionId);
|
|
128893
|
-
}
|
|
128894
|
-
if (systemPrompt) {
|
|
128895
|
-
const tmpFile = join2(tmpdir(), `droid-cli-sysprompt-${process.pid}.txt`);
|
|
128896
|
-
writeFileSync(tmpFile, systemPrompt, "utf-8");
|
|
128897
|
-
args.push("--append-system-prompt", tmpFile);
|
|
128898
|
-
}
|
|
128899
|
-
if (options?.effort) {
|
|
128900
|
-
args.push("--effort", options.effort);
|
|
128901
|
-
}
|
|
128902
|
-
if (options?.mcpConfigPath) {
|
|
128903
|
-
args.push("--mcp-config", options.mcpConfigPath);
|
|
128904
|
-
}
|
|
128905
|
-
return args;
|
|
128906
|
-
}
|
|
128907
|
-
function spawnDroid(modelId, systemPrompt, options) {
|
|
128908
|
-
const args = buildDroidSpawnArgs(modelId, systemPrompt, {
|
|
128909
|
-
effort: options?.effort,
|
|
128910
|
-
mcpConfigPath: options?.mcpConfigPath,
|
|
128911
|
-
resumeSessionId: options?.resumeSessionId,
|
|
128912
|
-
newSessionId: options?.newSessionId
|
|
128913
|
-
});
|
|
128914
|
-
const proc = spawn("droid", args, {
|
|
128915
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
128916
|
-
cwd: options?.cwd ?? process.cwd()
|
|
128917
|
-
});
|
|
128918
|
-
debugLog(`spawnDroid: pid=${proc.pid} model=${modelId}`);
|
|
128919
|
-
return proc;
|
|
128920
|
-
}
|
|
128921
|
-
function cleanupSystemPromptFile() {
|
|
128922
|
-
try {
|
|
128923
|
-
unlinkSync(join2(tmpdir(), `droid-cli-sysprompt-${process.pid}.txt`));
|
|
128924
|
-
} catch {
|
|
128925
|
-
}
|
|
128926
|
-
}
|
|
128927
|
-
function writeUserMessage(proc, prompt) {
|
|
128928
|
-
const message = {
|
|
128929
|
-
type: "user",
|
|
128930
|
-
message: {
|
|
128931
|
-
role: "user",
|
|
128932
|
-
content: prompt
|
|
128933
|
-
}
|
|
128934
|
-
};
|
|
128935
|
-
proc.stdin.write(JSON.stringify(message) + "\n");
|
|
128936
|
-
proc.stdin.end();
|
|
128937
|
-
}
|
|
128938
|
-
function forceKillProcess(proc) {
|
|
128939
|
-
if (proc.killed || proc.exitCode !== null)
|
|
128940
|
-
return;
|
|
128941
|
-
proc.kill("SIGKILL");
|
|
128942
|
-
}
|
|
128943
|
-
var activeProcesses = /* @__PURE__ */ new Set();
|
|
128944
|
-
function registerProcess(proc) {
|
|
128945
|
-
activeProcesses.add(proc);
|
|
128946
|
-
proc.on("exit", () => activeProcesses.delete(proc));
|
|
128947
|
-
}
|
|
128948
|
-
function killAllProcesses() {
|
|
128949
|
-
for (const proc of activeProcesses) {
|
|
128950
|
-
forceKillProcess(proc);
|
|
128951
|
-
}
|
|
128952
|
-
activeProcesses.clear();
|
|
128953
|
-
}
|
|
128954
|
-
function cleanupProcess(proc) {
|
|
128955
|
-
setTimeout(() => {
|
|
128956
|
-
forceKillProcess(proc);
|
|
128957
|
-
}, 500);
|
|
128958
|
-
}
|
|
128959
|
-
function captureStderr(proc) {
|
|
128960
|
-
let buffer = "";
|
|
128961
|
-
proc.stderr.on("data", (data) => {
|
|
128962
|
-
buffer += data.toString();
|
|
128963
|
-
});
|
|
128964
|
-
return () => buffer;
|
|
128965
|
-
}
|
|
128966
|
-
function runDroidProbe(args, timeoutMs = 45e3) {
|
|
128967
|
-
return new Promise((resolve2) => {
|
|
128968
|
-
const proc = spawn("droid", args, { stdio: "ignore" });
|
|
128969
|
-
const timer = setTimeout(() => {
|
|
128970
|
-
try {
|
|
128971
|
-
proc.kill("SIGKILL");
|
|
128972
|
-
} catch {
|
|
128973
|
-
}
|
|
128974
|
-
resolve2(124);
|
|
128975
|
-
}, timeoutMs);
|
|
128976
|
-
proc.once("error", () => {
|
|
128977
|
-
clearTimeout(timer);
|
|
128978
|
-
resolve2(127);
|
|
128979
|
-
});
|
|
128980
|
-
proc.once("exit", (code) => {
|
|
128981
|
-
clearTimeout(timer);
|
|
128982
|
-
resolve2(code ?? 1);
|
|
128983
|
-
});
|
|
128984
|
-
});
|
|
128985
|
-
}
|
|
128986
|
-
async function validateCliPresenceAsync() {
|
|
128987
|
-
const code = await runDroidProbe(["--version"]);
|
|
128988
|
-
if (code === 0)
|
|
128989
|
-
return { ok: true };
|
|
128990
|
-
return {
|
|
128991
|
-
ok: false,
|
|
128992
|
-
error: new Error("Droid CLI not found on PATH. Install Droid CLI and then run: droid auth login")
|
|
128993
|
-
};
|
|
128994
|
-
}
|
|
128995
|
-
async function validateCliAuthAsync() {
|
|
128996
|
-
const code = await runDroidProbe(["auth", "status"]);
|
|
128997
|
-
if (code === 0)
|
|
128998
|
-
return true;
|
|
128999
|
-
console.warn("[droid-cli] Droid CLI is not authenticated. Run 'droid auth login' to authenticate.");
|
|
129000
|
-
return false;
|
|
129001
|
-
}
|
|
129002
|
-
async function discoverDroidModels() {
|
|
129003
|
-
const attempts = [["models", "--json"], ["model", "list", "--json"], ["models"]];
|
|
129004
|
-
for (const args of attempts) {
|
|
129005
|
-
const models = await new Promise((resolve2) => {
|
|
129006
|
-
const proc = spawn("droid", args, { stdio: ["ignore", "pipe", "ignore"] });
|
|
129007
|
-
let out = "";
|
|
129008
|
-
proc.stdout?.on("data", (chunk) => {
|
|
129009
|
-
out += chunk.toString();
|
|
129010
|
-
});
|
|
129011
|
-
proc.once("error", () => resolve2(null));
|
|
129012
|
-
proc.once("exit", (code) => {
|
|
129013
|
-
if (code !== 0)
|
|
129014
|
-
return resolve2(null);
|
|
129015
|
-
const trimmed = out.trim();
|
|
129016
|
-
if (!trimmed)
|
|
129017
|
-
return resolve2([]);
|
|
129018
|
-
try {
|
|
129019
|
-
const parsed = JSON.parse(trimmed);
|
|
129020
|
-
if (Array.isArray(parsed)) {
|
|
129021
|
-
return resolve2(parsed.map((entry) => typeof entry === "string" ? entry : typeof entry?.id === "string" ? entry.id : typeof entry?.name === "string" ? entry.name : void 0).filter((id) => Boolean(id)));
|
|
129022
|
-
}
|
|
129023
|
-
} catch {
|
|
129024
|
-
}
|
|
129025
|
-
resolve2(trimmed.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
|
|
129026
|
-
});
|
|
129027
|
-
});
|
|
129028
|
-
if (models && models.length > 0) {
|
|
129029
|
-
return Array.from(new Set(models));
|
|
129030
|
-
}
|
|
129031
|
-
}
|
|
129032
|
-
return [];
|
|
129033
|
-
}
|
|
129034
|
-
|
|
129035
|
-
// ../../plugins/fusion-plugin-droid-runtime/dist/stream-parser.js
|
|
129036
|
-
function parseLine(line) {
|
|
129037
|
-
const trimmed = line.trim();
|
|
129038
|
-
if (!trimmed) {
|
|
129039
|
-
return null;
|
|
129040
|
-
}
|
|
129041
|
-
if (!trimmed.startsWith("{")) {
|
|
129042
|
-
return null;
|
|
129043
|
-
}
|
|
129044
|
-
let parsed;
|
|
129045
|
-
try {
|
|
129046
|
-
parsed = JSON.parse(trimmed);
|
|
129047
|
-
} catch {
|
|
129048
|
-
console.error("Failed to parse NDJSON line:", trimmed);
|
|
129049
|
-
return null;
|
|
129050
|
-
}
|
|
129051
|
-
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
129052
|
-
return null;
|
|
129053
|
-
}
|
|
129054
|
-
return parsed;
|
|
129055
|
-
}
|
|
129056
|
-
|
|
129057
128433
|
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/system/memory/memory.mjs
|
|
129058
128434
|
var memory_exports = {};
|
|
129059
128435
|
__export(memory_exports, {
|
|
@@ -132523,7 +131899,7 @@ function createLazyLoadErrorMessage(model, error40) {
|
|
|
132523
131899
|
}
|
|
132524
131900
|
function createLazyStream(loadModule) {
|
|
132525
131901
|
return (model, context, options) => {
|
|
132526
|
-
const outer = new
|
|
131902
|
+
const outer = new AssistantMessageEventStream();
|
|
132527
131903
|
loadModule().then((module) => {
|
|
132528
131904
|
const inner = module.stream(model, context, options);
|
|
132529
131905
|
forwardStream(outer, inner);
|
|
@@ -132537,7 +131913,7 @@ function createLazyStream(loadModule) {
|
|
|
132537
131913
|
}
|
|
132538
131914
|
function createLazySimpleStream(loadModule) {
|
|
132539
131915
|
return (model, context, options) => {
|
|
132540
|
-
const outer = new
|
|
131916
|
+
const outer = new AssistantMessageEventStream();
|
|
132541
131917
|
loadModule().then((module) => {
|
|
132542
131918
|
const inner = module.streamSimple(model, context, options);
|
|
132543
131919
|
forwardStream(outer, inner);
|
|
@@ -135648,249 +135024,866 @@ function Encode3(direction, context, type, value) {
|
|
|
135648
135024
|
for (let i2 = 0; i2 < exterior.length; i2++) {
|
|
135649
135025
|
exterior[i2] = FromType22(direction, context, type.items, exterior[i2]);
|
|
135650
135026
|
}
|
|
135651
|
-
return exterior;
|
|
135652
|
-
}
|
|
135653
|
-
function FromArray11(direction, context, type, value) {
|
|
135654
|
-
return guard_exports.IsEqual(direction, "Decode") ? Decode4(direction, context, type, value) : Encode3(direction, context, type, value);
|
|
135027
|
+
return exterior;
|
|
135028
|
+
}
|
|
135029
|
+
function FromArray11(direction, context, type, value) {
|
|
135030
|
+
return guard_exports.IsEqual(direction, "Decode") ? Decode4(direction, context, type, value) : Encode3(direction, context, type, value);
|
|
135031
|
+
}
|
|
135032
|
+
|
|
135033
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/from-cyclic.mjs
|
|
135034
|
+
function FromCyclic9(direction, context, type, value) {
|
|
135035
|
+
value = FromType22(direction, { ...context, ...type.$defs }, Ref(type.$ref), value);
|
|
135036
|
+
return Callback(direction, context, type, value);
|
|
135037
|
+
}
|
|
135038
|
+
|
|
135039
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/from-intersect.mjs
|
|
135040
|
+
function MergeInteriors(interiors) {
|
|
135041
|
+
return interiors.reduce((results, interior) => ({ ...results, ...interior }), {});
|
|
135042
|
+
}
|
|
135043
|
+
function NonMatchingInterior(value, interiors) {
|
|
135044
|
+
for (const interior of interiors)
|
|
135045
|
+
if (!guard_exports.IsDeepEqual(value, interior))
|
|
135046
|
+
return interior;
|
|
135047
|
+
return value;
|
|
135048
|
+
}
|
|
135049
|
+
function Decode5(direction, context, type, value) {
|
|
135050
|
+
if (guard_exports.IsEqual(type.allOf.length, 0))
|
|
135051
|
+
return Callback(direction, context, type, value);
|
|
135052
|
+
const interiors = type.allOf.map((schema) => FromType22(direction, context, schema, Clean(schema, Clone2(value))));
|
|
135053
|
+
const structural = interiors.every((result) => guard_exports.IsObject(result));
|
|
135054
|
+
const exterior = structural ? MergeInteriors(interiors) : NonMatchingInterior(value, interiors);
|
|
135055
|
+
return Callback(direction, context, type, exterior);
|
|
135056
|
+
}
|
|
135057
|
+
function Encode4(direction, context, type, value) {
|
|
135058
|
+
if (guard_exports.IsEqual(type.allOf.length, 0))
|
|
135059
|
+
return Callback(direction, context, type, value);
|
|
135060
|
+
const exterior = Callback(direction, context, type, value);
|
|
135061
|
+
const interiors = type.allOf.map((schema) => FromType22(direction, context, schema, Clean(schema, Clone2(exterior))));
|
|
135062
|
+
const structural = interiors.every((result) => guard_exports.IsObject(result));
|
|
135063
|
+
if (structural)
|
|
135064
|
+
return MergeInteriors(interiors);
|
|
135065
|
+
return NonMatchingInterior(exterior, interiors);
|
|
135066
|
+
}
|
|
135067
|
+
function FromIntersect9(direction, context, type, value) {
|
|
135068
|
+
return guard_exports.IsEqual(direction, "Decode") ? Decode5(direction, context, type, value) : Encode4(direction, context, type, value);
|
|
135069
|
+
}
|
|
135070
|
+
|
|
135071
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/from-object.mjs
|
|
135072
|
+
function Decode6(direction, context, type, value) {
|
|
135073
|
+
if (!guard_exports.IsObjectNotArray(value))
|
|
135074
|
+
return Unreachable();
|
|
135075
|
+
for (const key of guard_exports.Keys(type.properties)) {
|
|
135076
|
+
if (!guard_exports.HasPropertyKey(value, key) || IsOptionalUndefined(type.properties[key], key, value))
|
|
135077
|
+
continue;
|
|
135078
|
+
value[key] = FromType22(direction, context, type.properties[key], value[key]);
|
|
135079
|
+
}
|
|
135080
|
+
return Callback(direction, context, type, value);
|
|
135081
|
+
}
|
|
135082
|
+
function Encode5(direction, context, type, value) {
|
|
135083
|
+
const exterior = Callback(direction, context, type, value);
|
|
135084
|
+
if (!guard_exports.IsObjectNotArray(exterior))
|
|
135085
|
+
return exterior;
|
|
135086
|
+
for (const key of guard_exports.Keys(type.properties)) {
|
|
135087
|
+
if (!guard_exports.HasPropertyKey(exterior, key) || IsOptionalUndefined(type.properties[key], key, exterior))
|
|
135088
|
+
continue;
|
|
135089
|
+
exterior[key] = FromType22(direction, context, type.properties[key], exterior[key]);
|
|
135090
|
+
}
|
|
135091
|
+
return exterior;
|
|
135092
|
+
}
|
|
135093
|
+
function FromObject14(direction, context, type, value) {
|
|
135094
|
+
return guard_exports.IsEqual(direction, "Decode") ? Decode6(direction, context, type, value) : Encode5(direction, context, type, value);
|
|
135095
|
+
}
|
|
135096
|
+
|
|
135097
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/from-record.mjs
|
|
135098
|
+
function Decode7(direction, context, type, value) {
|
|
135099
|
+
if (!guard_exports.IsObjectNotArray(value))
|
|
135100
|
+
return Unreachable();
|
|
135101
|
+
const regexp = new RegExp(RecordPattern(type));
|
|
135102
|
+
for (const key of guard_exports.Keys(value)) {
|
|
135103
|
+
if (!regexp.test(key))
|
|
135104
|
+
Unreachable();
|
|
135105
|
+
value[key] = FromType22(direction, context, RecordValue(type), value[key]);
|
|
135106
|
+
}
|
|
135107
|
+
return Callback(direction, context, type, value);
|
|
135108
|
+
}
|
|
135109
|
+
function Encode6(direction, context, type, value) {
|
|
135110
|
+
const exterior = Callback(direction, context, type, value);
|
|
135111
|
+
if (!guard_exports.IsObjectNotArray(exterior))
|
|
135112
|
+
return exterior;
|
|
135113
|
+
const regexp = new RegExp(RecordPattern(type));
|
|
135114
|
+
for (const key of guard_exports.Keys(exterior)) {
|
|
135115
|
+
if (!regexp.test(key))
|
|
135116
|
+
continue;
|
|
135117
|
+
exterior[key] = FromType22(direction, context, RecordValue(type), exterior[key]);
|
|
135118
|
+
}
|
|
135119
|
+
return exterior;
|
|
135120
|
+
}
|
|
135121
|
+
function FromRecord5(direction, context, type, value) {
|
|
135122
|
+
return guard_exports.IsEqual(direction, "Decode") ? Decode7(direction, context, type, value) : Encode6(direction, context, type, value);
|
|
135123
|
+
}
|
|
135124
|
+
|
|
135125
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/from-ref.mjs
|
|
135126
|
+
function ResolveRef(direction, context, type, value) {
|
|
135127
|
+
return guard_exports.HasPropertyKey(context, type.$ref) ? FromType22(direction, context, context[type.$ref], value) : value;
|
|
135128
|
+
}
|
|
135129
|
+
function FromRef8(direction, context, type, value) {
|
|
135130
|
+
return guard_exports.IsEqual(direction, "Decode") ? Callback(direction, context, type, ResolveRef(direction, context, type, value)) : ResolveRef(direction, context, type, Callback(direction, context, type, value));
|
|
135131
|
+
}
|
|
135132
|
+
|
|
135133
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/from-tuple.mjs
|
|
135134
|
+
function Decode8(direction, context, type, value) {
|
|
135135
|
+
if (!guard_exports.IsArray(value))
|
|
135136
|
+
return Unreachable();
|
|
135137
|
+
for (let i2 = 0; i2 < Math.min(type.items.length, value.length); i2++) {
|
|
135138
|
+
value[i2] = FromType22(direction, context, type.items[i2], value[i2]);
|
|
135139
|
+
}
|
|
135140
|
+
return Callback(direction, context, type, value);
|
|
135141
|
+
}
|
|
135142
|
+
function Encode7(direction, context, type, value) {
|
|
135143
|
+
const exterior = Callback(direction, context, type, value);
|
|
135144
|
+
if (!guard_exports.IsArray(exterior))
|
|
135145
|
+
return value;
|
|
135146
|
+
for (let i2 = 0; i2 < Math.min(type.items.length, exterior.length); i2++) {
|
|
135147
|
+
exterior[i2] = FromType22(direction, context, type.items[i2], exterior[i2]);
|
|
135148
|
+
}
|
|
135149
|
+
return exterior;
|
|
135150
|
+
}
|
|
135151
|
+
function FromTuple8(direction, context, type, value) {
|
|
135152
|
+
return guard_exports.IsEqual(direction, "Decode") ? Decode8(direction, context, type, value) : Encode7(direction, context, type, value);
|
|
135153
|
+
}
|
|
135154
|
+
|
|
135155
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/from-union.mjs
|
|
135156
|
+
function Decode9(direction, context, type, value) {
|
|
135157
|
+
for (const schema of UnionPrioritySort(type.anyOf, 1)) {
|
|
135158
|
+
if (!Check2(context, schema, value))
|
|
135159
|
+
continue;
|
|
135160
|
+
const variant = FromType22(direction, context, schema, value);
|
|
135161
|
+
return Callback(direction, context, type, variant);
|
|
135162
|
+
}
|
|
135163
|
+
return value;
|
|
135164
|
+
}
|
|
135165
|
+
function Encode8(direction, context, type, value) {
|
|
135166
|
+
const exterior = Callback(direction, context, type, value);
|
|
135167
|
+
for (const schema of UnionPrioritySort(type.anyOf, -1)) {
|
|
135168
|
+
const variant = FromType22(direction, context, schema, Clone2(exterior));
|
|
135169
|
+
if (!Check2(context, schema, variant))
|
|
135170
|
+
continue;
|
|
135171
|
+
return variant;
|
|
135172
|
+
}
|
|
135173
|
+
return exterior;
|
|
135174
|
+
}
|
|
135175
|
+
function FromUnion12(direction, context, type, value) {
|
|
135176
|
+
return guard_exports.IsEqual(direction, "Decode") ? Decode9(direction, context, type, value) : Encode8(direction, context, type, value);
|
|
135177
|
+
}
|
|
135178
|
+
|
|
135179
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/from-type.mjs
|
|
135180
|
+
function FromType22(direction, context, type, value) {
|
|
135181
|
+
return IsArray2(type) ? FromArray11(direction, context, type, value) : IsCyclic(type) ? FromCyclic9(direction, context, type, value) : IsIntersect(type) ? FromIntersect9(direction, context, type, value) : IsObject2(type) ? FromObject14(direction, context, type, value) : IsRecord(type) ? FromRecord5(direction, context, type, value) : IsRef(type) ? FromRef8(direction, context, type, value) : IsTuple(type) ? FromTuple8(direction, context, type, value) : IsUnion(type) ? FromUnion12(direction, context, type, value) : Callback(direction, context, type, value);
|
|
135182
|
+
}
|
|
135183
|
+
|
|
135184
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/decode.mjs
|
|
135185
|
+
var DecodeError = class extends AssertError {
|
|
135186
|
+
constructor(value, errors) {
|
|
135187
|
+
super("Decode", value, errors);
|
|
135188
|
+
}
|
|
135189
|
+
};
|
|
135190
|
+
function Assert(context, type, value) {
|
|
135191
|
+
if (!Check2(context, type, value))
|
|
135192
|
+
throw new DecodeError(value, Errors2(context, type, value));
|
|
135193
|
+
return value;
|
|
135194
|
+
}
|
|
135195
|
+
function DecodeUnsafe(context, type, value) {
|
|
135196
|
+
return FromType22("Decode", context, type, value);
|
|
135197
|
+
}
|
|
135198
|
+
var Decoder = Pipeline([
|
|
135199
|
+
(_context, _type, value) => Clone2(value),
|
|
135200
|
+
(context, type, value) => Default(context, type, value),
|
|
135201
|
+
(context, type, value) => Convert(context, type, value),
|
|
135202
|
+
(context, type, value) => Clean(context, type, value),
|
|
135203
|
+
(context, type, value) => Assert(context, type, value),
|
|
135204
|
+
(context, type, value) => DecodeUnsafe(context, type, value)
|
|
135205
|
+
]);
|
|
135206
|
+
|
|
135207
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/encode.mjs
|
|
135208
|
+
var EncodeError = class extends AssertError {
|
|
135209
|
+
constructor(value, errors) {
|
|
135210
|
+
super("Encode", value, errors);
|
|
135211
|
+
}
|
|
135212
|
+
};
|
|
135213
|
+
function Assert2(context, type, value) {
|
|
135214
|
+
if (!Check2(context, type, value))
|
|
135215
|
+
throw new EncodeError(value, Errors2(context, type, value));
|
|
135216
|
+
return value;
|
|
135217
|
+
}
|
|
135218
|
+
function EncodeUnsafe(context, type, value) {
|
|
135219
|
+
return FromType22("Encode", context, type, value);
|
|
135220
|
+
}
|
|
135221
|
+
var Encoder = Pipeline([
|
|
135222
|
+
(_context, _type, value) => Clone2(value),
|
|
135223
|
+
(context, type, value) => EncodeUnsafe(context, type, value),
|
|
135224
|
+
(context, type, value) => Default(context, type, value),
|
|
135225
|
+
(context, type, value) => Convert(context, type, value),
|
|
135226
|
+
(context, type, value) => Clean(context, type, value),
|
|
135227
|
+
(context, type, value) => Assert2(context, type, value)
|
|
135228
|
+
]);
|
|
135229
|
+
|
|
135230
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/parse/parse.mjs
|
|
135231
|
+
var ParseError2 = class extends AssertError {
|
|
135232
|
+
constructor(value, errors) {
|
|
135233
|
+
super("Parse", value, errors);
|
|
135234
|
+
}
|
|
135235
|
+
};
|
|
135236
|
+
function Assert3(context, type, value) {
|
|
135237
|
+
if (!Check2(context, type, value))
|
|
135238
|
+
throw new ParseError2(value, Errors2(context, type, value));
|
|
135239
|
+
return value;
|
|
135240
|
+
}
|
|
135241
|
+
var Parser = Pipeline([
|
|
135242
|
+
(_context, _type, value) => Clone2(value),
|
|
135243
|
+
(context, type, value) => Default(context, type, value),
|
|
135244
|
+
(context, type, value) => Convert(context, type, value),
|
|
135245
|
+
(context, type, value) => Clean(context, type, value),
|
|
135246
|
+
(context, type, value) => Assert3(context, type, value)
|
|
135247
|
+
]);
|
|
135248
|
+
|
|
135249
|
+
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/delta/edit.mjs
|
|
135250
|
+
var Insert = _Object_({
|
|
135251
|
+
type: Literal("insert"),
|
|
135252
|
+
path: String2(),
|
|
135253
|
+
value: Unknown()
|
|
135254
|
+
});
|
|
135255
|
+
var Update2 = Object({
|
|
135256
|
+
type: Literal("update"),
|
|
135257
|
+
path: String2(),
|
|
135258
|
+
value: Unknown()
|
|
135259
|
+
});
|
|
135260
|
+
var Delete2 = _Object_({
|
|
135261
|
+
type: Literal("delete"),
|
|
135262
|
+
path: String2()
|
|
135263
|
+
});
|
|
135264
|
+
var Edit = Union([Insert, Update2, Delete2]);
|
|
135265
|
+
|
|
135266
|
+
// ../../node_modules/.pnpm/@mariozechner+pi-ai@0.72.1_@modelcontextprotocol+sdk@1.28.0_zod@4.3.6__ws@8.20.0_zod@4.3.6/node_modules/@mariozechner/pi-ai/dist/utils/validation.js
|
|
135267
|
+
var TYPEBOX_KIND = Symbol.for("TypeBox.Kind");
|
|
135268
|
+
|
|
135269
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/prompt-builder.ts
|
|
135270
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
135271
|
+
import { resolve, join, dirname } from "node:path";
|
|
135272
|
+
import { homedir } from "node:os";
|
|
135273
|
+
|
|
135274
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/tool-mapping.ts
|
|
135275
|
+
var TOOL_MAPPINGS = [
|
|
135276
|
+
{ claude: "Read", pi: "read", args: { file_path: "path" } },
|
|
135277
|
+
{ claude: "Write", pi: "write", args: { file_path: "path" } },
|
|
135278
|
+
{
|
|
135279
|
+
claude: "Edit",
|
|
135280
|
+
pi: "edit",
|
|
135281
|
+
args: { file_path: "path", old_string: "oldText", new_string: "newText" }
|
|
135282
|
+
},
|
|
135283
|
+
{ claude: "Bash", pi: "bash", args: {} },
|
|
135284
|
+
{ claude: "Grep", pi: "grep", args: { head_limit: "limit" } },
|
|
135285
|
+
{ claude: "Glob", pi: "find", args: {} }
|
|
135286
|
+
];
|
|
135287
|
+
var CUSTOM_TOOLS_MCP_PREFIX = "mcp__custom-tools__";
|
|
135288
|
+
var BUILT_IN_PI_NAMES = new Set(TOOL_MAPPINGS.map((m2) => m2.pi));
|
|
135289
|
+
function isCustomToolName(piName) {
|
|
135290
|
+
return !BUILT_IN_PI_NAMES.has(piName);
|
|
135291
|
+
}
|
|
135292
|
+
function isPiKnownDroidTool(claudeName) {
|
|
135293
|
+
if (claudeName.startsWith(CUSTOM_TOOLS_MCP_PREFIX)) return true;
|
|
135294
|
+
return claudeName.toLowerCase() in DROID_TO_PI_NAME;
|
|
135295
|
+
}
|
|
135296
|
+
var DROID_TO_PI_NAME = {};
|
|
135297
|
+
var PI_TO_DROID_NAME = {};
|
|
135298
|
+
var DROID_TO_PI_ARGS = {};
|
|
135299
|
+
var PI_TO_DROID_ARGS = {};
|
|
135300
|
+
for (const m2 of TOOL_MAPPINGS) {
|
|
135301
|
+
DROID_TO_PI_NAME[m2.claude.toLowerCase()] = m2.pi;
|
|
135302
|
+
PI_TO_DROID_NAME[m2.pi] = m2.claude;
|
|
135303
|
+
DROID_TO_PI_ARGS[m2.claude.toLowerCase()] = m2.args;
|
|
135304
|
+
const reverseArgs = {};
|
|
135305
|
+
for (const [from, to] of Object.entries(m2.args)) {
|
|
135306
|
+
reverseArgs[to] = from;
|
|
135307
|
+
}
|
|
135308
|
+
PI_TO_DROID_ARGS[m2.pi] = reverseArgs;
|
|
135309
|
+
}
|
|
135310
|
+
PI_TO_DROID_NAME["glob"] = "Glob";
|
|
135311
|
+
function mapDroidToolNameToPi(claudeName) {
|
|
135312
|
+
if (claudeName.startsWith(CUSTOM_TOOLS_MCP_PREFIX)) {
|
|
135313
|
+
return claudeName.slice(CUSTOM_TOOLS_MCP_PREFIX.length);
|
|
135314
|
+
}
|
|
135315
|
+
return DROID_TO_PI_NAME[claudeName.toLowerCase()] ?? claudeName;
|
|
135316
|
+
}
|
|
135317
|
+
function mapPiToolNameToDroid(piName) {
|
|
135318
|
+
return PI_TO_DROID_NAME[piName] ?? piName;
|
|
135319
|
+
}
|
|
135320
|
+
function translateDroidArgsToPi(claudeToolName, args) {
|
|
135321
|
+
const renames = DROID_TO_PI_ARGS[claudeToolName.toLowerCase()];
|
|
135322
|
+
if (!renames || Object.keys(renames).length === 0) return args;
|
|
135323
|
+
const result = {};
|
|
135324
|
+
for (const [key, value] of Object.entries(args)) {
|
|
135325
|
+
const newKey = renames[key] ?? key;
|
|
135326
|
+
result[newKey] = value;
|
|
135327
|
+
}
|
|
135328
|
+
return result;
|
|
135329
|
+
}
|
|
135330
|
+
function translatePiArgsToDroid(piToolName, args) {
|
|
135331
|
+
const renames = PI_TO_DROID_ARGS[piToolName];
|
|
135332
|
+
if (!renames || Object.keys(renames).length === 0) return args;
|
|
135333
|
+
const result = {};
|
|
135334
|
+
for (const [key, value] of Object.entries(args)) {
|
|
135335
|
+
const newKey = renames[key] ?? key;
|
|
135336
|
+
result[newKey] = value;
|
|
135337
|
+
}
|
|
135338
|
+
return result;
|
|
135339
|
+
}
|
|
135340
|
+
|
|
135341
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/prompt-builder.ts
|
|
135342
|
+
var placeholderImageCount = 0;
|
|
135343
|
+
function translateImageBlock(piBlock) {
|
|
135344
|
+
const block = piBlock;
|
|
135345
|
+
if (typeof block.data === "string" && typeof block.mimeType === "string") {
|
|
135346
|
+
return {
|
|
135347
|
+
type: "image",
|
|
135348
|
+
source: {
|
|
135349
|
+
type: "base64",
|
|
135350
|
+
media_type: block.mimeType,
|
|
135351
|
+
data: block.data
|
|
135352
|
+
}
|
|
135353
|
+
};
|
|
135354
|
+
}
|
|
135355
|
+
return null;
|
|
135356
|
+
}
|
|
135357
|
+
function buildFinalUserContent(content) {
|
|
135358
|
+
if (typeof content === "string") {
|
|
135359
|
+
return [{ type: "text", text: content }];
|
|
135360
|
+
}
|
|
135361
|
+
if (!Array.isArray(content)) {
|
|
135362
|
+
return [{ type: "text", text: "" }];
|
|
135363
|
+
}
|
|
135364
|
+
const blocks = [];
|
|
135365
|
+
for (const rawBlock of content) {
|
|
135366
|
+
const block = rawBlock;
|
|
135367
|
+
if (block.type === "text") {
|
|
135368
|
+
blocks.push({ type: "text", text: typeof block.text === "string" ? block.text : "" });
|
|
135369
|
+
} else if (block.type === "image") {
|
|
135370
|
+
const translated = translateImageBlock(block);
|
|
135371
|
+
if (translated) {
|
|
135372
|
+
blocks.push(translated);
|
|
135373
|
+
} else {
|
|
135374
|
+
blocks.push({
|
|
135375
|
+
type: "text",
|
|
135376
|
+
text: "[An image was shared here but could not be included]"
|
|
135377
|
+
});
|
|
135378
|
+
placeholderImageCount++;
|
|
135379
|
+
}
|
|
135380
|
+
}
|
|
135381
|
+
}
|
|
135382
|
+
return blocks;
|
|
135383
|
+
}
|
|
135384
|
+
function contentHasImages(content) {
|
|
135385
|
+
if (typeof content === "string" || !Array.isArray(content)) return false;
|
|
135386
|
+
return content.some((block) => block.type === "image");
|
|
135387
|
+
}
|
|
135388
|
+
function buildCustomToolResultPrompt(messages) {
|
|
135389
|
+
if (messages.length < 3) return null;
|
|
135390
|
+
const last = messages[messages.length - 1];
|
|
135391
|
+
if (last.role !== "toolResult") return null;
|
|
135392
|
+
if (!last.toolName || !isCustomToolName(last.toolName)) return null;
|
|
135393
|
+
let userMessage = null;
|
|
135394
|
+
for (let i2 = messages.length - 3; i2 >= 0; i2--) {
|
|
135395
|
+
const msg = messages[i2];
|
|
135396
|
+
if (msg.role === "user") {
|
|
135397
|
+
userMessage = userContentToText(msg.content);
|
|
135398
|
+
break;
|
|
135399
|
+
}
|
|
135400
|
+
}
|
|
135401
|
+
if (!userMessage) return null;
|
|
135402
|
+
const toolResult = toolResultContentToText(last.content);
|
|
135403
|
+
return `${userMessage}
|
|
135404
|
+
|
|
135405
|
+
[The ${last.toolName} tool was called and returned the following result]
|
|
135406
|
+
${toolResult}
|
|
135407
|
+
|
|
135408
|
+
Respond to the user using the tool result above.`;
|
|
135409
|
+
}
|
|
135410
|
+
function buildResumePrompt(context) {
|
|
135411
|
+
const messages = context.messages;
|
|
135412
|
+
if (messages.length === 0) return "";
|
|
135413
|
+
let lastAssistantIdx = -1;
|
|
135414
|
+
for (let i2 = messages.length - 1; i2 >= 0; i2--) {
|
|
135415
|
+
if (messages[i2].role === "assistant") {
|
|
135416
|
+
lastAssistantIdx = i2;
|
|
135417
|
+
break;
|
|
135418
|
+
}
|
|
135419
|
+
}
|
|
135420
|
+
const newMessages = messages.slice(lastAssistantIdx + 1);
|
|
135421
|
+
if (newMessages.length === 0) return "";
|
|
135422
|
+
const parts = [];
|
|
135423
|
+
for (const msg of newMessages) {
|
|
135424
|
+
if (msg.role === "toolResult") {
|
|
135425
|
+
if (msg.toolName && isCustomToolName(msg.toolName)) {
|
|
135426
|
+
parts.push(`TOOL RESULT (${msg.toolName}):`);
|
|
135427
|
+
} else {
|
|
135428
|
+
const claudeToolName = msg.toolName ? mapPiToolNameToDroid(msg.toolName) : "unknown";
|
|
135429
|
+
parts.push(`TOOL RESULT (${claudeToolName}):`);
|
|
135430
|
+
}
|
|
135431
|
+
parts.push(toolResultContentToText(msg.content));
|
|
135432
|
+
} else if (msg.role === "user") {
|
|
135433
|
+
if (contentHasImages(msg.content)) {
|
|
135434
|
+
const textSoFar = parts.join("\n");
|
|
135435
|
+
const userContent = buildFinalUserContent(msg.content);
|
|
135436
|
+
const result = [];
|
|
135437
|
+
if (textSoFar) {
|
|
135438
|
+
result.push({ type: "text", text: textSoFar });
|
|
135439
|
+
}
|
|
135440
|
+
result.push(...userContent);
|
|
135441
|
+
return result;
|
|
135442
|
+
}
|
|
135443
|
+
parts.push(userContentToText(msg.content));
|
|
135444
|
+
}
|
|
135445
|
+
}
|
|
135446
|
+
return parts.join("\n") || "";
|
|
135447
|
+
}
|
|
135448
|
+
function buildPrompt(context) {
|
|
135449
|
+
placeholderImageCount = 0;
|
|
135450
|
+
const customToolPrompt = buildCustomToolResultPrompt(context.messages);
|
|
135451
|
+
if (customToolPrompt) {
|
|
135452
|
+
if (placeholderImageCount > 0) {
|
|
135453
|
+
console.warn(
|
|
135454
|
+
`[droid-cli] ${placeholderImageCount} image(s) in conversation history could not be included in the prompt`
|
|
135455
|
+
);
|
|
135456
|
+
}
|
|
135457
|
+
return customToolPrompt;
|
|
135458
|
+
}
|
|
135459
|
+
const finalUserIndex = findFinalUserMessageIndex(context.messages);
|
|
135460
|
+
const finalUserMsg = finalUserIndex >= 0 ? context.messages[finalUserIndex] : void 0;
|
|
135461
|
+
const finalUserHasImages = finalUserMsg !== void 0 && finalUserMsg.role === "user" && contentHasImages(finalUserMsg.content);
|
|
135462
|
+
const anyToolResultHasImages = context.messages.some(
|
|
135463
|
+
(m2) => m2.role === "toolResult" && toolResultHasImages(m2.content)
|
|
135464
|
+
);
|
|
135465
|
+
if (finalUserHasImages || anyToolResultHasImages) {
|
|
135466
|
+
const historyParts = [];
|
|
135467
|
+
const toolResultImageBlocks = [];
|
|
135468
|
+
for (let i2 = 0; i2 < context.messages.length; i2++) {
|
|
135469
|
+
if (i2 === finalUserIndex) continue;
|
|
135470
|
+
const message = context.messages[i2];
|
|
135471
|
+
if (message.role === "user") {
|
|
135472
|
+
historyParts.push("USER:");
|
|
135473
|
+
historyParts.push(userContentToText(message.content));
|
|
135474
|
+
} else if (message.role === "assistant") {
|
|
135475
|
+
historyParts.push("ASSISTANT:");
|
|
135476
|
+
historyParts.push(contentToText(message.content));
|
|
135477
|
+
} else if (message.role === "toolResult") {
|
|
135478
|
+
if (message.toolName && isCustomToolName(message.toolName)) {
|
|
135479
|
+
historyParts.push(`TOOL RESULT (${message.toolName}):`);
|
|
135480
|
+
} else {
|
|
135481
|
+
const claudeToolName = message.toolName ? mapPiToolNameToDroid(message.toolName) : "unknown";
|
|
135482
|
+
historyParts.push(`TOOL RESULT (${claudeToolName}):`);
|
|
135483
|
+
}
|
|
135484
|
+
historyParts.push(toolResultContentToText(message.content));
|
|
135485
|
+
if (Array.isArray(message.content)) {
|
|
135486
|
+
for (const rawBlock of message.content) {
|
|
135487
|
+
const block = rawBlock;
|
|
135488
|
+
if (block.type === "image") {
|
|
135489
|
+
const translated = translateImageBlock(block);
|
|
135490
|
+
if (translated) {
|
|
135491
|
+
toolResultImageBlocks.push(translated);
|
|
135492
|
+
placeholderImageCount--;
|
|
135493
|
+
}
|
|
135494
|
+
}
|
|
135495
|
+
}
|
|
135496
|
+
}
|
|
135497
|
+
}
|
|
135498
|
+
}
|
|
135499
|
+
const finalUserContent = finalUserMsg?.role === "user" ? buildFinalUserContent(finalUserMsg.content) : [];
|
|
135500
|
+
const result = [];
|
|
135501
|
+
const historyText = historyParts.join("\n");
|
|
135502
|
+
if (historyText) {
|
|
135503
|
+
result.push({ type: "text", text: historyText });
|
|
135504
|
+
}
|
|
135505
|
+
result.push(...toolResultImageBlocks);
|
|
135506
|
+
result.push(...finalUserContent);
|
|
135507
|
+
if (placeholderImageCount > 0) {
|
|
135508
|
+
console.warn(
|
|
135509
|
+
`[droid-cli] ${placeholderImageCount} image(s) in conversation history could not be included in the prompt`
|
|
135510
|
+
);
|
|
135511
|
+
}
|
|
135512
|
+
return result;
|
|
135513
|
+
}
|
|
135514
|
+
const parts = [];
|
|
135515
|
+
for (const message of context.messages) {
|
|
135516
|
+
if (message.role === "user") {
|
|
135517
|
+
parts.push("USER:");
|
|
135518
|
+
parts.push(userContentToText(message.content));
|
|
135519
|
+
} else if (message.role === "assistant") {
|
|
135520
|
+
parts.push("ASSISTANT:");
|
|
135521
|
+
parts.push(contentToText(message.content));
|
|
135522
|
+
} else if (message.role === "toolResult") {
|
|
135523
|
+
if (message.toolName && isCustomToolName(message.toolName)) {
|
|
135524
|
+
parts.push(`TOOL RESULT (${message.toolName}):`);
|
|
135525
|
+
} else {
|
|
135526
|
+
const claudeToolName = message.toolName ? mapPiToolNameToDroid(message.toolName) : "unknown";
|
|
135527
|
+
parts.push(`TOOL RESULT (${claudeToolName}):`);
|
|
135528
|
+
}
|
|
135529
|
+
parts.push(toolResultContentToText(message.content));
|
|
135530
|
+
}
|
|
135531
|
+
}
|
|
135532
|
+
if (placeholderImageCount > 0) {
|
|
135533
|
+
console.warn(
|
|
135534
|
+
`[droid-cli] ${placeholderImageCount} image(s) in conversation history could not be included in the prompt`
|
|
135535
|
+
);
|
|
135536
|
+
}
|
|
135537
|
+
return parts.join("\n") || "";
|
|
135655
135538
|
}
|
|
135656
|
-
|
|
135657
|
-
|
|
135658
|
-
|
|
135659
|
-
|
|
135660
|
-
return
|
|
135539
|
+
function findFinalUserMessageIndex(messages) {
|
|
135540
|
+
for (let i2 = messages.length - 1; i2 >= 0; i2--) {
|
|
135541
|
+
if (messages[i2].role === "user") return i2;
|
|
135542
|
+
}
|
|
135543
|
+
return -1;
|
|
135661
135544
|
}
|
|
135662
|
-
|
|
135663
|
-
|
|
135664
|
-
|
|
135665
|
-
|
|
135545
|
+
function buildSystemPrompt(context, cwd) {
|
|
135546
|
+
const parts = [];
|
|
135547
|
+
if (context.systemPrompt) {
|
|
135548
|
+
parts.push(rewriteCustomToolReferences(context.systemPrompt, context.tools));
|
|
135549
|
+
}
|
|
135550
|
+
const agentsPath = resolveAgentsMdPath(cwd);
|
|
135551
|
+
if (agentsPath) {
|
|
135552
|
+
try {
|
|
135553
|
+
const content = readFileSync(agentsPath, "utf-8");
|
|
135554
|
+
const sanitized = sanitizeAgentsContent(content);
|
|
135555
|
+
parts.push(sanitized);
|
|
135556
|
+
} catch {
|
|
135557
|
+
}
|
|
135558
|
+
}
|
|
135559
|
+
if (context.messages?.some((m2) => m2.role === "toolResult")) {
|
|
135560
|
+
parts.push(
|
|
135561
|
+
"IMPORTANT: The conversation history below contains tool results from previously executed tools. Use these results to answer the user's question. Do NOT attempt to re-call tools that already have results."
|
|
135562
|
+
);
|
|
135563
|
+
}
|
|
135564
|
+
const customToolsAddendum = buildCustomToolsAddendum(context.tools);
|
|
135565
|
+
if (customToolsAddendum) {
|
|
135566
|
+
parts.push(customToolsAddendum);
|
|
135567
|
+
}
|
|
135568
|
+
return parts.join("\n\n");
|
|
135666
135569
|
}
|
|
135667
|
-
|
|
135668
|
-
|
|
135669
|
-
|
|
135670
|
-
|
|
135671
|
-
|
|
135570
|
+
var BUILT_IN_PI_TOOLS = /* @__PURE__ */ new Set([
|
|
135571
|
+
"read",
|
|
135572
|
+
"write",
|
|
135573
|
+
"edit",
|
|
135574
|
+
"bash",
|
|
135575
|
+
"grep",
|
|
135576
|
+
"find"
|
|
135577
|
+
]);
|
|
135578
|
+
function rewriteCustomToolReferences(prompt, tools) {
|
|
135579
|
+
if (!prompt || !tools || tools.length === 0) {
|
|
135580
|
+
return prompt;
|
|
135581
|
+
}
|
|
135582
|
+
let result = prompt;
|
|
135583
|
+
for (const tool of tools) {
|
|
135584
|
+
if (BUILT_IN_PI_TOOLS.has(tool.name)) continue;
|
|
135585
|
+
const escaped = tool.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
135586
|
+
const pattern = new RegExp(
|
|
135587
|
+
`(?<![A-Za-z0-9_])(?<!mcp__custom-tools__)${escaped}(?![A-Za-z0-9_])`,
|
|
135588
|
+
"g"
|
|
135589
|
+
);
|
|
135590
|
+
result = result.replace(pattern, `mcp__custom-tools__${tool.name}`);
|
|
135591
|
+
}
|
|
135592
|
+
return result;
|
|
135672
135593
|
}
|
|
135673
|
-
function
|
|
135674
|
-
if (
|
|
135675
|
-
|
|
135676
|
-
|
|
135677
|
-
const
|
|
135678
|
-
|
|
135679
|
-
|
|
135594
|
+
function buildCustomToolsAddendum(tools) {
|
|
135595
|
+
if (!tools || tools.length === 0) return "";
|
|
135596
|
+
const customNames = tools.map((t2) => t2.name).filter((name) => !BUILT_IN_PI_TOOLS.has(name));
|
|
135597
|
+
if (customNames.length === 0) return "";
|
|
135598
|
+
const lines = customNames.sort().map((name) => `- \`${name}\` is exposed as \`mcp__custom-tools__${name}\``);
|
|
135599
|
+
return [
|
|
135600
|
+
"## Custom tool naming (MCP)",
|
|
135601
|
+
"",
|
|
135602
|
+
"The following pi extension tools are available under MCP-prefixed",
|
|
135603
|
+
"names. When a system prompt or task instruction asks you to call one",
|
|
135604
|
+
"of these by its short name, call the MCP-prefixed name directly.",
|
|
135605
|
+
"",
|
|
135606
|
+
...lines
|
|
135607
|
+
].join("\n");
|
|
135680
135608
|
}
|
|
135681
|
-
function
|
|
135682
|
-
if (
|
|
135683
|
-
|
|
135684
|
-
const
|
|
135685
|
-
const
|
|
135686
|
-
|
|
135687
|
-
|
|
135688
|
-
|
|
135689
|
-
|
|
135609
|
+
function userContentToText(content) {
|
|
135610
|
+
if (typeof content === "string") return content;
|
|
135611
|
+
if (!Array.isArray(content)) return "";
|
|
135612
|
+
const texts = [];
|
|
135613
|
+
for (const rawBlock of content) {
|
|
135614
|
+
const block = rawBlock;
|
|
135615
|
+
if (block.type === "text") {
|
|
135616
|
+
texts.push(typeof block.text === "string" ? block.text : "");
|
|
135617
|
+
} else if (block.type === "image") {
|
|
135618
|
+
texts.push("[An image was shared here but could not be included]");
|
|
135619
|
+
placeholderImageCount++;
|
|
135620
|
+
}
|
|
135621
|
+
}
|
|
135622
|
+
return texts.join("\n");
|
|
135690
135623
|
}
|
|
135691
|
-
function
|
|
135692
|
-
|
|
135624
|
+
function contentToText(content) {
|
|
135625
|
+
if (typeof content === "string") return content;
|
|
135626
|
+
if (!Array.isArray(content)) return "";
|
|
135627
|
+
return content.map((rawBlock) => {
|
|
135628
|
+
const block = rawBlock;
|
|
135629
|
+
if (block.type === "text") return typeof block.text === "string" ? block.text : "";
|
|
135630
|
+
if (block.type === "thinking") return "";
|
|
135631
|
+
if (block.type === "toolCall") {
|
|
135632
|
+
const name = typeof block.name === "string" ? block.name : "";
|
|
135633
|
+
const rawArgs = block.arguments;
|
|
135634
|
+
const argsObject = rawArgs && typeof rawArgs === "object" ? rawArgs : void 0;
|
|
135635
|
+
const isCustom = isCustomToolName(name);
|
|
135636
|
+
if (isCustom) {
|
|
135637
|
+
const argsStr2 = argsObject ? JSON.stringify(argsObject) : typeof rawArgs === "string" ? JSON.stringify(rawArgs) : "{}";
|
|
135638
|
+
return `[Used ${name} tool with args: ${argsStr2}]`;
|
|
135639
|
+
}
|
|
135640
|
+
const claudeName = mapPiToolNameToDroid(name);
|
|
135641
|
+
const claudeArgs = argsObject ? translatePiArgsToDroid(name, argsObject) : void 0;
|
|
135642
|
+
const argsStr = claudeArgs ? JSON.stringify(claudeArgs) : typeof rawArgs === "string" ? JSON.stringify(rawArgs) : "{}";
|
|
135643
|
+
return `[Prior tool call \u2014 already executed; result follows in TOOL RESULT (${claudeName}):] args=${argsStr}`;
|
|
135644
|
+
}
|
|
135645
|
+
return `[${String(block.type)}]`;
|
|
135646
|
+
}).join("\n");
|
|
135693
135647
|
}
|
|
135694
|
-
|
|
135695
|
-
|
|
135696
|
-
|
|
135697
|
-
|
|
135698
|
-
|
|
135699
|
-
|
|
135700
|
-
if (
|
|
135701
|
-
|
|
135702
|
-
|
|
135648
|
+
function toolResultContentToText(content) {
|
|
135649
|
+
if (typeof content === "string") return content;
|
|
135650
|
+
if (!Array.isArray(content)) return "";
|
|
135651
|
+
const texts = [];
|
|
135652
|
+
for (const rawBlock of content) {
|
|
135653
|
+
const block = rawBlock;
|
|
135654
|
+
if (block.type === "text") {
|
|
135655
|
+
texts.push(typeof block.text === "string" ? block.text : "");
|
|
135656
|
+
} else if (block.type === "image") {
|
|
135657
|
+
texts.push("[An image was shared here but could not be included]");
|
|
135658
|
+
placeholderImageCount++;
|
|
135659
|
+
}
|
|
135703
135660
|
}
|
|
135704
|
-
return
|
|
135661
|
+
return texts.join("\n");
|
|
135705
135662
|
}
|
|
135706
|
-
function
|
|
135707
|
-
|
|
135708
|
-
|
|
135709
|
-
|
|
135710
|
-
|
|
135711
|
-
|
|
135712
|
-
|
|
135713
|
-
|
|
135663
|
+
function toolResultHasImages(content) {
|
|
135664
|
+
if (typeof content === "string" || !Array.isArray(content)) return false;
|
|
135665
|
+
return content.some((block) => block.type === "image");
|
|
135666
|
+
}
|
|
135667
|
+
function resolveAgentsMdPath(cwd) {
|
|
135668
|
+
let current = resolve(cwd);
|
|
135669
|
+
while (true) {
|
|
135670
|
+
const candidate = join(current, "AGENTS.md");
|
|
135671
|
+
if (existsSync(candidate)) return candidate;
|
|
135672
|
+
const parent = dirname(current);
|
|
135673
|
+
if (parent === current) break;
|
|
135674
|
+
current = parent;
|
|
135714
135675
|
}
|
|
135715
|
-
|
|
135676
|
+
const globalHome = process.env.HOME || process.env.USERPROFILE || homedir();
|
|
135677
|
+
const globalPath = join(globalHome, ".pi", "agent", "AGENTS.md");
|
|
135678
|
+
if (existsSync(globalPath)) return globalPath;
|
|
135679
|
+
return void 0;
|
|
135716
135680
|
}
|
|
135717
|
-
function
|
|
135718
|
-
|
|
135681
|
+
function sanitizeAgentsContent(content) {
|
|
135682
|
+
let sanitized = content;
|
|
135683
|
+
sanitized = sanitized.replace(/~\/\.pi\b/gi, "~/.claude");
|
|
135684
|
+
sanitized = sanitized.replace(/(^|[\s'"`])\.pi\//g, "$1.claude/");
|
|
135685
|
+
sanitized = sanitized.replace(/\b\.pi\b/gi, ".claude");
|
|
135686
|
+
return sanitized;
|
|
135719
135687
|
}
|
|
135720
135688
|
|
|
135721
|
-
// ../../
|
|
135722
|
-
|
|
135723
|
-
|
|
135724
|
-
|
|
135725
|
-
|
|
135726
|
-
|
|
135727
|
-
|
|
135728
|
-
|
|
135729
|
-
value[key] = FromType22(direction, context, RecordValue(type), value[key]);
|
|
135730
|
-
}
|
|
135731
|
-
return Callback(direction, context, type, value);
|
|
135689
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/process-manager.ts
|
|
135690
|
+
import { execSync, spawn } from "node:child_process";
|
|
135691
|
+
import { writeFileSync, unlinkSync } from "node:fs";
|
|
135692
|
+
import { join as join2 } from "node:path";
|
|
135693
|
+
import { tmpdir } from "node:os";
|
|
135694
|
+
function debugLog(message) {
|
|
135695
|
+
if (process.env.PI_DROID_CLI_DEBUG !== "1") return;
|
|
135696
|
+
console.error(`[droid-cli] ${message}`);
|
|
135732
135697
|
}
|
|
135733
|
-
function
|
|
135734
|
-
const
|
|
135735
|
-
|
|
135736
|
-
|
|
135737
|
-
|
|
135738
|
-
|
|
135739
|
-
|
|
135740
|
-
|
|
135741
|
-
|
|
135698
|
+
function buildDroidSpawnArgs(modelId, systemPrompt, options) {
|
|
135699
|
+
const args = [
|
|
135700
|
+
"-p",
|
|
135701
|
+
"--input-format",
|
|
135702
|
+
"stream-json",
|
|
135703
|
+
"--output-format",
|
|
135704
|
+
"stream-json",
|
|
135705
|
+
"--verbose",
|
|
135706
|
+
"--include-partial-messages",
|
|
135707
|
+
"--model",
|
|
135708
|
+
modelId
|
|
135709
|
+
];
|
|
135710
|
+
if (options?.resumeSessionId) {
|
|
135711
|
+
args.push("--resume", options.resumeSessionId);
|
|
135712
|
+
} else if (options?.newSessionId) {
|
|
135713
|
+
args.push("--session-id", options.newSessionId);
|
|
135742
135714
|
}
|
|
135743
|
-
|
|
135744
|
-
|
|
135745
|
-
|
|
135746
|
-
|
|
135747
|
-
|
|
135748
|
-
|
|
135749
|
-
|
|
135750
|
-
|
|
135751
|
-
|
|
135715
|
+
if (systemPrompt) {
|
|
135716
|
+
const tmpFile = join2(
|
|
135717
|
+
tmpdir(),
|
|
135718
|
+
`droid-cli-sysprompt-${process.pid}.txt`
|
|
135719
|
+
);
|
|
135720
|
+
writeFileSync(tmpFile, systemPrompt, "utf-8");
|
|
135721
|
+
args.push("--append-system-prompt", tmpFile);
|
|
135722
|
+
}
|
|
135723
|
+
if (options?.effort) {
|
|
135724
|
+
args.push("--effort", options.effort);
|
|
135725
|
+
}
|
|
135726
|
+
if (options?.mcpConfigPath) {
|
|
135727
|
+
args.push("--mcp-config", options.mcpConfigPath);
|
|
135728
|
+
}
|
|
135729
|
+
return args;
|
|
135752
135730
|
}
|
|
135753
|
-
function
|
|
135754
|
-
|
|
135731
|
+
function spawnDroid(modelId, systemPrompt, options) {
|
|
135732
|
+
const args = buildDroidSpawnArgs(modelId, systemPrompt, {
|
|
135733
|
+
effort: options?.effort,
|
|
135734
|
+
mcpConfigPath: options?.mcpConfigPath,
|
|
135735
|
+
resumeSessionId: options?.resumeSessionId,
|
|
135736
|
+
newSessionId: options?.newSessionId
|
|
135737
|
+
});
|
|
135738
|
+
const proc = spawn("droid", args, {
|
|
135739
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
135740
|
+
cwd: options?.cwd ?? process.cwd()
|
|
135741
|
+
});
|
|
135742
|
+
debugLog(`spawnDroid: pid=${proc.pid} model=${modelId}`);
|
|
135743
|
+
return proc;
|
|
135755
135744
|
}
|
|
135756
|
-
|
|
135757
|
-
|
|
135758
|
-
|
|
135759
|
-
|
|
135760
|
-
return Unreachable();
|
|
135761
|
-
for (let i2 = 0; i2 < Math.min(type.items.length, value.length); i2++) {
|
|
135762
|
-
value[i2] = FromType22(direction, context, type.items[i2], value[i2]);
|
|
135745
|
+
function cleanupSystemPromptFile() {
|
|
135746
|
+
try {
|
|
135747
|
+
unlinkSync(join2(tmpdir(), `droid-cli-sysprompt-${process.pid}.txt`));
|
|
135748
|
+
} catch {
|
|
135763
135749
|
}
|
|
135764
|
-
return Callback(direction, context, type, value);
|
|
135765
135750
|
}
|
|
135766
|
-
function
|
|
135767
|
-
const
|
|
135768
|
-
|
|
135769
|
-
|
|
135770
|
-
|
|
135771
|
-
|
|
135772
|
-
|
|
135773
|
-
|
|
135751
|
+
function writeUserMessage(proc, prompt) {
|
|
135752
|
+
const message = {
|
|
135753
|
+
type: "user",
|
|
135754
|
+
message: {
|
|
135755
|
+
role: "user",
|
|
135756
|
+
content: prompt
|
|
135757
|
+
}
|
|
135758
|
+
};
|
|
135759
|
+
proc.stdin.write(JSON.stringify(message) + "\n");
|
|
135760
|
+
proc.stdin.end();
|
|
135774
135761
|
}
|
|
135775
|
-
function
|
|
135776
|
-
|
|
135762
|
+
function forceKillProcess(proc) {
|
|
135763
|
+
if (proc.killed || proc.exitCode !== null) return;
|
|
135764
|
+
proc.kill("SIGKILL");
|
|
135777
135765
|
}
|
|
135778
|
-
|
|
135779
|
-
|
|
135780
|
-
|
|
135781
|
-
|
|
135782
|
-
if (!Check2(context, schema, value))
|
|
135783
|
-
continue;
|
|
135784
|
-
const variant = FromType22(direction, context, schema, value);
|
|
135785
|
-
return Callback(direction, context, type, variant);
|
|
135786
|
-
}
|
|
135787
|
-
return value;
|
|
135766
|
+
var activeProcesses = /* @__PURE__ */ new Set();
|
|
135767
|
+
function registerProcess(proc) {
|
|
135768
|
+
activeProcesses.add(proc);
|
|
135769
|
+
proc.on("exit", () => activeProcesses.delete(proc));
|
|
135788
135770
|
}
|
|
135789
|
-
function
|
|
135790
|
-
|
|
135791
|
-
|
|
135792
|
-
const variant = FromType22(direction, context, schema, Clone2(exterior));
|
|
135793
|
-
if (!Check2(context, schema, variant))
|
|
135794
|
-
continue;
|
|
135795
|
-
return variant;
|
|
135771
|
+
function killAllProcesses() {
|
|
135772
|
+
for (const proc of activeProcesses) {
|
|
135773
|
+
forceKillProcess(proc);
|
|
135796
135774
|
}
|
|
135797
|
-
|
|
135775
|
+
activeProcesses.clear();
|
|
135798
135776
|
}
|
|
135799
|
-
function
|
|
135800
|
-
|
|
135777
|
+
function cleanupProcess(proc) {
|
|
135778
|
+
setTimeout(() => {
|
|
135779
|
+
forceKillProcess(proc);
|
|
135780
|
+
}, 500);
|
|
135801
135781
|
}
|
|
135802
|
-
|
|
135803
|
-
|
|
135804
|
-
|
|
135805
|
-
|
|
135782
|
+
function captureStderr(proc) {
|
|
135783
|
+
let buffer = "";
|
|
135784
|
+
proc.stderr.on("data", (data) => {
|
|
135785
|
+
buffer += data.toString();
|
|
135786
|
+
});
|
|
135787
|
+
return () => buffer;
|
|
135806
135788
|
}
|
|
135807
|
-
|
|
135808
|
-
|
|
135809
|
-
|
|
135810
|
-
|
|
135811
|
-
|
|
135812
|
-
|
|
135813
|
-
}
|
|
135814
|
-
|
|
135815
|
-
|
|
135816
|
-
|
|
135817
|
-
|
|
135789
|
+
function runDroidProbe(args, timeoutMs = 45e3) {
|
|
135790
|
+
return new Promise((resolve2) => {
|
|
135791
|
+
const proc = spawn("droid", args, { stdio: "ignore" });
|
|
135792
|
+
const timer = setTimeout(() => {
|
|
135793
|
+
try {
|
|
135794
|
+
proc.kill("SIGKILL");
|
|
135795
|
+
} catch {
|
|
135796
|
+
}
|
|
135797
|
+
resolve2(124);
|
|
135798
|
+
}, timeoutMs);
|
|
135799
|
+
proc.once("error", () => {
|
|
135800
|
+
clearTimeout(timer);
|
|
135801
|
+
resolve2(127);
|
|
135802
|
+
});
|
|
135803
|
+
proc.once("exit", (code) => {
|
|
135804
|
+
clearTimeout(timer);
|
|
135805
|
+
resolve2(code ?? 1);
|
|
135806
|
+
});
|
|
135807
|
+
});
|
|
135818
135808
|
}
|
|
135819
|
-
function
|
|
135820
|
-
|
|
135809
|
+
async function validateCliPresenceAsync() {
|
|
135810
|
+
const code = await runDroidProbe(["--version"]);
|
|
135811
|
+
if (code === 0) return { ok: true };
|
|
135812
|
+
return {
|
|
135813
|
+
ok: false,
|
|
135814
|
+
error: new Error(
|
|
135815
|
+
"Droid CLI not found on PATH. Install Droid CLI and then run: droid auth login"
|
|
135816
|
+
)
|
|
135817
|
+
};
|
|
135821
135818
|
}
|
|
135822
|
-
|
|
135823
|
-
|
|
135824
|
-
(
|
|
135825
|
-
(
|
|
135826
|
-
|
|
135827
|
-
|
|
135828
|
-
|
|
135829
|
-
]);
|
|
135830
|
-
|
|
135831
|
-
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/codec/encode.mjs
|
|
135832
|
-
var EncodeError = class extends AssertError {
|
|
135833
|
-
constructor(value, errors) {
|
|
135834
|
-
super("Encode", value, errors);
|
|
135835
|
-
}
|
|
135836
|
-
};
|
|
135837
|
-
function Assert2(context, type, value) {
|
|
135838
|
-
if (!Check2(context, type, value))
|
|
135839
|
-
throw new EncodeError(value, Errors2(context, type, value));
|
|
135840
|
-
return value;
|
|
135819
|
+
async function validateCliAuthAsync() {
|
|
135820
|
+
const code = await runDroidProbe(["auth", "status"]);
|
|
135821
|
+
if (code === 0) return true;
|
|
135822
|
+
console.warn(
|
|
135823
|
+
"[droid-cli] Droid CLI is not authenticated. Run 'droid auth login' to authenticate."
|
|
135824
|
+
);
|
|
135825
|
+
return false;
|
|
135841
135826
|
}
|
|
135842
|
-
function
|
|
135843
|
-
|
|
135827
|
+
async function discoverDroidModels() {
|
|
135828
|
+
const attempts = [["models", "--json"], ["model", "list", "--json"], ["models"]];
|
|
135829
|
+
for (const args of attempts) {
|
|
135830
|
+
const models = await new Promise((resolve2) => {
|
|
135831
|
+
const proc = spawn("droid", args, { stdio: ["ignore", "pipe", "ignore"] });
|
|
135832
|
+
let out = "";
|
|
135833
|
+
proc.stdout?.on("data", (chunk) => {
|
|
135834
|
+
out += chunk.toString();
|
|
135835
|
+
});
|
|
135836
|
+
proc.once("error", () => resolve2(null));
|
|
135837
|
+
proc.once("exit", (code) => {
|
|
135838
|
+
if (code !== 0) return resolve2(null);
|
|
135839
|
+
const trimmed = out.trim();
|
|
135840
|
+
if (!trimmed) return resolve2([]);
|
|
135841
|
+
try {
|
|
135842
|
+
const parsed = JSON.parse(trimmed);
|
|
135843
|
+
if (Array.isArray(parsed)) {
|
|
135844
|
+
return resolve2(
|
|
135845
|
+
parsed.map(
|
|
135846
|
+
(entry) => typeof entry === "string" ? entry : typeof entry?.id === "string" ? entry.id : typeof entry?.name === "string" ? entry.name : void 0
|
|
135847
|
+
).filter((id) => Boolean(id))
|
|
135848
|
+
);
|
|
135849
|
+
}
|
|
135850
|
+
} catch {
|
|
135851
|
+
}
|
|
135852
|
+
resolve2(
|
|
135853
|
+
trimmed.split(/\r?\n/).map((line) => line.trim()).filter(Boolean)
|
|
135854
|
+
);
|
|
135855
|
+
});
|
|
135856
|
+
});
|
|
135857
|
+
if (models && models.length > 0) {
|
|
135858
|
+
return Array.from(new Set(models));
|
|
135859
|
+
}
|
|
135860
|
+
}
|
|
135861
|
+
return [];
|
|
135844
135862
|
}
|
|
135845
|
-
var Encoder = Pipeline([
|
|
135846
|
-
(_context, _type, value) => Clone2(value),
|
|
135847
|
-
(context, type, value) => EncodeUnsafe(context, type, value),
|
|
135848
|
-
(context, type, value) => Default(context, type, value),
|
|
135849
|
-
(context, type, value) => Convert(context, type, value),
|
|
135850
|
-
(context, type, value) => Clean(context, type, value),
|
|
135851
|
-
(context, type, value) => Assert2(context, type, value)
|
|
135852
|
-
]);
|
|
135853
135863
|
|
|
135854
|
-
// ../../
|
|
135855
|
-
|
|
135856
|
-
|
|
135857
|
-
|
|
135864
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/stream-parser.ts
|
|
135865
|
+
function parseLine(line) {
|
|
135866
|
+
const trimmed = line.trim();
|
|
135867
|
+
if (!trimmed) {
|
|
135868
|
+
return null;
|
|
135858
135869
|
}
|
|
135859
|
-
|
|
135860
|
-
|
|
135861
|
-
|
|
135862
|
-
|
|
135863
|
-
|
|
135870
|
+
if (!trimmed.startsWith("{")) {
|
|
135871
|
+
return null;
|
|
135872
|
+
}
|
|
135873
|
+
let parsed;
|
|
135874
|
+
try {
|
|
135875
|
+
parsed = JSON.parse(trimmed);
|
|
135876
|
+
} catch {
|
|
135877
|
+
console.error("Failed to parse NDJSON line:", trimmed);
|
|
135878
|
+
return null;
|
|
135879
|
+
}
|
|
135880
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
135881
|
+
return null;
|
|
135882
|
+
}
|
|
135883
|
+
return parsed;
|
|
135864
135884
|
}
|
|
135865
|
-
var Parser = Pipeline([
|
|
135866
|
-
(_context, _type, value) => Clone2(value),
|
|
135867
|
-
(context, type, value) => Default(context, type, value),
|
|
135868
|
-
(context, type, value) => Convert(context, type, value),
|
|
135869
|
-
(context, type, value) => Clean(context, type, value),
|
|
135870
|
-
(context, type, value) => Assert3(context, type, value)
|
|
135871
|
-
]);
|
|
135872
|
-
|
|
135873
|
-
// ../../node_modules/.pnpm/typebox@1.1.32/node_modules/typebox/build/value/delta/edit.mjs
|
|
135874
|
-
var Insert = _Object_({
|
|
135875
|
-
type: Literal("insert"),
|
|
135876
|
-
path: String2(),
|
|
135877
|
-
value: Unknown()
|
|
135878
|
-
});
|
|
135879
|
-
var Update2 = Object({
|
|
135880
|
-
type: Literal("update"),
|
|
135881
|
-
path: String2(),
|
|
135882
|
-
value: Unknown()
|
|
135883
|
-
});
|
|
135884
|
-
var Delete2 = _Object_({
|
|
135885
|
-
type: Literal("delete"),
|
|
135886
|
-
path: String2()
|
|
135887
|
-
});
|
|
135888
|
-
var Edit = Union([Insert, Update2, Delete2]);
|
|
135889
135885
|
|
|
135890
|
-
// ../../
|
|
135891
|
-
var TYPEBOX_KIND = Symbol.for("TypeBox.Kind");
|
|
135892
|
-
|
|
135893
|
-
// ../../plugins/fusion-plugin-droid-runtime/dist/event-bridge.js
|
|
135886
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/event-bridge.ts
|
|
135894
135887
|
function mapStopReason5(reason) {
|
|
135895
135888
|
switch (reason) {
|
|
135896
135889
|
case "tool_use":
|
|
@@ -136025,8 +136018,7 @@ function createEventBridge(stream2, model) {
|
|
|
136025
136018
|
const deltaType = event.delta?.type;
|
|
136026
136019
|
if (deltaType === "text_delta" && event.delta.text != null) {
|
|
136027
136020
|
const idx = blocks.findIndex((b) => b.index === event.index);
|
|
136028
|
-
if (idx === -1)
|
|
136029
|
-
return;
|
|
136021
|
+
if (idx === -1) return;
|
|
136030
136022
|
const block = blocks[idx];
|
|
136031
136023
|
if (block.type === "text") {
|
|
136032
136024
|
block.text += event.delta.text;
|
|
@@ -136041,8 +136033,7 @@ function createEventBridge(stream2, model) {
|
|
|
136041
136033
|
}
|
|
136042
136034
|
} else if (deltaType === "thinking_delta" && event.delta.thinking != null) {
|
|
136043
136035
|
const idx = blocks.findIndex((b) => b.index === event.index);
|
|
136044
|
-
if (idx === -1)
|
|
136045
|
-
return;
|
|
136036
|
+
if (idx === -1) return;
|
|
136046
136037
|
const block = blocks[idx];
|
|
136047
136038
|
if (block.type === "thinking") {
|
|
136048
136039
|
block.text += event.delta.thinking;
|
|
@@ -136057,8 +136048,7 @@ function createEventBridge(stream2, model) {
|
|
|
136057
136048
|
}
|
|
136058
136049
|
} else if (deltaType === "input_json_delta" && event.delta.partial_json != null) {
|
|
136059
136050
|
const idx = blocks.findIndex((b) => b.index === event.index);
|
|
136060
|
-
if (idx === -1)
|
|
136061
|
-
return;
|
|
136051
|
+
if (idx === -1) return;
|
|
136062
136052
|
const block = blocks[idx];
|
|
136063
136053
|
if (block.type === "tool_use") {
|
|
136064
136054
|
block.partialJson += event.delta.partial_json;
|
|
@@ -136076,8 +136066,7 @@ function createEventBridge(stream2, model) {
|
|
|
136076
136066
|
}
|
|
136077
136067
|
} else if (deltaType === "signature_delta" && event.delta.signature != null) {
|
|
136078
136068
|
const idx = blocks.findIndex((b) => b.index === event.index);
|
|
136079
|
-
if (idx === -1)
|
|
136080
|
-
return;
|
|
136069
|
+
if (idx === -1) return;
|
|
136081
136070
|
const block = blocks[idx];
|
|
136082
136071
|
if (block.type === "thinking") {
|
|
136083
136072
|
const contentBlock = output.content[idx];
|
|
@@ -136087,8 +136076,7 @@ function createEventBridge(stream2, model) {
|
|
|
136087
136076
|
}
|
|
136088
136077
|
function handleContentBlockStop(event) {
|
|
136089
136078
|
const idx = blocks.findIndex((b) => b.index === event.index);
|
|
136090
|
-
if (idx === -1)
|
|
136091
|
-
return;
|
|
136079
|
+
if (idx === -1) return;
|
|
136092
136080
|
const block = blocks[idx];
|
|
136093
136081
|
delete block.index;
|
|
136094
136082
|
if (block.type === "text") {
|
|
@@ -136140,8 +136128,7 @@ function createEventBridge(stream2, model) {
|
|
|
136140
136128
|
}
|
|
136141
136129
|
const usage = event.usage;
|
|
136142
136130
|
if (usage) {
|
|
136143
|
-
if (usage.input_tokens != null)
|
|
136144
|
-
output.usage.input = usage.input_tokens;
|
|
136131
|
+
if (usage.input_tokens != null) output.usage.input = usage.input_tokens;
|
|
136145
136132
|
if (usage.output_tokens != null)
|
|
136146
136133
|
output.usage.output = usage.output_tokens;
|
|
136147
136134
|
output.usage.totalTokens = output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
|
|
@@ -136156,7 +136143,7 @@ function createEventBridge(stream2, model) {
|
|
|
136156
136143
|
};
|
|
136157
136144
|
}
|
|
136158
136145
|
|
|
136159
|
-
// ../../plugins/fusion-plugin-droid-runtime/
|
|
136146
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/thinking-config.ts
|
|
136160
136147
|
var STANDARD_EFFORT_MAP = {
|
|
136161
136148
|
minimal: "low",
|
|
136162
136149
|
low: "low",
|
|
@@ -136183,22 +136170,23 @@ function mapThinkingEffort(reasoning, modelId, thinkingBudgets) {
|
|
|
136183
136170
|
return void 0;
|
|
136184
136171
|
}
|
|
136185
136172
|
if (thinkingBudgets && Object.keys(thinkingBudgets).length > 0) {
|
|
136186
|
-
console.warn(
|
|
136173
|
+
console.warn(
|
|
136174
|
+
"[droid-cli] Custom thinkingBudgets are not supported with CLI subprocess. The CLI uses --effort levels instead of token budgets. Budgets will be ignored."
|
|
136175
|
+
);
|
|
136187
136176
|
}
|
|
136188
136177
|
const isOpus = modelId ? isOpusModel(modelId) : false;
|
|
136189
136178
|
const map2 = isOpus ? OPUS_EFFORT_MAP : STANDARD_EFFORT_MAP;
|
|
136190
136179
|
return map2[reasoning];
|
|
136191
136180
|
}
|
|
136192
136181
|
|
|
136193
|
-
// ../../plugins/fusion-plugin-droid-runtime/
|
|
136182
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/provider.ts
|
|
136194
136183
|
var INACTIVITY_TIMEOUT_MS = 30 * 6e4;
|
|
136195
136184
|
var FIRST_LINE_TIMEOUT_MS = 6e4;
|
|
136196
136185
|
function isDebugStreamEnabled() {
|
|
136197
136186
|
return process.env.PI_DROID_CLI_DEBUG === "1";
|
|
136198
136187
|
}
|
|
136199
136188
|
function debugLog2(message) {
|
|
136200
|
-
if (!isDebugStreamEnabled())
|
|
136201
|
-
return;
|
|
136189
|
+
if (!isDebugStreamEnabled()) return;
|
|
136202
136190
|
console.error(`[droid-cli] ${message}`);
|
|
136203
136191
|
}
|
|
136204
136192
|
function streamViaCli(model, context, options) {
|
|
@@ -136208,8 +136196,7 @@ function streamViaCli(model, context, options) {
|
|
|
136208
136196
|
let abortHandler;
|
|
136209
136197
|
try {
|
|
136210
136198
|
let endStreamWithError2 = function(errMsg) {
|
|
136211
|
-
if (streamEnded || broken)
|
|
136212
|
-
return;
|
|
136199
|
+
if (streamEnded || broken) return;
|
|
136213
136200
|
streamEnded = true;
|
|
136214
136201
|
const output = bridge.getOutput();
|
|
136215
136202
|
const errorMessage = {
|
|
@@ -136224,11 +136211,12 @@ function streamViaCli(model, context, options) {
|
|
|
136224
136211
|
});
|
|
136225
136212
|
stream2.end();
|
|
136226
136213
|
}, resetInactivityTimer2 = function() {
|
|
136227
|
-
if (inactivityTimer !== void 0)
|
|
136228
|
-
clearTimeout(inactivityTimer);
|
|
136214
|
+
if (inactivityTimer !== void 0) clearTimeout(inactivityTimer);
|
|
136229
136215
|
inactivityTimer = setTimeout(() => {
|
|
136230
136216
|
forceKillProcess(proc);
|
|
136231
|
-
endStreamWithError2(
|
|
136217
|
+
endStreamWithError2(
|
|
136218
|
+
`Droid CLI subprocess timed out: no output for ${INACTIVITY_TIMEOUT_MS / 1e3} seconds`
|
|
136219
|
+
);
|
|
136232
136220
|
}, INACTIVITY_TIMEOUT_MS);
|
|
136233
136221
|
};
|
|
136234
136222
|
var endStreamWithError = endStreamWithError2, resetInactivityTimer = resetInactivityTimer2;
|
|
@@ -136236,7 +136224,11 @@ function streamViaCli(model, context, options) {
|
|
|
136236
136224
|
const resumeSessionId = options?.sessionId && context.messages.length > 1 ? options.sessionId : void 0;
|
|
136237
136225
|
const prompt = resumeSessionId ? buildResumePrompt(context) : buildPrompt(context);
|
|
136238
136226
|
const systemPrompt = resumeSessionId ? void 0 : buildSystemPrompt(context, cwd);
|
|
136239
|
-
const effort = mapThinkingEffort(
|
|
136227
|
+
const effort = mapThinkingEffort(
|
|
136228
|
+
options?.reasoning,
|
|
136229
|
+
model.id,
|
|
136230
|
+
options?.thinkingBudgets
|
|
136231
|
+
);
|
|
136240
136232
|
const spawnOptions = {
|
|
136241
136233
|
cwd,
|
|
136242
136234
|
signal: options?.signal,
|
|
@@ -136254,7 +136246,9 @@ function streamViaCli(model, context, options) {
|
|
|
136254
136246
|
resumeSessionId,
|
|
136255
136247
|
newSessionId: !resumeSessionId ? options?.sessionId : void 0
|
|
136256
136248
|
});
|
|
136257
|
-
debugLog2(
|
|
136249
|
+
debugLog2(
|
|
136250
|
+
`spawned droid subprocess pid=${proc.pid ?? "unknown"} args=${JSON.stringify(spawnArgs)}`
|
|
136251
|
+
);
|
|
136258
136252
|
writeUserMessage(proc, prompt);
|
|
136259
136253
|
debugLog2("user message written to stdin, stdin.end() called");
|
|
136260
136254
|
const bridge = createEventBridge(stream2, model);
|
|
@@ -136281,16 +136275,14 @@ function streamViaCli(model, context, options) {
|
|
|
136281
136275
|
terminal: false
|
|
136282
136276
|
});
|
|
136283
136277
|
proc.on("error", (err) => {
|
|
136284
|
-
if (broken)
|
|
136285
|
-
return;
|
|
136278
|
+
if (broken) return;
|
|
136286
136279
|
const stderr = getStderr();
|
|
136287
136280
|
endStreamWithError2(stderr || err.message);
|
|
136288
136281
|
});
|
|
136289
136282
|
proc.on("close", (code, _signal) => {
|
|
136290
136283
|
clearTimeout(inactivityTimer);
|
|
136291
136284
|
debugLog2(`subprocess closed: code=${code} signal=${_signal}`);
|
|
136292
|
-
if (broken)
|
|
136293
|
-
return;
|
|
136285
|
+
if (broken) return;
|
|
136294
136286
|
const stderr = getStderr().trim();
|
|
136295
136287
|
if (stderr) {
|
|
136296
136288
|
console.warn(`[droid-cli] Droid CLI stderr on close: ${stderr}`);
|
|
@@ -136302,10 +136294,11 @@ function streamViaCli(model, context, options) {
|
|
|
136302
136294
|
});
|
|
136303
136295
|
resetInactivityTimer2();
|
|
136304
136296
|
const firstLineTimer = setTimeout(() => {
|
|
136305
|
-
if (firstLineReceived)
|
|
136306
|
-
return;
|
|
136297
|
+
if (firstLineReceived) return;
|
|
136307
136298
|
forceKillProcess(proc);
|
|
136308
|
-
endStreamWithError2(
|
|
136299
|
+
endStreamWithError2(
|
|
136300
|
+
`Droid CLI produced no output within ${FIRST_LINE_TIMEOUT_MS / 1e3}s \u2014 likely binary hang or auth failure (try \`droid --version\` and \`droid auth status\`)`
|
|
136301
|
+
);
|
|
136309
136302
|
}, FIRST_LINE_TIMEOUT_MS);
|
|
136310
136303
|
proc.on("close", () => clearTimeout(firstLineTimer));
|
|
136311
136304
|
rl.on("line", (line) => {
|
|
@@ -136313,12 +136306,10 @@ function streamViaCli(model, context, options) {
|
|
|
136313
136306
|
firstLineReceived = true;
|
|
136314
136307
|
debugLog2("first stdout line received from Droid CLI");
|
|
136315
136308
|
}
|
|
136316
|
-
if (broken)
|
|
136317
|
-
return;
|
|
136309
|
+
if (broken) return;
|
|
136318
136310
|
resetInactivityTimer2();
|
|
136319
136311
|
const msg = parseLine(line);
|
|
136320
|
-
if (!msg)
|
|
136321
|
-
return;
|
|
136312
|
+
if (!msg) return;
|
|
136322
136313
|
if (msg.type === "stream_event") {
|
|
136323
136314
|
const isTopLevel = !msg.parent_tool_use_id;
|
|
136324
136315
|
if (isTopLevel) {
|
|
@@ -136328,7 +136319,9 @@ function streamViaCli(model, context, options) {
|
|
|
136328
136319
|
const toolName = msg.event.content_block.name;
|
|
136329
136320
|
if (toolName) {
|
|
136330
136321
|
const piKnownTool = isPiKnownDroidTool(toolName);
|
|
136331
|
-
debugLog2(
|
|
136322
|
+
debugLog2(
|
|
136323
|
+
`top-level tool_use seen: ${toolName} (piKnown=${piKnownTool ? "yes" : "no"})`
|
|
136324
|
+
);
|
|
136332
136325
|
if (piKnownTool) {
|
|
136333
136326
|
sawBuiltInOrCustomTool = true;
|
|
136334
136327
|
}
|
|
@@ -136344,7 +136337,9 @@ function streamViaCli(model, context, options) {
|
|
|
136344
136337
|
return;
|
|
136345
136338
|
}
|
|
136346
136339
|
} else if (msg.type === "control_request") {
|
|
136347
|
-
debugLog2(
|
|
136340
|
+
debugLog2(
|
|
136341
|
+
`unexpected control_request received (stdin already closed): ${msg.request_id}`
|
|
136342
|
+
);
|
|
136348
136343
|
} else if (msg.type === "result") {
|
|
136349
136344
|
if (msg.subtype === "error") {
|
|
136350
136345
|
endStreamWithError2(msg.error ?? "Unknown error from Droid CLI");
|
|
@@ -136369,9 +136364,13 @@ function streamViaCli(model, context, options) {
|
|
|
136369
136364
|
const output = bridge.getOutput();
|
|
136370
136365
|
const contentEvents = output.content || [];
|
|
136371
136366
|
if (contentEvents.length === 0) {
|
|
136372
|
-
console.warn(
|
|
136367
|
+
console.warn(
|
|
136368
|
+
`[droid-cli] Droid CLI closed without content events (model=${model.id}, sessionId=${options?.sessionId ?? "none"})`
|
|
136369
|
+
);
|
|
136373
136370
|
}
|
|
136374
|
-
const piToolCalls = (output.content || []).filter(
|
|
136371
|
+
const piToolCalls = (output.content || []).filter(
|
|
136372
|
+
(c) => c.type === "toolCall"
|
|
136373
|
+
);
|
|
136375
136374
|
const effectiveReason = output.stopReason === "toolUse" && piToolCalls.length === 0 ? "stop" : output.stopReason;
|
|
136376
136375
|
streamEnded = true;
|
|
136377
136376
|
stream2.push({
|
|
@@ -136408,7 +136407,7 @@ function streamViaCli(model, context, options) {
|
|
|
136408
136407
|
return stream2;
|
|
136409
136408
|
}
|
|
136410
136409
|
|
|
136411
|
-
// ../../plugins/fusion-plugin-droid-runtime/
|
|
136410
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/runtime-adapter.ts
|
|
136412
136411
|
var DroidRuntimeAdapter = class {
|
|
136413
136412
|
id = "droid";
|
|
136414
136413
|
name = "Droid Runtime";
|
|
@@ -136459,7 +136458,7 @@ var DroidRuntimeAdapter = class {
|
|
|
136459
136458
|
}
|
|
136460
136459
|
};
|
|
136461
136460
|
|
|
136462
|
-
// ../../plugins/fusion-plugin-droid-runtime/
|
|
136461
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/probe.ts
|
|
136463
136462
|
import { spawn as spawn2 } from "node:child_process";
|
|
136464
136463
|
function resolveDroidBinaryPath(settings2) {
|
|
136465
136464
|
if (typeof settings2?.droidBinaryPath === "string" && settings2.droidBinaryPath.trim().length > 0) {
|
|
@@ -136516,7 +136515,7 @@ async function probeDroidBinary(options) {
|
|
|
136516
136515
|
};
|
|
136517
136516
|
}
|
|
136518
136517
|
|
|
136519
|
-
// ../../plugins/fusion-plugin-droid-runtime/
|
|
136518
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/mcp-config.ts
|
|
136520
136519
|
import { writeFileSync as writeFileSync2 } from "node:fs";
|
|
136521
136520
|
import { join as join3, dirname as dirname2 } from "node:path";
|
|
136522
136521
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
@@ -136541,8 +136540,7 @@ function getCustomToolDefs(pi) {
|
|
|
136541
136540
|
}));
|
|
136542
136541
|
}
|
|
136543
136542
|
function toolsFromContext(contextTools) {
|
|
136544
|
-
if (!Array.isArray(contextTools))
|
|
136545
|
-
return [];
|
|
136543
|
+
if (!Array.isArray(contextTools)) return [];
|
|
136546
136544
|
return contextTools.filter((tool) => !BUILT_IN_TOOL_NAMES.has(tool.name)).map((tool) => ({
|
|
136547
136545
|
name: tool.name,
|
|
136548
136546
|
description: tool.description,
|
|
@@ -136551,7 +136549,10 @@ function toolsFromContext(contextTools) {
|
|
|
136551
136549
|
}
|
|
136552
136550
|
function writeMcpConfig(toolDefs, cacheKey) {
|
|
136553
136551
|
const suffix = cacheKey ? `${process.pid}-${cacheKey}` : `${process.pid}`;
|
|
136554
|
-
const schemaFilePath = join3(
|
|
136552
|
+
const schemaFilePath = join3(
|
|
136553
|
+
tmpdir2(),
|
|
136554
|
+
`droid-cli-mcp-schemas-${suffix}.json`
|
|
136555
|
+
);
|
|
136555
136556
|
writeFileSync2(schemaFilePath, JSON.stringify(toolDefs));
|
|
136556
136557
|
const __filename = fileURLToPath(import.meta.url);
|
|
136557
136558
|
const __dirname = dirname2(__filename);
|
|
@@ -136564,12 +136565,15 @@ function writeMcpConfig(toolDefs, cacheKey) {
|
|
|
136564
136565
|
}
|
|
136565
136566
|
}
|
|
136566
136567
|
};
|
|
136567
|
-
const configFilePath = join3(
|
|
136568
|
+
const configFilePath = join3(
|
|
136569
|
+
tmpdir2(),
|
|
136570
|
+
`droid-cli-mcp-config-${suffix}.json`
|
|
136571
|
+
);
|
|
136568
136572
|
writeFileSync2(configFilePath, JSON.stringify(config2));
|
|
136569
136573
|
return configFilePath;
|
|
136570
136574
|
}
|
|
136571
136575
|
|
|
136572
|
-
// ../../plugins/fusion-plugin-droid-runtime/
|
|
136576
|
+
// ../../plugins/fusion-plugin-droid-runtime/src/index.ts
|
|
136573
136577
|
var DROID_RUNTIME_ID = "droid";
|
|
136574
136578
|
var DROID_RUNTIME_VERSION = "0.1.0";
|
|
136575
136579
|
var droidRuntimeMetadata = {
|