@tanstack/ai-muse 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +79 -2
- package/dist/esm/adapters/text.d.ts +51 -0
- package/dist/esm/adapters/text.js +53 -0
- package/dist/esm/adapters/text.js.map +1 -0
- package/dist/esm/byok.d.ts +1 -0
- package/dist/esm/byok.js +11 -0
- package/dist/esm/byok.js.map +1 -0
- package/dist/esm/index.d.ts +11 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/message-types.d.ts +43 -0
- package/dist/esm/model-meta.d.ts +369 -0
- package/dist/esm/model-meta.js +214 -0
- package/dist/esm/model-meta.js.map +1 -0
- package/dist/esm/text/text-provider-options.d.ts +57 -0
- package/dist/esm/utils/client.d.ts +28 -0
- package/dist/esm/utils/client.js +38 -0
- package/dist/esm/utils/client.js.map +1 -0
- package/package.json +69 -3
- package/src/adapters/text.ts +113 -0
- package/src/byok.ts +7 -0
- package/src/index.ts +36 -0
- package/src/message-types.ts +45 -0
- package/src/model-meta.ts +329 -0
- package/src/text/text-provider-options.ts +66 -0
- package/src/utils/client.ts +49 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import type { Modality, ModelReasoning } from '@tanstack/ai'
|
|
2
|
+
import type { ModelReasoningCapability } from '@tanstack/ai/adapter-internals'
|
|
3
|
+
import type { MuseTextProviderOptions } from './text/text-provider-options'
|
|
4
|
+
|
|
5
|
+
// Model data below is from Meta's official Model API docs (dev.meta.ai):
|
|
6
|
+
// "Pricing and rate limits", "Choose a model", and the per-model pages,
|
|
7
|
+
// checked 2026-11-11. Prices are USD per 1M tokens, Standard mode unless the
|
|
8
|
+
// model id says `-contributor`. Every reasoning model on the API has a
|
|
9
|
+
// 1,048,576-token context window. Muse Glimmer is an open-weight,
|
|
10
|
+
// self-hosted model — it is NOT served by the Model API and is deliberately
|
|
11
|
+
// absent here.
|
|
12
|
+
|
|
13
|
+
// Reasoning shapes: the levels a model has for `chat({ reasoning })`, and the
|
|
14
|
+
// provider value to send for each. Each model points at one of them.
|
|
15
|
+
const EFFORT_MINIMAL_TO_MAX = {
|
|
16
|
+
levels: {
|
|
17
|
+
minimal: 'minimal',
|
|
18
|
+
low: 'low',
|
|
19
|
+
medium: 'medium',
|
|
20
|
+
high: 'high',
|
|
21
|
+
xhigh: 'xhigh',
|
|
22
|
+
max: 'max',
|
|
23
|
+
},
|
|
24
|
+
budget: false,
|
|
25
|
+
} as const
|
|
26
|
+
const EFFORT_MINIMAL_TO_XHIGH = {
|
|
27
|
+
levels: {
|
|
28
|
+
minimal: 'minimal',
|
|
29
|
+
low: 'low',
|
|
30
|
+
medium: 'medium',
|
|
31
|
+
high: 'high',
|
|
32
|
+
xhigh: 'xhigh',
|
|
33
|
+
},
|
|
34
|
+
budget: false,
|
|
35
|
+
} as const
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Internal metadata structure describing a Muse model's capabilities and
|
|
39
|
+
* pricing.
|
|
40
|
+
*/
|
|
41
|
+
interface ModelMeta<TProviderOptions = unknown> {
|
|
42
|
+
name: string
|
|
43
|
+
context_window?: number
|
|
44
|
+
max_completion_tokens?: number
|
|
45
|
+
pricing: {
|
|
46
|
+
input?: { normal: number; cached?: number }
|
|
47
|
+
output?: { normal: number }
|
|
48
|
+
}
|
|
49
|
+
supports: {
|
|
50
|
+
input: Array<'text' | 'image'>
|
|
51
|
+
output: Array<'text'>
|
|
52
|
+
endpoints: Array<'chat'>
|
|
53
|
+
features: Array<
|
|
54
|
+
| 'streaming'
|
|
55
|
+
| 'tools'
|
|
56
|
+
| 'json_object'
|
|
57
|
+
| 'json_schema'
|
|
58
|
+
| 'reasoning'
|
|
59
|
+
| 'vision'
|
|
60
|
+
>
|
|
61
|
+
tools?: ReadonlyArray<never>
|
|
62
|
+
}
|
|
63
|
+
/** Type-level description of which provider options this model supports. */
|
|
64
|
+
providerOptions?: TProviderOptions
|
|
65
|
+
/** The model's data for `chat({ reasoning })`. None: it does not reason. */
|
|
66
|
+
reasoning?: ModelReasoning
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const FEATURES = [
|
|
70
|
+
'streaming',
|
|
71
|
+
'tools',
|
|
72
|
+
'json_object',
|
|
73
|
+
'json_schema',
|
|
74
|
+
'reasoning',
|
|
75
|
+
'vision',
|
|
76
|
+
] as const
|
|
77
|
+
|
|
78
|
+
// Ember pricing is the ≤200K-input-token tier; requests over 200K input
|
|
79
|
+
// tokens bill at 3x ($0.30 / $0.012 cached / $1.50) for the whole request.
|
|
80
|
+
const EMBER_1_0 = {
|
|
81
|
+
name: 'muse-ember-1.0',
|
|
82
|
+
context_window: 1_048_576,
|
|
83
|
+
max_completion_tokens: 524_288,
|
|
84
|
+
pricing: {
|
|
85
|
+
input: { normal: 0.1, cached: 0.004 },
|
|
86
|
+
output: { normal: 0.5 },
|
|
87
|
+
},
|
|
88
|
+
supports: {
|
|
89
|
+
input: ['text', 'image'],
|
|
90
|
+
output: ['text'],
|
|
91
|
+
endpoints: ['chat'],
|
|
92
|
+
features: [...FEATURES],
|
|
93
|
+
tools: [] as const,
|
|
94
|
+
},
|
|
95
|
+
reasoning: EFFORT_MINIMAL_TO_MAX,
|
|
96
|
+
} as const satisfies ModelMeta<MuseTextProviderOptions>
|
|
97
|
+
|
|
98
|
+
const WONDER_1_0 = {
|
|
99
|
+
name: 'muse-wonder-1.0',
|
|
100
|
+
context_window: 1_048_576,
|
|
101
|
+
max_completion_tokens: 131_072,
|
|
102
|
+
pricing: {
|
|
103
|
+
input: { normal: 4, cached: 0.2 },
|
|
104
|
+
output: { normal: 20 },
|
|
105
|
+
},
|
|
106
|
+
supports: {
|
|
107
|
+
input: ['text', 'image'],
|
|
108
|
+
output: ['text'],
|
|
109
|
+
endpoints: ['chat'],
|
|
110
|
+
features: [...FEATURES],
|
|
111
|
+
tools: [] as const,
|
|
112
|
+
},
|
|
113
|
+
reasoning: EFFORT_MINIMAL_TO_MAX,
|
|
114
|
+
} as const satisfies ModelMeta<MuseTextProviderOptions>
|
|
115
|
+
|
|
116
|
+
const SPARK_1_3 = {
|
|
117
|
+
name: 'muse-spark-1.3',
|
|
118
|
+
context_window: 1_048_576,
|
|
119
|
+
max_completion_tokens: 131_072,
|
|
120
|
+
pricing: {
|
|
121
|
+
input: { normal: 1.25, cached: 0.15 },
|
|
122
|
+
output: { normal: 4.25 },
|
|
123
|
+
},
|
|
124
|
+
supports: {
|
|
125
|
+
input: ['text', 'image'],
|
|
126
|
+
output: ['text'],
|
|
127
|
+
endpoints: ['chat'],
|
|
128
|
+
features: [...FEATURES],
|
|
129
|
+
tools: [] as const,
|
|
130
|
+
},
|
|
131
|
+
// Spark 1.3 is the only Spark that accepts `max` effort.
|
|
132
|
+
reasoning: EFFORT_MINIMAL_TO_MAX,
|
|
133
|
+
} as const satisfies ModelMeta<MuseTextProviderOptions>
|
|
134
|
+
|
|
135
|
+
const SPARK_1_3_CONTRIBUTOR = {
|
|
136
|
+
name: 'muse-spark-1.3-contributor',
|
|
137
|
+
context_window: 1_048_576,
|
|
138
|
+
max_completion_tokens: 131_072,
|
|
139
|
+
pricing: {
|
|
140
|
+
input: { normal: 0.1, cached: 0.002 },
|
|
141
|
+
output: { normal: 0.2 },
|
|
142
|
+
},
|
|
143
|
+
supports: {
|
|
144
|
+
input: ['text', 'image'],
|
|
145
|
+
output: ['text'],
|
|
146
|
+
endpoints: ['chat'],
|
|
147
|
+
features: [...FEATURES],
|
|
148
|
+
tools: [] as const,
|
|
149
|
+
},
|
|
150
|
+
// `max` is not available on the Contributor variant.
|
|
151
|
+
reasoning: EFFORT_MINIMAL_TO_XHIGH,
|
|
152
|
+
} as const satisfies ModelMeta<MuseTextProviderOptions>
|
|
153
|
+
|
|
154
|
+
const SPARK_1_2 = {
|
|
155
|
+
name: 'muse-spark-1.2',
|
|
156
|
+
context_window: 1_048_576,
|
|
157
|
+
max_completion_tokens: 131_072,
|
|
158
|
+
pricing: {
|
|
159
|
+
input: { normal: 1.25, cached: 0.15 },
|
|
160
|
+
output: { normal: 4.25 },
|
|
161
|
+
},
|
|
162
|
+
supports: {
|
|
163
|
+
input: ['text', 'image'],
|
|
164
|
+
output: ['text'],
|
|
165
|
+
endpoints: ['chat'],
|
|
166
|
+
features: [...FEATURES],
|
|
167
|
+
tools: [] as const,
|
|
168
|
+
},
|
|
169
|
+
reasoning: EFFORT_MINIMAL_TO_XHIGH,
|
|
170
|
+
} as const satisfies ModelMeta<MuseTextProviderOptions>
|
|
171
|
+
|
|
172
|
+
const SPARK_1_2_CONTRIBUTOR = {
|
|
173
|
+
name: 'muse-spark-1.2-contributor',
|
|
174
|
+
context_window: 1_048_576,
|
|
175
|
+
max_completion_tokens: 131_072,
|
|
176
|
+
pricing: {
|
|
177
|
+
input: { normal: 0.1, cached: 0.002 },
|
|
178
|
+
output: { normal: 0.2 },
|
|
179
|
+
},
|
|
180
|
+
supports: {
|
|
181
|
+
input: ['text', 'image'],
|
|
182
|
+
output: ['text'],
|
|
183
|
+
endpoints: ['chat'],
|
|
184
|
+
features: [...FEATURES],
|
|
185
|
+
tools: [] as const,
|
|
186
|
+
},
|
|
187
|
+
reasoning: EFFORT_MINIMAL_TO_XHIGH,
|
|
188
|
+
} as const satisfies ModelMeta<MuseTextProviderOptions>
|
|
189
|
+
|
|
190
|
+
const SPARK_1_1 = {
|
|
191
|
+
name: 'muse-spark-1.1',
|
|
192
|
+
context_window: 1_048_576,
|
|
193
|
+
max_completion_tokens: 32_768,
|
|
194
|
+
pricing: {
|
|
195
|
+
input: { normal: 1.25, cached: 0.15 },
|
|
196
|
+
output: { normal: 4.25 },
|
|
197
|
+
},
|
|
198
|
+
supports: {
|
|
199
|
+
input: ['text', 'image'],
|
|
200
|
+
output: ['text'],
|
|
201
|
+
endpoints: ['chat'],
|
|
202
|
+
features: [...FEATURES],
|
|
203
|
+
tools: [] as const,
|
|
204
|
+
},
|
|
205
|
+
reasoning: EFFORT_MINIMAL_TO_XHIGH,
|
|
206
|
+
} as const satisfies ModelMeta<MuseTextProviderOptions>
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* All supported Muse chat model identifiers.
|
|
210
|
+
*/
|
|
211
|
+
export const MUSE_CHAT_MODELS = [
|
|
212
|
+
EMBER_1_0.name,
|
|
213
|
+
WONDER_1_0.name,
|
|
214
|
+
SPARK_1_3.name,
|
|
215
|
+
SPARK_1_3_CONTRIBUTOR.name,
|
|
216
|
+
SPARK_1_2.name,
|
|
217
|
+
SPARK_1_2_CONTRIBUTOR.name,
|
|
218
|
+
SPARK_1_1.name,
|
|
219
|
+
] as const
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Union type of all supported Muse chat model names.
|
|
223
|
+
*/
|
|
224
|
+
export type MuseChatModels = (typeof MUSE_CHAT_MODELS)[number]
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Type-only map from Muse chat model name to its supported input modalities.
|
|
228
|
+
*/
|
|
229
|
+
export type MuseModelInputModalitiesByName = {
|
|
230
|
+
[EMBER_1_0.name]: typeof EMBER_1_0.supports.input
|
|
231
|
+
[WONDER_1_0.name]: typeof WONDER_1_0.supports.input
|
|
232
|
+
[SPARK_1_3.name]: typeof SPARK_1_3.supports.input
|
|
233
|
+
[SPARK_1_3_CONTRIBUTOR.name]: typeof SPARK_1_3_CONTRIBUTOR.supports.input
|
|
234
|
+
[SPARK_1_2.name]: typeof SPARK_1_2.supports.input
|
|
235
|
+
[SPARK_1_2_CONTRIBUTOR.name]: typeof SPARK_1_2_CONTRIBUTOR.supports.input
|
|
236
|
+
[SPARK_1_1.name]: typeof SPARK_1_1.supports.input
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Runtime map from chat model name to its supported input modalities, for the
|
|
241
|
+
* text adapter's `inputModalities`. `satisfies` keeps it equal to
|
|
242
|
+
* {@link MuseModelInputModalitiesByName}. An unknown name gives `undefined`.
|
|
243
|
+
*/
|
|
244
|
+
export const MUSE_MODEL_INPUT_MODALITIES: Readonly<
|
|
245
|
+
Record<string, ReadonlyArray<Modality>>
|
|
246
|
+
> = {
|
|
247
|
+
[EMBER_1_0.name]: EMBER_1_0.supports.input,
|
|
248
|
+
[WONDER_1_0.name]: WONDER_1_0.supports.input,
|
|
249
|
+
[SPARK_1_3.name]: SPARK_1_3.supports.input,
|
|
250
|
+
[SPARK_1_3_CONTRIBUTOR.name]: SPARK_1_3_CONTRIBUTOR.supports.input,
|
|
251
|
+
[SPARK_1_2.name]: SPARK_1_2.supports.input,
|
|
252
|
+
[SPARK_1_2_CONTRIBUTOR.name]: SPARK_1_2_CONTRIBUTOR.supports.input,
|
|
253
|
+
[SPARK_1_1.name]: SPARK_1_1.supports.input,
|
|
254
|
+
} satisfies MuseModelInputModalitiesByName
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Type-only map from Muse chat model name to its provider options type.
|
|
258
|
+
*/
|
|
259
|
+
export type MuseChatModelProviderOptionsByName = {
|
|
260
|
+
[K in (typeof MUSE_CHAT_MODELS)[number]]: MuseTextProviderOptions
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Type-only map from Muse chat model name to its supported provider tools.
|
|
265
|
+
* Muse exposes no provider-specific tool factories, so every model gets an
|
|
266
|
+
* empty tuple. This makes passing another provider's ProviderTool to a Muse
|
|
267
|
+
* adapter a compile-time type error.
|
|
268
|
+
*/
|
|
269
|
+
export type MuseChatModelToolCapabilitiesByName = {
|
|
270
|
+
[EMBER_1_0.name]: typeof EMBER_1_0.supports.tools
|
|
271
|
+
[WONDER_1_0.name]: typeof WONDER_1_0.supports.tools
|
|
272
|
+
[SPARK_1_3.name]: typeof SPARK_1_3.supports.tools
|
|
273
|
+
[SPARK_1_3_CONTRIBUTOR.name]: typeof SPARK_1_3_CONTRIBUTOR.supports.tools
|
|
274
|
+
[SPARK_1_2.name]: typeof SPARK_1_2.supports.tools
|
|
275
|
+
[SPARK_1_2_CONTRIBUTOR.name]: typeof SPARK_1_2_CONTRIBUTOR.supports.tools
|
|
276
|
+
[SPARK_1_1.name]: typeof SPARK_1_1.supports.tools
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Resolves the provider options type for a specific Muse model.
|
|
281
|
+
*/
|
|
282
|
+
export type ResolveProviderOptions<TModel extends string> =
|
|
283
|
+
TModel extends keyof MuseChatModelProviderOptionsByName
|
|
284
|
+
? MuseChatModelProviderOptionsByName[TModel]
|
|
285
|
+
: MuseTextProviderOptions
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Resolve input modalities for a specific model. If the model has explicit
|
|
289
|
+
* modalities in the map, use those; otherwise use text only.
|
|
290
|
+
*/
|
|
291
|
+
export type ResolveInputModalities<TModel extends string> =
|
|
292
|
+
TModel extends keyof MuseModelInputModalitiesByName
|
|
293
|
+
? MuseModelInputModalitiesByName[TModel]
|
|
294
|
+
: readonly ['text']
|
|
295
|
+
|
|
296
|
+
// Reasoning
|
|
297
|
+
//
|
|
298
|
+
// Each model's `reasoning` field holds its data for `chat({ reasoning })`: the
|
|
299
|
+
// levels it has, with the provider value for each, and whether it takes a
|
|
300
|
+
// thinking token budget.
|
|
301
|
+
|
|
302
|
+
const MUSE_REASONING = {
|
|
303
|
+
[EMBER_1_0.name]: EMBER_1_0.reasoning,
|
|
304
|
+
[WONDER_1_0.name]: WONDER_1_0.reasoning,
|
|
305
|
+
[SPARK_1_3.name]: SPARK_1_3.reasoning,
|
|
306
|
+
[SPARK_1_3_CONTRIBUTOR.name]: SPARK_1_3_CONTRIBUTOR.reasoning,
|
|
307
|
+
[SPARK_1_2.name]: SPARK_1_2.reasoning,
|
|
308
|
+
[SPARK_1_2_CONTRIBUTOR.name]: SPARK_1_2_CONTRIBUTOR.reasoning,
|
|
309
|
+
[SPARK_1_1.name]: SPARK_1_1.reasoning,
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Each chat model's reasoning levels, and whether it takes a token budget, for
|
|
314
|
+
* `chat({ reasoning })`. Derived from the `reasoning` field. A model that is
|
|
315
|
+
* not here does not reason.
|
|
316
|
+
*/
|
|
317
|
+
export type MuseModelReasoningByName = {
|
|
318
|
+
[K in keyof typeof MUSE_REASONING]: ModelReasoningCapability<
|
|
319
|
+
(typeof MUSE_REASONING)[K]
|
|
320
|
+
>
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Runtime map from chat model name to its reasoning data, for the text
|
|
325
|
+
* adapter. An unknown name gives `undefined`: the adapter sends no reasoning
|
|
326
|
+
* field.
|
|
327
|
+
*/
|
|
328
|
+
export const MUSE_MODEL_REASONING: Readonly<Record<string, ModelReasoning>> =
|
|
329
|
+
MUSE_REASONING
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Muse-specific provider options for text/chat models.
|
|
3
|
+
*
|
|
4
|
+
* Muse exposes an OpenAI-compatible Chat Completions endpoint, so these are
|
|
5
|
+
* the standard Chat Completions parameters. They are the values a caller can
|
|
6
|
+
* pass through `chat({ modelOptions })`.
|
|
7
|
+
*/
|
|
8
|
+
export interface MuseTextProviderOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Sampling temperature between 0 and 2. Higher values make the output more
|
|
11
|
+
* random; lower values make it more focused and deterministic.
|
|
12
|
+
*/
|
|
13
|
+
temperature?: number | null
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Nucleus sampling. The model considers the tokens with `top_p` probability
|
|
17
|
+
* mass. 0.1 means only the tokens in the top 10% are considered.
|
|
18
|
+
*/
|
|
19
|
+
top_p?: number | null
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The maximum number of tokens to generate in the chat completion. The total
|
|
23
|
+
* of input tokens and generated tokens is limited by the model's context
|
|
24
|
+
* window.
|
|
25
|
+
*/
|
|
26
|
+
max_completion_tokens?: number | null
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Number between -2.0 and 2.0. Positive values penalize new tokens by their
|
|
30
|
+
* frequency so far, so the model is less likely to repeat the same line.
|
|
31
|
+
*/
|
|
32
|
+
frequency_penalty?: number | null
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Number between -2.0 and 2.0. Positive values penalize new tokens that have
|
|
36
|
+
* already appeared, so the model is more likely to talk about new topics.
|
|
37
|
+
*/
|
|
38
|
+
presence_penalty?: number | null
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* If set, the system makes a best effort to sample deterministically, so
|
|
42
|
+
* repeated requests with the same `seed` and parameters return the same
|
|
43
|
+
* result.
|
|
44
|
+
*/
|
|
45
|
+
seed?: number | null
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Up to 4 sequences where the API stops generating further tokens. The
|
|
49
|
+
* returned text does not contain the stop sequence.
|
|
50
|
+
*/
|
|
51
|
+
stop?: string | null | Array<string>
|
|
52
|
+
|
|
53
|
+
/** Whether to enable parallel function calling during tool use. */
|
|
54
|
+
parallel_tool_calls?: boolean | null
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A unique identifier for your end-user, which can help monitor and detect
|
|
58
|
+
* abuse.
|
|
59
|
+
*/
|
|
60
|
+
user?: string | null
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* External provider options (what users pass in).
|
|
65
|
+
*/
|
|
66
|
+
export type ExternalTextProviderOptions = MuseTextProviderOptions
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { getApiKeyFromEnv } from '@tanstack/ai-utils'
|
|
2
|
+
import type { createOpenAIClient } from '@tanstack/openai-base'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The options `createOpenAIClient` accepts. Derived from the base factory so
|
|
6
|
+
* the config type matches the exact `openai` copy the base resolves, rather
|
|
7
|
+
* than a second copy pulled in by a direct `openai` dependency.
|
|
8
|
+
*/
|
|
9
|
+
type OpenAIClientOptions = Parameters<typeof createOpenAIClient>[0]
|
|
10
|
+
|
|
11
|
+
export interface MuseClientConfig extends Omit<OpenAIClientOptions, 'apiKey'> {
|
|
12
|
+
apiKey: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Gets the Muse API key from environment variables.
|
|
17
|
+
*
|
|
18
|
+
* `MUSE_API_KEY` is the provider-scoped name, matching the repo's other
|
|
19
|
+
* adapters (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, …). Meta's own docs call
|
|
20
|
+
* the same key `MODEL_API_KEY`, so that name is accepted as a fallback.
|
|
21
|
+
*
|
|
22
|
+
* @throws Error if neither variable is found
|
|
23
|
+
*/
|
|
24
|
+
export function getMuseApiKeyFromEnv(): string {
|
|
25
|
+
try {
|
|
26
|
+
return getApiKeyFromEnv('MUSE_API_KEY')
|
|
27
|
+
} catch {
|
|
28
|
+
try {
|
|
29
|
+
return getApiKeyFromEnv('MODEL_API_KEY')
|
|
30
|
+
} catch {
|
|
31
|
+
throw new Error(
|
|
32
|
+
'MUSE_API_KEY is required. Please set it in your environment variables or use the factory function with an explicit API key.',
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Returns a Muse client config with the Meta Model API base URL applied
|
|
40
|
+
* when not already set. Meta serves Muse through an OpenAI-compatible
|
|
41
|
+
* endpoint at api.meta.ai, so the adapter drives it with the OpenAI SDK
|
|
42
|
+
* pointed at this base URL.
|
|
43
|
+
*/
|
|
44
|
+
export function withMuseDefaults(config: MuseClientConfig): MuseClientConfig {
|
|
45
|
+
return {
|
|
46
|
+
...config,
|
|
47
|
+
baseURL: config.baseURL || 'https://api.meta.ai/v1',
|
|
48
|
+
}
|
|
49
|
+
}
|