@ai-sdk/typesafe-ai 3.0.14 → 3.0.16

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 CHANGED
@@ -1,5 +1,31 @@
1
1
  # @ai-sdk/typesafe-ai
2
2
 
3
+ ## 3.0.16
4
+
5
+ ### Patch Changes
6
+
7
+ - 9184a35: Add ordered text, file, and JSON parts to experimental decision state. Support image input in OpenAI Decisions and language model adapters. Gateway retains its existing string and JSON request format and rejects files, as does TypeSafe AI.
8
+
9
+ Arrays passed directly as state now contain decision state parts. Wrap JSON arrays in an object or a json part.
10
+
11
+ Normalize all public state forms into an array of parts before calling decision providers. Providers receive text and JSON objects as text and json parts.
12
+
13
+ Serialize decision file bytes as base64 in OpenTelemetry state attributes. Model-call spans record normalized state parts, while outer spans retain public state inputs.
14
+
15
+ Preserve native JSON state in TypeSafe AI when state contains one JSON part. Label shared state in language-model decision prompts.
16
+
17
+ - Updated dependencies [9184a35]
18
+ - @ai-sdk/provider@4.0.25
19
+ - @ai-sdk/provider-utils@5.0.57
20
+
21
+ ## 3.0.15
22
+
23
+ ### Patch Changes
24
+
25
+ - Updated dependencies [d3bcad9]
26
+ - @ai-sdk/provider@4.0.24
27
+ - @ai-sdk/provider-utils@5.0.56
28
+
3
29
  ## 3.0.14
4
30
 
5
31
  ### Patch Changes
@@ -1 +1 @@
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"}
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":";;;KA0BY;;;;UCPK,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,4 +1,4 @@
1
- import { InvalidArgumentError, NoSuchModelError } from "@ai-sdk/provider";
1
+ import { InvalidArgumentError, NoSuchModelError, UnsupportedFunctionalityError } from "@ai-sdk/provider";
2
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
4
  //#region src/typesafe-ai-decision-api.ts
@@ -38,7 +38,7 @@ const typesafeFailedResponseHandler = createJsonErrorResponseHandler({
38
38
  });
39
39
  //#endregion
40
40
  //#region src/version.ts
41
- const VERSION = "3.0.14";
41
+ const VERSION = "3.0.16";
42
42
  //#endregion
43
43
  //#region src/typesafe-ai-decision-model.ts
44
44
  var DecisionTypeSafeAiModel = class DecisionTypeSafeAiModel {
@@ -83,6 +83,10 @@ var DecisionTypeSafeAiModel = class DecisionTypeSafeAiModel {
83
83
  type: "unsupported",
84
84
  feature: `providerOptions.typesafe.${option}`
85
85
  }));
86
+ const requestState = state.length === 1 && state[0].type === "json" ? state[0].value : state.map((part) => {
87
+ if (part.type === "file") throw new UnsupportedFunctionalityError({ functionality: "TypeSafe AI decision file input" });
88
+ return part.type === "text" ? part.text : JSON.stringify(part.value);
89
+ }).join("\n");
86
90
  const modelHeaders = this.config.headers === void 0 ? withUserAgentSuffix({ Authorization: `Bearer ${loadApiKey({
87
91
  apiKey: void 0,
88
92
  environmentVariableName: "TYPESAFE_AI_API_KEY",
@@ -93,7 +97,7 @@ var DecisionTypeSafeAiModel = class DecisionTypeSafeAiModel {
93
97
  headers: combineHeaders(modelHeaders, headers),
94
98
  body: {
95
99
  model: this.modelId,
96
- state,
100
+ state: requestState,
97
101
  questions: Object.fromEntries(Object.entries(questions).map(([id, question]) => [id, question.type === "boolean" ? {
98
102
  ...question,
99
103
  type: "noul"
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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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"}
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 UnsupportedFunctionalityError,\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 requestState =\n state.length === 1 && state[0].type === 'json'\n ? state[0].value\n : state\n .map(part => {\n if (part.type === 'file')\n throw new UnsupportedFunctionalityError({\n functionality: 'TypeSafe AI decision file input',\n });\n return part.type === 'text'\n ? part.text\n : JSON.stringify(part.value);\n })\n .join('\\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: requestState,\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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/typesafe-ai",
3
- "version": "3.0.14",
3
+ "version": "3.0.16",
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.23",
33
- "@ai-sdk/provider-utils": "5.0.55"
32
+ "@ai-sdk/provider": "4.0.25",
33
+ "@ai-sdk/provider-utils": "5.0.57"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@ai-sdk/test-server": "2.0.4",
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  InvalidArgumentError,
3
+ UnsupportedFunctionalityError,
3
4
  type Experimental_DecisionModelV4 as DecisionModelV4,
4
5
  type Experimental_DecisionModelV4Answer as DecisionModelV4Answer,
5
6
  type SharedV4Warning,
@@ -97,6 +98,20 @@ export class DecisionTypeSafeAiModel implements DecisionModelV4 {
97
98
  type: 'unsupported',
98
99
  feature: `providerOptions.typesafe.${option}`,
99
100
  }));
101
+ const requestState =
102
+ state.length === 1 && state[0].type === 'json'
103
+ ? state[0].value
104
+ : state
105
+ .map(part => {
106
+ if (part.type === 'file')
107
+ throw new UnsupportedFunctionalityError({
108
+ functionality: 'TypeSafe AI decision file input',
109
+ });
110
+ return part.type === 'text'
111
+ ? part.text
112
+ : JSON.stringify(part.value);
113
+ })
114
+ .join('\n');
100
115
  const modelHeaders =
101
116
  this.config.headers === undefined
102
117
  ? withUserAgentSuffix(
@@ -115,7 +130,7 @@ export class DecisionTypeSafeAiModel implements DecisionModelV4 {
115
130
  headers: combineHeaders(modelHeaders, headers),
116
131
  body: {
117
132
  model: this.modelId,
118
- state,
133
+ state: requestState,
119
134
  questions: Object.fromEntries(
120
135
  Object.entries(questions).map(([id, question]) => [
121
136
  id,