@truefoundry/ai-gateway-sdk 0.0.4 → 0.0.6

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.
Files changed (81) hide show
  1. package/dist/adapters/responses/index.js +2 -0
  2. package/dist/adapters/responses/index.js.map +1 -1
  3. package/dist/autogen/decoders.d.ts +5 -5
  4. package/dist/autogen/decoders.js +30 -30
  5. package/dist/autogen/decoders.js.map +1 -1
  6. package/dist/autogen/meta.d.ts +5 -5
  7. package/dist/autogen/meta.js +4 -4
  8. package/dist/autogen/meta.js.map +1 -1
  9. package/dist/autogen/models.d.ts +25 -25
  10. package/dist/autogen/schema.json +49 -49
  11. package/dist/entities/Provider.d.ts +1 -1
  12. package/dist/entities/Provider.js +1 -1
  13. package/dist/entities/Provider.js.map +1 -1
  14. package/dist/errors.d.ts +7 -0
  15. package/dist/errors.js +9 -0
  16. package/dist/errors.js.map +1 -1
  17. package/dist/globals.d.ts +1 -1
  18. package/dist/globals.js +2 -2
  19. package/dist/globals.js.map +1 -1
  20. package/dist/handlers/tfyUtils.js +3 -3
  21. package/dist/handlers/tfyUtils.js.map +1 -1
  22. package/dist/providers/databricks/api.js +3 -1
  23. package/dist/providers/databricks/api.js.map +1 -1
  24. package/dist/providers/databricks/decision.d.ts +5 -0
  25. package/dist/providers/databricks/decision.js +13 -0
  26. package/dist/providers/databricks/decision.js.map +1 -0
  27. package/dist/providers/databricks/index.js +6 -0
  28. package/dist/providers/databricks/index.js.map +1 -1
  29. package/dist/providers/index.js +2 -2
  30. package/dist/providers/index.js.map +1 -1
  31. package/dist/providers/microsoft-foundry/api.js +6 -0
  32. package/dist/providers/microsoft-foundry/api.js.map +1 -1
  33. package/dist/providers/microsoft-foundry/decision.d.ts +5 -0
  34. package/dist/providers/microsoft-foundry/decision.js +14 -0
  35. package/dist/providers/microsoft-foundry/decision.js.map +1 -0
  36. package/dist/providers/microsoft-foundry/index.js +3 -0
  37. package/dist/providers/microsoft-foundry/index.js.map +1 -1
  38. package/dist/providers/openai/api.js +2 -0
  39. package/dist/providers/openai/api.js.map +1 -1
  40. package/dist/providers/openai/decisions.d.ts +23 -0
  41. package/dist/providers/openai/decisions.js +52 -0
  42. package/dist/providers/openai/decisions.js.map +1 -0
  43. package/dist/providers/openai/index.js +3 -0
  44. package/dist/providers/openai/index.js.map +1 -1
  45. package/dist/providers/openrouter/api.js +2 -0
  46. package/dist/providers/openrouter/api.js.map +1 -1
  47. package/dist/providers/openrouter/decision.d.ts +13 -0
  48. package/dist/providers/openrouter/decision.js +5 -0
  49. package/dist/providers/openrouter/decision.js.map +1 -0
  50. package/dist/providers/openrouter/index.js +3 -0
  51. package/dist/providers/openrouter/index.js.map +1 -1
  52. package/dist/providers/perplexity-ai/decision.d.ts +5 -28
  53. package/dist/providers/perplexity-ai/decision.js +10 -45
  54. package/dist/providers/perplexity-ai/decision.js.map +1 -1
  55. package/dist/providers/shared/decisionDialect.d.ts +13 -0
  56. package/dist/providers/shared/decisionDialect.js +343 -0
  57. package/dist/providers/shared/decisionDialect.js.map +1 -0
  58. package/dist/providers/shared/systemOneDecision.d.ts +69 -0
  59. package/dist/providers/shared/systemOneDecision.js +71 -0
  60. package/dist/providers/shared/systemOneDecision.js.map +1 -0
  61. package/dist/providers/truefoundry-managed/api.d.ts +3 -0
  62. package/dist/providers/{truefoundry-models → truefoundry-managed}/api.js +2 -2
  63. package/dist/providers/truefoundry-managed/api.js.map +1 -0
  64. package/dist/providers/truefoundry-managed/index.d.ts +3 -0
  65. package/dist/providers/{truefoundry-models → truefoundry-managed}/index.js +11 -11
  66. package/dist/providers/truefoundry-managed/index.js.map +1 -0
  67. package/dist/providers/typesafe/decision.d.ts +4 -26
  68. package/dist/providers/typesafe/decision.js +5 -42
  69. package/dist/providers/typesafe/decision.js.map +1 -1
  70. package/dist/tfy-providers/custom/api.js +3 -0
  71. package/dist/tfy-providers/custom/api.js.map +1 -1
  72. package/dist/tfy-providers/custom/index.js +3 -0
  73. package/dist/tfy-providers/custom/index.js.map +1 -1
  74. package/dist/tfy-providers/custom/vllm-openai/decision.d.ts +6 -0
  75. package/dist/tfy-providers/custom/vllm-openai/decision.js +27 -0
  76. package/dist/tfy-providers/custom/vllm-openai/decision.js.map +1 -0
  77. package/package.json +1 -1
  78. package/dist/providers/truefoundry-models/api.d.ts +0 -3
  79. package/dist/providers/truefoundry-models/api.js.map +0 -1
  80. package/dist/providers/truefoundry-models/index.d.ts +0 -3
  81. package/dist/providers/truefoundry-models/index.js.map +0 -1
