Buckets:
| export * as OpenCode from "./opencode" | |
| import { Context, Effect, Layer } from "effect" | |
| import { Catalog } from "../catalog" | |
| import { Database } from "../database/database" | |
| import { EventV2 } from "../event" | |
| import { LocationServiceMap } from "../location-layer" | |
| import { PluginBoot } from "../plugin/boot" | |
| import { ProjectV2 } from "../project" | |
| import { SessionV2 } from "../session" | |
| import * as SessionExecutionLocal from "../session/execution/local" | |
| import { SessionProjector } from "../session/projector" | |
| import { SessionStore } from "../session/store" | |
| import { ApplicationTools } from "../tool/application-tools" | |
| import { Session } from "./session" | |
| import { Tool } from "./tool" | |
| export interface Interface { | |
| readonly sessions: Session.Interface | |
| readonly tools: Tool.Interface | |
| } | |
| /** Intentional public native API for Effect applications embedding OpenCode. */ | |
| export class Service extends Context.Service<Service, Interface>()("@opencode/public/OpenCode") {} | |
| class SessionModelValidation extends Context.Service< | |
| SessionModelValidation, | |
| { | |
| readonly validate: ( | |
| input: Session.SwitchModelInput & { readonly location: Session.Info["location"] }, | |
| ) => Effect.Effect<void, Session.ModelUnavailableError | Session.VariantUnavailableError> | |
| } | |
| >()("@opencode/public/OpenCode/SessionModelValidation") {} | |
| const ApplicationToolsLayer = ApplicationTools.layer | |
| const LocationServicesLayer = LocationServiceMap.layer.pipe(Layer.provide(ApplicationToolsLayer)) | |
| const SessionModelValidationLayer = Layer.effect( | |
| SessionModelValidation, | |
| Effect.gen(function* () { | |
| const locations = yield* LocationServiceMap | |
| return SessionModelValidation.of({ | |
| validate: Effect.fn("OpenCode.sessions.validateModel")(function* (input) { | |
| yield* Effect.gen(function* () { | |
| yield* (yield* PluginBoot.Service).wait() | |
| const catalog = yield* Catalog.Service | |
| const model = (yield* catalog.model.available()).find( | |
| (model) => model.providerID === input.model.providerID && model.id === input.model.id, | |
| ) | |
| if (!model) | |
| return yield* new Session.ModelUnavailableError({ | |
| providerID: input.model.providerID, | |
| modelID: input.model.id, | |
| }) | |
| if ( | |
| input.model.variant !== undefined && | |
| input.model.variant !== "default" && | |
| !model.variants.some((variant) => variant.id === input.model.variant) | |
| ) | |
| return yield* new Session.VariantUnavailableError({ | |
| providerID: input.model.providerID, | |
| modelID: input.model.id, | |
| variant: input.model.variant, | |
| }) | |
| }).pipe(Effect.provide(locations.get(input.location))) | |
| }), | |
| }) | |
| }), | |
| ) | |
| const SessionsLayer = Layer.merge( | |
| SessionV2.layer.pipe( | |
| Layer.provide(SessionProjector.layer), | |
| Layer.provide(SessionExecutionLocal.layer), | |
| Layer.provide(SessionStore.layer), | |
| Layer.provide(EventV2.layer), | |
| Layer.provide(Database.defaultLayer), | |
| Layer.provide(ProjectV2.defaultLayer), | |
| Layer.orDie, | |
| ), | |
| SessionModelValidationLayer, | |
| ).pipe(Layer.provide(LocationServicesLayer)) | |
| // TODO: Accept explicit storage so tests and embeddings can select disposable or application-owned persistence. | |
| export const layer = Layer.effect( | |
| Service, | |
| Effect.gen(function* () { | |
| const sessions = yield* SessionV2.Service | |
| const tools = yield* ApplicationTools.Service | |
| const validation = yield* SessionModelValidation | |
| return Service.of({ | |
| tools: { register: tools.register }, | |
| sessions: { | |
| create: (input) => | |
| sessions.create({ | |
| id: input.id, | |
| agent: input.agent, | |
| model: input.model, | |
| location: input.location, | |
| }), | |
| get: sessions.get, | |
| list: sessions.list, | |
| switchModel: Effect.fn("OpenCode.sessions.switchModel")(function* (input) { | |
| const session = yield* sessions.get(input.sessionID) | |
| yield* validation.validate({ ...input, location: session.location }) | |
| yield* sessions.switchModel(input) | |
| }), | |
| interrupt: sessions.interrupt, | |
| prompt: (input) => | |
| sessions.prompt({ | |
| id: input.id, | |
| sessionID: input.sessionID, | |
| prompt: input.prompt, | |
| delivery: input.delivery, | |
| }), | |
| messages: (input) => | |
| sessions.messages({ | |
| sessionID: input.sessionID, | |
| limit: input.limit, | |
| order: input.order, | |
| cursor: input.cursor, | |
| }), | |
| message: (input) => sessions.message({ sessionID: input.sessionID, messageID: input.messageID }), | |
| context: sessions.context, | |
| events: (input) => sessions.events({ sessionID: input.sessionID, after: input.after }), | |
| }, | |
| }) | |
| }), | |
| ).pipe(Layer.provide(Layer.merge(ApplicationToolsLayer, SessionsLayer))) | |
| // TODO: Add OpenCode.create(...) as the Promise facade over the same native API semantics. | |
Xet Storage Details
- Size:
- 5.01 kB
- Xet hash:
- b06933a773662c0fdde7b5f99f57fdd179807c26c66ef6873dd8e914f02d20d3
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.