@nextclaw/server 0.5.16 → 0.5.18

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
@@ -70,10 +70,12 @@ type SessionsListView = {
70
70
  };
71
71
  type SessionMessageView = {
72
72
  role: string;
73
- content: string;
73
+ content: unknown;
74
74
  timestamp: string;
75
75
  name?: string;
76
76
  tool_call_id?: string;
77
+ tool_calls?: Array<Record<string, unknown>>;
78
+ reasoning_content?: string;
77
79
  };
78
80
  type SessionHistoryView = {
79
81
  key: string;
@@ -145,6 +147,49 @@ type RuntimeConfigUpdate = {
145
147
  bindings?: AgentBindingView[];
146
148
  session?: SessionConfigView;
147
149
  };
150
+ type SecretSourceView = "env" | "file" | "exec";
151
+ type SecretRefView = {
152
+ source: SecretSourceView;
153
+ provider?: string;
154
+ id: string;
155
+ };
156
+ type SecretProviderEnvView = {
157
+ source: "env";
158
+ prefix?: string;
159
+ };
160
+ type SecretProviderFileView = {
161
+ source: "file";
162
+ path: string;
163
+ format?: "json";
164
+ };
165
+ type SecretProviderExecView = {
166
+ source: "exec";
167
+ command: string;
168
+ args?: string[];
169
+ cwd?: string;
170
+ timeoutMs?: number;
171
+ };
172
+ type SecretProviderView = SecretProviderEnvView | SecretProviderFileView | SecretProviderExecView;
173
+ type SecretsView = {
174
+ enabled: boolean;
175
+ defaults: {
176
+ env?: string;
177
+ file?: string;
178
+ exec?: string;
179
+ };
180
+ providers: Record<string, SecretProviderView>;
181
+ refs: Record<string, SecretRefView>;
182
+ };
183
+ type SecretsConfigUpdate = {
184
+ enabled?: boolean;
185
+ defaults?: {
186
+ env?: string | null;
187
+ file?: string | null;
188
+ exec?: string | null;
189
+ };
190
+ providers?: Record<string, SecretProviderView> | null;
191
+ refs?: Record<string, SecretRefView> | null;
192
+ };
148
193
  type ChatTurnRequest = {
149
194
  message: string;
150
195
  sessionKey?: string;
@@ -204,6 +249,7 @@ type ConfigView = {
204
249
  tools?: Record<string, unknown>;
205
250
  gateway?: Record<string, unknown>;
206
251
  ui?: Record<string, unknown>;
252
+ secrets?: SecretsView;
207
253
  };
208
254
  type ProviderSpecView = {
209
255
  name: string;
@@ -520,5 +566,6 @@ declare function getSessionHistory(configPath: string, key: string, limit?: numb
520
566
  declare function patchSession(configPath: string, key: string, patch: SessionPatchUpdate): SessionHistoryView | null;
521
567
  declare function deleteSession(configPath: string, key: string): boolean;
522
568
  declare function updateRuntime(configPath: string, patch: RuntimeConfigUpdate): Pick<ConfigView, "agents" | "bindings" | "session">;
569
+ declare function updateSecrets(configPath: string, patch: SecretsConfigUpdate): SecretsView;
523
570
 
524
- export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type BindingPeerView, type ChannelSpecView, type ChatTurnRequest, type ChatTurnResult, 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, type MarketplaceApiConfig, type MarketplaceInstallKind, type MarketplaceInstallSkillParams, type MarketplaceInstallSpec, type MarketplaceInstalledRecord, type MarketplaceInstalledView, type MarketplaceInstaller, type MarketplaceItemSummary, type MarketplaceItemType, type MarketplaceItemView, type MarketplaceListView, type MarketplacePluginInstallRequest, type MarketplacePluginInstallResult, type MarketplacePluginManageAction, type MarketplacePluginManageRequest, type MarketplacePluginManageResult, type MarketplaceRecommendationView, type MarketplaceSkillInstallRequest, type MarketplaceSkillInstallResult, type MarketplaceSkillManageAction, type MarketplaceSkillManageRequest, type MarketplaceSkillManageResult, type MarketplaceSort, type ProviderConfigUpdate, type ProviderConfigView, type ProviderSpecView, type RuntimeConfigUpdate, type SessionConfigView, type SessionEntryView, type SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, type SessionsListView, type UiChatRuntime, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createUiRouter, deleteSession, executeConfigAction, getSessionHistory, listSessions, loadConfigOrDefault, patchSession, startUiServer, updateChannel, updateModel, updateProvider, updateRuntime };
571
+ export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type BindingPeerView, type ChannelSpecView, type ChatTurnRequest, type ChatTurnResult, 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, type MarketplaceApiConfig, type MarketplaceInstallKind, type MarketplaceInstallSkillParams, type MarketplaceInstallSpec, type MarketplaceInstalledRecord, type MarketplaceInstalledView, type MarketplaceInstaller, type MarketplaceItemSummary, type MarketplaceItemType, type MarketplaceItemView, type MarketplaceListView, type MarketplacePluginInstallRequest, type MarketplacePluginInstallResult, type MarketplacePluginManageAction, type MarketplacePluginManageRequest, type MarketplacePluginManageResult, type MarketplaceRecommendationView, type MarketplaceSkillInstallRequest, type MarketplaceSkillInstallResult, type MarketplaceSkillManageAction, type MarketplaceSkillManageRequest, type MarketplaceSkillManageResult, type MarketplaceSort, type ProviderConfigUpdate, type ProviderConfigView, 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 SessionHistoryView, type SessionMessageView, type SessionPatchUpdate, type SessionsListView, type UiChatRuntime, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createUiRouter, deleteSession, executeConfigAction, getSessionHistory, listSessions, loadConfigOrDefault, patchSession, startUiServer, updateChannel, updateModel, updateProvider, updateRuntime, updateSecrets };
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ import {
23
23
  buildConfigSchema,
24
24
  findProviderByName,
25
25
  getPackageVersion,
26
+ hasSecretRef,
26
27
  isSensitiveConfigPath,
27
28
  SessionManager,
28
29
  getWorkspacePathFromConfig
@@ -230,7 +231,9 @@ function maskApiKey(value) {
230
231
  apiKeyMasked: `${value.slice(0, 2)}****${value.slice(-4)}`
231
232
  };
232
233
  }
233
- function toProviderView(provider, providerName, uiHints, spec) {
234
+ function toProviderView(config, provider, providerName, uiHints, spec) {
235
+ const apiKeyPath = `providers.${providerName}.apiKey`;
236
+ const apiKeyRefSet = hasSecretRef(config, apiKeyPath);
234
237
  const masked = maskApiKey(provider.apiKey);
235
238
  const extraHeaders = provider.extraHeaders && Object.keys(provider.extraHeaders).length > 0 ? sanitizePublicConfigValue(
236
239
  provider.extraHeaders,
@@ -238,8 +241,8 @@ function toProviderView(provider, providerName, uiHints, spec) {
238
241
  uiHints
239
242
  ) : null;
240
243
  const view = {
241
- apiKeySet: masked.apiKeySet,
242
- apiKeyMasked: masked.apiKeyMasked,
244
+ apiKeySet: masked.apiKeySet || apiKeyRefSet,
245
+ apiKeyMasked: masked.apiKeyMasked ?? (apiKeyRefSet ? "****" : void 0),
243
246
  apiBase: provider.apiBase ?? null,
244
247
  extraHeaders: extraHeaders && Object.keys(extraHeaders).length > 0 ? extraHeaders : null
245
248
  };
@@ -253,7 +256,7 @@ function buildConfigView(config) {
253
256
  const providers = {};
254
257
  for (const [name, provider] of Object.entries(config.providers)) {
255
258
  const spec = findProviderByName(name);
256
- providers[name] = toProviderView(provider, name, uiHints, spec);
259
+ providers[name] = toProviderView(config, provider, name, uiHints, spec);
257
260
  }
258
261
  return {
259
262
  agents: config.agents,
@@ -267,9 +270,20 @@ function buildConfigView(config) {
267
270
  session: sanitizePublicConfigValue(config.session, "session", uiHints),
268
271
  tools: sanitizePublicConfigValue(config.tools, "tools", uiHints),
269
272
  gateway: sanitizePublicConfigValue(config.gateway, "gateway", uiHints),
270
- ui: sanitizePublicConfigValue(config.ui, "ui", uiHints)
273
+ ui: sanitizePublicConfigValue(config.ui, "ui", uiHints),
274
+ secrets: {
275
+ enabled: config.secrets.enabled,
276
+ defaults: { ...config.secrets.defaults },
277
+ providers: { ...config.secrets.providers },
278
+ refs: { ...config.secrets.refs }
279
+ }
271
280
  };
272
281
  }
282
+ function clearSecretRef(config, path) {
283
+ if (config.secrets.refs[path]) {
284
+ delete config.secrets.refs[path];
285
+ }
286
+ }
273
287
  function buildConfigMeta(config) {
274
288
  const providers = PROVIDERS.map((spec) => ({
275
289
  name: spec.name,
@@ -369,6 +383,7 @@ function updateProvider(configPath, providerName, patch) {
369
383
  const spec = findProviderByName(providerName);
370
384
  if (Object.prototype.hasOwnProperty.call(patch, "apiKey")) {
371
385
  provider.apiKey = patch.apiKey ?? "";
386
+ clearSecretRef(config, `providers.${providerName}.apiKey`);
372
387
  }
373
388
  if (Object.prototype.hasOwnProperty.call(patch, "apiBase")) {
374
389
  provider.apiBase = patch.apiBase ?? null;
@@ -383,7 +398,7 @@ function updateProvider(configPath, providerName, patch) {
383
398
  saveConfig(next, configPath);
384
399
  const uiHints = buildUiHints(next);
385
400
  const updated = next.providers[providerName];
386
- return toProviderView(updated, providerName, uiHints, spec ?? void 0);
401
+ return toProviderView(next, updated, providerName, uiHints, spec ?? void 0);
387
402
  }
388
403
  function updateChannel(configPath, channelName, patch) {
389
404
  const config = loadConfigOrDefault(configPath);
@@ -391,6 +406,12 @@ function updateChannel(configPath, channelName, patch) {
391
406
  if (!channel) {
392
407
  return null;
393
408
  }
409
+ for (const key of Object.keys(patch)) {
410
+ const path = `channels.${channelName}.${key}`;
411
+ if (isSensitivePath(path)) {
412
+ clearSecretRef(config, path);
413
+ }
414
+ }
394
415
  config.channels[channelName] = { ...channel, ...patch };
395
416
  const next = ConfigSchema.parse(config);
396
417
  saveConfig(next, configPath);
@@ -485,6 +506,12 @@ function getSessionHistory(configPath, key, limit) {
485
506
  if (typeof message.tool_call_id === "string") {
486
507
  entry.tool_call_id = message.tool_call_id;
487
508
  }
509
+ if (Array.isArray(message.tool_calls)) {
510
+ entry.tool_calls = message.tool_calls;
511
+ }
512
+ if (typeof message.reasoning_content === "string") {
513
+ entry.reasoning_content = message.reasoning_content;
514
+ }
488
515
  return entry;
489
516
  })
490
517
  };
@@ -569,6 +596,41 @@ function updateRuntime(configPath, patch) {
569
596
  session: view.session ?? {}
570
597
  };
571
598
  }
599
+ function updateSecrets(configPath, patch) {
600
+ const config = loadConfigOrDefault(configPath);
601
+ if (Object.prototype.hasOwnProperty.call(patch, "enabled")) {
602
+ config.secrets.enabled = Boolean(patch.enabled);
603
+ }
604
+ if (patch.defaults) {
605
+ const nextDefaults = { ...config.secrets.defaults };
606
+ for (const source of ["env", "file", "exec"]) {
607
+ if (!Object.prototype.hasOwnProperty.call(patch.defaults, source)) {
608
+ continue;
609
+ }
610
+ const value = patch.defaults[source];
611
+ if (typeof value === "string" && value.trim()) {
612
+ nextDefaults[source] = value.trim();
613
+ } else {
614
+ delete nextDefaults[source];
615
+ }
616
+ }
617
+ config.secrets.defaults = nextDefaults;
618
+ }
619
+ if (Object.prototype.hasOwnProperty.call(patch, "providers")) {
620
+ config.secrets.providers = patch.providers ?? {};
621
+ }
622
+ if (Object.prototype.hasOwnProperty.call(patch, "refs")) {
623
+ config.secrets.refs = patch.refs ?? {};
624
+ }
625
+ const next = ConfigSchema.parse(config);
626
+ saveConfig(next, configPath);
627
+ return {
628
+ enabled: next.secrets.enabled,
629
+ defaults: { ...next.secrets.defaults },
630
+ providers: { ...next.secrets.providers },
631
+ refs: { ...next.secrets.refs }
632
+ };
633
+ }
572
634
 
573
635
  // src/ui/router.ts
574
636
  var DEFAULT_MARKETPLACE_API_BASE = "https://marketplace-api.nextclaw.io";
@@ -1500,6 +1562,15 @@ function createUiRouter(options) {
1500
1562
  options.publish({ type: "config.updated", payload: { path: `channels.${channel}` } });
1501
1563
  return c.json(ok(result));
1502
1564
  });
1565
+ app.put("/api/config/secrets", async (c) => {
1566
+ const body = await readJson(c.req.raw);
1567
+ if (!body.ok) {
1568
+ return c.json(err("INVALID_BODY", "invalid json body"), 400);
1569
+ }
1570
+ const result = updateSecrets(options.configPath, body.data);
1571
+ options.publish({ type: "config.updated", payload: { path: "secrets" } });
1572
+ return c.json(ok(result));
1573
+ });
1503
1574
  app.post("/api/chat/turn", async (c) => {
1504
1575
  if (!options.chatRuntime) {
1505
1576
  return c.json(err("NOT_AVAILABLE", "chat runtime unavailable"), 503);
@@ -1785,5 +1856,6 @@ export {
1785
1856
  updateChannel,
1786
1857
  updateModel,
1787
1858
  updateProvider,
1788
- updateRuntime
1859
+ updateRuntime,
1860
+ updateSecrets
1789
1861
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/server",
3
- "version": "0.5.16",
3
+ "version": "0.5.18",
4
4
  "private": false,
5
5
  "description": "Nextclaw UI/API server.",
6
6
  "type": "module",
@@ -18,7 +18,7 @@
18
18
  "@nextclaw/openclaw-compat": "^0.1.28",
19
19
  "hono": "^4.6.2",
20
20
  "ws": "^8.18.0",
21
- "@nextclaw/core": "^0.6.34"
21
+ "@nextclaw/core": "^0.6.35"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/node": "^20.17.6",