@qilin-agent/client-ui-settings-models 0.0.0-stage → 3.1.3

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.
@@ -0,0 +1,113 @@
1
+ /** Copy dictionaries for the Models settings section. */
2
+ /** English strings (the key-set source of truth for this pair). */
3
+ export declare const en: {
4
+ nav: string;
5
+ title: string;
6
+ intro: string;
7
+ edit: string;
8
+ editProvider: string;
9
+ remove: string;
10
+ removeProvider: string;
11
+ deleteTitle: string;
12
+ deleteDescription: string;
13
+ deleteDescriptionWithCredential: string;
14
+ deleteConfirm: string;
15
+ deleting: string;
16
+ add: string;
17
+ provider: string;
18
+ close: string;
19
+ cancel: string;
20
+ apply: string;
21
+ applying: string;
22
+ savedProvider: string;
23
+ credentialConfigured: string;
24
+ credentialMissing: string;
25
+ readOnly: string;
26
+ loadFailed: string;
27
+ conflict: string;
28
+ retry: string;
29
+ keyInput: string;
30
+ keyPlaceholder: string;
31
+ keyPlaceholderNative: string;
32
+ keyStored: string;
33
+ keyEnvLocked: string;
34
+ customized: string;
35
+ baseUrl: string;
36
+ baseUrlDefault: string;
37
+ deepSeekBaseUrl: string;
38
+ deepSeekEndpointHint: string;
39
+ models: string;
40
+ modelsInherited: string;
41
+ modelsCustomized: string;
42
+ resetModels: string;
43
+ model: string;
44
+ modelId: string;
45
+ modelName: string;
46
+ modelNamePlaceholder: string;
47
+ contextWindow: string;
48
+ contextWindowPlaceholder: string;
49
+ maxTokens: string;
50
+ maxTokensPlaceholder: string;
51
+ modelAdvanced: string;
52
+ modelInputTypes: string;
53
+ modelInputText: string;
54
+ modelInputImage: string;
55
+ addModel: string;
56
+ removeModel: string;
57
+ modelsEmpty: string;
58
+ keyBlank: string;
59
+ keyBlankNew: string;
60
+ keyIllegalCharacters: string;
61
+ modelIdRequired: string;
62
+ modelIdDuplicate: string;
63
+ modelNameInvalid: string;
64
+ modelContextInvalid: string;
65
+ modelMaxTokensInvalid: string;
66
+ advancedHint: string;
67
+ modelCapacityInvalid: string;
68
+ modelDuplicate: string;
69
+ fetchModels: string;
70
+ fetching: string;
71
+ fetchNeedsBaseUrl: string;
72
+ fetchEmpty: string;
73
+ fetchTitle: string;
74
+ fetchDescription: string;
75
+ fetchSearch: string;
76
+ fetchNoMatches: string;
77
+ fetchSelectAll: string;
78
+ fetchDeselectAll: string;
79
+ fetchAdopt: string;
80
+ customAdd: string;
81
+ customTitle: string;
82
+ customTag: string;
83
+ customRoute: string;
84
+ customRouteHint: string;
85
+ customRouteInvalid: string;
86
+ customRouteTaken: string;
87
+ customDisplayName: string;
88
+ customApi: string;
89
+ customApiUnset: string;
90
+ protocolOpenAiCompletions: string;
91
+ protocolOpenAiResponses: string;
92
+ protocolAnthropicMessages: string;
93
+ customNeedsBaseUrl: string;
94
+ customBaseUrlInvalid: string;
95
+ customNeedsModels: string;
96
+ customBaseUrlPlaceholder: string;
97
+ settingsPathUnresolvable: string;
98
+ create: string;
99
+ creating: string;
100
+ onboardingTitle: string;
101
+ onboardingDescription: string;
102
+ onboardingLater: string;
103
+ onboardingSave: string;
104
+ onboardingSaving: string;
105
+ keyRequired: string;
106
+ };
107
+ /** The settings.models namespace key union. */
108
+ export type ModelsKey = keyof typeof en;
109
+ /** Chinese strings (same keys as {@link en}). */
110
+ export declare const zh: {
111
+ [Key in keyof typeof en]: string;
112
+ };
113
+ //# sourceMappingURL=locales.d.ts.map
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The Host reads and writes the Models cards perform, as callbacks built in the
3
+ * plugin body. Cards receive these instead of a context: the outcomes name what
4
+ * a card renders — a stored view, a stale revision, a refusal message — so the
5
+ * failure codes and Remote namespaces stay in the apply world.
6
+ */
7
+ import type { Context as ClientContext } from '@qilin-agent/kylin';
8
+ import type { CredentialInfo, LlmDiscoveredModel, LlmModelDiscoveryRequest, SettingsNamespaceView, SettingsPathOpView } from '@qilin-agent/api-remotes/client';
9
+ /** What one namespace write answered. */
10
+ export type SettingsWriteOutcome =
11
+ /** Committed; the view carries the stored user subtree and the new revision. */
12
+ {
13
+ readonly kind: 'written';
14
+ readonly view: SettingsNamespaceView;
15
+ }
16
+ /**
17
+ * The stored revision moved after the card read it, so the draft is stale.
18
+ * The message stays for callers that report the Host diagnostic as it is.
19
+ */
20
+ | {
21
+ readonly kind: 'conflict';
22
+ readonly message: string;
23
+ }
24
+ /** Any other refusal, with the Host's own diagnostic. */
25
+ | {
26
+ readonly kind: 'refused';
27
+ readonly message: string;
28
+ };
29
+ /** What one endpoint interrogation answered. */
30
+ export type ModelDiscoveryOutcome =
31
+ /** The candidates the provider disclosed, in its own order. */
32
+ {
33
+ readonly kind: 'found';
34
+ readonly models: readonly LlmDiscoveredModel[];
35
+ }
36
+ /** The interrogation was refused, with the Host's own diagnostic. */
37
+ | {
38
+ readonly kind: 'refused';
39
+ readonly message: string;
40
+ };
41
+ /** The Host operations the Models page and its cards invoke. */
42
+ export interface ModelsOperations {
43
+ /**
44
+ * Read one credential reference's state.
45
+ * @param ref - credential reference name.
46
+ * @returns the state, or undefined when the reference is unknown or the read was refused.
47
+ */
48
+ describeCredential(ref: string): Promise<CredentialInfo | undefined>;
49
+ /**
50
+ * Store one credential literal under its reference.
51
+ * @param ref - credential reference name.
52
+ * @param value - the literal to store.
53
+ * @returns the refusal message, or undefined once stored.
54
+ */
55
+ storeCredential(ref: string, value: string): Promise<string | undefined>;
56
+ /**
57
+ * Remove one credential reference (idempotent).
58
+ * @param ref - credential reference name.
59
+ * @returns the refusal message, or undefined once removed.
60
+ */
61
+ removeCredential(ref: string): Promise<string | undefined>;
62
+ /**
63
+ * Apply path operations to one settings namespace.
64
+ * @param ns - settings namespace identity.
65
+ * @param ops - ordered path operations against the stored section, as the
66
+ * wire takes them (the Remote signature owns the array).
67
+ * @param expectedRevision - revision the draft was opened at, or undefined to write unfenced.
68
+ * @returns the write outcome the card renders from.
69
+ */
70
+ writeSettings(ns: string, ops: SettingsPathOpView[], expectedRevision: number | undefined): Promise<SettingsWriteOutcome>;
71
+ /**
72
+ * Ask a provider endpoint what models it serves.
73
+ * @param settingsNs - namespace whose adapter family answers.
74
+ * @param request - endpoint facts as the form currently shows them.
75
+ * @returns the candidates, or the refusal.
76
+ */
77
+ discoverModels(settingsNs: string, request: LlmModelDiscoveryRequest): Promise<ModelDiscoveryOutcome>;
78
+ }
79
+ /**
80
+ * Bind the page's Host operations to the plugin's own Remote namespaces.
81
+ * @param ctx - the page plugin's context, which declares `remote.credentials`,
82
+ * `remote.llm`, and `remote.settings` in its own `inject`.
83
+ * @returns the callbacks the section and its cards are injected with.
84
+ */
85
+ export declare function createModelsOperations(ctx: ClientContext): ModelsOperations;
86
+ //# sourceMappingURL=operations.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Product names for the wire protocols a pi-ai route may speak. The pickers
3
+ * show these instead of the schema identifiers (`openai-completions`), which
4
+ * are what `settings.yaml` carries and what the option values stay.
5
+ */
6
+ import type { ModelsKey } from './locales.ts';
7
+ /**
8
+ * The picker text for one protocol identifier.
9
+ * @param t - section copy.
10
+ * @param protocol - the schema identifier of the protocol.
11
+ * @returns the product name this page knows the protocol by; a protocol the
12
+ * adapter adds before this page names it shows its identifier, the spelling
13
+ * `settings.yaml` needs anyway.
14
+ */
15
+ export declare function protocolLabel(t: (key: ModelsKey) => string, protocol: string): string;
16
+ //# sourceMappingURL=protocol-label.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { SettingsSchemaService } from '@qilin-agent/client-ui-settings/client';
2
+ /** Plain schema callbacks exposed to Models stores and presentation components. */
3
+ export type SettingsSchemaOperations = Pick<SettingsSchemaService, 'rehydrate' | 'validate' | 'nodeAtPath' | 'getPath' | 'hasPath' | 'setPath' | 'deletePath'>;
4
+ /**
5
+ * Hide the Cordis service identity behind bound schema callbacks.
6
+ * @param service - settings-owned schema service available in the apply context.
7
+ * @returns callbacks that cannot expose the service context to React components.
8
+ */
9
+ export declare function createSettingsSchemaOperations(service: SettingsSchemaService): SettingsSchemaOperations;
10
+ //# sourceMappingURL=schema-operations.d.ts.map
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Models-page extension slots — the two seats through which a plugin
3
+ * distributed outside this repository adds UI to the Models settings section
4
+ * without editing it.
5
+ *
6
+ * `settings.models.provider-card` is keyed by the row's owning settings
7
+ * namespace (`ProviderDirectoryEntry.settingsNs`): an adapter family's
8
+ * companion plugin registers one entry under the family's namespace and
9
+ * receives every card of that family — shipped, added, and hand-declared rows
10
+ * alike — while the section never learns what the namespace means. Keying on
11
+ * the namespace follows `settings.plugin.item`, and the key domain stays the
12
+ * open string space because hand-declared route ids are user-chosen at
13
+ * runtime.
14
+ *
15
+ * TYPE HOME RATIONALE: the Models section declares these slots at runtime,
16
+ * and a plugin registering an extension already depends on this package for
17
+ * the declaration. The types therefore live with their declarer.
18
+ */
19
+ import type { ProviderDirectoryEntry } from './store.ts';
20
+ declare module '@qilin-agent/client-ui-slots' {
21
+ interface SlotMap {
22
+ /**
23
+ * One provider card's adapter extension area, dispatched with
24
+ * `entryKey = settingsNs` on every card that renders a directory row: a
25
+ * saved row's card (its first-run setup posture included) and the
26
+ * add-provider draft card. The hand-declared draft card has no directory
27
+ * row yet, so it dispatches nothing until saved. Without a registrant the
28
+ * area renders nothing.
29
+ */
30
+ 'settings.models.provider-card': {
31
+ kind: 'keyed';
32
+ scope: 'root';
33
+ owner: ProviderCardExtrasOwnerProps;
34
+ };
35
+ /**
36
+ * Ordered extension area after the provider rows and the add controls.
37
+ * Without a registrant the area renders nothing.
38
+ */
39
+ 'settings.models.footer': {
40
+ kind: 'list';
41
+ scope: 'root';
42
+ owner: ModelsFooterOwnerProps;
43
+ };
44
+ }
45
+ }
46
+ /** Owner share of one provider-card extension occurrence. */
47
+ export interface ProviderCardExtrasOwnerProps {
48
+ /** The card's directory row (route id, display name, settings address, live state). */
49
+ provider: ProviderDirectoryEntry;
50
+ /** Whether any layer configures this provider (its profile resolves); `false` while the add-provider draft edits a dormant row. */
51
+ configured: boolean;
52
+ /** Whether the row's referenced api-key credential is confirmed configured (the page's credential join). */
53
+ keyConfigured: boolean;
54
+ }
55
+ /** Owner share of the footer area (the section supplies nothing). */
56
+ export interface ModelsFooterOwnerProps {
57
+ /** Marker field: footer owner props are intentionally empty. */
58
+ children?: never;
59
+ }
60
+ //# sourceMappingURL=slot-contract.d.ts.map
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Models settings page store: one snapshot joining the configurable-provider
3
+ * directory (`llm/listProviders` joined with `llm/listConfigurableProviders`),
4
+ * the settings namespaces (shared settings mirror),
5
+ * and the referenced credentials (`credentials/describe`). The host stays the
6
+ * single fact source — every mutation writes through the wire and the page
7
+ * re-renders from the next describe, pushed or refetched.
8
+ */
9
+ import type { Context as ClientContext } from '@qilin-agent/kylin';
10
+ import type { CredentialInfo, LlmConfigurableProvider, LlmProviderInfo, SettingsNamespaceView } from '@qilin-agent/api-remotes/client';
11
+ import type { SnapshotStore } from '@qilin-agent/client-store';
12
+ import type { SettingsDescribeFace } from '@qilin-agent/client-ui-settings/client';
13
+ import type { SettingsSchemaOperations } from './schema-operations.ts';
14
+ /** One provider row after joining the configurable directory with live routes. */
15
+ export interface ProviderDirectoryEntry {
16
+ readonly provider: string;
17
+ readonly displayName: string;
18
+ readonly settingsNs: string;
19
+ readonly settingsPath: readonly string[];
20
+ readonly active: boolean;
21
+ readonly declared?: boolean;
22
+ readonly error?: string;
23
+ }
24
+ /**
25
+ * Join declared configurable providers with the currently registered routes.
26
+ * @param registered - live provider routes in registration order.
27
+ * @param directory - declared configurable providers in declaration order.
28
+ * @returns declared rows followed by live routes with no declaration.
29
+ */
30
+ export declare function joinProviderDirectory(registered: readonly LlmProviderInfo[], directory: readonly LlmConfigurableProvider[]): ProviderDirectoryEntry[];
31
+ /** One provider row the page renders. */
32
+ export interface ProviderRow {
33
+ /** The directory entry (route id, display name, settings address, live state). */
34
+ entry: ProviderDirectoryEntry;
35
+ /** Whether any layer configures this provider (its profile resolves). */
36
+ configured: boolean;
37
+ /** Whether the user layer alone carries the profile (removal restores the base). */
38
+ removable: boolean;
39
+ /** The credential reference the resolved profile names, when one does. */
40
+ apiKeyEnv: string | undefined;
41
+ /** Credential state for {@link apiKeyEnv}, once described. */
42
+ credential: CredentialInfo | undefined;
43
+ /**
44
+ * Credential state for the page's derived `<ROUTE>_API_KEY`, described only
45
+ * while the profile names no reference — the provider-card seat's
46
+ * `keyConfigured` fact for dormant and keyless rows, matching the editor's
47
+ * own derivation rule.
48
+ */
49
+ derivedCredential?: CredentialInfo;
50
+ }
51
+ /** Page snapshot. */
52
+ export interface ModelsSettingsState {
53
+ status: 'idle' | 'loading' | 'ready' | 'error';
54
+ /** Whole-load failure text; row-level write failures stay in the editor. */
55
+ error: string | null;
56
+ /** Credential enrichment failure; provider/settings rows remain usable. */
57
+ credentialError: string | null;
58
+ /** Whether the settings provider accepts writes. */
59
+ writable: boolean;
60
+ /** Every configurable provider joined with its configured/credential state. */
61
+ rows: readonly ProviderRow[];
62
+ /** Namespace views by ns, for the editor's schema/layers/secrets. */
63
+ namespaces: ReadonlyMap<string, SettingsNamespaceView>;
64
+ }
65
+ /**
66
+ * Derive the conventional credential reference for a provider route: the v1
67
+ * page never asks for an environment-variable name, so a typed key stores
68
+ * under this derived reference and the profile records it as `apiKeyEnv`.
69
+ * @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).
70
+ * @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).
71
+ */
72
+ export declare function deriveKeyRef(provider: string): string;
73
+ /**
74
+ * The wire protocols a hand-declared route may name, read out of the owning
75
+ * namespace's own schema. This stays a schema read rather than a wire field so
76
+ * the choices the page offers cannot drift from the ones the adapter accepts:
77
+ * both come from the same `Config`.
78
+ * @param namespace - the namespace view whose schema declares the profile shape.
79
+ * @param schema - settings schema operations.
80
+ * @returns the protocol identifiers, or an empty list when the schema has none.
81
+ */
82
+ export declare function protocolChoices(namespace: SettingsNamespaceView | undefined, schema: SettingsSchemaOperations): string[];
83
+ /** The models settings page controller (one per settings surface). */
84
+ export declare class ModelsSettingsStore {
85
+ private readonly ctx;
86
+ private readonly schema;
87
+ private readonly describeFace;
88
+ /** The snapshot the section renders from (uSES-safe store). */
89
+ readonly store: SnapshotStore<ModelsSettingsState>;
90
+ /** Latest load wins; an older response never overwrites a newer one. */
91
+ private generation;
92
+ /**
93
+ * @param ctx - the page plugin's context, whose `remote.llm` and
94
+ * `remote.credentials` namespaces carry the directory and credential reads.
95
+ * @param schema - settings-owned schema and immutable path operations.
96
+ * @param describeFace - the shared mirror's describe face (namespace views and writability).
97
+ */
98
+ constructor(ctx: ClientContext, schema: SettingsSchemaOperations, describeFace: SettingsDescribeFace);
99
+ /**
100
+ * Refresh the whole page snapshot: the provider directory and the mirror's
101
+ * settings answer in parallel, then one batched credential describe over
102
+ * every referenced ref. Provider failure or absence of an initial settings
103
+ * answer keeps the last good rows and surfaces an error; a failed settings
104
+ * refresh reuses the mirror's held view.
105
+ * @returns nothing; the snapshot carries the outcome.
106
+ */
107
+ load(): Promise<void>;
108
+ /** Publish one load's failure text, unless a newer load already took over. */
109
+ private failLoad;
110
+ }
111
+ /**
112
+ * Whether a joined row can serve model requests as it stands: the route is
113
+ * registered with the adapter registry, and whatever credential its resolved
114
+ * profile names is stored. A profile naming no reference authenticates through
115
+ * the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs
116
+ * nothing), as does a live route with no settings address at all, so neither
117
+ * owes this page a key.
118
+ * @param row - one joined provider row.
119
+ * @returns whether the user already has this provider to talk to.
120
+ */
121
+ export declare function providerUsable(row: ProviderRow): boolean;
122
+ /** First-run onboarding readiness derived only from the shared Models join. */
123
+ export type OnboardingReadiness = {
124
+ kind: 'loading';
125
+ } | {
126
+ kind: 'adapter-absent';
127
+ } | {
128
+ kind: 'provider-ready';
129
+ } | {
130
+ kind: 'credential-missing';
131
+ } | {
132
+ kind: 'unavailable';
133
+ reason: 'load-failed' | 'provider-inactive' | 'credentials-unavailable' | 'settings-read-only' | 'credential-read-only';
134
+ };
135
+ /**
136
+ * Project first-run readiness from the provider/settings/credential join used
137
+ * by the Models page. The step exists to leave the user with a model to talk
138
+ * to, so ANY usable provider ends it; only when none exists does the official
139
+ * DeepSeek route — the one route the prompt can offer a key field for — decide
140
+ * whether prompting can help. A missing official configurable-provider
141
+ * declaration means the adapter is not repairable by navigating to Models.
142
+ * @param state - current shared Models join snapshot.
143
+ * @returns the onboarding state without reading a parallel fact source.
144
+ */
145
+ export declare function onboardingReadiness(state: ModelsSettingsState): OnboardingReadiness;
146
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1,4 @@
1
+ /** Host loader entry for the browser implementation exported from `./client`. */
2
+ /** Host plugin body — no host-side behavior for the models settings plugin. */
3
+ export declare function apply(): void;
4
+ //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,69 @@
1
1
  {
2
2
  "name": "@qilin-agent/client-ui-settings-models",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "description": "Models settings and shared product-onboarding dialogs over existing settings and credential joins",
4
+ "version": "3.1.3",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/kkutysllb/QiLin.git",
11
+ "directory": "packages/client/ui-settings-models"
12
+ },
13
+ "engines": {
14
+ "node": "^22.19.0 || >=24.0.0"
15
+ },
16
+ "type": "module",
17
+ "main": "lib/index.js",
18
+ "types": "lib/types/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./lib/types/index.d.ts",
22
+ "default": "./lib/index.js"
23
+ },
24
+ "./client": {
25
+ "types": "./lib/types/client/index.d.ts",
26
+ "default": "./lib/client.js"
27
+ },
28
+ "./src/*": "./src/*",
29
+ "./package.json": "./package.json"
30
+ },
31
+ "qilin": {
32
+ "client": {
33
+ "inject": [
34
+ "@qilin-agent/client-ui-settings",
35
+ "@qilin-agent/client-locale",
36
+ "@qilin-agent/api-remotes"
37
+ ],
38
+ "platform": "web"
39
+ }
40
+ },
41
+ "license": "MIT",
42
+ "peerDependencies": {
43
+ "@qilin-agent/kylin": "~4.0.3"
44
+ },
45
+ "devDependencies": {
46
+ "@types/react": "~18.3.1",
47
+ "react": "^18.2.0",
48
+ "@qilin-agent/remote-mock": "3.1.3",
49
+ "@qilin-agent/api-remotes": "3.1.3",
50
+ "@qilin-agent/client-store": "3.1.3",
51
+ "@qilin-agent/client-test-runtime": "3.1.3",
52
+ "@qilin-agent/client-ui-primitives": "3.1.3",
53
+ "@qilin-agent/client-locale": "3.1.3",
54
+ "@qilin-agent/client-ui-slots": "3.1.3",
55
+ "@qilin-agent/client-ui-settings": "3.1.3",
56
+ "@qilin-agent/client-ui-renderer": "3.1.3",
57
+ "@qilin-agent/kylin": "~4.0.3",
58
+ "@qilin-agent/util-values": "3.1.3"
59
+ },
60
+ "files": [
61
+ "lib/index.js",
62
+ "lib/client.js",
63
+ "lib/types/**/*.d.ts"
64
+ ],
65
+ "scripts": {
66
+ "bundle": "tsdown",
67
+ "watch": "tsdown --watch"
68
+ }
6
69
  }