nextclaw 0.18.2 → 0.18.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/app/index.js +409 -123
- package/package.json +15 -15
- package/ui-dist/assets/api-DnPN4SyA.js +15 -0
- package/ui-dist/assets/app-manager-provider-M7TngYxx.js +1 -0
- package/ui-dist/assets/app-navigation.config-B5YIdRju.js +1 -0
- package/ui-dist/assets/{book-open-BE8M56IM.js → book-open-B4mOKdz8.js} +1 -1
- package/ui-dist/assets/channels-list-page-Cm-Bbu6u.js +8 -0
- package/ui-dist/assets/chat-C0ZNZtS3.js +58 -0
- package/ui-dist/assets/chat-page-CGHNhXaw.js +1 -0
- package/ui-dist/assets/chunk-JZWAC4HX-BJer-fqD.js +3 -0
- package/ui-dist/assets/config-split-page-B3PRA_AV.js +1 -0
- package/ui-dist/assets/{createLucideIcon-CCiTGX8L.js → createLucideIcon-C_GFKVuW.js} +1 -1
- package/ui-dist/assets/desktop-update-config-Dfh-3uma.js +1 -0
- package/ui-dist/assets/{dialog-BghZFPch.js → dialog-D-I7ONHQ.js} +1 -1
- package/ui-dist/assets/{dist-Dd9cr-kz.js → dist-DreLBS93.js} +1 -1
- package/ui-dist/assets/doc-browser-CoKIUCJj.js +1 -0
- package/ui-dist/assets/doc-browser-CwgI7ipB.js +1 -0
- package/ui-dist/assets/doc-browser-DYKpRqe-.js +1 -0
- package/ui-dist/assets/doc-browser-context-Dib9sS83.js +1 -0
- package/ui-dist/assets/{es2015-CEAreese.js → es2015-DMSUl3fm.js} +1 -1
- package/ui-dist/assets/{external-link-qsnCMhw1.js → external-link-DP2IJ7AM.js} +1 -1
- package/ui-dist/assets/folder-BPwc278w.js +1 -0
- package/ui-dist/assets/{hash-0zjWsNl-.js → hash-CvcvtMBq.js} +1 -1
- package/ui-dist/assets/i18n-BnNAQpVM.js +1 -0
- package/ui-dist/assets/index-Bc6c1kIx.js +2 -0
- package/ui-dist/assets/index-mRmSAB-e.css +1 -0
- package/ui-dist/assets/{key-round-BLe9D8ND.js → key-round-BQXmPSxD.js} +1 -1
- package/ui-dist/assets/loader-circle-C6gg2m2a.js +1 -0
- package/ui-dist/assets/{LogoBadge-DP8Ye7wJ.js → logo-badge-uB4SwANR.js} +1 -1
- package/ui-dist/assets/{logos-_v5b2SdG.js → logos-BcELLmYh.js} +1 -1
- package/ui-dist/assets/marketplace-page-BCrS-jH6.js +49 -0
- package/ui-dist/assets/marketplace-page-DVrlpB68.js +1 -0
- package/ui-dist/assets/mcp-marketplace-page-CjrxT6wI.js +40 -0
- package/ui-dist/assets/mcp-marketplace-page-pQ_A38fH.js +1 -0
- package/ui-dist/assets/message-square-CLVODA23.js +1 -0
- package/ui-dist/assets/model-config-D4myteLK.js +1 -0
- package/ui-dist/assets/notice-card-DX_NEZTQ.js +1 -0
- package/ui-dist/assets/play-DeNVUA5C.js +1 -0
- package/ui-dist/assets/plus-BptLViq1.js +1 -0
- package/ui-dist/assets/popover-Dm_NQ3Cs.js +1 -0
- package/ui-dist/assets/provider-scoped-model-input-BLHImwI5.js +1 -0
- package/ui-dist/assets/providers-list-DsBFslNi.js +1 -0
- package/ui-dist/assets/refresh-ccw-CeG203yU.js +1 -0
- package/ui-dist/assets/remote-CQQykOYe.js +1 -0
- package/ui-dist/assets/rotate-cw-F7aThvYj.js +1 -0
- package/ui-dist/assets/runtime-config-page-Bz9r68Rf.js +1 -0
- package/ui-dist/assets/{save-D4bObrmH.js → save-7ztImRj7.js} +1 -1
- package/ui-dist/assets/search-DZSNKEGp.js +1 -0
- package/ui-dist/assets/search-config-C-6KpgRQ.js +1 -0
- package/ui-dist/assets/secrets-config-MiMElvpm.js +3 -0
- package/ui-dist/assets/{select-BILPf7zs.js → select-RgeHgn_-.js} +1 -1
- package/ui-dist/assets/sessions-config-page-0KNW9QC_.js +2 -0
- package/ui-dist/assets/{setting-row-BATDgg4r.js → setting-row-vwm4XKv2.js} +1 -1
- package/ui-dist/assets/settings-DjvNMJde.js +1 -0
- package/ui-dist/assets/skeleton-5Mg6vZHN.js +1 -0
- package/ui-dist/assets/sparkles-CyDTgTM4.js +1 -0
- package/ui-dist/assets/status-dot-aQU9Mia4.js +1 -0
- package/ui-dist/assets/{tabs-custom-Bx3cNhD-.js → tabs-custom-C4P7g4vR.js} +1 -1
- package/ui-dist/assets/{tag-chip-zUaDE2-H.js → tag-chip-DGqz3TON.js} +1 -1
- package/ui-dist/assets/theme-provider-CUppbOyN.js +1 -0
- package/ui-dist/assets/tooltip-DQlSKhZ_.js +1 -0
- package/ui-dist/assets/{trash-2-CQUgYyRn.js → trash-2-C1cdqL6V.js} +1 -1
- package/ui-dist/assets/use-config-CrsavfWZ.js +1 -0
- package/ui-dist/assets/{useConfirmDialog-patAnl1g.js → use-confirm-dialog-D1AnLFlc.js} +1 -1
- package/ui-dist/assets/use-infinite-scroll-loader-DZhv-rmv.js +1 -0
- package/ui-dist/assets/use-viewport-layout-CytJAPWM.js +1 -0
- package/ui-dist/assets/x-BjMO7v8q.js +1 -0
- package/ui-dist/index.html +39 -22
- package/ui-dist/assets/ChannelsList-SQ7Oxotv.js +0 -8
- package/ui-dist/assets/DocBrowser-BCO2k6XD.js +0 -1
- package/ui-dist/assets/DocBrowser-rDOjI3ga.js +0 -1
- package/ui-dist/assets/DocBrowserContext-BUq3Wo8O.js +0 -1
- package/ui-dist/assets/ModelConfig-C77Ae9ru.js +0 -1
- package/ui-dist/assets/ProviderScopedModelInput-CEnK61uo.js +0 -1
- package/ui-dist/assets/ProvidersList-BCupBayq.js +0 -1
- package/ui-dist/assets/RuntimeConfig-Ad-CAcmy.js +0 -1
- package/ui-dist/assets/SearchConfig-BfCz4wJ4.js +0 -1
- package/ui-dist/assets/SecretsConfig-DjmBIhyy.js +0 -3
- package/ui-dist/assets/SessionsConfig-CvjxU40H.js +0 -2
- package/ui-dist/assets/chat-page-JKC6ln-y.js +0 -58
- package/ui-dist/assets/chat-session-display-YcRMrAMa.js +0 -1
- package/ui-dist/assets/chunk-JZWAC4HX-erTUn3b8.js +0 -3
- package/ui-dist/assets/client-CszWMVKi.js +0 -7
- package/ui-dist/assets/config-split-page-BAGSzUR3.js +0 -1
- package/ui-dist/assets/desktop-DfkLlkG2.js +0 -1
- package/ui-dist/assets/desktop-update-config-BXeGlqHD.js +0 -1
- package/ui-dist/assets/dist-ZwoAXs46.js +0 -9
- package/ui-dist/assets/download-D7LOizcW.js +0 -1
- package/ui-dist/assets/i18n-DvzXOGQX.js +0 -1
- package/ui-dist/assets/index-DvVTC9FF.css +0 -1
- package/ui-dist/assets/index-lr6rQUSd.js +0 -2
- package/ui-dist/assets/loader-circle-wj7kARHv.js +0 -1
- package/ui-dist/assets/marketplace-page-CAAk1Khc.js +0 -1
- package/ui-dist/assets/marketplace-page-CfCiq90S.js +0 -49
- package/ui-dist/assets/mcp-marketplace-page-D0Pp9Hs-.js +0 -40
- package/ui-dist/assets/play-o6NmwGTi.js +0 -1
- package/ui-dist/assets/plus-I9pBS4Fl.js +0 -1
- package/ui-dist/assets/refresh-cw-MNqgR3LZ.js +0 -1
- package/ui-dist/assets/remote-C9fXm4V5.js +0 -1
- package/ui-dist/assets/search-DxmL3IWE.js +0 -1
- package/ui-dist/assets/security-config-BUm6FFfl.js +0 -1
- package/ui-dist/assets/skeleton-COKMAnJy.js +0 -1
- package/ui-dist/assets/switch-CBOzecWS.js +0 -1
- package/ui-dist/assets/use-infinite-scroll-loader-B5V2Klve.js +0 -1
- package/ui-dist/assets/useMutation-__AYv-Pz.js +0 -1
- package/ui-dist/assets/x-BHUGQIUv.js +0 -1
- /package/ui-dist/assets/{config-hints-DSQQbeOA.js → config-hints-CPNzbMEp.js} +0 -0
package/dist/cli/app/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import * as NextclawCore from "@nextclaw/core";
|
|
4
|
-
import { APP_NAME, APP_TAGLINE, AgentRouteResolver, BUILTIN_MAIN_AGENT_ID, ChannelManager, CommandRegistry, ConfigSchema, ContextBuilder, CronService, CronTool, DEFAULT_WORKSPACE_DIR, DEFAULT_WORKSPACE_PATH, DisposableStore, EditFileTool, ExecTool, ExtensionToolAdapter, FileLogSink, GatewayTool, InputBudgetPruner, LLMProvider, ListDirTool, MemoryGetTool, MemorySearchTool, MessageBus, MessageTool, ProviderManager, ReadFileTool, RequestedSkillsMetadataReader, SessionManager, SessionsHistoryTool, SessionsListTool, SkillsLoader, Tool, ToolRegistry, WebFetchTool, WebSearchTool, WriteFileTool, buildConfigSchema, buildMinimalSystemExecutionPrompt, buildReloadPlan, buildToolCatalogEntries, createAgentProfile, createAssistantStreamDeltaControlMessage, createAssistantStreamResetControlMessage, createExternalCommandEnv, createGlobalTypedEventBus, createTypedEventKey, createTypingStopControlMessage, diffConfigPaths, expandHome, findEffectiveAgentProfile,
|
|
4
|
+
import { APP_NAME, APP_TAGLINE, AgentRouteResolver, BUILTIN_MAIN_AGENT_ID, ChannelManager, CommandRegistry, ConfigSchema, ContextBuilder, CronService, CronTool, DEFAULT_WORKSPACE_DIR, DEFAULT_WORKSPACE_PATH, DisposableStore, EditFileTool, ExecTool, ExtensionToolAdapter, FileLogSink, GatewayTool, InputBudgetPruner, LLMProvider, ListDirTool, MemoryGetTool, MemorySearchTool, MessageBus, MessageTool, ProviderManager, ReadFileTool, RequestedSkillsMetadataReader, SessionManager, SessionsHistoryTool, SessionsListTool, SkillsLoader, Tool, ToolRegistry, WebFetchTool, WebSearchTool, WriteFileTool, buildConfigSchema, buildMinimalSystemExecutionPrompt, buildReloadPlan, buildToolCatalogEntries, createAgentProfile, createAssistantStreamDeltaControlMessage, createAssistantStreamResetControlMessage, createExternalCommandEnv, createGlobalTypedEventBus, createTypedEventKey, createTypingStopControlMessage, diffConfigPaths, expandHome, findEffectiveAgentProfile, getConfigPath, getDataDir, getDataPath, getLoggingRuntime, getLogsPath, getPackageVersion, getWorkspacePath, hasSecretRef, loadConfig, normalizeInlineSecretRefs, parseAgentScopedSessionKey, parseThinkingLevel, readSessionProjectRoot, redactConfigObject, removeAgentProfile, resolveAppLogPath, resolveConfigSecrets, resolveDefaultAgentProfileId, resolveEffectiveAgentProfiles, resolveLocalUiBaseUrl, resolveProviderRuntime, resolveSessionWorkspacePath, resolveThinkingLevel, saveConfig, toDisposable, updateAgentProfile } from "@nextclaw/core";
|
|
5
5
|
import { Command } from "commander";
|
|
6
6
|
import fs, { appendFileSync, closeSync, constants, cpSync, existsSync, mkdirSync, openSync, readFileSync, readdirSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
7
7
|
import path, { basename, delimiter, dirname, extname, isAbsolute, join, relative, resolve, win32 } from "node:path";
|
|
8
8
|
import { homedir, hostname, platform } from "node:os";
|
|
9
9
|
import { ensureUiBridgeSecret, startUiServer } from "@nextclaw/server";
|
|
10
|
-
import { addPluginLoadPath, buildPluginStatusReport, disablePluginInConfig, discoverPluginStatusReport, enablePluginInConfig, getPackageManifestExtensions, getPluginChannelBindings, getPluginUiMetadataFromRegistry, installPluginFromNpmSpec, installPluginFromPath, loadOpenClawPlugins,
|
|
10
|
+
import { addPluginLoadPath, buildPluginStatusReport, disablePluginInConfig, discoverPluginStatusReport, enablePluginInConfig, getPackageManifestExtensions, getPluginChannelBindings, getPluginUiMetadataFromRegistry, installPluginFromNpmSpec, installPluginFromPath, loadOpenClawPlugins, loadPluginManifest, mergePluginConfigView, recordPluginInstall, resolvePluginChannelMessageToolHints, resolveUninstallDirectoryTargets, setPluginRuntimeBridge, stopPluginChannelGateways, toPluginConfigView, toPluginConfigView as toPluginConfigView$1, uninstallPlugin } from "@nextclaw/openclaw-compat";
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
12
|
+
import { fork, spawn, spawnSync } from "node:child_process";
|
|
13
13
|
import { createServer, isIP } from "node:net";
|
|
14
14
|
import { BUILTIN_CHANNEL_PLUGIN_IDS, builtinProviderIds, listBuiltinProviders } from "@nextclaw/runtime";
|
|
15
15
|
import { createInterface } from "node:readline";
|
|
@@ -5220,11 +5220,31 @@ async function waitForExit(pid, timeoutMs) {
|
|
|
5220
5220
|
}
|
|
5221
5221
|
return !isProcessRunning(pid);
|
|
5222
5222
|
}
|
|
5223
|
-
function
|
|
5223
|
+
function findNearestPackageManifest(startDir, expectedName) {
|
|
5224
|
+
let current = resolve(startDir);
|
|
5225
|
+
while (current.length > 0) {
|
|
5226
|
+
const pkgPath = join(current, "package.json");
|
|
5227
|
+
if (existsSync(pkgPath)) try {
|
|
5228
|
+
const raw = readFileSync(pkgPath, "utf-8");
|
|
5229
|
+
const parsed = JSON.parse(raw);
|
|
5230
|
+
if (!expectedName || parsed.name === expectedName) return {
|
|
5231
|
+
rootDir: current,
|
|
5232
|
+
version: typeof parsed.version === "string" ? parsed.version : void 0
|
|
5233
|
+
};
|
|
5234
|
+
} catch {}
|
|
5235
|
+
const parent = resolve(current, "..");
|
|
5236
|
+
if (parent === current) break;
|
|
5237
|
+
current = parent;
|
|
5238
|
+
}
|
|
5239
|
+
return null;
|
|
5240
|
+
}
|
|
5241
|
+
function resolveUiStaticDir(importMetaUrl = import.meta.url) {
|
|
5224
5242
|
if (process.env.NEXTCLAW_DISABLE_STATIC_UI === "1") return null;
|
|
5225
5243
|
const envDir = process.env.NEXTCLAW_UI_STATIC_DIR;
|
|
5226
5244
|
if (envDir) return existsSync(join(envDir, "index.html")) ? envDir : null;
|
|
5227
|
-
const
|
|
5245
|
+
const pkgRoot = findNearestPackageManifest(resolve(fileURLToPath(new URL(".", importMetaUrl))), "nextclaw")?.rootDir;
|
|
5246
|
+
if (!pkgRoot) return null;
|
|
5247
|
+
const bundledDir = join(pkgRoot, "ui-dist");
|
|
5228
5248
|
return existsSync(join(bundledDir, "index.html")) ? bundledDir : null;
|
|
5229
5249
|
}
|
|
5230
5250
|
function openBrowser(url) {
|
|
@@ -5246,7 +5266,7 @@ function openBrowser(url) {
|
|
|
5246
5266
|
command = "xdg-open";
|
|
5247
5267
|
args = [url];
|
|
5248
5268
|
}
|
|
5249
|
-
if (!
|
|
5269
|
+
if (!findExecutableOnPath(command)) return false;
|
|
5250
5270
|
try {
|
|
5251
5271
|
spawn(command, args, {
|
|
5252
5272
|
stdio: "ignore",
|
|
@@ -5260,7 +5280,7 @@ function openBrowser(url) {
|
|
|
5260
5280
|
}
|
|
5261
5281
|
function normalizePathEntries(rawPath, platform) {
|
|
5262
5282
|
const delimiter = platform === "win32" ? ";" : ":";
|
|
5263
|
-
return rawPath.split(delimiter).map((entry) => entry.trim().replace(/^"+|"+$/g, "")).filter(
|
|
5283
|
+
return rawPath.split(delimiter).map((entry) => entry.trim().replace(/^"+|"+$/g, "")).filter(Boolean);
|
|
5264
5284
|
}
|
|
5265
5285
|
function normalizeWindowsPathExt(rawPathExt) {
|
|
5266
5286
|
const source = rawPathExt && rawPathExt.trim().length > 0 ? rawPathExt : ".COM;.EXE;.BAT;.CMD";
|
|
@@ -5274,8 +5294,7 @@ function normalizeWindowsPathExt(rawPathExt) {
|
|
|
5274
5294
|
return [...unique];
|
|
5275
5295
|
}
|
|
5276
5296
|
function hasFileExtension(binary) {
|
|
5277
|
-
|
|
5278
|
-
return binary.lastIndexOf(".") > lastSlash;
|
|
5297
|
+
return binary.lastIndexOf(".") > Math.max(binary.lastIndexOf("/"), binary.lastIndexOf("\\"));
|
|
5279
5298
|
}
|
|
5280
5299
|
function findExecutableOnPath(binary, env = process.env, platform = process.platform) {
|
|
5281
5300
|
const target = binary.trim();
|
|
@@ -5285,41 +5304,20 @@ function findExecutableOnPath(binary, env = process.env, platform = process.plat
|
|
|
5285
5304
|
if (!rawPath.trim()) return null;
|
|
5286
5305
|
const entries = normalizePathEntries(rawPath, platform);
|
|
5287
5306
|
if (entries.length === 0) return null;
|
|
5288
|
-
const checkCandidates = (candidate) => existsSync(candidate) ? candidate : null;
|
|
5289
5307
|
for (const dir of entries) {
|
|
5290
|
-
const direct =
|
|
5291
|
-
if (direct) return direct;
|
|
5308
|
+
const direct = join(dir, target);
|
|
5309
|
+
if (existsSync(direct)) return direct;
|
|
5292
5310
|
if (platform !== "win32" || hasFileExtension(target)) continue;
|
|
5293
5311
|
for (const ext of normalizeWindowsPathExt(env.PATHEXT)) {
|
|
5294
|
-
const withExt =
|
|
5295
|
-
if (withExt) return withExt;
|
|
5312
|
+
const withExt = join(dir, `${target}${ext}`);
|
|
5313
|
+
if (existsSync(withExt)) return withExt;
|
|
5296
5314
|
}
|
|
5297
5315
|
}
|
|
5298
5316
|
return null;
|
|
5299
5317
|
}
|
|
5300
|
-
function which(binary) {
|
|
5301
|
-
return findExecutableOnPath(binary) !== null;
|
|
5302
|
-
}
|
|
5303
|
-
function resolveVersionFromPackageTree(startDir, expectedName) {
|
|
5304
|
-
let current = resolve(startDir);
|
|
5305
|
-
while (current.length > 0) {
|
|
5306
|
-
const pkgPath = join(current, "package.json");
|
|
5307
|
-
if (existsSync(pkgPath)) try {
|
|
5308
|
-
const raw = readFileSync(pkgPath, "utf-8");
|
|
5309
|
-
const parsed = JSON.parse(raw);
|
|
5310
|
-
const version = typeof parsed.version === "string" ? parsed.version : null;
|
|
5311
|
-
const matchesExpectedName = !expectedName || parsed.name === expectedName;
|
|
5312
|
-
if (version && matchesExpectedName) return version;
|
|
5313
|
-
} catch {}
|
|
5314
|
-
const parent = resolve(current, "..");
|
|
5315
|
-
if (parent === current) break;
|
|
5316
|
-
current = parent;
|
|
5317
|
-
}
|
|
5318
|
-
return null;
|
|
5319
|
-
}
|
|
5320
5318
|
function getPackageVersion$1() {
|
|
5321
5319
|
const cliDir = resolve(fileURLToPath(new URL(".", import.meta.url)));
|
|
5322
|
-
return
|
|
5320
|
+
return findNearestPackageManifest(cliDir, "nextclaw")?.version ?? findNearestPackageManifest(cliDir)?.version ?? getPackageVersion();
|
|
5323
5321
|
}
|
|
5324
5322
|
function printAgentResponse(response) {
|
|
5325
5323
|
console.log("\n" + response + "\n");
|
|
@@ -6026,23 +6024,9 @@ function toExtensionRegistry(pluginRegistry) {
|
|
|
6026
6024
|
}
|
|
6027
6025
|
//#endregion
|
|
6028
6026
|
//#region src/cli/commands/plugin/plugin-registry-loader.ts
|
|
6029
|
-
function createPluginLogger() {
|
|
6030
|
-
return getAppLogger("plugin.registry_loader");
|
|
6031
|
-
}
|
|
6032
6027
|
function withDevFirstPartyPluginPaths(config) {
|
|
6033
6028
|
return resolveDevPluginLoadingContext(config, resolveDevFirstPartyPluginDir(process.env.NEXTCLAW_DEV_FIRST_PARTY_PLUGIN_DIR));
|
|
6034
6029
|
}
|
|
6035
|
-
async function loadPluginRegistryProgressively(config, workspaceDir, options = {}) {
|
|
6036
|
-
const { configWithDevPluginOverrides, excludedRoots } = withDevFirstPartyPluginPaths(config);
|
|
6037
|
-
return await loadOpenClawPluginsProgressively({
|
|
6038
|
-
config: configWithDevPluginOverrides,
|
|
6039
|
-
workspaceDir,
|
|
6040
|
-
excludeRoots: excludedRoots,
|
|
6041
|
-
...buildReservedPluginLoadOptions(),
|
|
6042
|
-
onPluginProcessed: options.onPluginProcessed,
|
|
6043
|
-
logger: createPluginLogger()
|
|
6044
|
-
});
|
|
6045
|
-
}
|
|
6046
6030
|
function discoverPluginRegistryStatus(config, workspaceDir) {
|
|
6047
6031
|
const { configWithDevPluginOverrides } = withDevFirstPartyPluginPaths(config);
|
|
6048
6032
|
return discoverPluginStatusReport({
|
|
@@ -8554,6 +8538,7 @@ function buildLegacyAssistantMessages(message, timestamp) {
|
|
|
8554
8538
|
name: toolInvocation.toolName,
|
|
8555
8539
|
tool_call_id: toolInvocation.toolCallId,
|
|
8556
8540
|
content: typeof toolInvocation.result === "string" ? toolInvocation.result : JSON.stringify(toolInvocation.result ?? null),
|
|
8541
|
+
...toolInvocation.resultContentItems ? { ncp_tool_result_content_items: structuredClone(toolInvocation.resultContentItems) } : {},
|
|
8557
8542
|
timestamp,
|
|
8558
8543
|
ncp_message_id: message.id
|
|
8559
8544
|
});
|
|
@@ -9432,8 +9417,9 @@ function buildGenericMessage(params) {
|
|
|
9432
9417
|
parts: contentToParts(params.message.content)
|
|
9433
9418
|
};
|
|
9434
9419
|
}
|
|
9435
|
-
function attachToolResult(target, toolCallId, result, toolName) {
|
|
9420
|
+
function attachToolResult(target, toolCallId, result, toolName, resultContentItems) {
|
|
9436
9421
|
const normalizedResult = normalizeToolResultPayload(result);
|
|
9422
|
+
const normalizedContentItems = Array.isArray(resultContentItems) ? structuredClone(resultContentItems) : void 0;
|
|
9437
9423
|
target.parts = target.parts.map((part) => {
|
|
9438
9424
|
if (part.type !== "tool-invocation" || part.toolCallId !== toolCallId) return part;
|
|
9439
9425
|
if (part.state === "result" && Object.prototype.hasOwnProperty.call(part, "result")) return {
|
|
@@ -9444,7 +9430,8 @@ function attachToolResult(target, toolCallId, result, toolName) {
|
|
|
9444
9430
|
...part,
|
|
9445
9431
|
toolName: toolName ?? part.toolName,
|
|
9446
9432
|
state: "result",
|
|
9447
|
-
result: normalizedResult
|
|
9433
|
+
result: normalizedResult,
|
|
9434
|
+
...normalizedContentItems ? { resultContentItems: normalizedContentItems } : {}
|
|
9448
9435
|
};
|
|
9449
9436
|
});
|
|
9450
9437
|
}
|
|
@@ -9458,7 +9445,7 @@ function toNcpMessages(sessionId, messages) {
|
|
|
9458
9445
|
if (toolCallId) {
|
|
9459
9446
|
const assistantIndex = assistantIndexByToolCallId.get(toolCallId);
|
|
9460
9447
|
if (assistantIndex !== void 0) {
|
|
9461
|
-
attachToolResult(ncpMessages[assistantIndex], toolCallId, structuredClone(message.content), normalizeString(message.name) ?? void 0);
|
|
9448
|
+
attachToolResult(ncpMessages[assistantIndex], toolCallId, structuredClone(message.content), normalizeString(message.name) ?? void 0, message.ncp_tool_result_content_items);
|
|
9462
9449
|
return;
|
|
9463
9450
|
}
|
|
9464
9451
|
}
|
|
@@ -13973,19 +13960,6 @@ var ManagedServiceCommandService = class {
|
|
|
13973
13960
|
};
|
|
13974
13961
|
//#endregion
|
|
13975
13962
|
//#region src/cli/shared/services/gateway/service-startup-support.ts
|
|
13976
|
-
const pluginGatewayLogger = {
|
|
13977
|
-
info: (message) => console.log(`[plugins] ${message}`),
|
|
13978
|
-
warn: (message) => console.warn(`[plugins] ${message}`),
|
|
13979
|
-
error: (message) => console.error(`[plugins] ${message}`),
|
|
13980
|
-
debug: (message) => console.debug(`[plugins] ${message}`)
|
|
13981
|
-
};
|
|
13982
|
-
function logPluginGatewayDiagnostics(diagnostics) {
|
|
13983
|
-
for (const diag of diagnostics) {
|
|
13984
|
-
const text = `${diag.pluginId ? `${diag.pluginId}: ` : ""}${diag.message}`;
|
|
13985
|
-
if (diag.level === "error") console.error(`[plugins] ${text}`);
|
|
13986
|
-
else console.warn(`[plugins] ${text}`);
|
|
13987
|
-
}
|
|
13988
|
-
}
|
|
13989
13963
|
async function startGatewaySupportServices(params) {
|
|
13990
13964
|
if (params.cronJobs > 0) console.log(`✓ Cron: ${params.cronJobs} scheduled jobs`);
|
|
13991
13965
|
console.log("✓ Heartbeat: every 30m");
|
|
@@ -15396,14 +15370,10 @@ var NextclawApp = class {
|
|
|
15396
15370
|
await measureStartupAsync("service.deferred_startup.recover_durable_state", async () => await this.ncpAgentRuntime.recoverDurableState());
|
|
15397
15371
|
};
|
|
15398
15372
|
warmDerivedCapabilities = async () => {
|
|
15399
|
-
const runtimeWarmupTask = this.kernelReady ? measureStartupAsync("service.deferred_startup.warm_ncp_capabilities", async () => await this.ncpAgentRuntime.warmDerivedCapabilities()).catch((error) => {
|
|
15400
|
-
console.warn(`UI NCP derived capability warmup failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
15401
|
-
}) : Promise.resolve();
|
|
15402
15373
|
if (this.params.hydrateCapabilities) await measureStartupAsync("service.deferred_startup.hydrate_capabilities", this.params.hydrateCapabilities);
|
|
15403
15374
|
await measureStartupAsync("service.deferred_startup.start_plugin_gateways", this.params.startPluginGateways);
|
|
15404
15375
|
await measureStartupAsync("service.deferred_startup.start_channels", this.params.startChannels);
|
|
15405
15376
|
await measureStartupAsync("service.deferred_startup.wake_restart_sentinel", this.params.wakeFromRestartSentinel);
|
|
15406
|
-
await runtimeWarmupTask;
|
|
15407
15377
|
};
|
|
15408
15378
|
handleKernelStartupError(error) {
|
|
15409
15379
|
this.params.bootstrapStatus.markNcpAgentError(error instanceof Error ? error.message : String(error));
|
|
@@ -15905,58 +15875,57 @@ function countEnabledPlugins(config, workspaceDir) {
|
|
|
15905
15875
|
return discoverPluginRegistryStatus(config, workspaceDir).plugins.filter((plugin) => plugin.enabled).length;
|
|
15906
15876
|
}
|
|
15907
15877
|
async function hydrateServiceCapabilities(params) {
|
|
15908
|
-
|
|
15909
|
-
|
|
15878
|
+
const { bootstrapStatus, extensionHost, gateway, getLiveUiNcpAgent, state, uiStartup } = params;
|
|
15879
|
+
await waitForUiShellGraceWindow(uiStartup);
|
|
15880
|
+
const nextConfig = resolveConfigSecrets(loadConfig(), { configPath: gateway.runtimeConfigPath });
|
|
15910
15881
|
const nextWorkspace = getWorkspacePath(nextConfig.agents.defaults.workspace);
|
|
15911
15882
|
const totalPluginCount = countEnabledPlugins(nextConfig, nextWorkspace);
|
|
15912
15883
|
let loadedPluginCount = 0;
|
|
15913
|
-
|
|
15914
|
-
|
|
15884
|
+
bootstrapStatus.markPluginHydrationRunning({ totalPluginCount });
|
|
15885
|
+
bootstrapStatus.markChannelsPending();
|
|
15915
15886
|
try {
|
|
15916
|
-
const nextPluginRegistry = await
|
|
15917
|
-
|
|
15918
|
-
|
|
15919
|
-
|
|
15920
|
-
|
|
15921
|
-
});
|
|
15922
|
-
} });
|
|
15887
|
+
const nextPluginRegistry = extensionHost.createProxyPluginRegistry(await extensionHost.load({
|
|
15888
|
+
config: nextConfig,
|
|
15889
|
+
workspaceDir: nextWorkspace
|
|
15890
|
+
}));
|
|
15891
|
+
loadedPluginCount = loadedPluginCount || nextPluginRegistry.plugins.filter((plugin) => plugin.status === "loaded").length;
|
|
15923
15892
|
logPluginDiagnostics(nextPluginRegistry);
|
|
15924
15893
|
const nextExtensionRegistry = toExtensionRegistry(nextPluginRegistry);
|
|
15925
15894
|
const nextPluginChannelBindings = getPluginChannelBindings(nextPluginRegistry);
|
|
15926
15895
|
const nextPluginUiMetadata = getPluginUiMetadataFromRegistry(nextPluginRegistry);
|
|
15927
15896
|
const shouldRebuildChannels = shouldRestartChannelsForPluginReload({
|
|
15928
15897
|
changedPaths: [],
|
|
15929
|
-
currentPluginChannelBindings:
|
|
15898
|
+
currentPluginChannelBindings: state.pluginChannelBindings,
|
|
15930
15899
|
nextPluginChannelBindings,
|
|
15931
|
-
currentExtensionChannels:
|
|
15900
|
+
currentExtensionChannels: state.extensionRegistry.channels,
|
|
15932
15901
|
nextExtensionChannels: nextExtensionRegistry.channels
|
|
15933
15902
|
});
|
|
15934
|
-
applyGatewayCapabilityState(
|
|
15903
|
+
applyGatewayCapabilityState(gateway, {
|
|
15935
15904
|
pluginRegistry: nextPluginRegistry,
|
|
15936
15905
|
extensionRegistry: nextExtensionRegistry,
|
|
15937
15906
|
pluginChannelBindings: nextPluginChannelBindings
|
|
15938
15907
|
});
|
|
15939
|
-
|
|
15940
|
-
|
|
15941
|
-
|
|
15942
|
-
|
|
15943
|
-
|
|
15944
|
-
if (shouldRebuildChannels) await
|
|
15945
|
-
|
|
15908
|
+
state.pluginRegistry = nextPluginRegistry;
|
|
15909
|
+
state.extensionRegistry = nextExtensionRegistry;
|
|
15910
|
+
state.pluginChannelBindings = nextPluginChannelBindings;
|
|
15911
|
+
state.pluginUiMetadata = nextPluginUiMetadata;
|
|
15912
|
+
getLiveUiNcpAgent()?.applyExtensionRegistry?.(nextExtensionRegistry);
|
|
15913
|
+
if (shouldRebuildChannels) await gateway.reloader.rebuildChannels(nextConfig, { start: false });
|
|
15914
|
+
uiStartup?.publish({
|
|
15946
15915
|
type: "config.updated",
|
|
15947
15916
|
payload: { path: "channels" }
|
|
15948
15917
|
});
|
|
15949
|
-
|
|
15918
|
+
uiStartup?.publish({
|
|
15950
15919
|
type: "config.updated",
|
|
15951
15920
|
payload: { path: "plugins" }
|
|
15952
15921
|
});
|
|
15953
|
-
|
|
15922
|
+
bootstrapStatus.markPluginHydrationReady({
|
|
15954
15923
|
loadedPluginCount: loadedPluginCount || totalPluginCount,
|
|
15955
15924
|
totalPluginCount
|
|
15956
15925
|
});
|
|
15957
15926
|
} catch (error) {
|
|
15958
15927
|
const message = error instanceof Error ? error.message : String(error);
|
|
15959
|
-
|
|
15928
|
+
bootstrapStatus.markPluginHydrationError(message);
|
|
15960
15929
|
throw error;
|
|
15961
15930
|
}
|
|
15962
15931
|
}
|
|
@@ -16051,7 +16020,10 @@ function resolvePluginRuntimeAttachments(ctx) {
|
|
|
16051
16020
|
//#region src/cli/shared/services/plugin/service-plugin-reload.service.ts
|
|
16052
16021
|
async function reloadServicePlugins(params) {
|
|
16053
16022
|
const nextWorkspace = getWorkspacePath(params.nextConfig.agents.defaults.workspace);
|
|
16054
|
-
const nextPluginRegistry =
|
|
16023
|
+
const nextPluginRegistry = params.extensionHost.createProxyPluginRegistry(await params.extensionHost.load({
|
|
16024
|
+
config: params.nextConfig,
|
|
16025
|
+
workspaceDir: nextWorkspace
|
|
16026
|
+
}));
|
|
16055
16027
|
const nextExtensionRegistry = toExtensionRegistry(nextPluginRegistry);
|
|
16056
16028
|
const nextPluginChannelBindings = getPluginChannelBindings(nextPluginRegistry);
|
|
16057
16029
|
const shouldRestartChannels = shouldRestartChannelsForPluginReload({
|
|
@@ -16062,22 +16034,14 @@ async function reloadServicePlugins(params) {
|
|
|
16062
16034
|
nextExtensionChannels: nextExtensionRegistry.channels
|
|
16063
16035
|
});
|
|
16064
16036
|
logPluginDiagnostics(nextPluginRegistry);
|
|
16065
|
-
let pluginGatewayHandles = params.pluginGatewayHandles;
|
|
16066
16037
|
if (shouldRestartChannels) {
|
|
16067
|
-
await
|
|
16068
|
-
|
|
16069
|
-
registry: nextPluginRegistry,
|
|
16070
|
-
config: params.nextConfig,
|
|
16071
|
-
logger: params.pluginGatewayLogger
|
|
16072
|
-
});
|
|
16073
|
-
pluginGatewayHandles = startedPluginGateways.handles;
|
|
16074
|
-
params.logPluginGatewayDiagnostics(startedPluginGateways.diagnostics);
|
|
16038
|
+
await params.extensionHost.stopPluginGateways();
|
|
16039
|
+
await params.extensionHost.startPluginGateways(params.nextConfig);
|
|
16075
16040
|
}
|
|
16076
16041
|
return {
|
|
16077
16042
|
pluginRegistry: nextPluginRegistry,
|
|
16078
16043
|
extensionRegistry: nextExtensionRegistry,
|
|
16079
16044
|
pluginChannelBindings: nextPluginChannelBindings,
|
|
16080
|
-
pluginGatewayHandles,
|
|
16081
16045
|
restartChannels: shouldRestartChannels
|
|
16082
16046
|
};
|
|
16083
16047
|
}
|
|
@@ -16102,22 +16066,20 @@ function createGatewayRuntimeState(gateway) {
|
|
|
16102
16066
|
};
|
|
16103
16067
|
}
|
|
16104
16068
|
function applyGatewayRuntimeCapabilityState(params) {
|
|
16105
|
-
|
|
16106
|
-
|
|
16107
|
-
|
|
16108
|
-
|
|
16069
|
+
const { gateway, next, state } = params;
|
|
16070
|
+
applyGatewayCapabilityState(gateway, next);
|
|
16071
|
+
state.pluginRegistry = next.pluginRegistry;
|
|
16072
|
+
state.extensionRegistry = next.extensionRegistry;
|
|
16073
|
+
state.pluginChannelBindings = next.pluginChannelBindings;
|
|
16109
16074
|
}
|
|
16110
16075
|
function configureGatewayPluginRuntime(params) {
|
|
16111
16076
|
params.gateway.reloader.setReloadPlugins(async ({ config: nextConfig, changedPaths }) => {
|
|
16112
16077
|
const result = await reloadServicePlugins({
|
|
16113
16078
|
nextConfig,
|
|
16114
16079
|
changedPaths,
|
|
16115
|
-
pluginRegistry: params.state.pluginRegistry,
|
|
16116
16080
|
extensionRegistry: params.state.extensionRegistry,
|
|
16117
16081
|
pluginChannelBindings: params.state.pluginChannelBindings,
|
|
16118
|
-
|
|
16119
|
-
pluginGatewayLogger,
|
|
16120
|
-
logPluginGatewayDiagnostics
|
|
16082
|
+
extensionHost: params.extensionHost
|
|
16121
16083
|
});
|
|
16122
16084
|
applyGatewayRuntimeCapabilityState({
|
|
16123
16085
|
gateway: params.gateway,
|
|
@@ -16129,7 +16091,6 @@ function configureGatewayPluginRuntime(params) {
|
|
|
16129
16091
|
}
|
|
16130
16092
|
});
|
|
16131
16093
|
params.state.pluginUiMetadata = getPluginUiMetadataFromRegistry(result.pluginRegistry);
|
|
16132
|
-
params.state.pluginGatewayHandles = result.pluginGatewayHandles;
|
|
16133
16094
|
params.getLiveUiNcpAgent()?.applyExtensionRegistry?.(result.extensionRegistry);
|
|
16134
16095
|
if (result.restartChannels) console.log("Config reload: plugin channel gateways restarted.");
|
|
16135
16096
|
return { restartChannels: result.restartChannels };
|
|
@@ -16156,17 +16117,12 @@ function createDeferredGatewayStartupHooks(params) {
|
|
|
16156
16117
|
gateway: params.gateway,
|
|
16157
16118
|
state: params.state,
|
|
16158
16119
|
bootstrapStatus: params.bootstrapStatus,
|
|
16159
|
-
getLiveUiNcpAgent: params.getLiveUiNcpAgent
|
|
16120
|
+
getLiveUiNcpAgent: params.getLiveUiNcpAgent,
|
|
16121
|
+
extensionHost: params.extensionHost
|
|
16160
16122
|
});
|
|
16161
16123
|
},
|
|
16162
16124
|
startPluginGateways: async () => {
|
|
16163
|
-
|
|
16164
|
-
registry: params.state.pluginRegistry,
|
|
16165
|
-
config: resolveConfigSecrets$2(loadConfig$2(), { configPath: params.gateway.runtimeConfigPath }),
|
|
16166
|
-
logger: pluginGatewayLogger
|
|
16167
|
-
});
|
|
16168
|
-
params.state.pluginGatewayHandles = startedPluginGateways.handles;
|
|
16169
|
-
logPluginGatewayDiagnostics(startedPluginGateways.diagnostics);
|
|
16125
|
+
await params.extensionHost.startPluginGateways(resolveConfigSecrets$2(loadConfig$2(), { configPath: params.gateway.runtimeConfigPath }));
|
|
16170
16126
|
},
|
|
16171
16127
|
startChannels: async () => {
|
|
16172
16128
|
await params.gateway.reloader.getChannels().startAll();
|
|
@@ -16201,6 +16157,326 @@ async function cleanupGatewayRuntime(params) {
|
|
|
16201
16157
|
setPluginRuntimeBridge(null);
|
|
16202
16158
|
}
|
|
16203
16159
|
//#endregion
|
|
16160
|
+
//#region src/cli/shared/services/extension-host-proxy-registry.service.ts
|
|
16161
|
+
function normalizeSchema(schema) {
|
|
16162
|
+
if (!schema || typeof schema !== "object" || Array.isArray(schema)) return {
|
|
16163
|
+
type: "object",
|
|
16164
|
+
properties: {},
|
|
16165
|
+
additionalProperties: true
|
|
16166
|
+
};
|
|
16167
|
+
return schema;
|
|
16168
|
+
}
|
|
16169
|
+
function stringifyToolResult(value) {
|
|
16170
|
+
if (typeof value === "string") return value;
|
|
16171
|
+
if (value === void 0 || value === null) return "";
|
|
16172
|
+
try {
|
|
16173
|
+
return JSON.stringify(value, null, 2);
|
|
16174
|
+
} catch {
|
|
16175
|
+
return String(value);
|
|
16176
|
+
}
|
|
16177
|
+
}
|
|
16178
|
+
function pickPreview(params) {
|
|
16179
|
+
const { alias, descriptor } = params;
|
|
16180
|
+
const byName = descriptor.previews.find((preview) => preview.name === alias);
|
|
16181
|
+
if (byName) return byName;
|
|
16182
|
+
if (descriptor.previews.length === 1) return descriptor.previews[0] ?? null;
|
|
16183
|
+
if (descriptor.previews.length === descriptor.names.length) {
|
|
16184
|
+
const index = descriptor.names.indexOf(alias);
|
|
16185
|
+
if (index >= 0 && index < descriptor.previews.length) return descriptor.previews[index] ?? null;
|
|
16186
|
+
}
|
|
16187
|
+
return null;
|
|
16188
|
+
}
|
|
16189
|
+
var ExtensionHostProxyRuntime = class {
|
|
16190
|
+
constructor(params) {
|
|
16191
|
+
this.params = params;
|
|
16192
|
+
}
|
|
16193
|
+
run = (input, options) => this.params.client.runRuntimeStream({
|
|
16194
|
+
kind: this.params.kind,
|
|
16195
|
+
entry: this.params.entry,
|
|
16196
|
+
runtimeParams: this.params.runtimeParams,
|
|
16197
|
+
input,
|
|
16198
|
+
signal: options?.signal
|
|
16199
|
+
});
|
|
16200
|
+
};
|
|
16201
|
+
var ExtensionHostProxyRegistryService = class {
|
|
16202
|
+
constructor(client) {
|
|
16203
|
+
this.client = client;
|
|
16204
|
+
}
|
|
16205
|
+
createPluginRegistry = (snapshot) => ({
|
|
16206
|
+
plugins: snapshot.plugins,
|
|
16207
|
+
diagnostics: snapshot.diagnostics,
|
|
16208
|
+
tools: snapshot.tools.map((descriptor) => ({
|
|
16209
|
+
pluginId: descriptor.pluginId,
|
|
16210
|
+
source: descriptor.source,
|
|
16211
|
+
names: descriptor.names,
|
|
16212
|
+
optional: descriptor.optional,
|
|
16213
|
+
factory: (context) => this.createProxyTools(descriptor, context)
|
|
16214
|
+
})),
|
|
16215
|
+
channels: snapshot.channels.map((descriptor) => ({
|
|
16216
|
+
pluginId: descriptor.pluginId,
|
|
16217
|
+
source: descriptor.source,
|
|
16218
|
+
channel: {
|
|
16219
|
+
id: descriptor.channel.id,
|
|
16220
|
+
...descriptor.channel.meta ? { meta: descriptor.channel.meta } : {},
|
|
16221
|
+
...descriptor.channel.capabilities ? { capabilities: descriptor.channel.capabilities } : {},
|
|
16222
|
+
...descriptor.channel.configSchema ? { configSchema: descriptor.channel.configSchema } : {},
|
|
16223
|
+
outbound: this.createChannelOutbound(descriptor)
|
|
16224
|
+
}
|
|
16225
|
+
})),
|
|
16226
|
+
providers: snapshot.providers.map((descriptor) => ({
|
|
16227
|
+
pluginId: descriptor.pluginId,
|
|
16228
|
+
source: descriptor.source,
|
|
16229
|
+
provider: descriptor.provider
|
|
16230
|
+
})),
|
|
16231
|
+
ncpAgentRuntimes: snapshot.ncpAgentRuntimes.map((descriptor) => ({
|
|
16232
|
+
pluginId: descriptor.pluginId,
|
|
16233
|
+
source: descriptor.source,
|
|
16234
|
+
kind: descriptor.kind,
|
|
16235
|
+
label: descriptor.label,
|
|
16236
|
+
createRuntime: (runtimeParams) => new ExtensionHostProxyRuntime({
|
|
16237
|
+
client: this.client,
|
|
16238
|
+
kind: descriptor.kind,
|
|
16239
|
+
runtimeParams
|
|
16240
|
+
}),
|
|
16241
|
+
createRuntimeForEntry: descriptor.supportsEntryRuntime ? ({ entry, runtimeParams }) => new ExtensionHostProxyRuntime({
|
|
16242
|
+
client: this.client,
|
|
16243
|
+
kind: descriptor.kind,
|
|
16244
|
+
entry,
|
|
16245
|
+
runtimeParams
|
|
16246
|
+
}) : void 0,
|
|
16247
|
+
describeSessionType: async (describeParams) => await this.client.describeRuntime({
|
|
16248
|
+
kind: descriptor.kind,
|
|
16249
|
+
describeParams
|
|
16250
|
+
}),
|
|
16251
|
+
describeSessionTypeForEntry: descriptor.supportsEntryDescription ? async ({ entry, describeParams }) => await this.client.describeRuntime({
|
|
16252
|
+
kind: descriptor.kind,
|
|
16253
|
+
entry,
|
|
16254
|
+
describeParams
|
|
16255
|
+
}) : void 0
|
|
16256
|
+
})),
|
|
16257
|
+
resolvedTools: snapshot.tools.flatMap((descriptor) => descriptor.previews.map((preview) => this.createProxyTool(descriptor, preview.name, {}, preview)))
|
|
16258
|
+
});
|
|
16259
|
+
createChannelOutbound = (descriptor) => ({
|
|
16260
|
+
...descriptor.channel.hasOutboundText ? { sendText: async (ctx) => await this.client.sendChannelOutbound({
|
|
16261
|
+
pluginId: descriptor.pluginId,
|
|
16262
|
+
channelId: descriptor.channel.id,
|
|
16263
|
+
kind: "text",
|
|
16264
|
+
cfg: ctx.cfg,
|
|
16265
|
+
to: ctx.to,
|
|
16266
|
+
text: ctx.text,
|
|
16267
|
+
accountId: ctx.accountId
|
|
16268
|
+
}) } : {},
|
|
16269
|
+
...descriptor.channel.hasOutboundPayload ? { sendPayload: async (ctx) => await this.client.sendChannelOutbound({
|
|
16270
|
+
pluginId: descriptor.pluginId,
|
|
16271
|
+
channelId: descriptor.channel.id,
|
|
16272
|
+
kind: "payload",
|
|
16273
|
+
cfg: ctx.cfg,
|
|
16274
|
+
to: ctx.to,
|
|
16275
|
+
text: ctx.text,
|
|
16276
|
+
payload: ctx.payload,
|
|
16277
|
+
accountId: ctx.accountId
|
|
16278
|
+
}) } : {}
|
|
16279
|
+
});
|
|
16280
|
+
createProxyTools = (descriptor, context) => descriptor.names.map((alias) => {
|
|
16281
|
+
const preview = pickPreview({
|
|
16282
|
+
descriptor,
|
|
16283
|
+
alias
|
|
16284
|
+
});
|
|
16285
|
+
return this.createProxyTool(descriptor, alias, context, preview ?? void 0);
|
|
16286
|
+
});
|
|
16287
|
+
createProxyTool = (descriptor, alias, context, preview) => ({
|
|
16288
|
+
name: preview?.name ?? alias,
|
|
16289
|
+
...preview?.label ? { label: preview.label } : {},
|
|
16290
|
+
description: preview?.description ?? `Extension tool '${alias}' from ${descriptor.pluginId}`,
|
|
16291
|
+
parameters: normalizeSchema(preview?.parameters),
|
|
16292
|
+
execute: async (toolCallIdOrParams, maybeParams) => {
|
|
16293
|
+
const hasToolCallId = typeof toolCallIdOrParams === "string";
|
|
16294
|
+
const params = hasToolCallId ? maybeParams ?? {} : toolCallIdOrParams;
|
|
16295
|
+
const toolCallId = hasToolCallId ? toolCallIdOrParams : void 0;
|
|
16296
|
+
return stringifyToolResult(await this.client.executeTool({
|
|
16297
|
+
registrationId: descriptor.registrationId,
|
|
16298
|
+
alias,
|
|
16299
|
+
context,
|
|
16300
|
+
params,
|
|
16301
|
+
toolCallId
|
|
16302
|
+
}));
|
|
16303
|
+
}
|
|
16304
|
+
});
|
|
16305
|
+
};
|
|
16306
|
+
//#endregion
|
|
16307
|
+
//#region src/cli/shared/services/extension-host-client.service.ts
|
|
16308
|
+
function resolveChildEntryPath() {
|
|
16309
|
+
const sourcePath = fileURLToPath(new URL("./extension-host-child.service.ts", import.meta.url));
|
|
16310
|
+
if (existsSync(sourcePath)) return sourcePath;
|
|
16311
|
+
return fileURLToPath(new URL("./extension-host-child.service.js", import.meta.url));
|
|
16312
|
+
}
|
|
16313
|
+
var ExtensionHostClient = class {
|
|
16314
|
+
child = null;
|
|
16315
|
+
nextRequestId = 1;
|
|
16316
|
+
nextStreamId = 1;
|
|
16317
|
+
pending = /* @__PURE__ */ new Map();
|
|
16318
|
+
runtimeStreams = /* @__PURE__ */ new Map();
|
|
16319
|
+
proxyRegistry = new ExtensionHostProxyRegistryService(this);
|
|
16320
|
+
constructor(params = {}) {
|
|
16321
|
+
this.params = params;
|
|
16322
|
+
}
|
|
16323
|
+
load = async (request) => await this.request("load", request);
|
|
16324
|
+
startPluginGateways = async (config) => {
|
|
16325
|
+
await this.request("channel.startGateways", { config });
|
|
16326
|
+
};
|
|
16327
|
+
stopPluginGateways = async () => {
|
|
16328
|
+
await this.request("channel.stopGateways", void 0);
|
|
16329
|
+
};
|
|
16330
|
+
executeTool = async (request) => await this.request("tool.execute", request);
|
|
16331
|
+
sendChannelOutbound = async (request) => await this.request("channel.outbound", request);
|
|
16332
|
+
describeRuntime = async (request) => await this.request("runtime.describe", request);
|
|
16333
|
+
createProxyPluginRegistry = (snapshot) => this.proxyRegistry.createPluginRegistry(snapshot);
|
|
16334
|
+
runRuntimeStream = async function* (params) {
|
|
16335
|
+
const { entry, input, kind, runtimeParams, signal } = params;
|
|
16336
|
+
const streamId = `runtime-${this.nextStreamId++}`;
|
|
16337
|
+
const state = {
|
|
16338
|
+
queue: [],
|
|
16339
|
+
wake: null,
|
|
16340
|
+
onMetadata: runtimeParams.setSessionMetadata,
|
|
16341
|
+
applyStateBatch: async (events) => {
|
|
16342
|
+
await runtimeParams.stateManager.dispatchBatch(events);
|
|
16343
|
+
}
|
|
16344
|
+
};
|
|
16345
|
+
this.runtimeStreams.set(streamId, state);
|
|
16346
|
+
const abortListener = () => {
|
|
16347
|
+
this.request("runtime.abort", {
|
|
16348
|
+
streamId,
|
|
16349
|
+
reason: typeof signal?.reason === "string" ? signal.reason : void 0
|
|
16350
|
+
}).catch(() => void 0);
|
|
16351
|
+
};
|
|
16352
|
+
signal?.addEventListener("abort", abortListener, { once: true });
|
|
16353
|
+
await this.request("runtime.run", {
|
|
16354
|
+
streamId,
|
|
16355
|
+
kind,
|
|
16356
|
+
entry,
|
|
16357
|
+
runtimeParams: {
|
|
16358
|
+
sessionId: runtimeParams.sessionId,
|
|
16359
|
+
agentId: runtimeParams.agentId,
|
|
16360
|
+
sessionMetadata: runtimeParams.sessionMetadata,
|
|
16361
|
+
...runtimeParams.resolveTools ? { resolvedTools: Array.from(runtimeParams.resolveTools(input) ?? []) } : {}
|
|
16362
|
+
},
|
|
16363
|
+
input
|
|
16364
|
+
});
|
|
16365
|
+
try {
|
|
16366
|
+
while (true) {
|
|
16367
|
+
const next = await this.nextRuntimeStreamItem(state);
|
|
16368
|
+
if (next === null) return;
|
|
16369
|
+
if (next instanceof Error) throw next;
|
|
16370
|
+
yield next;
|
|
16371
|
+
}
|
|
16372
|
+
} finally {
|
|
16373
|
+
signal?.removeEventListener("abort", abortListener);
|
|
16374
|
+
this.runtimeStreams.delete(streamId);
|
|
16375
|
+
}
|
|
16376
|
+
};
|
|
16377
|
+
dispose = async () => {
|
|
16378
|
+
await this.stopPluginGateways().catch(() => void 0);
|
|
16379
|
+
this.child?.kill();
|
|
16380
|
+
this.child = null;
|
|
16381
|
+
this.rejectAll(/* @__PURE__ */ new Error("Extension host disposed"));
|
|
16382
|
+
};
|
|
16383
|
+
request = async (method, payload) => {
|
|
16384
|
+
const child = this.ensureChild();
|
|
16385
|
+
const id = this.nextRequestId++;
|
|
16386
|
+
const promise = new Promise((resolve, reject) => {
|
|
16387
|
+
this.pending.set(id, {
|
|
16388
|
+
resolve: (value) => resolve(value),
|
|
16389
|
+
reject
|
|
16390
|
+
});
|
|
16391
|
+
});
|
|
16392
|
+
child.send?.({
|
|
16393
|
+
type: "request",
|
|
16394
|
+
id,
|
|
16395
|
+
method,
|
|
16396
|
+
payload
|
|
16397
|
+
});
|
|
16398
|
+
return await promise;
|
|
16399
|
+
};
|
|
16400
|
+
ensureChild = () => {
|
|
16401
|
+
if (this.child) return this.child;
|
|
16402
|
+
const child = fork(resolveChildEntryPath(), [], {
|
|
16403
|
+
env: process.env,
|
|
16404
|
+
execArgv: process.execArgv,
|
|
16405
|
+
stdio: [
|
|
16406
|
+
"ignore",
|
|
16407
|
+
"inherit",
|
|
16408
|
+
"inherit",
|
|
16409
|
+
"ipc"
|
|
16410
|
+
]
|
|
16411
|
+
});
|
|
16412
|
+
child.on("message", (message) => this.handleMessage(message));
|
|
16413
|
+
child.on("exit", (code, signal) => {
|
|
16414
|
+
this.child = null;
|
|
16415
|
+
this.rejectAll(/* @__PURE__ */ new Error(`Extension host exited: code=${code ?? "null"} signal=${signal ?? "null"}`));
|
|
16416
|
+
});
|
|
16417
|
+
child.on("error", (error) => {
|
|
16418
|
+
this.rejectAll(error);
|
|
16419
|
+
});
|
|
16420
|
+
this.child = child;
|
|
16421
|
+
return child;
|
|
16422
|
+
};
|
|
16423
|
+
handleMessage = (message) => {
|
|
16424
|
+
if (message.type === "response") {
|
|
16425
|
+
const pending = this.pending.get(message.id);
|
|
16426
|
+
if (!pending) return;
|
|
16427
|
+
this.pending.delete(message.id);
|
|
16428
|
+
if (message.ok) {
|
|
16429
|
+
pending.resolve(message.payload);
|
|
16430
|
+
return;
|
|
16431
|
+
}
|
|
16432
|
+
pending.reject(new Error(message.error));
|
|
16433
|
+
return;
|
|
16434
|
+
}
|
|
16435
|
+
if (message.type !== "event") return;
|
|
16436
|
+
if (message.event === "load.progress") {
|
|
16437
|
+
this.params.onProgress?.(message.payload);
|
|
16438
|
+
return;
|
|
16439
|
+
}
|
|
16440
|
+
if (message.event === "runtime.state.dispatchBatch") {
|
|
16441
|
+
this.runtimeStreams.get(message.payload.streamId)?.applyStateBatch(message.payload.events);
|
|
16442
|
+
return;
|
|
16443
|
+
}
|
|
16444
|
+
const state = this.runtimeStreams.get(message.payload.streamId);
|
|
16445
|
+
if (!state) return;
|
|
16446
|
+
if (message.event === "runtime.event") {
|
|
16447
|
+
this.pushRuntimeStreamItem(state, message.payload.event);
|
|
16448
|
+
return;
|
|
16449
|
+
}
|
|
16450
|
+
if (message.event === "runtime.metadata") {
|
|
16451
|
+
state.onMetadata(message.payload.metadata);
|
|
16452
|
+
return;
|
|
16453
|
+
}
|
|
16454
|
+
if (message.event === "runtime.error") {
|
|
16455
|
+
this.pushRuntimeStreamItem(state, new Error(message.payload.error));
|
|
16456
|
+
return;
|
|
16457
|
+
}
|
|
16458
|
+
if (message.event === "runtime.done") this.pushRuntimeStreamItem(state, null);
|
|
16459
|
+
};
|
|
16460
|
+
pushRuntimeStreamItem = (state, item) => {
|
|
16461
|
+
state.queue.push(item);
|
|
16462
|
+
state.wake?.();
|
|
16463
|
+
state.wake = null;
|
|
16464
|
+
};
|
|
16465
|
+
nextRuntimeStreamItem = async (state) => {
|
|
16466
|
+
const queued = state.queue.shift();
|
|
16467
|
+
if (queued !== void 0) return queued;
|
|
16468
|
+
await new Promise((resolve) => {
|
|
16469
|
+
state.wake = resolve;
|
|
16470
|
+
});
|
|
16471
|
+
return state.queue.shift() ?? null;
|
|
16472
|
+
};
|
|
16473
|
+
rejectAll = (error) => {
|
|
16474
|
+
for (const pending of this.pending.values()) pending.reject(error);
|
|
16475
|
+
this.pending.clear();
|
|
16476
|
+
for (const state of this.runtimeStreams.values()) this.pushRuntimeStreamItem(state, error);
|
|
16477
|
+
};
|
|
16478
|
+
};
|
|
16479
|
+
//#endregion
|
|
16204
16480
|
//#region src/cli/shared/services/runtime/runtime-command.service.ts
|
|
16205
16481
|
const { getApiBase, getConfigPath: getConfigPath$1, getProvider, getProviderName, getWorkspacePath: getWorkspacePath$1, loadConfig: loadConfig$1, LiteLLMProvider, MessageBus: MessageBus$1, resolveConfigSecrets: resolveConfigSecrets$1, SessionManager: SessionManager$1, parseAgentScopedSessionKey: parseAgentScopedSessionKey$1 } = NextclawCore;
|
|
16206
16482
|
function createSkillsLoader(workspace) {
|
|
@@ -16237,6 +16513,12 @@ var RuntimeCommandService = class {
|
|
|
16237
16513
|
};
|
|
16238
16514
|
let runtimeState = null;
|
|
16239
16515
|
const bootstrapStatus = createBootstrapStatus(shellContext.config.remote.enabled);
|
|
16516
|
+
const extensionHost = new ExtensionHostClient({ onProgress: ({ loadedPluginCount, totalPluginCount }) => {
|
|
16517
|
+
bootstrapStatus.markPluginHydrationProgress({
|
|
16518
|
+
loadedPluginCount,
|
|
16519
|
+
totalPluginCount
|
|
16520
|
+
});
|
|
16521
|
+
} });
|
|
16240
16522
|
const ncpSessionRealtimeBridge = createServiceNcpSessionRealtimeBridge({ sessionManager: shellContext.sessionManager });
|
|
16241
16523
|
const marketplaceInstaller = new ServiceMarketplaceInstaller({
|
|
16242
16524
|
applyLiveConfigReload,
|
|
@@ -16303,7 +16585,8 @@ var RuntimeCommandService = class {
|
|
|
16303
16585
|
configureGatewayPluginRuntime({
|
|
16304
16586
|
gateway,
|
|
16305
16587
|
state: gatewayRuntimeState,
|
|
16306
|
-
getLiveUiNcpAgent: () => this.liveUiNcpAgent
|
|
16588
|
+
getLiveUiNcpAgent: () => this.liveUiNcpAgent,
|
|
16589
|
+
extensionHost
|
|
16307
16590
|
});
|
|
16308
16591
|
console.log("✓ Capability hydration: scheduled in background");
|
|
16309
16592
|
await measureStartupAsync("service.start_gateway_support_services", async () => await startGatewayRuntimeSupport({
|
|
@@ -16329,6 +16612,7 @@ var RuntimeCommandService = class {
|
|
|
16329
16612
|
setLiveUiNcpAgent: (ncpAgent) => {
|
|
16330
16613
|
this.liveUiNcpAgent = ncpAgent;
|
|
16331
16614
|
},
|
|
16615
|
+
extensionHost,
|
|
16332
16616
|
wakeFromRestartSentinel: async () => await this.wakeFromRestartSentinel({
|
|
16333
16617
|
bus: gateway.bus,
|
|
16334
16618
|
sessionManager: gateway.sessionManager
|
|
@@ -16365,6 +16649,8 @@ var RuntimeCommandService = class {
|
|
|
16365
16649
|
uiStartup,
|
|
16366
16650
|
remoteModule: gateway.remoteModule,
|
|
16367
16651
|
runtimeState
|
|
16652
|
+
}).finally(async () => {
|
|
16653
|
+
await extensionHost.dispose();
|
|
16368
16654
|
})
|
|
16369
16655
|
});
|
|
16370
16656
|
logStartupTrace("service.start_gateway.end");
|
|
@@ -18216,7 +18502,7 @@ var WorkspaceManager = class {
|
|
|
18216
18502
|
return this.exitWithError(`Bridge source not found. Try reinstalling ${APP_NAME}.`);
|
|
18217
18503
|
};
|
|
18218
18504
|
assertCommandAvailable = (command) => {
|
|
18219
|
-
if (
|
|
18505
|
+
if (findExecutableOnPath(command)) return;
|
|
18220
18506
|
this.exitWithError(`${command} not found. Please install Node.js >= 18.`);
|
|
18221
18507
|
};
|
|
18222
18508
|
runBridgeCommand = (cwd, args, step) => {
|