@nextclaw/server 0.6.8 → 0.6.9

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 CHANGED
@@ -54,6 +54,48 @@ type ProviderConnectionTestResult = {
54
54
  latencyMs: number;
55
55
  message: string;
56
56
  };
57
+ type SearchProviderName = "bocha" | "brave";
58
+ type BochaFreshnessValue = "noLimit" | "oneDay" | "oneWeek" | "oneMonth" | "oneYear" | string;
59
+ type SearchProviderConfigView = {
60
+ enabled: boolean;
61
+ apiKeySet: boolean;
62
+ apiKeyMasked?: string;
63
+ baseUrl: string;
64
+ docsUrl?: string;
65
+ summary?: boolean;
66
+ freshness?: BochaFreshnessValue;
67
+ };
68
+ type SearchConfigView = {
69
+ provider: SearchProviderName;
70
+ enabledProviders: SearchProviderName[];
71
+ defaults: {
72
+ maxResults: number;
73
+ };
74
+ providers: {
75
+ bocha: SearchProviderConfigView;
76
+ brave: SearchProviderConfigView;
77
+ };
78
+ };
79
+ type SearchConfigUpdate = {
80
+ provider?: SearchProviderName;
81
+ enabledProviders?: SearchProviderName[];
82
+ defaults?: {
83
+ maxResults?: number;
84
+ };
85
+ providers?: {
86
+ bocha?: {
87
+ apiKey?: string | null;
88
+ baseUrl?: string | null;
89
+ docsUrl?: string | null;
90
+ summary?: boolean;
91
+ freshness?: BochaFreshnessValue | null;
92
+ };
93
+ brave?: {
94
+ apiKey?: string | null;
95
+ baseUrl?: string | null;
96
+ };
97
+ };
98
+ };
57
99
  type ProviderAuthStartResult = {
58
100
  provider: string;
59
101
  kind: "device_code";
@@ -405,6 +447,7 @@ type ConfigView = {
405
447
  };
406
448
  };
407
449
  providers: Record<string, ProviderConfigView>;
450
+ search: SearchConfigView;
408
451
  channels: Record<string, Record<string, unknown>>;
409
452
  bindings?: AgentBindingView[];
410
453
  session?: SessionConfigView;
@@ -465,8 +508,17 @@ type ChannelSpecView = {
465
508
  zh?: string;
466
509
  };
467
510
  };
511
+ type SearchProviderSpecView = {
512
+ name: SearchProviderName;
513
+ displayName: string;
514
+ description: string;
515
+ docsUrl?: string;
516
+ isDefault?: boolean;
517
+ supportsSummary?: boolean;
518
+ };
468
519
  type ConfigMetaView = {
469
520
  providers: ProviderSpecView[];
521
+ search: SearchProviderSpecView[];
470
522
  channels: ChannelSpecView[];
471
523
  };
