chore: merge dev into v2 (#34788)

Co-authored-by: Brendan Allan <14191578+Brendonovich@users.noreply.github.com>
Co-authored-by: Kit Langton <kit.langton@gmail.com>
Co-authored-by: opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: Affan Ali <93028901+affanali2k3@users.noreply.github.com>
Co-authored-by: affanali2k3 <affanalikhanxx@gmail.com>
Co-authored-by: Frank <frank@anoma.ly>
Co-authored-by: opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com>
Co-authored-by: 𝓛𝓲𝓽𝓽𝓵𝓮 𝓕𝓻𝓪𝓷𝓴 <little-frank@opencord.local>
Co-authored-by: Aiden Cline <63023139+rekram1-node@users.noreply.github.com>
Co-authored-by: Jay V <air@live.ca>
Co-authored-by: Dax Raad <d@ironbay.co>
Co-authored-by: Aarav Sareen <96787824+arvsrn@users.noreply.github.com>
Co-authored-by: OpeOginni <107570612+OpeOginni@users.noreply.github.com>
Co-authored-by: Luke Parker <10430890+Hona@users.noreply.github.com>
Co-authored-by: Ben Guthrie <benjee.012@gmail.com>
Co-authored-by: Dax <mail@thdxr.com>
Co-authored-by: Filip <34747899+neriousy@users.noreply.github.com>
Co-authored-by: Max Anderson <max.a.anderson95@gmail.com>
Co-authored-by: Brendan Allan <git@brendonovich.dev>
Co-authored-by: Jack <jack@anoma.ly>
Co-authored-by: Shoubhit Dash <shoubhit2005@gmail.com>
Co-authored-by: Dustin Deus <deusdustin@gmail.com>
Co-authored-by: starptech <starptech@starptechs-MBP.fritz.box>
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
Co-authored-by: usrnk1 <7547651+usrnk1@users.noreply.github.com>
Co-authored-by: Jay <53023+jayair@users.noreply.github.com>
Co-authored-by: runvip <164729189+runvip@users.noreply.github.com>
Co-authored-by: opencode <opencode@sst.dev>
Co-authored-by: Julian Coy <julian@ex-machina.co>
Co-authored-by: Vladimir Glafirov <vglafirov@gitlab.com>
This commit is contained in:
James Long
2026-07-01 17:12:00 -04:00
committed by GitHub
co-authored by Brendan Allan Kit Langton opencode-agent[bot] <opencode-agent[bot]@users.noreply.github.com> Affan Ali affanali2k3 Frank opencode-agent[bot] <219766164+opencode-agent[bot]@users.noreply.github.com> 𝓛𝓲𝓽𝓽𝓵𝓮 𝓕𝓻𝓪𝓷𝓴 Aiden Cline Jay V Dax Raad Aarav Sareen OpeOginni Luke Parker Ben Guthrie Dax Filip Max Anderson Brendan Allan Jack Shoubhit Dash Dustin Deus starptech Aiden Cline usrnk1 Jay runvip opencode Julian Coy Vladimir Glafirov
parent 932a40cfd9
commit 8c94e9005f
590 changed files with 15772 additions and 5530 deletions
+1 -14
View File
@@ -153,7 +153,7 @@ export class Service extends Context.Service<Service, Interface>()("@opencode/Se
export const use = serviceUse(Service)
export const layer = Layer.effect(
const layer = Layer.effect(
Service,
Effect.gen(function* () {
const config = yield* Config.Service
@@ -544,19 +544,6 @@ export const layer = Layer.effect(
}),
)
export const defaultLayer = Layer.suspend(() =>
layer.pipe(
Layer.provide(Provider.defaultLayer),
Layer.provide(Session.defaultLayer),
Layer.provide(SessionProcessor.defaultLayer),
Layer.provide(Agent.defaultLayer),
Layer.provide(Plugin.defaultLayer),
Layer.provide(Config.defaultLayer),
Layer.provide(RuntimeFlags.defaultLayer),
Layer.provide(EventV2Bridge.defaultLayer),
),
)
export const node = LayerNode.make({
service: Service,
layer: layer,
+1 -9
View File
@@ -45,7 +45,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/Instruction") {}
export const layer: Layer.Layer<
const layer: Layer.Layer<
Service,
never,
FSUtil.Service | Config.Service | Global.Service | HttpClient.HttpClient | RuntimeFlags.Service
@@ -224,14 +224,6 @@ export const layer: Layer.Layer<
}),
)
export const defaultLayer = layer.pipe(
Layer.provide(Config.defaultLayer),
Layer.provide(Global.layer),
Layer.provide(FSUtil.defaultLayer),
Layer.provide(FetchHttpClient.layer),
Layer.provide(RuntimeFlags.defaultLayer),
)
export function loaded(messages: SessionV1.WithParts[]) {
return extract(messages)
}
+2 -17
View File
@@ -8,7 +8,7 @@ import { Context, Effect, Layer } from "effect"
import * as Stream from "effect/Stream"
import { streamText, wrapLanguageModel, type ModelMessage, type Tool } from "ai"
import type { LLMEvent } from "@opencode-ai/llm"
import { LLMClient, RequestExecutor, WebSocketExecutor } from "@opencode-ai/llm/route"
import { LLMClient } from "@opencode-ai/llm/route"
import type { LLMClientService } from "@opencode-ai/llm/route"
import { GitLabWorkflowLanguageModel } from "gitlab-ai-provider"
import { ProviderTransform } from "@/provider/transform"
@@ -384,26 +384,11 @@ const live: Layer.Layer<
}),
)
export const layer = live.pipe(Layer.provide(Permission.defaultLayer), Layer.provide(EventV2Bridge.defaultLayer))
export const defaultLayer = Layer.suspend(() =>
layer.pipe(
Layer.provide(Auth.defaultLayer),
Layer.provide(Config.defaultLayer),
Layer.provide(Provider.defaultLayer),
Layer.provide(Plugin.defaultLayer),
Layer.provide(
LLMClient.layer.pipe(Layer.provide(Layer.mergeAll(RequestExecutor.defaultLayer, WebSocketExecutor.layer))),
),
Layer.provide(RuntimeFlags.defaultLayer),
),
)
export const hasToolCalls = LLMRequestPrep.hasToolCalls
export const node = LayerNode.make({
service: Service,
layer: layer,
layer: live,
deps: [
Auth.node,
Config.node,
+1 -18
View File
@@ -78,7 +78,7 @@ type StreamEvent = LLMEvent
export class Service extends Context.Service<Service, Interface>()("@opencode/SessionProcessor") {}
export const layer = Layer.effect(
const layer = Layer.effect(
Service,
Effect.gen(function* () {
const session = yield* Session.Service
@@ -694,23 +694,6 @@ export const layer = Layer.effect(
}),
)
export const defaultLayer = Layer.suspend(() =>
layer.pipe(
Layer.provide(Session.defaultLayer),
Layer.provide(Snapshot.defaultLayer),
Layer.provide(Agent.defaultLayer),
Layer.provide(LLM.defaultLayer),
Layer.provide(Permission.defaultLayer),
Layer.provide(Plugin.defaultLayer),
Layer.provide(SessionSummary.defaultLayer),
Layer.provide(SessionStatus.defaultLayer),
Layer.provide(Image.defaultLayer),
Layer.provide(Config.defaultLayer),
Layer.provide(Database.defaultLayer),
Layer.provide(EventV2Bridge.defaultLayer),
),
)
export const node = LayerNode.make({
service: Service,
layer: layer,
+1 -35
View File
@@ -110,7 +110,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/SessionPrompt") {}
export const layer = Layer.effect(
const layer = Layer.effect(
Service,
Effect.gen(function* () {
const status = yield* SessionStatus.Service
@@ -1490,40 +1490,6 @@ export const layer = Layer.effect(
}),
)
export const defaultLayer = Layer.suspend(() =>
layer.pipe(
Layer.provide(SessionRunState.defaultLayer),
Layer.provide(SessionStatus.defaultLayer),
Layer.provide(SessionCompaction.defaultLayer),
Layer.provide(SessionProcessor.defaultLayer),
Layer.provide(Command.defaultLayer),
Layer.provide(Permission.defaultLayer),
Layer.provide(MCP.defaultLayer),
Layer.provide(LSP.defaultLayer),
Layer.provide(ToolRegistry.defaultLayer),
Layer.provide(Truncate.defaultLayer),
Layer.provide(Provider.defaultLayer),
Layer.provide(Config.defaultLayer),
Layer.provide(Instruction.defaultLayer),
Layer.provide(FSUtil.defaultLayer),
Layer.provide(Plugin.defaultLayer),
Layer.provide(Session.defaultLayer),
Layer.provide(SessionRevert.defaultLayer),
Layer.provide(SessionSummary.defaultLayer),
Layer.provide(Image.defaultLayer),
Layer.provide(
Layer.mergeAll(
Agent.defaultLayer,
Database.defaultLayer,
SystemPrompt.defaultLayer,
LLM.defaultLayer,
CrossSpawnSpawner.defaultLayer,
RuntimeFlags.defaultLayer,
EventV2Bridge.defaultLayer,
),
),
),
)
const ModelRef = Schema.Struct({
providerID: ProviderV2.ID,
modelID: ModelV2.ID,
+1 -12
View File
@@ -25,7 +25,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/SessionRevert") {}
export const layer = Layer.effect(
const layer = Layer.effect(
Service,
Effect.gen(function* () {
const sessions = yield* Session.Service
@@ -137,17 +137,6 @@ export const layer = Layer.effect(
}),
)
export const defaultLayer = Layer.suspend(() =>
layer.pipe(
Layer.provide(SessionRunState.defaultLayer),
Layer.provide(Session.defaultLayer),
Layer.provide(Snapshot.defaultLayer),
Layer.provide(Storage.defaultLayer),
Layer.provide(EventV2Bridge.defaultLayer),
Layer.provide(SessionSummary.defaultLayer),
),
)
export const node = LayerNode.make({
service: Service,
layer: layer,
+1 -3
View File
@@ -26,7 +26,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/SessionRunState") {}
export const layer = Layer.effect(
const layer = Layer.effect(
Service,
Effect.gen(function* () {
const jobs = yield* Job.Service
@@ -108,8 +108,6 @@ export const layer = Layer.effect(
}),
)
export const defaultLayer = layer.pipe(Layer.provide(Job.defaultLayer), Layer.provide(SessionStatus.defaultLayer))
const cancelJobs = Effect.fn("SessionRunState.cancelJobs")(function* (jobs: Job.Interface, sessionID: SessionID) {
const running = yield* jobs.list()
const pending = new Set<string>([sessionID])
+1 -89
View File
@@ -9,11 +9,8 @@ import { Decimal } from "decimal.js"
import type { ProviderMetadata, Usage } from "@opencode-ai/llm"
import { InstallationVersion } from "@opencode-ai/core/installation/version"
import { Database } from "@opencode-ai/core/database/database"
import { makeRuntime } from "@opencode-ai/core/effect/runtime"
import { EventV2Bridge } from "@/event-v2-bridge"
import { SessionV2 } from "@opencode-ai/core/session"
import * as SessionExecutionLocal from "@opencode-ai/core/session/execution/local"
import { locationServiceMapLayer } from "@opencode-ai/core/location-services"
import { NotFoundError } from "@/storage/storage"
import { eq } from "drizzle-orm"
@@ -46,8 +43,6 @@ import { ProviderV2 } from "@opencode-ai/core/provider"
import { ModelV2 } from "@opencode-ai/core/model"
import { SessionMessage } from "@opencode-ai/schema/session-message"
const runtime = makeRuntime(Database.Service, Database.defaultLayer)
const parentTitlePrefix = "New session - "
const childTitlePrefix = "Child session - "
@@ -488,7 +483,7 @@ export type Patch = Omit<Partial<Info>, "time" | "share" | "summary" | "revert"
permission?: Info["permission"] | null
}
export const layer: Layer.Layer<
const layer: Layer.Layer<
Service,
never,
Job.Service | RuntimeFlags.Service | Database.Service | EventV2Bridge.Service
@@ -940,19 +935,6 @@ export const layer: Layer.Layer<
}),
)
export const defaultLayer = layer.pipe(
Layer.provide(Job.defaultLayer),
Layer.provide(Database.defaultLayer),
Layer.provide(EventV2Bridge.defaultLayer),
Layer.provide(
SessionV2.defaultLayer.pipe(
Layer.provide(SessionExecutionLocal.defaultLayer),
Layer.provide(locationServiceMapLayer),
),
),
Layer.provide(RuntimeFlags.defaultLayer),
)
const cancelJobs = Effect.fn("Session.cancelJobs")(function* (jobs: Job.Interface, sessionID: SessionID) {
const running = yield* jobs.list()
yield* Effect.forEach(
@@ -1022,76 +1004,6 @@ function listByProject(
)
}
export function* listGlobal(input?: {
directory?: string
roots?: boolean
start?: number
cursor?: number
search?: string
limit?: number
archived?: boolean
}) {
const conditions: SQL[] = []
if (input?.directory) {
conditions.push(eq(SessionTable.directory, input.directory))
}
if (input?.roots) {
conditions.push(isNull(SessionTable.parent_id))
}
if (input?.start) {
conditions.push(gte(SessionTable.time_updated, input.start))
}
if (input?.cursor) {
conditions.push(lt(SessionTable.time_updated, input.cursor))
}
if (input?.search) {
conditions.push(like(SessionTable.title, `%${input.search}%`))
}
if (!input?.archived) {
conditions.push(isNull(SessionTable.time_archived))
}
const limit = input?.limit ?? 100
const rows = runtime.runSync(({ db }) => {
const query =
conditions.length > 0
? db
.select()
.from(SessionTable)
.where(and(...conditions))
: db.select().from(SessionTable)
return query.orderBy(desc(SessionTable.time_updated), desc(SessionTable.id)).limit(limit).all().pipe(Effect.orDie)
})
const ids = [...new Set(rows.map((row) => row.project_id))]
const projects = new Map<string, ProjectInfo>()
if (ids.length > 0) {
const items = runtime.runSync(({ db }) =>
db
.select({ id: ProjectTable.id, name: ProjectTable.name, worktree: ProjectTable.worktree })
.from(ProjectTable)
.where(inArray(ProjectTable.id, ids))
.all()
.pipe(Effect.orDie),
)
for (const item of items) {
projects.set(item.id, {
id: item.id,
name: item.name ?? undefined,
worktree: item.worktree,
})
}
}
for (const row of rows) {
const project = projects.get(row.project_id) ?? null
yield { ...fromRow(row), project }
}
}
export const node = LayerNode.make({
service: Service,
layer: layer,
+1 -3
View File
@@ -18,7 +18,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/SessionStatus") {}
export const layer = Layer.effect(
const layer = Layer.effect(
Service,
Effect.gen(function* () {
const events = yield* EventV2Bridge.Service
@@ -51,8 +51,6 @@ export const layer = Layer.effect(
}),
)
export const defaultLayer = layer.pipe(Layer.provide(EventV2Bridge.defaultLayer))
export const node = LayerNode.make({ service: Service, layer: layer, deps: [EventV2Bridge.node] })
export * as SessionStatus from "./status"
+1 -10
View File
@@ -71,7 +71,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/SessionSummary") {}
export const layer = Layer.effect(
const layer = Layer.effect(
Service,
Effect.gen(function* () {
const sessions = yield* Session.Service
@@ -145,15 +145,6 @@ export const layer = Layer.effect(
}),
)
export const defaultLayer = Layer.suspend(() =>
layer.pipe(
Layer.provide(Session.defaultLayer),
Layer.provide(Snapshot.defaultLayer),
Layer.provide(EventV2Bridge.defaultLayer),
Layer.provide(Config.defaultLayer),
),
)
export const DiffInput = Schema.Struct({
sessionID: SessionID,
messageID: Schema.optional(MessageID),
+1 -7
View File
@@ -47,7 +47,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/SystemPrompt") {}
export const layer = Layer.effect(
const layer = Layer.effect(
Service,
Effect.gen(function* () {
const skill = yield* Skill.Service
@@ -128,12 +128,6 @@ export const layer = Layer.effect(
}),
)
export const defaultLayer = layer.pipe(
Layer.provide(Skill.defaultLayer),
Layer.provide(MCP.defaultLayer),
Layer.provide(locationServiceMapLayer),
)
const locationServiceMapNode = LayerNode.make({
service: LocationServiceMap.Service,
layer: locationServiceMapLayer,
+1 -3
View File
@@ -20,7 +20,7 @@ export interface Interface {
export class Service extends Context.Service<Service, Interface>()("@opencode/SessionTodo") {}
export const layer = Layer.effect(
const layer = Layer.effect(
Service,
Effect.gen(function* () {
const events = yield* EventV2Bridge.Service
@@ -69,8 +69,6 @@ export const layer = Layer.effect(
}),
)
export const defaultLayer = layer.pipe(Layer.provide(EventV2Bridge.defaultLayer), Layer.provide(Database.defaultLayer))
export const node = LayerNode.make({ service: Service, layer: layer, deps: [EventV2Bridge.node, Database.node] })
export * as Todo from "./todo"