sync
This commit is contained in:
@@ -398,13 +398,11 @@ export namespace Agent {
|
||||
}),
|
||||
)
|
||||
|
||||
export const defaultLayer = Layer.suspend(() =>
|
||||
layer.pipe(
|
||||
Layer.provide(Provider.defaultLayer),
|
||||
Layer.provide(Auth.defaultLayer),
|
||||
Layer.provide(Config.defaultLayer),
|
||||
Layer.provide(Skill.defaultLayer),
|
||||
),
|
||||
export const defaultLayer = layer.pipe(
|
||||
Layer.provide(Provider.defaultLayer),
|
||||
Layer.provide(Auth.defaultLayer),
|
||||
Layer.provide(Config.defaultLayer),
|
||||
Layer.provide(Skill.defaultLayer),
|
||||
)
|
||||
|
||||
const { runPromise } = makeRuntime(Service, defaultLayer)
|
||||
|
||||
@@ -680,7 +680,7 @@ export const RunCommand = cmd({
|
||||
await bootstrap(process.cwd(), async () => {
|
||||
const fetchFn = (async (input: RequestInfo | URL, init?: RequestInit) => {
|
||||
const request = new Request(input, init)
|
||||
return Server.Default().app.fetch(request)
|
||||
return (await Server.Default()).app.fetch(request)
|
||||
}) as typeof globalThis.fetch
|
||||
const sdk = createOpencodeClient({ baseUrl: "http://opencode.internal", fetch: fetchFn })
|
||||
await execute(sdk)
|
||||
|
||||
@@ -138,7 +138,7 @@ export const rpc = {
|
||||
headers,
|
||||
body: input.body,
|
||||
})
|
||||
const response = await Server.Default().app.fetch(request)
|
||||
const response = await (await Server.Default()).app.fetch(request)
|
||||
const body = await response.text()
|
||||
return {
|
||||
status: response.status,
|
||||
|
||||
@@ -119,7 +119,7 @@ export namespace Plugin {
|
||||
Authorization: `Basic ${Buffer.from(`${Flag.OPENCODE_SERVER_USERNAME ?? "opencode"}:${Flag.OPENCODE_SERVER_PASSWORD}`).toString("base64")}`,
|
||||
}
|
||||
: undefined,
|
||||
fetch: async (...args) => Server.Default().app.fetch(...args),
|
||||
fetch: async (...args) => (await Server.Default()).app.fetch(...args),
|
||||
})
|
||||
const cfg = yield* config.get()
|
||||
const input: PluginInput = {
|
||||
|
||||
@@ -24,7 +24,7 @@ import { ProviderRoutes } from "./provider"
|
||||
import { EventRoutes } from "./event"
|
||||
import { WorkspaceRouterMiddleware } from "./middleware"
|
||||
|
||||
export const InstanceRoutes = (upgrade: UpgradeWebSocket) =>
|
||||
export const InstanceRoutes = (upgrade: UpgradeWebSocket): Hono =>
|
||||
new Hono()
|
||||
.use(WorkspaceRouterMiddleware(upgrade))
|
||||
.route("/project", ProjectRoutes())
|
||||
|
||||
@@ -3,19 +3,12 @@ import { Hono } from "hono"
|
||||
import { createNodeWebSocket } from "@hono/node-ws"
|
||||
import { MDNS } from "./mdns"
|
||||
import { lazy } from "@/util/lazy"
|
||||
import { AuthMiddleware, CompressionMiddleware, CorsMiddleware, ErrorMiddleware, LoggerMiddleware } from "./middleware"
|
||||
import { InstanceRoutes } from "./instance"
|
||||
import { initProjectors } from "./projectors"
|
||||
import { createAdaptorServer, type ServerType } from "@hono/node-server"
|
||||
import { ControlPlaneRoutes } from "./control"
|
||||
import { Log } from "@/util/log"
|
||||
import { UIRoutes } from "./ui"
|
||||
|
||||
// @ts-ignore This global is needed to prevent ai-sdk from logging warnings to stdout https://github.com/vercel/ai/blob/2dc67e0ef538307f21368db32d5a12345d98831b/packages/ai/src/logger/log-warnings.ts#L85
|
||||
globalThis.AI_SDK_LOG_WARNINGS = false
|
||||
|
||||
initProjectors()
|
||||
|
||||
export namespace Server {
|
||||
const log = Log.create({ service: "server" })
|
||||
|
||||
@@ -28,7 +21,20 @@ export namespace Server {
|
||||
|
||||
export const Default = lazy(() => create({}))
|
||||
|
||||
function create(opts: { cors?: string[] }) {
|
||||
async function create(opts: { cors?: string[] }) {
|
||||
const [
|
||||
{ AuthMiddleware, CompressionMiddleware, CorsMiddleware, ErrorMiddleware, LoggerMiddleware },
|
||||
,
|
||||
{ ControlPlaneRoutes },
|
||||
{ InstanceRoutes },
|
||||
{ UIRoutes },
|
||||
] = await Promise.all([
|
||||
import("./middleware"),
|
||||
import("./projectors"),
|
||||
import("./control"),
|
||||
import("./instance"),
|
||||
import("./ui"),
|
||||
])
|
||||
const app = new Hono()
|
||||
const ws = createNodeWebSocket({ app })
|
||||
return {
|
||||
@@ -50,7 +56,7 @@ export namespace Server {
|
||||
// hono-openapi can see describeRoute metadata (`.route()` wraps
|
||||
// handlers when the sub-app has a custom errorHandler, which
|
||||
// strips the metadata symbol).
|
||||
const { app } = create({})
|
||||
const { app } = await create({})
|
||||
const result = await generateSpecs(app, {
|
||||
documentation: {
|
||||
info: {
|
||||
@@ -73,7 +79,7 @@ export namespace Server {
|
||||
mdnsDomain?: string
|
||||
cors?: string[]
|
||||
}): Promise<Listener> {
|
||||
const built = create(opts)
|
||||
const built = await create(opts)
|
||||
const start = (port: number) =>
|
||||
new Promise<ServerType>((resolve, reject) => {
|
||||
const server = createAdaptorServer({ fetch: built.app.fetch })
|
||||
|
||||
@@ -16,7 +16,7 @@ const DEFAULT_CSP =
|
||||
const csp = (hash = "") =>
|
||||
`default-src 'self'; script-src 'self' 'wasm-unsafe-eval'${hash ? ` 'sha256-${hash}'` : ""}; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; media-src 'self' data:; connect-src 'self' data:`
|
||||
|
||||
export const UIRoutes = () =>
|
||||
export const UIRoutes = (): Hono =>
|
||||
new Hono().all("/*", async (c) => {
|
||||
const embeddedWebUI = await embeddedUIPromise
|
||||
const path = c.req.path
|
||||
|
||||
@@ -19,7 +19,7 @@ afterEach(async () => {
|
||||
describe("project.initGit endpoint", () => {
|
||||
test("initializes git and reloads immediately", async () => {
|
||||
await using tmp = await tmpdir()
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
const seen: { directory?: string; payload: { type: string } }[] = []
|
||||
const fn = (evt: { directory?: string; payload: { type: string } }) => {
|
||||
seen.push(evt)
|
||||
@@ -76,7 +76,7 @@ describe("project.initGit endpoint", () => {
|
||||
|
||||
test("does not reload when the project is already git", async () => {
|
||||
await using tmp = await tmpdir({ git: true })
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
const seen: { directory?: string; payload: { type: string } }[] = []
|
||||
const fn = (evt: { directory?: string; payload: { type: string } }) => {
|
||||
seen.push(evt)
|
||||
|
||||
@@ -43,7 +43,7 @@ describe("session action routes", () => {
|
||||
fn: async () => {
|
||||
const session = await Session.create({})
|
||||
const cancel = spyOn(SessionPrompt, "cancel").mockResolvedValue()
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
|
||||
const res = await app.request(`/session/${session.id}/abort`, {
|
||||
method: "POST",
|
||||
@@ -67,7 +67,7 @@ describe("session action routes", () => {
|
||||
const msg = await user(session.id, "hello")
|
||||
const busy = spyOn(SessionRunState, "assertNotBusy").mockRejectedValue(new Session.BusyError(session.id))
|
||||
const remove = spyOn(Session, "removeMessage").mockResolvedValue(msg.id)
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
|
||||
const res = await app.request(`/session/${session.id}/message/${msg.id}`, {
|
||||
method: "DELETE",
|
||||
|
||||
@@ -60,7 +60,7 @@ describe("session messages endpoint", () => {
|
||||
fn: async () => {
|
||||
const session = await Session.create({})
|
||||
const ids = await fill(session.id, 5)
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
|
||||
const a = await app.request(`/session/${session.id}/message?limit=2`)
|
||||
expect(a.status).toBe(200)
|
||||
@@ -89,7 +89,7 @@ describe("session messages endpoint", () => {
|
||||
fn: async () => {
|
||||
const session = await Session.create({})
|
||||
const ids = await fill(session.id, 3)
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
|
||||
const res = await app.request(`/session/${session.id}/message`)
|
||||
expect(res.status).toBe(200)
|
||||
@@ -109,7 +109,7 @@ describe("session messages endpoint", () => {
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const session = await Session.create({})
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
|
||||
const bad = await app.request(`/session/${session.id}/message?limit=2&before=bad`)
|
||||
expect(bad.status).toBe(400)
|
||||
@@ -131,7 +131,7 @@ describe("session messages endpoint", () => {
|
||||
fn: async () => {
|
||||
const session = await Session.create({})
|
||||
await fill(session.id, 520)
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
|
||||
const res = await app.request(`/session/${session.id}/message?limit=510`)
|
||||
expect(res.status).toBe(200)
|
||||
|
||||
@@ -21,7 +21,7 @@ describe("tui.selectSession endpoint", () => {
|
||||
const session = await Session.create({})
|
||||
|
||||
// #when
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
const response = await app.request("/tui/select-session", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -47,7 +47,7 @@ describe("tui.selectSession endpoint", () => {
|
||||
const nonExistentSessionID = "ses_nonexistent123"
|
||||
|
||||
// #when
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
const response = await app.request("/tui/select-session", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
@@ -69,7 +69,7 @@ describe("tui.selectSession endpoint", () => {
|
||||
const invalidSessionID = "invalid_session_id"
|
||||
|
||||
// #when
|
||||
const app = Server.Default().app
|
||||
const app = (await Server.Default()).app
|
||||
const response = await app.request("/tui/select-session", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
|
||||
Reference in New Issue
Block a user