472
524
  type ConfigUiHint = {
@@ -787,6 +839,7 @@ declare function loadConfigOrDefault(configPath: string): Config;
787
839
  declare function updateModel(configPath: string, patch: {
788
840
  model?: string;
789
841
  }): ConfigView;
842
+ declare function updateSearch(configPath: string, patch: SearchConfigUpdate): ConfigView["search"];
790
843
  declare function updateProvider(configPath: string, providerName: string, patch: ProviderConfigUpdate): ProviderConfigView | null;
791
844
  declare function createCustomProvider(configPath: string, patch?: ProviderConfigUpdate): {
792
845
  name: string;
@@ -813,4 +866,4 @@ declare function deleteSession(configPath: string, key: string): boolean;
813
866
  declare function updateRuntime(configPath: string, patch: RuntimeConfigUpdate): Pick<ConfigView, "agents" | "bindings" | "session">;
814
867
  declare function updateSecrets(configPath: string, patch: SecretsConfigUpdate): SecretsView;
815
868
 
816
- export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type AppMetaView, type BindingPeerView, type ChannelSpecView, type ChatCapabilitiesView, type ChatCommandOptionView, type ChatCommandView, type ChatCommandsView, type ChatRunListView, type ChatRunState, type ChatRunView, type ChatSessionTypeOptionView, type ChatSessionTypesView, type ChatTurnRequest, type ChatTurnResult, type ChatTurnStopRequest, type ChatTurnStopResult, type ChatTurnStreamEvent, type ChatTurnView, type ConfigActionExecuteRequest, type ConfigActionExecuteResult, type ConfigActionManifest, type ConfigActionType, type ConfigMetaView, type ConfigSchemaResponse, type ConfigUiHint, type ConfigUiHints, type ConfigView, type CronActionResult, type CronEnableRequest, type CronJobStateView, type CronJobView, type CronListView, type CronPayloadView, type CronRunRequest, type CronScheduleView, DEFAULT_SESSION_TYPE, type MarketplaceApiConfig, type MarketplaceInstallKind, type MarketplaceInstallSkillParams, type MarketplaceInstallSpec, type MarketplaceInstalledRecord, type MarketplaceInstalledView, type MarketplaceInstaller, type MarketplaceItemSummary, type MarketplaceItemType, type MarketplaceItemView, type MarketplaceListView, type MarketplaceLocalizedTextMap, type MarketplacePluginContentView, type MarketplacePluginInstallKind, type MarketplacePluginInstallRequest, type MarketplacePluginInstallResult, type MarketplacePluginManageAction, type MarketplacePluginManageRequest, type MarketplacePluginManageResult, type MarketplaceRecommendationView, type MarketplaceSkillContentView, type MarketplaceSkillInstallKind, type MarketplaceSkillInstallRequest, type MarketplaceSkillInstallResult, type MarketplaceSkillManageAction, type MarketplaceSkillManageRequest, type MarketplaceSkillManageResult, type MarketplaceSort, type ProviderAuthImportResult, type ProviderAuthPollRequest, type ProviderAuthPollResult, type ProviderAuthStartRequest, type ProviderAuthStartResult, type ProviderConfigUpdate, type ProviderConfigView, type ProviderConnectionTestRequest, type ProviderConnectionTestResult, type ProviderCreateRequest, type ProviderCreateResult, type ProviderDeleteResult, type ProviderSpecView, type RuntimeConfigUpdate, type SecretProviderEnvView, type SecretProviderExecView, type SecretProviderFileView, type SecretProviderView, type SecretRefView, type SecretSourceView, type SecretsConfigUpdate, type SecretsView, type SessionConfigView, type SessionEntryView, type SessionEventView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, SessionPatchValidationError, type SessionsListView, type UiChatRuntime, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createCustomProvider, createUiRouter, deleteCustomProvider, deleteSession, executeConfigAction, getSessionHistory, listSessions, loadConfigOrDefault, patchSession, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSecrets };
869
+ export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type AppMetaView, type BindingPeerView, type BochaFreshnessValue, type ChannelSpecView, type ChatCapabilitiesView, type ChatCommandOptionView, type ChatCommandView, type ChatCommandsView, type ChatRunListView, type ChatRunState, type ChatRunView, type ChatSessionTypeOptionView, type ChatSessionTypesView, type ChatTurnRequest, type ChatTurnResult, type ChatTurnStopRequest, type ChatTurnStopResult, type ChatTurnStreamEvent, type ChatTurnView, type ConfigActionExecuteRequest, type ConfigActionExecuteResult, type ConfigActionManifest, type ConfigActionType, type ConfigMetaView, type ConfigSchemaResponse, type ConfigUiHint, type ConfigUiHints, type ConfigView, type CronActionResult, type CronEnableRequest, type CronJobStateView, type CronJobView, type CronListView, type CronPayloadView, type CronRunRequest, type CronScheduleView, DEFAULT_SESSION_TYPE, type MarketplaceApiConfig, type MarketplaceInstallKind, type MarketplaceInstallSkillParams, type MarketplaceInstallSpec, type MarketplaceInstalledRecord, type MarketplaceInstalledView, type MarketplaceInstaller, type MarketplaceItemSummary, type MarketplaceItemType, type MarketplaceItemView, type MarketplaceListView, type MarketplaceLocalizedTextMap, type MarketplacePluginContentView, type MarketplacePluginInstallKind, type MarketplacePluginInstallRequest, type MarketplacePluginInstallResult, type MarketplacePluginManageAction, type MarketplacePluginManageRequest, type MarketplacePluginManageResult, type MarketplaceRecommendationView, type MarketplaceSkillContentView, type MarketplaceSkillInstallKind, type MarketplaceSkillInstallRequest, type MarketplaceSkillInstallResult, type MarketplaceSkillManageAction, type MarketplaceSkillManageRequest, type MarketplaceSkillManageResult, type MarketplaceSort, type ProviderAuthImportResult, type ProviderAuthPollRequest, type ProviderAuthPollResult, type ProviderAuthStartRequest, type ProviderAuthStartResult, type ProviderConfigUpdate, type ProviderConfigView, type ProviderConnectionTestRequest, type ProviderConnectionTestResult, type ProviderCreateRequest, type ProviderCreateResult, type ProviderDeleteResult, type ProviderSpecView, type RuntimeConfigUpdate, type SearchConfigUpdate, type SearchConfigView, type SearchProviderConfigView, type SearchProviderName, type SearchProviderSpecView, type SecretProviderEnvView, type SecretProviderExecView, type SecretProviderFileView, type SecretProviderView, type SecretRefView, type SecretSourceView, type SecretsConfigUpdate, type SecretsView, type SessionConfigView, type SessionEntryView, type SessionEventView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, SessionPatchValidationError, type SessionsListView, type UiChatRuntime, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createCustomProvider, createUiRouter, deleteCustomProvider, deleteSession, executeConfigAction, getSessionHistory, listSessions, loadConfigOrDefault, patchSession, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSearch, updateSecrets };
package/dist/index.js CHANGED
@@ -212,6 +212,7 @@ function clearSecretRefsByPrefix(config, pathPrefix) {
212
212
  }
