mohdel 0.90.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 +377 -0
- package/config/benchmarks.json +39 -0
- package/js/client/call.js +75 -0
- package/js/client/call_image.js +82 -0
- package/js/client/gate-binary.js +72 -0
- package/js/client/index.js +16 -0
- package/js/client/ndjson.js +29 -0
- package/js/client/transport.js +48 -0
- package/js/core/envelope.js +141 -0
- package/js/core/errors.js +75 -0
- package/js/core/events.js +96 -0
- package/js/core/image.js +58 -0
- package/js/core/index.js +10 -0
- package/js/core/status.js +48 -0
- package/js/factory/bridge.js +372 -0
- package/js/session/_cooldown.js +114 -0
- package/js/session/_logger.js +138 -0
- package/js/session/_rate_limiter.js +77 -0
- package/js/session/_tracing.js +58 -0
- package/js/session/adapters/_cancelled.js +44 -0
- package/js/session/adapters/_catalog.js +58 -0
- package/js/session/adapters/_chat_completions.js +439 -0
- package/js/session/adapters/_errors.js +85 -0
- package/js/session/adapters/_images.js +60 -0
- package/js/session/adapters/_lazy_json_cache.js +76 -0
- package/js/session/adapters/_pricing.js +67 -0
- package/js/session/adapters/_providers.js +60 -0
- package/js/session/adapters/_tools.js +185 -0
- package/js/session/adapters/_videos.js +283 -0
- package/js/session/adapters/anthropic.js +397 -0
- package/js/session/adapters/cerebras.js +28 -0
- package/js/session/adapters/deepseek.js +32 -0
- package/js/session/adapters/echo.js +51 -0
- package/js/session/adapters/fake.js +262 -0
- package/js/session/adapters/fireworks.js +46 -0
- package/js/session/adapters/gemini.js +381 -0
- package/js/session/adapters/groq.js +23 -0
- package/js/session/adapters/image/fake.js +55 -0
- package/js/session/adapters/image/index.js +40 -0
- package/js/session/adapters/image/novita.js +135 -0
- package/js/session/adapters/image/openai.js +50 -0
- package/js/session/adapters/index.js +53 -0
- package/js/session/adapters/mistral.js +31 -0
- package/js/session/adapters/novita.js +29 -0
- package/js/session/adapters/openai.js +381 -0
- package/js/session/adapters/openrouter.js +66 -0
- package/js/session/adapters/xai.js +27 -0
- package/js/session/bin.js +54 -0
- package/js/session/driver.js +160 -0
- package/js/session/index.js +18 -0
- package/js/session/run.js +393 -0
- package/js/session/run_image.js +61 -0
- package/package.json +107 -0
- package/src/cli/ask.js +160 -0
- package/src/cli/backup.js +107 -0
- package/src/cli/bench.js +262 -0
- package/src/cli/check.js +123 -0
- package/src/cli/colored-logger.js +67 -0
- package/src/cli/colors.js +13 -0
- package/src/cli/default.js +39 -0
- package/src/cli/index.js +150 -0
- package/src/cli/json-output.js +60 -0
- package/src/cli/model.js +571 -0
- package/src/cli/onboard.js +232 -0
- package/src/cli/rank.js +176 -0
- package/src/cli/ratelimit.js +160 -0
- package/src/cli/tag.js +105 -0
- package/src/lib/assets/alibaba.svg +1 -0
- package/src/lib/assets/anthropic.svg +5 -0
- package/src/lib/assets/deepseek.svg +1 -0
- package/src/lib/assets/gemini.svg +1 -0
- package/src/lib/assets/google.svg +2 -0
- package/src/lib/assets/kwaipilot.svg +1 -0
- package/src/lib/assets/meta.svg +1 -0
- package/src/lib/assets/minimax.svg +9 -0
- package/src/lib/assets/moonshotai.svg +4 -0
- package/src/lib/assets/openai.svg +5 -0
- package/src/lib/assets/xai.svg +1 -0
- package/src/lib/assets/xiaomi.svg +2 -0
- package/src/lib/assets/zai.svg +219 -0
- package/src/lib/benchmark-score.js +215 -0
- package/src/lib/benchmark-truth.js +68 -0
- package/src/lib/cache.js +76 -0
- package/src/lib/common.js +208 -0
- package/src/lib/cooldown.js +63 -0
- package/src/lib/creators.js +71 -0
- package/src/lib/curated-cache.js +146 -0
- package/src/lib/errors.js +126 -0
- package/src/lib/index.js +726 -0
- package/src/lib/logger.js +29 -0
- package/src/lib/providers.js +87 -0
- package/src/lib/rank.js +390 -0
- package/src/lib/rate-limiter.js +50 -0
- package/src/lib/schema.js +150 -0
- package/src/lib/select.js +474 -0
- package/src/lib/tracing.js +62 -0
- package/src/lib/utils.js +85 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek adapter — OpenAI-compatible chat completions against
|
|
3
|
+
* api.deepseek.com. DeepSeek models occasionally emit tool calls as
|
|
4
|
+
* DSML XML-style blocks in `content` rather than the native
|
|
5
|
+
* `tool_calls` array; the shared core handles the fallback parse
|
|
6
|
+
* when `parseDsml: true`.
|
|
7
|
+
*
|
|
8
|
+
* @module session/adapters/deepseek
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import OpenAI from 'openai'
|
|
12
|
+
|
|
13
|
+
import { runChatCompletions } from './_chat_completions.js'
|
|
14
|
+
|
|
15
|
+
const BASE_URL = 'https://api.deepseek.com'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {import('#core/envelope.js').CallEnvelope} envelope
|
|
19
|
+
* @param {{client?: any, signal?: AbortSignal, log?: any, span?: any}} [deps]
|
|
20
|
+
* @returns {AsyncGenerator<import('#core/events.js').Event>}
|
|
21
|
+
*/
|
|
22
|
+
export async function * deepseek (envelope, deps = {}) {
|
|
23
|
+
const client = deps.client ?? new OpenAI({ apiKey: envelope.auth.key, baseURL: envelope.auth.baseURL || BASE_URL })
|
|
24
|
+
yield * runChatCompletions(envelope, client, {
|
|
25
|
+
provider: 'deepseek',
|
|
26
|
+
parseDsml: true
|
|
27
|
+
}, {
|
|
28
|
+
signal: deps.signal,
|
|
29
|
+
log: deps.log,
|
|
30
|
+
span: deps.span
|
|
31
|
+
})
|
|
32
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Echo adapter — deterministic stub. Emits two message deltas and a
|
|
3
|
+
* `done` event with a synthetic `AnswerResult`. Honors `signal` for
|
|
4
|
+
* test-controlled cancellation.
|
|
5
|
+
*
|
|
6
|
+
* @module session/adapters/echo
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { STATUS_COMPLETED } from '#core/status.js'
|
|
10
|
+
|
|
11
|
+
import { cancelledDone } from './_cancelled.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {import('#core/envelope.js').CallEnvelope} envelope
|
|
15
|
+
* @param {{signal?: AbortSignal}} [deps]
|
|
16
|
+
* @returns {AsyncGenerator<import('#core/events.js').Event>}
|
|
17
|
+
*/
|
|
18
|
+
export async function * echo (envelope, { signal } = {}) {
|
|
19
|
+
const start = String(process.hrtime.bigint())
|
|
20
|
+
let first = null
|
|
21
|
+
let output = ''
|
|
22
|
+
|
|
23
|
+
for (const delta of ['Hello', ', world.']) {
|
|
24
|
+
if (signal?.aborted) {
|
|
25
|
+
yield cancelledDone(start, first, envelope, output, 0, 0)
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
if (first === null) first = String(process.hrtime.bigint())
|
|
29
|
+
output += delta
|
|
30
|
+
yield { type: 'delta', delta: { type: 'message', delta } }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (signal?.aborted) {
|
|
34
|
+
yield cancelledDone(start, first, envelope, output, 0, 0)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const end = String(process.hrtime.bigint())
|
|
39
|
+
yield {
|
|
40
|
+
type: 'done',
|
|
41
|
+
result: {
|
|
42
|
+
status: STATUS_COMPLETED,
|
|
43
|
+
output,
|
|
44
|
+
inputTokens: 0,
|
|
45
|
+
outputTokens: 0,
|
|
46
|
+
thinkingTokens: 0,
|
|
47
|
+
cost: 0,
|
|
48
|
+
timestamps: { start, first: first ?? end, end }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fake provider — scenario-driven adapter for stress tests,
|
|
3
|
+
* benchmarks, and bug reproductions. Never calls a real API.
|
|
4
|
+
*
|
|
5
|
+
* The envelope's `prompt` field carries a JSON scenario spec; the
|
|
6
|
+
* `mode` key picks a behavior, the rest are mode-specific params.
|
|
7
|
+
* Invalid / non-JSON prompts fall through to `mode: "echo"` so ad-hoc
|
|
8
|
+
* use from scripts Just Works.
|
|
9
|
+
*
|
|
10
|
+
* ## Modes
|
|
11
|
+
*
|
|
12
|
+
* | mode | params | behavior |
|
|
13
|
+
* |---------------|--------------------------------|------------------------------------------------------|
|
|
14
|
+
* | `echo` | – | one short delta + `done` (default fallback) |
|
|
15
|
+
* | `slow` | `tokens`, `delayMs` | emit N deltas `delayMs` apart |
|
|
16
|
+
* | `volume` | `tokens` | emit N deltas as fast as the event loop allows |
|
|
17
|
+
* | `tool` | `name`, `args` | single `tool_use` terminal with one tool call |
|
|
18
|
+
* | `incomplete` | `warning` | `done` with status=incomplete + warning |
|
|
19
|
+
* | `error` | `type`, `message`, `retryable` | yield typed error event |
|
|
20
|
+
* | `hang` | – | never emits a terminal (caller aborts via signal) |
|
|
21
|
+
* | `cancel_after`| `tokens` | emit N deltas then wait for `signal.aborted` |
|
|
22
|
+
* | `crash` | `code` | `process.exit(code\|1)` — kills whichever process is running the adapter. Used by the isolation benchmark to demonstrate that via-gate the crash stays in the session subprocess, in-process it takes down the caller. |
|
|
23
|
+
*
|
|
24
|
+
* Every mode honors `deps.signal`: when aborted mid-stream, emits a
|
|
25
|
+
* `cancelled` done event. That keeps consumer behavior uniform with
|
|
26
|
+
* the real provider adapters.
|
|
27
|
+
*
|
|
28
|
+
* @module session/adapters/fake
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import {
|
|
32
|
+
STATUS_COMPLETED,
|
|
33
|
+
STATUS_INCOMPLETE,
|
|
34
|
+
STATUS_TOOL_USE,
|
|
35
|
+
WARNING_INSUFFICIENT_OUTPUT_BUDGET
|
|
36
|
+
} from '#core/status.js'
|
|
37
|
+
|
|
38
|
+
import { cancelledDone } from './_cancelled.js'
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {import('#core/envelope.js').CallEnvelope} envelope
|
|
42
|
+
* @param {{signal?: AbortSignal, log?: any}} [deps]
|
|
43
|
+
* @returns {AsyncGenerator<import('#core/events.js').Event>}
|
|
44
|
+
*/
|
|
45
|
+
export async function * fake (envelope, deps = {}) {
|
|
46
|
+
const signal = deps.signal
|
|
47
|
+
const spec = parseSpec(envelope.prompt)
|
|
48
|
+
const start = String(process.hrtime.bigint())
|
|
49
|
+
let first = null
|
|
50
|
+
|
|
51
|
+
switch (spec.mode) {
|
|
52
|
+
case 'error':
|
|
53
|
+
yield {
|
|
54
|
+
type: 'error',
|
|
55
|
+
error: {
|
|
56
|
+
message: spec.message ?? 'fake error',
|
|
57
|
+
severity: spec.severity ?? 'error',
|
|
58
|
+
retryable: spec.retryable ?? false,
|
|
59
|
+
type: spec.type ?? 'PROVIDER_ERROR'
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
case 'hang':
|
|
65
|
+
// Wait for abort. If the signal is already aborted, yield
|
|
66
|
+
// cancelled immediately. Otherwise block until it fires.
|
|
67
|
+
await waitForAbort(signal)
|
|
68
|
+
yield cancelledDone(start, first, envelope, '', 0, 0)
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
case 'crash': {
|
|
72
|
+
// Kills whatever process is executing the adapter. In-process
|
|
73
|
+
// this takes down the caller; via the gate it only takes down
|
|
74
|
+
// one session subprocess, which the pool respawns.
|
|
75
|
+
const code = Number.isInteger(spec.code) ? spec.code : 1
|
|
76
|
+
process.exit(code)
|
|
77
|
+
// process.exit does not return; this line is unreachable but
|
|
78
|
+
// the linter can't see that and would flag no-fallthrough.
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
case 'incomplete': {
|
|
83
|
+
const warning = spec.warning ?? WARNING_INSUFFICIENT_OUTPUT_BUDGET
|
|
84
|
+
const text = spec.output ?? 'partial output'
|
|
85
|
+
first = String(process.hrtime.bigint())
|
|
86
|
+
yield { type: 'delta', delta: { type: 'message', delta: text } }
|
|
87
|
+
yield doneEvent({
|
|
88
|
+
status: STATUS_INCOMPLETE,
|
|
89
|
+
output: text,
|
|
90
|
+
warning,
|
|
91
|
+
start,
|
|
92
|
+
first,
|
|
93
|
+
tokens: approxTokens(text)
|
|
94
|
+
})
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
case 'tool': {
|
|
99
|
+
const name = spec.name ?? 'fake_tool'
|
|
100
|
+
const args = spec.args ?? {}
|
|
101
|
+
const id = spec.id ?? `fake_call_${Date.now()}`
|
|
102
|
+
first = String(process.hrtime.bigint())
|
|
103
|
+
yield {
|
|
104
|
+
type: 'delta',
|
|
105
|
+
delta: { type: 'function_call', delta: JSON.stringify(args) }
|
|
106
|
+
}
|
|
107
|
+
yield doneEvent({
|
|
108
|
+
status: STATUS_TOOL_USE,
|
|
109
|
+
output: null,
|
|
110
|
+
start,
|
|
111
|
+
first,
|
|
112
|
+
tokens: 0,
|
|
113
|
+
toolCalls: [{ id, name, arguments: args }]
|
|
114
|
+
})
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
case 'slow':
|
|
119
|
+
case 'volume': {
|
|
120
|
+
const total = clampPositive(spec.tokens, 5)
|
|
121
|
+
const delayMs = spec.mode === 'slow' ? clampPositive(spec.delayMs, 50) : 0
|
|
122
|
+
let output = ''
|
|
123
|
+
for (let i = 0; i < total; i++) {
|
|
124
|
+
if (signal?.aborted) {
|
|
125
|
+
yield cancelledDone(start, first, envelope, output, approxTokens(output), approxTokens(output))
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
if (first === null) first = String(process.hrtime.bigint())
|
|
129
|
+
const chunk = spec.chunk ?? `tok${i} `
|
|
130
|
+
output += chunk
|
|
131
|
+
yield { type: 'delta', delta: { type: 'message', delta: chunk } }
|
|
132
|
+
if (delayMs > 0) {
|
|
133
|
+
await sleep(delayMs, signal)
|
|
134
|
+
if (signal?.aborted) {
|
|
135
|
+
yield cancelledDone(start, first, envelope, output, approxTokens(output), approxTokens(output))
|
|
136
|
+
return
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
yield doneEvent({
|
|
141
|
+
status: STATUS_COMPLETED,
|
|
142
|
+
output,
|
|
143
|
+
start,
|
|
144
|
+
first,
|
|
145
|
+
tokens: approxTokens(output)
|
|
146
|
+
})
|
|
147
|
+
return
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
case 'cancel_after': {
|
|
151
|
+
const total = clampPositive(spec.tokens, 3)
|
|
152
|
+
let output = ''
|
|
153
|
+
for (let i = 0; i < total; i++) {
|
|
154
|
+
if (first === null) first = String(process.hrtime.bigint())
|
|
155
|
+
const chunk = `tok${i} `
|
|
156
|
+
output += chunk
|
|
157
|
+
yield { type: 'delta', delta: { type: 'message', delta: chunk } }
|
|
158
|
+
}
|
|
159
|
+
await waitForAbort(signal)
|
|
160
|
+
yield cancelledDone(start, first, envelope, output, approxTokens(output), approxTokens(output))
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
case 'echo':
|
|
165
|
+
default: {
|
|
166
|
+
const text = spec.output ?? 'ok'
|
|
167
|
+
first = String(process.hrtime.bigint())
|
|
168
|
+
yield { type: 'delta', delta: { type: 'message', delta: text } }
|
|
169
|
+
yield doneEvent({
|
|
170
|
+
status: STATUS_COMPLETED,
|
|
171
|
+
output: text,
|
|
172
|
+
start,
|
|
173
|
+
first,
|
|
174
|
+
tokens: approxTokens(text)
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* @param {string | any[]} prompt
|
|
182
|
+
* @returns {{mode: string, [k: string]: any}}
|
|
183
|
+
*/
|
|
184
|
+
function parseSpec (prompt) {
|
|
185
|
+
if (typeof prompt !== 'string') return { mode: 'echo' }
|
|
186
|
+
const trimmed = prompt.trim()
|
|
187
|
+
if (!trimmed.startsWith('{')) return { mode: 'echo' }
|
|
188
|
+
try {
|
|
189
|
+
const obj = JSON.parse(trimmed)
|
|
190
|
+
if (!obj || typeof obj !== 'object' || !obj.mode) return { mode: 'echo' }
|
|
191
|
+
return obj
|
|
192
|
+
} catch {
|
|
193
|
+
return { mode: 'echo' }
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @param {number | undefined} v
|
|
199
|
+
* @param {number} fallback
|
|
200
|
+
*/
|
|
201
|
+
function clampPositive (v, fallback) {
|
|
202
|
+
if (typeof v !== 'number' || !Number.isFinite(v) || v < 0) return fallback
|
|
203
|
+
return Math.floor(v)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Cheap token estimate — 4 chars/token, deterministic across runs. */
|
|
207
|
+
function approxTokens (text) {
|
|
208
|
+
return Math.max(1, Math.ceil((text?.length ?? 0) / 4))
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* @param {number} ms
|
|
213
|
+
* @param {AbortSignal} [signal]
|
|
214
|
+
*/
|
|
215
|
+
function sleep (ms, signal) {
|
|
216
|
+
return new Promise((resolve) => {
|
|
217
|
+
const timer = setTimeout(resolve, ms)
|
|
218
|
+
if (signal) {
|
|
219
|
+
signal.addEventListener('abort', () => {
|
|
220
|
+
clearTimeout(timer)
|
|
221
|
+
resolve()
|
|
222
|
+
}, { once: true })
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** @param {AbortSignal} [signal] */
|
|
228
|
+
function waitForAbort (signal) {
|
|
229
|
+
if (!signal) return new Promise(() => {}) // never resolves — caller had better set a timeout
|
|
230
|
+
if (signal.aborted) return Promise.resolve()
|
|
231
|
+
return new Promise((resolve) => {
|
|
232
|
+
signal.addEventListener('abort', () => resolve(), { once: true })
|
|
233
|
+
})
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* @param {{
|
|
238
|
+
* status: string,
|
|
239
|
+
* output: string | null,
|
|
240
|
+
* start: string,
|
|
241
|
+
* first: string | null,
|
|
242
|
+
* tokens: number,
|
|
243
|
+
* warning?: string,
|
|
244
|
+
* toolCalls?: any[]
|
|
245
|
+
* }} opts
|
|
246
|
+
* @returns {import('#core/events.js').DoneEvent}
|
|
247
|
+
*/
|
|
248
|
+
function doneEvent (opts) {
|
|
249
|
+
const end = String(process.hrtime.bigint())
|
|
250
|
+
const result = {
|
|
251
|
+
status: opts.status,
|
|
252
|
+
output: opts.output,
|
|
253
|
+
inputTokens: opts.tokens,
|
|
254
|
+
outputTokens: opts.tokens,
|
|
255
|
+
thinkingTokens: 0,
|
|
256
|
+
cost: 0,
|
|
257
|
+
timestamps: { start: opts.start, first: opts.first ?? end, end }
|
|
258
|
+
}
|
|
259
|
+
if (opts.warning) result.warning = opts.warning
|
|
260
|
+
if (opts.toolCalls) result.toolCalls = opts.toolCalls
|
|
261
|
+
return { type: 'done', result }
|
|
262
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fireworks adapter — OpenAI-compatible chat completions with
|
|
3
|
+
* streaming, over api.fireworks.ai/inference/v1.
|
|
4
|
+
*
|
|
5
|
+
* Fireworks model IDs carry an `accounts/fireworks/models/` prefix;
|
|
6
|
+
* envelopes can supply either form. The `mutateArgs` hook normalizes
|
|
7
|
+
* `args.model` before the request leaves the adapter.
|
|
8
|
+
*
|
|
9
|
+
* Implementation uses the OpenAI SDK with a custom baseURL — the
|
|
10
|
+
* wire shape is identical and the SDK's streaming iterator matches
|
|
11
|
+
* what `_chat_completions.js` expects.
|
|
12
|
+
*
|
|
13
|
+
* @module session/adapters/fireworks
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import OpenAI from 'openai'
|
|
17
|
+
|
|
18
|
+
import { runChatCompletions } from './_chat_completions.js'
|
|
19
|
+
|
|
20
|
+
const BASE_URL = 'https://api.fireworks.ai/inference/v1'
|
|
21
|
+
const MODEL_PREFIX = 'accounts/fireworks/models/'
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {import('#core/envelope.js').CallEnvelope} envelope
|
|
25
|
+
* @param {{client?: any, signal?: AbortSignal, log?: any, span?: any}} [deps]
|
|
26
|
+
* @returns {AsyncGenerator<import('#core/events.js').Event>}
|
|
27
|
+
*/
|
|
28
|
+
export async function * fireworks (envelope, deps = {}) {
|
|
29
|
+
const client = deps.client ?? new OpenAI({
|
|
30
|
+
apiKey: envelope.auth.key,
|
|
31
|
+
baseURL: envelope.auth.baseURL || BASE_URL
|
|
32
|
+
})
|
|
33
|
+
yield * runChatCompletions(envelope, client, {
|
|
34
|
+
provider: 'fireworks',
|
|
35
|
+
stream: true,
|
|
36
|
+
mutateArgs: (env, args) => {
|
|
37
|
+
if (!args.model.includes('/')) {
|
|
38
|
+
args.model = `${MODEL_PREFIX}${args.model}`
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}, {
|
|
42
|
+
signal: deps.signal,
|
|
43
|
+
log: deps.log,
|
|
44
|
+
span: deps.span
|
|
45
|
+
})
|
|
46
|
+
}
|