@skaile/forge-settings 0.0.0-stage → 1.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/CHANGELOG.md +21 -0
- package/LICENSE +21 -0
- package/README.md +94 -2
- package/dist/module.d.mts +17 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +23 -0
- package/dist/runtime/ai-sdk/index.d.ts +45 -0
- package/dist/runtime/ai-sdk/index.js +39 -0
- package/dist/runtime/components/ForgeProvidersPanel.d.vue.ts +21 -0
- package/dist/runtime/components/ForgeProvidersPanel.vue +435 -0
- package/dist/runtime/components/ForgeProvidersPanel.vue.d.ts +21 -0
- package/dist/runtime/editor/index.d.ts +58 -0
- package/dist/runtime/editor/index.js +83 -0
- package/dist/runtime/model/errors.d.ts +24 -0
- package/dist/runtime/model/errors.js +10 -0
- package/dist/runtime/server/credential-policy.d.ts +60 -0
- package/dist/runtime/server/credential-policy.js +64 -0
- package/dist/runtime/server/credential-store.d.ts +184 -0
- package/dist/runtime/server/credential-store.js +234 -0
- package/dist/runtime/server/env-layers.d.ts +62 -0
- package/dist/runtime/server/env-layers.js +185 -0
- package/dist/runtime/server/env.d.ts +30 -0
- package/dist/runtime/server/env.js +15 -0
- package/dist/runtime/server/harness-settings.d.ts +150 -0
- package/dist/runtime/server/harness-settings.js +166 -0
- package/dist/runtime/server/index.d.ts +23 -0
- package/dist/runtime/server/index.js +14 -0
- package/dist/runtime/server/provider-discovery.d.ts +73 -0
- package/dist/runtime/server/provider-discovery.js +77 -0
- package/dist/runtime/server/provider-layers.d.ts +27 -0
- package/dist/runtime/server/provider-layers.js +37 -0
- package/dist/runtime/server/provider-service.d.ts +126 -0
- package/dist/runtime/server/provider-service.js +87 -0
- package/dist/runtime/server/provider-settings.d.ts +78 -0
- package/dist/runtime/server/provider-settings.js +81 -0
- package/dist/runtime/server/provider-write.d.ts +154 -0
- package/dist/runtime/server/provider-write.js +223 -0
- package/dist/runtime/server/settings-defaults.d.ts +26 -0
- package/dist/runtime/server/settings-defaults.js +46 -0
- package/dist/runtime/shared/env-vars.d.ts +55 -0
- package/dist/runtime/shared/env-vars.js +22 -0
- package/dist/runtime/shared/harness-providers.d.ts +62 -0
- package/dist/runtime/shared/harness-providers.js +38 -0
- package/dist/runtime/shared/harnesses.d.ts +19 -0
- package/dist/runtime/shared/harnesses.js +15 -0
- package/dist/runtime/shared/provider-registry.d.ts +255 -0
- package/dist/runtime/shared/provider-registry.js +112 -0
- package/dist/runtime/shared/settings-types.d.ts +84 -0
- package/dist/runtime/shared/settings-types.js +0 -0
- package/dist/runtime/shims-vue.d.ts +8 -0
- package/dist/runtime/vue/index.d.ts +14 -0
- package/dist/runtime/vue/index.js +6 -0
- package/dist/runtime/vue/settings-modal-scope.d.ts +62 -0
- package/dist/runtime/vue/settings-modal-scope.js +2 -0
- package/dist/runtime/vue/useProvidersPanel.d.ts +232 -0
- package/dist/runtime/vue/useProvidersPanel.js +655 -0
- package/dist/types.d.mts +9 -0
- package/package.json +117 -4
- package/src/runtime/ai-sdk/index.ts +91 -0
- package/src/runtime/components/ForgeProvidersPanel.vue +449 -0
- package/src/runtime/editor/index.ts +157 -0
- package/src/runtime/model/errors.ts +31 -0
- package/src/runtime/server/credential-policy.ts +137 -0
- package/src/runtime/server/credential-store.ts +473 -0
- package/src/runtime/server/env-layers.ts +290 -0
- package/src/runtime/server/env.ts +46 -0
- package/src/runtime/server/harness-settings.ts +373 -0
- package/src/runtime/server/index.ts +24 -0
- package/src/runtime/server/provider-discovery.ts +164 -0
- package/src/runtime/server/provider-layers.ts +70 -0
- package/src/runtime/server/provider-service.ts +244 -0
- package/src/runtime/server/provider-settings.ts +192 -0
- package/src/runtime/server/provider-write.ts +438 -0
- package/src/runtime/server/settings-defaults.ts +87 -0
- package/src/runtime/shared/env-vars.ts +82 -0
- package/src/runtime/shared/harness-providers.ts +118 -0
- package/src/runtime/shared/harnesses.ts +34 -0
- package/src/runtime/shared/provider-registry.ts +391 -0
- package/src/runtime/shared/settings-types.ts +87 -0
- package/src/runtime/shims-vue.d.ts +8 -0
- package/src/runtime/vue/index.ts +15 -0
- package/src/runtime/vue/settings-modal-scope.ts +66 -0
- package/src/runtime/vue/useProvidersPanel.ts +1087 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
First release. Extracted from `@skaile/forge-common` (provider/settings half) and skaile-forge's editor model adapter; `@skaile/forge-common` is unchanged and stays installable for consumers that have not migrated.
|
|
6
|
+
|
|
7
|
+
- `@skaile/forge-settings/server`: provider registry vocabulary, layer read/write (`readProviderLayer`, `writeProviderLayer`, `upsertProviderEntry`, `removeProviderEntry`, `withProviderLayers`, `catalogPreset`), the credential store (AES-256-GCM, 64-hex `FORGE_CREDENTIAL_KEY`, reference as per-record AAD), `.env` layer helpers, provider inventory (`listAIProviders`, `listAIProviderModels`, `testAIProviderCredential`), harness settings rules, voice provider selection and legacy-settings migration. Imports no Vue, editor, AI SDK or agent session code.
|
|
8
|
+
- `@skaile/forge-settings/vue`: `useProvidersPanel`, `SettingsModalScope` (and its URL fields), and the browser-safe env/harness/registry vocabulary.
|
|
9
|
+
- `@skaile/forge-settings/nuxt`: registers `<ForgeProvidersPanel>` (needs `@nuxt/ui` registered first). No route, auto-import or authorization.
|
|
10
|
+
- `@skaile/forge-settings/ai-sdk`: `resolveRegistryLanguageModel(selector, { projectDir, env, roles?, policy? })` over `@skaile/workspaces/ai-sdk`'s `resolveLanguageModel`.
|
|
11
|
+
- `@skaile/forge-settings/editor`: `createEditorModelProvider({ registry, env, policy?, onFailure? })`, an implementation of `@skaile/forge-editor`'s `ModelProvider`, plus `editorModelProfiles` and `editorLanguageModel`.
|
|
12
|
+
|
|
13
|
+
Added over the extracted code:
|
|
14
|
+
|
|
15
|
+
- `CredentialPolicy` (`forms`, `envNames`): a host states which references may be resolved. `entryPolicyRefusal` checks an entry's `credential.ref` and every `${NAME}` interpolation in `base_url`, `headers` and `query_params` before anything is read; `applyCredentialPolicy` filters a registry. `CredentialStoreOptions.policy` and `.env`: a policy-bound call reads only the explicit `env` (an empty one when omitted), never `process.env`. `ProviderWriteScope.policy` refuses writes that name a refused reference.
|
|
16
|
+
- `CredentialKeyError` (`statusCode: 503`): only operations that need the encrypted store raise it; `env:` references resolve without a key. `CredentialDecryptError` for a replayed or altered blob.
|
|
17
|
+
- `ProviderWriteError` replaces h3's `createError` in the provider write helpers; it carries `statusCode`, `statusMessage` and `data`, which an H3 host answers unchanged. The package has no h3 dependency.
|
|
18
|
+
- `discoverProviderModels`: live model discovery with an explicit `status` (`live` | `static` | `unsupported` | `error`), so an offline catalog is never presented as live. Error text is built here, carries no remote response body, and has resolved secrets (and any `redact` strings) removed.
|
|
19
|
+
- `ModelResolutionError` (`registry_invalid` | `unknown_selector` | `policy_refused` | `unresolved`): framework-free, mapped to HTTP by the host.
|
|
20
|
+
|
|
21
|
+
Not included (host-owned): storage (`getUserSettings`/`saveUserSettings`), workspace ACLs and lock flags, agent sessions, a settings action catalogue.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Matthias Ortegro
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,95 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @skaile/forge-settings
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Provider and settings operations for Skaile forge apps, without the app's database, authentication or agent runtime.
|
|
4
|
+
|
|
5
|
+
| Entry | Contents | Peers it needs |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| `/server` | registry layers and writes, credential store, `.env` layers, provider inventory and discovery, harness settings rules, credential policy | none |
|
|
8
|
+
| `/vue` | `useProvidersPanel`, `SettingsModalScope`, browser-safe registry/env/harness vocabulary | `vue` |
|
|
9
|
+
| `/nuxt` | Nuxt module registering `<ForgeProvidersPanel>` | `nuxt`, `@nuxt/ui` |
|
|
10
|
+
| `/ai-sdk` | AI SDK `LanguageModel` of a registry selector | `ai` + the `@ai-sdk/*` provider the surface needs |
|
|
11
|
+
| `/editor` | the editor's `ModelProvider` over a registry | `@skaile/forge-editor`, `@ai-sdk/openai-compatible` |
|
|
12
|
+
|
|
13
|
+
Importing `/server` loads no Vue, editor, AI SDK or agent session code. Every peer is optional and used by one entry only.
|
|
14
|
+
|
|
15
|
+
## What stays with the host
|
|
16
|
+
|
|
17
|
+
Where settings are stored, who may write which scope, workspace ACLs, lock flags, and what a failure becomes over HTTP. The package supplies the operations (`upsertProviderEntry`, `removeProviderEntry`, `buildEnvSettingsDocument`, …) and the rules they enforce on a document; the host builds a `ProviderWriteScope` (file paths, effective env, lock state, optional `policy`) after its own authentication and permission check.
|
|
18
|
+
|
|
19
|
+
## Credential policy
|
|
20
|
+
|
|
21
|
+
A host that runs next to its own secrets (a database token, an encryption key) states up front which references may be resolved:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { type CredentialPolicy } from '@skaile/forge-settings/server'
|
|
25
|
+
|
|
26
|
+
const policy: CredentialPolicy = {
|
|
27
|
+
forms: ['env'], // no cmd:, keyring:, platform:
|
|
28
|
+
envNames: [/ASSISTENT_PROVIDER_[A-Z0-9_]+/, 'NUXT_AI_API_KEY'], // whole-name match
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The policy is checked against `credential.ref` and every `${NAME}` token in `base_url`, `headers` and `query_params` **before** anything is read; a refused reference is never resolved, looked up or requested. A policy-bound call reads only the `env` you pass (an empty one when omitted), never `process.env`. Without a policy, behaviour is the unrestricted forge-common behaviour.
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
const scope: ProviderWriteScope = { name: 'instance', file, below: [], env, lock, policy } // refuses writes naming a refused ref
|
|
36
|
+
discoverProviderModels('main', registry, { env, policy })
|
|
37
|
+
resolveRegistryLanguageModel('main/gpt-x', { projectDir, env, policy })
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Credential store
|
|
41
|
+
|
|
42
|
+
`keyring:<service>/<account>` references are stored AES-256-GCM encrypted in a JSON file; the reference is the additional authenticated data, so a blob cannot be replayed under another reference. The key is `FORGE_CREDENTIAL_KEY` (64 hex characters) or `options.key`. Without it only operations that need the store fail, with `CredentialKeyError` (`statusCode: 503`); `env:` references keep working. A blob that does not authenticate raises `CredentialDecryptError`.
|
|
43
|
+
|
|
44
|
+
## Model discovery
|
|
45
|
+
|
|
46
|
+
`discoverProviderModels(id, registry, { env, policy?, redact? })` returns `live`, `static` (the offline catalog, with the scrubbed reason the live request failed), `unsupported` (no catalog preset: let the admin type a model id) or `error`. Error text never contains a remote response body, and every secret the call resolved (plus `redact`) is removed from it, also in URL-encoded and base64 form.
|
|
47
|
+
|
|
48
|
+
## Models for the editor and the AI SDK
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
// server/utils/editor-models.ts: ModelProvider for @skaile/forge-editor
|
|
52
|
+
import { createEditorModelProvider, ModelResolutionError } from '@skaile/forge-settings/editor'
|
|
53
|
+
|
|
54
|
+
export const models = createEditorModelProvider({
|
|
55
|
+
registry: () => getProviderRegistry(home()),
|
|
56
|
+
env: () => effectiveEnv(),
|
|
57
|
+
policy, // refused entries are neither listed nor resolved
|
|
58
|
+
onFailure: (e) => createError({ statusCode: e.code === 'policy_refused' ? 403 : 400, statusMessage: e.message }),
|
|
59
|
+
})
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { resolveRegistryLanguageModel } from '@skaile/forge-settings/ai-sdk'
|
|
64
|
+
const { model } = await resolveRegistryLanguageModel('assistant-default/some-model', { projectDir, env, policy })
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Role-to-selector mapping belongs to the host's settings document; there is no global model locator. Failures are `ModelResolutionError` with a `code`; messages never carry a secret.
|
|
68
|
+
|
|
69
|
+
## Providers panel
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
// nuxt.config.ts: '@nuxt/ui' BEFORE this module
|
|
73
|
+
modules: ['@nuxt/ui', '@skaile/forge-settings/nuxt']
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```vue
|
|
77
|
+
<ForgeProvidersPanel
|
|
78
|
+
providers-url="/api/providers" providers-write-url="/api/providers"
|
|
79
|
+
environment-url="/api/settings/env" layer="instance" :read-only="!canAdmin"
|
|
80
|
+
@changed="reload" />
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The panel (`PUT|DELETE <writeUrl>/:id`, `GET <writeUrl>/detected`, `GET <providersUrl>`, `GET|PUT <environmentUrl>`) reads and writes only the routes you give it. The host serves them with the `/server` operations and decides who may call them. `SettingsModalScope` documents the same URL fields for hosts that compose a larger modal.
|
|
84
|
+
|
|
85
|
+
## Development
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
bun install
|
|
89
|
+
bun run prepare # generate module types
|
|
90
|
+
bun run typecheck
|
|
91
|
+
bun run test
|
|
92
|
+
bun run build
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Releases: push a `v*` tag equal to the `package.json` version; `publish.yml` publishes with npm trusted publishing.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { NuxtModule } from '@nuxt/schema';
|
|
2
|
+
|
|
3
|
+
/** `@skaile/forge-settings/nuxt` has no options: it registers one component. */
|
|
4
|
+
type ForgeSettingsOptions = Record<string, never>;
|
|
5
|
+
/**
|
|
6
|
+
* Nuxt module registering `<ForgeProvidersPanel>`, the narrow provider
|
|
7
|
+
* settings surface (registry editor, detected-in-environment adds, key entry).
|
|
8
|
+
*
|
|
9
|
+
* It installs no server route, no auto-import and no authorization: the host
|
|
10
|
+
* serves the panel's routes with `@skaile/forge-settings/server` and decides who
|
|
11
|
+
* may call them. Requires `@nuxt/ui` (^4.11) registered BEFORE this module in
|
|
12
|
+
* `modules`; the panel renders Nuxt UI primitives.
|
|
13
|
+
*/
|
|
14
|
+
declare const forgeSettingsModule: NuxtModule<ForgeSettingsOptions>;
|
|
15
|
+
|
|
16
|
+
export { forgeSettingsModule as default };
|
|
17
|
+
export type { ForgeSettingsOptions };
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineNuxtModule, createResolver, hasNuxtModule, addComponent } from '@nuxt/kit';
|
|
2
|
+
|
|
3
|
+
const forgeSettingsModule = defineNuxtModule({
|
|
4
|
+
meta: {
|
|
5
|
+
name: "@skaile/forge-settings",
|
|
6
|
+
configKey: "forgeSettings"
|
|
7
|
+
},
|
|
8
|
+
setup(_options, nuxt) {
|
|
9
|
+
const { resolve } = createResolver(import.meta.url);
|
|
10
|
+
if (!nuxt.options._prepare && !hasNuxtModule("@nuxt/ui", nuxt)) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
"[@skaile/forge-settings] requires the '@nuxt/ui' module, but it was not registered before '@skaile/forge-settings/nuxt'. Add '@nuxt/ui' to the `modules` array in your nuxt.config *before* '@skaile/forge-settings/nuxt' (and install it as a dependency): <ForgeProvidersPanel> renders Nuxt UI primitives (<UModal>, <UButton>, <UInput>, \u2026)."
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
addComponent({
|
|
16
|
+
name: "ForgeProvidersPanel",
|
|
17
|
+
filePath: resolve("./runtime/components/ForgeProvidersPanel.vue"),
|
|
18
|
+
global: false
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export { forgeSettingsModule as default };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@skaile/forge-settings/ai-sdk` — the AI SDK language model of a registry
|
|
3
|
+
* selector, resolved by `@skaile/workspaces/ai-sdk` and gated by the host's
|
|
4
|
+
* credential policy.
|
|
5
|
+
*
|
|
6
|
+
* Workspaces owns endpoint, header and credential wiring for every surface;
|
|
7
|
+
* this module only decides *whether* an entry may be resolved and against
|
|
8
|
+
* *which* environment. It is not a service locator: the caller passes the
|
|
9
|
+
* selector (role-to-selector mapping belongs to the host's settings document)
|
|
10
|
+
* and the environment explicitly.
|
|
11
|
+
*
|
|
12
|
+
* Provider SDKs (`@ai-sdk/anthropic`, `@ai-sdk/openai`,
|
|
13
|
+
* `@ai-sdk/openai-compatible`) are optional peers of Workspaces: install the
|
|
14
|
+
* one the selected surface needs.
|
|
15
|
+
*/
|
|
16
|
+
import { type ResolvedLanguageModel } from "@skaile/workspaces/ai-sdk";
|
|
17
|
+
import { type CredentialPolicy } from "../server/credential-policy.js";
|
|
18
|
+
export { ModelResolutionError } from "../model/errors.js";
|
|
19
|
+
export type { ModelResolutionCode } from "../model/errors.js";
|
|
20
|
+
export type { ResolvedLanguageModel };
|
|
21
|
+
/** Options for {@link resolveRegistryLanguageModel}. */
|
|
22
|
+
export interface ResolveRegistryLanguageModelOptions {
|
|
23
|
+
/** Workspace whose `.skaile/providers.yml` is the workspace layer. */
|
|
24
|
+
projectDir: string;
|
|
25
|
+
/**
|
|
26
|
+
* The environment `env:` credential references are read from. Required, so a
|
|
27
|
+
* host never reads the ambient process by accident.
|
|
28
|
+
*/
|
|
29
|
+
env: Record<string, string | undefined>;
|
|
30
|
+
/** Role → model-ref map `@role` selectors resolve against. */
|
|
31
|
+
roles?: Record<string, string>;
|
|
32
|
+
/**
|
|
33
|
+
* Which credential references may be resolved. The selected entry is checked
|
|
34
|
+
* before anything is read; a refused one is a `policy_refused` failure.
|
|
35
|
+
*/
|
|
36
|
+
policy?: CredentialPolicy;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The AI SDK model for `selector` (`<providerId>/<modelId>`, a bare model id or
|
|
40
|
+
* `@role`), resolved by Workspaces against the registry on disk.
|
|
41
|
+
*
|
|
42
|
+
* @throws {ModelResolutionError} `registry_invalid` · `unknown_selector` ·
|
|
43
|
+
* `policy_refused` · `unresolved` (credential, endpoint or provider SDK).
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveRegistryLanguageModel(selector: string, options: ResolveRegistryLanguageModelOptions): Promise<ResolvedLanguageModel>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { parseModelRef } from "@skaile/workspaces/core";
|
|
2
|
+
import { resolveLanguageModel } from "@skaile/workspaces/ai-sdk";
|
|
3
|
+
import { loadMergedProviderRegistry } from "@skaile/workspaces/sdk/bridge";
|
|
4
|
+
import { entryPolicyRefusal } from "../server/credential-policy.js";
|
|
5
|
+
import { ModelResolutionError } from "../model/errors.js";
|
|
6
|
+
export { ModelResolutionError } from "../model/errors.js";
|
|
7
|
+
export async function resolveRegistryLanguageModel(selector, options) {
|
|
8
|
+
const { merged, diagnostics } = loadMergedProviderRegistry({ projectDir: options.projectDir });
|
|
9
|
+
const errors = diagnostics.filter((d) => d.severity === "error").map((d) => d.path ? `${d.path}: ${d.message}` : d.message);
|
|
10
|
+
if (errors.length > 0) {
|
|
11
|
+
throw new ModelResolutionError("registry_invalid", `providers registry: ${errors.join("; ")}`);
|
|
12
|
+
}
|
|
13
|
+
const ref = parseModelRef(selector, merged, options.roles);
|
|
14
|
+
if (!ref) {
|
|
15
|
+
throw new ModelResolutionError("unknown_selector", `no provider serves '${selector}'`);
|
|
16
|
+
}
|
|
17
|
+
const entry = merged.providers[ref.providerId];
|
|
18
|
+
if (entry && options.policy) {
|
|
19
|
+
const refusal = entryPolicyRefusal(entry, options.policy);
|
|
20
|
+
if (refusal) {
|
|
21
|
+
throw new ModelResolutionError("policy_refused", `provider '${ref.providerId}': ${refusal}`, {
|
|
22
|
+
providerId: ref.providerId
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
return await resolveLanguageModel(selector, {
|
|
28
|
+
projectDir: options.projectDir,
|
|
29
|
+
env: options.env,
|
|
30
|
+
...options.roles ? { roles: options.roles } : {}
|
|
31
|
+
});
|
|
32
|
+
} catch (cause) {
|
|
33
|
+
throw new ModelResolutionError(
|
|
34
|
+
"unresolved",
|
|
35
|
+
cause instanceof Error ? cause.message : String(cause),
|
|
36
|
+
{ providerId: ref.providerId, cause }
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type ProvidersPanelLayer } from "../vue/useProvidersPanel.js";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
/** `GET` merged view for this scope (`/api/providers` | `/api/workspaces/:id/providers`). */
|
|
4
|
+
providersUrl: string;
|
|
5
|
+
/** `PUT|DELETE ${providersWriteUrl}/:id`; `GET ${providersWriteUrl}/detected`. */
|
|
6
|
+
providersWriteUrl: string;
|
|
7
|
+
/** Catalog preset summaries. Default `/api/providers/presets`. */
|
|
8
|
+
presetsUrl?: string;
|
|
9
|
+
/** The scope's `.env` route: hand-entered keys. Omitted, key entry is hidden. */
|
|
10
|
+
environmentUrl?: string;
|
|
11
|
+
/** Edit/Delete are offered only for entries this layer defines. */
|
|
12
|
+
layer: ProvidersPanelLayer;
|
|
13
|
+
/** Disables add, edit and delete. */
|
|
14
|
+
readOnly?: boolean;
|
|
15
|
+
};
|
|
16
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
17
|
+
changed: () => any;
|
|
18
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
19
|
+
onChanged?: (() => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
export default _default;
|