@@ -0,0 +1,343 @@
1
+ /**
2
+ * ================================
3
+ * TFY Managed File - Decision dialect translation
4
+ * ================================
5
+ *
6
+ * Two wire formats answer typed questions, and the gateway serves both on fn `decision`:
7
+ *
8
+ * System One `{state, questions: {name: {type: noul|choice|score, criteria}}}`
9
+ * -> `{answers: {name: {...}}}` (every provider except OpenAI)
10
+ * OpenAI `{input, questions: [{type: predicate|choice|score, name, choices|levels}]}`
11
+ * -> `{answers: [{name, ...}]}` (OpenAI only)
12
+ *
13
+ * A virtual model can mix the two, and the caller cannot know which target will serve the
14
+ * request, so the body has to be translated per target. This module does that translation; the
15
+ * caller always gets answers back in the dialect of the route it called.
16
+ *
17
+ * Only `answers`, `questions` and the evidence field are reshaped. `usage` is left exactly as
18
+ * the provider's response transform produced it, because the gateway's token names on it are
19
+ * what the costing path reads.
20
+ *
21
+ * ── Request: System One -> OpenAI ────────────────────────────────────────────────────────────
22
+ *
23
+ * { state: { ticket: 4411, text: "Charged twice" }, -> { input: '{"ticket":4411,...}',
24
+ * questions: { questions: [
25
+ * damaged: { type: "noul", instructions: "Damaged?", { type: "predicate", name: "damaged",
26
+ * criteria: { true: "Visible damage" } }, instructions: "Damaged?\n\nAnswer true when: Visible damage" },
27
+ * team: { type: "choice", instructions: "Which?", { type: "choice", name: "team", instructions: "Which?",
28
+ * criteria: { billing: "Payments", choices: [{ value: "billing", description: "Payments" },
29
+ * eng: null } }, { value: "eng" }] },
30
+ * severity: { type: "score", instructions: "How bad?", { type: "score", name: "severity", instructions: "How bad?",
31
+ * criteria: ["minor", "major"] } } } levels: [{ label: "minor" }, { label: "major" }] }] }
32
+ *
33
+ * The map key becomes `name`. A noul's `criteria` have no OpenAI field, so they are folded into
34
+ * the instructions text. A structured `state` is serialized, since `input` is text.
35
+ *
36
+ * ── Request: OpenAI -> System One ────────────────────────────────────────────────────────────
37
+ *
38
+ * { input: [{ type: "message", role: "user", -> { state: "Charged twice\nRefund please",
39
+ * content: [{ type: "input_text", questions: {
40
+ * text: "Charged twice" }, is_dup: { type: "noul", instructions: "Duplicate?" } } }
41
+ * { type: "input_text",
42
+ * text: "Refund please" }] }],
43
+ * questions: [{ type: "predicate", name: "is_dup",
44
+ * instructions: "Duplicate?" }],
45
+ * safety_identifier: "user-1234" }
46
+ *
47
+ * Text parts are joined into `state`; message roles and `safety_identifier` are dropped. An
48
+ * unnamed question is keyed `question_<index>` so its answer can be matched back. Only `type`,
49
+ * `instructions` and `criteria` are emitted — System One servers 400 on other question fields.
50
+ *
51
+ * ── Response: System One -> OpenAI ───────────────────────────────────────────────────────────
52
+ *
53
+ * { answers: { -> { answers: [
54
+ * damaged: { type: "noul", noul: 0.98 }, { type: "predicate", name: "damaged", probability: 0.98 },
55
+ * team: { type: "choice", choice: "eng", { type: "choice", name: "team", choice: "eng",
56
+ * confidence: 0.9, confidence: 0.9,
57
+ * probabilities: { billing: 0.1, probabilities: [{ value: "billing", probability: 0.1 },
58
+ * eng: 0.9 } }, { value: "eng", probability: 0.9 }] },
59
+ * severity: { type: "score", score: 1.2, { type: "score", name: "severity", score: 1.2,
60
+ * confidence: 0.8, confidence: 0.8,
61
+ * legend: { 0: "minor", 1: "major" }, probabilities: [{ value: 0, label: "minor", probability: 0.3 },
62
+ * probabilities: { 0: 0.3, 1: 0.7 } } } } { value: 1, label: "major", probability: 0.7 }] }] }
63
+ *
64
+ * Order and names come from the caller's own question list, since a map has none. `legend` and
65
+ * `probabilities` merge into one array. The reverse direction splits them apart again.
66
+ */
67
+ import { DecisionTranslationUnsupportedError, ValidationError } from '../../errors.js';
68
+ /**
69
+ * Derived from the provider's own decision config rather than a separate list of providers:
70
+ * System One configs declare a `state` param, OpenAI's declares `input`. Holds for TypeSafe's
71
+ * Cloudflare variant too, which remaps `state` to `input.state` but still keys on `state`.
72
+ */
73
+ export const getProviderDecisionDialect = (decisionConfig) => decisionConfig && 'state' in decisionConfig ? 'systemOne' : 'openai';
74
+ /** OpenAI requires instructions on every question; System One does not. */
75
+ const GENERIC_INSTRUCTIONS = {
76
+ noul: 'Is this true of the input?',
77
+ choice: 'Which choice best fits the input?',
78
+ score: 'Which level best fits the input?',
79
+ };
80
+ const unsupported = (reason) => {
81
+ throw new DecisionTranslationUnsupportedError(reason);
82
+ };
83
+ /** Stable key for an OpenAI question that carries no `name`, so answers can be matched back. */
84
+ const questionKey = (question, index) => question.name ?? `question_${index}`;
85
+ /** System One accepts a string, JSON object or array wherever OpenAI needs plain text. */
86
+ const decisionsText = (value) => (typeof value === 'string' ? value : JSON.stringify(value));
87
+ /** The generic is a fallback for a missing instruction only; a structured one is serialized. */
88
+ const asInstructions = (instructions, type) => instructions == null ? GENERIC_INSTRUCTIONS[type] : decisionsText(instructions);
89
+ /* ------------------------------------------------------------------ *
90
+ * System One -> OpenAI
91
+ * ------------------------------------------------------------------ */
92
+ /**
93
+ * A noul's criteria have no OpenAI field, so each non-null rule becomes an `Answer <key> when:`
94
+ * line after the instructions. The generic instruction applies only when that leaves nothing at
95
+ * all, so criteria-only questions keep their own wording.
96
+ */
97
+ const predicateInstructions = (question) => {
98
+ const parts = question.instructions == null ? [] : [decisionsText(question.instructions)];
99
+ const criteria = question.criteria;
100
+ if (criteria && typeof criteria === 'object' && !Array.isArray(criteria)) {
101
+ for (const [answer, rule] of Object.entries(criteria)) {
102
+ if (rule != null)
103
+ parts.push(`Answer ${answer} when: ${decisionsText(rule)}`);
104
+ }
105
+ }
106
+ return parts.join('\n\n') || GENERIC_INSTRUCTIONS.noul;
107
+ };
108
+ const systemOneQuestionToOpenAI = (name, question) => {
109
+ if (question.type === 'noul') {
110
+ return { type: 'predicate', name, instructions: predicateInstructions(question) };
111
+ }
112
+ const instructions = asInstructions(question.instructions, question.type);
113
+ if (question.type === 'choice') {
114
+ const criteria = (question.criteria ?? {});
115
+ const choices = Object.entries(criteria).map(([value, description]) => ({
116
+ value,
117
+ ...(typeof description === 'string' && description ? { description } : {}),
118
+ }));
119
+ // OpenAI requires at least two choices; a single-option choice has no equivalent.
120
+ if (choices.length < 2) {
121
+ unsupported(`choice question '${name}' needs at least 2 criteria to be served by an OpenAI decision model`);
122
+ }
123
+ return { type: 'choice', name, instructions, choices };
124
+ }
125
+ const criteria = question.criteria;
126
+ if (!Array.isArray(criteria) || criteria.length < 2) {
127
+ unsupported(`score question '${name}' needs at least 2 ordered criteria to be served by an OpenAI decision model`);
128
+ }
129
+ const levels = criteria.map(level => typeof level === 'string' ? { label: level } : level);
130
+ return { type: 'score', name, instructions, levels };
131
+ };
132
+ const systemOneRequestToOpenAI = (params) => {
133
+ const { state, questions, images, ...rest } = params;
134
+ if (images != null) {
135
+ throw new ValidationError('images is a Clef System One extension and is not accepted by OpenAI decision models');
136
+ }
137
+ const questionMap = (questions ?? {});
138
+ return {
139
+ ...rest,
140
+ // OpenAI's `input` is text; a structured state is serialized rather than dropped. A missing
141
+ // state stays missing — substituting empty text would have the model decide on no evidence.
142
+ input: typeof state === 'string' ? state : JSON.stringify(state),
143
+ questions: Object.entries(questionMap).map(([name, question]) => systemOneQuestionToOpenAI(name, question)),
144
+ };
145
+ };
146
+ /* ------------------------------------------------------------------ *
147
+ * OpenAI -> System One
148
+ * ------------------------------------------------------------------ */
149
+ /**
150
+ * Flattens OpenAI's string-or-messages `input` into System One's `state`. A missing input stays
151
+ * missing — substituting empty text would have the model decide on no evidence.
152
+ */
153
+ const openAIInputToState = (input) => {
154
+ if (typeof input === 'string')
155
+ return input;
156
+ if (!Array.isArray(input))
157
+ return JSON.stringify(input);
158
+ const texts = [];
159
+ for (const message of input) {
160
+ const content = message?.content;
161
+ if (typeof content === 'string') {
162
+ texts.push(content);
163
+ continue;
164
+ }
165
+ for (const part of Array.isArray(content) ? content : []) {
166
+ const { type, text } = (part ?? {});
167
+ // System One providers are text-only, so an image cannot be silently dropped.
168
+ if (type === 'input_image') {
169
+ unsupported('input_image parts are not supported: System One decision models accept text input only');
170
+ }
171
+ if (type === 'input_text' && typeof text === 'string')
172
+ texts.push(text);
173
+ }
174
+ }
175
+ return texts.join('\n');
176
+ };
177
+ /**
178
+ * Only `type`, `instructions` and `criteria` are emitted. System One servers reject a question
179
+ * carrying any other field with a 400 — vLLM and the Decision 1.0 reference implementation both
180
+ * do — so OpenAI-only fields must be dropped rather than passed through.
181
+ * https://docs.vllm.ai/en/latest/serving/online_serving/structured_decisions.html
182
+ */
183
+ const openAIQuestionToSystemOne = (question) => {
184
+ const { type, name, instructions, choices, levels } = question;
185
+ if (type === 'predicate') {
186
+ return { type: 'noul', instructions };
187
+ }
188
+ if (type === 'choice') {
189
+ const criteria = {};
190
+ for (const choice of choices ?? []) {
191
+ const key = String(choice.value);
192
+ // System One keys choices by their text, so `true` and "true" would collide.
193
+ if (key in criteria) {
194
+ unsupported(`choice question '${name ?? key}' has two options that are both '${key}' as text, which a System One ` +
195
+ 'decision model cannot represent');
196
+ }
197
+ criteria[key] = choice.description ?? null;
198
+ }
199
+ return { type: 'choice', instructions, criteria };
200
+ }
201
+ // System One score criteria are ordered label strings; OpenAI's per-level descriptions have
202
+ // no equivalent field and are dropped.
203
+ return { type: 'score', instructions, criteria: (levels ?? []).map(level => level.label) };
204
+ };
205
+ const openAIRequestToSystemOne = (params) => {
206
+ // `safety_identifier` is dropped: OpenAI is the only dialect that accepts it.
207
+ const { input, questions, safety_identifier: _safetyIdentifier, ...rest } = params;
208
+ const questionList = (Array.isArray(questions) ? questions : []);
209
+ const named = new Set();
210
+ const entries = questionList.map((question, index) => {
211
+ const key = questionKey(question, index);
212
+ // System One keys answers by question name, so two questions sharing one would collide and
213
+ // the caller would silently get back fewer answers than it asked for.
214
+ if (named.has(key)) {
215
+ unsupported(`two questions are both named '${key}', which a System One decision model cannot answer separately`);
216
+ }
217
+ named.add(key);
218
+ return [key, openAIQuestionToSystemOne(question)];
219
+ });
220
+ return {
221
+ ...rest,
222
+ state: openAIInputToState(input),
223
+ questions: Object.fromEntries(entries),
224
+ };
225
+ };
226
+ /* ------------------------------------------------------------------ *
227
+ * Responses
228
+ * ------------------------------------------------------------------ */
229
+ const openAIAnswerToSystemOne = (answer) => {
230
+ const { type, name: _name, ...rest } = answer;
231
+ if (type === 'predicate') {
232
+ const { probability, ...others } = rest;
233
+ return { ...others, type: 'noul', noul: probability };
234
+ }
235
+ if (type === 'choice') {
236
+ const { probabilities, ...others } = rest;
237
+ const entries = (Array.isArray(probabilities) ? probabilities : []);
238
+ return {
239
+ ...others,
240
+ type: 'choice',
241
+ probabilities: Object.fromEntries(entries.map(entry => [String(entry.value), entry.probability])),
242
+ };
243
+ }
244
+ if (type === 'score') {
245
+ const { probabilities, ...others } = rest;
246
+ const entries = (Array.isArray(probabilities) ? probabilities : []);
247
+ return {
248
+ ...others,
249
+ type: 'score',
250
+ legend: Object.fromEntries(entries.map(entry => [String(entry.value), entry.label])),
251
+ probabilities: Object.fromEntries(entries.map(entry => [String(entry.value), entry.probability])),
252
+ };
253
+ }
254
+ // `refusal` has no System One equivalent; pass it through so callers can branch on it.
255
+ return answer;
256
+ };
257
+ const openAIResponseToSystemOne = (body) => {
258
+ const answers = (Array.isArray(body.answers) ? body.answers : []);
259
+ return {
260
+ ...body,
261
+ answers: Object.fromEntries(answers.map((answer, index) => [answer.name ?? `question_${index}`, openAIAnswerToSystemOne(answer)])),
262
+ };
263
+ };
264
+ /** OpenAI echoes only the names it was given, so an unnamed question gets no `name` back. */
265
+ const withName = (name) => (name === undefined ? {} : { name });
266
+ /** System One keys score levels by their index, but fall back to the raw key if it is not one. */
267
+ const scoreLevelValue = (key) => (Number.isNaN(Number(key)) ? key : Number(key));
268
+ /** Look up the caller's original OpenAI choice value; System One only ever returns the string key. */
269
+ const restoreChoiceValue = (key, choices) => {
270
+ const match = choices?.find(choice => String(choice.value) === key);
271
+ return match ? match.value : key;
272
+ };
273
+ const systemOneAnswerToOpenAI = (name, answer, originalQuestion) => {
274
+ const { type, ...rest } = answer;
275
+ if (type === 'noul') {
276
+ const { noul, ...others } = rest;
277
+ return { ...others, type: 'predicate', ...withName(name), probability: noul };
278
+ }
279
+ if (type === 'choice') {
280
+ const { probabilities, choice, ...others } = rest;
281
+ const originalChoices = originalQuestion?.choices;
282
+ const probabilityMap = (probabilities ?? {});
283
+ return {
284
+ ...others,
285
+ type: 'choice',
286
+ ...withName(name),
287
+ ...(choice !== undefined ? { choice: restoreChoiceValue(String(choice), originalChoices) } : {}),
288
+ probabilities: originalChoices?.length
289
+ ? originalChoices.map(option => ({
290
+ value: option.value,
291
+ probability: probabilityMap[String(option.value)] ?? 0,
292
+ }))
293
+ : Object.entries(probabilityMap).map(([value, probability]) => ({ value, probability })),
294
+ };
295
+ }
296
+ if (type === 'score') {
297
+ const { probabilities, legend, ...others } = rest;
298
+ const levels = (legend ?? {});
299
+ const entries = Object.entries((probabilities ?? {}));
300
+ return {
301
+ ...others,
302
+ type: 'score',
303
+ ...withName(name),
304
+ probabilities: entries.map(([value, probability]) => ({
305
+ value: scoreLevelValue(value),
306
+ ...(levels[value] !== undefined ? { label: levels[value] } : {}),
307
+ probability,
308
+ })),
309
+ };
310
+ }
311
+ return { ...answer, ...withName(name) };
312
+ };
313
+ /**
314
+ * System One answers are keyed by question name; OpenAI returns them as an array in the order the
315
+ * caller asked, so the original request supplies both the order and each question's name.
316
+ */
317
+ const systemOneResponseToOpenAI = (body, callerRequest) => {
318
+ const answers = (body.answers ?? {});
319
+ const callerQuestions = (Array.isArray(callerRequest?.questions) ? callerRequest.questions : []);
320
+ // The lookup key is how the question was sent upstream; the echoed name is the one the caller
321
+ // actually supplied, which is absent for a question it left unnamed.
322
+ const lookups = callerQuestions.length
323
+ ? callerQuestions.map((question, index) => ({
324
+ key: questionKey(question, index),
325
+ name: question.name,
326
+ question,
327
+ }))
328
+ : Object.keys(answers).map(key => ({ key, name: key, question: undefined }));
329
+ return {
330
+ ...body,
331
+ answers: lookups
332
+ .filter(({ key }) => answers[key] !== undefined)
333
+ .map(({ key, name, question }) => systemOneAnswerToOpenAI(name, answers[key], question)),
334
+ };
335
+ };
336
+ /* ------------------------------------------------------------------ *
337
+ * Entry points
338
+ * ------------------------------------------------------------------ */
339
+ /** `to` is the serving provider's dialect. */
340
+ export const translateDecisionRequest = (params, to) => to === 'openai' ? systemOneRequestToOpenAI(params) : openAIRequestToSystemOne(params);
341
+ /** `to` is the caller's dialect: responses are translated back to the route that was called. */
342
+ export const translateDecisionResponse = (body, to, callerRequest) => to === 'systemOne' ? openAIResponseToSystemOne(body) : systemOneResponseToOpenAI(body, callerRequest);
343
+ //# sourceMappingURL=decisionDialect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decisionDialect.js","sourceRoot":"","sources":["../../../src/providers/shared/decisionDialect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * ================================
3
+ * TFY Managed File - System One decision wire format
4
+ * ================================
5
+ *
6
+ * System One is `{model, state, questions}` in, `{model, answers, usage}` out, where `questions`
7
+ * is a map keyed by caller-chosen names and `answers` comes back keyed the same way. TypeSafe
8
+ * publishes the format and every non-OpenAI decision provider serves it, so they differ only in
9
+ * URL and auth (see each provider's `api.ts`):
10
+ *
11
+ * TypeSafe POST {base}/v1/systemone
12
+ * OpenRouter POST https://openrouter.ai/api/v1/systemone
13
+ * Perplexity POST https://api.perplexity.ai/v1/decisions
14
+ * Databricks POST {workspace}/serving-endpoints/{endpoint}/invocations
15
+ * Microsoft Foundry POST {resource}/providers/microsoft/v1/systemone
16
+ * vLLM (self-hosted) POST {server}/v1/systemone
17
+ *
18
+ * OpenAI's Decisions API is the other dialect — `input` plus a questions array — and lives in
19
+ * `providers/openai/decisions.ts`. Both arrive as fn `decision`; `shared/decisionDialect.ts`
20
+ * translates when the caller's dialect and the serving provider's differ.
21
+ */
22
+ import { ErrorResponse, ProviderConfig } from '../types.js';
23
+ /**
24
+ * Params this config does not list pass through untouched (`transformUsingProviderConfig`),
25
+ * which is what System One expects: extra fields on a question are the provider's to interpret.
26
+ */
27
+ export declare const SystemOneDecisionConfig: ProviderConfig;
28
+ interface SystemOneUsage {
29
+ input_tokens?: number;
30
+ output_tokens?: number;
31
+ }
32
+ export interface SystemOneDecisionResponse {
33
+ model?: string;
34
+ answers?: Record<string, unknown>;
35
+ usage?: SystemOneUsage;
36
+ }
37
+ /**
38
+ * Failure shapes in use; `message`/`detail` cover servers that skip `error`. Databricks answers a
39
+ * validation failure with HTTP 422 and `detail` as an array of problems, so `detail` is not
40
+ * always a string.
41
+ */
42
+ export interface SystemOneErrorResponse {
43
+ error?: {
44
+ message?: string;
45
+ type?: string;
46
+ code?: string | number | null;
47
+ };
48
+ message?: string;
49
+ detail?: unknown;
50
+ }
51
+ export interface SystemOneDecisionGatewayResponse extends SystemOneDecisionResponse {
52
+ usage?: SystemOneUsage & {
53
+ prompt_tokens?: number;
54
+ completion_tokens?: number;
55
+ total_tokens?: number;
56
+ };
57
+ }
58
+ /**
59
+ * Mirrors the provider's token counts onto the gateway's usage names. `logDecisionResponse` falls
60
+ * back to the provider names, but `resolveCostInUsdFromUsage` reads only `prompt_tokens` /
61
+ * `completion_tokens`, so without this the response carries no `costInUSD`.
62
+ */
63
+ export declare const normalizeSystemOneDecisionUsage: (response: SystemOneDecisionResponse) => SystemOneDecisionGatewayResponse;
64
+ /**
65
+ * Builds the `decision` response transform for a provider that serves System One natively.
66
+ * `fallbackMessage` is used only when the provider reports a failure with no message at all.
67
+ */
68
+ export declare const createSystemOneDecisionResponseTransform: (provider: string, fallbackMessage: string) => (response: SystemOneDecisionResponse | SystemOneErrorResponse, responseStatus: number) => SystemOneDecisionGatewayResponse | ErrorResponse;
69
+ export {};
@@ -0,0 +1,71 @@
1
+ import { generateErrorResponse, generateInvalidProviderResponseError } from '../utils.js';
2
+ /**
3
+ * Params this config does not list pass through untouched (`transformUsingProviderConfig`),
4
+ * which is what System One expects: extra fields on a question are the provider's to interpret.
5
+ */
6
+ export const SystemOneDecisionConfig = {
7
+ model: {
8
+ param: 'model',
9
+ required: true,
10
+ },
11
+ state: {
12
+ param: 'state',
13
+ required: true,
14
+ },
15
+ questions: {
16
+ param: 'questions',
17
+ required: true,
18
+ },
19
+ };
20
+ /**
21
+ * Mirrors the provider's token counts onto the gateway's usage names. `logDecisionResponse` falls
22
+ * back to the provider names, but `resolveCostInUsdFromUsage` reads only `prompt_tokens` /
23
+ * `completion_tokens`, so without this the response carries no `costInUSD`.
24
+ */
25
+ export const normalizeSystemOneDecisionUsage = (response) => {
26
+ const inputTokens = response.usage?.input_tokens ?? 0;
27
+ const outputTokens = response.usage?.output_tokens ?? 0;
28
+ return {
29
+ ...response,
30
+ usage: {
31
+ ...response.usage,
32
+ prompt_tokens: inputTokens,
33
+ completion_tokens: outputTokens,
34
+ total_tokens: inputTokens + outputTokens,
35
+ },
36
+ };
37
+ };
38
+ /** Keeps a 422 `detail` readable whether the server sends a string or a list of problems. */
39
+ const describeDetail = (detail) => {
40
+ if (typeof detail === 'string')
41
+ return detail;
42
+ if (detail == null)
43
+ return undefined;
44
+ return JSON.stringify(detail);
45
+ };
46
+ const systemOneDecisionErrorResponse = (response, responseStatus, provider, fallbackMessage) => {
47
+ const message = response.error?.message ?? response.message ?? describeDetail(response.detail) ?? fallbackMessage;
48
+ const code = response.error?.code;
49
+ return generateErrorResponse({
50
+ message,
51
+ type: response.error?.type ?? null,
52
+ // `code` becomes the HTTP status downstream, so fall back to the upstream status.
53
+ code: code != null ? String(code) : String(responseStatus),
54
+ }, provider);
55
+ };
56
+ /**
57
+ * Builds the `decision` response transform for a provider that serves System One natively.
58
+ * `fallbackMessage` is used only when the provider reports a failure with no message at all.
59
+ */
60
+ export const createSystemOneDecisionResponseTransform = (provider, fallbackMessage) => (response, responseStatus) => {
61
+ if (responseStatus !== 200) {
62
+ return systemOneDecisionErrorResponse(response, responseStatus, provider, fallbackMessage);
63
+ }
64
+ const decisionResponse = response;
65
+ // A 200 with no `answers` is not a decision; surface it rather than billing an empty result.
66
+ if (!decisionResponse.answers) {
67
+ return generateInvalidProviderResponseError(response, provider);
68
+ }
69
+ return normalizeSystemOneDecisionUsage(decisionResponse);
70
+ };
71
+ //# sourceMappingURL=systemOneDecision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"systemOneDecision.js","sourceRoot":"","sources":["../../../src/providers/shared/systemOneDecision.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,qBAAqB,EAAE,oCAAoC,EAAE,MAAM,UAAU,CAAC;AAEvF;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAmB;IACrD,KAAK,EAAE;QACL,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,IAAI;KACf;IACD,KAAK,EAAE;QACL,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,IAAI;KACf;IACD,SAAS,EAAE;QACT,KAAK,EAAE,WAAW;QAClB,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAkCF;;;;GAIG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAC7C,QAAmC,EACD,EAAE;IACpC,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC,CAAC;IAExD,OAAO;QACL,GAAG,QAAQ;QACX,KAAK,EAAE;YACL,GAAG,QAAQ,CAAC,KAAK;YACjB,aAAa,EAAE,WAAW;YAC1B,iBAAiB,EAAE,YAAY;YAC/B,YAAY,EAAE,WAAW,GAAG,YAAY;SACzC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,6FAA6F;AAC7F,MAAM,cAAc,GAAG,CAAC,MAAe,EAAsB,EAAE;IAC7D,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAC9C,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,SAAS,CAAC;IACrC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,8BAA8B,GAAG,CACrC,QAAgC,EAChC,cAAsB,EACtB,QAAgB,EAChB,eAAuB,EACR,EAAE;IACjB,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,QAAQ,CAAC,OAAO,IAAI,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,eAAe,CAAC;IAClH,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IAElC,OAAO,qBAAqB,CAC1B;QACE,OAAO;QACP,IAAI,EAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,IAAI,IAAI;QAClC,kFAAkF;QAClF,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC;KAC3D,EACD,QAAQ,CACT,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,wCAAwC,GACnD,CAAC,QAAgB,EAAE,eAAuB,EAAE,EAAE,CAC9C,CACE,QAA4D,EAC5D,cAAsB,EAC4B,EAAE;IACpD,IAAI,cAAc,KAAK,GAAG,EAAE,CAAC;QAC3B,OAAO,8BAA8B,CACnC,QAAkC,EAClC,cAAc,EACd,QAAQ,EACR,eAAe,CAChB,CAAC;IACJ,CAAC;IAED,MAAM,gBAAgB,GAAG,QAAqC,CAAC;IAC/D,6FAA6F;IAC7F,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAC9B,OAAO,oCAAoC,CAAC,QAAmC,EAAE,QAAQ,CAAC,CAAC;IAC7F,CAAC;IAED,OAAO,+BAA+B,CAAC,gBAAgB,CAAC,CAAC;AAC3D,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { ProviderAPIConfig } from '../types.js';
2
+ declare const TrueFoundryManagedAPIConfig: ProviderAPIConfig;
3
+ export default TrueFoundryManagedAPIConfig;
@@ -1,5 +1,5 @@
1
1
  const TRAILING_SLASHES_REGEX = /\/+$/;
2
- const TrueFoundryModelsAPIConfig = {
2
+ const TrueFoundryManagedAPIConfig = {
3
3
  getBaseURL: ({ providerOptions }) => {
4
4
  const manifest = providerOptions.providerAccount.manifest;
5
5
  return (manifest.base_url ?? '').replace(TRAILING_SLASHES_REGEX, '');
@@ -25,5 +25,5 @@ const TrueFoundryModelsAPIConfig = {
25
25
  }
26
26
  },
27
27
  };
28
- export default TrueFoundryModelsAPIConfig;
28
+ export default TrueFoundryManagedAPIConfig;
29
29
  //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/providers/truefoundry-managed/api.ts"],"names":[],"mappings":"AAUA,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAEtC,MAAM,2BAA2B,GAAsB;IACrD,UAAU,EAAE,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE;QAClC,MAAM,QAAQ,GAAG,eAAe,CAAC,eAAe,CAAC,QAA6C,CAAC;QAC/F,OAAO,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,sBAAsB,EAAE,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,EAAE,CAAC,EAAE,eAAe,EAAE,EAAE,EAAE;QAC/B,MAAM,QAAQ,GAAG,eAAe,CAAC,eAAe,CAAC,QAA6C,CAAC;QAC/F,OAAO;YACL,aAAa,EAAE,UAAU,QAAQ,CAAC,SAAS,EAAE,OAAO,EAAE;SACvD,CAAC;IACJ,CAAC;IACD,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE;QAC5B,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,cAAc;gBACjB,OAAO,mBAAmB,CAAC;YAC7B,KAAK,UAAU;gBACb,OAAO,cAAc,CAAC;YACxB,KAAK,OAAO;gBACV,OAAO,aAAa,CAAC;YACvB,KAAK,qBAAqB;gBACxB,OAAO,YAAY,CAAC;YACtB;gBACE,OAAO,EAAE,CAAC;QACd,CAAC;IACH,CAAC;CACF,CAAC;AAEF,eAAe,2BAA2B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { ProviderConfigs } from '../types.js';
2
+ declare const TrueFoundryManagedConfig: ProviderConfigs;
3
+ export default TrueFoundryManagedConfig;
@@ -1,27 +1,27 @@
1
1
  /**
2
2
  * ================================
3
3
  * TFY Managed File
4
- * TrueFoundry Models provider config
4
+ * TrueFoundry Managed provider config
5
5
  * ================================
6
6
  */
7
- import { TRUEFOUNDRY_MODELS } from '../../globals.js';
7
+ import { TRUEFOUNDRY_MANAGED } from '../../globals.js';
8
8
  import { chatCompleteParams, completeParams, createModelResponseParams, embedParams, OpenAICreateModelResponseTransformer, responseTransformers, } from '../open-ai-base/index.js';
9
9
  import { OpenAILikeChatCompleteResponseTransform, OpenAILikeChatCompleteStreamChunkTransform, } from '../openai-like/chatComplete.js';
10
10
  import { OpenAILikeEmbedResponseTransform } from '../openai-like/embed.js';
11
- import TrueFoundryModelsAPIConfig from './api.js';
12
- const TrueFoundryModelsConfig = {
11
+ import TrueFoundryManagedAPIConfig from './api.js';
12
+ const TrueFoundryManagedConfig = {
13
13
  chatComplete: chatCompleteParams([]),
14
14
  complete: completeParams([]),
15
15
  createModelResponse: createModelResponseParams([]),
16
16
  embed: embedParams([]),
17
- api: TrueFoundryModelsAPIConfig,
17
+ api: TrueFoundryManagedAPIConfig,
18
18
  responseTransforms: {
19
- ...responseTransformers(TRUEFOUNDRY_MODELS, { complete: true }),
20
- chatComplete: OpenAILikeChatCompleteResponseTransform(TRUEFOUNDRY_MODELS),
21
- embed: OpenAILikeEmbedResponseTransform(TRUEFOUNDRY_MODELS),
22
- createModelResponse: OpenAICreateModelResponseTransformer(TRUEFOUNDRY_MODELS),
23
- 'stream-chatComplete': OpenAILikeChatCompleteStreamChunkTransform(TRUEFOUNDRY_MODELS),
19
+ ...responseTransformers(TRUEFOUNDRY_MANAGED, { complete: true }),
20
+ chatComplete: OpenAILikeChatCompleteResponseTransform(TRUEFOUNDRY_MANAGED),
21
+ embed: OpenAILikeEmbedResponseTransform(TRUEFOUNDRY_MANAGED),
22
+ createModelResponse: OpenAICreateModelResponseTransformer(TRUEFOUNDRY_MANAGED),
23
+ 'stream-chatComplete': OpenAILikeChatCompleteStreamChunkTransform(TRUEFOUNDRY_MANAGED),
24
24
  },
25
25
  };
26
- export default TrueFoundryModelsConfig;
26
+ export default TrueFoundryManagedConfig;
27
27
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/truefoundry-managed/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,yBAAyB,EACzB,WAAW,EACX,oCAAoC,EACpC,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,uCAAuC,EACvC,0CAA0C,GAC3C,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,2BAA2B,MAAM,OAAO,CAAC;AAEhD,MAAM,wBAAwB,GAAoB;IAChD,YAAY,EAAE,kBAAkB,CAAC,EAAE,CAAC;IACpC,QAAQ,EAAE,cAAc,CAAC,EAAE,CAAC;IAC5B,mBAAmB,EAAE,yBAAyB,CAAC,EAAE,CAAC;IAClD,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;IACtB,GAAG,EAAE,2BAA2B;IAChC,kBAAkB,EAAE;QAClB,GAAG,oBAAoB,CAAC,mBAAmB,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAChE,YAAY,EAAE,uCAAuC,CAAC,mBAAmB,CAAC;QAC1E,KAAK,EAAE,gCAAgC,CAAC,mBAAmB,CAAC;QAC5D,mBAAmB,EAAE,oCAAoC,CAAC,mBAAmB,CAAC;QAC9E,qBAAqB,EAAE,0CAA0C,CAAC,mBAAmB,CAAC;KACvF;CACF,CAAC;AAEF,eAAe,wBAAwB,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { SystemOneDecisionGatewayResponse, SystemOneDecisionResponse, SystemOneErrorResponse } from '../shared/systemOneDecision.js';
1
2
  import { ErrorResponse, ProviderConfig } from '../types.js';
2
3
  export declare const TypeSafeDecisionConfig: ProviderConfig;
3
4
  /**
@@ -5,31 +6,8 @@ export declare const TypeSafeDecisionConfig: ProviderConfig;
5
6
  * System One body under `input`. `images` is Clef's extension to System One.
6
7
  */
7
8
  export declare const TypeSafeCloudflareDecisionConfig: ProviderConfig;
8
- interface TypeSafeUsage {
9
- input_tokens?: number;
10
- output_tokens?: number;
11
- }
12
- export interface TypeSafeDecisionResponse {
13
- model?: string;
14
- answers?: Record<string, unknown>;
15
- usage?: TypeSafeUsage;
16
- }
17
- interface TypeSafeErrorResponse {
18
- error?: {
19
- message?: string;
20
- type?: string;
21
- code?: string;
22
- };
23
- message?: string;
24
- detail?: unknown;
25
- }
26
- export interface DecisionResponse extends TypeSafeDecisionResponse {
27
- usage?: TypeSafeUsage & {
28
- prompt_tokens?: number;
29
- completion_tokens?: number;
30
- total_tokens?: number;
31
- };
32
- }
9
+ export type TypeSafeDecisionResponse = SystemOneDecisionResponse;
10
+ export type DecisionResponse = SystemOneDecisionGatewayResponse;
33
11
  /** Cloudflare Workers AI response envelope. */
34
12
  interface CloudflareEnvelope {
35
13
  success: boolean;
@@ -40,5 +18,5 @@ interface CloudflareEnvelope {
40
18
  }[];
41
19
  messages?: unknown[];
42
20
  }
43
- export declare const TypeSafeDecisionResponseTransform: (response: TypeSafeDecisionResponse | TypeSafeErrorResponse | CloudflareEnvelope, responseStatus: number) => DecisionResponse | ErrorResponse;
21
+ export declare const TypeSafeDecisionResponseTransform: (response: TypeSafeDecisionResponse | SystemOneErrorResponse | CloudflareEnvelope, responseStatus: number) => DecisionResponse | ErrorResponse;
44
22
  export {};