@ai-sdk/typesafe-ai 3.0.12 → 3.0.13
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 +11 -0
- package/README.md +12 -10
- package/dist/index.d.ts +18 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -16
- package/dist/index.js.map +1 -1
- package/docs/105-typesafe-ai.mdx +25 -14
- package/package.json +3 -3
- package/src/index.ts +7 -1
- package/src/{typesafe-ai-evaluation-api.ts → typesafe-ai-decision-api.ts} +1 -1
- package/src/{typesafe-ai-evaluation-model.ts → typesafe-ai-decision-model.ts} +23 -18
- package/src/typesafe-ai-provider.ts +31 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @ai-sdk/typesafe-ai
|
|
2
2
|
|
|
3
|
+
## 3.0.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 2959d35: feat: rename `evaluate` to `decide`
|
|
8
|
+
- e6d6dab: feat(typesafe-ai): read `TYPESAFE_AI_BASE_URL` when no explicit base URL is configured
|
|
9
|
+
- Updated dependencies [2959d35]
|
|
10
|
+
- Updated dependencies [59116e6]
|
|
11
|
+
- @ai-sdk/provider@4.0.22
|
|
12
|
+
- @ai-sdk/provider-utils@5.0.54
|
|
13
|
+
|
|
3
14
|
## 3.0.12
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AI SDK TypeSafe Provider
|
|
2
2
|
|
|
3
3
|
The **[TypeSafe provider](https://ai-sdk.dev/providers/ai-sdk-providers/typesafe-ai)**
|
|
4
|
-
for the [AI SDK](https://ai-sdk.dev/docs)
|
|
4
|
+
for the [AI SDK](https://ai-sdk.dev/docs) decides answers to Choice, Score, and Boolean
|
|
5
5
|
questions using TypeSafe's System One models.
|
|
6
6
|
|
|
7
7
|
## Setup
|
|
@@ -10,14 +10,14 @@ questions using TypeSafe's System One models.
|
|
|
10
10
|
pnpm add @ai-sdk/typesafe-ai ai
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Set `TYPESAFE_AI_API_KEY`, then pass
|
|
13
|
+
Set `TYPESAFE_AI_API_KEY`, then pass a decision model instance:
|
|
14
14
|
|
|
15
15
|
```ts
|
|
16
16
|
import { typeSafeAi } from '@ai-sdk/typesafe-ai';
|
|
17
|
-
import {
|
|
17
|
+
import { experimental_decide } from 'ai';
|
|
18
18
|
|
|
19
|
-
const result = await
|
|
20
|
-
model: typeSafeAi.
|
|
19
|
+
const result = await experimental_decide({
|
|
20
|
+
model: typeSafeAi.decisionModel('jev-latest'),
|
|
21
21
|
state: 'I was charged twice. Please refund the duplicate.',
|
|
22
22
|
questions: {
|
|
23
23
|
department: {
|
|
@@ -35,16 +35,18 @@ const result = await experimental_evaluate({
|
|
|
35
35
|
console.log(result.answers);
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
Decision is experimental. The package exports `typeSafeAi`, `createTypeSafeAi`,
|
|
39
39
|
`TypeSafeAiProviderSettings`, `TypeSafeAiProvider`,
|
|
40
|
-
`
|
|
40
|
+
`Experimental_TypeSafeAiDecisionModelId`, and `VERSION`.
|
|
41
41
|
|
|
42
42
|
## Configuration
|
|
43
43
|
|
|
44
44
|
`createTypeSafeAi({ apiKey, baseURL, headers, fetch })` supports an explicit key,
|
|
45
|
-
custom headers, a custom fetch implementation, and a base URL
|
|
46
|
-
`https://api.typesafe.ai/v1
|
|
47
|
-
|
|
45
|
+
custom headers, a custom fetch implementation, and a base URL. The base URL
|
|
46
|
+
defaults to `TYPESAFE_AI_BASE_URL`, then `https://api.typesafe.ai/v1`. An
|
|
47
|
+
explicit `baseURL` takes precedence over the environment variable. The default
|
|
48
|
+
key comes from `TYPESAFE_AI_API_KEY`. Language, embedding, and image model
|
|
49
|
+
factories are unsupported.
|
|
48
50
|
|
|
49
51
|
All questions are sent in one request against shared state. Choice supports up to
|
|
50
52
|
255 options; Score supports 2–10 ordered levels; Boolean maps to TypeSafe's Noul
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Experimental_DecisionModelV4, ProviderV4 } from "@ai-sdk/provider";
|
|
2
2
|
import { FetchFunction, WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from "@ai-sdk/provider-utils";
|
|
3
|
-
//#region src/typesafe-ai-
|
|
4
|
-
type
|
|
3
|
+
//#region src/typesafe-ai-decision-model.d.ts
|
|
4
|
+
type TypeSafeAiDecisionModelId = 'jev-latest' | (string & {});
|
|
5
5
|
//#endregion
|
|
6
6
|
//#region src/typesafe-ai-provider.d.ts
|
|
7
|
-
/** TypeSafe's experimental
|
|
7
|
+
/** TypeSafe's experimental decision capability, isolated from ProviderV4. */
|
|
8
8
|
interface TypeSafeAiProvider extends ProviderV4 {
|
|
9
|
-
|
|
9
|
+
decisionModel(modelId: TypeSafeAiDecisionModelId): Experimental_DecisionModelV4;
|
|
10
|
+
/** @deprecated Use `decisionModel` instead. */
|
|
11
|
+
evaluationModel(modelId: TypeSafeAiDecisionModelId): Experimental_DecisionModelV4 & {
|
|
12
|
+
doEvaluate: Experimental_DecisionModelV4['doDecide'];
|
|
13
|
+
};
|
|
10
14
|
}
|
|
11
15
|
interface TypeSafeAiProviderSettings {
|
|
12
16
|
/** API key. Defaults to the TYPESAFE_AI_API_KEY environment variable. */
|
|
13
17
|
apiKey?: string;
|
|
14
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* API base URL. Defaults to the TYPESAFE_AI_BASE_URL environment variable,
|
|
20
|
+
* then https://api.typesafe.ai/v1.
|
|
21
|
+
*/
|
|
15
22
|
baseURL?: string;
|
|
16
23
|
headers?: Record<string, string>;
|
|
17
24
|
fetch?: FetchFunction;
|
|
@@ -22,5 +29,9 @@ export declare const typeSafeAi: TypeSafeAiProvider;
|
|
|
22
29
|
//#region src/version.d.ts
|
|
23
30
|
export declare const VERSION: string;
|
|
24
31
|
//#endregion
|
|
25
|
-
|
|
32
|
+
//#region src/index.d.ts
|
|
33
|
+
/** @deprecated Use `Experimental_TypeSafeAiDecisionModelId` instead. */
|
|
34
|
+
export type Experimental_TypeSafeAiEvaluationModelId = TypeSafeAiDecisionModelId;
|
|
35
|
+
//#endregion
|
|
36
|
+
export type { TypeSafeAiDecisionModelId as Experimental_TypeSafeAiDecisionModelId, TypeSafeAiProvider, TypeSafeAiProviderSettings };
|
|
26
37
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":["
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["DecisionModelV4"],"sources":["../src/typesafe-ai-decision-model.ts","../src/typesafe-ai-provider.ts","../src/version.ts","../src/index.ts"],"mappings":";;;KAyBY;;;;UCNK,2BAA2B;EAC1C,cAAc,SAAS,4BAA4BA;;EAEnD,gBAAgB,SAAS,4BAA4BA;IACnD,YAAYA;;;UAIC;;EAEf;;;;;EAKA;EACA,UAAU;EACV,QAAQ;;wBAGM,iBACd,UAAS,6BACR;qBAyCU,YAAU;;;qBChFV;;;;YCSD,2CACV"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { InvalidArgumentError, NoSuchModelError } from "@ai-sdk/provider";
|
|
2
|
-
import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE, combineHeaders, createJsonErrorResponseHandler, createJsonResponseHandler, loadApiKey, postJsonToApi, resolve, serializeModelOptions, withUserAgentSuffix, withoutTrailingSlash } from "@ai-sdk/provider-utils";
|
|
2
|
+
import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE, combineHeaders, createJsonErrorResponseHandler, createJsonResponseHandler, loadApiKey, loadOptionalSetting, postJsonToApi, resolve, serializeModelOptions, withUserAgentSuffix, withoutTrailingSlash } from "@ai-sdk/provider-utils";
|
|
3
3
|
import * as z from "zod/v4";
|
|
4
|
-
//#region src/typesafe-ai-
|
|
5
|
-
const
|
|
4
|
+
//#region src/typesafe-ai-decision-api.ts
|
|
5
|
+
const typesafeDecisionResponseSchema = z.object({
|
|
6
6
|
model: z.string().nullish(),
|
|
7
7
|
answers: z.record(z.string(), z.discriminatedUnion("type", [
|
|
8
8
|
z.object({
|
|
@@ -38,10 +38,10 @@ const typesafeFailedResponseHandler = createJsonErrorResponseHandler({
|
|
|
38
38
|
});
|
|
39
39
|
//#endregion
|
|
40
40
|
//#region src/version.ts
|
|
41
|
-
const VERSION = "3.0.
|
|
41
|
+
const VERSION = "3.0.13";
|
|
42
42
|
//#endregion
|
|
43
|
-
//#region src/typesafe-ai-
|
|
44
|
-
var
|
|
43
|
+
//#region src/typesafe-ai-decision-model.ts
|
|
44
|
+
var DecisionTypeSafeAiModel = class DecisionTypeSafeAiModel {
|
|
45
45
|
constructor(modelId, config) {
|
|
46
46
|
this.modelId = modelId;
|
|
47
47
|
this.config = config;
|
|
@@ -62,9 +62,13 @@ var EvaluationTypeSafeAiModel = class EvaluationTypeSafeAiModel {
|
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
static [WORKFLOW_DESERIALIZE](options) {
|
|
65
|
-
return new
|
|
65
|
+
return new DecisionTypeSafeAiModel(options.modelId, options.config);
|
|
66
66
|
}
|
|
67
|
-
|
|
67
|
+
/** @deprecated Use `doDecide` instead. */
|
|
68
|
+
doEvaluate(options) {
|
|
69
|
+
return this.doDecide(options);
|
|
70
|
+
}
|
|
71
|
+
async doDecide({ state, questions, headers, abortSignal, providerOptions }) {
|
|
68
72
|
for (const [id, question] of Object.entries(questions)) {
|
|
69
73
|
if (question.type === "choice" && Object.keys(question.criteria).length > 255) throw new InvalidArgumentError({
|
|
70
74
|
argument: `questions.${id}.criteria`,
|
|
@@ -98,7 +102,7 @@ var EvaluationTypeSafeAiModel = class EvaluationTypeSafeAiModel {
|
|
|
98
102
|
abortSignal,
|
|
99
103
|
fetch: this.config.fetch,
|
|
100
104
|
failedResponseHandler: typesafeFailedResponseHandler,
|
|
101
|
-
successfulResponseHandler: createJsonResponseHandler(
|
|
105
|
+
successfulResponseHandler: createJsonResponseHandler(typesafeDecisionResponseSchema)
|
|
102
106
|
});
|
|
103
107
|
const confidence = Object.fromEntries(Object.entries(response.answers).flatMap(([id, answer]) => answer.type !== "noul" && answer.confidence != null ? [[id, answer.confidence]] : []));
|
|
104
108
|
return {
|
|
@@ -141,7 +145,10 @@ var EvaluationTypeSafeAiModel = class EvaluationTypeSafeAiModel {
|
|
|
141
145
|
//#endregion
|
|
142
146
|
//#region src/typesafe-ai-provider.ts
|
|
143
147
|
function createTypeSafeAi(options = {}) {
|
|
144
|
-
const baseURL = withoutTrailingSlash(
|
|
148
|
+
const baseURL = withoutTrailingSlash(loadOptionalSetting({
|
|
149
|
+
settingValue: options.baseURL,
|
|
150
|
+
environmentVariableName: "TYPESAFE_AI_BASE_URL"
|
|
151
|
+
})) ?? "https://api.typesafe.ai/v1";
|
|
145
152
|
const headers = () => withUserAgentSuffix({
|
|
146
153
|
Authorization: `Bearer ${loadApiKey({
|
|
147
154
|
apiKey: options.apiKey,
|
|
@@ -150,14 +157,16 @@ function createTypeSafeAi(options = {}) {
|
|
|
150
157
|
})}`,
|
|
151
158
|
...options.headers
|
|
152
159
|
}, `ai-sdk-typesafe-ai/${VERSION}`);
|
|
160
|
+
const decisionModel = (modelId) => new DecisionTypeSafeAiModel(modelId, {
|
|
161
|
+
provider: "typesafe.decision",
|
|
162
|
+
baseURL,
|
|
163
|
+
headers,
|
|
164
|
+
fetch: options.fetch
|
|
165
|
+
});
|
|
153
166
|
return {
|
|
154
167
|
specificationVersion: "v4",
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
baseURL,
|
|
158
|
-
headers,
|
|
159
|
-
fetch: options.fetch
|
|
160
|
-
}),
|
|
168
|
+
decisionModel,
|
|
169
|
+
evaluationModel: decisionModel,
|
|
161
170
|
languageModel: (modelId) => {
|
|
162
171
|
throw new NoSuchModelError({
|
|
163
172
|
modelId,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/typesafe-ai-evaluation-api.ts","../src/version.ts","../src/typesafe-ai-evaluation-model.ts","../src/typesafe-ai-provider.ts"],"sourcesContent":["import { createJsonErrorResponseHandler } from '@ai-sdk/provider-utils';\nimport * as z from 'zod/v4';\n\n// Verified against the official SDK at 66880ccded6cb642dc1809620c2b108c33730214.\n// https://github.com/typesafe-ai/typesafe-sdk-js/blob/66880ccded6cb642dc1809620c2b108c33730214/src/types.ts\nexport const typesafeEvaluationResponseSchema = z.object({\n model: z.string().nullish(),\n answers: z.record(\n z.string(),\n z.discriminatedUnion('type', [\n z.object({\n type: z.literal('choice'),\n choice: z.string(),\n probabilities: z.record(z.string(), z.number()),\n confidence: z.number().nullish(),\n }),\n z.object({\n type: z.literal('score'),\n score: z.number(),\n probabilities: z.record(z.string(), z.number()),\n confidence: z.number().nullish(),\n }),\n z.object({ type: z.literal('noul'), noul: z.number() }),\n ]),\n ),\n usage: z\n .object({\n input_tokens: z.number().nullish(),\n output_tokens: z.number().nullish(),\n })\n .nullish(),\n});\n\nexport const typesafeFailedResponseHandler = createJsonErrorResponseHandler({\n errorSchema: z.object({\n message: z.string().nullish(),\n detail: z.unknown().nullish(),\n error: z\n .union([z.string(), z.object({ message: z.string().nullish() })])\n .nullish(),\n error_type: z.string().nullish(),\n }),\n errorToMessage: error =>\n error.message ??\n (typeof error.error === 'string' ? error.error : error.error?.message) ??\n (typeof error.detail === 'string'\n ? error.detail\n : JSON.stringify(error.detail)) ??\n error.error_type ??\n 'TypeSafe request failed',\n});\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import {\n InvalidArgumentError,\n type Experimental_EvaluationModelV4 as EvaluationModelV4,\n type Experimental_EvaluationModelV4Answer as EvaluationModelV4Answer,\n type SharedV4Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n createJsonResponseHandler,\n loadApiKey,\n postJsonToApi,\n resolve,\n serializeModelOptions,\n withUserAgentSuffix,\n WORKFLOW_SERIALIZE,\n WORKFLOW_DESERIALIZE,\n type FetchFunction,\n type Resolvable,\n} from '@ai-sdk/provider-utils';\nimport {\n typesafeEvaluationResponseSchema,\n typesafeFailedResponseHandler,\n} from './typesafe-ai-evaluation-api';\nimport { VERSION } from './version';\n\nexport type TypeSafeAiEvaluationModelId = 'jev-latest' | (string & {});\n\ntype TypeSafeAiEvaluationModelConfig = {\n provider: string;\n baseURL: string;\n headers?: Resolvable<Record<string, string | undefined>>;\n fetch?: FetchFunction;\n};\n\nexport class EvaluationTypeSafeAiModel implements EvaluationModelV4 {\n readonly specificationVersion = 'v4';\n readonly supportedQuestionTypes = ['choice', 'score', 'boolean'] as const;\n\n constructor(\n readonly modelId: TypeSafeAiEvaluationModelId,\n private readonly config: TypeSafeAiEvaluationModelConfig,\n ) {}\n\n get provider() {\n return this.config.provider;\n }\n\n static [WORKFLOW_SERIALIZE](model: EvaluationTypeSafeAiModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.config,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: TypeSafeAiEvaluationModelId;\n config: TypeSafeAiEvaluationModelConfig;\n }) {\n return new EvaluationTypeSafeAiModel(options.modelId, options.config);\n }\n\n async doEvaluate({\n state,\n questions,\n headers,\n abortSignal,\n providerOptions,\n }: Parameters<EvaluationModelV4['doEvaluate']>[0]): Promise<\n Awaited<ReturnType<EvaluationModelV4['doEvaluate']>>\n > {\n for (const [id, question] of Object.entries(questions)) {\n if (\n question.type === 'choice' &&\n Object.keys(question.criteria).length > 255\n ) {\n throw new InvalidArgumentError({\n argument: `questions.${id}.criteria`,\n message: 'TypeSafe Choice questions support at most 255 options.',\n });\n }\n if (question.type === 'score' && question.criteria.length > 10) {\n throw new InvalidArgumentError({\n argument: `questions.${id}.criteria`,\n message: 'TypeSafe Score questions support at most 10 levels.',\n });\n }\n }\n\n const warnings: SharedV4Warning[] = Object.keys(\n providerOptions?.typesafe ?? {},\n ).map(option => ({\n type: 'unsupported',\n feature: `providerOptions.typesafe.${option}`,\n }));\n const modelHeaders =\n this.config.headers === undefined\n ? withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({ apiKey: undefined, environmentVariableName: 'TYPESAFE_AI_API_KEY', description: 'TypeSafe' })}`,\n },\n `ai-sdk-typesafe-ai/${VERSION}`,\n )\n : await resolve(this.config.headers);\n const {\n value: response,\n rawValue,\n responseHeaders,\n } = await postJsonToApi({\n url: `${this.config.baseURL}/systemone`,\n headers: combineHeaders(modelHeaders, headers),\n body: {\n model: this.modelId,\n state,\n questions: Object.fromEntries(\n Object.entries(questions).map(([id, question]) => [\n id,\n question.type === 'boolean'\n ? { ...question, type: 'noul' }\n : question,\n ]),\n ),\n },\n abortSignal,\n fetch: this.config.fetch,\n failedResponseHandler: typesafeFailedResponseHandler,\n successfulResponseHandler: createJsonResponseHandler(\n typesafeEvaluationResponseSchema,\n ),\n });\n\n const confidence = Object.fromEntries(\n Object.entries(response.answers).flatMap(([id, answer]) =>\n answer.type !== 'noul' && answer.confidence != null\n ? [[id, answer.confidence]]\n : [],\n ),\n );\n\n return {\n answers: Object.fromEntries(\n Object.entries(response.answers).map(\n ([id, answer]): [string, EvaluationModelV4Answer] => {\n switch (answer.type) {\n case 'noul':\n return [id, { type: 'boolean', probability: answer.noul }];\n case 'choice':\n return [\n id,\n {\n type: 'choice',\n choice: answer.choice,\n probabilities: answer.probabilities,\n },\n ];\n case 'score':\n return [\n id,\n {\n type: 'score',\n score: answer.score,\n probabilities: answer.probabilities,\n },\n ];\n }\n },\n ),\n ),\n usage: {\n inputTokens: response.usage?.input_tokens ?? undefined,\n outputTokens: response.usage?.output_tokens ?? undefined,\n },\n // The API rounds displayed probabilities and scores to two decimal places.\n rounding: { probabilityDecimals: 2, scoreDecimals: 2 },\n warnings,\n providerMetadata: { typesafe: { confidence } },\n response: {\n modelId: response.model ?? this.modelId,\n headers: responseHeaders,\n body: rawValue,\n },\n };\n }\n}\n","import {\n NoSuchModelError,\n type Experimental_EvaluationModelV4 as EvaluationModelV4,\n type ProviderV4,\n} from '@ai-sdk/provider';\nimport {\n loadApiKey,\n withoutTrailingSlash,\n withUserAgentSuffix,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport {\n EvaluationTypeSafeAiModel,\n type TypeSafeAiEvaluationModelId,\n} from './typesafe-ai-evaluation-model';\nimport { VERSION } from './version';\n\n/** TypeSafe's experimental evaluation capability, isolated from ProviderV4. */\nexport interface TypeSafeAiProvider extends ProviderV4 {\n evaluationModel(modelId: TypeSafeAiEvaluationModelId): EvaluationModelV4;\n}\n\nexport interface TypeSafeAiProviderSettings {\n /** API key. Defaults to the TYPESAFE_AI_API_KEY environment variable. */\n apiKey?: string;\n /** API base URL. Defaults to https://api.typesafe.ai/v1. */\n baseURL?: string;\n headers?: Record<string, string>;\n fetch?: FetchFunction;\n}\n\nexport function createTypeSafeAi(\n options: TypeSafeAiProviderSettings = {},\n): TypeSafeAiProvider {\n const baseURL =\n withoutTrailingSlash(options.baseURL) ?? 'https://api.typesafe.ai/v1';\n const headers = () =>\n withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({ apiKey: options.apiKey, environmentVariableName: 'TYPESAFE_AI_API_KEY', description: 'TypeSafe' })}`,\n ...options.headers,\n },\n `ai-sdk-typesafe-ai/${VERSION}`,\n );\n\n return {\n specificationVersion: 'v4',\n evaluationModel: modelId =>\n new EvaluationTypeSafeAiModel(modelId, {\n provider: 'typesafe.evaluation',\n baseURL,\n headers,\n fetch: options.fetch,\n }),\n languageModel: modelId => {\n throw new NoSuchModelError({ modelId, modelType: 'languageModel' });\n },\n embeddingModel: modelId => {\n throw new NoSuchModelError({ modelId, modelType: 'embeddingModel' });\n },\n imageModel: modelId => {\n throw new NoSuchModelError({ modelId, modelType: 'imageModel' });\n },\n };\n}\n\nexport const typeSafeAi = createTypeSafeAi();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/typesafe-ai-decision-api.ts","../src/version.ts","../src/typesafe-ai-decision-model.ts","../src/typesafe-ai-provider.ts"],"sourcesContent":["import { createJsonErrorResponseHandler } from '@ai-sdk/provider-utils';\nimport * as z from 'zod/v4';\n\n// Verified against the official SDK at 66880ccded6cb642dc1809620c2b108c33730214.\n// https://github.com/typesafe-ai/typesafe-sdk-js/blob/66880ccded6cb642dc1809620c2b108c33730214/src/types.ts\nexport const typesafeDecisionResponseSchema = z.object({\n model: z.string().nullish(),\n answers: z.record(\n z.string(),\n z.discriminatedUnion('type', [\n z.object({\n type: z.literal('choice'),\n choice: z.string(),\n probabilities: z.record(z.string(), z.number()),\n confidence: z.number().nullish(),\n }),\n z.object({\n type: z.literal('score'),\n score: z.number(),\n probabilities: z.record(z.string(), z.number()),\n confidence: z.number().nullish(),\n }),\n z.object({ type: z.literal('noul'), noul: z.number() }),\n ]),\n ),\n usage: z\n .object({\n input_tokens: z.number().nullish(),\n output_tokens: z.number().nullish(),\n })\n .nullish(),\n});\n\nexport const typesafeFailedResponseHandler = createJsonErrorResponseHandler({\n errorSchema: z.object({\n message: z.string().nullish(),\n detail: z.unknown().nullish(),\n error: z\n .union([z.string(), z.object({ message: z.string().nullish() })])\n .nullish(),\n error_type: z.string().nullish(),\n }),\n errorToMessage: error =>\n error.message ??\n (typeof error.error === 'string' ? error.error : error.error?.message) ??\n (typeof error.detail === 'string'\n ? error.detail\n : JSON.stringify(error.detail)) ??\n error.error_type ??\n 'TypeSafe request failed',\n});\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import {\n InvalidArgumentError,\n type Experimental_DecisionModelV4 as DecisionModelV4,\n type Experimental_DecisionModelV4Answer as DecisionModelV4Answer,\n type SharedV4Warning,\n} from '@ai-sdk/provider';\nimport {\n combineHeaders,\n createJsonResponseHandler,\n loadApiKey,\n postJsonToApi,\n resolve,\n serializeModelOptions,\n withUserAgentSuffix,\n WORKFLOW_SERIALIZE,\n WORKFLOW_DESERIALIZE,\n type FetchFunction,\n type Resolvable,\n} from '@ai-sdk/provider-utils';\nimport {\n typesafeDecisionResponseSchema,\n typesafeFailedResponseHandler,\n} from './typesafe-ai-decision-api';\nimport { VERSION } from './version';\n\nexport type TypeSafeAiDecisionModelId = 'jev-latest' | (string & {});\n\ntype TypeSafeAiDecisionModelConfig = {\n provider: string;\n baseURL: string;\n headers?: Resolvable<Record<string, string | undefined>>;\n fetch?: FetchFunction;\n};\n\nexport class DecisionTypeSafeAiModel implements DecisionModelV4 {\n readonly specificationVersion = 'v4';\n readonly supportedQuestionTypes = ['choice', 'score', 'boolean'] as const;\n\n constructor(\n readonly modelId: TypeSafeAiDecisionModelId,\n private readonly config: TypeSafeAiDecisionModelConfig,\n ) {}\n\n get provider() {\n return this.config.provider;\n }\n\n static [WORKFLOW_SERIALIZE](model: DecisionTypeSafeAiModel) {\n return serializeModelOptions({\n modelId: model.modelId,\n config: model.config,\n });\n }\n\n static [WORKFLOW_DESERIALIZE](options: {\n modelId: TypeSafeAiDecisionModelId;\n config: TypeSafeAiDecisionModelConfig;\n }) {\n return new DecisionTypeSafeAiModel(options.modelId, options.config);\n }\n\n /** @deprecated Use `doDecide` instead. */\n doEvaluate(options: Parameters<DecisionModelV4['doDecide']>[0]) {\n return this.doDecide(options);\n }\n\n async doDecide({\n state,\n questions,\n headers,\n abortSignal,\n providerOptions,\n }: Parameters<DecisionModelV4['doDecide']>[0]): Promise<\n Awaited<ReturnType<DecisionModelV4['doDecide']>>\n > {\n for (const [id, question] of Object.entries(questions)) {\n if (\n question.type === 'choice' &&\n Object.keys(question.criteria).length > 255\n ) {\n throw new InvalidArgumentError({\n argument: `questions.${id}.criteria`,\n message: 'TypeSafe Choice questions support at most 255 options.',\n });\n }\n if (question.type === 'score' && question.criteria.length > 10) {\n throw new InvalidArgumentError({\n argument: `questions.${id}.criteria`,\n message: 'TypeSafe Score questions support at most 10 levels.',\n });\n }\n }\n\n const warnings: SharedV4Warning[] = Object.keys(\n providerOptions?.typesafe ?? {},\n ).map(option => ({\n type: 'unsupported',\n feature: `providerOptions.typesafe.${option}`,\n }));\n const modelHeaders =\n this.config.headers === undefined\n ? withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({ apiKey: undefined, environmentVariableName: 'TYPESAFE_AI_API_KEY', description: 'TypeSafe' })}`,\n },\n `ai-sdk-typesafe-ai/${VERSION}`,\n )\n : await resolve(this.config.headers);\n const {\n value: response,\n rawValue,\n responseHeaders,\n } = await postJsonToApi({\n url: `${this.config.baseURL}/systemone`,\n headers: combineHeaders(modelHeaders, headers),\n body: {\n model: this.modelId,\n state,\n questions: Object.fromEntries(\n Object.entries(questions).map(([id, question]) => [\n id,\n question.type === 'boolean'\n ? { ...question, type: 'noul' }\n : question,\n ]),\n ),\n },\n abortSignal,\n fetch: this.config.fetch,\n failedResponseHandler: typesafeFailedResponseHandler,\n successfulResponseHandler: createJsonResponseHandler(\n typesafeDecisionResponseSchema,\n ),\n });\n\n const confidence = Object.fromEntries(\n Object.entries(response.answers).flatMap(([id, answer]) =>\n answer.type !== 'noul' && answer.confidence != null\n ? [[id, answer.confidence]]\n : [],\n ),\n );\n\n return {\n answers: Object.fromEntries(\n Object.entries(response.answers).map(\n ([id, answer]): [string, DecisionModelV4Answer] => {\n switch (answer.type) {\n case 'noul':\n return [id, { type: 'boolean', probability: answer.noul }];\n case 'choice':\n return [\n id,\n {\n type: 'choice',\n choice: answer.choice,\n probabilities: answer.probabilities,\n },\n ];\n case 'score':\n return [\n id,\n {\n type: 'score',\n score: answer.score,\n probabilities: answer.probabilities,\n },\n ];\n }\n },\n ),\n ),\n usage: {\n inputTokens: response.usage?.input_tokens ?? undefined,\n outputTokens: response.usage?.output_tokens ?? undefined,\n },\n // The API rounds displayed probabilities and scores to two decimal places.\n rounding: { probabilityDecimals: 2, scoreDecimals: 2 },\n warnings,\n providerMetadata: { typesafe: { confidence } },\n response: {\n modelId: response.model ?? this.modelId,\n headers: responseHeaders,\n body: rawValue,\n },\n };\n }\n}\n","import {\n NoSuchModelError,\n type Experimental_DecisionModelV4 as DecisionModelV4,\n type ProviderV4,\n} from '@ai-sdk/provider';\nimport {\n loadApiKey,\n loadOptionalSetting,\n withoutTrailingSlash,\n withUserAgentSuffix,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport {\n DecisionTypeSafeAiModel,\n type TypeSafeAiDecisionModelId,\n} from './typesafe-ai-decision-model';\nimport { VERSION } from './version';\n\n/** TypeSafe's experimental decision capability, isolated from ProviderV4. */\nexport interface TypeSafeAiProvider extends ProviderV4 {\n decisionModel(modelId: TypeSafeAiDecisionModelId): DecisionModelV4;\n /** @deprecated Use `decisionModel` instead. */\n evaluationModel(modelId: TypeSafeAiDecisionModelId): DecisionModelV4 & {\n doEvaluate: DecisionModelV4['doDecide'];\n };\n}\n\nexport interface TypeSafeAiProviderSettings {\n /** API key. Defaults to the TYPESAFE_AI_API_KEY environment variable. */\n apiKey?: string;\n /**\n * API base URL. Defaults to the TYPESAFE_AI_BASE_URL environment variable,\n * then https://api.typesafe.ai/v1.\n */\n baseURL?: string;\n headers?: Record<string, string>;\n fetch?: FetchFunction;\n}\n\nexport function createTypeSafeAi(\n options: TypeSafeAiProviderSettings = {},\n): TypeSafeAiProvider {\n const baseURL =\n withoutTrailingSlash(\n loadOptionalSetting({\n settingValue: options.baseURL,\n environmentVariableName: 'TYPESAFE_AI_BASE_URL',\n }),\n ) ?? 'https://api.typesafe.ai/v1';\n const headers = () =>\n withUserAgentSuffix(\n {\n Authorization: `Bearer ${loadApiKey({ apiKey: options.apiKey, environmentVariableName: 'TYPESAFE_AI_API_KEY', description: 'TypeSafe' })}`,\n ...options.headers,\n },\n `ai-sdk-typesafe-ai/${VERSION}`,\n );\n\n const decisionModel = (modelId: TypeSafeAiDecisionModelId) =>\n new DecisionTypeSafeAiModel(modelId, {\n provider: 'typesafe.decision',\n baseURL,\n headers,\n fetch: options.fetch,\n });\n\n return {\n specificationVersion: 'v4',\n decisionModel,\n evaluationModel: decisionModel,\n languageModel: modelId => {\n throw new NoSuchModelError({ modelId, modelType: 'languageModel' });\n },\n embeddingModel: modelId => {\n throw new NoSuchModelError({ modelId, modelType: 'embeddingModel' });\n },\n imageModel: modelId => {\n throw new NoSuchModelError({ modelId, modelType: 'imageModel' });\n },\n };\n}\n\nexport const typeSafeAi = createTypeSafeAi();\n"],"mappings":"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"}
|
package/docs/105-typesafe-ai.mdx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: TypeSafe
|
|
3
|
-
description: Use TypeSafe System One models for typed
|
|
3
|
+
description: Use TypeSafe System One models for typed decisions with the AI SDK.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# TypeSafe Provider
|
|
7
7
|
|
|
8
|
-
The [TypeSafe](https://typesafe.ai) provider supports the experimental
|
|
8
|
+
The [TypeSafe](https://typesafe.ai) provider supports the experimental decision
|
|
9
9
|
API with native Choice, Score, and Boolean answers. It sends all questions in one
|
|
10
10
|
request against the same state.
|
|
11
11
|
|
|
@@ -30,21 +30,32 @@ const customTypeSafe = createTypeSafeAi({
|
|
|
30
30
|
|
|
31
31
|
`createTypeSafeAi` accepts:
|
|
32
32
|
|
|
33
|
-
| Setting | Description
|
|
34
|
-
| --------- |
|
|
35
|
-
| `apiKey` | API key; defaults to `TYPESAFE_AI_API_KEY`.
|
|
36
|
-
| `baseURL` | Defaults to `https://api.typesafe.ai/v1`.
|
|
37
|
-
| `headers` | Additional request headers.
|
|
38
|
-
| `fetch` | Custom fetch implementation.
|
|
33
|
+
| Setting | Description |
|
|
34
|
+
| --------- | ---------------------------------------------------------------------- |
|
|
35
|
+
| `apiKey` | API key; defaults to `TYPESAFE_AI_API_KEY`. |
|
|
36
|
+
| `baseURL` | Defaults to `TYPESAFE_AI_BASE_URL`, then `https://api.typesafe.ai/v1`. |
|
|
37
|
+
| `headers` | Additional request headers. |
|
|
38
|
+
| `fetch` | Custom fetch implementation. |
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Use `TYPESAFE_AI_BASE_URL` to route the default `typeSafeAi` instance through a
|
|
41
|
+
trusted proxy or self-hosted TypeSafe-compatible server:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
TYPESAFE_AI_BASE_URL=http://127.0.0.1:8766/v1
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
An explicit `baseURL` passed to `createTypeSafeAi` takes precedence over the
|
|
48
|
+
environment variable. The configured server receives the API key and decision
|
|
49
|
+
state and must implement the TypeSafe `POST /systemone` API.
|
|
50
|
+
|
|
51
|
+
## Decision
|
|
41
52
|
|
|
42
53
|
```ts
|
|
43
54
|
import { typeSafeAi } from '@ai-sdk/typesafe-ai';
|
|
44
|
-
import {
|
|
55
|
+
import { experimental_decide } from 'ai';
|
|
45
56
|
|
|
46
|
-
const result = await
|
|
47
|
-
model: typeSafeAi.
|
|
57
|
+
const result = await experimental_decide({
|
|
58
|
+
model: typeSafeAi.decisionModel('jev-latest'),
|
|
48
59
|
state: {
|
|
49
60
|
message: 'I was charged twice. Please refund the duplicate.',
|
|
50
61
|
},
|
|
@@ -80,7 +91,7 @@ Use `jev-latest` or another TypeSafe model ID. The response includes the actual
|
|
|
80
91
|
model ID, such as the resolved version behind the alias. Use model instances,
|
|
81
92
|
custom aliases, or registered providers. With `typeSafeAi` explicitly configured
|
|
82
93
|
as `globalThis.AI_SDK_DEFAULT_PROVIDER`, you can pass `model: 'jev-latest'`
|
|
83
|
-
directly. See [model aliases and registries](/docs/ai-sdk-core/
|
|
94
|
+
directly. See [model aliases and registries](/docs/ai-sdk-core/decisions#model-aliases-and-registries).
|
|
84
95
|
|
|
85
96
|
| Question | Native TypeSafe primitive | Limits and semantics |
|
|
86
97
|
| --------- | ------------------------- | -------------------------------------------------------------------- |
|
|
@@ -115,5 +126,5 @@ No provider-specific options are currently defined. Unknown entries under
|
|
|
115
126
|
`providerOptions.typesafe` produce unsupported-option warnings. Language,
|
|
116
127
|
embedding, and image model factories throw `NoSuchModelError`.
|
|
117
128
|
|
|
118
|
-
|
|
129
|
+
Decision models support workflow serialization. A custom fetch function is not
|
|
119
130
|
serialized; restored models use the default fetch implementation.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/typesafe-ai",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@ai-sdk/provider": "4.0.
|
|
33
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
32
|
+
"@ai-sdk/provider": "4.0.22",
|
|
33
|
+
"@ai-sdk/provider-utils": "5.0.54"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@ai-sdk/test-server": "2.0.3",
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import type { TypeSafeAiDecisionModelId } from './typesafe-ai-decision-model';
|
|
2
|
+
|
|
1
3
|
export { createTypeSafeAi, typeSafeAi } from './typesafe-ai-provider';
|
|
2
4
|
export type {
|
|
3
5
|
TypeSafeAiProvider,
|
|
4
6
|
TypeSafeAiProviderSettings,
|
|
5
7
|
} from './typesafe-ai-provider';
|
|
6
|
-
export type {
|
|
8
|
+
export type { TypeSafeAiDecisionModelId as Experimental_TypeSafeAiDecisionModelId } from './typesafe-ai-decision-model';
|
|
7
9
|
export { VERSION } from './version';
|
|
10
|
+
|
|
11
|
+
/** @deprecated Use `Experimental_TypeSafeAiDecisionModelId` instead. */
|
|
12
|
+
export type Experimental_TypeSafeAiEvaluationModelId =
|
|
13
|
+
TypeSafeAiDecisionModelId;
|
|
@@ -3,7 +3,7 @@ import * as z from 'zod/v4';
|
|
|
3
3
|
|
|
4
4
|
// Verified against the official SDK at 66880ccded6cb642dc1809620c2b108c33730214.
|
|
5
5
|
// https://github.com/typesafe-ai/typesafe-sdk-js/blob/66880ccded6cb642dc1809620c2b108c33730214/src/types.ts
|
|
6
|
-
export const
|
|
6
|
+
export const typesafeDecisionResponseSchema = z.object({
|
|
7
7
|
model: z.string().nullish(),
|
|
8
8
|
answers: z.record(
|
|
9
9
|
z.string(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
InvalidArgumentError,
|
|
3
|
-
type
|
|
4
|
-
type
|
|
3
|
+
type Experimental_DecisionModelV4 as DecisionModelV4,
|
|
4
|
+
type Experimental_DecisionModelV4Answer as DecisionModelV4Answer,
|
|
5
5
|
type SharedV4Warning,
|
|
6
6
|
} from '@ai-sdk/provider';
|
|
7
7
|
import {
|
|
@@ -18,34 +18,34 @@ import {
|
|
|
18
18
|
type Resolvable,
|
|
19
19
|
} from '@ai-sdk/provider-utils';
|
|
20
20
|
import {
|
|
21
|
-
|
|
21
|
+
typesafeDecisionResponseSchema,
|
|
22
22
|
typesafeFailedResponseHandler,
|
|
23
|
-
} from './typesafe-ai-
|
|
23
|
+
} from './typesafe-ai-decision-api';
|
|
24
24
|
import { VERSION } from './version';
|
|
25
25
|
|
|
26
|
-
export type
|
|
26
|
+
export type TypeSafeAiDecisionModelId = 'jev-latest' | (string & {});
|
|
27
27
|
|
|
28
|
-
type
|
|
28
|
+
type TypeSafeAiDecisionModelConfig = {
|
|
29
29
|
provider: string;
|
|
30
30
|
baseURL: string;
|
|
31
31
|
headers?: Resolvable<Record<string, string | undefined>>;
|
|
32
32
|
fetch?: FetchFunction;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
export class
|
|
35
|
+
export class DecisionTypeSafeAiModel implements DecisionModelV4 {
|
|
36
36
|
readonly specificationVersion = 'v4';
|
|
37
37
|
readonly supportedQuestionTypes = ['choice', 'score', 'boolean'] as const;
|
|
38
38
|
|
|
39
39
|
constructor(
|
|
40
|
-
readonly modelId:
|
|
41
|
-
private readonly config:
|
|
40
|
+
readonly modelId: TypeSafeAiDecisionModelId,
|
|
41
|
+
private readonly config: TypeSafeAiDecisionModelConfig,
|
|
42
42
|
) {}
|
|
43
43
|
|
|
44
44
|
get provider() {
|
|
45
45
|
return this.config.provider;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
static [WORKFLOW_SERIALIZE](model:
|
|
48
|
+
static [WORKFLOW_SERIALIZE](model: DecisionTypeSafeAiModel) {
|
|
49
49
|
return serializeModelOptions({
|
|
50
50
|
modelId: model.modelId,
|
|
51
51
|
config: model.config,
|
|
@@ -53,20 +53,25 @@ export class EvaluationTypeSafeAiModel implements EvaluationModelV4 {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
static [WORKFLOW_DESERIALIZE](options: {
|
|
56
|
-
modelId:
|
|
57
|
-
config:
|
|
56
|
+
modelId: TypeSafeAiDecisionModelId;
|
|
57
|
+
config: TypeSafeAiDecisionModelConfig;
|
|
58
58
|
}) {
|
|
59
|
-
return new
|
|
59
|
+
return new DecisionTypeSafeAiModel(options.modelId, options.config);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
/** @deprecated Use `doDecide` instead. */
|
|
63
|
+
doEvaluate(options: Parameters<DecisionModelV4['doDecide']>[0]) {
|
|
64
|
+
return this.doDecide(options);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async doDecide({
|
|
63
68
|
state,
|
|
64
69
|
questions,
|
|
65
70
|
headers,
|
|
66
71
|
abortSignal,
|
|
67
72
|
providerOptions,
|
|
68
|
-
}: Parameters<
|
|
69
|
-
Awaited<ReturnType<
|
|
73
|
+
}: Parameters<DecisionModelV4['doDecide']>[0]): Promise<
|
|
74
|
+
Awaited<ReturnType<DecisionModelV4['doDecide']>>
|
|
70
75
|
> {
|
|
71
76
|
for (const [id, question] of Object.entries(questions)) {
|
|
72
77
|
if (
|
|
@@ -124,7 +129,7 @@ export class EvaluationTypeSafeAiModel implements EvaluationModelV4 {
|
|
|
124
129
|
fetch: this.config.fetch,
|
|
125
130
|
failedResponseHandler: typesafeFailedResponseHandler,
|
|
126
131
|
successfulResponseHandler: createJsonResponseHandler(
|
|
127
|
-
|
|
132
|
+
typesafeDecisionResponseSchema,
|
|
128
133
|
),
|
|
129
134
|
});
|
|
130
135
|
|
|
@@ -139,7 +144,7 @@ export class EvaluationTypeSafeAiModel implements EvaluationModelV4 {
|
|
|
139
144
|
return {
|
|
140
145
|
answers: Object.fromEntries(
|
|
141
146
|
Object.entries(response.answers).map(
|
|
142
|
-
([id, answer]): [string,
|
|
147
|
+
([id, answer]): [string, DecisionModelV4Answer] => {
|
|
143
148
|
switch (answer.type) {
|
|
144
149
|
case 'noul':
|
|
145
150
|
return [id, { type: 'boolean', probability: answer.noul }];
|
|
@@ -1,29 +1,37 @@
|
|
|
1
1
|
import {
|
|
2
2
|
NoSuchModelError,
|
|
3
|
-
type
|
|
3
|
+
type Experimental_DecisionModelV4 as DecisionModelV4,
|
|
4
4
|
type ProviderV4,
|
|
5
5
|
} from '@ai-sdk/provider';
|
|
6
6
|
import {
|
|
7
7
|
loadApiKey,
|
|
8
|
+
loadOptionalSetting,
|
|
8
9
|
withoutTrailingSlash,
|
|
9
10
|
withUserAgentSuffix,
|
|
10
11
|
type FetchFunction,
|
|
11
12
|
} from '@ai-sdk/provider-utils';
|
|
12
13
|
import {
|
|
13
|
-
|
|
14
|
-
type
|
|
15
|
-
} from './typesafe-ai-
|
|
14
|
+
DecisionTypeSafeAiModel,
|
|
15
|
+
type TypeSafeAiDecisionModelId,
|
|
16
|
+
} from './typesafe-ai-decision-model';
|
|
16
17
|
import { VERSION } from './version';
|
|
17
18
|
|
|
18
|
-
/** TypeSafe's experimental
|
|
19
|
+
/** TypeSafe's experimental decision capability, isolated from ProviderV4. */
|
|
19
20
|
export interface TypeSafeAiProvider extends ProviderV4 {
|
|
20
|
-
|
|
21
|
+
decisionModel(modelId: TypeSafeAiDecisionModelId): DecisionModelV4;
|
|
22
|
+
/** @deprecated Use `decisionModel` instead. */
|
|
23
|
+
evaluationModel(modelId: TypeSafeAiDecisionModelId): DecisionModelV4 & {
|
|
24
|
+
doEvaluate: DecisionModelV4['doDecide'];
|
|
25
|
+
};
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
export interface TypeSafeAiProviderSettings {
|
|
24
29
|
/** API key. Defaults to the TYPESAFE_AI_API_KEY environment variable. */
|
|
25
30
|
apiKey?: string;
|
|
26
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* API base URL. Defaults to the TYPESAFE_AI_BASE_URL environment variable,
|
|
33
|
+
* then https://api.typesafe.ai/v1.
|
|
34
|
+
*/
|
|
27
35
|
baseURL?: string;
|
|
28
36
|
headers?: Record<string, string>;
|
|
29
37
|
fetch?: FetchFunction;
|
|
@@ -33,7 +41,12 @@ export function createTypeSafeAi(
|
|
|
33
41
|
options: TypeSafeAiProviderSettings = {},
|
|
34
42
|
): TypeSafeAiProvider {
|
|
35
43
|
const baseURL =
|
|
36
|
-
withoutTrailingSlash(
|
|
44
|
+
withoutTrailingSlash(
|
|
45
|
+
loadOptionalSetting({
|
|
46
|
+
settingValue: options.baseURL,
|
|
47
|
+
environmentVariableName: 'TYPESAFE_AI_BASE_URL',
|
|
48
|
+
}),
|
|
49
|
+
) ?? 'https://api.typesafe.ai/v1';
|
|
37
50
|
const headers = () =>
|
|
38
51
|
withUserAgentSuffix(
|
|
39
52
|
{
|
|
@@ -43,15 +56,18 @@ export function createTypeSafeAi(
|
|
|
43
56
|
`ai-sdk-typesafe-ai/${VERSION}`,
|
|
44
57
|
);
|
|
45
58
|
|
|
59
|
+
const decisionModel = (modelId: TypeSafeAiDecisionModelId) =>
|
|
60
|
+
new DecisionTypeSafeAiModel(modelId, {
|
|
61
|
+
provider: 'typesafe.decision',
|
|
62
|
+
baseURL,
|
|
63
|
+
headers,
|
|
64
|
+
fetch: options.fetch,
|
|
65
|
+
});
|
|
66
|
+
|
|
46
67
|
return {
|
|
47
68
|
specificationVersion: 'v4',
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
provider: 'typesafe.evaluation',
|
|
51
|
-
baseURL,
|
|
52
|
-
headers,
|
|
53
|
-
fetch: options.fetch,
|
|
54
|
-
}),
|
|
69
|
+
decisionModel,
|
|
70
|
+
evaluationModel: decisionModel,
|
|
55
71
|
languageModel: modelId => {
|
|
56
72
|
throw new NoSuchModelError({ modelId, modelType: 'languageModel' });
|
|
57
73
|
},
|