fix(tui): stabilize reload connection state
This commit is contained in:
parent
24ab17e718
commit
8dd993d25a
16 changed files with 224 additions and 19 deletions
|
|
@ -29,6 +29,12 @@ const PluginModule = Schema.Struct({
|
|||
]),
|
||||
})
|
||||
|
||||
const PluginPackage = Schema.Struct({
|
||||
exports: Schema.optional(Schema.Unknown),
|
||||
main: Schema.optional(Schema.String),
|
||||
module: Schema.optional(Schema.String),
|
||||
})
|
||||
|
||||
export const Plugin = define({
|
||||
id: "config-plugin",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
|
|
@ -65,8 +71,30 @@ export const Plugin = define({
|
|||
symlink: true,
|
||||
})
|
||||
.pipe(Effect.orElseSucceed(() => []))
|
||||
const directories = yield* fs
|
||||
.glob("{plugin,plugins}/*", {
|
||||
cwd: entry.path,
|
||||
absolute: true,
|
||||
include: "all",
|
||||
dot: true,
|
||||
symlink: true,
|
||||
})
|
||||
.pipe(
|
||||
Effect.flatMap((items) =>
|
||||
Effect.filter(items, (item) => fs.isDir(item), {
|
||||
concurrency: "unbounded",
|
||||
}),
|
||||
),
|
||||
Effect.orElseSucceed(() => []),
|
||||
)
|
||||
const packages = yield* Effect.forEach(
|
||||
directories.sort(),
|
||||
(directory) => resolvePackageEntrypoint(fs, directory),
|
||||
{ concurrency: "unbounded" },
|
||||
).pipe(Effect.map((items) => items.filter((item): item is string => item !== undefined)))
|
||||
files.sort()
|
||||
for (const file of files) configured.push({ package: file })
|
||||
for (const file of packages) configured.push({ package: file })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,3 +117,18 @@ export const Plugin = define({
|
|||
})
|
||||
}),
|
||||
})
|
||||
|
||||
const resolvePackageEntrypoint = Effect.fnUntraced(function* (fs: FSUtil.Interface, directory: string) {
|
||||
const pkg = yield* fs.readJson(path.join(directory, "package.json")).pipe(
|
||||
Effect.flatMap(Schema.decodeUnknownEffect(PluginPackage)),
|
||||
Effect.catch(() => Effect.succeed(undefined)),
|
||||
)
|
||||
const exported = typeof pkg?.exports === "string" ? pkg.exports : undefined
|
||||
const entries = [exported, pkg?.module, pkg?.main, "index.ts", "index.js"]
|
||||
|
||||
return yield* Effect.forEach(entries, (entry) => {
|
||||
if (!entry) return Effect.succeed(undefined)
|
||||
const file = path.resolve(directory, entry)
|
||||
return fs.isFile(file).pipe(Effect.map((exists) => (exists ? file : undefined)))
|
||||
}).pipe(Effect.map((items) => items.find((item): item is string => item !== undefined)))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { Formatter, Logger, type LogLevel } from "effect"
|
||||
import path from "path"
|
||||
import { Global } from "../global"
|
||||
import { InstallationChannel, InstallationLocal } from "../installation/version"
|
||||
import { runID } from "./shared"
|
||||
|
||||
function formatter(id: string = runID) {
|
||||
|
|
@ -46,9 +47,14 @@ function format(input: unknown) {
|
|||
return /^[^\s="\\]+$/.test(value) ? value : JSON.stringify(value)
|
||||
}
|
||||
|
||||
export function fileLogger(file = path.join(Global.Path.log, "opencode.log"), id: string = runID) {
|
||||
export function file(local = InstallationLocal, channel = InstallationChannel) {
|
||||
if (!local) return path.join(Global.Path.log, "opencode.log")
|
||||
return path.join(Global.Path.log, `opencode-${channel.replace(/[^a-zA-Z0-9._-]/g, "-")}.log`)
|
||||
}
|
||||
|
||||
export function fileLogger(target = file(), id: string = runID) {
|
||||
// Do not set batchWindow to 0; it causes high idle CPU usage.
|
||||
return Logger.toFile(formatter(id), file, { flag: "a" })
|
||||
return Logger.toFile(formatter(id), target, { flag: "a" })
|
||||
}
|
||||
|
||||
const stderrLogger = Logger.make((options) => process.stderr.write(formatter().log(options) + "\n"))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { define } from "./internal"
|
||||
import type { ModelV2Info } from "@opencode-ai/sdk/v2/types"
|
||||
import { Effect, Stream } from "effect"
|
||||
import { EventV2 } from "../event"
|
||||
import { ModelV2 } from "../model"
|
||||
|
|
@ -45,6 +46,15 @@ function variants(model: ModelsDev.Model) {
|
|||
}))
|
||||
}
|
||||
|
||||
function mergeVariants(model: ModelV2Info, next: ModelV2Info["variants"]) {
|
||||
const existing = new Map(model.variants.map((variant) => [variant.id, variant]))
|
||||
const nextIDs = new Set(next.map((variant) => variant.id))
|
||||
model.variants = [
|
||||
...next.map((variant) => existing.get(variant.id) ?? variant),
|
||||
...model.variants.filter((variant) => !nextIDs.has(variant.id)),
|
||||
]
|
||||
}
|
||||
|
||||
export const ModelsDevPlugin = define({
|
||||
id: "models-dev",
|
||||
effect: Effect.fn(function* (ctx) {
|
||||
|
|
@ -111,7 +121,7 @@ export const ModelsDevPlugin = define({
|
|||
input: [...(model.modalities?.input ?? [])],
|
||||
output: [...(model.modalities?.output ?? [])],
|
||||
}
|
||||
draft.variants = variants(model)
|
||||
mergeVariants(draft, variants(model))
|
||||
draft.time.released = released(model.release_date)
|
||||
draft.cost = cost(model.cost)
|
||||
draft.status = model.status ?? "active"
|
||||
|
|
|
|||
|
|
@ -142,11 +142,16 @@ export const OpencodePlugin = define<HttpClient.HttpClient | EventV2.Service | S
|
|||
Object.assign(model.request.headers, config.headers)
|
||||
Object.assign(model.request.body, lowerer.request(withoutCredentials(config.options)))
|
||||
if (config.variants !== undefined) {
|
||||
model.variants = Object.entries(config.variants).map(([id, options]) => ({
|
||||
id: ModelV2.VariantID.make(id),
|
||||
headers: { ...(options.headers ?? {}) },
|
||||
body: lowerer.request(withoutCredentials(options)),
|
||||
}))
|
||||
for (const [id, options] of Object.entries(config.variants)) {
|
||||
const variantID = ModelV2.VariantID.make(id)
|
||||
let existing = model.variants.find((item) => item.id === variantID)
|
||||
if (!existing) {
|
||||
existing = { id: variantID, headers: {}, body: {} }
|
||||
model.variants.push(existing)
|
||||
}
|
||||
Object.assign(existing.headers, options.headers)
|
||||
Object.assign(existing.body, lowerer.request(withoutCredentials(options)))
|
||||
}
|
||||
}
|
||||
if (config.release_date !== undefined) {
|
||||
const released = Date.parse(config.release_date)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue