@shipfox/api-agent 2.0.0
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/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +105 -0
- package/LICENSE +21 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +60 -0
- package/dist/config.js.map +1 -0
- package/dist/core/credential-fingerprints.d.ts +10 -0
- package/dist/core/credential-fingerprints.d.ts.map +1 -0
- package/dist/core/credential-fingerprints.js +65 -0
- package/dist/core/credential-fingerprints.js.map +1 -0
- package/dist/core/custom-model-provider-config-service.d.ts +26 -0
- package/dist/core/custom-model-provider-config-service.d.ts.map +1 -0
- package/dist/core/custom-model-provider-config-service.js +390 -0
- package/dist/core/custom-model-provider-config-service.js.map +1 -0
- package/dist/core/custom-provider-url.d.ts +4 -0
- package/dist/core/custom-provider-url.d.ts.map +1 -0
- package/dist/core/custom-provider-url.js +23 -0
- package/dist/core/custom-provider-url.js.map +1 -0
- package/dist/core/discover-custom-model-provider-models.d.ts +3 -0
- package/dist/core/discover-custom-model-provider-models.d.ts.map +1 -0
- package/dist/core/discover-custom-model-provider-models.js +122 -0
- package/dist/core/discover-custom-model-provider-models.js.map +1 -0
- package/dist/core/entities/agent-workspace-settings.d.ts +9 -0
- package/dist/core/entities/agent-workspace-settings.d.ts.map +1 -0
- package/dist/core/entities/agent-workspace-settings.js +3 -0
- package/dist/core/entities/agent-workspace-settings.js.map +1 -0
- package/dist/core/entities/model-provider-config.d.ts +19 -0
- package/dist/core/entities/model-provider-config.d.ts.map +1 -0
- package/dist/core/entities/model-provider-config.js +3 -0
- package/dist/core/entities/model-provider-config.js.map +1 -0
- package/dist/core/errors.d.ts +62 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +80 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/harness/claude.d.ts +6 -0
- package/dist/core/harness/claude.d.ts.map +1 -0
- package/dist/core/harness/claude.js +104 -0
- package/dist/core/harness/claude.js.map +1 -0
- package/dist/core/harness/index.d.ts +4 -0
- package/dist/core/harness/index.d.ts.map +1 -0
- package/dist/core/harness/index.js +5 -0
- package/dist/core/harness/index.js.map +1 -0
- package/dist/core/harness/pi.d.ts +6 -0
- package/dist/core/harness/pi.d.ts.map +1 -0
- package/dist/core/harness/pi.js +16 -0
- package/dist/core/harness/pi.js.map +1 -0
- package/dist/core/harness/registry.d.ts +22 -0
- package/dist/core/harness/registry.d.ts.map +1 -0
- package/dist/core/harness/registry.js +46 -0
- package/dist/core/harness/registry.js.map +1 -0
- package/dist/core/index.d.ts +12 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +11 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/model-provider-catalog.d.ts +3 -0
- package/dist/core/model-provider-catalog.d.ts.map +1 -0
- package/dist/core/model-provider-catalog.js +25 -0
- package/dist/core/model-provider-catalog.js.map +1 -0
- package/dist/core/model-provider-config-service.d.ts +32 -0
- package/dist/core/model-provider-config-service.d.ts.map +1 -0
- package/dist/core/model-provider-config-service.js +133 -0
- package/dist/core/model-provider-config-service.js.map +1 -0
- package/dist/core/model-provider-validation.d.ts +31 -0
- package/dist/core/model-provider-validation.d.ts.map +1 -0
- package/dist/core/model-provider-validation.js +220 -0
- package/dist/core/model-provider-validation.js.map +1 -0
- package/dist/core/resolve-agent-config.d.ts +32 -0
- package/dist/core/resolve-agent-config.d.ts.map +1 -0
- package/dist/core/resolve-agent-config.js +143 -0
- package/dist/core/resolve-agent-config.js.map +1 -0
- package/dist/core/resolve-runtime-credentials.d.ts +21 -0
- package/dist/core/resolve-runtime-credentials.d.ts.map +1 -0
- package/dist/core/resolve-runtime-credentials.js +101 -0
- package/dist/core/resolve-runtime-credentials.js.map +1 -0
- package/dist/core/workspace-agent-defaults-resolver.d.ts +3 -0
- package/dist/core/workspace-agent-defaults-resolver.d.ts.map +1 -0
- package/dist/core/workspace-agent-defaults-resolver.js +26 -0
- package/dist/core/workspace-agent-defaults-resolver.js.map +1 -0
- package/dist/db/agent-defaults-snapshot.d.ts +9 -0
- package/dist/db/agent-defaults-snapshot.d.ts.map +1 -0
- package/dist/db/agent-defaults-snapshot.js +24 -0
- package/dist/db/agent-defaults-snapshot.js.map +1 -0
- package/dist/db/agent-workspace-settings.d.ts +12 -0
- package/dist/db/agent-workspace-settings.d.ts.map +1 -0
- package/dist/db/agent-workspace-settings.js +53 -0
- package/dist/db/agent-workspace-settings.js.map +1 -0
- package/dist/db/db.d.ts +771 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +20 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/index.d.ts +9 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +11 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/model-provider-configs.d.ts +38 -0
- package/dist/db/model-provider-configs.d.ts.map +1 -0
- package/dist/db/model-provider-configs.js +159 -0
- package/dist/db/model-provider-configs.js.map +1 -0
- package/dist/db/schema/agent-workspace-settings.d.ts +97 -0
- package/dist/db/schema/agent-workspace-settings.d.ts.map +1 -0
- package/dist/db/schema/agent-workspace-settings.js +26 -0
- package/dist/db/schema/agent-workspace-settings.js.map +1 -0
- package/dist/db/schema/common.d.ts +2 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +4 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/model-provider-configs.d.ts +296 -0
- package/dist/db/schema/model-provider-configs.d.ts.map +1 -0
- package/dist/db/schema/model-provider-configs.js +52 -0
- package/dist/db/schema/model-provider-configs.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +3 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/instance.d.ts +10 -0
- package/dist/metrics/instance.d.ts.map +1 -0
- package/dist/metrics/instance.js +10 -0
- package/dist/metrics/instance.js.map +1 -0
- package/dist/presentation/dto/index.d.ts +2 -0
- package/dist/presentation/dto/index.d.ts.map +1 -0
- package/dist/presentation/dto/index.js +3 -0
- package/dist/presentation/dto/index.js.map +1 -0
- package/dist/presentation/dto/model-provider-config.d.ts +6 -0
- package/dist/presentation/dto/model-provider-config.d.ts.map +1 -0
- package/dist/presentation/dto/model-provider-config.js +32 -0
- package/dist/presentation/dto/model-provider-config.js.map +1 -0
- package/dist/presentation/e2eRoutes/create-model-provider.d.ts +2 -0
- package/dist/presentation/e2eRoutes/create-model-provider.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/create-model-provider.js +66 -0
- package/dist/presentation/e2eRoutes/create-model-provider.js.map +1 -0
- package/dist/presentation/e2eRoutes/index.d.ts +3 -0
- package/dist/presentation/e2eRoutes/index.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/index.js +9 -0
- package/dist/presentation/e2eRoutes/index.js.map +1 -0
- package/dist/presentation/index.d.ts +2 -0
- package/dist/presentation/index.d.ts.map +1 -0
- package/dist/presentation/index.js +3 -0
- package/dist/presentation/index.js.map +1 -0
- package/dist/presentation/routes/create-custom-model-provider.d.ts +2 -0
- package/dist/presentation/routes/create-custom-model-provider.d.ts.map +1 -0
- package/dist/presentation/routes/create-custom-model-provider.js +45 -0
- package/dist/presentation/routes/create-custom-model-provider.js.map +1 -0
- package/dist/presentation/routes/delete-model-provider-config.d.ts +2 -0
- package/dist/presentation/routes/delete-model-provider-config.d.ts.map +1 -0
- package/dist/presentation/routes/delete-model-provider-config.js +38 -0
- package/dist/presentation/routes/delete-model-provider-config.js.map +1 -0
- package/dist/presentation/routes/discover-custom-model-provider-models-by-slug.d.ts +2 -0
- package/dist/presentation/routes/discover-custom-model-provider-models-by-slug.d.ts.map +1 -0
- package/dist/presentation/routes/discover-custom-model-provider-models-by-slug.js +37 -0
- package/dist/presentation/routes/discover-custom-model-provider-models-by-slug.js.map +1 -0
- package/dist/presentation/routes/discover-custom-model-provider-models.d.ts +2 -0
- package/dist/presentation/routes/discover-custom-model-provider-models.d.ts.map +1 -0
- package/dist/presentation/routes/discover-custom-model-provider-models.js +31 -0
- package/dist/presentation/routes/discover-custom-model-provider-models.js.map +1 -0
- package/dist/presentation/routes/errors.d.ts +2 -0
- package/dist/presentation/routes/errors.d.ts.map +1 -0
- package/dist/presentation/routes/errors.js +112 -0
- package/dist/presentation/routes/errors.js.map +1 -0
- package/dist/presentation/routes/index.d.ts +3 -0
- package/dist/presentation/routes/index.d.ts.map +1 -0
- package/dist/presentation/routes/index.js +39 -0
- package/dist/presentation/routes/index.js.map +1 -0
- package/dist/presentation/routes/list-model-provider-catalog.d.ts +2 -0
- package/dist/presentation/routes/list-model-provider-catalog.d.ts.map +1 -0
- package/dist/presentation/routes/list-model-provider-catalog.js +18 -0
- package/dist/presentation/routes/list-model-provider-catalog.js.map +1 -0
- package/dist/presentation/routes/list-model-provider-configs.d.ts +2 -0
- package/dist/presentation/routes/list-model-provider-configs.d.ts.map +1 -0
- package/dist/presentation/routes/list-model-provider-configs.js +37 -0
- package/dist/presentation/routes/list-model-provider-configs.js.map +1 -0
- package/dist/presentation/routes/set-default-harness.d.ts +2 -0
- package/dist/presentation/routes/set-default-harness.d.ts.map +1 -0
- package/dist/presentation/routes/set-default-harness.js +38 -0
- package/dist/presentation/routes/set-default-harness.js.map +1 -0
- package/dist/presentation/routes/set-default-model-provider.d.ts +2 -0
- package/dist/presentation/routes/set-default-model-provider.d.ts.map +1 -0
- package/dist/presentation/routes/set-default-model-provider.js +48 -0
- package/dist/presentation/routes/set-default-model-provider.js.map +1 -0
- package/dist/presentation/routes/update-custom-model-provider.d.ts +2 -0
- package/dist/presentation/routes/update-custom-model-provider.d.ts.map +1 -0
- package/dist/presentation/routes/update-custom-model-provider.js +47 -0
- package/dist/presentation/routes/update-custom-model-provider.js.map +1 -0
- package/dist/presentation/routes/update-model-provider-default-model.d.ts +2 -0
- package/dist/presentation/routes/update-model-provider-default-model.d.ts.map +1 -0
- package/dist/presentation/routes/update-model-provider-default-model.js +38 -0
- package/dist/presentation/routes/update-model-provider-default-model.js.map +1 -0
- package/dist/presentation/routes/upsert-model-provider-config.d.ts +2 -0
- package/dist/presentation/routes/upsert-model-provider-config.d.ts.map +1 -0
- package/dist/presentation/routes/upsert-model-provider-config.js +52 -0
- package/dist/presentation/routes/upsert-model-provider-config.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_daffy_leopardon.sql +28 -0
- package/drizzle/0001_default_harness.sql +1 -0
- package/drizzle/meta/0000_snapshot.json +199 -0
- package/drizzle/meta/0001_snapshot.json +205 -0
- package/drizzle/meta/_journal.json +20 -0
- package/drizzle.config.ts +7 -0
- package/package.json +109 -0
- package/src/config.test.ts +118 -0
- package/src/config.ts +75 -0
- package/src/core/catalog-registry.test.ts +48 -0
- package/src/core/credential-fingerprints.test.ts +34 -0
- package/src/core/credential-fingerprints.ts +84 -0
- package/src/core/custom-model-provider-config-service.ts +537 -0
- package/src/core/custom-provider-url.ts +24 -0
- package/src/core/discover-custom-model-provider-models.ts +147 -0
- package/src/core/entities/agent-workspace-settings.ts +9 -0
- package/src/core/entities/model-provider-config.ts +25 -0
- package/src/core/errors.ts +139 -0
- package/src/core/harness/claude.ts +75 -0
- package/src/core/harness/index.ts +19 -0
- package/src/core/harness/pi.ts +18 -0
- package/src/core/harness/registry.test.ts +281 -0
- package/src/core/harness/registry.ts +108 -0
- package/src/core/index.ts +56 -0
- package/src/core/model-provider-catalog.ts +33 -0
- package/src/core/model-provider-config-service.test.ts +940 -0
- package/src/core/model-provider-config-service.ts +207 -0
- package/src/core/model-provider-validation.test.ts +354 -0
- package/src/core/model-provider-validation.ts +276 -0
- package/src/core/resolve-agent-config.test.ts +441 -0
- package/src/core/resolve-agent-config.ts +272 -0
- package/src/core/resolve-runtime-credentials.test.ts +316 -0
- package/src/core/resolve-runtime-credentials.ts +147 -0
- package/src/core/workspace-agent-defaults-resolver.ts +42 -0
- package/src/db/agent-defaults-snapshot.ts +49 -0
- package/src/db/agent-workspace-settings.test.ts +111 -0
- package/src/db/agent-workspace-settings.ts +92 -0
- package/src/db/db.ts +20 -0
- package/src/db/index.ts +29 -0
- package/src/db/model-provider-configs.test.ts +281 -0
- package/src/db/model-provider-configs.ts +230 -0
- package/src/db/schema/agent-workspace-settings.ts +27 -0
- package/src/db/schema/common.ts +3 -0
- package/src/db/schema/model-provider-configs.ts +80 -0
- package/src/index.ts +43 -0
- package/src/metrics/index.ts +1 -0
- package/src/metrics/instance.ts +18 -0
- package/src/presentation/dto/index.ts +5 -0
- package/src/presentation/dto/model-provider-config.ts +41 -0
- package/src/presentation/e2eRoutes/create-model-provider.test.ts +47 -0
- package/src/presentation/e2eRoutes/create-model-provider.ts +61 -0
- package/src/presentation/e2eRoutes/index.ts +7 -0
- package/src/presentation/index.ts +1 -0
- package/src/presentation/routes/create-custom-model-provider.ts +45 -0
- package/src/presentation/routes/delete-model-provider-config.ts +31 -0
- package/src/presentation/routes/discover-custom-model-provider-models-by-slug.ts +42 -0
- package/src/presentation/routes/discover-custom-model-provider-models.ts +29 -0
- package/src/presentation/routes/errors.ts +122 -0
- package/src/presentation/routes/index.ts +37 -0
- package/src/presentation/routes/list-model-provider-catalog.ts +15 -0
- package/src/presentation/routes/list-model-provider-configs.ts +33 -0
- package/src/presentation/routes/model-provider-catalog.test.ts +73 -0
- package/src/presentation/routes/model-provider-config.test.ts +807 -0
- package/src/presentation/routes/set-default-harness.ts +33 -0
- package/src/presentation/routes/set-default-model-provider.ts +47 -0
- package/src/presentation/routes/update-custom-model-provider.ts +50 -0
- package/src/presentation/routes/update-model-provider-default-model.ts +40 -0
- package/src/presentation/routes/upsert-model-provider-config.ts +53 -0
- package/test/env.ts +8 -0
- package/test/globalSetup.ts +25 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +9 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +3 -0
- package/tsconfig.test.json +8 -0
- package/vitest.config.ts +11 -0
package/src/config.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {
|
|
2
|
+
agentThinkingSchema,
|
|
3
|
+
buildHarnessToolDeploymentConfig,
|
|
4
|
+
getModelProviderEntry,
|
|
5
|
+
SUPPORTED_MODEL_PROVIDER_IDS,
|
|
6
|
+
type SupportedModelProviderId,
|
|
7
|
+
} from '@shipfox/api-agent-dto';
|
|
8
|
+
import {bool, createConfig, num, str} from '@shipfox/config';
|
|
9
|
+
|
|
10
|
+
const AGENT_THINKING_CHOICES = agentThinkingSchema.options;
|
|
11
|
+
|
|
12
|
+
export const config = createConfig({
|
|
13
|
+
AGENT_DEFAULT_PROVIDER: str({
|
|
14
|
+
desc: 'Instance-wide default model provider ID used when a workflow and workspace do not choose one. Optional. Use one of the supported model provider IDs from the model provider catalog.',
|
|
15
|
+
choices: SUPPORTED_MODEL_PROVIDER_IDS,
|
|
16
|
+
default: undefined,
|
|
17
|
+
}),
|
|
18
|
+
AGENT_DEFAULT_PROVIDER_MODEL: str({
|
|
19
|
+
desc: 'Instance-wide default model ID used when the resolved provider matches AGENT_DEFAULT_PROVIDER and no workflow or workspace model is set. Optional. Use a model ID supported by that provider.',
|
|
20
|
+
default: undefined,
|
|
21
|
+
}),
|
|
22
|
+
AGENT_DEFAULT_PROVIDER_THINKING: str({
|
|
23
|
+
desc: 'Instance-wide default thinking effort used when the resolved provider matches AGENT_DEFAULT_PROVIDER and no workflow or workspace thinking effort is set. Optional. Accepted values are off, minimal, low, medium, high, and xhigh.',
|
|
24
|
+
choices: AGENT_THINKING_CHOICES,
|
|
25
|
+
default: undefined,
|
|
26
|
+
}),
|
|
27
|
+
AGENT_DEFAULT_PROVIDER_API_KEY: str({
|
|
28
|
+
desc: 'API key for the instance default provider. Optional. Must belong to AGENT_DEFAULT_PROVIDER. If you change the default provider, change this key too. Instance defaults support API-key-only providers.',
|
|
29
|
+
default: undefined,
|
|
30
|
+
}),
|
|
31
|
+
AGENT_PROVIDER_VALIDATION_TIMEOUT_MS: num({
|
|
32
|
+
desc: 'Maximum time in milliseconds to wait for the live provider test request when saving credentials.',
|
|
33
|
+
default: 10000,
|
|
34
|
+
}),
|
|
35
|
+
AGENT_CUSTOM_PROVIDER_ALLOW_PRIVATE_NETWORKS: bool({
|
|
36
|
+
desc: 'Allows custom model providers to use private, loopback, link-local, metadata, and .internal network targets. Keep this true for local development and self-hosted private networks. Set it to false on cloud instances.',
|
|
37
|
+
default: true,
|
|
38
|
+
}),
|
|
39
|
+
AGENT_CUSTOM_PROVIDER_HOST_DENYLIST: str({
|
|
40
|
+
desc: 'Comma-separated hosts and IP ranges that custom model providers may not call. Accepts exact hosts, suffix patterns such as .internal.example or *.internal.example, IP literals, and CIDR blocks such as 10.0.0.0/8.',
|
|
41
|
+
default: '',
|
|
42
|
+
}),
|
|
43
|
+
AGENT_PI_ENABLED_TOOL_PACKAGES: str({
|
|
44
|
+
desc: 'Comma-separated optional Pi tool packages enabled for this deployment. Defaults to pi-web-access so Pi web access is available. Set it to an empty value to enable only Pi built-in tools. Accepted values: pi-web-access.',
|
|
45
|
+
default: 'pi-web-access',
|
|
46
|
+
}),
|
|
47
|
+
AGENT_PI_WEB_SEARCH_ENABLED: bool({
|
|
48
|
+
desc: 'Enables Pi web search tools when pi-web-access is enabled. Set it to false to disable web_search and get_search_content while keeping fetch_content available.',
|
|
49
|
+
default: true,
|
|
50
|
+
}),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
assertInstanceDefaultModelProviderApiKeyConfig();
|
|
54
|
+
|
|
55
|
+
export const harnessToolDeploymentConfig = buildHarnessToolDeploymentConfig({
|
|
56
|
+
piEnabledToolPackages: config.AGENT_PI_ENABLED_TOOL_PACKAGES,
|
|
57
|
+
piWebSearchEnabled: config.AGENT_PI_WEB_SEARCH_ENABLED,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
function assertInstanceDefaultModelProviderApiKeyConfig(): void {
|
|
61
|
+
if (!config.AGENT_DEFAULT_PROVIDER_API_KEY) return;
|
|
62
|
+
if (!config.AGENT_DEFAULT_PROVIDER) {
|
|
63
|
+
throw new Error('AGENT_DEFAULT_PROVIDER_API_KEY requires AGENT_DEFAULT_PROVIDER to be set.');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const credentialFields =
|
|
67
|
+
getModelProviderEntry(config.AGENT_DEFAULT_PROVIDER as SupportedModelProviderId)
|
|
68
|
+
?.credential_fields ?? [];
|
|
69
|
+
const field = credentialFields[0];
|
|
70
|
+
if (credentialFields.length === 1 && field?.key === 'api_key' && field.secret) return;
|
|
71
|
+
|
|
72
|
+
throw new Error(
|
|
73
|
+
'AGENT_DEFAULT_PROVIDER_API_KEY requires AGENT_DEFAULT_PROVIDER to use exactly one secret api_key credential field.',
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {getModels, getProviders, type KnownProvider} from '@earendil-works/pi-ai';
|
|
2
|
+
import {
|
|
3
|
+
getModelProviderEntry,
|
|
4
|
+
MODEL_PROVIDER_CATALOG_SEED,
|
|
5
|
+
MODEL_PROVIDER_IDS,
|
|
6
|
+
type ModelProviderId,
|
|
7
|
+
SUPPORTED_MODEL_PROVIDER_IDS,
|
|
8
|
+
} from '@shipfox/api-agent-dto';
|
|
9
|
+
|
|
10
|
+
const STORE_COMPATIBLE_CREDENTIAL_KEY_PATTERN = /^[a-z_][a-z0-9_]*$/;
|
|
11
|
+
|
|
12
|
+
describe('model provider catalog registry', () => {
|
|
13
|
+
it('keeps catalog provider ids synced with the pinned Pi provider registry', () => {
|
|
14
|
+
const catalogModelProviderIds = [...MODEL_PROVIDER_IDS].sort();
|
|
15
|
+
const piModelProviderIds = getProviders().sort();
|
|
16
|
+
|
|
17
|
+
expect(catalogModelProviderIds).toEqual(piModelProviderIds);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('keeps supported catalog default models present in the pinned Pi model registry', () => {
|
|
21
|
+
const supportedEntries = MODEL_PROVIDER_CATALOG_SEED.filter(
|
|
22
|
+
(entry) => entry.support_status === 'supported',
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const missingDefaults = supportedEntries.flatMap((entry) => {
|
|
26
|
+
const piModels = getModels(entry.id as KnownProvider);
|
|
27
|
+
const defaultExists = piModels.some((model) => model.id === entry.default_model);
|
|
28
|
+
return defaultExists ? [] : [formatMissingDefault(entry.id, entry.default_model)];
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
expect(missingDefaults).toEqual([]);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('keeps supported credential field keys compatible with the agent secrets namespace', () => {
|
|
35
|
+
const invalidKeys = SUPPORTED_MODEL_PROVIDER_IDS.flatMap((providerId) => {
|
|
36
|
+
const entry = getModelProviderEntry(providerId);
|
|
37
|
+
return (entry?.credential_fields ?? [])
|
|
38
|
+
.filter((field) => !STORE_COMPATIBLE_CREDENTIAL_KEY_PATTERN.test(field.key))
|
|
39
|
+
.map((field) => `${providerId}:${field.key}`);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
expect(invalidKeys).toEqual([]);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
function formatMissingDefault(providerId: ModelProviderId, defaultModel: string | null): string {
|
|
47
|
+
return `${providerId}:${defaultModel ?? '<null>'}`;
|
|
48
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
credentialsToStoreValues,
|
|
3
|
+
storeValuesToRuntimeCredentials,
|
|
4
|
+
} from './credential-fingerprints.js';
|
|
5
|
+
|
|
6
|
+
describe('credential storage keys', () => {
|
|
7
|
+
it('maps provider credential keys to uppercase store keys', () => {
|
|
8
|
+
const values = credentialsToStoreValues('cloudflare-ai-gateway', {
|
|
9
|
+
api_key: 'cf-secret',
|
|
10
|
+
account_id: 'account-123',
|
|
11
|
+
gateway_id: 'gateway-456',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
expect(values).toEqual({
|
|
15
|
+
API_KEY: 'cf-secret',
|
|
16
|
+
ACCOUNT_ID: 'account-123',
|
|
17
|
+
GATEWAY_ID: 'gateway-456',
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('maps store keys back to provider runtime keys', () => {
|
|
22
|
+
const credentials = storeValuesToRuntimeCredentials('cloudflare-ai-gateway', {
|
|
23
|
+
API_KEY: 'cf-secret',
|
|
24
|
+
ACCOUNT_ID: 'account-123',
|
|
25
|
+
GATEWAY_ID: 'gateway-456',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
expect(credentials).toEqual({
|
|
29
|
+
api_key: 'cf-secret',
|
|
30
|
+
account_id: 'account-123',
|
|
31
|
+
gateway_id: 'gateway-456',
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type {SupportedModelProviderId} from '@shipfox/api-agent-dto';
|
|
2
|
+
import {getModelProviderEntry} from '@shipfox/api-agent-dto';
|
|
3
|
+
import {UnsupportedModelProviderError} from './errors.js';
|
|
4
|
+
|
|
5
|
+
export function agentSystemNamespace(providerId: string): string {
|
|
6
|
+
return `system/agent/model-provider/${providerId}`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function toStoreKey(fieldKey: string): string {
|
|
10
|
+
return fieldKey.toUpperCase();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function customCredentialToStoreKey(fieldKey: string): string {
|
|
14
|
+
if (fieldKey === 'api_key') return 'API_KEY';
|
|
15
|
+
if (fieldKey.startsWith('header:'))
|
|
16
|
+
return `HEADER_${encodeStoreKey(fieldKey.slice('header:'.length))}`;
|
|
17
|
+
return `CREDENTIAL_${encodeStoreKey(fieldKey)}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function customStoreKeyToRuntimeKey(storeKey: string): string {
|
|
21
|
+
if (storeKey === 'API_KEY') return 'api_key';
|
|
22
|
+
if (storeKey.startsWith('HEADER_'))
|
|
23
|
+
return `header:${decodeStoreKey(storeKey.slice('HEADER_'.length))}`;
|
|
24
|
+
if (storeKey.startsWith('CREDENTIAL_'))
|
|
25
|
+
return decodeStoreKey(storeKey.slice('CREDENTIAL_'.length));
|
|
26
|
+
return storeKey.toLowerCase();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function customCredentialsToStoreValues(
|
|
30
|
+
credentials: Record<string, string>,
|
|
31
|
+
): Record<string, string> {
|
|
32
|
+
return Object.fromEntries(
|
|
33
|
+
Object.entries(credentials).map(([key, value]) => [customCredentialToStoreKey(key), value]),
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function storeValuesToCustomRuntimeCredentials(
|
|
38
|
+
values: Record<string, string>,
|
|
39
|
+
): Record<string, string> {
|
|
40
|
+
return Object.fromEntries(
|
|
41
|
+
Object.entries(values).map(([key, value]) => [customStoreKeyToRuntimeKey(key), value]),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function credentialsToStoreValues(
|
|
46
|
+
providerId: SupportedModelProviderId,
|
|
47
|
+
credentials: Record<string, string>,
|
|
48
|
+
): Record<string, string> {
|
|
49
|
+
const entry = getSupportedModelProviderEntry(providerId);
|
|
50
|
+
|
|
51
|
+
return Object.fromEntries(
|
|
52
|
+
entry.credential_fields.map((field) => [toStoreKey(field.key), credentials[field.key] ?? '']),
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function storeValuesToRuntimeCredentials(
|
|
57
|
+
providerId: SupportedModelProviderId,
|
|
58
|
+
values: Record<string, string>,
|
|
59
|
+
): Record<string, string> {
|
|
60
|
+
const entry = getSupportedModelProviderEntry(providerId);
|
|
61
|
+
|
|
62
|
+
return Object.fromEntries(
|
|
63
|
+
entry.credential_fields.flatMap((field) => {
|
|
64
|
+
const value = values[toStoreKey(field.key)];
|
|
65
|
+
return value === undefined ? [] : [[field.key, value]];
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function getSupportedModelProviderEntry(providerId: SupportedModelProviderId) {
|
|
71
|
+
const entry = getModelProviderEntry(providerId);
|
|
72
|
+
if (entry === undefined || entry.support_status !== 'supported') {
|
|
73
|
+
throw new UnsupportedModelProviderError(providerId);
|
|
74
|
+
}
|
|
75
|
+
return entry;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function encodeStoreKey(value: string): string {
|
|
79
|
+
return Buffer.from(value, 'utf8').toString('hex').toUpperCase();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function decodeStoreKey(value: string): string {
|
|
83
|
+
return Buffer.from(value, 'hex').toString('utf8');
|
|
84
|
+
}
|