mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-01 03:42:04 +00:00
refactor(ai): make Promise the root entry and move Effect to @opencode/ai/effect (#58847)
This commit is contained in:
parent
ddd9e103fe
commit
dad29a8991
265 changed files with 678 additions and 670 deletions
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
- Use `HttpClient`, `Stream`, and Schema codecs instead of `fetch`, async generators, and `JSON.parse`/`JSON.stringify`.
|
||||
- `return yield* new MyError(...)` instead of `Effect.fail(...)`; `Effect.void` instead of `Effect.succeed(undefined)`.
|
||||
- Only `src/promise.ts` may use Promises.
|
||||
- Only `src/index.ts` (the Promise entry) may use Promises.
|
||||
|
||||
## Tests
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,32 @@
|
|||
|
||||
Schema-first APIs for text, images, video, speech, and transcription, built with Effect.
|
||||
|
||||
`@opencode/ai` is the Promise API: one managed runtime behind the LLM and media methods, plus asset helpers. `ai.file`
|
||||
and `ai.write` load `node:fs/promises` on first use, so no Effect `FileSystem` is needed:
|
||||
|
||||
```ts
|
||||
import { AI } from "@opencode/ai"
|
||||
import { OpenAI } from "@opencode/ai/providers"
|
||||
|
||||
const openai = OpenAI.configure({ apiKey: process.env.OPENAI_API_KEY })
|
||||
|
||||
const ai = AI.make()
|
||||
const input = { model: openai.responses("gpt-4o-mini"), prompt: "Say hello." }
|
||||
const response = await ai.llm.generate(input)
|
||||
console.log(response.text)
|
||||
const generated = await ai.image.generate({ model: openai.image("gpt-image-2"), prompt: "A lighthouse" })
|
||||
await ai.write(generated.image, "./lighthouse.png") // also ai.file(path), ai.bytes(asset), ai.base64(asset), ai.materialize(asset)
|
||||
for await (const event of ai.llm.stream(ai.llm.request(input))) {
|
||||
// LLMEvent
|
||||
}
|
||||
await ai.dispose()
|
||||
```
|
||||
|
||||
The Effect API lives at `@opencode/ai/effect`. Its methods return `Effect` or `Stream`:
|
||||
|
||||
```ts
|
||||
import { Effect } from "effect"
|
||||
import { AIClient, LLM } from "@opencode/ai"
|
||||
import { AIClient, LLM } from "@opencode/ai/effect"
|
||||
import { OpenAI } from "@opencode/ai/providers"
|
||||
|
||||
const openai = OpenAI.configure({ apiKey: process.env.OPENAI_API_KEY })
|
||||
|
|
@ -64,7 +87,7 @@ provider's image route from the model and returns `Media.Asset`s with lazily dec
|
|||
|
||||
```ts
|
||||
import { NodeFileSystem } from "@effect/platform-node"
|
||||
import { Image, Media } from "@opencode/ai"
|
||||
import { Image, Media } from "@opencode/ai/effect"
|
||||
|
||||
const image = Effect.gen(function* () {
|
||||
const response = yield* Image.generate({
|
||||
|
|
@ -96,30 +119,13 @@ const logged = RequestExecutor.middleware((request, next) =>
|
|||
const everything = AIClient.layerWith(logged) // or AI.make({ layer: logged })
|
||||
```
|
||||
|
||||
Prefer promises? `@opencode/ai/promise` exposes the same LLM and media APIs over one managed runtime, plus asset
|
||||
helpers; `ai.file` and `ai.write` load `node:fs/promises` on first use, so no Effect `FileSystem` is needed:
|
||||
|
||||
```ts
|
||||
import { AI } from "@opencode/ai/promise"
|
||||
|
||||
const ai = AI.make()
|
||||
const input = { model: openai.responses("gpt-4o-mini"), prompt: "Say hello." }
|
||||
const text = await ai.llm.generate(input)
|
||||
const generated = await ai.image.generate({ model: openai.image("gpt-image-2"), prompt: "A lighthouse" })
|
||||
await ai.write(generated.image, "./lighthouse.png") // also ai.file(path), ai.bytes(asset), ai.base64(asset), ai.materialize(asset)
|
||||
for await (const event of ai.llm.stream(ai.llm.request(input))) {
|
||||
// LLMEvent
|
||||
}
|
||||
await ai.dispose()
|
||||
```
|
||||
|
||||
## Venice AI
|
||||
|
||||
`Venice` provides native Chat Completions with streaming tools and reasoning. `model` and `chat`
|
||||
select the same API; credentials default to `VENICE_API_KEY`.
|
||||
|
||||
```ts
|
||||
import { LLM } from "@opencode/ai"
|
||||
import { LLM } from "@opencode/ai/effect"
|
||||
import { Venice } from "@opencode/ai/providers"
|
||||
import { Effect } from "effect"
|
||||
|
||||
|
|
@ -155,7 +161,7 @@ values, or a `score` on ordered levels, each with the probability of every optio
|
|||
|
||||
```ts
|
||||
import { Effect } from "effect"
|
||||
import { Decision, DecisionClient, Media } from "@opencode/ai"
|
||||
import { Decision, DecisionClient, Media } from "@opencode/ai/effect"
|
||||
import { OpenAI } from "@opencode/ai/providers"
|
||||
|
||||
const program = Decision.generate({
|
||||
|
|
@ -223,7 +229,7 @@ Chat Completions (`.model` or `.chat`), Anthropic-compatible Messages (`.message
|
|||
Responses (`.responses`). These routes use HTTP/SSE.
|
||||
|
||||
```ts
|
||||
import { LLM } from "@opencode/ai"
|
||||
import { LLM } from "@opencode/ai/effect"
|
||||
import { Alibaba } from "@opencode/ai/providers"
|
||||
|
||||
const alibaba = Alibaba.configure({
|
||||
|
|
@ -302,7 +308,7 @@ pass through. Results are URLs that Model Studio keeps for 24 hours. A complete
|
|||
the existing `.image(...)` selector provides image generation.
|
||||
|
||||
```ts
|
||||
import { LLM } from "@opencode/ai"
|
||||
import { LLM } from "@opencode/ai/effect"
|
||||
import { ZAI, ZAICodingPlan } from "@opencode/ai/providers"
|
||||
|
||||
const zai = ZAI.configure({ apiKey: process.env.ZAI_API_KEY })
|
||||
|
|
@ -368,7 +374,7 @@ Package entrypoints are `@opencode/ai/providers/zai`, `zai/chat`, `zai-coding-pl
|
|||
Moonshot defaults to Chat Completions, with Messages and Responses selectors for Kimi K3:
|
||||
|
||||
```ts
|
||||
import { LLM } from "@opencode/ai"
|
||||
import { LLM } from "@opencode/ai/effect"
|
||||
import { Moonshot } from "@opencode/ai/providers"
|
||||
|
||||
const moonshot = Moonshot.configure({ apiKey: process.env.MOONSHOT_API_KEY })
|
||||
|
|
@ -430,7 +436,7 @@ MiniMax defaults to its Messages API and reads `MINIMAX_API_KEY` when `apiKey` i
|
|||
|
||||
```ts
|
||||
import { Effect } from "effect"
|
||||
import { AIClient, LLM } from "@opencode/ai"
|
||||
import { AIClient, LLM } from "@opencode/ai/effect"
|
||||
import { MiniMax } from "@opencode/ai/providers"
|
||||
|
||||
const minimax = MiniMax.configure({ apiKey: process.env.MINIMAX_API_KEY })
|
||||
|
|
@ -507,7 +513,7 @@ citations or separate result blocks. Retain `response.message` for either API's
|
|||
Use `Image.generate` for one-off generation or editing:
|
||||
|
||||
```ts
|
||||
import { Image, Media } from "@opencode/ai"
|
||||
import { Image, Media } from "@opencode/ai/effect"
|
||||
|
||||
const generation = Image.generate({
|
||||
model: meta.image("muse-image-1.0"),
|
||||
|
|
@ -543,7 +549,7 @@ selected model. `aspect` is a ratio such as `"16:9"`; `resolution` is a size tie
|
|||
at that ratio, `"2K"` about 2048×2048). Exact sizes, seeds, masks, and output formats are provider options:
|
||||
|
||||
```ts
|
||||
import { Image, Media } from "@opencode/ai"
|
||||
import { Image, Media } from "@opencode/ai/effect"
|
||||
import { OpenAI } from "@opencode/ai/providers"
|
||||
|
||||
const openai = OpenAI.configure({ apiKey: process.env.OPENAI_API_KEY })
|
||||
|
|
@ -729,7 +735,7 @@ and emits `image-partial` events before each final `image`; `Image.generate` kee
|
|||
|
||||
```ts
|
||||
import { Stream } from "effect"
|
||||
import { ImageEvent } from "@opencode/ai"
|
||||
import { ImageEvent } from "@opencode/ai/effect"
|
||||
|
||||
const previews = Image.stream({
|
||||
model: openai.image("gpt-image-2"),
|
||||
|
|
@ -813,7 +819,7 @@ Common fields (`frames`, `references`, `video`, `durationSeconds`, `aspect`, `re
|
|||
under `providerOptions`, inferred from the selected model.
|
||||
|
||||
```ts
|
||||
import { Video } from "@opencode/ai"
|
||||
import { Video } from "@opencode/ai/effect"
|
||||
import { Google, Runway } from "@opencode/ai/providers"
|
||||
|
||||
const google = Google.configure({ apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY })
|
||||
|
|
@ -885,7 +891,7 @@ aborting rejects the Promise or throws from the `for await` loop with `signal.re
|
|||
unless `abort(reason)` passed one), while `break` stops a stream without throwing.
|
||||
|
||||
```ts
|
||||
import { ai } from "@opencode/ai/promise"
|
||||
import { ai } from "@opencode/ai"
|
||||
|
||||
const generation = await ai.video.start({ model, prompt })
|
||||
for await (const event of generation.events({ poll: { interval: 10_000 } })) console.log(event.type)
|
||||
|
|
@ -902,7 +908,7 @@ selectors on the `OpenAI`, `Google` (Gemini TTS), `ElevenLabs`, `Cartesia`, and
|
|||
before any network call; provider-native controls live under `providerOptions`, inferred from the selected model.
|
||||
|
||||
```ts
|
||||
import { Media, Speech, SpeechClient, SpeechEvent } from "@opencode/ai"
|
||||
import { Media, Speech, SpeechClient, SpeechEvent } from "@opencode/ai/effect"
|
||||
import { ElevenLabs, OpenAI } from "@opencode/ai/providers"
|
||||
|
||||
const openai = OpenAI.configure({ apiKey: process.env.OPENAI_API_KEY })
|
||||
|
|
@ -967,7 +973,7 @@ Provider notes:
|
|||
The promise client mirrors the Effect API; `ai.speech.stream` is an `AsyncIterable`.
|
||||
|
||||
```ts
|
||||
import { ai } from "@opencode/ai/promise"
|
||||
import { ai } from "@opencode/ai"
|
||||
|
||||
const response = await ai.speech.generate({ model, text: "Hello from OpenCode.", voice: "coral" })
|
||||
await ai.write(response.audio, "hello.mp3")
|
||||
|
|
@ -989,7 +995,7 @@ any network call; a route may return more than asked.
|
|||
|
||||
```ts
|
||||
import { Console, Effect, Stream } from "effect"
|
||||
import { Media, Transcription, TranscriptionEvent } from "@opencode/ai"
|
||||
import { Media, Transcription, TranscriptionEvent } from "@opencode/ai/effect"
|
||||
import { AssemblyAI, Deepgram, OpenAI } from "@opencode/ai/providers"
|
||||
|
||||
const openai = OpenAI.configure({ apiKey: process.env.OPENAI_API_KEY })
|
||||
|
|
@ -1050,6 +1056,8 @@ const transcript = await generation.await({ poll: { interval: 3_000 } })
|
|||
|
||||
## Public API
|
||||
|
||||
Everything below is exported from `@opencode/ai/effect` unless noted.
|
||||
|
||||
- **`LLM.request({...})`** — build a provider-neutral `LLMRequest`. Accepts ergonomic inputs (`system: string`, `prompt: string`) that normalize into the canonical Schema classes.
|
||||
- **`LLM.generate` / `LLM.stream`** — run direct input or an `LLMRequest` through `LLMClient` for one-import use.
|
||||
- **`Message.user(...)` / `Message.assistant(...)` / `Message.tool(...)`** — message constructors from the canonical schema model.
|
||||
|
|
@ -1063,7 +1071,7 @@ const transcript = await generation.await({ poll: { interval: 3_000 } })
|
|||
- **`Speech.request` / `Speech.generate` / `Speech.stream`** — text-to-speech through a provider-neutral request; `SpeechClient` is its Effect service and layer.
|
||||
- **`Transcription.request` / `generate` / `stream` / `start` / `resume`** — speech-to-text over inline, streaming, and queued routes; `TranscriptionClient` is its Effect service and layer.
|
||||
- **`AIClient.layer` / `AIClient.layerWith(executor)`** — every modality client plus the request executor in one layer.
|
||||
- **`@opencode/ai/promise`** — `AI.make({ layer? })` and a default `ai` client exposing `llm`, `image`, `video`, `speech`, and `transcription` as Promise / `AsyncIterable` APIs, plus `file`, `write`, `bytes`, `base64`, and `materialize` for assets.
|
||||
- **`@opencode/ai`** (Promise root) — `AI.make({ layer? })` and a default `ai` client exposing `llm`, `image`, `video`, `speech`, and `transcription` as Promise / `AsyncIterable` APIs, plus `file`, `write`, `bytes`, `base64`, and `materialize` for assets.
|
||||
|
||||
## Testing
|
||||
|
||||
|
|
@ -1188,7 +1196,7 @@ Enable OpenAI compaction with typed provider options:
|
|||
|
||||
```ts
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMClient, LLMRequest, Message } from "@opencode/ai"
|
||||
import { LLM, LLMClient, LLMRequest, Message } from "@opencode/ai/effect"
|
||||
import { OpenAI } from "@opencode/ai/providers"
|
||||
|
||||
const request = LLM.request({
|
||||
|
|
@ -1211,7 +1219,7 @@ const continued = Effect.gen(function* () {
|
|||
A compaction part has `provider` and exactly one representation: `encrypted` for Responses, or `text` for Anthropic. Responses also preserves the optional checkpoint `id`. These fields survive message serialization without becoming visible assistant text. Sending a checkpoint to another provider or an incompatible API fails rather than silently losing context.
|
||||
|
||||
```ts
|
||||
import { CompactionPart, ProviderID } from "@opencode/ai"
|
||||
import { CompactionPart, ProviderID } from "@opencode/ai/effect"
|
||||
|
||||
CompactionPart.make({ provider: ProviderID.make("openai"), id: "cmp_123", encrypted: "..." })
|
||||
CompactionPart.make({ provider: ProviderID.make("anthropic"), text: "Summary of the conversation..." })
|
||||
|
|
@ -1431,7 +1439,7 @@ Compose a route with `Route.make({ protocol, endpoint, auth, framing, ... })`. T
|
|||
|
||||
## Effect
|
||||
|
||||
This package is built on Effect. Public methods return `Effect` or `Stream`; provide `AIClient.layer` (or `AIClient.layerWith(executor)`) for every modality, then import the provider/protocol modules for the routes you use. The example at `example/tutorial.ts` is a runnable walkthrough.
|
||||
This package is built on Effect. Public methods in `@opencode/ai/effect` return `Effect` or `Stream`; provide `AIClient.layer` (or `AIClient.layerWith(executor)`) for every modality, then import the provider/protocol modules for the routes you use. The example at `example/tutorial.ts` is a runnable walkthrough.
|
||||
|
||||
## See also
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Config, Effect, Formatter, Schema, Stream } from "effect"
|
||||
import { NodeFileSystem } from "@effect/platform-node"
|
||||
import { AIClient, Image, LLM, LLMRequest, Media, Message, ProviderID, Tool, ToolRuntime } from "@opencode/ai"
|
||||
import { AIClient, Image, LLM, LLMRequest, Media, Message, ProviderID, Tool, ToolRuntime } from "@opencode/ai/effect"
|
||||
import { Route, Auth, Endpoint, Framing, Protocol } from "@opencode/ai/route"
|
||||
import { OpenAI } from "@opencode/ai/providers"
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
],
|
||||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./promise": "./src/promise.ts",
|
||||
"./effect": "./src/effect.ts",
|
||||
"./testing": "./src/testing.ts",
|
||||
"./*": "./src/*.ts"
|
||||
},
|
||||
|
|
|
|||
153
packages/ai/src/effect.ts
Normal file
153
packages/ai/src/effect.ts
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
export { AIClient } from "./ai-client.js"
|
||||
export { LLMClient } from "./route/client.js"
|
||||
export { ImageClient } from "./image-client.js"
|
||||
export { Auth } from "./route/auth.js"
|
||||
export { Provider } from "./provider.js"
|
||||
export { ProviderPackage } from "./provider-package.js"
|
||||
export { isContextOverflow, isContextOverflowFailure, isRetryable } from "./provider-error.js"
|
||||
export type {
|
||||
RouteLanguageModelInput,
|
||||
RouteRoutedLanguageModelInput,
|
||||
Interface as LLMClientShape,
|
||||
LLMClientService,
|
||||
} from "./route/client.js"
|
||||
export * from "./schema/index.js"
|
||||
export { ImageAspectRatio, ImageEvent, ImageModel, ImageModelSchema, ImageRequest, ImageResponse } from "./image.js"
|
||||
export type {
|
||||
ImageModelOptions,
|
||||
ImageOptions,
|
||||
ImageRequestFor,
|
||||
ImageRequestInput,
|
||||
ImageResolution,
|
||||
ImageRoute,
|
||||
} from "./image.js"
|
||||
export { Image } from "./image.js"
|
||||
export { VideoClient } from "./video-client.js"
|
||||
export {
|
||||
VideoAspectRatio,
|
||||
VideoEvent,
|
||||
VideoFrames,
|
||||
VideoModel,
|
||||
VideoModelSchema,
|
||||
VideoRequest,
|
||||
VideoResponse,
|
||||
} from "./video.js"
|
||||
export type {
|
||||
VideoModelOptions,
|
||||
VideoOptions,
|
||||
VideoRequestFor,
|
||||
VideoRequestInput,
|
||||
VideoResolution,
|
||||
VideoRoute,
|
||||
} from "./video.js"
|
||||
export { Video } from "./video.js"
|
||||
export { SpeechClient } from "./speech-client.js"
|
||||
export {
|
||||
SpeechEvent,
|
||||
SpeechModel,
|
||||
SpeechModelSchema,
|
||||
SpeechRequest,
|
||||
SpeechResponse,
|
||||
SpeechTimestamp,
|
||||
SpeechVoice,
|
||||
} from "./speech.js"
|
||||
export type {
|
||||
SpeechFormat,
|
||||
SpeechModelOptions,
|
||||
SpeechOptions,
|
||||
SpeechRequestFor,
|
||||
SpeechRequestInput,
|
||||
SpeechRoute,
|
||||
} from "./speech.js"
|
||||
export { Speech } from "./speech.js"
|
||||
export { TranscriptionClient } from "./transcription-client.js"
|
||||
export {
|
||||
TranscriptionEvent,
|
||||
TranscriptionModel,
|
||||
TranscriptionModelSchema,
|
||||
TranscriptionRequest,
|
||||
TranscriptionResponse,
|
||||
TranscriptionSegment,
|
||||
TranscriptionTimestamps,
|
||||
TranscriptionWord,
|
||||
} from "./transcription.js"
|
||||
export type {
|
||||
TranscriptionModelOptions,
|
||||
TranscriptionOptions,
|
||||
TranscriptionRequestFor,
|
||||
TranscriptionRequestInput,
|
||||
TranscriptionRoute,
|
||||
} from "./transcription.js"
|
||||
export { Transcription } from "./transcription.js"
|
||||
export { DecisionClient } from "./decision-client.js"
|
||||
export {
|
||||
ChoiceAnswer,
|
||||
ChoiceQuestion,
|
||||
ChoiceValue,
|
||||
DecisionAnswer,
|
||||
DecisionJsonPart,
|
||||
DecisionMediaPart,
|
||||
DecisionModel,
|
||||
DecisionModelCompatibility,
|
||||
DecisionModelSchema,
|
||||
DecisionPart,
|
||||
DecisionQuestion,
|
||||
DecisionRequest,
|
||||
DecisionResponse,
|
||||
DecisionTextPart,
|
||||
ErrorAnswer,
|
||||
PredicateAnswer,
|
||||
PredicateQuestion,
|
||||
ScoreAnswer,
|
||||
ScoreQuestion,
|
||||
} from "./decision.js"
|
||||
export type {
|
||||
AnswerFor,
|
||||
AnswersFor,
|
||||
DecisionInput,
|
||||
DecisionModelOptions,
|
||||
DecisionOptions,
|
||||
DecisionQuestions,
|
||||
DecisionRequestFor,
|
||||
DecisionRequestInput,
|
||||
DecisionResponseFor,
|
||||
DecisionModelRoute,
|
||||
} from "./decision.js"
|
||||
export { Decision } from "./decision.js"
|
||||
export { DecisionRoute } from "./route/decision.js"
|
||||
export { Media } from "./media.js"
|
||||
export { Generation } from "./generation.js"
|
||||
export type {
|
||||
AwaitOptions as GenerationAwaitOptions,
|
||||
Event as GenerationEvent,
|
||||
Poll,
|
||||
Route as GenerationRoute,
|
||||
Snapshot as GenerationSnapshot,
|
||||
Status as GenerationStatus,
|
||||
} from "./generation.js"
|
||||
export { Tool, ToolFailure, toDefinitions } from "./tool.js"
|
||||
export { ToolRuntime } from "./tool-runtime.js"
|
||||
export type { DispatchResult as ToolDispatchResult, ToolSettlement } from "./tool-runtime.js"
|
||||
export type {
|
||||
AnyExecutableTool,
|
||||
AnyTool,
|
||||
ExecutableTool,
|
||||
ExecutableTools,
|
||||
Definition as ToolShape,
|
||||
ToolExecute,
|
||||
ToolExecuteContext,
|
||||
ToolModelOutputInput,
|
||||
Tools,
|
||||
ToolSchema,
|
||||
ToolToModelOutput,
|
||||
} from "./tool.js"
|
||||
export * as LLM from "./llm.js"
|
||||
export type {
|
||||
Definition as ProviderDefinition,
|
||||
LanguageModelFactory as ProviderLanguageModelFactory,
|
||||
LanguageModelOptions as ProviderLanguageModelOptions,
|
||||
} from "./provider.js"
|
||||
export type {
|
||||
Definition as ProviderPackageDefinition,
|
||||
Settings as ProviderPackageSettings,
|
||||
} from "./provider-package.js"
|
||||
|
|
@ -1,153 +1,218 @@
|
|||
export { AIClient } from "./ai-client.js"
|
||||
export { LLMClient } from "./route/client.js"
|
||||
export { ImageClient } from "./image-client.js"
|
||||
export { Auth } from "./route/auth.js"
|
||||
export { Provider } from "./provider.js"
|
||||
export { ProviderPackage } from "./provider-package.js"
|
||||
export { isContextOverflow, isContextOverflowFailure, isRetryable } from "./provider-error.js"
|
||||
export type {
|
||||
RouteLanguageModelInput,
|
||||
RouteRoutedLanguageModelInput,
|
||||
Interface as LLMClientShape,
|
||||
LLMClientService,
|
||||
} from "./route/client.js"
|
||||
export * from "./schema/index.js"
|
||||
export { ImageAspectRatio, ImageEvent, ImageModel, ImageModelSchema, ImageRequest, ImageResponse } from "./image.js"
|
||||
export type {
|
||||
ImageModelOptions,
|
||||
ImageOptions,
|
||||
ImageRequestFor,
|
||||
ImageRequestInput,
|
||||
ImageResolution,
|
||||
ImageRoute,
|
||||
} from "./image.js"
|
||||
export { Image } from "./image.js"
|
||||
export { VideoClient } from "./video-client.js"
|
||||
export {
|
||||
VideoAspectRatio,
|
||||
VideoEvent,
|
||||
VideoFrames,
|
||||
VideoModel,
|
||||
VideoModelSchema,
|
||||
VideoRequest,
|
||||
VideoResponse,
|
||||
} from "./video.js"
|
||||
export type {
|
||||
VideoModelOptions,
|
||||
VideoOptions,
|
||||
VideoRequestFor,
|
||||
VideoRequestInput,
|
||||
VideoResolution,
|
||||
VideoRoute,
|
||||
} from "./video.js"
|
||||
export { Video } from "./video.js"
|
||||
export { SpeechClient } from "./speech-client.js"
|
||||
export {
|
||||
SpeechEvent,
|
||||
SpeechModel,
|
||||
SpeechModelSchema,
|
||||
SpeechRequest,
|
||||
SpeechResponse,
|
||||
SpeechTimestamp,
|
||||
SpeechVoice,
|
||||
} from "./speech.js"
|
||||
export type {
|
||||
SpeechFormat,
|
||||
SpeechModelOptions,
|
||||
SpeechOptions,
|
||||
SpeechRequestFor,
|
||||
SpeechRequestInput,
|
||||
SpeechRoute,
|
||||
} from "./speech.js"
|
||||
export { Speech } from "./speech.js"
|
||||
export { TranscriptionClient } from "./transcription-client.js"
|
||||
export {
|
||||
TranscriptionEvent,
|
||||
TranscriptionModel,
|
||||
TranscriptionModelSchema,
|
||||
TranscriptionRequest,
|
||||
TranscriptionResponse,
|
||||
TranscriptionSegment,
|
||||
TranscriptionTimestamps,
|
||||
TranscriptionWord,
|
||||
import { Effect, Layer, ManagedRuntime, Stream } from "effect"
|
||||
import { AIClient } from "./ai-client.js"
|
||||
import { Decision, type DecisionModel, type DecisionQuestions, type DecisionRequestInput } from "./decision.js"
|
||||
import type { AwaitOptions, Event, Generation, Snapshot } from "./generation.js"
|
||||
import { Image, type ImageModel, type ImageRequest, type ImageRequestInput } from "./image.js"
|
||||
import { LLM } from "./effect.js"
|
||||
import { Media } from "./media.js"
|
||||
import { RequestExecutor } from "./route/executor.js"
|
||||
import { AIError, InvalidRequestError, LanguageModel, type LLMRequest } from "./schema/index.js"
|
||||
import type { RequestInput } from "./llm.js"
|
||||
import { Speech, type SpeechModel, type SpeechRequest, type SpeechRequestInput } from "./speech.js"
|
||||
import {
|
||||
Transcription,
|
||||
type TranscriptionModel,
|
||||
type TranscriptionRequest,
|
||||
type TranscriptionRequestInput,
|
||||
} from "./transcription.js"
|
||||
export type {
|
||||
TranscriptionModelOptions,
|
||||
TranscriptionOptions,
|
||||
TranscriptionRequestFor,
|
||||
TranscriptionRequestInput,
|
||||
TranscriptionRoute,
|
||||
} from "./transcription.js"
|
||||
export { Transcription } from "./transcription.js"
|
||||
export { DecisionClient } from "./decision-client.js"
|
||||
export {
|
||||
ChoiceAnswer,
|
||||
ChoiceQuestion,
|
||||
ChoiceValue,
|
||||
DecisionAnswer,
|
||||
DecisionJsonPart,
|
||||
DecisionMediaPart,
|
||||
DecisionModel,
|
||||
DecisionModelCompatibility,
|
||||
DecisionModelSchema,
|
||||
DecisionPart,
|
||||
DecisionQuestion,
|
||||
DecisionRequest,
|
||||
DecisionResponse,
|
||||
DecisionTextPart,
|
||||
ErrorAnswer,
|
||||
PredicateAnswer,
|
||||
PredicateQuestion,
|
||||
ScoreAnswer,
|
||||
ScoreQuestion,
|
||||
} from "./decision.js"
|
||||
export type {
|
||||
AnswerFor,
|
||||
AnswersFor,
|
||||
DecisionInput,
|
||||
DecisionModelOptions,
|
||||
DecisionOptions,
|
||||
DecisionQuestions,
|
||||
DecisionRequestFor,
|
||||
DecisionRequestInput,
|
||||
DecisionResponseFor,
|
||||
DecisionModelRoute,
|
||||
} from "./decision.js"
|
||||
export { Decision } from "./decision.js"
|
||||
export { DecisionRoute } from "./route/decision.js"
|
||||
export { Media } from "./media.js"
|
||||
export { Generation } from "./generation.js"
|
||||
export type {
|
||||
AwaitOptions as GenerationAwaitOptions,
|
||||
Event as GenerationEvent,
|
||||
Poll,
|
||||
Route as GenerationRoute,
|
||||
Snapshot as GenerationSnapshot,
|
||||
Status as GenerationStatus,
|
||||
} from "./generation.js"
|
||||
export { Tool, ToolFailure, toDefinitions } from "./tool.js"
|
||||
export { ToolRuntime } from "./tool-runtime.js"
|
||||
export type { DispatchResult as ToolDispatchResult, ToolSettlement } from "./tool-runtime.js"
|
||||
export type {
|
||||
AnyExecutableTool,
|
||||
AnyTool,
|
||||
ExecutableTool,
|
||||
ExecutableTools,
|
||||
Definition as ToolShape,
|
||||
ToolExecute,
|
||||
ToolExecuteContext,
|
||||
ToolModelOutputInput,
|
||||
Tools,
|
||||
ToolSchema,
|
||||
ToolToModelOutput,
|
||||
} from "./tool.js"
|
||||
export * as LLM from "./llm.js"
|
||||
export type {
|
||||
Definition as ProviderDefinition,
|
||||
LanguageModelFactory as ProviderLanguageModelFactory,
|
||||
LanguageModelOptions as ProviderLanguageModelOptions,
|
||||
} from "./provider.js"
|
||||
export type {
|
||||
Definition as ProviderPackageDefinition,
|
||||
Settings as ProviderPackageSettings,
|
||||
} from "./provider-package.js"
|
||||
import { fileMediaType } from "./utils/media-type.js"
|
||||
import { Video, type VideoModel, type VideoRequest, type VideoRequestInput } from "./video.js"
|
||||
|
||||
/**
|
||||
* Promise-first entrypoint for scripts and non-Effect callers. One `ManagedRuntime` hosts the LLM, image, video, speech,
|
||||
* transcription and decision clients over a request executor; every method runs the corresponding Effect API and rethrows
|
||||
* `AIError` unchanged. `file` and `write` load `node:fs/promises` on first use, so importing this module does not.
|
||||
*/
|
||||
export interface Options {
|
||||
/** Executor layer; defaults to `RequestExecutor.fetchLayer`. Inject a recorder or `RequestExecutor.middleware(fn)` here. */
|
||||
readonly layer?: Layer.Layer<RequestExecutor.Service>
|
||||
}
|
||||
|
||||
export interface RunOptions {
|
||||
readonly signal?: AbortSignal
|
||||
}
|
||||
|
||||
export type Services = AIClient.Services
|
||||
|
||||
/**
|
||||
* Promise view of a `Generation`. Its fields are a snapshot taken when the handle was created; `refresh()` resolves to a
|
||||
* new handle rather than updating this one.
|
||||
*/
|
||||
export type GenerationHandle<Response> = Snapshot & {
|
||||
/** Serializable JSON; pass it back to `resume` from another process. */
|
||||
readonly token: unknown
|
||||
readonly await: (options?: AwaitOptions & RunOptions) => Promise<Response>
|
||||
/** Status observations until the first terminal one, polling like `await`; abort throws `signal.reason`. */
|
||||
readonly events: (options?: AwaitOptions & RunOptions) => AsyncIterable<Event>
|
||||
/** The result without polling; fails when the generation has not completed. */
|
||||
readonly result: (options?: RunOptions) => Promise<Response>
|
||||
readonly refresh: (options?: RunOptions) => Promise<GenerationHandle<Response>>
|
||||
readonly cancel: (options?: RunOptions) => Promise<void>
|
||||
}
|
||||
|
||||
// Fails with `signal.reason` so aborted calls reject and aborted streams throw like `fetch`: an `AbortError` by default.
|
||||
const abortEffect = (signal: AbortSignal | undefined) =>
|
||||
signal === undefined
|
||||
? Effect.never
|
||||
: Effect.callback<never, unknown>((resume) => {
|
||||
if (signal.aborted) {
|
||||
resume(Effect.fail(signal.reason))
|
||||
return
|
||||
}
|
||||
const onAbort = () => resume(Effect.fail(signal.reason))
|
||||
signal.addEventListener("abort", onAbort, { once: true })
|
||||
return Effect.sync(() => signal.removeEventListener("abort", onAbort))
|
||||
})
|
||||
|
||||
export const make = (options: Options = {}) => {
|
||||
const runtime = ManagedRuntime.make(AIClient.layerWith(options.layer ?? RequestExecutor.fetchLayer))
|
||||
|
||||
/** Run any package Effect (for example `LLMClient.compact(...)`) inside this runtime. */
|
||||
const run = <A, E>(effect: Effect.Effect<A, E, Services>, options?: RunOptions) =>
|
||||
runtime.runPromise(Effect.raceFirst(effect, abortEffect(options?.signal)))
|
||||
|
||||
const iterate = <A, E>(stream: Stream.Stream<A, E, Services>, options?: RunOptions): AsyncIterable<A> =>
|
||||
Stream.toAsyncIterable(
|
||||
Stream.unwrap(
|
||||
runtime.contextEffect.pipe(
|
||||
Effect.map(
|
||||
(context): Stream.Stream<A, unknown> =>
|
||||
stream.pipe(Stream.interruptWhen(abortEffect(options?.signal)), Stream.provideContext(context)),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
const handle = <Response>(generation: Generation<Response>): GenerationHandle<Response> => ({
|
||||
...generation.snapshot,
|
||||
token: generation.token,
|
||||
await: (options) => run(generation.await({ poll: options?.poll }), options),
|
||||
events: (options) => iterate(generation.events({ poll: options?.poll }), options),
|
||||
result: (options) => run(generation.result(), options),
|
||||
refresh: (options) => run(generation.refresh(), options).then(handle),
|
||||
cancel: (options) => run(generation.cancel(), options),
|
||||
})
|
||||
|
||||
return {
|
||||
run,
|
||||
/** Decoded asset bytes, downloading `url` sources through the executor. */
|
||||
bytes: (asset: Media.Asset, options?: RunOptions) => run(asset.bytes(), options),
|
||||
base64: (asset: Media.Asset, options?: RunOptions) => run(asset.base64(), options),
|
||||
/** Pull a `url` asset into owned bytes before the provider URL expires. */
|
||||
materialize: (asset: Media.Asset, options?: RunOptions) => run(asset.materialize(), options),
|
||||
/** Read a file into an asset like `Media.file`: sniffed media type, then the extension's. */
|
||||
file: async (path: string, options?: Media.AssetOptions & RunOptions) => {
|
||||
const { readFile } = await import("node:fs/promises")
|
||||
return run(
|
||||
Effect.tryPromise({
|
||||
try: (signal) => readFile(path, { signal }),
|
||||
catch: (cause) => fileError(`Failed to read media file ${path}`, cause),
|
||||
}).pipe(
|
||||
Effect.map((buffer) => {
|
||||
const data = new Uint8Array(buffer)
|
||||
return Media.bytes(data, fileMediaType(data, path), options)
|
||||
}),
|
||||
),
|
||||
options,
|
||||
)
|
||||
},
|
||||
/** Write an asset's bytes like `Media.write`, downloading `url` sources through the executor. */
|
||||
write: async (asset: Media.Asset, path: string, options?: RunOptions) => {
|
||||
const { writeFile } = await import("node:fs/promises")
|
||||
return run(
|
||||
asset.bytes().pipe(
|
||||
Effect.flatMap((data) =>
|
||||
Effect.tryPromise({
|
||||
try: (signal) => writeFile(path, data, { signal }),
|
||||
catch: (cause) => fileError(`Failed to write media file ${path}`, cause),
|
||||
}),
|
||||
),
|
||||
),
|
||||
options,
|
||||
)
|
||||
},
|
||||
llm: {
|
||||
request: LLM.request,
|
||||
generate: <const Model extends LanguageModel>(input: RequestInput<Model> | LLMRequest, options?: RunOptions) =>
|
||||
run(LLM.generate(input), options),
|
||||
stream: <const Model extends LanguageModel>(input: RequestInput<Model> | LLMRequest, options?: RunOptions) =>
|
||||
iterate(LLM.stream(input), options),
|
||||
},
|
||||
image: {
|
||||
request: Image.request,
|
||||
generate: <const Model extends ImageModel>(
|
||||
input: ImageRequestInput<Model> | ImageRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => run(Image.generate(input, { poll: options?.poll }), options),
|
||||
stream: <const Model extends ImageModel>(
|
||||
input: ImageRequestInput<Model> | ImageRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => iterate(Image.stream(input, { poll: options?.poll }), options),
|
||||
start: <const Model extends ImageModel>(input: ImageRequestInput<Model> | ImageRequest, options?: RunOptions) =>
|
||||
run(Image.start(input), options).then(handle),
|
||||
resume: (model: ImageModel, token: unknown, options?: RunOptions) =>
|
||||
run(Image.resume(model, token), options).then(handle),
|
||||
},
|
||||
video: {
|
||||
request: Video.request,
|
||||
start: <const Model extends VideoModel>(input: VideoRequestInput<Model> | VideoRequest, options?: RunOptions) =>
|
||||
run(Video.start(input), options).then(handle),
|
||||
generate: <const Model extends VideoModel>(
|
||||
input: VideoRequestInput<Model> | VideoRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => run(Video.generate(input, { poll: options?.poll }), options),
|
||||
resume: (model: VideoModel, token: unknown, options?: RunOptions) =>
|
||||
run(Video.resume(model, token), options).then(handle),
|
||||
stream: <const Model extends VideoModel>(
|
||||
input: VideoRequestInput<Model> | VideoRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => iterate(Video.stream(input, { poll: options?.poll }), options),
|
||||
},
|
||||
speech: {
|
||||
request: Speech.request,
|
||||
generate: <const Model extends SpeechModel>(
|
||||
input: SpeechRequestInput<Model> | SpeechRequest,
|
||||
options?: RunOptions,
|
||||
) => run(Speech.generate(input), options),
|
||||
stream: <const Model extends SpeechModel>(
|
||||
input: SpeechRequestInput<Model> | SpeechRequest,
|
||||
options?: RunOptions,
|
||||
) => iterate(Speech.stream(input), options),
|
||||
},
|
||||
transcription: {
|
||||
request: Transcription.request,
|
||||
generate: <const Model extends TranscriptionModel>(
|
||||
input: TranscriptionRequestInput<Model> | TranscriptionRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => run(Transcription.generate(input, { poll: options?.poll }), options),
|
||||
stream: <const Model extends TranscriptionModel>(
|
||||
input: TranscriptionRequestInput<Model> | TranscriptionRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => iterate(Transcription.stream(input, { poll: options?.poll }), options),
|
||||
start: <const Model extends TranscriptionModel>(
|
||||
input: TranscriptionRequestInput<Model> | TranscriptionRequest,
|
||||
options?: RunOptions,
|
||||
) => run(Transcription.start(input), options).then(handle),
|
||||
resume: (model: TranscriptionModel, token: unknown, options?: RunOptions) =>
|
||||
run(Transcription.resume(model, token), options).then(handle),
|
||||
},
|
||||
decision: {
|
||||
request: Decision.request,
|
||||
generate: <const Model extends DecisionModel, const Questions extends DecisionQuestions>(
|
||||
input: DecisionRequestInput<Model, Questions>,
|
||||
options?: RunOptions,
|
||||
) => run(Decision.generate(input), options),
|
||||
},
|
||||
dispose: () => runtime.dispose(),
|
||||
}
|
||||
}
|
||||
|
||||
export type Client = ReturnType<typeof make>
|
||||
|
||||
const fileError = (message: string, cause: unknown) =>
|
||||
new AIError({ reason: new InvalidRequestError({ message, cause }) })
|
||||
|
||||
/** Default client over `RequestExecutor.fetchLayer` for scripts; the runtime builds its layer on first use. */
|
||||
export const ai = make()
|
||||
|
||||
export * as AI from "./index.js"
|
||||
|
|
|
|||
|
|
@ -1,218 +0,0 @@
|
|||
import { Effect, Layer, ManagedRuntime, Stream } from "effect"
|
||||
import { AIClient } from "./ai-client.js"
|
||||
import { Decision, type DecisionModel, type DecisionQuestions, type DecisionRequestInput } from "./decision.js"
|
||||
import type { AwaitOptions, Event, Generation, Snapshot } from "./generation.js"
|
||||
import { Image, type ImageModel, type ImageRequest, type ImageRequestInput } from "./image.js"
|
||||
import { LLM } from "./index.js"
|
||||
import { Media } from "./media.js"
|
||||
import { RequestExecutor } from "./route/executor.js"
|
||||
import { AIError, InvalidRequestError, LanguageModel, type LLMRequest } from "./schema/index.js"
|
||||
import type { RequestInput } from "./llm.js"
|
||||
import { Speech, type SpeechModel, type SpeechRequest, type SpeechRequestInput } from "./speech.js"
|
||||
import {
|
||||
Transcription,
|
||||
type TranscriptionModel,
|
||||
type TranscriptionRequest,
|
||||
type TranscriptionRequestInput,
|
||||
} from "./transcription.js"
|
||||
import { fileMediaType } from "./utils/media-type.js"
|
||||
import { Video, type VideoModel, type VideoRequest, type VideoRequestInput } from "./video.js"
|
||||
|
||||
/**
|
||||
* Promise-first entrypoint for scripts and non-Effect callers. One `ManagedRuntime` hosts the LLM, image, video, speech,
|
||||
* transcription and decision clients over a request executor; every method runs the corresponding Effect API and rethrows
|
||||
* `AIError` unchanged. `file` and `write` load `node:fs/promises` on first use, so importing this module does not.
|
||||
*/
|
||||
export interface Options {
|
||||
/** Executor layer; defaults to `RequestExecutor.fetchLayer`. Inject a recorder or `RequestExecutor.middleware(fn)` here. */
|
||||
readonly layer?: Layer.Layer<RequestExecutor.Service>
|
||||
}
|
||||
|
||||
export interface RunOptions {
|
||||
readonly signal?: AbortSignal
|
||||
}
|
||||
|
||||
export type Services = AIClient.Services
|
||||
|
||||
/**
|
||||
* Promise view of a `Generation`. Its fields are a snapshot taken when the handle was created; `refresh()` resolves to a
|
||||
* new handle rather than updating this one.
|
||||
*/
|
||||
export type GenerationHandle<Response> = Snapshot & {
|
||||
/** Serializable JSON; pass it back to `resume` from another process. */
|
||||
readonly token: unknown
|
||||
readonly await: (options?: AwaitOptions & RunOptions) => Promise<Response>
|
||||
/** Status observations until the first terminal one, polling like `await`; abort throws `signal.reason`. */
|
||||
readonly events: (options?: AwaitOptions & RunOptions) => AsyncIterable<Event>
|
||||
/** The result without polling; fails when the generation has not completed. */
|
||||
readonly result: (options?: RunOptions) => Promise<Response>
|
||||
readonly refresh: (options?: RunOptions) => Promise<GenerationHandle<Response>>
|
||||
readonly cancel: (options?: RunOptions) => Promise<void>
|
||||
}
|
||||
|
||||
// Fails with `signal.reason` so aborted calls reject and aborted streams throw like `fetch`: an `AbortError` by default.
|
||||
const abortEffect = (signal: AbortSignal | undefined) =>
|
||||
signal === undefined
|
||||
? Effect.never
|
||||
: Effect.callback<never, unknown>((resume) => {
|
||||
if (signal.aborted) {
|
||||
resume(Effect.fail(signal.reason))
|
||||
return
|
||||
}
|
||||
const onAbort = () => resume(Effect.fail(signal.reason))
|
||||
signal.addEventListener("abort", onAbort, { once: true })
|
||||
return Effect.sync(() => signal.removeEventListener("abort", onAbort))
|
||||
})
|
||||
|
||||
export const make = (options: Options = {}) => {
|
||||
const runtime = ManagedRuntime.make(AIClient.layerWith(options.layer ?? RequestExecutor.fetchLayer))
|
||||
|
||||
/** Run any package Effect (for example `LLMClient.compact(...)`) inside this runtime. */
|
||||
const run = <A, E>(effect: Effect.Effect<A, E, Services>, options?: RunOptions) =>
|
||||
runtime.runPromise(Effect.raceFirst(effect, abortEffect(options?.signal)))
|
||||
|
||||
const iterate = <A, E>(stream: Stream.Stream<A, E, Services>, options?: RunOptions): AsyncIterable<A> =>
|
||||
Stream.toAsyncIterable(
|
||||
Stream.unwrap(
|
||||
runtime.contextEffect.pipe(
|
||||
Effect.map(
|
||||
(context): Stream.Stream<A, unknown> =>
|
||||
stream.pipe(Stream.interruptWhen(abortEffect(options?.signal)), Stream.provideContext(context)),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
const handle = <Response>(generation: Generation<Response>): GenerationHandle<Response> => ({
|
||||
...generation.snapshot,
|
||||
token: generation.token,
|
||||
await: (options) => run(generation.await({ poll: options?.poll }), options),
|
||||
events: (options) => iterate(generation.events({ poll: options?.poll }), options),
|
||||
result: (options) => run(generation.result(), options),
|
||||
refresh: (options) => run(generation.refresh(), options).then(handle),
|
||||
cancel: (options) => run(generation.cancel(), options),
|
||||
})
|
||||
|
||||
return {
|
||||
run,
|
||||
/** Decoded asset bytes, downloading `url` sources through the executor. */
|
||||
bytes: (asset: Media.Asset, options?: RunOptions) => run(asset.bytes(), options),
|
||||
base64: (asset: Media.Asset, options?: RunOptions) => run(asset.base64(), options),
|
||||
/** Pull a `url` asset into owned bytes before the provider URL expires. */
|
||||
materialize: (asset: Media.Asset, options?: RunOptions) => run(asset.materialize(), options),
|
||||
/** Read a file into an asset like `Media.file`: sniffed media type, then the extension's. */
|
||||
file: async (path: string, options?: Media.AssetOptions & RunOptions) => {
|
||||
const { readFile } = await import("node:fs/promises")
|
||||
return run(
|
||||
Effect.tryPromise({
|
||||
try: (signal) => readFile(path, { signal }),
|
||||
catch: (cause) => fileError(`Failed to read media file ${path}`, cause),
|
||||
}).pipe(
|
||||
Effect.map((buffer) => {
|
||||
const data = new Uint8Array(buffer)
|
||||
return Media.bytes(data, fileMediaType(data, path), options)
|
||||
}),
|
||||
),
|
||||
options,
|
||||
)
|
||||
},
|
||||
/** Write an asset's bytes like `Media.write`, downloading `url` sources through the executor. */
|
||||
write: async (asset: Media.Asset, path: string, options?: RunOptions) => {
|
||||
const { writeFile } = await import("node:fs/promises")
|
||||
return run(
|
||||
asset.bytes().pipe(
|
||||
Effect.flatMap((data) =>
|
||||
Effect.tryPromise({
|
||||
try: (signal) => writeFile(path, data, { signal }),
|
||||
catch: (cause) => fileError(`Failed to write media file ${path}`, cause),
|
||||
}),
|
||||
),
|
||||
),
|
||||
options,
|
||||
)
|
||||
},
|
||||
llm: {
|
||||
request: LLM.request,
|
||||
generate: <const Model extends LanguageModel>(input: RequestInput<Model> | LLMRequest, options?: RunOptions) =>
|
||||
run(LLM.generate(input), options),
|
||||
stream: <const Model extends LanguageModel>(input: RequestInput<Model> | LLMRequest, options?: RunOptions) =>
|
||||
iterate(LLM.stream(input), options),
|
||||
},
|
||||
image: {
|
||||
request: Image.request,
|
||||
generate: <const Model extends ImageModel>(
|
||||
input: ImageRequestInput<Model> | ImageRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => run(Image.generate(input, { poll: options?.poll }), options),
|
||||
stream: <const Model extends ImageModel>(
|
||||
input: ImageRequestInput<Model> | ImageRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => iterate(Image.stream(input, { poll: options?.poll }), options),
|
||||
start: <const Model extends ImageModel>(input: ImageRequestInput<Model> | ImageRequest, options?: RunOptions) =>
|
||||
run(Image.start(input), options).then(handle),
|
||||
resume: (model: ImageModel, token: unknown, options?: RunOptions) =>
|
||||
run(Image.resume(model, token), options).then(handle),
|
||||
},
|
||||
video: {
|
||||
request: Video.request,
|
||||
start: <const Model extends VideoModel>(input: VideoRequestInput<Model> | VideoRequest, options?: RunOptions) =>
|
||||
run(Video.start(input), options).then(handle),
|
||||
generate: <const Model extends VideoModel>(
|
||||
input: VideoRequestInput<Model> | VideoRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => run(Video.generate(input, { poll: options?.poll }), options),
|
||||
resume: (model: VideoModel, token: unknown, options?: RunOptions) =>
|
||||
run(Video.resume(model, token), options).then(handle),
|
||||
stream: <const Model extends VideoModel>(
|
||||
input: VideoRequestInput<Model> | VideoRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => iterate(Video.stream(input, { poll: options?.poll }), options),
|
||||
},
|
||||
speech: {
|
||||
request: Speech.request,
|
||||
generate: <const Model extends SpeechModel>(
|
||||
input: SpeechRequestInput<Model> | SpeechRequest,
|
||||
options?: RunOptions,
|
||||
) => run(Speech.generate(input), options),
|
||||
stream: <const Model extends SpeechModel>(
|
||||
input: SpeechRequestInput<Model> | SpeechRequest,
|
||||
options?: RunOptions,
|
||||
) => iterate(Speech.stream(input), options),
|
||||
},
|
||||
transcription: {
|
||||
request: Transcription.request,
|
||||
generate: <const Model extends TranscriptionModel>(
|
||||
input: TranscriptionRequestInput<Model> | TranscriptionRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => run(Transcription.generate(input, { poll: options?.poll }), options),
|
||||
stream: <const Model extends TranscriptionModel>(
|
||||
input: TranscriptionRequestInput<Model> | TranscriptionRequest,
|
||||
options?: AwaitOptions & RunOptions,
|
||||
) => iterate(Transcription.stream(input, { poll: options?.poll }), options),
|
||||
start: <const Model extends TranscriptionModel>(
|
||||
input: TranscriptionRequestInput<Model> | TranscriptionRequest,
|
||||
options?: RunOptions,
|
||||
) => run(Transcription.start(input), options).then(handle),
|
||||
resume: (model: TranscriptionModel, token: unknown, options?: RunOptions) =>
|
||||
run(Transcription.resume(model, token), options).then(handle),
|
||||
},
|
||||
decision: {
|
||||
request: Decision.request,
|
||||
generate: <const Model extends DecisionModel, const Questions extends DecisionQuestions>(
|
||||
input: DecisionRequestInput<Model, Questions>,
|
||||
options?: RunOptions,
|
||||
) => run(Decision.generate(input), options),
|
||||
},
|
||||
dispose: () => runtime.dispose(),
|
||||
}
|
||||
}
|
||||
|
||||
export type Client = ReturnType<typeof make>
|
||||
|
||||
const fileError = (message: string, cause: unknown) =>
|
||||
new AIError({ reason: new InvalidRequestError({ message, cause }) })
|
||||
|
||||
/** Default client over `RequestExecutor.fetchLayer` for scripts; the runtime builds its layer on first use. */
|
||||
export const ai = make()
|
||||
|
||||
export * as AI from "./promise.js"
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { Effect, Schema, Stream } from "effect"
|
||||
import { LLM, LLMRequest, LLMResponse } from "../src/index.js"
|
||||
import { LLM, LLMRequest, LLMResponse } from "../src/effect.js"
|
||||
import { Route, Endpoint, LLMClient, Protocol, type FramingDef } from "../src/route.js"
|
||||
import { compileRequest } from "../src/route/client.js"
|
||||
import { LanguageModel } from "../src/schema/index.js"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { ConfigProvider, Effect } from "effect"
|
||||
import { Headers } from "effect/http"
|
||||
import { LLM } from "../src/index.js"
|
||||
import { LLM } from "../src/effect.js"
|
||||
import { Auth } from "../src/route/auth.js"
|
||||
import * as OpenAIChat from "../src/protocols/openai-chat.js"
|
||||
import { LanguageModel } from "../src/schema/index.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { CacheHint, CompactionPart, LLM, Message, ProviderID, ToolCallPart } from "../src/index.js"
|
||||
import { CacheHint, CompactionPart, LLM, Message, ProviderID, ToolCallPart } from "../src/effect.js"
|
||||
import { Auth } from "../src/route.js"
|
||||
import { compileRequest } from "../src/route/client.js"
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { FetchHttpClient } from "effect/http"
|
||||
import { LLM, LLMRequest, Message } from "../src/index.js"
|
||||
import { LLM, LLMRequest, Message } from "../src/effect.js"
|
||||
import { LLMClient } from "../src/route/client.js"
|
||||
import { OpenAI } from "../src/providers.js"
|
||||
import { testEffect } from "./lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { expect, test } from "bun:test"
|
||||
import { Effect, Schema } from "effect"
|
||||
import { CompactionPart, CompactionResponse, LLMEvent, LLMResponse, Message, ProviderID } from "../src/schema/index.js"
|
||||
import { LLM, LLMClient, LLMRequest, LanguageModel } from "../src/index.js"
|
||||
import { LLM, LLMClient, LLMRequest, LanguageModel } from "../src/effect.js"
|
||||
import { OpenAI, Anthropic } from "../src/providers.js"
|
||||
import { testEffect } from "./lib/effect.js"
|
||||
import { fixedResponse } from "./lib/http.js"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import {
|
|||
ToolDefinition,
|
||||
ToolNamespace,
|
||||
mergeProviderOptions,
|
||||
} from "../src/index.js"
|
||||
} from "../src/effect.js"
|
||||
import { AnthropicMessages, OpenAIChat, OpenAIResponses } from "../src/protocols.js"
|
||||
import { Auth, LLMClient } from "../src/route.js"
|
||||
import { compileRequest } from "../src/route/client.js"
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
ToolResultPart,
|
||||
type ContentPart,
|
||||
type LanguageModel,
|
||||
} from "../src/index.js"
|
||||
} from "../src/effect.js"
|
||||
|
||||
export const basicContinuation = ["system", "user-text", "assistant-text", "user-follow-up"] as const
|
||||
export const toolContinuation = ["tool-call", "tool-result"] as const
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { HttpClientRequest } from "effect/http"
|
||||
import { Decision, DecisionClient, Media } from "../src/index.js"
|
||||
import { Decision, DecisionClient, Media } from "../src/effect.js"
|
||||
import {
|
||||
Baseten,
|
||||
CloudflareWorkersAI,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
DecisionModel,
|
||||
type DecisionRequestInput,
|
||||
type DecisionModelRoute,
|
||||
} from "../src/index.js"
|
||||
} from "../src/effect.js"
|
||||
import type { Service } from "../src/decision-client.js"
|
||||
import { Baseten, OpenAI, OpenCode, OpenRouter, TypeSafeAI } from "../src/providers.js"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, Message, ToolCallPart } from "../src/index.js"
|
||||
import { LLM, Message, ToolCallPart } from "../src/effect.js"
|
||||
import { Auth, LLMClient } from "../src/route.js"
|
||||
import { compileRequest } from "../src/route/client.js"
|
||||
import { AnthropicMessages } from "../src/protocols/anthropic-messages.js"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { LLM } from "../src/index.js"
|
||||
import { LLM } from "../src/effect.js"
|
||||
import * as OpenAIChat from "../src/protocols/openai-chat.js"
|
||||
import { Endpoint } from "../src/route.js"
|
||||
import { LanguageModel } from "../src/schema/index.js"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { describe, expect } from "bun:test"
|
|||
import { Deferred, Effect, Fiber, Layer, Ref, Stream } from "effect"
|
||||
import { Headers, HttpClientError, HttpClientRequest, HttpClientResponse } from "effect/http"
|
||||
import { Socket } from "effect/socket"
|
||||
import { LLM, AIError, HttpContext, InvalidProviderOutputError, TransportError, isRetryable } from "../src/index.js"
|
||||
import { LLM, AIError, HttpContext, InvalidProviderOutputError, TransportError, isRetryable } from "../src/effect.js"
|
||||
import {
|
||||
LLMClient,
|
||||
RequestExecutor,
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import {
|
|||
TranscriptionClient,
|
||||
Video,
|
||||
VideoClient,
|
||||
} from "@opencode/ai"
|
||||
} from "@opencode/ai/effect"
|
||||
import { Route, Protocol, RequestExecutor, WebSocketTransport } from "@opencode/ai/route"
|
||||
import { Provider as ProviderSubpath } from "@opencode/ai/provider"
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { Effect, Schema } from "effect"
|
||||
import { LLM } from "../src/index.js"
|
||||
import { LLM } from "../src/effect.js"
|
||||
import * as OpenAIChat from "../src/protocols/openai-chat.js"
|
||||
import { Auth } from "../src/route.js"
|
||||
import { Tool, toDefinitions } from "../src/tool.js"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {
|
|||
type GenerationRoute,
|
||||
type GenerationSnapshot,
|
||||
type GenerationStatus,
|
||||
} from "../src/index.js"
|
||||
} from "../src/effect.js"
|
||||
import { it } from "./lib/effect.js"
|
||||
|
||||
/** In-memory generation route whose status advances through `statuses` on every poll. */
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Deferred, Effect, Fiber } from "effect"
|
||||
import * as TestClock from "effect/testing/TestClock"
|
||||
import { HttpOptions, LLM, mergeHttpOptions } from "../src/index.js"
|
||||
import { HttpOptions, LLM, mergeHttpOptions } from "../src/effect.js"
|
||||
import { LLMClient } from "../src/route.js"
|
||||
import { configure } from "../src/providers/openai.js"
|
||||
import { dynamicResponse } from "./lib/http.js"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Layer, Stream } from "effect"
|
||||
import { HttpClientRequest } from "effect/http"
|
||||
import { Image, ImageClient, Media } from "../src/index.js"
|
||||
import { Image, ImageClient, Media } from "../src/effect.js"
|
||||
import {
|
||||
BlackForestLabs,
|
||||
Fal,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
type ImageModelOptions,
|
||||
type ImageOptions,
|
||||
type ImageRequestFor,
|
||||
} from "../src/index.js"
|
||||
} from "../src/effect.js"
|
||||
import type { Service } from "../src/image-client.js"
|
||||
import { Anthropic, BlackForestLabs, Google, OpenAI, Stability, XAI, ZAI } from "../src/providers.js"
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import {
|
|||
type LanguageModel,
|
||||
type LanguageModelProviderOptions,
|
||||
type ProviderOptions,
|
||||
} from "../src/index.js"
|
||||
import { ai } from "../src/promise.js"
|
||||
} from "../src/effect.js"
|
||||
import { ai } from "../src/index.js"
|
||||
import { OpenAIChat } from "../src/protocols.js"
|
||||
|
||||
interface ExampleOptions {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { Effect, Schema, Stream } from "effect"
|
||||
import { CacheHint, LLM, LLMEvent, LLMResponse, ToolEntry, ToolNamespace } from "../src/index.js"
|
||||
import { CacheHint, LLM, LLMEvent, LLMResponse, ToolEntry, ToolNamespace } from "../src/effect.js"
|
||||
import { OpenAI } from "../src/providers.js"
|
||||
import * as OpenAIChat from "../src/protocols/openai-chat.js"
|
||||
import * as OpenAIResponses from "../src/protocols/openai-responses.js"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { NodeFileSystem } from "@effect/platform-node"
|
|||
import { Effect, Ref, Schema } from "effect"
|
||||
import { FileSystem } from "effect"
|
||||
import { HttpClientRequest } from "effect/http"
|
||||
import { AIError, LLM, Media, Message, ToolCallPart } from "../src/index.js"
|
||||
import { AIError, LLM, Media, Message, ToolCallPart } from "../src/effect.js"
|
||||
import { OpenAI } from "../src/providers.js"
|
||||
import { compileRequest } from "../src/route/client.js"
|
||||
import { it } from "./lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import { tmpdir } from "node:os"
|
|||
import { join } from "node:path"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { HttpClientRequest } from "effect/http"
|
||||
import { AIError, LLMEvent, Media, SpeechEvent, TranscriptionEvent } from "../src/index.js"
|
||||
import { AIError, LLMEvent, Media, SpeechEvent, TranscriptionEvent } from "../src/effect.js"
|
||||
import { RequestExecutor } from "../src/route.js"
|
||||
import { AI } from "../src/promise.js"
|
||||
import { AI } from "../src/index.js"
|
||||
import { AssemblyAI, OpenAI, Replicate, Runway } from "../src/providers.js"
|
||||
import { handlerLayer, json } from "./lib/http.js"
|
||||
import { sseEvents } from "./lib/sse.js"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { isContextOverflow, isContextOverflowFailure, isRetryable } from "../src/index.js"
|
||||
import { isContextOverflow, isContextOverflowFailure, isRetryable } from "../src/effect.js"
|
||||
import { AIError } from "../src/schema/index.js"
|
||||
import { classifyProviderFailure, providerErrorMessage } from "../src/provider-error.js"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { Alibaba } from "../../src/providers.js"
|
||||
|
||||
const provider = Alibaba.configure({ region: "ap-southeast-1" })
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { AnthropicCompatible } from "../../src/providers.js"
|
||||
|
||||
const model = AnthropicCompatible.configure({ baseURL: "https://example.com" }).model("claude")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { Anthropic } from "../../src/providers.js"
|
||||
|
||||
const model = Anthropic.provider.model("claude-sonnet-4-5")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { Azure } from "../../src/providers.js"
|
||||
|
||||
const model = Azure.configure({ resourceName: "example" }).responses("deployment")
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
LLM,
|
||||
LLMClient,
|
||||
LLMRequest,
|
||||
} from "../../src/index.js"
|
||||
} from "../../src/effect.js"
|
||||
import {
|
||||
Anthropic,
|
||||
Azure,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { CloudflareWorkersAI } from "../../src/providers.js"
|
||||
|
||||
const model = CloudflareWorkersAI.configure({ accountId: "account", apiKey: "test" }).model("model")
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {
|
|||
LLMRequest,
|
||||
Message,
|
||||
ProviderID,
|
||||
} from "../../src/index.js"
|
||||
} from "../../src/effect.js"
|
||||
import { OpenAI, Azure, XAI, Anthropic, OpenAICompatibleResponses } from "../../src/providers.js"
|
||||
|
||||
const openai = OpenAI.configure({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { GoogleVertexChat } from "../../src/providers.js"
|
||||
|
||||
const model = GoogleVertexChat.configure({ accessToken: "test", project: "project" }).model("gemini")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { GoogleVertexInteractions } from "../../src/providers.js"
|
||||
import { Auth } from "../../src/route/auth.js"
|
||||
import { model } from "../../src/providers/google-vertex/interactions.js"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { GoogleVertexMessages } from "../../src/providers.js"
|
||||
|
||||
const model = GoogleVertexMessages.configure({ accessToken: "test", project: "project" }).model("claude")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { GoogleVertexResponses } from "../../src/providers.js"
|
||||
|
||||
const model = GoogleVertexResponses.configure({ accessToken: "test", project: "project" }).model("gemini")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { GoogleVertex } from "../../src/providers.js"
|
||||
|
||||
const model = GoogleVertex.provider.configure({ apiKey: "test" }).model("gemini-2.5-pro")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { Google } from "../../src/providers.js"
|
||||
|
||||
const model = Google.provider.model("gemini-2.5-pro")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { MiniMax } from "../../src/providers.js"
|
||||
|
||||
const minimax = MiniMax.configure()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { Mistral } from "../../src/providers.js"
|
||||
|
||||
const selected = Mistral.provider.model("mistral-small-latest")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { Moonshot } from "../../src/providers.js"
|
||||
|
||||
const moonshot = Moonshot.configure()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { OpenAICompatibleResponses } from "../../src/providers.js"
|
||||
|
||||
const model = OpenAICompatibleResponses.configure({ baseURL: "https://example.com" }).model("model")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { OpenAICompatible } from "../../src/providers.js"
|
||||
|
||||
const model = OpenAICompatible.configure({ baseURL: "https://compatible.example/v1" }).model("test-model")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { OpenAI } from "../../src/providers.js"
|
||||
|
||||
const selected = OpenAI.responses("gpt-5")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { OpenRouter } from "../../src/providers.js"
|
||||
|
||||
const model = OpenRouter.provider.model("anthropic/claude-sonnet-4.5")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { Venice } from "../../src/providers.js"
|
||||
|
||||
LLM.request({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { VercelAIGateway } from "../../src/providers/vercel-ai-gateway.js"
|
||||
|
||||
const gateway = VercelAIGateway.configure({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { XAI } from "../../src/providers.js"
|
||||
|
||||
const model = XAI.provider.model("grok-4")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { ZAI, ZAICodingPlan } from "../../src/providers.js"
|
||||
|
||||
LLM.request({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { model } from "@opencode/ai/providers/openai"
|
||||
import { LLM } from "../src/index.js"
|
||||
import { LLM } from "../src/effect.js"
|
||||
import { Endpoint } from "../src/route/endpoint.js"
|
||||
|
||||
const configuration = (provider: string, message: string) =>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMEvent, LLMRequest, Message, ToolDefinition, Media } from "../../src/index.js"
|
||||
import { LLM, LLMEvent, LLMRequest, Message, ToolDefinition, Media } from "../../src/effect.js"
|
||||
import { Alibaba } from "../../src/providers.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Image, Media } from "../../src/index.js"
|
||||
import { Image, Media } from "../../src/effect.js"
|
||||
import { Alibaba } from "../../src/providers.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { HttpClientRequest } from "effect/http"
|
||||
import { Image, ImageClient, Media } from "../../src/index.js"
|
||||
import { Image, ImageClient, Media } from "../../src/effect.js"
|
||||
import { Alibaba } from "../../src/providers.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
import { dynamicResponse, fixedResponse } from "../lib/http.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMEvent, LLMRequest, Message, ToolDefinition, type LLMResponse } from "../../src/index.js"
|
||||
import { LLM, LLMEvent, LLMRequest, Message, ToolDefinition, type LLMResponse } from "../../src/effect.js"
|
||||
import { Alibaba } from "../../src/providers.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { expect, test } from "bun:test"
|
||||
import { ConfigProvider, Effect } from "effect"
|
||||
import { Headers } from "effect/http"
|
||||
import { Auth, LLM, LLMClient, LLMRequest, Message, ReasoningPart, ToolDefinition } from "../../src/index.js"
|
||||
import { Auth, LLM, LLMClient, LLMRequest, Message, ReasoningPart, ToolDefinition } from "../../src/effect.js"
|
||||
import { Alibaba } from "../../src/providers.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
import { Endpoint } from "../../src/route/endpoint.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect, Schema } from "effect"
|
||||
import { LLM, LLMRequest, Message } from "../../src/index.js"
|
||||
import { LLM, LLMRequest, Message } from "../../src/effect.js"
|
||||
import { LLMClient } from "../../src/route/client.js"
|
||||
import { Anthropic, GoogleVertexMessages } from "../../src/providers/index.js"
|
||||
import { testEffect } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { CacheHint, LLM, LLMRequest, Message, ToolCallPart, ToolDefinition } from "../../src/index.js"
|
||||
import { CacheHint, LLM, LLMRequest, Message, ToolCallPart, ToolDefinition } from "../../src/effect.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import * as Anthropic from "../../src/providers/anthropic.js"
|
||||
import { LARGE_CACHEABLE_SYSTEM } from "../recorded-scenarios.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, AIError, Message, ToolCallPart } from "../../src/index.js"
|
||||
import { LLM, AIError, Message, ToolCallPart } from "../../src/effect.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import * as Anthropic from "../../src/providers/anthropic.js"
|
||||
import { weatherToolName } from "../recorded-scenarios.js"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
ToolDefinition,
|
||||
Usage,
|
||||
Media,
|
||||
} from "../../src/index.js"
|
||||
} from "../../src/effect.js"
|
||||
import { Auth, Endpoint, LLMClient, Route } from "../../src/route.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
import { AnthropicMessages } from "../../src/protocols/anthropic-messages.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { AnthropicMessages } from "../../src/protocols/anthropic-messages.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Transcription } from "../../src/index.js"
|
||||
import { Transcription } from "../../src/effect.js"
|
||||
import { AssemblyAI } from "../../src/providers.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
import { TRANSCRIPT, audio, audioRecording } from "./transcription-recording.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, Message, ToolDefinition, ToolCallPart } from "../../src/index.js"
|
||||
import { LLM, Message, ToolDefinition, ToolCallPart } from "../../src/effect.js"
|
||||
import { Azure } from "../../src/providers.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { CacheHint, LLM } from "../../src/index.js"
|
||||
import { CacheHint, LLM } from "../../src/effect.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { AmazonBedrock } from "../../src/providers.js"
|
||||
import { LARGE_CACHEABLE_SYSTEM } from "../recorded-scenarios.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { CacheHint, LanguageModel, LLM, Message, ToolCallPart } from "../../src/index.js"
|
||||
import { CacheHint, LanguageModel, LLM, Message, ToolCallPart } from "../../src/effect.js"
|
||||
import { AmazonBedrock } from "../../src/providers.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMRequest, Message } from "../../src/index.js"
|
||||
import { LLM, LLMRequest, Message } from "../../src/effect.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { AmazonBedrock } from "../../src/providers.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { GenerationOptions, LanguageModel, LLM } from "../../src/index.js"
|
||||
import { GenerationOptions, LanguageModel, LLM } from "../../src/effect.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
import { AmazonBedrock } from "../../src/providers.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import {
|
|||
ToolChoice,
|
||||
ToolDefinition,
|
||||
ToolRuntime,
|
||||
} from "../../src/index.js"
|
||||
} from "../../src/effect.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
import { AmazonBedrock } from "../../src/providers.js"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { HttpClientRequest } from "effect/http"
|
||||
import { LLM, LLMEvent, LLMRequest, Message, ToolDefinition } from "../../src/index.js"
|
||||
import { LLM, LLMEvent, LLMRequest, Message, ToolDefinition } from "../../src/effect.js"
|
||||
import { AmazonBedrockMantle } from "../../src/providers.js"
|
||||
import { OpenResponses } from "../../src/protocols/open-responses.js"
|
||||
import { compileRequest, LLMClient } from "../../src/route/client.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect, Schema } from "effect"
|
||||
import { LLM, Message, ToolCallPart } from "../../src/index.js"
|
||||
import { LLM, Message, ToolCallPart } from "../../src/effect.js"
|
||||
import { AmazonBedrock } from "../../src/providers.js"
|
||||
import { BedrockConverse } from "../../src/protocols/bedrock-converse.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Image } from "../../src/index.js"
|
||||
import { Image } from "../../src/effect.js"
|
||||
import { BlackForestLabs } from "../../src/providers.js"
|
||||
import { dimensions } from "../lib/image.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Speech, SpeechEvent } from "../../src/index.js"
|
||||
import { Speech, SpeechEvent } from "../../src/effect.js"
|
||||
import { Cartesia } from "../../src/providers.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
import { TEXT, collectSpeech } from "./speech-recording.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect, Stream } from "effect"
|
||||
import { LLM, LLMClient, LLMRequest } from "../../src/index.js"
|
||||
import { LLM, LLMClient, LLMRequest } from "../../src/effect.js"
|
||||
import { Azure, OpenAI } from "../../src/providers.js"
|
||||
import { testEffect } from "../lib/effect.js"
|
||||
import { dynamicResponse, fixedResponse } from "../lib/http.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Image } from "../../src/index.js"
|
||||
import { Image } from "../../src/effect.js"
|
||||
import { CloudflareWorkersAI } from "../../src/providers.js"
|
||||
import { dimensions } from "../lib/image.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { Effect, Layer } from "effect"
|
||||
import { HttpClientRequest } from "effect/http"
|
||||
import { Image, ImageClient, Media } from "../../src/index.js"
|
||||
import { Image, ImageClient, Media } from "../../src/effect.js"
|
||||
import { CloudflareWorkersAI } from "../../src/providers.js"
|
||||
import { ProviderConfigurationError } from "../../src/schema/index.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { ConfigProvider, Effect, Schema } from "effect"
|
||||
import { HttpClientRequest } from "effect/http"
|
||||
import { LLM, LLMEvent } from "../../src/index.js"
|
||||
import { LLM, LLMEvent } from "../../src/effect.js"
|
||||
import { CloudflareAIGateway } from "../../src/providers/cloudflare-ai-gateway.js"
|
||||
import { CloudflareWorkersAI } from "../../src/providers/cloudflare-workers-ai.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMEvent, LLMRequest, SystemPart } from "../../src/index.js"
|
||||
import { LLM, LLMEvent, LLMRequest, SystemPart } from "../../src/effect.js"
|
||||
import { Cohere } from "../../src/providers/cohere.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { expectWeatherToolLoop, goldenWeatherToolLoopRequest, runWeatherToolLoop } from "../recorded-scenarios.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect, test } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMClient, LLMEvent, Media, Message, SystemPart, isRetryable } from "../../src/index.js"
|
||||
import { LLM, LLMClient, LLMEvent, Media, Message, SystemPart, isRetryable } from "../../src/effect.js"
|
||||
import { Cohere } from "../../src/providers/cohere.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect, Stream } from "effect"
|
||||
import { LLM, LLMRequest, Message } from "../../src/index.js"
|
||||
import { LLM, LLMRequest, Message } from "../../src/effect.js"
|
||||
import { LLMClient, WebSocketTransport } from "../../src/route.js"
|
||||
import { OpenAI } from "../../src/providers.js"
|
||||
import { testEffect } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMRequest, Message } from "../../src/index.js"
|
||||
import { LLM, LLMRequest, Message } from "../../src/effect.js"
|
||||
import { LLMClient } from "../../src/route/client.js"
|
||||
import { OpenAI, XAI, Anthropic } from "../../src/providers.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect, Schema } from "effect"
|
||||
import { LLM, LLMRequest, Message } from "../../src/index.js"
|
||||
import { LLM, LLMRequest, Message } from "../../src/effect.js"
|
||||
import { LLMClient } from "../../src/route/client.js"
|
||||
import { OpenAI, Azure, XAI } from "../../src/providers/index.js"
|
||||
import { testEffect } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, Message } from "../../src/index.js"
|
||||
import { LLM, Message } from "../../src/effect.js"
|
||||
import { OpenAI } from "../../src/providers.js"
|
||||
import { OpenResponses } from "../../src/protocols/open-responses.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Decision, type DecisionModel, type DecisionOptions } from "../../src/index.js"
|
||||
import { Decision, type DecisionModel, type DecisionOptions } from "../../src/effect.js"
|
||||
import {
|
||||
Baseten,
|
||||
CloudflareAIGateway,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Speech } from "../../src/index.js"
|
||||
import { Speech } from "../../src/effect.js"
|
||||
import { Deepgram } from "../../src/providers.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
import { TEXT, collectSpeech } from "./speech-recording.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Stream } from "effect"
|
||||
import { Transcription } from "../../src/index.js"
|
||||
import { Transcription } from "../../src/effect.js"
|
||||
import { Deepgram } from "../../src/providers.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
import { TRANSCRIPT, audio, audioRecording, dialog } from "./transcription-recording.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMRequest } from "../../src/index.js"
|
||||
import { LLM, LLMRequest } from "../../src/effect.js"
|
||||
import { DigitalOcean } from "../../src/providers/digitalocean.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { CacheHint, LLM } from "../../src/index.js"
|
||||
import { CacheHint, LLM } from "../../src/effect.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
import { DigitalOcean } from "../../src/providers/digitalocean.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Speech, SpeechEvent } from "../../src/index.js"
|
||||
import { Speech, SpeechEvent } from "../../src/effect.js"
|
||||
import { ElevenLabs } from "../../src/providers.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
import { TEXT, collectSpeech } from "./speech-recording.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect, Stream } from "effect"
|
||||
import { Transcription } from "../../src/index.js"
|
||||
import { Transcription } from "../../src/effect.js"
|
||||
import { ElevenLabs } from "../../src/providers.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
import { TRANSCRIPT, audio, audioRecording, dialog } from "./transcription-recording.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, Message, ToolCallPart } from "../../src/index.js"
|
||||
import { LLM, Message, ToolCallPart } from "../../src/effect.js"
|
||||
import { OpenAIChat } from "../../src/protocols/openai-chat.js"
|
||||
import { OpenAIResponses } from "../../src/protocols/openai-responses.js"
|
||||
import { Auth } from "../../src/route/auth.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { Anthropic, Google, OpenAI } from "../../src/providers.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { it } from "../lib/effect.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { expect } from "bun:test"
|
||||
import { Effect, Schema } from "effect"
|
||||
import { LLM, LLMRequest, Message, ToolDefinition } from "../../src/index.js"
|
||||
import { LLM, LLMRequest, Message, ToolDefinition } from "../../src/effect.js"
|
||||
import { LLMClient, Route } from "../../src/route/client.js"
|
||||
import { Auth } from "../../src/route/auth.js"
|
||||
import { Endpoint } from "../../src/route/endpoint.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Image } from "../../src/index.js"
|
||||
import { Image } from "../../src/effect.js"
|
||||
import { Fal } from "../../src/providers.js"
|
||||
import { dimensions } from "../lib/image.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { Video } from "../../src/index.js"
|
||||
import { Video } from "../../src/effect.js"
|
||||
import { Fal } from "../../src/providers.js"
|
||||
import { recordedTests } from "../recorded-test.js"
|
||||
import { queuedPoll } from "./queued-recording.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM } from "../../src/index.js"
|
||||
import { LLM } from "../../src/effect.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import * as Google from "../../src/providers/google.js"
|
||||
import { LARGE_CACHEABLE_SYSTEM } from "../recorded-scenarios.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect } from "bun:test"
|
||||
import { Effect } from "effect"
|
||||
import { LLM, LLMEvent, LLMRequest, Message, ToolRuntime, toDefinitions } from "../../src/index.js"
|
||||
import { LLM, LLMEvent, LLMRequest, Message, ToolRuntime, toDefinitions } from "../../src/effect.js"
|
||||
import * as OpenAICompatible from "../../src/providers/openai-compatible.js"
|
||||
import { LLMClient } from "../../src/route.js"
|
||||
import { compileRequest } from "../../src/route/client.js"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue