feat(core): add public native API (#30828)

This commit is contained in:
Kit Langton 2026-06-04 20:49:43 -04:00 committed by GitHub
commit 773d33e282
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 220 additions and 55 deletions

View file

@ -0,0 +1,70 @@
export * as OpenCode from "./opencode"
import { Context, Effect, Layer } from "effect"
import { Database } from "../database/database"
import { EventV2 } from "../event"
import { LocationServiceMap } from "../location-layer"
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 { Session } from "./session"
export interface Interface {
readonly sessions: Session.Interface
}
/** Intentional public native API for Effect applications embedding OpenCode. */
export class Service extends Context.Service<Service, Interface>()("@opencode/public/OpenCode") {}
const SessionsLayer = SessionV2.layer.pipe(
Layer.provide(SessionProjector.layer),
Layer.provide(SessionExecutionLocal.layer),
Layer.provide(LocationServiceMap.layer),
Layer.provide(SessionStore.layer),
Layer.provide(EventV2.layer),
Layer.provide(Database.defaultLayer),
Layer.provide(ProjectV2.defaultLayer),
Layer.orDie,
)
// 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
return Service.of({
sessions: {
create: (input) =>
sessions.create({
id: input.id,
agent: input.agent,
model: input.model,
location: input.location,
}),
get: sessions.get,
list: sessions.list,
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(SessionsLayer))
// TODO: Add OpenCode.create(...) as the Promise facade over the same native API semantics.