@dsh-ai-providers/typesafe 0.5.0 → 0.5.2
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/lib/client.js +13 -13
- package/lib/client.js.map +1 -1
- package/package.json +15 -15
package/lib/client.js
CHANGED
|
@@ -264,8 +264,8 @@ window.__ModuleLoader__.load({
|
|
|
264
264
|
saving: t("saving")
|
|
265
265
|
});
|
|
266
266
|
//#endregion
|
|
267
|
-
//#region \0css-module:/home/
|
|
268
|
-
const css = ".
|
|
267
|
+
//#region \0css-module:/home/runner/work/dsh-ai-providers/dsh-ai-providers/packages/dsh-ai-typesafe/src/client/TypeSafeSurface.module.css.mjs
|
|
268
|
+
const css = ".ai_M0yd5a_section{flex-direction:column;gap:16px;min-width:0;display:flex}.ai_M0yd5a_title{color:var(--dsw-alias-label-primary);margin:0;font-size:16px;font-weight:500;line-height:24px}.ai_M0yd5a_providerTitle{color:var(--dsw-alias-label-primary);margin:0;font-size:14px;font-weight:500;line-height:22px}.ai_M0yd5a_description{max-width:72ch;color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:20px}.ai_M0yd5a_providerDescription{max-width:72ch;color:var(--dsw-alias-label-secondary);margin:0;font-size:12px;line-height:18px}.ai_M0yd5a_list{gap:16px;min-width:0;display:grid}.ai_M0yd5a_card{border:.5px solid var(--dsw-alias-settings-card-stroke);border-radius:var(--dsw-radius-xl);background:var(--dsw-alias-settings-card-fill);gap:12px;min-width:0;padding:16px;display:grid}.ai_M0yd5a_field{min-width:0;color:var(--dsw-alias-label-primary);gap:5px;font-size:13px;line-height:20px;display:grid}.ai_M0yd5a_field input,.ai_M0yd5a_field select{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);width:min(100%,560px);min-width:0;min-height:32px;color:var(--dsw-alias-label-primary);font:inherit;padding:4px 8px}.ai_M0yd5a_field input:focus-visible,.ai_M0yd5a_field select:focus-visible{border-color:var(--dsw-alias-state-business-primary);outline:none}.ai_M0yd5a_field small{max-width:72ch;color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.ai_M0yd5a_actions{flex-wrap:wrap;gap:8px;display:flex}.ai_M0yd5a_empty{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px}";
|
|
269
269
|
const key = "@dsh-ai-providers/typesafe/src/client/TypeSafeSurface.module.css";
|
|
270
270
|
let tag = document.querySelector("style[data-plugin-css=" + JSON.stringify(key) + "]");
|
|
271
271
|
if (tag === null) {
|
|
@@ -276,16 +276,16 @@ window.__ModuleLoader__.load({
|
|
|
276
276
|
}
|
|
277
277
|
tag.textContent = css;
|
|
278
278
|
var TypeSafeSurface_module_css_default = {
|
|
279
|
-
"
|
|
280
|
-
"
|
|
281
|
-
"
|
|
282
|
-
"
|
|
283
|
-
"
|
|
284
|
-
"
|
|
285
|
-
"
|
|
286
|
-
"
|
|
287
|
-
"
|
|
288
|
-
"
|
|
279
|
+
"field": "ai_M0yd5a_field",
|
|
280
|
+
"actions": "ai_M0yd5a_actions",
|
|
281
|
+
"description": "ai_M0yd5a_description",
|
|
282
|
+
"providerTitle": "ai_M0yd5a_providerTitle",
|
|
283
|
+
"section": "ai_M0yd5a_section",
|
|
284
|
+
"card": "ai_M0yd5a_card",
|
|
285
|
+
"providerDescription": "ai_M0yd5a_providerDescription",
|
|
286
|
+
"list": "ai_M0yd5a_list",
|
|
287
|
+
"empty": "ai_M0yd5a_empty",
|
|
288
|
+
"title": "ai_M0yd5a_title"
|
|
289
289
|
};
|
|
290
290
|
//#endregion
|
|
291
291
|
//#region src/client/TypeSafeCard.tsx
|
|
@@ -480,7 +480,7 @@ window.__ModuleLoader__.load({
|
|
|
480
480
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
481
481
|
variant: "outline",
|
|
482
482
|
size: "sm",
|
|
483
|
-
disabled: key.trim() === "" || saving || status?.writable === false,
|
|
483
|
+
disabled: disabled || key.trim() === "" || saving || status?.writable === false,
|
|
484
484
|
onClick: () => {
|
|
485
485
|
saveKey();
|
|
486
486
|
},
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["SettingsFormModel","settingsTextField","settingsNumberField","css","SettingsForm","SettingsValueField","css","SettingsForm","Button","useState","SettingsSecretField"],"sources":["../../dsh-ai-core/src/capabilities.ts","../../dsh-ai-core/src/api.ts","../src/ids.ts","../src/client/controller.ts","../src/client/locales.ts","../src/client/TypeSafeCard.tsx","../src/client/TypeSafeConnections.tsx","../src/client/index.ts"],"sourcesContent":["import type { EmbeddingService } from './embedding.ts'\nimport type { RerankService } from './rerank.ts'\nimport type { TtsService } from './tts.ts'\nimport type { SttService } from './stt.ts'\nimport type { ImageGenerationService } from './image.ts'\nimport type { DecisionService } from './decision.ts'\n\n/**\n * The service each capability is offered as. Adding a capability is adding a line here, a\n * service class beside `EmbeddingService`, and its name in {@link SERVICE_NAMES}.\n */\nexport interface CapabilityServices {\n embedding: EmbeddingService\n rerank: RerankService\n tts: TtsService\n stt: SttService\n image: ImageGenerationService\n decision: DecisionService\n}\n\nexport type Capability = keyof CapabilityServices\n\n/** Every capability, in the order a settings UI lists them. */\nexport const CAPABILITIES = ['embedding', 'rerank', 'tts', 'stt', 'image', 'decision'] as const satisfies readonly Capability[]\n\n/** The name of the service that offers each capability on the Cordis context (`ctx.embeddings`, `ctx.rerankers`). */\nexport const SERVICE_NAMES = { embedding: 'embeddings', rerank: 'rerankers', tts: 'textToSpeech', stt: 'apiSpeechToText', image: 'imageGeneration', decision: 'decisions' } as const satisfies Record<Capability, string>\n\n/** The slot a capability's tab declares for its providers' configuration: a slot has one declarer, so each tab has its own. */\nexport type ProviderSlotName = `ai.provider.${Capability}`\n\nexport const providerSlotName = (capability: Capability): ProviderSlotName => `ai.provider.${capability}`\n\n/** The id of a provider's entry in the slot of its capability (see {@link providerSlotName}). */\nexport const providerSlotId = (capability: Capability, providerId: string): string => `${capability}:${providerId}`\n\n/** The provider and capability an entry of the `ai.provider` slot stands for, or `undefined` for an id that is not one. */\nexport function parseProviderSlotId(id: string): { capability: Capability; providerId: string } | undefined {\n const at = id.indexOf(':')\n const capability = id.slice(0, at)\n return at > 0 && (CAPABILITIES as readonly string[]).includes(capability) ? { capability: capability as Capability, providerId: id.slice(at + 1) } : undefined\n}\n","import type { Capability } from './capabilities.ts'\nimport type { RequestOption } from './options.ts'\nimport type { AiErrorCode } from './errors.ts'\n\n/**\n * The browser API of the main plugin, which the UI of the main plugin and of every vendor plugin\n * uses. Paths are relative to the prefix, and the browser calls them with relative URLs so that a\n * mounted deployment works.\n */\nexport const AI_API_PREFIX = 'ai-api'\n\n/** One provider as the settings UI shows it. */\nexport interface ProviderSummary {\n id: string\n label: string\n /** The profile entry whose form configures the provider. */\n configEntryId?: string\n /** What can be set per request to it for the capability, for whatever keeps its own session configuration. */\n requestOptions?: RequestOption[]\n}\n\n/** One capability as the settings UI shows it: what can supply it, and which one the profile chose. */\nexport interface CapabilityState {\n capability: Capability\n providers: ProviderSummary[]\n /** The id of the selected provider; absent when none is, or when the selected one is not loaded. */\n selected?: string\n /** Whether the service is on the context right now. */\n available: boolean\n}\n\n/** `GET /ai-api/capabilities` */\nexport interface CapabilitiesPayload {\n capabilities: CapabilityState[]\n}\n\n/** What the credentials service says about one reference, never its value. */\nexport interface CredentialStatus {\n ref: string\n configured: boolean\n /** Whether a value can be stored for it from here. */\n writable: boolean\n /** Where the value comes from (the environment, the private store). */\n source?: string\n}\n\n/** `GET /ai-api/credentials?ref=NAME` */\nexport type CredentialsPayload = CredentialStatus\n\n/** `PUT /ai-api/credentials` with `{ ref, value }`; an empty value removes the stored one. */\nexport interface CredentialWrite {\n ref: string\n value: string\n}\n\n/** `POST /ai-api/probe?capability=<capability>`: whether the configured service works, as the user would see it. */\nexport type ProbeResult =\n | { ok: true; provider: string; model: string; milliseconds: number; /** For embedding: how many dimensions its vectors have. */ dimensions?: number }\n | { ok: false; code: AiErrorCode | 'internal'; message: string }\n\n/** The paths of the API. */\n/** One route of a provider's language models as the settings UI shows it. */\nexport interface LlmRouteSummary {\n provider: string\n providerLabel: string\n id: string\n name: string\n models: { id: string; name: string; contextWindow?: number; maxTokens?: number }[]\n /** Whether DSH is served this route by the plugin now; when not, `problem` says why (another adapter holds the id, for example). */\n active: boolean\n problem?: string\n}\n\n/** `GET /ai-api/llm` */\nexport interface LlmPayload {\n routes: LlmRouteSummary[]\n}\n\n/** `POST /ai-api/llm/probe?route=&model=`: one short request through DSH's own model service, as a chat would send it. */\nexport type LlmProbeResult =\n | { ok: true; route: string; model: string; milliseconds: number; outputTokens?: number; text: string }\n | { ok: false; code: string; message: string }\n\n/** `GET /ai-api/llm/discover?provider=&route=`: the models the endpoint of a route lists. */\nexport interface LlmDiscoverPayload {\n models: { id: string; name: string; contextWindow?: number; maxTokens?: number; inputs?: ('text' | 'image')[]; reasoning?: { levels: { id: string; name: string; body: Record<string, unknown> }[]; default?: string } }[]\n}\n\n/** What one limit of the gate serves and keeps waiting right now. */\nexport interface ConcurrencyStatus {\n id: string\n max: number\n active: number\n queued: { foreground: number; background: number }\n /** How long the call that has waited longest has waited, in milliseconds. */\n oldestWaitMs: number\n /** What holds the places now, longest first. */\n running: { capability: string; route?: string; priority: string; ms: number }[]\n}\n\n/** `GET /ai-api/concurrency`: the state of each configured limit, and the language model routes a limit can name. */\nexport interface ConcurrencyPayload {\n limits: ConcurrencyStatus[]\n routes: { id: string; name: string }[]\n}\n\nexport const AI_API_ROUTES = {\n capabilities: '/capabilities',\n credentials: '/credentials',\n probe: '/probe',\n llm: '/llm',\n llmProbe: '/llm/probe',\n llmDiscover: '/llm/discover',\n concurrency: '/concurrency',\n} as const\n","/**\n * Profile entry id of this plugin's row. Its settings form is the provider's form in the\n * settings UI, so the row in a profile must use the same id.\n */\nexport const ENTRY_ID = 'ai-typesafe'\n\n/** The id the provider is registered and selected by. */\nexport const PROVIDER_ID = 'typesafe'\n","import type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport {\n SettingsFormModel,\n settingsNumberField,\n settingsTextField,\n type SettingsFieldState,\n type SettingsFormActions,\n type SettingsFormScope,\n type SettingsFormShell,\n type SettingsFieldSpec,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport { AI_API_PREFIX, AI_API_ROUTES, type CredentialsPayload } from '@dsh-ai-providers/core'\nimport type { TypeSafeConnectionConfig } from '../config.ts'\n\n/** The fields of the provider's configuration this form edits. */\nexport interface TypeSafeSettings {\n connections?: TypeSafeConnectionConfig[]\n decisionConnection?: string\n decisionModel?: string\n longContext?: boolean\n timeoutMs?: number\n}\n\nexport interface TypeSafeCardState extends SettingsFormShell {\n connections: TypeSafeConnectionConfig[]\n connectionStatus: Record<string, CredentialsPayload>\n decisionConnection: SettingsFieldState\n decisionModel: SettingsFieldState\n longContext: SettingsFieldState\n timeoutMs: SettingsFieldState\n}\n\nexport interface TypeSafeCardFace extends SettingsFormActions {\n hooks: {\n /** Bound by the renderer as `useTypeSafeCard`. */\n typeSafeCard: SnapshotStore<TypeSafeCardState>\n }\n addConnection(): void\n updateConnection(id: string, field: 'name' | 'baseUrl' | 'apiKeyRef', value: string): void\n removeConnection(id: string): void\n saveKey(id: string, value: string): Promise<boolean>\n}\n\nconst longContextField: SettingsFieldSpec = {\n field: 'longContext',\n format: value => (value === true ? 'true' : 'false'),\n parse: text => (text === 'true' || text === 'false' ? { kind: 'set', value: text === 'true' } : undefined),\n}\n\nconst connectionListField: SettingsFieldSpec = {\n field: 'connections',\n format: value => JSON.stringify(Array.isArray(value) ? value : []),\n parse: text => {\n try {\n const value = JSON.parse(text) as unknown\n return Array.isArray(value) ? { kind: 'set', value } : undefined\n } catch { return undefined }\n },\n}\n\n/**\n * Stages the provider's model and reusable connections over its configuration entry.\n */\nexport class TypeSafeCardController {\n private readonly form: SettingsFormModel<TypeSafeSettings>\n private readonly store: SnapshotStore<TypeSafeCardState>\n private unsubscribe = () => {}\n private readonly abort = new AbortController()\n private credentialStatus: Record<string, CredentialsPayload> = {}\n\n constructor(private readonly scope: SettingsFormScope<TypeSafeSettings>) {\n this.form = new SettingsFormModel(\n scope,\n [\n connectionListField, settingsTextField('decisionConnection'), settingsTextField('decisionModel'), longContextField,\n settingsNumberField('timeoutMs'),\n ],\n )\n this.store = this.form.bind(() => this.projection())\n }\n\n start(): void {\n this.unsubscribe = this.scope.subscribe(() => { void this.readCredentials() })\n void this.readCredentials()\n }\n\n private projection(): TypeSafeCardState {\n return {\n ...this.form.shell(),\n connections: this.connections(),\n connectionStatus: this.credentialStatus,\n decisionConnection: this.form.field('decisionConnection'),\n decisionModel: this.form.field('decisionModel'),\n longContext: this.form.field('longContext'),\n timeoutMs: this.form.field('timeoutMs'),\n }\n }\n\n private connections(): TypeSafeConnectionConfig[] {\n try { return JSON.parse(this.form.field('connections').text) as TypeSafeConnectionConfig[] }\n catch { return [] }\n }\n\n private setConnections(connections: TypeSafeConnectionConfig[]): void { this.form.actions().edit('connections', JSON.stringify(connections)) }\n\n private async readCredentials(): Promise<void> {\n const refs = [...new Set(this.connections().map(connection => connection.apiKeyRef.trim()).filter(Boolean))]\n const statuses = await Promise.all(refs.map(async ref => {\n try {\n const response = await fetch(`${AI_API_PREFIX}${AI_API_ROUTES.credentials}?ref=${encodeURIComponent(ref)}`, { credentials: 'same-origin', signal: this.abort.signal })\n return response.ok ? [ref, await response.json() as CredentialsPayload] as const : undefined\n } catch { return undefined }\n }))\n this.credentialStatus = Object.fromEntries(statuses.filter(status => status !== undefined))\n this.store.set(this.projection())\n }\n\n private async writeKey(id: string, value: string): Promise<boolean> {\n const ref = this.connections().find(connection => connection.id === id)?.apiKeyRef.trim()\n if (ref === undefined || ref === '' || value.trim() === '') return false\n const response = await fetch(`${AI_API_PREFIX}${AI_API_ROUTES.credentials}`, {\n method: 'PUT',\n credentials: 'same-origin',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ ref, value }),\n signal: this.abort.signal,\n })\n if (response.ok) this.credentialStatus = { ...this.credentialStatus, [ref]: await response.json() as CredentialsPayload }\n this.store.set(this.projection())\n return response.ok\n }\n\n inject(): TypeSafeCardFace {\n return {\n hooks: { typeSafeCard: this.store }, ...this.form.actions(),\n addConnection: () => {\n const id = crypto.randomUUID()\n this.setConnections([...this.connections(), { id, name: 'New connection', baseUrl: 'https://api.typesafe.ai/v1', apiKeyRef: `TYPESAFE_API_KEY_${id.slice(0, 8).toUpperCase()}` }])\n },\n updateConnection: (id, field, value) => { this.setConnections(this.connections().map(connection => connection.id === id ? { ...connection, [field]: value } : connection)) },\n removeConnection: id => {\n this.setConnections(this.connections().filter(connection => connection.id !== id))\n if (this.form.field('decisionConnection').text === id) this.form.actions().edit('decisionConnection', '')\n },\n saveKey: (id, value) => this.writeKey(id, value),\n }\n }\n\n dispose(): void {\n this.abort.abort()\n this.unsubscribe()\n this.form.dispose()\n }\n}\n","import type { SettingsFormLabels } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { Dictionaries } from './i18n.ts'\n\nexport type TypeSafeLocaleKey =\n | 'label' | 'title' | 'description'\n | 'connectionsTitle' | 'connectionsDescription' | 'connectionsEmpty' | 'connection' | 'connectionHint' | 'connectionNone' | 'connectionName' | 'connectionAdd' | 'connectionRemove' | 'apiKeySave'\n | 'baseUrl' | 'baseUrlHint' | 'apiKeyEnv' | 'apiKeyEnvHint' | 'apiKey' | 'apiKeyHint' | 'apiKeySet' | 'apiKeyUnset'\n | 'decisionModel' | 'decisionModelHint' | 'longContext' | 'longContextHint' | 'timeoutMs' | 'timeoutMsHint'\n | 'overridden' | 'reset' | 'invalidNumber'\n | 'readOnly' | 'unavailable' | 'save' | 'saving' | 'saveFailed'\n\nexport const dictionaries: Dictionaries<TypeSafeLocaleKey> = {\n en: {\n label: 'TypeSafe',\n title: 'TypeSafe decisions',\n description: 'Decisions from TypeSafe\\'s Jev, a hosted model that answers typed questions about text or structured state with probabilities in one pass. The state a plugin asks about is sent to TypeSafe. A server that copies the System One API, such as a local one, works through a custom connection.',\n connectionsTitle: 'TypeSafe connections',\n connectionsDescription: 'Configure the TypeSafe endpoint, or a compatible server, and its credentials once, then select it in the Decisions settings.',\n connectionsEmpty: 'No TypeSafe connections are configured.',\n connection: 'Connection', connectionHint: 'Managed in the TypeSafe connections settings page.', connectionNone: 'No connection',\n connectionName: 'Name', connectionAdd: 'Add connection', connectionRemove: 'Remove', apiKeySave: 'Store key',\n baseUrl: 'Base URL',\n baseUrlHint: 'The API root, for example https://api.typesafe.ai/v1 or http://localhost:8081/v1. Requests go to {base URL}/systemone.',\n apiKeyEnv: 'Key name',\n apiKeyEnvHint: 'The name the key is stored under. It can also be supplied by an environment variable of this name, which then takes precedence.',\n apiKey: 'API key',\n apiKeyHint: 'Typed here, kept by DSH\\'s credentials store and never written to the profile or shown again. A server that needs no key can be left without one.',\n apiKeySet: 'Key stored',\n apiKeyUnset: 'No key',\n decisionModel: 'Model',\n decisionModelHint: 'The decision model, as the API names it: jev-latest follows TypeSafe\\'s newest release, while a version such as jev-1.14.0 keeps the answers from changing under you.',\n longContext: 'Longer context window',\n longContextHint: 'Asks for TypeSafe\\'s extended context (262k tokens instead of 64k) with the header it offers for it.',\n timeoutMs: 'Timeout (ms)',\n timeoutMsHint: 'How long a request may take before it is given up.',\n overridden: 'Changed',\n reset: 'Reset',\n invalidNumber: 'Enter a whole number.',\n readOnly: 'This deployment stores settings read-only.',\n unavailable: 'The TypeSafe provider is not loaded, so it cannot be configured right now.',\n save: 'Save',\n saving: 'Saving…',\n saveFailed: 'The deployment did not accept these values; they were left for you to correct.',\n },\n zh: {\n label: 'TypeSafe',\n title: 'TypeSafe 决策',\n description: '使用 TypeSafe 的 Jev 做决策。Jev 是托管模型,一次性针对文本或结构化状态回答带类型的问题并给出概率。插件要询问的状态会发送给 TypeSafe。复制了 System One 接口的服务(例如本地服务)可通过自定义连接使用。',\n connectionsTitle: 'TypeSafe 连接',\n connectionsDescription: '只需配置一次 TypeSafe 端点(或兼容服务)及其凭据,然后在“决策”设置中选择。',\n connectionsEmpty: '尚未配置 TypeSafe 连接。',\n connection: '连接', connectionHint: '在“TypeSafe 连接”设置页中管理。', connectionNone: '无连接',\n connectionName: '名称', connectionAdd: '添加连接', connectionRemove: '移除', apiKeySave: '保存密钥',\n baseUrl: '基础 URL',\n baseUrlHint: '接口根地址,例如 https://api.typesafe.ai/v1 或 http://localhost:8081/v1。请求发往 {基础 URL}/systemone。',\n apiKeyEnv: '密钥名称',\n apiKeyEnvHint: '密钥存放所用的名称。也可以由同名环境变量提供,此时环境变量优先。',\n apiKey: 'API 密钥',\n apiKeyHint: '在此输入,由 DSH 的凭据存储保管,不会写入配置,也不会再次显示。不需要密钥的服务可以留空。',\n apiKeySet: '已保存密钥',\n apiKeyUnset: '无密钥',\n decisionModel: '模型',\n decisionModelHint: '决策模型在接口中的名称:jev-latest 会跟随 TypeSafe 的最新版本,而 jev-1.14.0 这样的指定版本可避免答案在你不知情时改变。',\n longContext: '更长的上下文窗口',\n longContextHint: '通过 TypeSafe 提供的请求头,请求其扩展上下文(262k 词元,而非 64k)。',\n timeoutMs: '超时(毫秒)',\n timeoutMsHint: '一次请求最长等待多久后放弃。',\n overridden: '已更改',\n reset: '重置',\n invalidNumber: '请输入整数。',\n readOnly: '本部署的设置为只读。',\n unavailable: 'TypeSafe 提供方未加载,暂时无法配置。',\n save: '保存',\n saving: '正在保存…',\n saveFailed: '本部署没有接受这些值,已保留供你修改。',\n },\n}\n\nexport const formLabels = (t: (key: TypeSafeLocaleKey) => string): SettingsFormLabels => ({\n unavailable: t('unavailable'),\n readOnly: t('readOnly'),\n saveFailed: t('saveFailed'),\n save: t('save'),\n saving: t('saving'),\n})\n","import { SettingsForm, SettingsValueField } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@dsh-ai-providers/core/slots'\nimport type { TypeSafeCardFace } from './controller.ts'\nimport { formLabels } from './locales.ts'\nimport css from './TypeSafeSurface.module.css'\n\nexport type TypeSafeCardProps =\n PropsRuntime<'ai.provider.decision'>\n & PropsLocale<'ai.typesafe'>\n & InjectFace<TypeSafeCardFace>\n\n/** The connection selection and model defaults of the TypeSafe decision provider. */\nexport function TypeSafeCard(props: TypeSafeCardProps) {\n const { t } = props\n const state = props.useTypeSafeCard(snapshot => snapshot)\n const disabled = !state.writable\n const common = { overriddenLabel: t('overridden'), resetLabel: t('reset'), invalidLabel: t('invalidNumber'), disabled }\n return (\n <div data-testid=\"ai-typesafe\" className={css.section}>\n <h3 className={css.providerTitle}>{t('title')}</h3>\n <p className={css.providerDescription}>{t('description')}</p>\n <SettingsForm labels={formLabels(t)} state={state} onSave={props.save} onDiscard={props.discard}>\n <label className={css.field}>\n <span>{t('connection')}</span>\n <select value={state.decisionConnection.text} disabled={disabled} onChange={event => { props.edit('decisionConnection', event.target.value) }}>\n <option value=\"\">{t('connectionNone')}</option>\n {state.connections.map(item => <option key={item.id} value={item.id}>{item.name}</option>)}\n </select>\n <small>{t('connectionHint')}</small>\n </label>\n <SettingsValueField id=\"ai-typesafe-model\" label={t('decisionModel')} hint={t('decisionModelHint')} {...common} {...state.decisionModel} onEdit={(text) => { props.edit('decisionModel', text) }} onReset={() => { props.resetField('decisionModel') }} />\n <label className={css.field}>\n <span>\n <input type=\"checkbox\" checked={state.longContext.text === 'true'} disabled={disabled} onChange={event => { props.edit('longContext', event.target.checked ? 'true' : 'false') }} /> {t('longContext')}\n </span>\n <small>{t('longContextHint')}</small>\n </label>\n <SettingsValueField id=\"ai-typesafe-timeout\" label={t('timeoutMs')} hint={t('timeoutMsHint')} numeric {...common} {...state.timeoutMs} onEdit={(text) => { props.edit('timeoutMs', text) }} onReset={() => { props.resetField('timeoutMs') }} />\n </SettingsForm>\n </div>\n )\n}\n","import { useState } from 'react'\nimport { Button, SettingsForm, SettingsSecretField } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { TypeSafeCardFace } from './controller.ts'\nimport { formLabels } from './locales.ts'\nimport css from './TypeSafeSurface.module.css'\n\nexport type TypeSafeConnectionsProps = PropsRuntime<'ai.provider.connection'> & PropsLocale<'ai.typesafe'> & InjectFace<TypeSafeCardFace>\n\nexport function TypeSafeConnections(props: TypeSafeConnectionsProps) {\n const state = props.useTypeSafeCard(snapshot => snapshot)\n const { t } = props\n return <div data-testid=\"ai-typesafe-connections\" className={css.section}>\n <h3 className={css.providerTitle}>{t('connectionsTitle')}</h3>\n <p className={css.description}>{t('connectionsDescription')}</p>\n <SettingsForm labels={formLabels(t)} state={state} onSave={props.save} onDiscard={props.discard}>\n <div className={css.list}>\n {state.connections.map(connection => {\n const status = state.connectionStatus[connection.apiKeyRef]\n return <ConnectionRow key={connection.id} {...props} connection={connection} {...(status === undefined ? {} : { status })} disabled={!state.writable} />\n })}\n {state.connections.length === 0 && <p className={css.empty}>{t('connectionsEmpty')}</p>}\n <div><Button variant=\"outline\" size=\"sm\" disabled={!state.writable} onClick={props.addConnection}>{t('connectionAdd')}</Button></div>\n </div>\n </SettingsForm>\n </div>\n}\n\nfunction ConnectionRow(props: TypeSafeConnectionsProps & { connection: { id: string; name: string; baseUrl: string; apiKeyRef: string }; status?: { configured: boolean; writable: boolean }; disabled: boolean }) {\n const { connection, status, t, disabled } = props\n const [key, setKey] = useState('')\n const [saving, setSaving] = useState(false)\n const saveKey = async () => {\n setSaving(true)\n try { if (await props.saveKey(connection.id, key)) setKey('') }\n finally { setSaving(false) }\n }\n const input = (field: 'name' | 'baseUrl' | 'apiKeyRef', label: string, value: string) => <label className={css.field}>\n <span>{label}</span>\n <input value={value} disabled={disabled} onChange={event => { props.updateConnection(connection.id, field, event.target.value) }} />\n </label>\n return <section className={css.card}>\n {input('name', t('connectionName'), connection.name)}\n {input('baseUrl', t('baseUrl'), connection.baseUrl)}\n {input('apiKeyRef', t('apiKeyEnv'), connection.apiKeyRef)}\n <SettingsSecretField id={`ai-typesafe-key-${connection.id}`} label={t('apiKey')} hint={t('apiKeyHint')}\n disabled={disabled || saving || status?.writable === false || connection.apiKeyRef.trim() === ''} text={key}\n configured={status?.configured ?? false} stateLabel={status?.configured === true ? t('apiKeySet') : t('apiKeyUnset')} onEdit={setKey} />\n <div className={css.actions}>\n <Button variant=\"outline\" size=\"sm\" disabled={key.trim() === '' || saving || status?.writable === false} onClick={() => { void saveKey() }}>{saving ? t('saving') : t('apiKeySave')}</Button>\n <Button variant=\"outline\" size=\"sm\" disabled={disabled} onClick={() => { props.removeConnection(connection.id) }}>{t('connectionRemove')}</Button>\n </div>\n </section>\n}\n","import type { Context } from '@deepseek-ai/cordis'\n// Type-only: these pull in the Context and SlotMap augmentations this feature relies on.\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { providerSlotId, providerSlotName } from '@dsh-ai-providers/core'\nimport type {} from '@dsh-ai-providers/core/slots'\nimport { ENTRY_ID, PROVIDER_ID } from '../ids.ts'\nimport { TypeSafeCardController } from './controller.ts'\nimport { TypeSafeCard } from './TypeSafeCard.tsx'\nimport { TypeSafeConnections } from './TypeSafeConnections.tsx'\nimport { dictionaries, type TypeSafeLocaleKey } from './locales.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'ai.typesafe': TypeSafeLocaleKey\n }\n}\n\nconst NAMESPACE = 'ai.typesafe'\n\n/** Union of what the card needs. */\nexport const inject = ['slots', 'locale', 'configForms']\n\n/** Puts the provider's configuration into the Providers and Decisions tabs of the settings modal. */\nexport function apply(ctx: Context): void {\n const t = ctx.locale.bind(NAMESPACE)\n ctx.effect(() => ctx.locale.register(NAMESPACE, dictionaries), 'dsh-ai-typesafe: dictionaries')\n\n const controller = new TypeSafeCardController(ctx.configForms.get(ENTRY_ID))\n controller.start()\n ctx.effect(() => () => { controller.dispose() }, 'dsh-ai-typesafe: form')\n\n ctx.effect(\n () => ctx.configForms.whileServed([ENTRY_ID], () => ctx.slots.inject('ai.provider.connection', () =>\n ctx.slots.register({\n name: 'ai.provider.connection', id: `connection:${PROVIDER_ID}`, order: 6,\n label: () => t('label'), locale: NAMESPACE, inject: () => controller.inject(),\n }, TypeSafeConnections as never))),\n 'dsh-ai-typesafe: provider connection entry',\n )\n\n // The entry only exists while the provider's plugin is loaded and serves its form.\n ctx.effect(\n () => ctx.configForms.whileServed([ENTRY_ID], () => ctx.slots.inject(providerSlotName('decision'), () =>\n ctx.slots.register({\n name: providerSlotName('decision'),\n id: providerSlotId('decision', PROVIDER_ID),\n order: 0,\n label: () => t('label'),\n locale: NAMESPACE,\n inject: () => controller.inject(),\n }, TypeSafeCard))),\n 'dsh-ai-typesafe: provider entry',\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["SettingsFormModel","settingsTextField","settingsNumberField","css","SettingsForm","SettingsValueField","css","SettingsForm","Button","useState","SettingsSecretField"],"sources":["../../dsh-ai-core/src/capabilities.ts","../../dsh-ai-core/src/api.ts","../src/ids.ts","../src/client/controller.ts","../src/client/locales.ts","../src/client/TypeSafeCard.tsx","../src/client/TypeSafeConnections.tsx","../src/client/index.ts"],"sourcesContent":["import type { EmbeddingService } from './embedding.ts'\nimport type { RerankService } from './rerank.ts'\nimport type { TtsService } from './tts.ts'\nimport type { SttService } from './stt.ts'\nimport type { ImageGenerationService } from './image.ts'\nimport type { DecisionService } from './decision.ts'\n\n/**\n * The service each capability is offered as. Adding a capability is adding a line here, a\n * service class beside `EmbeddingService`, and its name in {@link SERVICE_NAMES}.\n */\nexport interface CapabilityServices {\n embedding: EmbeddingService\n rerank: RerankService\n tts: TtsService\n stt: SttService\n image: ImageGenerationService\n decision: DecisionService\n}\n\nexport type Capability = keyof CapabilityServices\n\n/** Every capability, in the order a settings UI lists them. */\nexport const CAPABILITIES = ['embedding', 'rerank', 'tts', 'stt', 'image', 'decision'] as const satisfies readonly Capability[]\n\n/** The name of the service that offers each capability on the Cordis context (`ctx.embeddings`, `ctx.rerankers`). */\nexport const SERVICE_NAMES = { embedding: 'embeddings', rerank: 'rerankers', tts: 'textToSpeech', stt: 'apiSpeechToText', image: 'imageGeneration', decision: 'decisions' } as const satisfies Record<Capability, string>\n\n/** The slot a capability's tab declares for its providers' configuration: a slot has one declarer, so each tab has its own. */\nexport type ProviderSlotName = `ai.provider.${Capability}`\n\nexport const providerSlotName = (capability: Capability): ProviderSlotName => `ai.provider.${capability}`\n\n/** The id of a provider's entry in the slot of its capability (see {@link providerSlotName}). */\nexport const providerSlotId = (capability: Capability, providerId: string): string => `${capability}:${providerId}`\n\n/** The provider and capability an entry of the `ai.provider` slot stands for, or `undefined` for an id that is not one. */\nexport function parseProviderSlotId(id: string): { capability: Capability; providerId: string } | undefined {\n const at = id.indexOf(':')\n const capability = id.slice(0, at)\n return at > 0 && (CAPABILITIES as readonly string[]).includes(capability) ? { capability: capability as Capability, providerId: id.slice(at + 1) } : undefined\n}\n","import type { Capability } from './capabilities.ts'\nimport type { RequestOption } from './options.ts'\nimport type { AiErrorCode } from './errors.ts'\n\n/**\n * The browser API of the main plugin, which the UI of the main plugin and of every vendor plugin\n * uses. Paths are relative to the prefix, and the browser calls them with relative URLs so that a\n * mounted deployment works.\n */\nexport const AI_API_PREFIX = 'ai-api'\n\n/** One provider as the settings UI shows it. */\nexport interface ProviderSummary {\n id: string\n label: string\n /** The profile entry whose form configures the provider. */\n configEntryId?: string\n /** What can be set per request to it for the capability, for whatever keeps its own session configuration. */\n requestOptions?: RequestOption[]\n}\n\n/** One capability as the settings UI shows it: what can supply it, and which one the profile chose. */\nexport interface CapabilityState {\n capability: Capability\n providers: ProviderSummary[]\n /** The id of the selected provider; absent when none is, or when the selected one is not loaded. */\n selected?: string\n /** Whether the service is on the context right now. */\n available: boolean\n}\n\n/** `GET /ai-api/capabilities` */\nexport interface CapabilitiesPayload {\n capabilities: CapabilityState[]\n}\n\n/** What the credentials service says about one reference, never its value. */\nexport interface CredentialStatus {\n ref: string\n configured: boolean\n /** Whether a value can be stored for it from here. */\n writable: boolean\n /** Where the value comes from (the environment, the private store). */\n source?: string\n}\n\n/** `GET /ai-api/credentials?ref=NAME` */\nexport type CredentialsPayload = CredentialStatus\n\n/** `PUT /ai-api/credentials` with `{ ref, value }`; an empty value removes the stored one. */\nexport interface CredentialWrite {\n ref: string\n value: string\n}\n\n/** `POST /ai-api/probe?capability=<capability>`: whether the configured service works, as the user would see it. */\nexport type ProbeResult =\n | { ok: true; provider: string; model: string; milliseconds: number; /** For embedding: how many dimensions its vectors have. */ dimensions?: number }\n | { ok: false; code: AiErrorCode | 'internal'; message: string }\n\n/** The paths of the API. */\n/** One route of a provider's language models as the settings UI shows it. */\nexport interface LlmRouteSummary {\n provider: string\n providerLabel: string\n id: string\n name: string\n models: { id: string; name: string; contextWindow?: number; maxTokens?: number }[]\n /** Whether DSH is served this route by the plugin now; when not, `problem` says why (another adapter holds the id, for example). */\n active: boolean\n problem?: string\n}\n\n/** `GET /ai-api/llm` */\nexport interface LlmPayload {\n routes: LlmRouteSummary[]\n}\n\n/** `POST /ai-api/llm/probe?route=&model=`: one short request through DSH's own model service, as a chat would send it. */\nexport type LlmProbeResult =\n | { ok: true; route: string; model: string; milliseconds: number; outputTokens?: number; text: string }\n | { ok: false; code: string; message: string }\n\n/** `GET /ai-api/llm/discover?provider=&route=`: the models the endpoint of a route lists. */\nexport interface LlmDiscoverPayload {\n models: { id: string; name: string; contextWindow?: number; maxTokens?: number; inputs?: ('text' | 'image')[]; reasoning?: { levels: { id: string; name: string; body: Record<string, unknown> }[]; default?: string } }[]\n}\n\n/** What one limit of the gate serves and keeps waiting right now. */\nexport interface ConcurrencyStatus {\n id: string\n max: number\n active: number\n queued: { foreground: number; background: number }\n /** How long the call that has waited longest has waited, in milliseconds. */\n oldestWaitMs: number\n /** What holds the places now, longest first. */\n running: { capability: string; route?: string; priority: string; ms: number }[]\n}\n\n/** `GET /ai-api/concurrency`: the state of each configured limit, and the language model routes a limit can name. */\nexport interface ConcurrencyPayload {\n limits: ConcurrencyStatus[]\n routes: { id: string; name: string }[]\n}\n\nexport const AI_API_ROUTES = {\n capabilities: '/capabilities',\n credentials: '/credentials',\n probe: '/probe',\n llm: '/llm',\n llmProbe: '/llm/probe',\n llmDiscover: '/llm/discover',\n concurrency: '/concurrency',\n} as const\n","/**\n * Profile entry id of this plugin's row. Its settings form is the provider's form in the\n * settings UI, so the row in a profile must use the same id.\n */\nexport const ENTRY_ID = 'ai-typesafe'\n\n/** The id the provider is registered and selected by. */\nexport const PROVIDER_ID = 'typesafe'\n","import type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport {\n SettingsFormModel,\n settingsNumberField,\n settingsTextField,\n type SettingsFieldState,\n type SettingsFormActions,\n type SettingsFormScope,\n type SettingsFormShell,\n type SettingsFieldSpec,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport { AI_API_PREFIX, AI_API_ROUTES, type CredentialsPayload } from '@dsh-ai-providers/core'\nimport type { TypeSafeConnectionConfig } from '../config.ts'\n\n/** The fields of the provider's configuration this form edits. */\nexport interface TypeSafeSettings {\n connections?: TypeSafeConnectionConfig[]\n decisionConnection?: string\n decisionModel?: string\n longContext?: boolean\n timeoutMs?: number\n}\n\nexport interface TypeSafeCardState extends SettingsFormShell {\n connections: TypeSafeConnectionConfig[]\n connectionStatus: Record<string, CredentialsPayload>\n decisionConnection: SettingsFieldState\n decisionModel: SettingsFieldState\n longContext: SettingsFieldState\n timeoutMs: SettingsFieldState\n}\n\nexport interface TypeSafeCardFace extends SettingsFormActions {\n hooks: {\n /** Bound by the renderer as `useTypeSafeCard`. */\n typeSafeCard: SnapshotStore<TypeSafeCardState>\n }\n addConnection(): void\n updateConnection(id: string, field: 'name' | 'baseUrl' | 'apiKeyRef', value: string): void\n removeConnection(id: string): void\n saveKey(id: string, value: string): Promise<boolean>\n}\n\nconst longContextField: SettingsFieldSpec = {\n field: 'longContext',\n format: value => (value === true ? 'true' : 'false'),\n parse: text => (text === 'true' || text === 'false' ? { kind: 'set', value: text === 'true' } : undefined),\n}\n\nconst connectionListField: SettingsFieldSpec = {\n field: 'connections',\n format: value => JSON.stringify(Array.isArray(value) ? value : []),\n parse: text => {\n try {\n const value = JSON.parse(text) as unknown\n return Array.isArray(value) ? { kind: 'set', value } : undefined\n } catch { return undefined }\n },\n}\n\n/**\n * Stages the provider's model and reusable connections over its configuration entry.\n */\nexport class TypeSafeCardController {\n private readonly form: SettingsFormModel<TypeSafeSettings>\n private readonly store: SnapshotStore<TypeSafeCardState>\n private unsubscribe = () => {}\n private readonly abort = new AbortController()\n private credentialStatus: Record<string, CredentialsPayload> = {}\n\n constructor(private readonly scope: SettingsFormScope<TypeSafeSettings>) {\n this.form = new SettingsFormModel(\n scope,\n [\n connectionListField, settingsTextField('decisionConnection'), settingsTextField('decisionModel'), longContextField,\n settingsNumberField('timeoutMs'),\n ],\n )\n this.store = this.form.bind(() => this.projection())\n }\n\n start(): void {\n this.unsubscribe = this.scope.subscribe(() => { void this.readCredentials() })\n void this.readCredentials()\n }\n\n private projection(): TypeSafeCardState {\n return {\n ...this.form.shell(),\n connections: this.connections(),\n connectionStatus: this.credentialStatus,\n decisionConnection: this.form.field('decisionConnection'),\n decisionModel: this.form.field('decisionModel'),\n longContext: this.form.field('longContext'),\n timeoutMs: this.form.field('timeoutMs'),\n }\n }\n\n private connections(): TypeSafeConnectionConfig[] {\n try { return JSON.parse(this.form.field('connections').text) as TypeSafeConnectionConfig[] }\n catch { return [] }\n }\n\n private setConnections(connections: TypeSafeConnectionConfig[]): void { this.form.actions().edit('connections', JSON.stringify(connections)) }\n\n private async readCredentials(): Promise<void> {\n const refs = [...new Set(this.connections().map(connection => connection.apiKeyRef.trim()).filter(Boolean))]\n const statuses = await Promise.all(refs.map(async ref => {\n try {\n const response = await fetch(`${AI_API_PREFIX}${AI_API_ROUTES.credentials}?ref=${encodeURIComponent(ref)}`, { credentials: 'same-origin', signal: this.abort.signal })\n return response.ok ? [ref, await response.json() as CredentialsPayload] as const : undefined\n } catch { return undefined }\n }))\n this.credentialStatus = Object.fromEntries(statuses.filter(status => status !== undefined))\n this.store.set(this.projection())\n }\n\n private async writeKey(id: string, value: string): Promise<boolean> {\n const ref = this.connections().find(connection => connection.id === id)?.apiKeyRef.trim()\n if (ref === undefined || ref === '' || value.trim() === '') return false\n const response = await fetch(`${AI_API_PREFIX}${AI_API_ROUTES.credentials}`, {\n method: 'PUT',\n credentials: 'same-origin',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ ref, value }),\n signal: this.abort.signal,\n })\n if (response.ok) this.credentialStatus = { ...this.credentialStatus, [ref]: await response.json() as CredentialsPayload }\n this.store.set(this.projection())\n return response.ok\n }\n\n inject(): TypeSafeCardFace {\n return {\n hooks: { typeSafeCard: this.store }, ...this.form.actions(),\n addConnection: () => {\n const id = crypto.randomUUID()\n this.setConnections([...this.connections(), { id, name: 'New connection', baseUrl: 'https://api.typesafe.ai/v1', apiKeyRef: `TYPESAFE_API_KEY_${id.slice(0, 8).toUpperCase()}` }])\n },\n updateConnection: (id, field, value) => { this.setConnections(this.connections().map(connection => connection.id === id ? { ...connection, [field]: value } : connection)) },\n removeConnection: id => {\n this.setConnections(this.connections().filter(connection => connection.id !== id))\n if (this.form.field('decisionConnection').text === id) this.form.actions().edit('decisionConnection', '')\n },\n saveKey: (id, value) => this.writeKey(id, value),\n }\n }\n\n dispose(): void {\n this.abort.abort()\n this.unsubscribe()\n this.form.dispose()\n }\n}\n","import type { SettingsFormLabels } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { Dictionaries } from './i18n.ts'\n\nexport type TypeSafeLocaleKey =\n | 'label' | 'title' | 'description'\n | 'connectionsTitle' | 'connectionsDescription' | 'connectionsEmpty' | 'connection' | 'connectionHint' | 'connectionNone' | 'connectionName' | 'connectionAdd' | 'connectionRemove' | 'apiKeySave'\n | 'baseUrl' | 'baseUrlHint' | 'apiKeyEnv' | 'apiKeyEnvHint' | 'apiKey' | 'apiKeyHint' | 'apiKeySet' | 'apiKeyUnset'\n | 'decisionModel' | 'decisionModelHint' | 'longContext' | 'longContextHint' | 'timeoutMs' | 'timeoutMsHint'\n | 'overridden' | 'reset' | 'invalidNumber'\n | 'readOnly' | 'unavailable' | 'save' | 'saving' | 'saveFailed'\n\nexport const dictionaries: Dictionaries<TypeSafeLocaleKey> = {\n en: {\n label: 'TypeSafe',\n title: 'TypeSafe decisions',\n description: 'Decisions from TypeSafe\\'s Jev, a hosted model that answers typed questions about text or structured state with probabilities in one pass. The state a plugin asks about is sent to TypeSafe. A server that copies the System One API, such as a local one, works through a custom connection.',\n connectionsTitle: 'TypeSafe connections',\n connectionsDescription: 'Configure the TypeSafe endpoint, or a compatible server, and its credentials once, then select it in the Decisions settings.',\n connectionsEmpty: 'No TypeSafe connections are configured.',\n connection: 'Connection', connectionHint: 'Managed in the TypeSafe connections settings page.', connectionNone: 'No connection',\n connectionName: 'Name', connectionAdd: 'Add connection', connectionRemove: 'Remove', apiKeySave: 'Store key',\n baseUrl: 'Base URL',\n baseUrlHint: 'The API root, for example https://api.typesafe.ai/v1 or http://localhost:8081/v1. Requests go to {base URL}/systemone.',\n apiKeyEnv: 'Key name',\n apiKeyEnvHint: 'The name the key is stored under. It can also be supplied by an environment variable of this name, which then takes precedence.',\n apiKey: 'API key',\n apiKeyHint: 'Typed here, kept by DSH\\'s credentials store and never written to the profile or shown again. A server that needs no key can be left without one.',\n apiKeySet: 'Key stored',\n apiKeyUnset: 'No key',\n decisionModel: 'Model',\n decisionModelHint: 'The decision model, as the API names it: jev-latest follows TypeSafe\\'s newest release, while a version such as jev-1.14.0 keeps the answers from changing under you.',\n longContext: 'Longer context window',\n longContextHint: 'Asks for TypeSafe\\'s extended context (262k tokens instead of 64k) with the header it offers for it.',\n timeoutMs: 'Timeout (ms)',\n timeoutMsHint: 'How long a request may take before it is given up.',\n overridden: 'Changed',\n reset: 'Reset',\n invalidNumber: 'Enter a whole number.',\n readOnly: 'This deployment stores settings read-only.',\n unavailable: 'The TypeSafe provider is not loaded, so it cannot be configured right now.',\n save: 'Save',\n saving: 'Saving…',\n saveFailed: 'The deployment did not accept these values; they were left for you to correct.',\n },\n zh: {\n label: 'TypeSafe',\n title: 'TypeSafe 决策',\n description: '使用 TypeSafe 的 Jev 做决策。Jev 是托管模型,一次性针对文本或结构化状态回答带类型的问题并给出概率。插件要询问的状态会发送给 TypeSafe。复制了 System One 接口的服务(例如本地服务)可通过自定义连接使用。',\n connectionsTitle: 'TypeSafe 连接',\n connectionsDescription: '只需配置一次 TypeSafe 端点(或兼容服务)及其凭据,然后在“决策”设置中选择。',\n connectionsEmpty: '尚未配置 TypeSafe 连接。',\n connection: '连接', connectionHint: '在“TypeSafe 连接”设置页中管理。', connectionNone: '无连接',\n connectionName: '名称', connectionAdd: '添加连接', connectionRemove: '移除', apiKeySave: '保存密钥',\n baseUrl: '基础 URL',\n baseUrlHint: '接口根地址,例如 https://api.typesafe.ai/v1 或 http://localhost:8081/v1。请求发往 {基础 URL}/systemone。',\n apiKeyEnv: '密钥名称',\n apiKeyEnvHint: '密钥存放所用的名称。也可以由同名环境变量提供,此时环境变量优先。',\n apiKey: 'API 密钥',\n apiKeyHint: '在此输入,由 DSH 的凭据存储保管,不会写入配置,也不会再次显示。不需要密钥的服务可以留空。',\n apiKeySet: '已保存密钥',\n apiKeyUnset: '无密钥',\n decisionModel: '模型',\n decisionModelHint: '决策模型在接口中的名称:jev-latest 会跟随 TypeSafe 的最新版本,而 jev-1.14.0 这样的指定版本可避免答案在你不知情时改变。',\n longContext: '更长的上下文窗口',\n longContextHint: '通过 TypeSafe 提供的请求头,请求其扩展上下文(262k 词元,而非 64k)。',\n timeoutMs: '超时(毫秒)',\n timeoutMsHint: '一次请求最长等待多久后放弃。',\n overridden: '已更改',\n reset: '重置',\n invalidNumber: '请输入整数。',\n readOnly: '本部署的设置为只读。',\n unavailable: 'TypeSafe 提供方未加载,暂时无法配置。',\n save: '保存',\n saving: '正在保存…',\n saveFailed: '本部署没有接受这些值,已保留供你修改。',\n },\n}\n\nexport const formLabels = (t: (key: TypeSafeLocaleKey) => string): SettingsFormLabels => ({\n unavailable: t('unavailable'),\n readOnly: t('readOnly'),\n saveFailed: t('saveFailed'),\n save: t('save'),\n saving: t('saving'),\n})\n","import { SettingsForm, SettingsValueField } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@dsh-ai-providers/core/slots'\nimport type { TypeSafeCardFace } from './controller.ts'\nimport { formLabels } from './locales.ts'\nimport css from './TypeSafeSurface.module.css'\n\nexport type TypeSafeCardProps =\n PropsRuntime<'ai.provider.decision'>\n & PropsLocale<'ai.typesafe'>\n & InjectFace<TypeSafeCardFace>\n\n/** The connection selection and model defaults of the TypeSafe decision provider. */\nexport function TypeSafeCard(props: TypeSafeCardProps) {\n const { t } = props\n const state = props.useTypeSafeCard(snapshot => snapshot)\n const disabled = !state.writable\n const common = { overriddenLabel: t('overridden'), resetLabel: t('reset'), invalidLabel: t('invalidNumber'), disabled }\n return (\n <div data-testid=\"ai-typesafe\" className={css.section}>\n <h3 className={css.providerTitle}>{t('title')}</h3>\n <p className={css.providerDescription}>{t('description')}</p>\n <SettingsForm labels={formLabels(t)} state={state} onSave={props.save} onDiscard={props.discard}>\n <label className={css.field}>\n <span>{t('connection')}</span>\n <select value={state.decisionConnection.text} disabled={disabled} onChange={event => { props.edit('decisionConnection', event.target.value) }}>\n <option value=\"\">{t('connectionNone')}</option>\n {state.connections.map(item => <option key={item.id} value={item.id}>{item.name}</option>)}\n </select>\n <small>{t('connectionHint')}</small>\n </label>\n <SettingsValueField id=\"ai-typesafe-model\" label={t('decisionModel')} hint={t('decisionModelHint')} {...common} {...state.decisionModel} onEdit={(text) => { props.edit('decisionModel', text) }} onReset={() => { props.resetField('decisionModel') }} />\n <label className={css.field}>\n <span>\n <input type=\"checkbox\" checked={state.longContext.text === 'true'} disabled={disabled} onChange={event => { props.edit('longContext', event.target.checked ? 'true' : 'false') }} /> {t('longContext')}\n </span>\n <small>{t('longContextHint')}</small>\n </label>\n <SettingsValueField id=\"ai-typesafe-timeout\" label={t('timeoutMs')} hint={t('timeoutMsHint')} numeric {...common} {...state.timeoutMs} onEdit={(text) => { props.edit('timeoutMs', text) }} onReset={() => { props.resetField('timeoutMs') }} />\n </SettingsForm>\n </div>\n )\n}\n","import { useState } from 'react'\nimport { Button, SettingsForm, SettingsSecretField } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { TypeSafeCardFace } from './controller.ts'\nimport { formLabels } from './locales.ts'\nimport css from './TypeSafeSurface.module.css'\n\nexport type TypeSafeConnectionsProps = PropsRuntime<'ai.provider.connection'> & PropsLocale<'ai.typesafe'> & InjectFace<TypeSafeCardFace>\n\nexport function TypeSafeConnections(props: TypeSafeConnectionsProps) {\n const state = props.useTypeSafeCard(snapshot => snapshot)\n const { t } = props\n return <div data-testid=\"ai-typesafe-connections\" className={css.section}>\n <h3 className={css.providerTitle}>{t('connectionsTitle')}</h3>\n <p className={css.description}>{t('connectionsDescription')}</p>\n <SettingsForm labels={formLabels(t)} state={state} onSave={props.save} onDiscard={props.discard}>\n <div className={css.list}>\n {state.connections.map(connection => {\n const status = state.connectionStatus[connection.apiKeyRef]\n return <ConnectionRow key={connection.id} {...props} connection={connection} {...(status === undefined ? {} : { status })} disabled={!state.writable} />\n })}\n {state.connections.length === 0 && <p className={css.empty}>{t('connectionsEmpty')}</p>}\n <div><Button variant=\"outline\" size=\"sm\" disabled={!state.writable} onClick={props.addConnection}>{t('connectionAdd')}</Button></div>\n </div>\n </SettingsForm>\n </div>\n}\n\nfunction ConnectionRow(props: TypeSafeConnectionsProps & { connection: { id: string; name: string; baseUrl: string; apiKeyRef: string }; status?: { configured: boolean; writable: boolean }; disabled: boolean }) {\n const { connection, status, t, disabled } = props\n const [key, setKey] = useState('')\n const [saving, setSaving] = useState(false)\n const saveKey = async () => {\n setSaving(true)\n try { if (await props.saveKey(connection.id, key)) setKey('') }\n finally { setSaving(false) }\n }\n const input = (field: 'name' | 'baseUrl' | 'apiKeyRef', label: string, value: string) => <label className={css.field}>\n <span>{label}</span>\n <input value={value} disabled={disabled} onChange={event => { props.updateConnection(connection.id, field, event.target.value) }} />\n </label>\n return <section className={css.card}>\n {input('name', t('connectionName'), connection.name)}\n {input('baseUrl', t('baseUrl'), connection.baseUrl)}\n {input('apiKeyRef', t('apiKeyEnv'), connection.apiKeyRef)}\n <SettingsSecretField id={`ai-typesafe-key-${connection.id}`} label={t('apiKey')} hint={t('apiKeyHint')}\n disabled={disabled || saving || status?.writable === false || connection.apiKeyRef.trim() === ''} text={key}\n configured={status?.configured ?? false} stateLabel={status?.configured === true ? t('apiKeySet') : t('apiKeyUnset')} onEdit={setKey} />\n <div className={css.actions}>\n <Button variant=\"outline\" size=\"sm\" disabled={disabled || key.trim() === '' || saving || status?.writable === false} onClick={() => { void saveKey() }}>{saving ? t('saving') : t('apiKeySave')}</Button>\n <Button variant=\"outline\" size=\"sm\" disabled={disabled} onClick={() => { props.removeConnection(connection.id) }}>{t('connectionRemove')}</Button>\n </div>\n </section>\n}\n","import type { Context } from '@deepseek-ai/cordis'\n// Type-only: these pull in the Context and SlotMap augmentations this feature relies on.\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { providerSlotId, providerSlotName } from '@dsh-ai-providers/core'\nimport type {} from '@dsh-ai-providers/core/slots'\nimport { ENTRY_ID, PROVIDER_ID } from '../ids.ts'\nimport { TypeSafeCardController } from './controller.ts'\nimport { TypeSafeCard } from './TypeSafeCard.tsx'\nimport { TypeSafeConnections } from './TypeSafeConnections.tsx'\nimport { dictionaries, type TypeSafeLocaleKey } from './locales.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'ai.typesafe': TypeSafeLocaleKey\n }\n}\n\nconst NAMESPACE = 'ai.typesafe'\n\n/** Union of what the card needs. */\nexport const inject = ['slots', 'locale', 'configForms']\n\n/** Puts the provider's configuration into the Providers and Decisions tabs of the settings modal. */\nexport function apply(ctx: Context): void {\n const t = ctx.locale.bind(NAMESPACE)\n ctx.effect(() => ctx.locale.register(NAMESPACE, dictionaries), 'dsh-ai-typesafe: dictionaries')\n\n const controller = new TypeSafeCardController(ctx.configForms.get(ENTRY_ID))\n controller.start()\n ctx.effect(() => () => { controller.dispose() }, 'dsh-ai-typesafe: form')\n\n ctx.effect(\n () => ctx.configForms.whileServed([ENTRY_ID], () => ctx.slots.inject('ai.provider.connection', () =>\n ctx.slots.register({\n name: 'ai.provider.connection', id: `connection:${PROVIDER_ID}`, order: 6,\n label: () => t('label'), locale: NAMESPACE, inject: () => controller.inject(),\n }, TypeSafeConnections as never))),\n 'dsh-ai-typesafe: provider connection entry',\n )\n\n // The entry only exists while the provider's plugin is loaded and serves its form.\n ctx.effect(\n () => ctx.configForms.whileServed([ENTRY_ID], () => ctx.slots.inject(providerSlotName('decision'), () =>\n ctx.slots.register({\n name: providerSlotName('decision'),\n id: providerSlotId('decision', PROVIDER_ID),\n order: 0,\n label: () => t('label'),\n locale: NAMESPACE,\n inject: () => controller.inject(),\n }, TypeSafeCard))),\n 'dsh-ai-typesafe: provider entry',\n )\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-ai-providers/typesafe",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "TypeSafe AI's Jev decision provider for dsh-ai-providers.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Firefox2100",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"engines": {
|
|
17
17
|
"node": ">=22",
|
|
18
|
-
"dsh": ">=0.2.0-rc.2 <0.2.1 || >=0.2.1-
|
|
18
|
+
"dsh": ">=0.2.0-rc.2 <0.2.1 || >=0.2.1-0 <0.2.2"
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
@@ -61,28 +61,28 @@
|
|
|
61
61
|
],
|
|
62
62
|
"license": "GPL-3.0-only",
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@deepseek-ai/dsh": ">=0.2.0-rc.2 <0.2.1 || >=0.2.1-
|
|
64
|
+
"@deepseek-ai/dsh": ">=0.2.0-rc.2 <0.2.1 || >=0.2.1-0 <0.2.2",
|
|
65
65
|
"@deepseek-ai/schemastery": "^3.18.4",
|
|
66
|
-
"@dsh-ai-providers/core": "0.5.
|
|
66
|
+
"@dsh-ai-providers/core": "0.5.2"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@dsh-ai-providers/runtime": "0.5.
|
|
70
|
-
"@dsh-ai-providers/systemone": "0.5.
|
|
69
|
+
"@dsh-ai-providers/runtime": "0.5.2",
|
|
70
|
+
"@dsh-ai-providers/systemone": "0.5.2"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"@deepseek-ai/cordis": "^4.0.5",
|
|
74
|
-
"@deepseek-ai/dsh-client-locale": "0.2.1-rc.
|
|
75
|
-
"@deepseek-ai/dsh-client-store": "0.2.1-rc.
|
|
76
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.
|
|
77
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.
|
|
78
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-rc.
|
|
79
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.
|
|
80
|
-
"@deepseek-ai/dsh-credentials": "0.2.1-rc.
|
|
74
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-rc.3",
|
|
75
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-rc.3",
|
|
76
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-rc.3",
|
|
77
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-rc.3",
|
|
78
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-rc.3",
|
|
79
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-rc.3",
|
|
80
|
+
"@deepseek-ai/dsh-credentials": "0.2.1-rc.3",
|
|
81
81
|
"@deepseek-ai/schemastery": "^3.18.5",
|
|
82
82
|
"@types/node": "^22.20.0",
|
|
83
83
|
"@types/react": "~18.3.31",
|
|
84
|
-
"@dsh-ai-providers/core": "0.5.
|
|
85
|
-
"@dsh-ai-providers/systemone": "0.5.
|
|
84
|
+
"@dsh-ai-providers/core": "0.5.2",
|
|
85
|
+
"@dsh-ai-providers/systemone": "0.5.2",
|
|
86
86
|
"lightningcss": "^1.33.0",
|
|
87
87
|
"react": "^18.3.1",
|
|
88
88
|
"tsdown": "^0.22.2",
|