@nextclaw/server 0.12.1 → 0.12.2
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/index.d.ts +42 -3
- package/dist/index.js +323 -77
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -486,8 +486,9 @@ type ProviderConnectionTestResult = {
|
|
|
486
486
|
latencyMs: number;
|
|
487
487
|
message: string;
|
|
488
488
|
};
|
|
489
|
-
type SearchProviderName = "bocha" | "brave";
|
|
489
|
+
type SearchProviderName = "bocha" | "tavily" | "brave";
|
|
490
490
|
type BochaFreshnessValue = "noLimit" | "oneDay" | "oneWeek" | "oneMonth" | "oneYear" | string;
|
|
491
|
+
type TavilySearchDepthValue = "basic" | "advanced";
|
|
491
492
|
type SearchProviderConfigView = {
|
|
492
493
|
enabled: boolean;
|
|
493
494
|
apiKeySet: boolean;
|
|
@@ -496,6 +497,8 @@ type SearchProviderConfigView = {
|
|
|
496
497
|
docsUrl?: string;
|
|
497
498
|
summary?: boolean;
|
|
498
499
|
freshness?: BochaFreshnessValue;
|
|
500
|
+
searchDepth?: TavilySearchDepthValue;
|
|
501
|
+
includeAnswer?: boolean;
|
|
499
502
|
};
|
|
500
503
|
type SearchConfigView = {
|
|
501
504
|
provider: SearchProviderName;
|
|
@@ -505,6 +508,7 @@ type SearchConfigView = {
|
|
|
505
508
|
};
|
|
506
509
|
providers: {
|
|
507
510
|
bocha: SearchProviderConfigView;
|
|
511
|
+
tavily: SearchProviderConfigView;
|
|
508
512
|
brave: SearchProviderConfigView;
|
|
509
513
|
};
|
|
510
514
|
};
|
|
@@ -522,6 +526,12 @@ type SearchConfigUpdate = {
|
|
|
522
526
|
summary?: boolean;
|
|
523
527
|
freshness?: BochaFreshnessValue | null;
|
|
524
528
|
};
|
|
529
|
+
tavily?: {
|
|
530
|
+
apiKey?: string | null;
|
|
531
|
+
baseUrl?: string | null;
|
|
532
|
+
searchDepth?: TavilySearchDepthValue | null;
|
|
533
|
+
includeAnswer?: boolean;
|
|
534
|
+
};
|
|
525
535
|
brave?: {
|
|
526
536
|
apiKey?: string | null;
|
|
527
537
|
baseUrl?: string | null;
|
|
@@ -700,6 +710,8 @@ type AgentProfileView = {
|
|
|
700
710
|
avatarUrl?: string;
|
|
701
711
|
workspace?: string;
|
|
702
712
|
model?: string;
|
|
713
|
+
runtime?: string;
|
|
714
|
+
runtimeConfig?: Record<string, unknown>;
|
|
703
715
|
engine?: string;
|
|
704
716
|
engineConfig?: Record<string, unknown>;
|
|
705
717
|
contextTokens?: number;
|
|
@@ -712,6 +724,17 @@ type AgentCreateRequest = {
|
|
|
712
724
|
description?: string;
|
|
713
725
|
avatar?: string;
|
|
714
726
|
home?: string;
|
|
727
|
+
model?: string;
|
|
728
|
+
runtime?: string;
|
|
729
|
+
runtimeConfig?: Record<string, unknown>;
|
|
730
|
+
};
|
|
731
|
+
type AgentUpdateRequest = {
|
|
732
|
+
displayName?: string;
|
|
733
|
+
description?: string;
|
|
734
|
+
avatar?: string;
|
|
735
|
+
model?: string;
|
|
736
|
+
runtime?: string;
|
|
737
|
+
runtimeConfig?: Record<string, unknown>;
|
|
715
738
|
};
|
|
716
739
|
type AgentDeleteResult = {
|
|
717
740
|
deleted: boolean;
|
|
@@ -854,6 +877,20 @@ type CronListView = {
|
|
|
854
877
|
jobs: CronJobView[];
|
|
855
878
|
total: number;
|
|
856
879
|
};
|
|
880
|
+
type CronCreateRequest = {
|
|
881
|
+
name: string;
|
|
882
|
+
message: string;
|
|
883
|
+
schedule: CronScheduleView;
|
|
884
|
+
agentId?: string | null;
|
|
885
|
+
deliver?: boolean;
|
|
886
|
+
channel?: string | null;
|
|
887
|
+
to?: string | null;
|
|
888
|
+
accountId?: string | null;
|
|
889
|
+
deleteAfterRun?: boolean;
|
|
890
|
+
};
|
|
891
|
+
type CronCreateResult = {
|
|
892
|
+
job: CronJobView;
|
|
893
|
+
};
|
|
857
894
|
type CronEnableRequest = {
|
|
858
895
|
enabled: boolean;
|
|
859
896
|
};
|
|
@@ -1192,6 +1229,9 @@ type PluginConfigProjectionOptions = {
|
|
|
1192
1229
|
pluginUiMetadata?: PluginUiMetadata[];
|
|
1193
1230
|
};
|
|
1194
1231
|
//#endregion
|
|
1232
|
+
//#region src/ui/search-config.d.ts
|
|
1233
|
+
declare function updateSearch(configPath: string, patch: SearchConfigUpdate): ConfigView["search"];
|
|
1234
|
+
//#endregion
|
|
1195
1235
|
//#region src/ui/config.d.ts
|
|
1196
1236
|
type ExecuteActionResult = {
|
|
1197
1237
|
ok: true;
|
|
@@ -1211,7 +1251,6 @@ declare function updateModel(configPath: string, patch: {
|
|
|
1211
1251
|
model?: string;
|
|
1212
1252
|
workspace?: string;
|
|
1213
1253
|
}): ConfigView;
|
|
1214
|
-
declare function updateSearch(configPath: string, patch: SearchConfigUpdate): ConfigView["search"];
|
|
1215
1254
|
declare function updateProvider(configPath: string, providerName: string, patch: ProviderConfigUpdate): ProviderConfigView | null;
|
|
1216
1255
|
declare function createCustomProvider(configPath: string, patch?: ProviderConfigUpdate): {
|
|
1217
1256
|
name: string;
|
|
@@ -1243,4 +1282,4 @@ declare function getUiBridgeSecretPath(): string;
|
|
|
1243
1282
|
declare function readUiBridgeSecret(): string | null;
|
|
1244
1283
|
declare function ensureUiBridgeSecret(): string;
|
|
1245
1284
|
//#endregion
|
|
1246
|
-
export { AgentBindingView, AgentCreateRequest, AgentDeleteResult, AgentProfileView, ApiError, ApiResponse, AppMetaView, AuthEnabledUpdateRequest, AuthLoginRequest, AuthPasswordUpdateRequest, AuthSetupRequest, AuthStatusView, BindingPeerView, BochaFreshnessValue, BootstrapPhase, BootstrapRemoteState, BootstrapStageState, BootstrapStatusView, ChannelAuthPollRequest, ChannelAuthPollResult, ChannelAuthStartRequest, ChannelAuthStartResult, ChannelSpecView, type ChatSessionTypeCtaView, type ChatSessionTypeOptionView, type ChatSessionTypesView, ConfigActionExecuteRequest, ConfigActionExecuteResult, ConfigActionManifest, ConfigActionType, ConfigMetaView, ConfigSchemaResponse, ConfigUiHint, ConfigUiHints, ConfigView, CronActionResult, CronEnableRequest, CronJobStateView, CronJobView, CronListView, CronPayloadView, CronRunRequest, CronScheduleView, DEFAULT_SESSION_TYPE, MarketplaceApiConfig, MarketplaceInstallKind, MarketplaceInstallSkillParams, MarketplaceInstallSpec, MarketplaceInstalledRecord, MarketplaceInstalledView, MarketplaceInstaller, MarketplaceItemSummary, MarketplaceItemType, MarketplaceItemView, MarketplaceListView, MarketplaceLocalizedTextMap, MarketplaceMcpContentView, MarketplaceMcpDoctorResult, MarketplaceMcpInstallKind, MarketplaceMcpInstallRequest, MarketplaceMcpInstallResult, MarketplaceMcpInstallSpec, MarketplaceMcpManageAction, MarketplaceMcpManageRequest, MarketplaceMcpManageResult, MarketplaceMcpTemplateInput, MarketplacePluginContentView, MarketplacePluginInstallKind, MarketplacePluginInstallRequest, MarketplacePluginInstallResult, MarketplacePluginManageAction, MarketplacePluginManageRequest, MarketplacePluginManageResult, MarketplaceRecommendationView, MarketplaceSkillContentView, MarketplaceSkillInstallKind, MarketplaceSkillInstallRequest, MarketplaceSkillInstallResult, MarketplaceSkillManageAction, MarketplaceSkillManageRequest, MarketplaceSkillManageResult, MarketplaceSort, NcpSessionSkillsView, ProviderAuthImportResult, ProviderAuthPollRequest, ProviderAuthPollResult, ProviderAuthStartRequest, ProviderAuthStartResult, ProviderConfigUpdate, ProviderConfigView, ProviderConnectionTestRequest, ProviderConnectionTestResult, ProviderCreateRequest, ProviderCreateResult, ProviderDeleteResult, ProviderSpecView, RemoteAccessView, RemoteAccountView, RemoteBrowserAuthPollRequest, RemoteBrowserAuthPollResult, RemoteBrowserAuthStartRequest, RemoteBrowserAuthStartResult, RemoteDoctorCheckView, RemoteDoctorView, RemoteLoginRequest, RemoteRuntimeView, RemoteServiceAction, RemoteServiceActionResult, RemoteServiceView, RemoteSettingsUpdateRequest, RemoteSettingsView, RuntimeConfigUpdate, SearchConfigUpdate, SearchConfigView, SearchProviderConfigView, SearchProviderName, SearchProviderSpecView, SecretProviderEnvView, SecretProviderExecView, SecretProviderFileView, SecretProviderView, SecretRefView, SecretSourceView, SecretsConfigUpdate, SecretsView, ServerPathBreadcrumbView, ServerPathBrowseView, ServerPathEntryView, SessionConfigView, SessionEntryView, SessionEventView, SessionHistoryView, SessionMessageView, SessionPatchUpdate, SessionPatchValidationError, SessionSkillEntryView, SessionTypeDescribeParams, SessionsListView, UiNcpAgent, UiNcpAssetPutView, UiNcpAssetView, UiNcpSessionListView, UiNcpSessionMessagesView, UiNcpSessionService, UiNcpStoredAssetRecord, type UiRemoteAccessHost, UiServerEvent, UiServerHandle, UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createCustomProvider, createUiRouter, deleteCustomProvider, deleteSession, ensureUiBridgeSecret, executeConfigAction, getSessionHistory, getUiBridgeSecretPath, listSessions, loadConfigOrDefault, patchSession, readUiBridgeSecret, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSearch, updateSecrets };
|
|
1285
|
+
export { AgentBindingView, AgentCreateRequest, AgentDeleteResult, AgentProfileView, AgentUpdateRequest, ApiError, ApiResponse, AppMetaView, AuthEnabledUpdateRequest, AuthLoginRequest, AuthPasswordUpdateRequest, AuthSetupRequest, AuthStatusView, BindingPeerView, BochaFreshnessValue, BootstrapPhase, BootstrapRemoteState, BootstrapStageState, BootstrapStatusView, ChannelAuthPollRequest, ChannelAuthPollResult, ChannelAuthStartRequest, ChannelAuthStartResult, ChannelSpecView, type ChatSessionTypeCtaView, type ChatSessionTypeOptionView, type ChatSessionTypesView, ConfigActionExecuteRequest, ConfigActionExecuteResult, ConfigActionManifest, ConfigActionType, ConfigMetaView, ConfigSchemaResponse, ConfigUiHint, ConfigUiHints, ConfigView, CronActionResult, CronCreateRequest, CronCreateResult, CronEnableRequest, CronJobStateView, CronJobView, CronListView, CronPayloadView, CronRunRequest, CronScheduleView, DEFAULT_SESSION_TYPE, MarketplaceApiConfig, MarketplaceInstallKind, MarketplaceInstallSkillParams, MarketplaceInstallSpec, MarketplaceInstalledRecord, MarketplaceInstalledView, MarketplaceInstaller, MarketplaceItemSummary, MarketplaceItemType, MarketplaceItemView, MarketplaceListView, MarketplaceLocalizedTextMap, MarketplaceMcpContentView, MarketplaceMcpDoctorResult, MarketplaceMcpInstallKind, MarketplaceMcpInstallRequest, MarketplaceMcpInstallResult, MarketplaceMcpInstallSpec, MarketplaceMcpManageAction, MarketplaceMcpManageRequest, MarketplaceMcpManageResult, MarketplaceMcpTemplateInput, MarketplacePluginContentView, MarketplacePluginInstallKind, MarketplacePluginInstallRequest, MarketplacePluginInstallResult, MarketplacePluginManageAction, MarketplacePluginManageRequest, MarketplacePluginManageResult, MarketplaceRecommendationView, MarketplaceSkillContentView, MarketplaceSkillInstallKind, MarketplaceSkillInstallRequest, MarketplaceSkillInstallResult, MarketplaceSkillManageAction, MarketplaceSkillManageRequest, MarketplaceSkillManageResult, MarketplaceSort, NcpSessionSkillsView, ProviderAuthImportResult, ProviderAuthPollRequest, ProviderAuthPollResult, ProviderAuthStartRequest, ProviderAuthStartResult, ProviderConfigUpdate, ProviderConfigView, ProviderConnectionTestRequest, ProviderConnectionTestResult, ProviderCreateRequest, ProviderCreateResult, ProviderDeleteResult, ProviderSpecView, RemoteAccessView, RemoteAccountView, RemoteBrowserAuthPollRequest, RemoteBrowserAuthPollResult, RemoteBrowserAuthStartRequest, RemoteBrowserAuthStartResult, RemoteDoctorCheckView, RemoteDoctorView, RemoteLoginRequest, RemoteRuntimeView, RemoteServiceAction, RemoteServiceActionResult, RemoteServiceView, RemoteSettingsUpdateRequest, RemoteSettingsView, RuntimeConfigUpdate, SearchConfigUpdate, SearchConfigView, SearchProviderConfigView, SearchProviderName, SearchProviderSpecView, SecretProviderEnvView, SecretProviderExecView, SecretProviderFileView, SecretProviderView, SecretRefView, SecretSourceView, SecretsConfigUpdate, SecretsView, ServerPathBreadcrumbView, ServerPathBrowseView, ServerPathEntryView, SessionConfigView, SessionEntryView, SessionEventView, SessionHistoryView, SessionMessageView, SessionPatchUpdate, SessionPatchValidationError, SessionSkillEntryView, SessionTypeDescribeParams, SessionsListView, TavilySearchDepthValue, UiNcpAgent, UiNcpAssetPutView, UiNcpAssetView, UiNcpSessionListView, UiNcpSessionMessagesView, UiNcpSessionService, UiNcpStoredAssetRecord, type UiRemoteAccessHost, UiServerEvent, UiServerHandle, UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createCustomProvider, createUiRouter, deleteCustomProvider, deleteSession, ensureUiBridgeSecret, executeConfigAction, getSessionHistory, getUiBridgeSecretPath, listSessions, loadConfigOrDefault, patchSession, readUiBridgeSecret, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSearch, updateSecrets };
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
6
6
|
import { readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
7
7
|
import { dirname, isAbsolute, join, parse, resolve } from "node:path";
|
|
8
8
|
import * as NextclawCore from "@nextclaw/core";
|
|
9
|
-
import { ConfigSchema, DEFAULT_WORKSPACE_PATH, LiteLLMProvider, SessionManager, buildConfigSchema, createAgentProfile, expandHome, findEffectiveAgentProfile, getDataDir, getPackageVersion, getProviderName, getWorkspacePathFromConfig, hasSecretRef, isSensitiveConfigPath, loadConfig, normalizeThinkingLevels, parseThinkingLevel, probeFeishu, readAgentAvatarContent, removeAgentProfile, resolveEffectiveAgentProfiles, saveConfig } from "@nextclaw/core";
|
|
9
|
+
import { ConfigSchema, DEFAULT_WORKSPACE_PATH, LiteLLMProvider, SessionManager, buildConfigSchema, createAgentProfile, expandHome, findEffectiveAgentProfile, getDataDir, getPackageVersion, getProviderName, getWorkspacePathFromConfig, hasSecretRef, isSensitiveConfigPath, loadConfig, normalizeThinkingLevels, parseThinkingLevel, probeFeishu, readAgentAvatarContent, removeAgentProfile, resolveEffectiveAgentProfiles, saveConfig, updateAgentProfile } from "@nextclaw/core";
|
|
10
10
|
import { createHash, randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
|
|
11
11
|
import { mountNcpHttpAgentRoutes } from "@nextclaw/ncp-http-agent-server";
|
|
12
12
|
import { discoverPluginStatusReport, enablePluginInConfig, mergePluginConfigView, toPluginConfigView } from "@nextclaw/openclaw-compat";
|
|
@@ -291,7 +291,10 @@ function createAgent(configPath, input, options = {}) {
|
|
|
291
291
|
displayName: input.displayName,
|
|
292
292
|
description: input.description,
|
|
293
293
|
avatar: input.avatar,
|
|
294
|
-
home: input.home
|
|
294
|
+
home: input.home,
|
|
295
|
+
model: input.model,
|
|
296
|
+
runtime: input.runtime,
|
|
297
|
+
runtimeConfig: input.runtimeConfig
|
|
295
298
|
}, {
|
|
296
299
|
configPath,
|
|
297
300
|
initializeHomeDirectory: options.initializeAgentHomeDirectory
|
|
@@ -305,6 +308,18 @@ function deleteAgent(configPath, agentId) {
|
|
|
305
308
|
agentId: agentId.trim().toLowerCase()
|
|
306
309
|
};
|
|
307
310
|
}
|
|
311
|
+
function updateAgent(configPath, agentId, input) {
|
|
312
|
+
const updated = updateAgentProfile({
|
|
313
|
+
id: agentId,
|
|
314
|
+
displayName: input.displayName,
|
|
315
|
+
description: input.description,
|
|
316
|
+
avatar: input.avatar,
|
|
317
|
+
model: input.model,
|
|
318
|
+
runtime: input.runtime,
|
|
319
|
+
runtimeConfig: input.runtimeConfig
|
|
320
|
+
}, { configPath });
|
|
321
|
+
return toAgentProfileView(loadConfig(configPath), updated.id);
|
|
322
|
+
}
|
|
308
323
|
function readAgentAvatar(configPath, agentId) {
|
|
309
324
|
return readAgentAvatarContent({
|
|
310
325
|
config: loadConfig(configPath),
|
|
@@ -323,6 +338,8 @@ function toAgentProfileView(config, agentId) {
|
|
|
323
338
|
avatarUrl: buildAgentAvatarUrl(profile.id, profile.avatar),
|
|
324
339
|
workspace: profile.workspace,
|
|
325
340
|
model: profile.model,
|
|
341
|
+
runtime: profile.runtime,
|
|
342
|
+
runtimeConfig: profile.runtimeConfig,
|
|
326
343
|
engine: profile.engine,
|
|
327
344
|
engineConfig: profile.engineConfig,
|
|
328
345
|
contextTokens: profile.contextTokens,
|
|
@@ -410,6 +427,20 @@ var AgentsRoutesController = class {
|
|
|
410
427
|
return c.json(err("AGENT_CREATE_FAILED", error instanceof Error ? error.message : String(error)), 400);
|
|
411
428
|
}
|
|
412
429
|
};
|
|
430
|
+
updateAgent = async (c) => {
|
|
431
|
+
const agentId = c.req.param("agentId");
|
|
432
|
+
const body = await readJson(c.req.raw);
|
|
433
|
+
if (!body.ok) return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
434
|
+
try {
|
|
435
|
+
const agent = updateAgent(this.options.configPath, agentId, body.data);
|
|
436
|
+
await this.publishAgentUpdates(["agents.list"]);
|
|
437
|
+
return c.json(ok(agent));
|
|
438
|
+
} catch (error) {
|
|
439
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
440
|
+
const status = message.includes("not found") ? 404 : 400;
|
|
441
|
+
return c.json(err("AGENT_UPDATE_FAILED", message), status);
|
|
442
|
+
}
|
|
443
|
+
};
|
|
413
444
|
deleteAgent = async (c) => {
|
|
414
445
|
const agentId = c.req.param("agentId");
|
|
415
446
|
try {
|
|
@@ -766,6 +797,230 @@ function findServerBuiltinProviderByName(name) {
|
|
|
766
797
|
return SERVER_BUILTIN_PROVIDER_OVERRIDE_MAP.get(name) ?? findBuiltinProviderByName(name);
|
|
767
798
|
}
|
|
768
799
|
//#endregion
|
|
800
|
+
//#region src/ui/search-config.ts
|
|
801
|
+
const MASK_MIN_LENGTH$1 = 8;
|
|
802
|
+
const BOCHA_OPEN_URL = "https://open.bocha.cn";
|
|
803
|
+
const TAVILY_DOCS_URL = "https://docs.tavily.com/documentation/api-reference/endpoint/search";
|
|
804
|
+
const SEARCH_PROVIDER_NAMES = [
|
|
805
|
+
"bocha",
|
|
806
|
+
"tavily",
|
|
807
|
+
"brave"
|
|
808
|
+
];
|
|
809
|
+
function normalizeOptionalString$1(value) {
|
|
810
|
+
if (typeof value !== "string") return null;
|
|
811
|
+
const trimmed = value.trim();
|
|
812
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
813
|
+
}
|
|
814
|
+
function maskApiKey$1(value) {
|
|
815
|
+
if (!value) return { apiKeySet: false };
|
|
816
|
+
if (value.length < MASK_MIN_LENGTH$1) return {
|
|
817
|
+
apiKeySet: true,
|
|
818
|
+
apiKeyMasked: "****"
|
|
819
|
+
};
|
|
820
|
+
return {
|
|
821
|
+
apiKeySet: true,
|
|
822
|
+
apiKeyMasked: `${value.slice(0, 2)}****${value.slice(-4)}`
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
function clearSecretRef$1(refs, path) {
|
|
826
|
+
if (!refs[path]) return refs;
|
|
827
|
+
const nextRefs = { ...refs };
|
|
828
|
+
delete nextRefs[path];
|
|
829
|
+
return nextRefs;
|
|
830
|
+
}
|
|
831
|
+
function isSearchProviderName(value) {
|
|
832
|
+
return typeof value === "string" && SEARCH_PROVIDER_NAMES.some((providerName) => providerName === value);
|
|
833
|
+
}
|
|
834
|
+
const SEARCH_PROVIDER_META = [
|
|
835
|
+
{
|
|
836
|
+
name: "bocha",
|
|
837
|
+
displayName: "Bocha Search",
|
|
838
|
+
description: "China-friendly web search with AI-ready summaries.",
|
|
839
|
+
docsUrl: BOCHA_OPEN_URL,
|
|
840
|
+
isDefault: true,
|
|
841
|
+
supportsSummary: true
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
name: "tavily",
|
|
845
|
+
displayName: "Tavily Search",
|
|
846
|
+
description: "Research-focused web search with optional synthesized answers.",
|
|
847
|
+
docsUrl: TAVILY_DOCS_URL,
|
|
848
|
+
supportsSummary: true
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
name: "brave",
|
|
852
|
+
displayName: "Brave Search",
|
|
853
|
+
description: "Brave web search API kept as an optional provider.",
|
|
854
|
+
supportsSummary: false
|
|
855
|
+
}
|
|
856
|
+
];
|
|
857
|
+
function toSearchProviderView(config, providerName, provider) {
|
|
858
|
+
const apiKeyRefSet = hasSecretRef(config, `search.providers.${providerName}.apiKey`);
|
|
859
|
+
const masked = maskApiKey$1(provider.apiKey);
|
|
860
|
+
const view = {
|
|
861
|
+
enabled: config.search.enabledProviders.includes(providerName),
|
|
862
|
+
apiKeySet: masked.apiKeySet || apiKeyRefSet,
|
|
863
|
+
apiKeyMasked: masked.apiKeyMasked ?? (apiKeyRefSet ? "****" : void 0),
|
|
864
|
+
baseUrl: provider.baseUrl
|
|
865
|
+
};
|
|
866
|
+
if ("docsUrl" in provider) view.docsUrl = provider.docsUrl;
|
|
867
|
+
if ("summary" in provider) view.summary = provider.summary;
|
|
868
|
+
if ("freshness" in provider) view.freshness = provider.freshness;
|
|
869
|
+
if ("searchDepth" in provider) view.searchDepth = provider.searchDepth;
|
|
870
|
+
if ("includeAnswer" in provider) view.includeAnswer = Boolean(provider.includeAnswer);
|
|
871
|
+
return view;
|
|
872
|
+
}
|
|
873
|
+
function buildSearchView(config) {
|
|
874
|
+
return {
|
|
875
|
+
provider: config.search.provider,
|
|
876
|
+
enabledProviders: [...config.search.enabledProviders],
|
|
877
|
+
defaults: { maxResults: config.search.defaults.maxResults },
|
|
878
|
+
providers: {
|
|
879
|
+
bocha: toSearchProviderView(config, "bocha", config.search.providers.bocha),
|
|
880
|
+
tavily: toSearchProviderView(config, "tavily", config.search.providers.tavily),
|
|
881
|
+
brave: toSearchProviderView(config, "brave", config.search.providers.brave)
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
function replaceSearchConfig(config, search, refs = config.secrets.refs) {
|
|
886
|
+
return {
|
|
887
|
+
...config,
|
|
888
|
+
search,
|
|
889
|
+
secrets: refs === config.secrets.refs ? config.secrets : {
|
|
890
|
+
...config.secrets,
|
|
891
|
+
refs
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
function applyActiveSearchProviderPatch(config, provider) {
|
|
896
|
+
if (!isSearchProviderName(provider)) return config;
|
|
897
|
+
return replaceSearchConfig(config, {
|
|
898
|
+
...config.search,
|
|
899
|
+
provider
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
function applyEnabledSearchProvidersPatch(config, enabledProviders) {
|
|
903
|
+
if (!Array.isArray(enabledProviders)) return config;
|
|
904
|
+
const nextEnabledProviders = Array.from(new Set(enabledProviders.filter((value) => isSearchProviderName(value))));
|
|
905
|
+
return replaceSearchConfig(config, {
|
|
906
|
+
...config.search,
|
|
907
|
+
enabledProviders: nextEnabledProviders
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
function applySearchDefaultsPatch(config, defaults) {
|
|
911
|
+
if (!defaults || !Object.prototype.hasOwnProperty.call(defaults, "maxResults")) return config;
|
|
912
|
+
const nextMaxResults = defaults.maxResults;
|
|
913
|
+
if (typeof nextMaxResults === "number" && Number.isFinite(nextMaxResults)) return replaceSearchConfig(config, {
|
|
914
|
+
...config.search,
|
|
915
|
+
defaults: {
|
|
916
|
+
...config.search.defaults,
|
|
917
|
+
maxResults: Math.max(1, Math.min(50, Math.trunc(nextMaxResults)))
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
return config;
|
|
921
|
+
}
|
|
922
|
+
function applyBochaSearchPatch(config, patch) {
|
|
923
|
+
if (!patch) return config;
|
|
924
|
+
let nextRefs = config.secrets.refs;
|
|
925
|
+
let nextProvider = config.search.providers.bocha;
|
|
926
|
+
if (Object.prototype.hasOwnProperty.call(patch, "apiKey")) {
|
|
927
|
+
nextProvider = {
|
|
928
|
+
...nextProvider,
|
|
929
|
+
apiKey: patch.apiKey ?? ""
|
|
930
|
+
};
|
|
931
|
+
nextRefs = clearSecretRef$1(nextRefs, "search.providers.bocha.apiKey");
|
|
932
|
+
}
|
|
933
|
+
if (Object.prototype.hasOwnProperty.call(patch, "baseUrl")) nextProvider = {
|
|
934
|
+
...nextProvider,
|
|
935
|
+
baseUrl: normalizeOptionalString$1(patch.baseUrl) ?? "https://api.bocha.cn/v1/web-search"
|
|
936
|
+
};
|
|
937
|
+
if (Object.prototype.hasOwnProperty.call(patch, "docsUrl")) nextProvider = {
|
|
938
|
+
...nextProvider,
|
|
939
|
+
docsUrl: normalizeOptionalString$1(patch.docsUrl) ?? BOCHA_OPEN_URL
|
|
940
|
+
};
|
|
941
|
+
if (Object.prototype.hasOwnProperty.call(patch, "summary")) nextProvider = {
|
|
942
|
+
...nextProvider,
|
|
943
|
+
summary: Boolean(patch.summary)
|
|
944
|
+
};
|
|
945
|
+
if (Object.prototype.hasOwnProperty.call(patch, "freshness")) {
|
|
946
|
+
const freshness = normalizeOptionalString$1(patch.freshness);
|
|
947
|
+
nextProvider = {
|
|
948
|
+
...nextProvider,
|
|
949
|
+
freshness: freshness === "noLimit" || freshness === "oneDay" || freshness === "oneWeek" || freshness === "oneMonth" || freshness === "oneYear" ? freshness : "noLimit"
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
return replaceSearchConfig(config, {
|
|
953
|
+
...config.search,
|
|
954
|
+
providers: {
|
|
955
|
+
...config.search.providers,
|
|
956
|
+
bocha: nextProvider
|
|
957
|
+
}
|
|
958
|
+
}, nextRefs);
|
|
959
|
+
}
|
|
960
|
+
function applyTavilySearchPatch(config, patch) {
|
|
961
|
+
if (!patch) return config;
|
|
962
|
+
let nextRefs = config.secrets.refs;
|
|
963
|
+
let nextProvider = config.search.providers.tavily;
|
|
964
|
+
if (Object.prototype.hasOwnProperty.call(patch, "apiKey")) {
|
|
965
|
+
nextProvider = {
|
|
966
|
+
...nextProvider,
|
|
967
|
+
apiKey: patch.apiKey ?? ""
|
|
968
|
+
};
|
|
969
|
+
nextRefs = clearSecretRef$1(nextRefs, "search.providers.tavily.apiKey");
|
|
970
|
+
}
|
|
971
|
+
if (Object.prototype.hasOwnProperty.call(patch, "baseUrl")) nextProvider = {
|
|
972
|
+
...nextProvider,
|
|
973
|
+
baseUrl: normalizeOptionalString$1(patch.baseUrl) ?? "https://api.tavily.com/search"
|
|
974
|
+
};
|
|
975
|
+
if (Object.prototype.hasOwnProperty.call(patch, "searchDepth")) {
|
|
976
|
+
const searchDepth = normalizeOptionalString$1(patch.searchDepth);
|
|
977
|
+
nextProvider = {
|
|
978
|
+
...nextProvider,
|
|
979
|
+
searchDepth: searchDepth === "advanced" ? "advanced" : "basic"
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
if (Object.prototype.hasOwnProperty.call(patch, "includeAnswer")) nextProvider = {
|
|
983
|
+
...nextProvider,
|
|
984
|
+
includeAnswer: Boolean(patch.includeAnswer)
|
|
985
|
+
};
|
|
986
|
+
return replaceSearchConfig(config, {
|
|
987
|
+
...config.search,
|
|
988
|
+
providers: {
|
|
989
|
+
...config.search.providers,
|
|
990
|
+
tavily: nextProvider
|
|
991
|
+
}
|
|
992
|
+
}, nextRefs);
|
|
993
|
+
}
|
|
994
|
+
function applyBraveSearchPatch(config, patch) {
|
|
995
|
+
if (!patch) return config;
|
|
996
|
+
let nextRefs = config.secrets.refs;
|
|
997
|
+
let nextProvider = config.search.providers.brave;
|
|
998
|
+
if (Object.prototype.hasOwnProperty.call(patch, "apiKey")) {
|
|
999
|
+
nextProvider = {
|
|
1000
|
+
...nextProvider,
|
|
1001
|
+
apiKey: patch.apiKey ?? ""
|
|
1002
|
+
};
|
|
1003
|
+
nextRefs = clearSecretRef$1(nextRefs, "search.providers.brave.apiKey");
|
|
1004
|
+
}
|
|
1005
|
+
if (Object.prototype.hasOwnProperty.call(patch, "baseUrl")) nextProvider = {
|
|
1006
|
+
...nextProvider,
|
|
1007
|
+
baseUrl: normalizeOptionalString$1(patch.baseUrl) ?? "https://api.search.brave.com/res/v1/web/search"
|
|
1008
|
+
};
|
|
1009
|
+
return replaceSearchConfig(config, {
|
|
1010
|
+
...config.search,
|
|
1011
|
+
providers: {
|
|
1012
|
+
...config.search.providers,
|
|
1013
|
+
brave: nextProvider
|
|
1014
|
+
}
|
|
1015
|
+
}, nextRefs);
|
|
1016
|
+
}
|
|
1017
|
+
function updateSearch(configPath, patch) {
|
|
1018
|
+
const nextConfig = applyBraveSearchPatch(applyTavilySearchPatch(applyBochaSearchPatch(applySearchDefaultsPatch(applyEnabledSearchProvidersPatch(applyActiveSearchProviderPatch(loadConfig(configPath), patch.provider), patch.enabledProviders), patch.defaults), patch.providers?.bocha), patch.providers?.tavily), patch.providers?.brave);
|
|
1019
|
+
const next = ConfigSchema.parse(nextConfig);
|
|
1020
|
+
saveConfig(next, configPath);
|
|
1021
|
+
return buildSearchView(next);
|
|
1022
|
+
}
|
|
1023
|
+
//#endregion
|
|
769
1024
|
//#region src/ui/session-preference-patch.ts
|
|
770
1025
|
function applySessionPreferencePatch(params) {
|
|
771
1026
|
const nextMetadata = params.metadata;
|
|
@@ -876,20 +1131,6 @@ function ensureProviderConfig(config, providerName) {
|
|
|
876
1131
|
function clearSecretRefsByPrefix(config, pathPrefix) {
|
|
877
1132
|
for (const key of Object.keys(config.secrets.refs)) if (key === pathPrefix || key.startsWith(`${pathPrefix}.`)) delete config.secrets.refs[key];
|
|
878
1133
|
}
|
|
879
|
-
const BOCHA_OPEN_URL = "https://open.bocha.cn";
|
|
880
|
-
const SEARCH_PROVIDER_META = [{
|
|
881
|
-
name: "bocha",
|
|
882
|
-
displayName: "Bocha Search",
|
|
883
|
-
description: "China-friendly web search with AI-ready summaries.",
|
|
884
|
-
docsUrl: BOCHA_OPEN_URL,
|
|
885
|
-
isDefault: true,
|
|
886
|
-
supportsSummary: true
|
|
887
|
-
}, {
|
|
888
|
-
name: "brave",
|
|
889
|
-
displayName: "Brave Search",
|
|
890
|
-
description: "Brave web search API kept as an optional provider.",
|
|
891
|
-
supportsSummary: false
|
|
892
|
-
}];
|
|
893
1134
|
function matchesExtraSensitivePath(path) {
|
|
894
1135
|
if (path === "session" || path.startsWith("session.")) return false;
|
|
895
1136
|
return EXTRA_SENSITIVE_PATH_PATTERNS.some((pattern) => pattern.test(path));
|
|
@@ -1106,31 +1347,6 @@ function buildConfigView(config, options) {
|
|
|
1106
1347
|
}
|
|
1107
1348
|
};
|
|
1108
1349
|
}
|
|
1109
|
-
function toSearchProviderView(config, providerName, provider) {
|
|
1110
|
-
const apiKeyRefSet = hasSecretRef(config, `search.providers.${providerName}.apiKey`);
|
|
1111
|
-
const masked = maskApiKey(provider.apiKey);
|
|
1112
|
-
const base = {
|
|
1113
|
-
enabled: config.search.enabledProviders.includes(providerName),
|
|
1114
|
-
apiKeySet: masked.apiKeySet || apiKeyRefSet,
|
|
1115
|
-
apiKeyMasked: masked.apiKeyMasked ?? (apiKeyRefSet ? "****" : void 0),
|
|
1116
|
-
baseUrl: provider.baseUrl
|
|
1117
|
-
};
|
|
1118
|
-
if ("docsUrl" in provider) base.docsUrl = provider.docsUrl;
|
|
1119
|
-
if ("summary" in provider) base.summary = provider.summary;
|
|
1120
|
-
if ("freshness" in provider) base.freshness = provider.freshness;
|
|
1121
|
-
return base;
|
|
1122
|
-
}
|
|
1123
|
-
function buildSearchView(config) {
|
|
1124
|
-
return {
|
|
1125
|
-
provider: config.search.provider,
|
|
1126
|
-
enabledProviders: [...config.search.enabledProviders],
|
|
1127
|
-
defaults: { maxResults: config.search.defaults.maxResults },
|
|
1128
|
-
providers: {
|
|
1129
|
-
bocha: toSearchProviderView(config, "bocha", config.search.providers.bocha),
|
|
1130
|
-
brave: toSearchProviderView(config, "brave", config.search.providers.brave)
|
|
1131
|
-
}
|
|
1132
|
-
};
|
|
1133
|
-
}
|
|
1134
1350
|
function clearSecretRef(config, path) {
|
|
1135
1351
|
if (config.secrets.refs[path]) delete config.secrets.refs[path];
|
|
1136
1352
|
}
|
|
@@ -1266,41 +1482,6 @@ function updateModel(configPath, patch) {
|
|
|
1266
1482
|
saveConfig(next, configPath);
|
|
1267
1483
|
return buildConfigView(next);
|
|
1268
1484
|
}
|
|
1269
|
-
function updateSearch(configPath, patch) {
|
|
1270
|
-
const config = loadConfigOrDefault(configPath);
|
|
1271
|
-
if (patch.provider === "bocha" || patch.provider === "brave") config.search.provider = patch.provider;
|
|
1272
|
-
if (Array.isArray(patch.enabledProviders)) config.search.enabledProviders = Array.from(new Set(patch.enabledProviders.filter((value) => value === "bocha" || value === "brave")));
|
|
1273
|
-
if (patch.defaults && Object.prototype.hasOwnProperty.call(patch.defaults, "maxResults")) {
|
|
1274
|
-
const nextMaxResults = patch.defaults.maxResults;
|
|
1275
|
-
if (typeof nextMaxResults === "number" && Number.isFinite(nextMaxResults)) config.search.defaults.maxResults = Math.max(1, Math.min(50, Math.trunc(nextMaxResults)));
|
|
1276
|
-
}
|
|
1277
|
-
const bochaPatch = patch.providers?.bocha;
|
|
1278
|
-
if (bochaPatch) {
|
|
1279
|
-
if (Object.prototype.hasOwnProperty.call(bochaPatch, "apiKey")) {
|
|
1280
|
-
config.search.providers.bocha.apiKey = bochaPatch.apiKey ?? "";
|
|
1281
|
-
clearSecretRef(config, "search.providers.bocha.apiKey");
|
|
1282
|
-
}
|
|
1283
|
-
if (Object.prototype.hasOwnProperty.call(bochaPatch, "baseUrl")) config.search.providers.bocha.baseUrl = normalizeOptionalString(bochaPatch.baseUrl) ?? "https://api.bocha.cn/v1/web-search";
|
|
1284
|
-
if (Object.prototype.hasOwnProperty.call(bochaPatch, "docsUrl")) config.search.providers.bocha.docsUrl = normalizeOptionalString(bochaPatch.docsUrl) ?? BOCHA_OPEN_URL;
|
|
1285
|
-
if (Object.prototype.hasOwnProperty.call(bochaPatch, "summary")) config.search.providers.bocha.summary = Boolean(bochaPatch.summary);
|
|
1286
|
-
if (Object.prototype.hasOwnProperty.call(bochaPatch, "freshness")) {
|
|
1287
|
-
const freshness = normalizeOptionalString(bochaPatch.freshness);
|
|
1288
|
-
if (freshness === "noLimit" || freshness === "oneDay" || freshness === "oneWeek" || freshness === "oneMonth" || freshness === "oneYear") config.search.providers.bocha.freshness = freshness;
|
|
1289
|
-
else config.search.providers.bocha.freshness = "noLimit";
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
const bravePatch = patch.providers?.brave;
|
|
1293
|
-
if (bravePatch) {
|
|
1294
|
-
if (Object.prototype.hasOwnProperty.call(bravePatch, "apiKey")) {
|
|
1295
|
-
config.search.providers.brave.apiKey = bravePatch.apiKey ?? "";
|
|
1296
|
-
clearSecretRef(config, "search.providers.brave.apiKey");
|
|
1297
|
-
}
|
|
1298
|
-
if (Object.prototype.hasOwnProperty.call(bravePatch, "baseUrl")) config.search.providers.brave.baseUrl = normalizeOptionalString(bravePatch.baseUrl) ?? "https://api.search.brave.com/res/v1/web/search";
|
|
1299
|
-
}
|
|
1300
|
-
const next = ConfigSchema.parse(config);
|
|
1301
|
-
saveConfig(next, configPath);
|
|
1302
|
-
return buildSearchView(next);
|
|
1303
|
-
}
|
|
1304
1485
|
function updateProvider(configPath, providerName, patch) {
|
|
1305
1486
|
const config = loadConfigOrDefault(configPath);
|
|
1306
1487
|
const provider = ensureProviderConfig(config, providerName);
|
|
@@ -1495,13 +1676,14 @@ function createSessionManager(config) {
|
|
|
1495
1676
|
}
|
|
1496
1677
|
const DEFAULT_SESSION_TYPE = "native";
|
|
1497
1678
|
const SESSION_TYPE_METADATA_KEY = "session_type";
|
|
1679
|
+
const RUNTIME_METADATA_KEY = "runtime";
|
|
1498
1680
|
function normalizeSessionType(value) {
|
|
1499
1681
|
if (typeof value !== "string") return null;
|
|
1500
1682
|
const normalized = value.trim().toLowerCase();
|
|
1501
1683
|
return normalized.length > 0 ? normalized : null;
|
|
1502
1684
|
}
|
|
1503
1685
|
function readSessionType(session) {
|
|
1504
|
-
return normalizeSessionType(session.metadata[SESSION_TYPE_METADATA_KEY]) ?? "native";
|
|
1686
|
+
return normalizeSessionType(session.metadata[RUNTIME_METADATA_KEY]) ?? normalizeSessionType(session.metadata[SESSION_TYPE_METADATA_KEY]) ?? "native";
|
|
1505
1687
|
}
|
|
1506
1688
|
function countUserMessages(session) {
|
|
1507
1689
|
return session.messages.reduce((total, message) => {
|
|
@@ -1642,6 +1824,7 @@ function patchSession(configPath, key, patch, options) {
|
|
|
1642
1824
|
availableSessionTypes.add(DEFAULT_SESSION_TYPE);
|
|
1643
1825
|
if (!availableSessionTypes.has(normalizedSessionType)) throw new SessionPatchValidationError("SESSION_TYPE_UNAVAILABLE", `sessionType is unavailable: ${normalizedSessionType}`);
|
|
1644
1826
|
session.metadata[SESSION_TYPE_METADATA_KEY] = normalizedSessionType;
|
|
1827
|
+
session.metadata[RUNTIME_METADATA_KEY] = normalizedSessionType;
|
|
1645
1828
|
}
|
|
1646
1829
|
session.updatedAt = /* @__PURE__ */ new Date();
|
|
1647
1830
|
sessionManager.save(session);
|
|
@@ -2449,6 +2632,56 @@ function buildCronJobView(job) {
|
|
|
2449
2632
|
function findCronJob(service, id) {
|
|
2450
2633
|
return service.listJobs(true).find((job) => job.id === id) ?? null;
|
|
2451
2634
|
}
|
|
2635
|
+
function normalizeCronSchedule(schedule) {
|
|
2636
|
+
if (!schedule) return null;
|
|
2637
|
+
if (schedule.kind === "every") {
|
|
2638
|
+
if (typeof schedule.everyMs !== "number" || !Number.isFinite(schedule.everyMs) || schedule.everyMs <= 0) return null;
|
|
2639
|
+
return {
|
|
2640
|
+
kind: "every",
|
|
2641
|
+
everyMs: schedule.everyMs
|
|
2642
|
+
};
|
|
2643
|
+
}
|
|
2644
|
+
if (schedule.kind === "at") {
|
|
2645
|
+
if (typeof schedule.atMs !== "number" || !Number.isFinite(schedule.atMs)) return null;
|
|
2646
|
+
return {
|
|
2647
|
+
kind: "at",
|
|
2648
|
+
atMs: schedule.atMs
|
|
2649
|
+
};
|
|
2650
|
+
}
|
|
2651
|
+
if (schedule.kind === "cron") {
|
|
2652
|
+
const expr = readNonEmptyString(schedule.expr);
|
|
2653
|
+
if (!expr) return null;
|
|
2654
|
+
const tz = readNonEmptyString(schedule.tz);
|
|
2655
|
+
return tz ? {
|
|
2656
|
+
kind: "cron",
|
|
2657
|
+
expr,
|
|
2658
|
+
tz
|
|
2659
|
+
} : {
|
|
2660
|
+
kind: "cron",
|
|
2661
|
+
expr
|
|
2662
|
+
};
|
|
2663
|
+
}
|
|
2664
|
+
return null;
|
|
2665
|
+
}
|
|
2666
|
+
function readCronCreateParams(input) {
|
|
2667
|
+
const name = readNonEmptyString(input.name);
|
|
2668
|
+
if (!name) return { error: "name must be a non-empty string" };
|
|
2669
|
+
const message = readNonEmptyString(input.message);
|
|
2670
|
+
if (!message) return { error: "message must be a non-empty string" };
|
|
2671
|
+
const schedule = normalizeCronSchedule(input.schedule);
|
|
2672
|
+
if (!schedule) return { error: "schedule must be a valid at/every/cron definition" };
|
|
2673
|
+
return { params: {
|
|
2674
|
+
name,
|
|
2675
|
+
message,
|
|
2676
|
+
schedule,
|
|
2677
|
+
agentId: readNonEmptyString(input.agentId),
|
|
2678
|
+
deliver: input.deliver === true,
|
|
2679
|
+
channel: readNonEmptyString(input.channel),
|
|
2680
|
+
to: readNonEmptyString(input.to),
|
|
2681
|
+
accountId: readNonEmptyString(input.accountId),
|
|
2682
|
+
deleteAfterRun: input.deleteAfterRun === true
|
|
2683
|
+
} };
|
|
2684
|
+
}
|
|
2452
2685
|
var CronRoutesController = class {
|
|
2453
2686
|
constructor(options) {
|
|
2454
2687
|
this.options = options;
|
|
@@ -2463,6 +2696,15 @@ var CronRoutesController = class {
|
|
|
2463
2696
|
total: jobs.length
|
|
2464
2697
|
}));
|
|
2465
2698
|
};
|
|
2699
|
+
createJob = async (c) => {
|
|
2700
|
+
if (!this.options.cronService) return c.json(err("NOT_AVAILABLE", "cron service unavailable"), 503);
|
|
2701
|
+
const body = await readJson(c.req.raw);
|
|
2702
|
+
if (!body.ok) return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
2703
|
+
const normalized = readCronCreateParams(body.data);
|
|
2704
|
+
if ("error" in normalized) return c.json(err("INVALID_BODY", normalized.error), 400);
|
|
2705
|
+
const data = { job: buildCronJobView(this.options.cronService.addJob(normalized.params)) };
|
|
2706
|
+
return c.json(ok(data), 201);
|
|
2707
|
+
};
|
|
2466
2708
|
deleteJob = (c) => {
|
|
2467
2709
|
if (!this.options.cronService) return c.json(err("NOT_AVAILABLE", "cron service unavailable"), 503);
|
|
2468
2710
|
const id = decodeURIComponent(c.req.param("id"));
|
|
@@ -2738,9 +2980,11 @@ function applySessionTypePatch(metadata, patch) {
|
|
|
2738
2980
|
const sessionType = typeof patch.sessionType === "string" ? patch.sessionType.trim() : "";
|
|
2739
2981
|
if (sessionType) {
|
|
2740
2982
|
metadata.session_type = sessionType;
|
|
2983
|
+
metadata.runtime = sessionType;
|
|
2741
2984
|
delete metadata.sessionType;
|
|
2742
2985
|
return;
|
|
2743
2986
|
}
|
|
2987
|
+
delete metadata.runtime;
|
|
2744
2988
|
delete metadata.session_type;
|
|
2745
2989
|
delete metadata.sessionType;
|
|
2746
2990
|
}
|
|
@@ -4190,6 +4434,7 @@ function registerAuthRoutes(app, authController) {
|
|
|
4190
4434
|
function registerAgentRoutes(app, agentsController) {
|
|
4191
4435
|
app.get("/api/agents", agentsController.listAgents);
|
|
4192
4436
|
app.post("/api/agents", agentsController.createAgent);
|
|
4437
|
+
app.put("/api/agents/:agentId", agentsController.updateAgent);
|
|
4193
4438
|
app.delete("/api/agents/:agentId", agentsController.deleteAgent);
|
|
4194
4439
|
app.get("/api/agents/:agentId/avatar", agentsController.getAgentAvatar);
|
|
4195
4440
|
}
|
|
@@ -4237,6 +4482,7 @@ function registerNcpRuntimeRoutes(app, options, ncpAssetController) {
|
|
|
4237
4482
|
}
|
|
4238
4483
|
function registerCronRoutes(app, cronController) {
|
|
4239
4484
|
app.get("/api/cron", cronController.listJobs);
|
|
4485
|
+
app.post("/api/cron", cronController.createJob);
|
|
4240
4486
|
app.delete("/api/cron/:id", cronController.deleteJob);
|
|
4241
4487
|
app.put("/api/cron/:id/enable", cronController.enableJob);
|
|
4242
4488
|
app.post("/api/cron/:id/run", cronController.runJob);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/server",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Nextclaw UI/API server.",
|
|
6
6
|
"type": "module",
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
"@hono/node-server": "^1.13.3",
|
|
19
19
|
"hono": "^4.6.2",
|
|
20
20
|
"ws": "^8.18.0",
|
|
21
|
-
"@nextclaw/
|
|
22
|
-
"@nextclaw/
|
|
23
|
-
"@nextclaw/openclaw-compat": "1.0.1",
|
|
24
|
-
"@nextclaw/runtime": "0.2.33",
|
|
21
|
+
"@nextclaw/core": "0.12.2",
|
|
22
|
+
"@nextclaw/mcp": "0.1.67",
|
|
25
23
|
"@nextclaw/ncp": "0.5.0",
|
|
26
|
-
"@nextclaw/ncp-http-agent-server": "0.3.12"
|
|
24
|
+
"@nextclaw/ncp-http-agent-server": "0.3.12",
|
|
25
|
+
"@nextclaw/openclaw-compat": "1.0.2",
|
|
26
|
+
"@nextclaw/runtime": "0.2.34"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^20.17.6",
|