213
213
  }
214
214
  var DOCS_BASE_URL = "https://docs.nextclaw.io";
215
+ var BOCHA_OPEN_URL = "https://open.bocha.cn";
215
216
  var CHANNEL_TUTORIAL_URLS = {
216
217
  feishu: {
217
218
  default: `${DOCS_BASE_URL}/guide/tutorials/feishu`,
@@ -219,6 +220,22 @@ var CHANNEL_TUTORIAL_URLS = {
219
220
  zh: `${DOCS_BASE_URL}/zh/guide/tutorials/feishu`
220
221
  }
221
222
  };
223
+ var SEARCH_PROVIDER_META = [
224
+ {
225
+ name: "bocha",
226
+ displayName: "Bocha Search",
227
+ description: "China-friendly web search with AI-ready summaries.",
228
+ docsUrl: BOCHA_OPEN_URL,
229
+ isDefault: true,
230
+ supportsSummary: true
231
+ },
232
+ {
233
+ name: "brave",
234
+ displayName: "Brave Search",
235
+ description: "Brave web search API kept as an optional provider.",
236
+ supportsSummary: false
237
+ }
238
+ ];
222
239
  function matchesExtraSensitivePath(path) {
223
240
  if (path === "session" || path.startsWith("session.")) {
224
241
  return false;
@@ -470,6 +487,7 @@ function buildConfigView(config) {
470
487
  return {
471
488
  agents: config.agents,
472
489
  providers,
490
+ search: buildSearchView(config),
473
491
  channels: sanitizePublicConfigValue(
474
492
  config.channels,
475
493
  "channels",
@@ -488,6 +506,40 @@ function buildConfigView(config) {
488
506
  }
489
507
  };
490
508
  }
509
+ function toSearchProviderView(config, providerName, provider) {
510
+ const apiKeyPath = `search.providers.${providerName}.apiKey`;
511
+ const apiKeyRefSet = hasSecretRef(config, apiKeyPath);
512
+ const masked = maskApiKey(provider.apiKey);
513
+ const base = {
514
+ enabled: config.search.enabledProviders.includes(providerName),
515
+ apiKeySet: masked.apiKeySet || apiKeyRefSet,
516
+ apiKeyMasked: masked.apiKeyMasked ?? (apiKeyRefSet ? "****" : void 0),
517
+ baseUrl: provider.baseUrl
518
+ };
519
+ if ("docsUrl" in provider) {
520
+ base.docsUrl = provider.docsUrl;
521
+ }
522
+ if ("summary" in provider) {
523
+ base.summary = provider.summary;
524
+ }
525
+ if ("freshness" in provider) {
526
+ base.freshness = provider.freshness;
527
+ }
528
+ return base;
529
+ }
530
+ function buildSearchView(config) {
531
+ return {
532
+ provider: config.search.provider,
533
+ enabledProviders: [...config.search.enabledProviders],
534
+ defaults: {
535
+ maxResults: config.search.defaults.maxResults
536
+ },
537
+ providers: {
538
+ bocha: toSearchProviderView(config, "bocha", config.search.providers.bocha),
539
+ brave: toSearchProviderView(config, "brave", config.search.providers.brave)
540
+ }
541
+ };
542
+ }
491
543
  function clearSecretRef(config, path) {
492
544
  if (config.secrets.refs[path]) {
493
545
  delete config.secrets.refs[path];
@@ -574,7 +626,7 @@ function buildConfigMeta(config) {
574
626
  tutorialUrls
575
627
  };
576
628
  });
577
- return { providers, channels };
629
+ return { providers, search: SEARCH_PROVIDER_META, channels };
578
630
  }
579
631
  function buildConfigSchemaView(_config) {
580
632
  return buildConfigSchema({ version: getPackageVersion() });
@@ -643,6 +695,60 @@ function updateModel(configPath, patch) {
643
695
  saveConfig(next, configPath);
644
696
  return buildConfigView(next);
645
697
  }
698
+ function updateSearch(configPath, patch) {
699
+ const config = loadConfigOrDefault(configPath);
700
+ if (patch.provider === "bocha" || patch.provider === "brave") {
701
+ config.search.provider = patch.provider;
702
+ }
703
+ if (Array.isArray(patch.enabledProviders)) {
704
+ config.search.enabledProviders = Array.from(new Set(
705
+ patch.enabledProviders.filter((value) => value === "bocha" || value === "brave")
706
+ ));
707
+ }
708
+ if (patch.defaults && Object.prototype.hasOwnProperty.call(patch.defaults, "maxResults")) {
709
+ const nextMaxResults = patch.defaults.maxResults;
710
+ if (typeof nextMaxResults === "number" && Number.isFinite(nextMaxResults)) {
711
+ config.search.defaults.maxResults = Math.max(1, Math.min(50, Math.trunc(nextMaxResults)));
712
+ }
713
+ }
714
+ const bochaPatch = patch.providers?.bocha;
715
+ if (bochaPatch) {
716
+ if (Object.prototype.hasOwnProperty.call(bochaPatch, "apiKey")) {
717
+ config.search.providers.bocha.apiKey = bochaPatch.apiKey ?? "";
718
+ clearSecretRef(config, "search.providers.bocha.apiKey");
719
+ }
720
+ if (Object.prototype.hasOwnProperty.call(bochaPatch, "baseUrl")) {
721
+ config.search.providers.bocha.baseUrl = normalizeOptionalString(bochaPatch.baseUrl) ?? "https://api.bocha.cn/v1/web-search";
722
+ }
723
+ if (Object.prototype.hasOwnProperty.call(bochaPatch, "docsUrl")) {
724
+ config.search.providers.bocha.docsUrl = normalizeOptionalString(bochaPatch.docsUrl) ?? BOCHA_OPEN_URL;
725
+ }
726
+ if (Object.prototype.hasOwnProperty.call(bochaPatch, "summary")) {
727
+ config.search.providers.bocha.summary = Boolean(bochaPatch.summary);
728
+ }
729
+ if (Object.prototype.hasOwnProperty.call(bochaPatch, "freshness")) {
730
+ const freshness = normalizeOptionalString(bochaPatch.freshness);
731
+ if (freshness === "noLimit" || freshness === "oneDay" || freshness === "oneWeek" || freshness === "oneMonth" || freshness === "oneYear") {
732
+ config.search.providers.bocha.freshness = freshness;
733
+ } else {
734
+ config.search.providers.bocha.freshness = "noLimit";
735
+ }
736
+ }
737
+ }
738
+ const bravePatch = patch.providers?.brave;
739
+ if (bravePatch) {
740
+ if (Object.prototype.hasOwnProperty.call(bravePatch, "apiKey")) {
741
+ config.search.providers.brave.apiKey = bravePatch.apiKey ?? "";
742
+ clearSecretRef(config, "search.providers.brave.apiKey");
743
+ }
744
+ if (Object.prototype.hasOwnProperty.call(bravePatch, "baseUrl")) {
745
+ config.search.providers.brave.baseUrl = normalizeOptionalString(bravePatch.baseUrl) ?? "https://api.search.brave.com/res/v1/web/search";
746
+ }
747
+ }
748
+ const next = ConfigSchema.parse(config);
749
+ saveConfig(next, configPath);
750
+ return buildSearchView(next);
751
+ }
646
752
  function updateProvider(configPath, providerName, patch) {
647
753
  const config = loadConfigOrDefault(configPath);
648
754
  const provider = ensureProviderConfig(config, providerName);
@@ -3026,6 +3132,15 @@ function createUiRouter(options) {
3026
3132
  model: view.agents.defaults.model
3027
3133
  }));
3028
3134
  });
3135
+ app.put("/api/config/search", async (c) => {
3136
+ const body = await readJson(c.req.raw);
3137
+ if (!body.ok) {
3138
+ return c.json(err("INVALID_BODY", "invalid json body"), 400);
3139
+ }
3140
+ const result = updateSearch(options.configPath, body.data);
3141
+ options.publish({ type: "config.updated", payload: { path: "search" } });
3142
+ return c.json(ok(result));
3143
+ });
3029
3144
  app.put("/api/config/providers/:provider", async (c) => {
3030
3145
  const provider = c.req.param("provider");
3031
3146
  const body = await readJson(c.req.raw);
@@ -3906,5 +4021,6 @@ export {
3906
4021
  updateModel,
3907
4022
  updateProvider,
3908
4023
  updateRuntime,
4024
+ updateSearch,
3909
4025
  updateSecrets
3910
4026
  };
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@nextclaw/server",
3
- "version": "0.6.8",
3
+ "version": "0.6.9",
4
4
  "private": false,
5
5
  "description": "Nextclaw UI/API server.",
6
6
  "type": "module",
7
7
  "exports": {
8
8
  ".": {
9
+ "development": "./src/index.ts",
9
10
  "types": "./dist/index.d.ts",
10
11
  "default": "./dist/index.js"
11
12
  }
@@ -17,9 +18,9 @@
17
18
  "@hono/node-server": "^1.13.3",
18
19
  "hono": "^4.6.2",
19
20
  "ws": "^8.18.0",
20
- "@nextclaw/openclaw-compat": "0.2.3",
21
- "@nextclaw/core": "0.7.4",
22
- "@nextclaw/runtime": "0.1.3"
21
+ "@nextclaw/openclaw-compat": "0.2.4",
22
+ "@nextclaw/core": "0.7.5",
23
+ "@nextclaw/runtime": "0.1.4"
23
24
  },
24
25
  "devDependencies": {
25
26
  "@types/node": "^20.17.6",