@nextclaw/server 0.5.26 → 0.5.27
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 +18 -1
- package/dist/index.js +197 -22
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ type ApiResponse<T> = {
|
|
|
15
15
|
error: ApiError;
|
|
16
16
|
};
|
|
17
17
|
type ProviderConfigView = {
|
|
18
|
+
displayName?: string;
|
|
18
19
|
apiKeySet: boolean;
|
|
19
20
|
apiKeyMasked?: string;
|
|
20
21
|
apiBase?: string | null;
|
|
@@ -23,6 +24,7 @@ type ProviderConfigView = {
|
|
|
23
24
|
models?: string[];
|
|
24
25
|
};
|
|
25
26
|
type ProviderConfigUpdate = {
|
|
27
|
+
displayName?: string | null;
|
|
26
28
|
apiKey?: string | null;
|
|
27
29
|
apiBase?: string | null;
|
|
28
30
|
extraHeaders?: Record<string, string> | null;
|
|
@@ -32,6 +34,15 @@ type ProviderConfigUpdate = {
|
|
|
32
34
|
type ProviderConnectionTestRequest = ProviderConfigUpdate & {
|
|
33
35
|
model?: string | null;
|
|
34
36
|
};
|
|
37
|
+
type ProviderCreateRequest = ProviderConfigUpdate;
|
|
38
|
+
type ProviderCreateResult = {
|
|
39
|
+
name: string;
|
|
40
|
+
provider: ProviderConfigView;
|
|
41
|
+
};
|
|
42
|
+
type ProviderDeleteResult = {
|
|
43
|
+
deleted: boolean;
|
|
44
|
+
provider: string;
|
|
45
|
+
};
|
|
35
46
|
type ProviderConnectionTestResult = {
|
|
36
47
|
success: boolean;
|
|
37
48
|
provider: string;
|
|
@@ -288,6 +299,7 @@ type ConfigView = {
|
|
|
288
299
|
type ProviderSpecView = {
|
|
289
300
|
name: string;
|
|
290
301
|
displayName?: string;
|
|
302
|
+
isCustom?: boolean;
|
|
291
303
|
modelPrefix?: string;
|
|
292
304
|
keywords: string[];
|
|
293
305
|
envKey: string;
|
|
@@ -622,6 +634,11 @@ declare function updateModel(configPath: string, patch: {
|
|
|
622
634
|
maxTokens?: number;
|
|
623
635
|
}): ConfigView;
|
|
624
636
|
declare function updateProvider(configPath: string, providerName: string, patch: ProviderConfigUpdate): ProviderConfigView | null;
|
|
637
|
+
declare function createCustomProvider(configPath: string, patch?: ProviderConfigUpdate): {
|
|
638
|
+
name: string;
|
|
639
|
+
provider: ProviderConfigView;
|
|
640
|
+
};
|
|
641
|
+
declare function deleteCustomProvider(configPath: string, providerName: string): boolean | null;
|
|
625
642
|
declare function testProviderConnection(configPath: string, providerName: string, patch: ProviderConnectionTestRequest): Promise<ProviderConnectionTestResult | null>;
|
|
626
643
|
declare function updateChannel(configPath: string, channelName: string, patch: Record<string, unknown>): Record<string, unknown> | null;
|
|
627
644
|
declare function listSessions(configPath: string, query?: {
|
|
@@ -635,4 +652,4 @@ declare function deleteSession(configPath: string, key: string): boolean;
|
|
|
635
652
|
declare function updateRuntime(configPath: string, patch: RuntimeConfigUpdate): Pick<ConfigView, "agents" | "bindings" | "session">;
|
|
636
653
|
declare function updateSecrets(configPath: string, patch: SecretsConfigUpdate): SecretsView;
|
|
637
654
|
|
|
638
|
-
export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type BindingPeerView, type ChannelSpecView, type ChatTurnRequest, type ChatTurnResult, 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, 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 MarketplacePluginInstallRequest, type MarketplacePluginInstallResult, type MarketplacePluginManageAction, type MarketplacePluginManageRequest, type MarketplacePluginManageResult, type MarketplaceRecommendationView, type MarketplaceSkillContentView, type MarketplaceSkillInstallRequest, type MarketplaceSkillInstallResult, type MarketplaceSkillManageAction, type MarketplaceSkillManageRequest, type MarketplaceSkillManageResult, type MarketplaceSort, type ProviderConfigUpdate, type ProviderConfigView, type ProviderConnectionTestRequest, type ProviderConnectionTestResult, 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, type SessionsListView, type UiChatRuntime, type UiServerEvent, type UiServerHandle, type UiServerOptions, buildConfigMeta, buildConfigSchemaView, buildConfigView, createUiRouter, deleteSession, executeConfigAction, getSessionHistory, listSessions, loadConfigOrDefault, patchSession, startUiServer, testProviderConnection, updateChannel, updateModel, updateProvider, updateRuntime, updateSecrets };
|
|
655
|
+
export { type AgentBindingView, type AgentProfileView, type ApiError, type ApiResponse, type BindingPeerView, type ChannelSpecView, type ChatTurnRequest, type ChatTurnResult, 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, 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 MarketplacePluginInstallRequest, type MarketplacePluginInstallResult, type MarketplacePluginManageAction, type MarketplacePluginManageRequest, type MarketplacePluginManageResult, type MarketplaceRecommendationView, type MarketplaceSkillContentView, type MarketplaceSkillInstallRequest, type MarketplaceSkillInstallResult, type MarketplaceSkillManageAction, type MarketplaceSkillManageRequest, type MarketplaceSkillManageResult, type MarketplaceSort, 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, 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 };
|
package/dist/index.js
CHANGED
|
@@ -60,6 +60,53 @@ var PREFERRED_PROVIDER_ORDER = [
|
|
|
60
60
|
var PREFERRED_PROVIDER_ORDER_INDEX = new Map(
|
|
61
61
|
PREFERRED_PROVIDER_ORDER.map((name, index) => [name, index])
|
|
62
62
|
);
|
|
63
|
+
var BUILTIN_PROVIDER_NAMES = new Set(PROVIDERS.map((spec) => spec.name));
|
|
64
|
+
var CUSTOM_PROVIDER_WIRE_API_OPTIONS = ["auto", "chat", "responses"];
|
|
65
|
+
var CUSTOM_PROVIDER_PREFIX = "custom-";
|
|
66
|
+
function normalizeOptionalDisplayName(value) {
|
|
67
|
+
if (typeof value !== "string") {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const trimmed = value.trim();
|
|
71
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
72
|
+
}
|
|
73
|
+
function isCustomProviderName(name) {
|
|
74
|
+
return name.trim().length > 0 && !BUILTIN_PROVIDER_NAMES.has(name);
|
|
75
|
+
}
|
|
76
|
+
function resolveCustomProviderFallbackDisplayName(name) {
|
|
77
|
+
if (name.startsWith(CUSTOM_PROVIDER_PREFIX)) {
|
|
78
|
+
const suffix = name.slice(CUSTOM_PROVIDER_PREFIX.length);
|
|
79
|
+
if (/^\d+$/.test(suffix)) {
|
|
80
|
+
return `Custom ${suffix}`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return name;
|
|
84
|
+
}
|
|
85
|
+
function resolveProviderDisplayName(providerName, provider, spec) {
|
|
86
|
+
const configDisplayName = normalizeOptionalDisplayName(provider?.displayName);
|
|
87
|
+
if (isCustomProviderName(providerName)) {
|
|
88
|
+
return configDisplayName ?? resolveCustomProviderFallbackDisplayName(providerName);
|
|
89
|
+
}
|
|
90
|
+
return spec?.displayName ?? configDisplayName ?? spec?.name;
|
|
91
|
+
}
|
|
92
|
+
function listCustomProviderNames(config) {
|
|
93
|
+
return Object.keys(config.providers).filter((name) => isCustomProviderName(name));
|
|
94
|
+
}
|
|
95
|
+
function findNextCustomProviderName(config) {
|
|
96
|
+
const providers = config.providers;
|
|
97
|
+
let index = 1;
|
|
98
|
+
while (providers[`${CUSTOM_PROVIDER_PREFIX}${index}`]) {
|
|
99
|
+
index += 1;
|
|
100
|
+
}
|
|
101
|
+
return `${CUSTOM_PROVIDER_PREFIX}${index}`;
|
|
102
|
+
}
|
|
103
|
+
function clearSecretRefsByPrefix(config, pathPrefix) {
|
|
104
|
+
for (const key of Object.keys(config.secrets.refs)) {
|
|
105
|
+
if (key === pathPrefix || key.startsWith(`${pathPrefix}.`)) {
|
|
106
|
+
delete config.secrets.refs[key];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
63
110
|
var DOCS_BASE_URL = "https://docs.nextclaw.io";
|
|
64
111
|
var CHANNEL_TUTORIAL_URLS = {
|
|
65
112
|
feishu: {
|
|
@@ -296,14 +343,16 @@ function toProviderView(config, provider, providerName, uiHints, spec) {
|
|
|
296
343
|
uiHints
|
|
297
344
|
) : null;
|
|
298
345
|
const view = {
|
|
346
|
+
displayName: resolveProviderDisplayName(providerName, provider, spec),
|
|
299
347
|
apiKeySet: masked.apiKeySet || apiKeyRefSet,
|
|
300
348
|
apiKeyMasked: masked.apiKeyMasked ?? (apiKeyRefSet ? "****" : void 0),
|
|
301
349
|
apiBase: provider.apiBase ?? null,
|
|
302
350
|
extraHeaders: extraHeaders && Object.keys(extraHeaders).length > 0 ? extraHeaders : null,
|
|
303
351
|
models: normalizeModelList(provider.models ?? [])
|
|
304
352
|
};
|
|
305
|
-
|
|
306
|
-
|
|
353
|
+
const supportsWireApi = Boolean(spec?.supportsWireApi) || isCustomProviderName(providerName);
|
|
354
|
+
if (supportsWireApi) {
|
|
355
|
+
view.wireApi = provider.wireApi ?? spec?.defaultWireApi ?? "auto";
|
|
307
356
|
}
|
|
308
357
|
return view;
|
|
309
358
|
}
|
|
@@ -341,20 +390,25 @@ function clearSecretRef(config, path) {
|
|
|
341
390
|
}
|
|
342
391
|
}
|
|
343
392
|
function buildConfigMeta(config) {
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
393
|
+
const configProviders = config.providers;
|
|
394
|
+
const builtinProviders = PROVIDERS.map((spec) => {
|
|
395
|
+
const providerConfig = configProviders[spec.name];
|
|
396
|
+
return {
|
|
397
|
+
name: spec.name,
|
|
398
|
+
displayName: resolveProviderDisplayName(spec.name, providerConfig, spec),
|
|
399
|
+
isCustom: false,
|
|
400
|
+
modelPrefix: spec.modelPrefix,
|
|
401
|
+
keywords: spec.keywords,
|
|
402
|
+
envKey: spec.envKey,
|
|
403
|
+
isGateway: spec.isGateway,
|
|
404
|
+
isLocal: spec.isLocal,
|
|
405
|
+
defaultApiBase: spec.defaultApiBase,
|
|
406
|
+
defaultModels: normalizeModelList(spec.defaultModels ?? []),
|
|
407
|
+
supportsWireApi: spec.supportsWireApi,
|
|
408
|
+
wireApiOptions: spec.wireApiOptions,
|
|
409
|
+
defaultWireApi: spec.defaultWireApi
|
|
410
|
+
};
|
|
411
|
+
}).sort((left, right) => {
|
|
358
412
|
const leftRank = PREFERRED_PROVIDER_ORDER_INDEX.get(left.name);
|
|
359
413
|
const rightRank = PREFERRED_PROVIDER_ORDER_INDEX.get(right.name);
|
|
360
414
|
if (leftRank !== void 0 && rightRank !== void 0) {
|
|
@@ -368,6 +422,26 @@ function buildConfigMeta(config) {
|
|
|
368
422
|
}
|
|
369
423
|
return left.name.localeCompare(right.name);
|
|
370
424
|
});
|
|
425
|
+
const customProviders = listCustomProviderNames(config).sort((left, right) => left.localeCompare(right, void 0, { numeric: true, sensitivity: "base" })).map((name) => {
|
|
426
|
+
const providerConfig = configProviders[name];
|
|
427
|
+
const displayName = resolveProviderDisplayName(name, providerConfig);
|
|
428
|
+
return {
|
|
429
|
+
name,
|
|
430
|
+
displayName,
|
|
431
|
+
isCustom: true,
|
|
432
|
+
modelPrefix: name,
|
|
433
|
+
keywords: normalizeModelList([name, displayName ?? ""]),
|
|
434
|
+
envKey: "OPENAI_API_KEY",
|
|
435
|
+
isGateway: false,
|
|
436
|
+
isLocal: false,
|
|
437
|
+
defaultApiBase: void 0,
|
|
438
|
+
defaultModels: [],
|
|
439
|
+
supportsWireApi: true,
|
|
440
|
+
wireApiOptions: CUSTOM_PROVIDER_WIRE_API_OPTIONS,
|
|
441
|
+
defaultWireApi: "auto"
|
|
442
|
+
};
|
|
443
|
+
});
|
|
444
|
+
const providers = [...customProviders, ...builtinProviders];
|
|
371
445
|
const channels = Object.keys(config.channels).map((name) => {
|
|
372
446
|
const tutorialUrls = CHANNEL_TUTORIAL_URLS[name];
|
|
373
447
|
const tutorialUrl = tutorialUrls?.default ?? tutorialUrls?.en ?? tutorialUrls?.zh;
|
|
@@ -458,6 +532,10 @@ function updateProvider(configPath, providerName, patch) {
|
|
|
458
532
|
return null;
|
|
459
533
|
}
|
|
460
534
|
const spec = findProviderByName(providerName);
|
|
535
|
+
const isCustom = isCustomProviderName(providerName);
|
|
536
|
+
if (Object.prototype.hasOwnProperty.call(patch, "displayName") && isCustom) {
|
|
537
|
+
provider.displayName = normalizeOptionalDisplayName(patch.displayName) ?? "";
|
|
538
|
+
}
|
|
461
539
|
if (Object.prototype.hasOwnProperty.call(patch, "apiKey")) {
|
|
462
540
|
provider.apiKey = patch.apiKey ?? "";
|
|
463
541
|
clearSecretRef(config, `providers.${providerName}.apiKey`);
|
|
@@ -468,8 +546,8 @@ function updateProvider(configPath, providerName, patch) {
|
|
|
468
546
|
if (Object.prototype.hasOwnProperty.call(patch, "extraHeaders")) {
|
|
469
547
|
provider.extraHeaders = patch.extraHeaders ?? null;
|
|
470
548
|
}
|
|
471
|
-
if (Object.prototype.hasOwnProperty.call(patch, "wireApi") && spec?.supportsWireApi) {
|
|
472
|
-
provider.wireApi = patch.wireApi ?? spec
|
|
549
|
+
if (Object.prototype.hasOwnProperty.call(patch, "wireApi") && (spec?.supportsWireApi || isCustom)) {
|
|
550
|
+
provider.wireApi = patch.wireApi ?? spec?.defaultWireApi ?? "auto";
|
|
473
551
|
}
|
|
474
552
|
if (Object.prototype.hasOwnProperty.call(patch, "models")) {
|
|
475
553
|
provider.models = normalizeModelList(patch.models ?? []);
|
|
@@ -480,6 +558,43 @@ function updateProvider(configPath, providerName, patch) {
|
|
|
480
558
|
const updated = next.providers[providerName];
|
|
481
559
|
return toProviderView(next, updated, providerName, uiHints, spec ?? void 0);
|
|
482
560
|
}
|
|
561
|
+
function createCustomProvider(configPath, patch = {}) {
|
|
562
|
+
const config = loadConfigOrDefault(configPath);
|
|
563
|
+
const providerName = findNextCustomProviderName(config);
|
|
564
|
+
const providers = config.providers;
|
|
565
|
+
const generatedDisplayName = resolveCustomProviderFallbackDisplayName(providerName);
|
|
566
|
+
providers[providerName] = {
|
|
567
|
+
displayName: normalizeOptionalDisplayName(patch.displayName) ?? generatedDisplayName,
|
|
568
|
+
apiKey: normalizeOptionalString(patch.apiKey) ?? "",
|
|
569
|
+
apiBase: normalizeOptionalString(patch.apiBase),
|
|
570
|
+
extraHeaders: normalizeHeaders(patch.extraHeaders ?? null),
|
|
571
|
+
wireApi: patch.wireApi ?? "auto",
|
|
572
|
+
models: normalizeModelList(patch.models ?? [])
|
|
573
|
+
};
|
|
574
|
+
const next = ConfigSchema.parse(config);
|
|
575
|
+
saveConfig(next, configPath);
|
|
576
|
+
const uiHints = buildUiHints(next);
|
|
577
|
+
const created = next.providers[providerName];
|
|
578
|
+
return {
|
|
579
|
+
name: providerName,
|
|
580
|
+
provider: toProviderView(next, created, providerName, uiHints)
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
function deleteCustomProvider(configPath, providerName) {
|
|
584
|
+
if (!isCustomProviderName(providerName)) {
|
|
585
|
+
return null;
|
|
586
|
+
}
|
|
587
|
+
const config = loadConfigOrDefault(configPath);
|
|
588
|
+
const providers = config.providers;
|
|
589
|
+
if (!providers[providerName]) {
|
|
590
|
+
return null;
|
|
591
|
+
}
|
|
592
|
+
delete providers[providerName];
|
|
593
|
+
clearSecretRefsByPrefix(config, `providers.${providerName}`);
|
|
594
|
+
const next = ConfigSchema.parse(config);
|
|
595
|
+
saveConfig(next, configPath);
|
|
596
|
+
return true;
|
|
597
|
+
}
|
|
483
598
|
function normalizeOptionalString(value) {
|
|
484
599
|
if (typeof value !== "string") {
|
|
485
600
|
return null;
|
|
@@ -497,10 +612,37 @@ function normalizeHeaders(input) {
|
|
|
497
612
|
}
|
|
498
613
|
return Object.fromEntries(entries);
|
|
499
614
|
}
|
|
500
|
-
function
|
|
615
|
+
function buildScopedProviderModel(providerName, model, spec) {
|
|
616
|
+
const trimmed = model.trim();
|
|
617
|
+
if (!trimmed) {
|
|
618
|
+
return "";
|
|
619
|
+
}
|
|
620
|
+
if (trimmed.includes("/")) {
|
|
621
|
+
return trimmed;
|
|
622
|
+
}
|
|
623
|
+
if (isCustomProviderName(providerName)) {
|
|
624
|
+
return trimmed;
|
|
625
|
+
}
|
|
626
|
+
const prefix = (spec?.modelPrefix ?? providerName).trim();
|
|
627
|
+
if (!prefix) {
|
|
628
|
+
return trimmed;
|
|
629
|
+
}
|
|
630
|
+
return `${prefix}/${trimmed}`;
|
|
631
|
+
}
|
|
632
|
+
function resolveTestModel(config, providerName, requestedModel, provider, spec) {
|
|
501
633
|
if (requestedModel) {
|
|
634
|
+
if (isCustomProviderName(providerName)) {
|
|
635
|
+
const prefix = `${providerName}/`;
|
|
636
|
+
if (requestedModel.startsWith(prefix)) {
|
|
637
|
+
return requestedModel.slice(prefix.length) || null;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
502
640
|
return requestedModel;
|
|
503
641
|
}
|
|
642
|
+
const providerModels = normalizeModelList(provider.models ?? []).map((modelId) => buildScopedProviderModel(providerName, modelId, spec)).filter((modelId) => modelId.length > 0);
|
|
643
|
+
if (providerModels.length > 0) {
|
|
644
|
+
return providerModels[0];
|
|
645
|
+
}
|
|
504
646
|
const defaultModel = normalizeOptionalString(config.agents.defaults.model);
|
|
505
647
|
if (defaultModel) {
|
|
506
648
|
const routedProvider = getProviderName(config, defaultModel);
|
|
@@ -508,6 +650,9 @@ function resolveTestModel(config, providerName, requestedModel) {
|
|
|
508
650
|
return defaultModel;
|
|
509
651
|
}
|
|
510
652
|
}
|
|
653
|
+
if (isCustomProviderName(providerName)) {
|
|
654
|
+
return null;
|
|
655
|
+
}
|
|
511
656
|
return PROVIDER_TEST_MODEL_FALLBACKS[providerName] ?? defaultModel ?? null;
|
|
512
657
|
}
|
|
513
658
|
function stringifyError(error) {
|
|
@@ -531,7 +676,8 @@ async function testProviderConnection(configPath, providerName, patch) {
|
|
|
531
676
|
const apiBase = hasApiBasePatch ? patchedApiBase ?? spec?.defaultApiBase ?? null : currentApiBase ?? spec?.defaultApiBase ?? null;
|
|
532
677
|
const hasHeadersPatch = Object.prototype.hasOwnProperty.call(patch, "extraHeaders");
|
|
533
678
|
const extraHeaders = hasHeadersPatch ? normalizeHeaders(patch.extraHeaders ?? null) : normalizeHeaders(provider.extraHeaders ?? null);
|
|
534
|
-
const
|
|
679
|
+
const isCustom = isCustomProviderName(providerName);
|
|
680
|
+
const wireApi = spec?.supportsWireApi || isCustom ? patch.wireApi ?? provider.wireApi ?? spec?.defaultWireApi ?? "auto" : null;
|
|
535
681
|
if (!apiKey && !spec?.isLocal) {
|
|
536
682
|
return {
|
|
537
683
|
success: false,
|
|
@@ -541,13 +687,13 @@ async function testProviderConnection(configPath, providerName, patch) {
|
|
|
541
687
|
};
|
|
542
688
|
}
|
|
543
689
|
const requestedModel = normalizeOptionalString(patch.model);
|
|
544
|
-
const model = resolveTestModel(config, providerName, requestedModel);
|
|
690
|
+
const model = resolveTestModel(config, providerName, requestedModel, provider, spec ?? void 0);
|
|
545
691
|
if (!model) {
|
|
546
692
|
return {
|
|
547
693
|
success: false,
|
|
548
694
|
provider: providerName,
|
|
549
695
|
latencyMs: 0,
|
|
550
|
-
message: "No test model found.
|
|
696
|
+
message: "No test model found. Configure provider models or set a default model for this provider, then try again."
|
|
551
697
|
};
|
|
552
698
|
}
|
|
553
699
|
const probe = new LiteLLMProvider({
|
|
@@ -2133,6 +2279,33 @@ function createUiRouter(options) {
|
|
|
2133
2279
|
options.publish({ type: "config.updated", payload: { path: `providers.${provider}` } });
|
|
2134
2280
|
return c.json(ok(result));
|
|
2135
2281
|
});
|
|
2282
|
+
app.post("/api/config/providers", async (c) => {
|
|
2283
|
+
const body = await readJson(c.req.raw);
|
|
2284
|
+
if (!body.ok) {
|
|
2285
|
+
return c.json(err("INVALID_BODY", "invalid json body"), 400);
|
|
2286
|
+
}
|
|
2287
|
+
const result = createCustomProvider(
|
|
2288
|
+
options.configPath,
|
|
2289
|
+
body.data
|
|
2290
|
+
);
|
|
2291
|
+
options.publish({ type: "config.updated", payload: { path: `providers.${result.name}` } });
|
|
2292
|
+
return c.json(ok({
|
|
2293
|
+
name: result.name,
|
|
2294
|
+
provider: result.provider
|
|
2295
|
+
}));
|
|
2296
|
+
});
|
|
2297
|
+
app.delete("/api/config/providers/:provider", async (c) => {
|
|
2298
|
+
const provider = c.req.param("provider");
|
|
2299
|
+
const result = deleteCustomProvider(options.configPath, provider);
|
|
2300
|
+
if (result === null) {
|
|
2301
|
+
return c.json(err("NOT_FOUND", `custom provider not found: ${provider}`), 404);
|
|
2302
|
+
}
|
|
2303
|
+
options.publish({ type: "config.updated", payload: { path: `providers.${provider}` } });
|
|
2304
|
+
return c.json(ok({
|
|
2305
|
+
deleted: true,
|
|
2306
|
+
provider
|
|
2307
|
+
}));
|
|
2308
|
+
});
|
|
2136
2309
|
app.post("/api/config/providers/:provider/test", async (c) => {
|
|
2137
2310
|
const provider = c.req.param("provider");
|
|
2138
2311
|
const body = await readJson(c.req.raw);
|
|
@@ -2561,7 +2734,9 @@ export {
|
|
|
2561
2734
|
buildConfigMeta,
|
|
2562
2735
|
buildConfigSchemaView,
|
|
2563
2736
|
buildConfigView,
|
|
2737
|
+
createCustomProvider,
|
|
2564
2738
|
createUiRouter,
|
|
2739
|
+
deleteCustomProvider,
|
|
2565
2740
|
deleteSession,
|
|
2566
2741
|
executeConfigAction,
|
|
2567
2742
|
getSessionHistory,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/server",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.27",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Nextclaw UI/API server.",
|
|
6
6
|
"type": "module",
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
],
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@hono/node-server": "^1.13.3",
|
|
18
|
-
"@nextclaw/openclaw-compat": "^0.1.
|
|
18
|
+
"@nextclaw/openclaw-compat": "^0.1.32",
|
|
19
19
|
"hono": "^4.6.2",
|
|
20
20
|
"ws": "^8.18.0",
|
|
21
|
-
"@nextclaw/core": "^0.6.
|
|
21
|
+
"@nextclaw/core": "^0.6.43"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^20.17.6",
|