mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-15 17:08:21 -04:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a9f14f553 |
@@ -20,7 +20,7 @@ const profiles = [
|
|||||||
{ name: "edit", tool: "edit", input: { filePath: "src/edit.ts" } },
|
{ name: "edit", tool: "edit", input: { filePath: "src/edit.ts" } },
|
||||||
{
|
{
|
||||||
name: "multi patch",
|
name: "multi patch",
|
||||||
tool: "patch",
|
tool: "apply_patch",
|
||||||
input: { files: ["src/a.ts", "src/b.ts", "src/old.ts", "src/moved.ts"] },
|
input: { files: ["src/a.ts", "src/b.ts", "src/old.ts", "src/moved.ts"] },
|
||||||
},
|
},
|
||||||
] as const
|
] as const
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ test("adds patch files incrementally without resetting outer expansion", async (
|
|||||||
userMessage(),
|
userMessage(),
|
||||||
assistantMessage(
|
assistantMessage(
|
||||||
[
|
[
|
||||||
toolPart(patchID, "patch", "running", { files: [first.filePath] }, { metadata: { files: [first] } }),
|
toolPart(patchID, "apply_patch", "running", { files: [first.filePath] }, { metadata: { files: [first] } }),
|
||||||
textPart(followingID, "Following incremental patch"),
|
textPart(followingID, "Following incremental patch"),
|
||||||
],
|
],
|
||||||
{ completed: false },
|
{ completed: false },
|
||||||
@@ -49,7 +49,7 @@ test("adds patch files incrementally without resetting outer expansion", async (
|
|||||||
partUpdated(
|
partUpdated(
|
||||||
toolPart(
|
toolPart(
|
||||||
patchID,
|
patchID,
|
||||||
"patch",
|
"apply_patch",
|
||||||
"running",
|
"running",
|
||||||
{ files: [first.filePath, second.filePath] },
|
{ files: [first.filePath, second.filePath] },
|
||||||
{ metadata: { files: [first, second] } },
|
{ metadata: { files: [first, second] } },
|
||||||
@@ -61,7 +61,7 @@ test("adds patch files incrementally without resetting outer expansion", async (
|
|||||||
partUpdated(
|
partUpdated(
|
||||||
toolPart(
|
toolPart(
|
||||||
patchID,
|
patchID,
|
||||||
"patch",
|
"apply_patch",
|
||||||
"completed",
|
"completed",
|
||||||
{ files: [first.filePath, second.filePath, third.filePath] },
|
{ files: [first.filePath, second.filePath, third.filePath] },
|
||||||
{ metadata: { files: [first, second, third] } },
|
{ metadata: { files: [first, second, third] } },
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ function performanceTurn(index: number) {
|
|||||||
messageID: assistantID,
|
messageID: assistantID,
|
||||||
type: "tool",
|
type: "tool",
|
||||||
callID: `call_0000_${suffix}_patch`,
|
callID: `call_0000_${suffix}_patch`,
|
||||||
tool: "patch",
|
tool: "apply_patch",
|
||||||
state: {
|
state: {
|
||||||
status: "completed",
|
status: "completed",
|
||||||
input: { patchText: realisticPatch(index) },
|
input: { patchText: realisticPatch(index) },
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ function toolPart(
|
|||||||
): MessagePart {
|
): MessagePart {
|
||||||
const metadata =
|
const metadata =
|
||||||
metadataOverride ??
|
metadataOverride ??
|
||||||
(tool === "patch"
|
(tool === "apply_patch"
|
||||||
? { files: [patchFile(index, "update"), patchFile(index + 1, index % 2 === 0 ? "add" : "delete")] }
|
? { files: [patchFile(index, "update"), patchFile(index + 1, index % 2 === 0 ? "add" : "delete")] }
|
||||||
: tool === "edit" || tool === "write"
|
: tool === "edit" || tool === "write"
|
||||||
? {
|
? {
|
||||||
@@ -219,7 +219,7 @@ function turn(index: number): Message[] {
|
|||||||
? [toolPart(index, 7, "write", { filePath: `src/generated/write-${index}.ts`, content: code(index, 28) }, 560)]
|
? [toolPart(index, 7, "write", { filePath: `src/generated/write-${index}.ts`, content: code(index, 28) }, 560)]
|
||||||
: []),
|
: []),
|
||||||
...(index % 8 === 0
|
...(index % 8 === 0
|
||||||
? [toolPart(index, 8, "patch", { files: [`src/generated/patch-${index}.ts`] }, 620)]
|
? [toolPart(index, 8, "apply_patch", { files: [`src/generated/patch-${index}.ts`] }, 620)]
|
||||||
: []),
|
: []),
|
||||||
...(index % 7 === 0
|
...(index % 7 === 0
|
||||||
? [toolPart(index, 4, "bash", { command: "bun typecheck", description: "Verify generated output" }, 620)]
|
? [toolPart(index, 4, "bash", { command: "bun typecheck", description: "Verify generated output" }, 620)]
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ test("renders a completed single-file patch", async ({ page }) => {
|
|||||||
assistantMessage([
|
assistantMessage([
|
||||||
toolPart(
|
toolPart(
|
||||||
id,
|
id,
|
||||||
"patch",
|
"apply_patch",
|
||||||
"completed",
|
"completed",
|
||||||
{ files: ["src/a.ts"] },
|
{ files: ["src/a.ts"] },
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ test("preserves nested patch file state through outer collapse and reopen", asyn
|
|||||||
assistantMessage([
|
assistantMessage([
|
||||||
toolPart(
|
toolPart(
|
||||||
patchID,
|
patchID,
|
||||||
"patch",
|
"apply_patch",
|
||||||
"completed",
|
"completed",
|
||||||
{ files: files.map((file) => file.filePath) },
|
{ files: files.map((file) => file.filePath) },
|
||||||
{ metadata: { files } },
|
{ metadata: { files } },
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ function editPart(id: string) {
|
|||||||
function patchPart(id: string) {
|
function patchPart(id: string) {
|
||||||
return toolPart(
|
return toolPart(
|
||||||
id,
|
id,
|
||||||
"patch",
|
"apply_patch",
|
||||||
"completed",
|
"completed",
|
||||||
{ files: ["src/a.ts", "src/b.ts"] },
|
{ files: ["src/a.ts", "src/b.ts"] },
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
} from "../performance/timeline-stability/fixture"
|
} from "../performance/timeline-stability/fixture"
|
||||||
|
|
||||||
test("renders every tool error outcome without leaking hidden tools", async ({ page }) => {
|
test("renders every tool error outcome without leaking hidden tools", async ({ page }) => {
|
||||||
const ordinary = ["bash", "edit", "write", "patch", "webfetch", "websearch", "task", "skill", "mcp_probe"]
|
const ordinary = ["bash", "edit", "write", "apply_patch", "webfetch", "websearch", "task", "skill", "mcp_probe"]
|
||||||
const parts = ordinary.map((tool, index) =>
|
const parts = ordinary.map((tool, index) =>
|
||||||
toolPart(`prt_error_${index}`, tool, "error", errorInput(tool), { error: `${tool} failed visibly` }),
|
toolPart(`prt_error_${index}`, tool, "error", errorInput(tool), { error: `${tool} failed visibly` }),
|
||||||
)
|
)
|
||||||
@@ -90,7 +90,7 @@ function questionInput() {
|
|||||||
function errorInput(tool: string) {
|
function errorInput(tool: string) {
|
||||||
if (tool === "bash") return { command: "exit 1" }
|
if (tool === "bash") return { command: "exit 1" }
|
||||||
if (["edit", "write"].includes(tool)) return { filePath: "src/error.ts", content: "" }
|
if (["edit", "write"].includes(tool)) return { filePath: "src/error.ts", content: "" }
|
||||||
if (tool === "patch") return { files: ["src/error.ts"] }
|
if (tool === "apply_patch") return { files: ["src/error.ts"] }
|
||||||
if (tool === "webfetch") return { url: "https://example.com" }
|
if (tool === "webfetch") return { url: "https://example.com" }
|
||||||
if (tool === "websearch") return { query: "failure" }
|
if (tool === "websearch") return { query: "failure" }
|
||||||
if (tool === "task") return { description: "Fail task", subagent_type: "explore" }
|
if (tool === "task") return { description: "Fail task", subagent_type: "explore" }
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ function toolPart(
|
|||||||
outputLength = 160,
|
outputLength = 160,
|
||||||
): MessagePart {
|
): MessagePart {
|
||||||
const metadata =
|
const metadata =
|
||||||
tool === "patch"
|
tool === "apply_patch"
|
||||||
? { files: [patchFile(index, "update"), patchFile(index + 1, index % 2 === 0 ? "add" : "delete")] }
|
? { files: [patchFile(index, "update"), patchFile(index + 1, index % 2 === 0 ? "add" : "delete")] }
|
||||||
: tool === "edit" || tool === "write"
|
: tool === "edit" || tool === "write"
|
||||||
? {
|
? {
|
||||||
@@ -199,7 +199,7 @@ function turn(index: number): Message[] {
|
|||||||
? [toolPart(index, 7, "write", { filePath: `src/generated/write-${index}.ts`, content: code(index, 28) }, 560)]
|
? [toolPart(index, 7, "write", { filePath: `src/generated/write-${index}.ts`, content: code(index, 28) }, 560)]
|
||||||
: []),
|
: []),
|
||||||
...(index % 8 === 0
|
...(index % 8 === 0
|
||||||
? [toolPart(index, 8, "patch", { files: [`src/generated/patch-${index}.ts`] }, 620)]
|
? [toolPart(index, 8, "apply_patch", { files: [`src/generated/patch-${index}.ts`] }, 620)]
|
||||||
: []),
|
: []),
|
||||||
...(index % 7 === 0 ? [toolPart(index, 4, "bash", { command: "bun typecheck" }, 620)] : []),
|
...(index % 7 === 0 ? [toolPart(index, 4, "bash", { command: "bun typecheck" }, 620)] : []),
|
||||||
...(index % 10 === 0 ? [toolPart(index, 9, "webfetch", { url: "https://example.com/docs/sample" }, 120)] : []),
|
...(index % 10 === 0 ? [toolPart(index, 9, "webfetch", { url: "https://example.com/docs/sample" }, 120)] : []),
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export async function mockOpenCodeServer(page: Page, config: MockServerConfig) {
|
|||||||
const path = url.pathname
|
const path = url.pathname
|
||||||
if (path === "/global/event" || path === "/event") return sse(route, config.events?.(), config.eventRetry)
|
if (path === "/global/event" || path === "/event") return sse(route, config.events?.(), config.eventRetry)
|
||||||
if (path === "/global/health") return json(route, { healthy: true })
|
if (path === "/global/health") return json(route, { healthy: true })
|
||||||
if (path === "/experimental/capabilities") return json(route, { backgroundSubagents: true })
|
if (path === "/experimental/capabilities") return json(route, { backgroundSubagents: false })
|
||||||
if (path === "/permission")
|
if (path === "/permission")
|
||||||
return json(route, typeof config.permissions === "function" ? config.permissions() : (config.permissions ?? []))
|
return json(route, typeof config.permissions === "function" ? config.permissions() : (config.permissions ?? []))
|
||||||
if (path === "/question")
|
if (path === "/question")
|
||||||
|
|||||||
@@ -1245,7 +1245,7 @@ export function MessageTimeline(props: {
|
|||||||
const value = row()
|
const value = row()
|
||||||
if (value._tag !== "AssistantPart" || value.group.type !== "part") return false
|
if (value._tag !== "AssistantPart" || value.group.type !== "part") return false
|
||||||
const part = getMsgPart(value.group.ref.messageID, value.group.ref.partID)
|
const part = getMsgPart(value.group.ref.messageID, value.group.ref.partID)
|
||||||
return part?.type === "tool" && ["edit", "write", "patch", "apply_patch"].includes(part.tool)
|
return part?.type === "tool" && ["edit", "write", "apply_patch"].includes(part.tool)
|
||||||
}
|
}
|
||||||
const [ready, setReady] = createSignal(initialItem.size <= timelineFallbackItemSize || !asyncFile())
|
const [ready, setReady] = createSignal(initialItem.size <= timelineFallbackItemSize || !asyncFile())
|
||||||
let contentMeasureFrame: number | undefined
|
let contentMeasureFrame: number | undefined
|
||||||
|
|||||||
@@ -628,11 +628,11 @@ function emitEdit(state: State): void {
|
|||||||
|
|
||||||
function emitPatch(state: State): void {
|
function emitPatch(state: State): void {
|
||||||
const file = path.join(process.cwd(), "src", "demo-format.ts")
|
const file = path.join(process.cwd(), "src", "demo-format.ts")
|
||||||
const ref = make(state, "patch", {
|
const ref = make(state, "apply_patch", {
|
||||||
patchText: "*** Begin Patch\n*** End Patch",
|
patchText: "*** Begin Patch\n*** End Patch",
|
||||||
})
|
})
|
||||||
doneTool(state, ref, {
|
doneTool(state, ref, {
|
||||||
title: "patch",
|
title: "apply_patch",
|
||||||
output: "",
|
output: "",
|
||||||
metadata: {
|
metadata: {
|
||||||
files: [
|
files: [
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ type RunFooterOptions = {
|
|||||||
theme: RunTheme
|
theme: RunTheme
|
||||||
keymap: Keymap<Renderable, KeyEvent>
|
keymap: Keymap<Renderable, KeyEvent>
|
||||||
tuiConfig: RunTuiConfig
|
tuiConfig: RunTuiConfig
|
||||||
|
backgroundSubagents: boolean
|
||||||
diffStyle: RunDiffStyle
|
diffStyle: RunDiffStyle
|
||||||
onPermissionReply: (input: PermissionReply) => void | Promise<void>
|
onPermissionReply: (input: PermissionReply) => void | Promise<void>
|
||||||
onQuestionReply: (input: QuestionReply) => void | Promise<void>
|
onQuestionReply: (input: QuestionReply) => void | Promise<void>
|
||||||
@@ -325,6 +326,7 @@ export class RunFooter implements FooterApi {
|
|||||||
theme: footer.theme,
|
theme: footer.theme,
|
||||||
diffStyle: options.diffStyle,
|
diffStyle: options.diffStyle,
|
||||||
tuiConfig: options.tuiConfig,
|
tuiConfig: options.tuiConfig,
|
||||||
|
backgroundSubagents: options.backgroundSubagents,
|
||||||
history: footer.history,
|
history: footer.history,
|
||||||
agent: options.agentLabel,
|
agent: options.agentLabel,
|
||||||
onSubmit: footer.handlePrompt,
|
onSubmit: footer.handlePrompt,
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ type RunFooterViewProps = {
|
|||||||
theme: () => RunTheme
|
theme: () => RunTheme
|
||||||
diffStyle?: RunDiffStyle
|
diffStyle?: RunDiffStyle
|
||||||
tuiConfig: RunTuiConfig
|
tuiConfig: RunTuiConfig
|
||||||
|
backgroundSubagents: boolean
|
||||||
history?: () => RunPrompt[]
|
history?: () => RunPrompt[]
|
||||||
agent: string
|
agent: string
|
||||||
onSubmit: (input: RunPrompt) => boolean
|
onSubmit: (input: RunPrompt) => boolean
|
||||||
@@ -168,7 +169,9 @@ export function RunFooterView(props: RunFooterViewProps) {
|
|||||||
|
|
||||||
return tabs().findIndex((item) => item.sessionID === sessionID) + 1
|
return tabs().findIndex((item) => item.sessionID === sessionID) + 1
|
||||||
})
|
})
|
||||||
const foregroundSubagents = createMemo(() => activeTabs().some((item) => !item.background))
|
const foregroundSubagents = createMemo(
|
||||||
|
() => props.backgroundSubagents && activeTabs().some((item) => !item.background),
|
||||||
|
)
|
||||||
const model = createMemo(() => {
|
const model = createMemo(() => {
|
||||||
const current = props.currentModel()
|
const current = props.currentModel()
|
||||||
return current ? modelInfo(props.providers(), current) : { model: props.state().model, provider: undefined }
|
return current ? modelInfo(props.providers(), current) : { model: props.state().model, provider: undefined }
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { NodeFileSystem } from "@effect/platform-node"
|
import { NodeFileSystem } from "@effect/platform-node"
|
||||||
import { OpenCode, type OpenCodeClient } from "@opencode-ai/client/promise"
|
import { OpenCode, type OpenCodeClient } from "@opencode-ai/client/promise"
|
||||||
|
import { truthy } from "@opencode-ai/core/flag/flag"
|
||||||
import { Global } from "@opencode-ai/core/global"
|
import { Global } from "@opencode-ai/core/global"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
@@ -83,6 +84,9 @@ export async function runMini(input: MiniCommandInput) {
|
|||||||
files: [],
|
files: [],
|
||||||
initialInput,
|
initialInput,
|
||||||
thinking: true,
|
thinking: true,
|
||||||
|
backgroundSubagents:
|
||||||
|
truthy("OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS") ||
|
||||||
|
(process.env.OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS === undefined && truthy("OPENCODE_EXPERIMENTAL")),
|
||||||
replay: input.replay ?? true,
|
replay: input.replay ?? true,
|
||||||
replayLimit: input.replayLimit,
|
replayLimit: input.replayLimit,
|
||||||
demo: input.demo,
|
demo: input.demo,
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ export type LifecycleInput = {
|
|||||||
model: RunInput["model"]
|
model: RunInput["model"]
|
||||||
variant: string | undefined
|
variant: string | undefined
|
||||||
tuiConfig: RunTuiConfig | Promise<RunTuiConfig>
|
tuiConfig: RunTuiConfig | Promise<RunTuiConfig>
|
||||||
|
backgroundSubagents: boolean
|
||||||
onPermissionReply: (input: PermissionReply) => void | Promise<void>
|
onPermissionReply: (input: PermissionReply) => void | Promise<void>
|
||||||
onQuestionReply: (input: QuestionReply) => void | Promise<void>
|
onQuestionReply: (input: QuestionReply) => void | Promise<void>
|
||||||
onQuestionReject: (input: QuestionReject) => void | Promise<void>
|
onQuestionReject: (input: QuestionReject) => void | Promise<void>
|
||||||
@@ -235,6 +236,7 @@ export async function createRuntimeLifecycle(input: LifecycleInput): Promise<Lif
|
|||||||
wrote,
|
wrote,
|
||||||
keymap,
|
keymap,
|
||||||
tuiConfig,
|
tuiConfig,
|
||||||
|
backgroundSubagents: input.backgroundSubagents,
|
||||||
diffStyle: tuiConfig.diff_style ?? "auto",
|
diffStyle: tuiConfig.diff_style ?? "auto",
|
||||||
onPermissionReply: input.onPermissionReply,
|
onPermissionReply: input.onPermissionReply,
|
||||||
onQuestionReply: input.onQuestionReply,
|
onQuestionReply: input.onQuestionReply,
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ type RunRuntimeInput = {
|
|||||||
files: RunInput["files"]
|
files: RunInput["files"]
|
||||||
initialInput?: string
|
initialInput?: string
|
||||||
thinking: boolean
|
thinking: boolean
|
||||||
|
backgroundSubagents: boolean
|
||||||
replay?: boolean
|
replay?: boolean
|
||||||
replayLimit?: number
|
replayLimit?: number
|
||||||
demo?: RunInput["demo"]
|
demo?: RunInput["demo"]
|
||||||
@@ -74,6 +75,7 @@ type RunDeferredInput = {
|
|||||||
files: RunInput["files"]
|
files: RunInput["files"]
|
||||||
initialInput?: string
|
initialInput?: string
|
||||||
thinking: boolean
|
thinking: boolean
|
||||||
|
backgroundSubagents: boolean
|
||||||
replay?: boolean
|
replay?: boolean
|
||||||
replayLimit?: number
|
replayLimit?: number
|
||||||
demo?: RunInput["demo"]
|
demo?: RunInput["demo"]
|
||||||
@@ -268,6 +270,7 @@ async function runInteractiveRuntime(input: RunRuntimeInput, deps: RunRuntimeDep
|
|||||||
model: state.model,
|
model: state.model,
|
||||||
variant: state.activeVariant,
|
variant: state.activeVariant,
|
||||||
tuiConfig: tuiConfigTask,
|
tuiConfig: tuiConfigTask,
|
||||||
|
backgroundSubagents: input.backgroundSubagents,
|
||||||
onPermissionReply: async (next) => {
|
onPermissionReply: async (next) => {
|
||||||
if (state.demo?.permission(next)) {
|
if (state.demo?.permission(next)) {
|
||||||
return
|
return
|
||||||
@@ -873,6 +876,7 @@ export async function runInteractiveDeferredMode(input: RunDeferredInput, deps?:
|
|||||||
files: input.files,
|
files: input.files,
|
||||||
initialInput: input.initialInput,
|
initialInput: input.initialInput,
|
||||||
thinking: input.thinking,
|
thinking: input.thinking,
|
||||||
|
backgroundSubagents: input.backgroundSubagents,
|
||||||
replay: input.replay,
|
replay: input.replay,
|
||||||
replayLimit: input.replayLimit,
|
replayLimit: input.replayLimit,
|
||||||
demo: input.demo,
|
demo: input.demo,
|
||||||
@@ -924,6 +928,7 @@ export async function runInteractiveMode(
|
|||||||
files: input.files,
|
files: input.files,
|
||||||
initialInput: input.initialInput,
|
initialInput: input.initialInput,
|
||||||
thinking: input.thinking,
|
thinking: input.thinking,
|
||||||
|
backgroundSubagents: input.backgroundSubagents,
|
||||||
replay: input.replay,
|
replay: input.replay,
|
||||||
replayLimit: input.replayLimit,
|
replayLimit: input.replayLimit,
|
||||||
demo: input.demo,
|
demo: input.demo,
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ type ToolName =
|
|||||||
| "bash"
|
| "bash"
|
||||||
| "write"
|
| "write"
|
||||||
| "edit"
|
| "edit"
|
||||||
| "patch"
|
| "apply_patch"
|
||||||
| "batch"
|
| "batch"
|
||||||
| "task"
|
| "task"
|
||||||
| "todowrite"
|
| "todowrite"
|
||||||
@@ -1094,7 +1094,7 @@ const TOOL_RULES = {
|
|||||||
},
|
},
|
||||||
permission: permEdit,
|
permission: permEdit,
|
||||||
},
|
},
|
||||||
patch: {
|
apply_patch: {
|
||||||
view: {
|
view: {
|
||||||
output: false,
|
output: false,
|
||||||
final: true,
|
final: true,
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ export type RunInput = {
|
|||||||
files: RunFilePart[]
|
files: RunFilePart[]
|
||||||
initialInput?: string
|
initialInput?: string
|
||||||
thinking: boolean
|
thinking: boolean
|
||||||
|
backgroundSubagents: boolean
|
||||||
demo?: boolean
|
demo?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ import { compile, emitEffectImported, emitEffectShape, emitPromise, write } from
|
|||||||
import {
|
import {
|
||||||
ClientApi,
|
ClientApi,
|
||||||
effectOmitEndpoints,
|
effectOmitEndpoints,
|
||||||
|
endpointNames,
|
||||||
groupNames,
|
groupNames,
|
||||||
promiseOmitEndpoints,
|
promiseOmitEndpoints,
|
||||||
} from "@opencode-ai/protocol/client"
|
} from "@opencode-ai/protocol/client"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
import { fileURLToPath } from "url"
|
import { fileURLToPath } from "url"
|
||||||
|
|
||||||
const promiseContract = compile(ClientApi, { groupNames, omitEndpoints: promiseOmitEndpoints })
|
const promiseContract = compile(ClientApi, { groupNames, endpointNames, omitEndpoints: promiseOmitEndpoints })
|
||||||
const effectContract = compile(ClientApi, { groupNames, omitEndpoints: effectOmitEndpoints })
|
const effectContract = compile(ClientApi, { groupNames, endpointNames, omitEndpoints: effectOmitEndpoints })
|
||||||
|
|
||||||
await Effect.runPromise(
|
await Effect.runPromise(
|
||||||
Effect.all(
|
Effect.all(
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export {
|
export {
|
||||||
ClientApi,
|
ClientApi,
|
||||||
effectOmitEndpoints,
|
effectOmitEndpoints,
|
||||||
|
endpointNames,
|
||||||
groupNames,
|
groupNames,
|
||||||
promiseOmitEndpoints,
|
promiseOmitEndpoints,
|
||||||
} from "@opencode-ai/protocol/client"
|
} from "@opencode-ai/protocol/client"
|
||||||
|
|||||||
@@ -111,167 +111,158 @@ export type Endpoint4_8Input = {
|
|||||||
export type Endpoint4_8Output = EffectValue<ReturnType<RawClient["server.session"]["session.rename"]>>
|
export type Endpoint4_8Output = EffectValue<ReturnType<RawClient["server.session"]["session.rename"]>>
|
||||||
export type SessionRenameOperation<E = never> = (input: Endpoint4_8Input) => Effect.Effect<Endpoint4_8Output, E>
|
export type SessionRenameOperation<E = never> = (input: Endpoint4_8Input) => Effect.Effect<Endpoint4_8Output, E>
|
||||||
|
|
||||||
type Endpoint4_9Request = Parameters<RawClient["server.session"]["session.move"]>[0]
|
type Endpoint4_9Request = Parameters<RawClient["server.session"]["session.prompt"]>[0]
|
||||||
export type Endpoint4_9Input = {
|
export type Endpoint4_9Input = {
|
||||||
readonly sessionID: Endpoint4_9Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_9Request["params"]["sessionID"]
|
||||||
readonly destination: Endpoint4_9Request["payload"]["destination"]
|
readonly id?: Endpoint4_9Request["payload"]["id"]
|
||||||
readonly moveChanges?: Endpoint4_9Request["payload"]["moveChanges"]
|
readonly prompt: Endpoint4_9Request["payload"]["prompt"]
|
||||||
|
readonly delivery?: Endpoint4_9Request["payload"]["delivery"]
|
||||||
|
readonly resume?: Endpoint4_9Request["payload"]["resume"]
|
||||||
}
|
}
|
||||||
export type Endpoint4_9Output = EffectValue<ReturnType<RawClient["server.session"]["session.move"]>>
|
export type Endpoint4_9Output = EffectValue<ReturnType<RawClient["server.session"]["session.prompt"]>>["data"]
|
||||||
export type SessionMoveOperation<E = never> = (input: Endpoint4_9Input) => Effect.Effect<Endpoint4_9Output, E>
|
export type SessionPromptOperation<E = never> = (input: Endpoint4_9Input) => Effect.Effect<Endpoint4_9Output, E>
|
||||||
|
|
||||||
type Endpoint4_10Request = Parameters<RawClient["server.session"]["session.prompt"]>[0]
|
type Endpoint4_10Request = Parameters<RawClient["server.session"]["session.command"]>[0]
|
||||||
export type Endpoint4_10Input = {
|
export type Endpoint4_10Input = {
|
||||||
readonly sessionID: Endpoint4_10Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_10Request["params"]["sessionID"]
|
||||||
readonly id?: Endpoint4_10Request["payload"]["id"]
|
readonly id?: Endpoint4_10Request["payload"]["id"]
|
||||||
readonly prompt: Endpoint4_10Request["payload"]["prompt"]
|
readonly command: Endpoint4_10Request["payload"]["command"]
|
||||||
|
readonly arguments?: Endpoint4_10Request["payload"]["arguments"]
|
||||||
|
readonly agent?: Endpoint4_10Request["payload"]["agent"]
|
||||||
|
readonly model?: Endpoint4_10Request["payload"]["model"]
|
||||||
|
readonly files?: Endpoint4_10Request["payload"]["files"]
|
||||||
|
readonly agents?: Endpoint4_10Request["payload"]["agents"]
|
||||||
readonly delivery?: Endpoint4_10Request["payload"]["delivery"]
|
readonly delivery?: Endpoint4_10Request["payload"]["delivery"]
|
||||||
readonly resume?: Endpoint4_10Request["payload"]["resume"]
|
readonly resume?: Endpoint4_10Request["payload"]["resume"]
|
||||||
}
|
}
|
||||||
export type Endpoint4_10Output = EffectValue<ReturnType<RawClient["server.session"]["session.prompt"]>>["data"]
|
export type Endpoint4_10Output = EffectValue<ReturnType<RawClient["server.session"]["session.command"]>>["data"]
|
||||||
export type SessionPromptOperation<E = never> = (input: Endpoint4_10Input) => Effect.Effect<Endpoint4_10Output, E>
|
export type SessionCommandOperation<E = never> = (input: Endpoint4_10Input) => Effect.Effect<Endpoint4_10Output, E>
|
||||||
|
|
||||||
type Endpoint4_11Request = Parameters<RawClient["server.session"]["session.command"]>[0]
|
type Endpoint4_11Request = Parameters<RawClient["server.session"]["session.skill"]>[0]
|
||||||
export type Endpoint4_11Input = {
|
export type Endpoint4_11Input = {
|
||||||
readonly sessionID: Endpoint4_11Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_11Request["params"]["sessionID"]
|
||||||
readonly id?: Endpoint4_11Request["payload"]["id"]
|
readonly id?: Endpoint4_11Request["payload"]["id"]
|
||||||
readonly command: Endpoint4_11Request["payload"]["command"]
|
readonly skill: Endpoint4_11Request["payload"]["skill"]
|
||||||
readonly arguments?: Endpoint4_11Request["payload"]["arguments"]
|
|
||||||
readonly agent?: Endpoint4_11Request["payload"]["agent"]
|
|
||||||
readonly model?: Endpoint4_11Request["payload"]["model"]
|
|
||||||
readonly files?: Endpoint4_11Request["payload"]["files"]
|
|
||||||
readonly agents?: Endpoint4_11Request["payload"]["agents"]
|
|
||||||
readonly delivery?: Endpoint4_11Request["payload"]["delivery"]
|
|
||||||
readonly resume?: Endpoint4_11Request["payload"]["resume"]
|
readonly resume?: Endpoint4_11Request["payload"]["resume"]
|
||||||
}
|
}
|
||||||
export type Endpoint4_11Output = EffectValue<ReturnType<RawClient["server.session"]["session.command"]>>["data"]
|
export type Endpoint4_11Output = EffectValue<ReturnType<RawClient["server.session"]["session.skill"]>>
|
||||||
export type SessionCommandOperation<E = never> = (input: Endpoint4_11Input) => Effect.Effect<Endpoint4_11Output, E>
|
export type SessionSkillOperation<E = never> = (input: Endpoint4_11Input) => Effect.Effect<Endpoint4_11Output, E>
|
||||||
|
|
||||||
type Endpoint4_12Request = Parameters<RawClient["server.session"]["session.skill"]>[0]
|
type Endpoint4_12Request = Parameters<RawClient["server.session"]["session.synthetic"]>[0]
|
||||||
export type Endpoint4_12Input = {
|
export type Endpoint4_12Input = {
|
||||||
readonly sessionID: Endpoint4_12Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_12Request["params"]["sessionID"]
|
||||||
readonly id?: Endpoint4_12Request["payload"]["id"]
|
readonly text: Endpoint4_12Request["payload"]["text"]
|
||||||
readonly skill: Endpoint4_12Request["payload"]["skill"]
|
readonly description?: Endpoint4_12Request["payload"]["description"]
|
||||||
|
readonly metadata?: Endpoint4_12Request["payload"]["metadata"]
|
||||||
readonly resume?: Endpoint4_12Request["payload"]["resume"]
|
readonly resume?: Endpoint4_12Request["payload"]["resume"]
|
||||||
}
|
}
|
||||||
export type Endpoint4_12Output = EffectValue<ReturnType<RawClient["server.session"]["session.skill"]>>
|
export type Endpoint4_12Output = EffectValue<ReturnType<RawClient["server.session"]["session.synthetic"]>>
|
||||||
export type SessionSkillOperation<E = never> = (input: Endpoint4_12Input) => Effect.Effect<Endpoint4_12Output, E>
|
export type SessionSyntheticOperation<E = never> = (input: Endpoint4_12Input) => Effect.Effect<Endpoint4_12Output, E>
|
||||||
|
|
||||||
type Endpoint4_13Request = Parameters<RawClient["server.session"]["session.synthetic"]>[0]
|
type Endpoint4_13Request = Parameters<RawClient["server.session"]["session.shell"]>[0]
|
||||||
export type Endpoint4_13Input = {
|
export type Endpoint4_13Input = {
|
||||||
readonly sessionID: Endpoint4_13Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_13Request["params"]["sessionID"]
|
||||||
readonly text: Endpoint4_13Request["payload"]["text"]
|
readonly id?: Endpoint4_13Request["payload"]["id"]
|
||||||
readonly description?: Endpoint4_13Request["payload"]["description"]
|
readonly command: Endpoint4_13Request["payload"]["command"]
|
||||||
readonly metadata?: Endpoint4_13Request["payload"]["metadata"]
|
|
||||||
readonly resume?: Endpoint4_13Request["payload"]["resume"]
|
|
||||||
}
|
}
|
||||||
export type Endpoint4_13Output = EffectValue<ReturnType<RawClient["server.session"]["session.synthetic"]>>
|
export type Endpoint4_13Output = EffectValue<ReturnType<RawClient["server.session"]["session.shell"]>>
|
||||||
export type SessionSyntheticOperation<E = never> = (input: Endpoint4_13Input) => Effect.Effect<Endpoint4_13Output, E>
|
export type SessionShellOperation<E = never> = (input: Endpoint4_13Input) => Effect.Effect<Endpoint4_13Output, E>
|
||||||
|
|
||||||
type Endpoint4_14Request = Parameters<RawClient["server.session"]["session.shell"]>[0]
|
type Endpoint4_14Request = Parameters<RawClient["server.session"]["session.compact"]>[0]
|
||||||
export type Endpoint4_14Input = {
|
export type Endpoint4_14Input = {
|
||||||
readonly sessionID: Endpoint4_14Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_14Request["params"]["sessionID"]
|
||||||
readonly id?: Endpoint4_14Request["payload"]["id"]
|
readonly id?: Endpoint4_14Request["payload"]["id"]
|
||||||
readonly command: Endpoint4_14Request["payload"]["command"]
|
|
||||||
}
|
}
|
||||||
export type Endpoint4_14Output = EffectValue<ReturnType<RawClient["server.session"]["session.shell"]>>
|
export type Endpoint4_14Output = EffectValue<ReturnType<RawClient["server.session"]["session.compact"]>>["data"]
|
||||||
export type SessionShellOperation<E = never> = (input: Endpoint4_14Input) => Effect.Effect<Endpoint4_14Output, E>
|
export type SessionCompactOperation<E = never> = (input: Endpoint4_14Input) => Effect.Effect<Endpoint4_14Output, E>
|
||||||
|
|
||||||
type Endpoint4_15Request = Parameters<RawClient["server.session"]["session.compact"]>[0]
|
type Endpoint4_15Request = Parameters<RawClient["server.session"]["session.wait"]>[0]
|
||||||
export type Endpoint4_15Input = {
|
export type Endpoint4_15Input = { readonly sessionID: Endpoint4_15Request["params"]["sessionID"] }
|
||||||
readonly sessionID: Endpoint4_15Request["params"]["sessionID"]
|
export type Endpoint4_15Output = EffectValue<ReturnType<RawClient["server.session"]["session.wait"]>>
|
||||||
readonly id?: Endpoint4_15Request["payload"]["id"]
|
export type SessionWaitOperation<E = never> = (input: Endpoint4_15Input) => Effect.Effect<Endpoint4_15Output, E>
|
||||||
|
|
||||||
|
type Endpoint4_16Request = Parameters<RawClient["server.session"]["session.revert.stage"]>[0]
|
||||||
|
export type Endpoint4_16Input = {
|
||||||
|
readonly sessionID: Endpoint4_16Request["params"]["sessionID"]
|
||||||
|
readonly messageID: Endpoint4_16Request["payload"]["messageID"]
|
||||||
|
readonly files?: Endpoint4_16Request["payload"]["files"]
|
||||||
}
|
}
|
||||||
export type Endpoint4_15Output = EffectValue<ReturnType<RawClient["server.session"]["session.compact"]>>["data"]
|
export type Endpoint4_16Output = EffectValue<ReturnType<RawClient["server.session"]["session.revert.stage"]>>["data"]
|
||||||
export type SessionCompactOperation<E = never> = (input: Endpoint4_15Input) => Effect.Effect<Endpoint4_15Output, E>
|
export type SessionRevertStageOperation<E = never> = (input: Endpoint4_16Input) => Effect.Effect<Endpoint4_16Output, E>
|
||||||
|
|
||||||
type Endpoint4_16Request = Parameters<RawClient["server.session"]["session.wait"]>[0]
|
type Endpoint4_17Request = Parameters<RawClient["server.session"]["session.revert.clear"]>[0]
|
||||||
export type Endpoint4_16Input = { readonly sessionID: Endpoint4_16Request["params"]["sessionID"] }
|
export type Endpoint4_17Input = { readonly sessionID: Endpoint4_17Request["params"]["sessionID"] }
|
||||||
export type Endpoint4_16Output = EffectValue<ReturnType<RawClient["server.session"]["session.wait"]>>
|
export type Endpoint4_17Output = EffectValue<ReturnType<RawClient["server.session"]["session.revert.clear"]>>
|
||||||
export type SessionWaitOperation<E = never> = (input: Endpoint4_16Input) => Effect.Effect<Endpoint4_16Output, E>
|
export type SessionRevertClearOperation<E = never> = (input: Endpoint4_17Input) => Effect.Effect<Endpoint4_17Output, E>
|
||||||
|
|
||||||
type Endpoint4_17Request = Parameters<RawClient["server.session"]["session.revert.stage"]>[0]
|
type Endpoint4_18Request = Parameters<RawClient["server.session"]["session.revert.commit"]>[0]
|
||||||
export type Endpoint4_17Input = {
|
|
||||||
readonly sessionID: Endpoint4_17Request["params"]["sessionID"]
|
|
||||||
readonly messageID: Endpoint4_17Request["payload"]["messageID"]
|
|
||||||
readonly files?: Endpoint4_17Request["payload"]["files"]
|
|
||||||
}
|
|
||||||
export type Endpoint4_17Output = EffectValue<ReturnType<RawClient["server.session"]["session.revert.stage"]>>["data"]
|
|
||||||
export type SessionRevertStageOperation<E = never> = (input: Endpoint4_17Input) => Effect.Effect<Endpoint4_17Output, E>
|
|
||||||
|
|
||||||
type Endpoint4_18Request = Parameters<RawClient["server.session"]["session.revert.clear"]>[0]
|
|
||||||
export type Endpoint4_18Input = { readonly sessionID: Endpoint4_18Request["params"]["sessionID"] }
|
export type Endpoint4_18Input = { readonly sessionID: Endpoint4_18Request["params"]["sessionID"] }
|
||||||
export type Endpoint4_18Output = EffectValue<ReturnType<RawClient["server.session"]["session.revert.clear"]>>
|
export type Endpoint4_18Output = EffectValue<ReturnType<RawClient["server.session"]["session.revert.commit"]>>
|
||||||
export type SessionRevertClearOperation<E = never> = (input: Endpoint4_18Input) => Effect.Effect<Endpoint4_18Output, E>
|
export type SessionRevertCommitOperation<E = never> = (input: Endpoint4_18Input) => Effect.Effect<Endpoint4_18Output, E>
|
||||||
|
|
||||||
type Endpoint4_19Request = Parameters<RawClient["server.session"]["session.revert.commit"]>[0]
|
type Endpoint4_19Request = Parameters<RawClient["server.session"]["session.context"]>[0]
|
||||||
export type Endpoint4_19Input = { readonly sessionID: Endpoint4_19Request["params"]["sessionID"] }
|
export type Endpoint4_19Input = { readonly sessionID: Endpoint4_19Request["params"]["sessionID"] }
|
||||||
export type Endpoint4_19Output = EffectValue<ReturnType<RawClient["server.session"]["session.revert.commit"]>>
|
export type Endpoint4_19Output = EffectValue<ReturnType<RawClient["server.session"]["session.context"]>>["data"]
|
||||||
export type SessionRevertCommitOperation<E = never> = (input: Endpoint4_19Input) => Effect.Effect<Endpoint4_19Output, E>
|
export type SessionContextOperation<E = never> = (input: Endpoint4_19Input) => Effect.Effect<Endpoint4_19Output, E>
|
||||||
|
|
||||||
type Endpoint4_20Request = Parameters<RawClient["server.session"]["session.context"]>[0]
|
type Endpoint4_20Request = Parameters<RawClient["server.session"]["session.instructions.entry.list"]>[0]
|
||||||
export type Endpoint4_20Input = { readonly sessionID: Endpoint4_20Request["params"]["sessionID"] }
|
export type Endpoint4_20Input = { readonly sessionID: Endpoint4_20Request["params"]["sessionID"] }
|
||||||
export type Endpoint4_20Output = EffectValue<ReturnType<RawClient["server.session"]["session.context"]>>["data"]
|
export type Endpoint4_20Output = EffectValue<
|
||||||
export type SessionContextOperation<E = never> = (input: Endpoint4_20Input) => Effect.Effect<Endpoint4_20Output, E>
|
|
||||||
|
|
||||||
type Endpoint4_21Request = Parameters<RawClient["server.session"]["session.instructions.entry.list"]>[0]
|
|
||||||
export type Endpoint4_21Input = { readonly sessionID: Endpoint4_21Request["params"]["sessionID"] }
|
|
||||||
export type Endpoint4_21Output = EffectValue<
|
|
||||||
ReturnType<RawClient["server.session"]["session.instructions.entry.list"]>
|
ReturnType<RawClient["server.session"]["session.instructions.entry.list"]>
|
||||||
>["data"]
|
>["data"]
|
||||||
export type SessionInstructionsEntryListOperation<E = never> = (
|
export type SessionInstructionsEntryListOperation<E = never> = (
|
||||||
|
input: Endpoint4_20Input,
|
||||||
|
) => Effect.Effect<Endpoint4_20Output, E>
|
||||||
|
|
||||||
|
type Endpoint4_21Request = Parameters<RawClient["server.session"]["session.instructions.entry.put"]>[0]
|
||||||
|
export type Endpoint4_21Input = {
|
||||||
|
readonly sessionID: Endpoint4_21Request["params"]["sessionID"]
|
||||||
|
readonly key: Endpoint4_21Request["params"]["key"]
|
||||||
|
readonly value: Endpoint4_21Request["payload"]["value"]
|
||||||
|
}
|
||||||
|
export type Endpoint4_21Output = EffectValue<ReturnType<RawClient["server.session"]["session.instructions.entry.put"]>>
|
||||||
|
export type SessionInstructionsEntryPutOperation<E = never> = (
|
||||||
input: Endpoint4_21Input,
|
input: Endpoint4_21Input,
|
||||||
) => Effect.Effect<Endpoint4_21Output, E>
|
) => Effect.Effect<Endpoint4_21Output, E>
|
||||||
|
|
||||||
type Endpoint4_22Request = Parameters<RawClient["server.session"]["session.instructions.entry.put"]>[0]
|
type Endpoint4_22Request = Parameters<RawClient["server.session"]["session.instructions.entry.remove"]>[0]
|
||||||
export type Endpoint4_22Input = {
|
export type Endpoint4_22Input = {
|
||||||
readonly sessionID: Endpoint4_22Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_22Request["params"]["sessionID"]
|
||||||
readonly key: Endpoint4_22Request["params"]["key"]
|
readonly key: Endpoint4_22Request["params"]["key"]
|
||||||
readonly value: Endpoint4_22Request["payload"]["value"]
|
|
||||||
}
|
}
|
||||||
export type Endpoint4_22Output = EffectValue<ReturnType<RawClient["server.session"]["session.instructions.entry.put"]>>
|
export type Endpoint4_22Output = EffectValue<
|
||||||
export type SessionInstructionsEntryPutOperation<E = never> = (
|
|
||||||
input: Endpoint4_22Input,
|
|
||||||
) => Effect.Effect<Endpoint4_22Output, E>
|
|
||||||
|
|
||||||
type Endpoint4_23Request = Parameters<RawClient["server.session"]["session.instructions.entry.remove"]>[0]
|
|
||||||
export type Endpoint4_23Input = {
|
|
||||||
readonly sessionID: Endpoint4_23Request["params"]["sessionID"]
|
|
||||||
readonly key: Endpoint4_23Request["params"]["key"]
|
|
||||||
}
|
|
||||||
export type Endpoint4_23Output = EffectValue<
|
|
||||||
ReturnType<RawClient["server.session"]["session.instructions.entry.remove"]>
|
ReturnType<RawClient["server.session"]["session.instructions.entry.remove"]>
|
||||||
>
|
>
|
||||||
export type SessionInstructionsEntryRemoveOperation<E = never> = (
|
export type SessionInstructionsEntryRemoveOperation<E = never> = (
|
||||||
input: Endpoint4_23Input,
|
input: Endpoint4_22Input,
|
||||||
) => Effect.Effect<Endpoint4_23Output, E>
|
) => Effect.Effect<Endpoint4_22Output, E>
|
||||||
|
|
||||||
type Endpoint4_24Request = Parameters<RawClient["server.session"]["session.log"]>[0]
|
type Endpoint4_23Request = Parameters<RawClient["server.session"]["session.log"]>[0]
|
||||||
export type Endpoint4_24Input = {
|
export type Endpoint4_23Input = {
|
||||||
readonly sessionID: Endpoint4_24Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_23Request["params"]["sessionID"]
|
||||||
readonly after?: Endpoint4_24Request["query"]["after"]
|
readonly after?: Endpoint4_23Request["query"]["after"]
|
||||||
readonly follow?: Endpoint4_24Request["query"]["follow"]
|
readonly follow?: Endpoint4_23Request["query"]["follow"]
|
||||||
}
|
}
|
||||||
export type Endpoint4_24Output = StreamValue<EffectValue<ReturnType<RawClient["server.session"]["session.log"]>>>
|
export type Endpoint4_23Output = StreamValue<EffectValue<ReturnType<RawClient["server.session"]["session.log"]>>>
|
||||||
export type SessionLogOperation<E = never> = (input: Endpoint4_24Input) => Stream.Stream<Endpoint4_24Output, E>
|
export type SessionLogOperation<E = never> = (input: Endpoint4_23Input) => Stream.Stream<Endpoint4_23Output, E>
|
||||||
|
|
||||||
type Endpoint4_25Request = Parameters<RawClient["server.session"]["session.interrupt"]>[0]
|
type Endpoint4_24Request = Parameters<RawClient["server.session"]["session.interrupt"]>[0]
|
||||||
|
export type Endpoint4_24Input = { readonly sessionID: Endpoint4_24Request["params"]["sessionID"] }
|
||||||
|
export type Endpoint4_24Output = EffectValue<ReturnType<RawClient["server.session"]["session.interrupt"]>>
|
||||||
|
export type SessionInterruptOperation<E = never> = (input: Endpoint4_24Input) => Effect.Effect<Endpoint4_24Output, E>
|
||||||
|
|
||||||
|
type Endpoint4_25Request = Parameters<RawClient["server.session"]["session.background"]>[0]
|
||||||
export type Endpoint4_25Input = { readonly sessionID: Endpoint4_25Request["params"]["sessionID"] }
|
export type Endpoint4_25Input = { readonly sessionID: Endpoint4_25Request["params"]["sessionID"] }
|
||||||
export type Endpoint4_25Output = EffectValue<ReturnType<RawClient["server.session"]["session.interrupt"]>>
|
export type Endpoint4_25Output = EffectValue<ReturnType<RawClient["server.session"]["session.background"]>>
|
||||||
export type SessionInterruptOperation<E = never> = (input: Endpoint4_25Input) => Effect.Effect<Endpoint4_25Output, E>
|
export type SessionBackgroundOperation<E = never> = (input: Endpoint4_25Input) => Effect.Effect<Endpoint4_25Output, E>
|
||||||
|
|
||||||
type Endpoint4_26Request = Parameters<RawClient["server.session"]["session.background"]>[0]
|
type Endpoint4_26Request = Parameters<RawClient["server.session"]["session.message"]>[0]
|
||||||
export type Endpoint4_26Input = { readonly sessionID: Endpoint4_26Request["params"]["sessionID"] }
|
export type Endpoint4_26Input = {
|
||||||
export type Endpoint4_26Output = EffectValue<ReturnType<RawClient["server.session"]["session.background"]>>
|
readonly sessionID: Endpoint4_26Request["params"]["sessionID"]
|
||||||
export type SessionBackgroundOperation<E = never> = (input: Endpoint4_26Input) => Effect.Effect<Endpoint4_26Output, E>
|
readonly messageID: Endpoint4_26Request["params"]["messageID"]
|
||||||
|
|
||||||
type Endpoint4_27Request = Parameters<RawClient["server.session"]["session.message"]>[0]
|
|
||||||
export type Endpoint4_27Input = {
|
|
||||||
readonly sessionID: Endpoint4_27Request["params"]["sessionID"]
|
|
||||||
readonly messageID: Endpoint4_27Request["params"]["messageID"]
|
|
||||||
}
|
}
|
||||||
export type Endpoint4_27Output = EffectValue<ReturnType<RawClient["server.session"]["session.message"]>>["data"]
|
export type Endpoint4_26Output = EffectValue<ReturnType<RawClient["server.session"]["session.message"]>>["data"]
|
||||||
export type SessionMessageOperation<E = never> = (input: Endpoint4_27Input) => Effect.Effect<Endpoint4_27Output, E>
|
export type SessionMessageOperation<E = never> = (input: Endpoint4_26Input) => Effect.Effect<Endpoint4_26Output, E>
|
||||||
|
|
||||||
export interface SessionApi<E = never> {
|
export interface SessionApi<E = never> {
|
||||||
readonly list: SessionListOperation<E>
|
readonly list: SessionListOperation<E>
|
||||||
@@ -283,7 +274,6 @@ export interface SessionApi<E = never> {
|
|||||||
readonly switchAgent: SessionSwitchAgentOperation<E>
|
readonly switchAgent: SessionSwitchAgentOperation<E>
|
||||||
readonly switchModel: SessionSwitchModelOperation<E>
|
readonly switchModel: SessionSwitchModelOperation<E>
|
||||||
readonly rename: SessionRenameOperation<E>
|
readonly rename: SessionRenameOperation<E>
|
||||||
readonly move: SessionMoveOperation<E>
|
|
||||||
readonly prompt: SessionPromptOperation<E>
|
readonly prompt: SessionPromptOperation<E>
|
||||||
readonly command: SessionCommandOperation<E>
|
readonly command: SessionCommandOperation<E>
|
||||||
readonly skill: SessionSkillOperation<E>
|
readonly skill: SessionSkillOperation<E>
|
||||||
@@ -291,11 +281,9 @@ export interface SessionApi<E = never> {
|
|||||||
readonly shell: SessionShellOperation<E>
|
readonly shell: SessionShellOperation<E>
|
||||||
readonly compact: SessionCompactOperation<E>
|
readonly compact: SessionCompactOperation<E>
|
||||||
readonly wait: SessionWaitOperation<E>
|
readonly wait: SessionWaitOperation<E>
|
||||||
readonly revert: {
|
readonly revertStage: SessionRevertStageOperation<E>
|
||||||
readonly stage: SessionRevertStageOperation<E>
|
readonly revertClear: SessionRevertClearOperation<E>
|
||||||
readonly clear: SessionRevertClearOperation<E>
|
readonly revertCommit: SessionRevertCommitOperation<E>
|
||||||
readonly commit: SessionRevertCommitOperation<E>
|
|
||||||
}
|
|
||||||
readonly context: SessionContextOperation<E>
|
readonly context: SessionContextOperation<E>
|
||||||
readonly instructions: {
|
readonly instructions: {
|
||||||
readonly entry: {
|
readonly entry: {
|
||||||
@@ -440,15 +428,11 @@ export type IntegrationAttemptCancelOperation<E = never> = (
|
|||||||
export interface IntegrationApi<E = never> {
|
export interface IntegrationApi<E = never> {
|
||||||
readonly list: IntegrationListOperation<E>
|
readonly list: IntegrationListOperation<E>
|
||||||
readonly get: IntegrationGetOperation<E>
|
readonly get: IntegrationGetOperation<E>
|
||||||
readonly connect: {
|
readonly connectKey: IntegrationConnectKeyOperation<E>
|
||||||
readonly key: IntegrationConnectKeyOperation<E>
|
readonly connectOauth: IntegrationConnectOauthOperation<E>
|
||||||
readonly oauth: IntegrationConnectOauthOperation<E>
|
readonly attemptStatus: IntegrationAttemptStatusOperation<E>
|
||||||
}
|
readonly attemptComplete: IntegrationAttemptCompleteOperation<E>
|
||||||
readonly attempt: {
|
readonly attemptCancel: IntegrationAttemptCancelOperation<E>
|
||||||
readonly status: IntegrationAttemptStatusOperation<E>
|
|
||||||
readonly complete: IntegrationAttemptCompleteOperation<E>
|
|
||||||
readonly cancel: IntegrationAttemptCancelOperation<E>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Endpoint10_0Request = Parameters<RawClient["server.mcp"]["mcp.list"]>[0]
|
type Endpoint10_0Request = Parameters<RawClient["server.mcp"]["mcp.list"]>[0]
|
||||||
@@ -459,13 +443,11 @@ export type ServerMcpListOperation<E = never> = (input?: Endpoint10_0Input) => E
|
|||||||
type Endpoint10_1Request = Parameters<RawClient["server.mcp"]["mcp.resource.catalog"]>[0]
|
type Endpoint10_1Request = Parameters<RawClient["server.mcp"]["mcp.resource.catalog"]>[0]
|
||||||
export type Endpoint10_1Input = { readonly location?: Endpoint10_1Request["query"]["location"] }
|
export type Endpoint10_1Input = { readonly location?: Endpoint10_1Request["query"]["location"] }
|
||||||
export type Endpoint10_1Output = EffectValue<ReturnType<RawClient["server.mcp"]["mcp.resource.catalog"]>>
|
export type Endpoint10_1Output = EffectValue<ReturnType<RawClient["server.mcp"]["mcp.resource.catalog"]>>
|
||||||
export type ServerMcpResourceCatalogOperation<E = never> = (
|
export type ServerMcpCatalogOperation<E = never> = (input?: Endpoint10_1Input) => Effect.Effect<Endpoint10_1Output, E>
|
||||||
input?: Endpoint10_1Input,
|
|
||||||
) => Effect.Effect<Endpoint10_1Output, E>
|
|
||||||
|
|
||||||
export interface ServerMcpApi<E = never> {
|
export interface ServerMcpApi<E = never> {
|
||||||
readonly list: ServerMcpListOperation<E>
|
readonly list: ServerMcpListOperation<E>
|
||||||
readonly resource: { readonly catalog: ServerMcpResourceCatalogOperation<E> }
|
readonly catalog: ServerMcpCatalogOperation<E>
|
||||||
}
|
}
|
||||||
|
|
||||||
type Endpoint11_0Request = Parameters<RawClient["server.credential"]["credential.update"]>[0]
|
type Endpoint11_0Request = Parameters<RawClient["server.credential"]["credential.update"]>[0]
|
||||||
@@ -515,7 +497,7 @@ export interface ProjectApi<E = never> {
|
|||||||
type Endpoint13_0Request = Parameters<RawClient["server.form"]["form.request.list"]>[0]
|
type Endpoint13_0Request = Parameters<RawClient["server.form"]["form.request.list"]>[0]
|
||||||
export type Endpoint13_0Input = { readonly location?: Endpoint13_0Request["query"]["location"] }
|
export type Endpoint13_0Input = { readonly location?: Endpoint13_0Request["query"]["location"] }
|
||||||
export type Endpoint13_0Output = EffectValue<ReturnType<RawClient["server.form"]["form.request.list"]>>
|
export type Endpoint13_0Output = EffectValue<ReturnType<RawClient["server.form"]["form.request.list"]>>
|
||||||
export type FormRequestListOperation<E = never> = (input?: Endpoint13_0Input) => Effect.Effect<Endpoint13_0Output, E>
|
export type FormListRequestsOperation<E = never> = (input?: Endpoint13_0Input) => Effect.Effect<Endpoint13_0Output, E>
|
||||||
|
|
||||||
type Endpoint13_1Request = Parameters<RawClient["server.form"]["session.form.list"]>[0]
|
type Endpoint13_1Request = Parameters<RawClient["server.form"]["session.form.list"]>[0]
|
||||||
export type Endpoint13_1Input = { readonly sessionID: Endpoint13_1Request["params"]["sessionID"] }
|
export type Endpoint13_1Input = { readonly sessionID: Endpoint13_1Request["params"]["sessionID"] }
|
||||||
@@ -569,7 +551,7 @@ export type Endpoint13_6Output = EffectValue<ReturnType<RawClient["server.form"]
|
|||||||
export type FormCancelOperation<E = never> = (input: Endpoint13_6Input) => Effect.Effect<Endpoint13_6Output, E>
|
export type FormCancelOperation<E = never> = (input: Endpoint13_6Input) => Effect.Effect<Endpoint13_6Output, E>
|
||||||
|
|
||||||
export interface FormApi<E = never> {
|
export interface FormApi<E = never> {
|
||||||
readonly request: { readonly list: FormRequestListOperation<E> }
|
readonly listRequests: FormListRequestsOperation<E>
|
||||||
readonly list: FormListOperation<E>
|
readonly list: FormListOperation<E>
|
||||||
readonly create: FormCreateOperation<E>
|
readonly create: FormCreateOperation<E>
|
||||||
readonly get: FormGetOperation<E>
|
readonly get: FormGetOperation<E>
|
||||||
@@ -581,7 +563,7 @@ export interface FormApi<E = never> {
|
|||||||
type Endpoint14_0Request = Parameters<RawClient["server.permission"]["permission.request.list"]>[0]
|
type Endpoint14_0Request = Parameters<RawClient["server.permission"]["permission.request.list"]>[0]
|
||||||
export type Endpoint14_0Input = { readonly location?: Endpoint14_0Request["query"]["location"] }
|
export type Endpoint14_0Input = { readonly location?: Endpoint14_0Request["query"]["location"] }
|
||||||
export type Endpoint14_0Output = EffectValue<ReturnType<RawClient["server.permission"]["permission.request.list"]>>
|
export type Endpoint14_0Output = EffectValue<ReturnType<RawClient["server.permission"]["permission.request.list"]>>
|
||||||
export type PermissionRequestListOperation<E = never> = (
|
export type PermissionListRequestsOperation<E = never> = (
|
||||||
input?: Endpoint14_0Input,
|
input?: Endpoint14_0Input,
|
||||||
) => Effect.Effect<Endpoint14_0Output, E>
|
) => Effect.Effect<Endpoint14_0Output, E>
|
||||||
|
|
||||||
@@ -590,14 +572,14 @@ export type Endpoint14_1Input = { readonly projectID?: Endpoint14_1Request["quer
|
|||||||
export type Endpoint14_1Output = EffectValue<
|
export type Endpoint14_1Output = EffectValue<
|
||||||
ReturnType<RawClient["server.permission"]["permission.saved.list"]>
|
ReturnType<RawClient["server.permission"]["permission.saved.list"]>
|
||||||
>["data"]
|
>["data"]
|
||||||
export type PermissionSavedListOperation<E = never> = (
|
export type PermissionListSavedOperation<E = never> = (
|
||||||
input?: Endpoint14_1Input,
|
input?: Endpoint14_1Input,
|
||||||
) => Effect.Effect<Endpoint14_1Output, E>
|
) => Effect.Effect<Endpoint14_1Output, E>
|
||||||
|
|
||||||
type Endpoint14_2Request = Parameters<RawClient["server.permission"]["permission.saved.remove"]>[0]
|
type Endpoint14_2Request = Parameters<RawClient["server.permission"]["permission.saved.remove"]>[0]
|
||||||
export type Endpoint14_2Input = { readonly id: Endpoint14_2Request["params"]["id"] }
|
export type Endpoint14_2Input = { readonly id: Endpoint14_2Request["params"]["id"] }
|
||||||
export type Endpoint14_2Output = EffectValue<ReturnType<RawClient["server.permission"]["permission.saved.remove"]>>
|
export type Endpoint14_2Output = EffectValue<ReturnType<RawClient["server.permission"]["permission.saved.remove"]>>
|
||||||
export type PermissionSavedRemoveOperation<E = never> = (
|
export type PermissionRemoveSavedOperation<E = never> = (
|
||||||
input: Endpoint14_2Input,
|
input: Endpoint14_2Input,
|
||||||
) => Effect.Effect<Endpoint14_2Output, E>
|
) => Effect.Effect<Endpoint14_2Output, E>
|
||||||
|
|
||||||
@@ -645,8 +627,9 @@ export type Endpoint14_6Output = EffectValue<ReturnType<RawClient["server.permis
|
|||||||
export type PermissionReplyOperation<E = never> = (input: Endpoint14_6Input) => Effect.Effect<Endpoint14_6Output, E>
|
export type PermissionReplyOperation<E = never> = (input: Endpoint14_6Input) => Effect.Effect<Endpoint14_6Output, E>
|
||||||
|
|
||||||
export interface PermissionApi<E = never> {
|
export interface PermissionApi<E = never> {
|
||||||
readonly request: { readonly list: PermissionRequestListOperation<E> }
|
readonly listRequests: PermissionListRequestsOperation<E>
|
||||||
readonly saved: { readonly list: PermissionSavedListOperation<E>; readonly remove: PermissionSavedRemoveOperation<E> }
|
readonly listSaved: PermissionListSavedOperation<E>
|
||||||
|
readonly removeSaved: PermissionRemoveSavedOperation<E>
|
||||||
readonly create: PermissionCreateOperation<E>
|
readonly create: PermissionCreateOperation<E>
|
||||||
readonly list: PermissionListOperation<E>
|
readonly list: PermissionListOperation<E>
|
||||||
readonly get: PermissionGetOperation<E>
|
readonly get: PermissionGetOperation<E>
|
||||||
@@ -815,7 +798,7 @@ export interface ShellApi<E = never> {
|
|||||||
type Endpoint21_0Request = Parameters<RawClient["server.question"]["question.request.list"]>[0]
|
type Endpoint21_0Request = Parameters<RawClient["server.question"]["question.request.list"]>[0]
|
||||||
export type Endpoint21_0Input = { readonly location?: Endpoint21_0Request["query"]["location"] }
|
export type Endpoint21_0Input = { readonly location?: Endpoint21_0Request["query"]["location"] }
|
||||||
export type Endpoint21_0Output = EffectValue<ReturnType<RawClient["server.question"]["question.request.list"]>>
|
export type Endpoint21_0Output = EffectValue<ReturnType<RawClient["server.question"]["question.request.list"]>>
|
||||||
export type QuestionRequestListOperation<E = never> = (
|
export type QuestionListRequestsOperation<E = never> = (
|
||||||
input?: Endpoint21_0Input,
|
input?: Endpoint21_0Input,
|
||||||
) => Effect.Effect<Endpoint21_0Output, E>
|
) => Effect.Effect<Endpoint21_0Output, E>
|
||||||
|
|
||||||
@@ -842,7 +825,7 @@ export type Endpoint21_3Output = EffectValue<ReturnType<RawClient["server.questi
|
|||||||
export type QuestionRejectOperation<E = never> = (input: Endpoint21_3Input) => Effect.Effect<Endpoint21_3Output, E>
|
export type QuestionRejectOperation<E = never> = (input: Endpoint21_3Input) => Effect.Effect<Endpoint21_3Output, E>
|
||||||
|
|
||||||
export interface QuestionApi<E = never> {
|
export interface QuestionApi<E = never> {
|
||||||
readonly request: { readonly list: QuestionRequestListOperation<E> }
|
readonly listRequests: QuestionListRequestsOperation<E>
|
||||||
readonly list: QuestionListOperation<E>
|
readonly list: QuestionListOperation<E>
|
||||||
readonly reply: QuestionReplyOperation<E>
|
readonly reply: QuestionReplyOperation<E>
|
||||||
readonly reject: QuestionRejectOperation<E>
|
readonly reject: QuestionRejectOperation<E>
|
||||||
@@ -912,15 +895,16 @@ export interface VcsApi<E = never> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type Endpoint25_0Output = EffectValue<ReturnType<RawClient["server.debug"]["debug.location"]>>
|
export type Endpoint25_0Output = EffectValue<ReturnType<RawClient["server.debug"]["debug.location"]>>
|
||||||
export type DebugLocationListOperation<E = never> = () => Effect.Effect<Endpoint25_0Output, E>
|
export type DebugLocationOperation<E = never> = () => Effect.Effect<Endpoint25_0Output, E>
|
||||||
|
|
||||||
type Endpoint25_1Request = Parameters<RawClient["server.debug"]["debug.location.evict"]>[0]
|
type Endpoint25_1Request = Parameters<RawClient["server.debug"]["debug.location.evict"]>[0]
|
||||||
export type Endpoint25_1Input = { readonly location?: Endpoint25_1Request["query"]["location"] }
|
export type Endpoint25_1Input = { readonly location?: Endpoint25_1Request["query"]["location"] }
|
||||||
export type Endpoint25_1Output = EffectValue<ReturnType<RawClient["server.debug"]["debug.location.evict"]>>
|
export type Endpoint25_1Output = EffectValue<ReturnType<RawClient["server.debug"]["debug.location.evict"]>>
|
||||||
export type DebugLocationEvictOperation<E = never> = (input?: Endpoint25_1Input) => Effect.Effect<Endpoint25_1Output, E>
|
export type DebugEvictLocationOperation<E = never> = (input?: Endpoint25_1Input) => Effect.Effect<Endpoint25_1Output, E>
|
||||||
|
|
||||||
export interface DebugApi<E = never> {
|
export interface DebugApi<E = never> {
|
||||||
readonly location: { readonly list: DebugLocationListOperation<E>; readonly evict: DebugLocationEvictOperation<E> }
|
readonly location: DebugLocationOperation<E>
|
||||||
|
readonly evictLocation: DebugEvictLocationOperation<E>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppApi<E = never> {
|
export interface AppApi<E = never> {
|
||||||
|
|||||||
@@ -141,27 +141,15 @@ const Endpoint4_8 = (raw: RawClient["server.session"]) => (input: Endpoint4_8Inp
|
|||||||
Effect.mapError(mapClientError),
|
Effect.mapError(mapClientError),
|
||||||
)
|
)
|
||||||
|
|
||||||
type Endpoint4_9Request = Parameters<RawClient["server.session"]["session.move"]>[0]
|
type Endpoint4_9Request = Parameters<RawClient["server.session"]["session.prompt"]>[0]
|
||||||
type Endpoint4_9Input = {
|
type Endpoint4_9Input = {
|
||||||
readonly sessionID: Endpoint4_9Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_9Request["params"]["sessionID"]
|
||||||
readonly destination: Endpoint4_9Request["payload"]["destination"]
|
readonly id?: Endpoint4_9Request["payload"]["id"]
|
||||||
readonly moveChanges?: Endpoint4_9Request["payload"]["moveChanges"]
|
readonly prompt: Endpoint4_9Request["payload"]["prompt"]
|
||||||
|
readonly delivery?: Endpoint4_9Request["payload"]["delivery"]
|
||||||
|
readonly resume?: Endpoint4_9Request["payload"]["resume"]
|
||||||
}
|
}
|
||||||
const Endpoint4_9 = (raw: RawClient["server.session"]) => (input: Endpoint4_9Input) =>
|
const Endpoint4_9 = (raw: RawClient["server.session"]) => (input: Endpoint4_9Input) =>
|
||||||
raw["session.move"]({
|
|
||||||
params: { sessionID: input["sessionID"] },
|
|
||||||
payload: { destination: input["destination"], moveChanges: input["moveChanges"] },
|
|
||||||
}).pipe(Effect.mapError(mapClientError))
|
|
||||||
|
|
||||||
type Endpoint4_10Request = Parameters<RawClient["server.session"]["session.prompt"]>[0]
|
|
||||||
type Endpoint4_10Input = {
|
|
||||||
readonly sessionID: Endpoint4_10Request["params"]["sessionID"]
|
|
||||||
readonly id?: Endpoint4_10Request["payload"]["id"]
|
|
||||||
readonly prompt: Endpoint4_10Request["payload"]["prompt"]
|
|
||||||
readonly delivery?: Endpoint4_10Request["payload"]["delivery"]
|
|
||||||
readonly resume?: Endpoint4_10Request["payload"]["resume"]
|
|
||||||
}
|
|
||||||
const Endpoint4_10 = (raw: RawClient["server.session"]) => (input: Endpoint4_10Input) =>
|
|
||||||
raw["session.prompt"]({
|
raw["session.prompt"]({
|
||||||
params: { sessionID: input["sessionID"] },
|
params: { sessionID: input["sessionID"] },
|
||||||
payload: { id: input["id"], prompt: input["prompt"], delivery: input["delivery"], resume: input["resume"] },
|
payload: { id: input["id"], prompt: input["prompt"], delivery: input["delivery"], resume: input["resume"] },
|
||||||
@@ -170,20 +158,20 @@ const Endpoint4_10 = (raw: RawClient["server.session"]) => (input: Endpoint4_10I
|
|||||||
Effect.map((value) => value.data),
|
Effect.map((value) => value.data),
|
||||||
)
|
)
|
||||||
|
|
||||||
type Endpoint4_11Request = Parameters<RawClient["server.session"]["session.command"]>[0]
|
type Endpoint4_10Request = Parameters<RawClient["server.session"]["session.command"]>[0]
|
||||||
type Endpoint4_11Input = {
|
type Endpoint4_10Input = {
|
||||||
readonly sessionID: Endpoint4_11Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_10Request["params"]["sessionID"]
|
||||||
readonly id?: Endpoint4_11Request["payload"]["id"]
|
readonly id?: Endpoint4_10Request["payload"]["id"]
|
||||||
readonly command: Endpoint4_11Request["payload"]["command"]
|
readonly command: Endpoint4_10Request["payload"]["command"]
|
||||||
readonly arguments?: Endpoint4_11Request["payload"]["arguments"]
|
readonly arguments?: Endpoint4_10Request["payload"]["arguments"]
|
||||||
readonly agent?: Endpoint4_11Request["payload"]["agent"]
|
readonly agent?: Endpoint4_10Request["payload"]["agent"]
|
||||||
readonly model?: Endpoint4_11Request["payload"]["model"]
|
readonly model?: Endpoint4_10Request["payload"]["model"]
|
||||||
readonly files?: Endpoint4_11Request["payload"]["files"]
|
readonly files?: Endpoint4_10Request["payload"]["files"]
|
||||||
readonly agents?: Endpoint4_11Request["payload"]["agents"]
|
readonly agents?: Endpoint4_10Request["payload"]["agents"]
|
||||||
readonly delivery?: Endpoint4_11Request["payload"]["delivery"]
|
readonly delivery?: Endpoint4_10Request["payload"]["delivery"]
|
||||||
readonly resume?: Endpoint4_11Request["payload"]["resume"]
|
readonly resume?: Endpoint4_10Request["payload"]["resume"]
|
||||||
}
|
}
|
||||||
const Endpoint4_11 = (raw: RawClient["server.session"]) => (input: Endpoint4_11Input) =>
|
const Endpoint4_10 = (raw: RawClient["server.session"]) => (input: Endpoint4_10Input) =>
|
||||||
raw["session.command"]({
|
raw["session.command"]({
|
||||||
params: { sessionID: input["sessionID"] },
|
params: { sessionID: input["sessionID"] },
|
||||||
payload: {
|
payload: {
|
||||||
@@ -202,28 +190,28 @@ const Endpoint4_11 = (raw: RawClient["server.session"]) => (input: Endpoint4_11I
|
|||||||
Effect.map((value) => value.data),
|
Effect.map((value) => value.data),
|
||||||
)
|
)
|
||||||
|
|
||||||
type Endpoint4_12Request = Parameters<RawClient["server.session"]["session.skill"]>[0]
|
type Endpoint4_11Request = Parameters<RawClient["server.session"]["session.skill"]>[0]
|
||||||
type Endpoint4_12Input = {
|
type Endpoint4_11Input = {
|
||||||
readonly sessionID: Endpoint4_12Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_11Request["params"]["sessionID"]
|
||||||
readonly id?: Endpoint4_12Request["payload"]["id"]
|
readonly id?: Endpoint4_11Request["payload"]["id"]
|
||||||
readonly skill: Endpoint4_12Request["payload"]["skill"]
|
readonly skill: Endpoint4_11Request["payload"]["skill"]
|
||||||
readonly resume?: Endpoint4_12Request["payload"]["resume"]
|
readonly resume?: Endpoint4_11Request["payload"]["resume"]
|
||||||
}
|
}
|
||||||
const Endpoint4_12 = (raw: RawClient["server.session"]) => (input: Endpoint4_12Input) =>
|
const Endpoint4_11 = (raw: RawClient["server.session"]) => (input: Endpoint4_11Input) =>
|
||||||
raw["session.skill"]({
|
raw["session.skill"]({
|
||||||
params: { sessionID: input["sessionID"] },
|
params: { sessionID: input["sessionID"] },
|
||||||
payload: { id: input["id"], skill: input["skill"], resume: input["resume"] },
|
payload: { id: input["id"], skill: input["skill"], resume: input["resume"] },
|
||||||
}).pipe(Effect.mapError(mapClientError))
|
}).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
type Endpoint4_13Request = Parameters<RawClient["server.session"]["session.synthetic"]>[0]
|
type Endpoint4_12Request = Parameters<RawClient["server.session"]["session.synthetic"]>[0]
|
||||||
type Endpoint4_13Input = {
|
type Endpoint4_12Input = {
|
||||||
readonly sessionID: Endpoint4_13Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_12Request["params"]["sessionID"]
|
||||||
readonly text: Endpoint4_13Request["payload"]["text"]
|
readonly text: Endpoint4_12Request["payload"]["text"]
|
||||||
readonly description?: Endpoint4_13Request["payload"]["description"]
|
readonly description?: Endpoint4_12Request["payload"]["description"]
|
||||||
readonly metadata?: Endpoint4_13Request["payload"]["metadata"]
|
readonly metadata?: Endpoint4_12Request["payload"]["metadata"]
|
||||||
readonly resume?: Endpoint4_13Request["payload"]["resume"]
|
readonly resume?: Endpoint4_12Request["payload"]["resume"]
|
||||||
}
|
}
|
||||||
const Endpoint4_13 = (raw: RawClient["server.session"]) => (input: Endpoint4_13Input) =>
|
const Endpoint4_12 = (raw: RawClient["server.session"]) => (input: Endpoint4_12Input) =>
|
||||||
raw["session.synthetic"]({
|
raw["session.synthetic"]({
|
||||||
params: { sessionID: input["sessionID"] },
|
params: { sessionID: input["sessionID"] },
|
||||||
payload: {
|
payload: {
|
||||||
@@ -234,41 +222,41 @@ const Endpoint4_13 = (raw: RawClient["server.session"]) => (input: Endpoint4_13I
|
|||||||
},
|
},
|
||||||
}).pipe(Effect.mapError(mapClientError))
|
}).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
type Endpoint4_14Request = Parameters<RawClient["server.session"]["session.shell"]>[0]
|
type Endpoint4_13Request = Parameters<RawClient["server.session"]["session.shell"]>[0]
|
||||||
type Endpoint4_14Input = {
|
type Endpoint4_13Input = {
|
||||||
readonly sessionID: Endpoint4_14Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_13Request["params"]["sessionID"]
|
||||||
readonly id?: Endpoint4_14Request["payload"]["id"]
|
readonly id?: Endpoint4_13Request["payload"]["id"]
|
||||||
readonly command: Endpoint4_14Request["payload"]["command"]
|
readonly command: Endpoint4_13Request["payload"]["command"]
|
||||||
}
|
}
|
||||||
const Endpoint4_14 = (raw: RawClient["server.session"]) => (input: Endpoint4_14Input) =>
|
const Endpoint4_13 = (raw: RawClient["server.session"]) => (input: Endpoint4_13Input) =>
|
||||||
raw["session.shell"]({
|
raw["session.shell"]({
|
||||||
params: { sessionID: input["sessionID"] },
|
params: { sessionID: input["sessionID"] },
|
||||||
payload: { id: input["id"], command: input["command"] },
|
payload: { id: input["id"], command: input["command"] },
|
||||||
}).pipe(Effect.mapError(mapClientError))
|
}).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
type Endpoint4_15Request = Parameters<RawClient["server.session"]["session.compact"]>[0]
|
type Endpoint4_14Request = Parameters<RawClient["server.session"]["session.compact"]>[0]
|
||||||
type Endpoint4_15Input = {
|
type Endpoint4_14Input = {
|
||||||
readonly sessionID: Endpoint4_15Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_14Request["params"]["sessionID"]
|
||||||
readonly id?: Endpoint4_15Request["payload"]["id"]
|
readonly id?: Endpoint4_14Request["payload"]["id"]
|
||||||
}
|
}
|
||||||
const Endpoint4_15 = (raw: RawClient["server.session"]) => (input: Endpoint4_15Input) =>
|
const Endpoint4_14 = (raw: RawClient["server.session"]) => (input: Endpoint4_14Input) =>
|
||||||
raw["session.compact"]({ params: { sessionID: input["sessionID"] }, payload: { id: input["id"] } }).pipe(
|
raw["session.compact"]({ params: { sessionID: input["sessionID"] }, payload: { id: input["id"] } }).pipe(
|
||||||
Effect.mapError(mapClientError),
|
Effect.mapError(mapClientError),
|
||||||
Effect.map((value) => value.data),
|
Effect.map((value) => value.data),
|
||||||
)
|
)
|
||||||
|
|
||||||
type Endpoint4_16Request = Parameters<RawClient["server.session"]["session.wait"]>[0]
|
type Endpoint4_15Request = Parameters<RawClient["server.session"]["session.wait"]>[0]
|
||||||
type Endpoint4_16Input = { readonly sessionID: Endpoint4_16Request["params"]["sessionID"] }
|
type Endpoint4_15Input = { readonly sessionID: Endpoint4_15Request["params"]["sessionID"] }
|
||||||
const Endpoint4_16 = (raw: RawClient["server.session"]) => (input: Endpoint4_16Input) =>
|
const Endpoint4_15 = (raw: RawClient["server.session"]) => (input: Endpoint4_15Input) =>
|
||||||
raw["session.wait"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
raw["session.wait"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
type Endpoint4_17Request = Parameters<RawClient["server.session"]["session.revert.stage"]>[0]
|
type Endpoint4_16Request = Parameters<RawClient["server.session"]["session.revert.stage"]>[0]
|
||||||
type Endpoint4_17Input = {
|
type Endpoint4_16Input = {
|
||||||
readonly sessionID: Endpoint4_17Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_16Request["params"]["sessionID"]
|
||||||
readonly messageID: Endpoint4_17Request["payload"]["messageID"]
|
readonly messageID: Endpoint4_16Request["payload"]["messageID"]
|
||||||
readonly files?: Endpoint4_17Request["payload"]["files"]
|
readonly files?: Endpoint4_16Request["payload"]["files"]
|
||||||
}
|
}
|
||||||
const Endpoint4_17 = (raw: RawClient["server.session"]) => (input: Endpoint4_17Input) =>
|
const Endpoint4_16 = (raw: RawClient["server.session"]) => (input: Endpoint4_16Input) =>
|
||||||
raw["session.revert.stage"]({
|
raw["session.revert.stage"]({
|
||||||
params: { sessionID: input["sessionID"] },
|
params: { sessionID: input["sessionID"] },
|
||||||
payload: { messageID: input["messageID"], files: input["files"] },
|
payload: { messageID: input["messageID"], files: input["files"] },
|
||||||
@@ -277,61 +265,61 @@ const Endpoint4_17 = (raw: RawClient["server.session"]) => (input: Endpoint4_17I
|
|||||||
Effect.map((value) => value.data),
|
Effect.map((value) => value.data),
|
||||||
)
|
)
|
||||||
|
|
||||||
type Endpoint4_18Request = Parameters<RawClient["server.session"]["session.revert.clear"]>[0]
|
type Endpoint4_17Request = Parameters<RawClient["server.session"]["session.revert.clear"]>[0]
|
||||||
type Endpoint4_18Input = { readonly sessionID: Endpoint4_18Request["params"]["sessionID"] }
|
type Endpoint4_17Input = { readonly sessionID: Endpoint4_17Request["params"]["sessionID"] }
|
||||||
const Endpoint4_18 = (raw: RawClient["server.session"]) => (input: Endpoint4_18Input) =>
|
const Endpoint4_17 = (raw: RawClient["server.session"]) => (input: Endpoint4_17Input) =>
|
||||||
raw["session.revert.clear"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
raw["session.revert.clear"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
type Endpoint4_19Request = Parameters<RawClient["server.session"]["session.revert.commit"]>[0]
|
type Endpoint4_18Request = Parameters<RawClient["server.session"]["session.revert.commit"]>[0]
|
||||||
type Endpoint4_19Input = { readonly sessionID: Endpoint4_19Request["params"]["sessionID"] }
|
type Endpoint4_18Input = { readonly sessionID: Endpoint4_18Request["params"]["sessionID"] }
|
||||||
const Endpoint4_19 = (raw: RawClient["server.session"]) => (input: Endpoint4_19Input) =>
|
const Endpoint4_18 = (raw: RawClient["server.session"]) => (input: Endpoint4_18Input) =>
|
||||||
raw["session.revert.commit"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
raw["session.revert.commit"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
type Endpoint4_20Request = Parameters<RawClient["server.session"]["session.context"]>[0]
|
type Endpoint4_19Request = Parameters<RawClient["server.session"]["session.context"]>[0]
|
||||||
type Endpoint4_20Input = { readonly sessionID: Endpoint4_20Request["params"]["sessionID"] }
|
type Endpoint4_19Input = { readonly sessionID: Endpoint4_19Request["params"]["sessionID"] }
|
||||||
const Endpoint4_20 = (raw: RawClient["server.session"]) => (input: Endpoint4_20Input) =>
|
const Endpoint4_19 = (raw: RawClient["server.session"]) => (input: Endpoint4_19Input) =>
|
||||||
raw["session.context"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
raw["session.context"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||||
Effect.mapError(mapClientError),
|
Effect.mapError(mapClientError),
|
||||||
Effect.map((value) => value.data),
|
Effect.map((value) => value.data),
|
||||||
)
|
)
|
||||||
|
|
||||||
type Endpoint4_21Request = Parameters<RawClient["server.session"]["session.instructions.entry.list"]>[0]
|
type Endpoint4_20Request = Parameters<RawClient["server.session"]["session.instructions.entry.list"]>[0]
|
||||||
type Endpoint4_21Input = { readonly sessionID: Endpoint4_21Request["params"]["sessionID"] }
|
type Endpoint4_20Input = { readonly sessionID: Endpoint4_20Request["params"]["sessionID"] }
|
||||||
const Endpoint4_21 = (raw: RawClient["server.session"]) => (input: Endpoint4_21Input) =>
|
const Endpoint4_20 = (raw: RawClient["server.session"]) => (input: Endpoint4_20Input) =>
|
||||||
raw["session.instructions.entry.list"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
raw["session.instructions.entry.list"]({ params: { sessionID: input["sessionID"] } }).pipe(
|
||||||
Effect.mapError(mapClientError),
|
Effect.mapError(mapClientError),
|
||||||
Effect.map((value) => value.data),
|
Effect.map((value) => value.data),
|
||||||
)
|
)
|
||||||
|
|
||||||
type Endpoint4_22Request = Parameters<RawClient["server.session"]["session.instructions.entry.put"]>[0]
|
type Endpoint4_21Request = Parameters<RawClient["server.session"]["session.instructions.entry.put"]>[0]
|
||||||
type Endpoint4_22Input = {
|
type Endpoint4_21Input = {
|
||||||
readonly sessionID: Endpoint4_22Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_21Request["params"]["sessionID"]
|
||||||
readonly key: Endpoint4_22Request["params"]["key"]
|
readonly key: Endpoint4_21Request["params"]["key"]
|
||||||
readonly value: Endpoint4_22Request["payload"]["value"]
|
readonly value: Endpoint4_21Request["payload"]["value"]
|
||||||
}
|
}
|
||||||
const Endpoint4_22 = (raw: RawClient["server.session"]) => (input: Endpoint4_22Input) =>
|
const Endpoint4_21 = (raw: RawClient["server.session"]) => (input: Endpoint4_21Input) =>
|
||||||
raw["session.instructions.entry.put"]({
|
raw["session.instructions.entry.put"]({
|
||||||
params: { sessionID: input["sessionID"], key: input["key"] },
|
params: { sessionID: input["sessionID"], key: input["key"] },
|
||||||
payload: { value: input["value"] },
|
payload: { value: input["value"] },
|
||||||
}).pipe(Effect.mapError(mapClientError))
|
}).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
type Endpoint4_23Request = Parameters<RawClient["server.session"]["session.instructions.entry.remove"]>[0]
|
type Endpoint4_22Request = Parameters<RawClient["server.session"]["session.instructions.entry.remove"]>[0]
|
||||||
type Endpoint4_23Input = {
|
type Endpoint4_22Input = {
|
||||||
readonly sessionID: Endpoint4_23Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_22Request["params"]["sessionID"]
|
||||||
readonly key: Endpoint4_23Request["params"]["key"]
|
readonly key: Endpoint4_22Request["params"]["key"]
|
||||||
}
|
}
|
||||||
const Endpoint4_23 = (raw: RawClient["server.session"]) => (input: Endpoint4_23Input) =>
|
const Endpoint4_22 = (raw: RawClient["server.session"]) => (input: Endpoint4_22Input) =>
|
||||||
raw["session.instructions.entry.remove"]({ params: { sessionID: input["sessionID"], key: input["key"] } }).pipe(
|
raw["session.instructions.entry.remove"]({ params: { sessionID: input["sessionID"], key: input["key"] } }).pipe(
|
||||||
Effect.mapError(mapClientError),
|
Effect.mapError(mapClientError),
|
||||||
)
|
)
|
||||||
|
|
||||||
type Endpoint4_24Request = Parameters<RawClient["server.session"]["session.log"]>[0]
|
type Endpoint4_23Request = Parameters<RawClient["server.session"]["session.log"]>[0]
|
||||||
type Endpoint4_24Input = {
|
type Endpoint4_23Input = {
|
||||||
readonly sessionID: Endpoint4_24Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_23Request["params"]["sessionID"]
|
||||||
readonly after?: Endpoint4_24Request["query"]["after"]
|
readonly after?: Endpoint4_23Request["query"]["after"]
|
||||||
readonly follow?: Endpoint4_24Request["query"]["follow"]
|
readonly follow?: Endpoint4_23Request["query"]["follow"]
|
||||||
}
|
}
|
||||||
const Endpoint4_24 = (raw: RawClient["server.session"]) => (input: Endpoint4_24Input) =>
|
const Endpoint4_23 = (raw: RawClient["server.session"]) => (input: Endpoint4_23Input) =>
|
||||||
Stream.unwrap(
|
Stream.unwrap(
|
||||||
raw["session.log"]({
|
raw["session.log"]({
|
||||||
params: { sessionID: input["sessionID"] },
|
params: { sessionID: input["sessionID"] },
|
||||||
@@ -342,22 +330,22 @@ const Endpoint4_24 = (raw: RawClient["server.session"]) => (input: Endpoint4_24I
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
type Endpoint4_25Request = Parameters<RawClient["server.session"]["session.interrupt"]>[0]
|
type Endpoint4_24Request = Parameters<RawClient["server.session"]["session.interrupt"]>[0]
|
||||||
type Endpoint4_25Input = { readonly sessionID: Endpoint4_25Request["params"]["sessionID"] }
|
type Endpoint4_24Input = { readonly sessionID: Endpoint4_24Request["params"]["sessionID"] }
|
||||||
const Endpoint4_25 = (raw: RawClient["server.session"]) => (input: Endpoint4_25Input) =>
|
const Endpoint4_24 = (raw: RawClient["server.session"]) => (input: Endpoint4_24Input) =>
|
||||||
raw["session.interrupt"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
raw["session.interrupt"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
type Endpoint4_26Request = Parameters<RawClient["server.session"]["session.background"]>[0]
|
type Endpoint4_25Request = Parameters<RawClient["server.session"]["session.background"]>[0]
|
||||||
type Endpoint4_26Input = { readonly sessionID: Endpoint4_26Request["params"]["sessionID"] }
|
type Endpoint4_25Input = { readonly sessionID: Endpoint4_25Request["params"]["sessionID"] }
|
||||||
const Endpoint4_26 = (raw: RawClient["server.session"]) => (input: Endpoint4_26Input) =>
|
const Endpoint4_25 = (raw: RawClient["server.session"]) => (input: Endpoint4_25Input) =>
|
||||||
raw["session.background"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
raw["session.background"]({ params: { sessionID: input["sessionID"] } }).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
type Endpoint4_27Request = Parameters<RawClient["server.session"]["session.message"]>[0]
|
type Endpoint4_26Request = Parameters<RawClient["server.session"]["session.message"]>[0]
|
||||||
type Endpoint4_27Input = {
|
type Endpoint4_26Input = {
|
||||||
readonly sessionID: Endpoint4_27Request["params"]["sessionID"]
|
readonly sessionID: Endpoint4_26Request["params"]["sessionID"]
|
||||||
readonly messageID: Endpoint4_27Request["params"]["messageID"]
|
readonly messageID: Endpoint4_26Request["params"]["messageID"]
|
||||||
}
|
}
|
||||||
const Endpoint4_27 = (raw: RawClient["server.session"]) => (input: Endpoint4_27Input) =>
|
const Endpoint4_26 = (raw: RawClient["server.session"]) => (input: Endpoint4_26Input) =>
|
||||||
raw["session.message"]({ params: { sessionID: input["sessionID"], messageID: input["messageID"] } }).pipe(
|
raw["session.message"]({ params: { sessionID: input["sessionID"], messageID: input["messageID"] } }).pipe(
|
||||||
Effect.mapError(mapClientError),
|
Effect.mapError(mapClientError),
|
||||||
Effect.map((value) => value.data),
|
Effect.map((value) => value.data),
|
||||||
@@ -373,21 +361,22 @@ const adaptGroup4 = (raw: RawClient["server.session"]) => ({
|
|||||||
switchAgent: Endpoint4_6(raw),
|
switchAgent: Endpoint4_6(raw),
|
||||||
switchModel: Endpoint4_7(raw),
|
switchModel: Endpoint4_7(raw),
|
||||||
rename: Endpoint4_8(raw),
|
rename: Endpoint4_8(raw),
|
||||||
move: Endpoint4_9(raw),
|
prompt: Endpoint4_9(raw),
|
||||||
prompt: Endpoint4_10(raw),
|
command: Endpoint4_10(raw),
|
||||||
command: Endpoint4_11(raw),
|
skill: Endpoint4_11(raw),
|
||||||
skill: Endpoint4_12(raw),
|
synthetic: Endpoint4_12(raw),
|
||||||
synthetic: Endpoint4_13(raw),
|
shell: Endpoint4_13(raw),
|
||||||
shell: Endpoint4_14(raw),
|
compact: Endpoint4_14(raw),
|
||||||
compact: Endpoint4_15(raw),
|
wait: Endpoint4_15(raw),
|
||||||
wait: Endpoint4_16(raw),
|
revertStage: Endpoint4_16(raw),
|
||||||
revert: { stage: Endpoint4_17(raw), clear: Endpoint4_18(raw), commit: Endpoint4_19(raw) },
|
revertClear: Endpoint4_17(raw),
|
||||||
context: Endpoint4_20(raw),
|
revertCommit: Endpoint4_18(raw),
|
||||||
instructions: { entry: { list: Endpoint4_21(raw), put: Endpoint4_22(raw), remove: Endpoint4_23(raw) } },
|
context: Endpoint4_19(raw),
|
||||||
log: Endpoint4_24(raw),
|
instructions: { entry: { list: Endpoint4_20(raw), put: Endpoint4_21(raw), remove: Endpoint4_22(raw) } },
|
||||||
interrupt: Endpoint4_25(raw),
|
log: Endpoint4_23(raw),
|
||||||
background: Endpoint4_26(raw),
|
interrupt: Endpoint4_24(raw),
|
||||||
message: Endpoint4_27(raw),
|
background: Endpoint4_25(raw),
|
||||||
|
message: Endpoint4_26(raw),
|
||||||
})
|
})
|
||||||
|
|
||||||
type Endpoint5_0Request = Parameters<RawClient["server.message"]["session.messages"]>[0]
|
type Endpoint5_0Request = Parameters<RawClient["server.message"]["session.messages"]>[0]
|
||||||
@@ -534,8 +523,11 @@ const Endpoint9_6 = (raw: RawClient["server.integration"]) => (input: Endpoint9_
|
|||||||
const adaptGroup9 = (raw: RawClient["server.integration"]) => ({
|
const adaptGroup9 = (raw: RawClient["server.integration"]) => ({
|
||||||
list: Endpoint9_0(raw),
|
list: Endpoint9_0(raw),
|
||||||
get: Endpoint9_1(raw),
|
get: Endpoint9_1(raw),
|
||||||
connect: { key: Endpoint9_2(raw), oauth: Endpoint9_3(raw) },
|
connectKey: Endpoint9_2(raw),
|
||||||
attempt: { status: Endpoint9_4(raw), complete: Endpoint9_5(raw), cancel: Endpoint9_6(raw) },
|
connectOauth: Endpoint9_3(raw),
|
||||||
|
attemptStatus: Endpoint9_4(raw),
|
||||||
|
attemptComplete: Endpoint9_5(raw),
|
||||||
|
attemptCancel: Endpoint9_6(raw),
|
||||||
})
|
})
|
||||||
|
|
||||||
type Endpoint10_0Request = Parameters<RawClient["server.mcp"]["mcp.list"]>[0]
|
type Endpoint10_0Request = Parameters<RawClient["server.mcp"]["mcp.list"]>[0]
|
||||||
@@ -548,10 +540,7 @@ type Endpoint10_1Input = { readonly location?: Endpoint10_1Request["query"]["loc
|
|||||||
const Endpoint10_1 = (raw: RawClient["server.mcp"]) => (input?: Endpoint10_1Input) =>
|
const Endpoint10_1 = (raw: RawClient["server.mcp"]) => (input?: Endpoint10_1Input) =>
|
||||||
raw["mcp.resource.catalog"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
raw["mcp.resource.catalog"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
const adaptGroup10 = (raw: RawClient["server.mcp"]) => ({
|
const adaptGroup10 = (raw: RawClient["server.mcp"]) => ({ list: Endpoint10_0(raw), catalog: Endpoint10_1(raw) })
|
||||||
list: Endpoint10_0(raw),
|
|
||||||
resource: { catalog: Endpoint10_1(raw) },
|
|
||||||
})
|
|
||||||
|
|
||||||
type Endpoint11_0Request = Parameters<RawClient["server.credential"]["credential.update"]>[0]
|
type Endpoint11_0Request = Parameters<RawClient["server.credential"]["credential.update"]>[0]
|
||||||
type Endpoint11_0Input = {
|
type Endpoint11_0Input = {
|
||||||
@@ -688,7 +677,7 @@ const Endpoint13_6 = (raw: RawClient["server.form"]) => (input: Endpoint13_6Inpu
|
|||||||
)
|
)
|
||||||
|
|
||||||
const adaptGroup13 = (raw: RawClient["server.form"]) => ({
|
const adaptGroup13 = (raw: RawClient["server.form"]) => ({
|
||||||
request: { list: Endpoint13_0(raw) },
|
listRequests: Endpoint13_0(raw),
|
||||||
list: Endpoint13_1(raw),
|
list: Endpoint13_1(raw),
|
||||||
create: Endpoint13_2(raw),
|
create: Endpoint13_2(raw),
|
||||||
get: Endpoint13_3(raw),
|
get: Endpoint13_3(raw),
|
||||||
@@ -776,8 +765,9 @@ const Endpoint14_6 = (raw: RawClient["server.permission"]) => (input: Endpoint14
|
|||||||
}).pipe(Effect.mapError(mapClientError))
|
}).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
const adaptGroup14 = (raw: RawClient["server.permission"]) => ({
|
const adaptGroup14 = (raw: RawClient["server.permission"]) => ({
|
||||||
request: { list: Endpoint14_0(raw) },
|
listRequests: Endpoint14_0(raw),
|
||||||
saved: { list: Endpoint14_1(raw), remove: Endpoint14_2(raw) },
|
listSaved: Endpoint14_1(raw),
|
||||||
|
removeSaved: Endpoint14_2(raw),
|
||||||
create: Endpoint14_3(raw),
|
create: Endpoint14_3(raw),
|
||||||
list: Endpoint14_4(raw),
|
list: Endpoint14_4(raw),
|
||||||
get: Endpoint14_5(raw),
|
get: Endpoint14_5(raw),
|
||||||
@@ -1010,7 +1000,7 @@ const Endpoint21_3 = (raw: RawClient["server.question"]) => (input: Endpoint21_3
|
|||||||
)
|
)
|
||||||
|
|
||||||
const adaptGroup21 = (raw: RawClient["server.question"]) => ({
|
const adaptGroup21 = (raw: RawClient["server.question"]) => ({
|
||||||
request: { list: Endpoint21_0(raw) },
|
listRequests: Endpoint21_0(raw),
|
||||||
list: Endpoint21_1(raw),
|
list: Endpoint21_1(raw),
|
||||||
reply: Endpoint21_2(raw),
|
reply: Endpoint21_2(raw),
|
||||||
reject: Endpoint21_3(raw),
|
reject: Endpoint21_3(raw),
|
||||||
@@ -1096,7 +1086,8 @@ const Endpoint25_1 = (raw: RawClient["server.debug"]) => (input?: Endpoint25_1In
|
|||||||
raw["debug.location.evict"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
raw["debug.location.evict"]({ query: { location: input?.["location"] } }).pipe(Effect.mapError(mapClientError))
|
||||||
|
|
||||||
const adaptGroup25 = (raw: RawClient["server.debug"]) => ({
|
const adaptGroup25 = (raw: RawClient["server.debug"]) => ({
|
||||||
location: { list: Endpoint25_0(raw), evict: Endpoint25_1(raw) },
|
location: Endpoint25_0(raw),
|
||||||
|
evictLocation: Endpoint25_1(raw),
|
||||||
})
|
})
|
||||||
|
|
||||||
const adaptClient = (raw: RawClient) => ({
|
const adaptClient = (raw: RawClient) => ({
|
||||||
|
|||||||
@@ -23,8 +23,6 @@ import type {
|
|||||||
SessionSwitchModelOutput,
|
SessionSwitchModelOutput,
|
||||||
SessionRenameInput,
|
SessionRenameInput,
|
||||||
SessionRenameOutput,
|
SessionRenameOutput,
|
||||||
SessionMoveInput,
|
|
||||||
SessionMoveOutput,
|
|
||||||
SessionPromptInput,
|
SessionPromptInput,
|
||||||
SessionPromptOutput,
|
SessionPromptOutput,
|
||||||
SessionCommandInput,
|
SessionCommandInput,
|
||||||
@@ -89,8 +87,8 @@ import type {
|
|||||||
IntegrationAttemptCancelOutput,
|
IntegrationAttemptCancelOutput,
|
||||||
ServerMcpListInput,
|
ServerMcpListInput,
|
||||||
ServerMcpListOutput,
|
ServerMcpListOutput,
|
||||||
ServerMcpResourceCatalogInput,
|
ServerMcpCatalogInput,
|
||||||
ServerMcpResourceCatalogOutput,
|
ServerMcpCatalogOutput,
|
||||||
CredentialUpdateInput,
|
CredentialUpdateInput,
|
||||||
CredentialUpdateOutput,
|
CredentialUpdateOutput,
|
||||||
CredentialRemoveInput,
|
CredentialRemoveInput,
|
||||||
@@ -100,8 +98,8 @@ import type {
|
|||||||
ProjectCurrentOutput,
|
ProjectCurrentOutput,
|
||||||
ProjectDirectoriesInput,
|
ProjectDirectoriesInput,
|
||||||
ProjectDirectoriesOutput,
|
ProjectDirectoriesOutput,
|
||||||
FormRequestListInput,
|
FormListRequestsInput,
|
||||||
FormRequestListOutput,
|
FormListRequestsOutput,
|
||||||
FormListInput,
|
FormListInput,
|
||||||
FormListOutput,
|
FormListOutput,
|
||||||
FormCreateInput,
|
FormCreateInput,
|
||||||
@@ -114,12 +112,12 @@ import type {
|
|||||||
FormReplyOutput,
|
FormReplyOutput,
|
||||||
FormCancelInput,
|
FormCancelInput,
|
||||||
FormCancelOutput,
|
FormCancelOutput,
|
||||||
PermissionRequestListInput,
|
PermissionListRequestsInput,
|
||||||
PermissionRequestListOutput,
|
PermissionListRequestsOutput,
|
||||||
PermissionSavedListInput,
|
PermissionListSavedInput,
|
||||||
PermissionSavedListOutput,
|
PermissionListSavedOutput,
|
||||||
PermissionSavedRemoveInput,
|
PermissionRemoveSavedInput,
|
||||||
PermissionSavedRemoveOutput,
|
PermissionRemoveSavedOutput,
|
||||||
PermissionCreateInput,
|
PermissionCreateInput,
|
||||||
PermissionCreateOutput,
|
PermissionCreateOutput,
|
||||||
PermissionListInput,
|
PermissionListInput,
|
||||||
@@ -161,8 +159,8 @@ import type {
|
|||||||
ShellOutputOutput,
|
ShellOutputOutput,
|
||||||
ShellRemoveInput,
|
ShellRemoveInput,
|
||||||
ShellRemoveOutput,
|
ShellRemoveOutput,
|
||||||
QuestionRequestListInput,
|
QuestionListRequestsInput,
|
||||||
QuestionRequestListOutput,
|
QuestionListRequestsOutput,
|
||||||
QuestionListInput,
|
QuestionListInput,
|
||||||
QuestionListOutput,
|
QuestionListOutput,
|
||||||
QuestionReplyInput,
|
QuestionReplyInput,
|
||||||
@@ -181,9 +179,9 @@ import type {
|
|||||||
VcsStatusOutput,
|
VcsStatusOutput,
|
||||||
VcsDiffInput,
|
VcsDiffInput,
|
||||||
VcsDiffOutput,
|
VcsDiffOutput,
|
||||||
DebugLocationListOutput,
|
DebugLocationOutput,
|
||||||
DebugLocationEvictInput,
|
DebugEvictLocationInput,
|
||||||
DebugLocationEvictOutput,
|
DebugEvictLocationOutput,
|
||||||
} from "./types"
|
} from "./types"
|
||||||
import { ClientError } from "./client-error"
|
import { ClientError } from "./client-error"
|
||||||
|
|
||||||
@@ -491,18 +489,6 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
move: (input: SessionMoveInput, requestOptions?: RequestOptions) =>
|
|
||||||
request<SessionMoveOutput>(
|
|
||||||
{
|
|
||||||
method: "POST",
|
|
||||||
path: `/api/session/${encodeURIComponent(input.sessionID)}/move`,
|
|
||||||
body: { destination: input["destination"], moveChanges: input["moveChanges"] },
|
|
||||||
successStatus: 204,
|
|
||||||
declaredStatuses: [404, 400, 401],
|
|
||||||
empty: true,
|
|
||||||
},
|
|
||||||
requestOptions,
|
|
||||||
),
|
|
||||||
prompt: (input: SessionPromptInput, requestOptions?: RequestOptions) =>
|
prompt: (input: SessionPromptInput, requestOptions?: RequestOptions) =>
|
||||||
request<{ readonly data: SessionPromptOutput }>(
|
request<{ readonly data: SessionPromptOutput }>(
|
||||||
{
|
{
|
||||||
@@ -601,8 +587,7 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
revert: {
|
revertStage: (input: SessionRevertStageInput, requestOptions?: RequestOptions) =>
|
||||||
stage: (input: SessionRevertStageInput, requestOptions?: RequestOptions) =>
|
|
||||||
request<{ readonly data: SessionRevertStageOutput }>(
|
request<{ readonly data: SessionRevertStageOutput }>(
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -614,7 +599,7 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
).then((value) => value.data),
|
).then((value) => value.data),
|
||||||
clear: (input: SessionRevertClearInput, requestOptions?: RequestOptions) =>
|
revertClear: (input: SessionRevertClearInput, requestOptions?: RequestOptions) =>
|
||||||
request<SessionRevertClearOutput>(
|
request<SessionRevertClearOutput>(
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -625,7 +610,7 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
commit: (input: SessionRevertCommitInput, requestOptions?: RequestOptions) =>
|
revertCommit: (input: SessionRevertCommitInput, requestOptions?: RequestOptions) =>
|
||||||
request<SessionRevertCommitOutput>(
|
request<SessionRevertCommitOutput>(
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -636,7 +621,6 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
},
|
|
||||||
context: (input: SessionContextInput, requestOptions?: RequestOptions) =>
|
context: (input: SessionContextInput, requestOptions?: RequestOptions) =>
|
||||||
request<{ readonly data: SessionContextOutput }>(
|
request<{ readonly data: SessionContextOutput }>(
|
||||||
{
|
{
|
||||||
@@ -838,8 +822,7 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
connect: {
|
connectKey: (input: IntegrationConnectKeyInput, requestOptions?: RequestOptions) =>
|
||||||
key: (input: IntegrationConnectKeyInput, requestOptions?: RequestOptions) =>
|
|
||||||
request<IntegrationConnectKeyOutput>(
|
request<IntegrationConnectKeyOutput>(
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -852,7 +835,7 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
oauth: (input: IntegrationConnectOauthInput, requestOptions?: RequestOptions) =>
|
connectOauth: (input: IntegrationConnectOauthInput, requestOptions?: RequestOptions) =>
|
||||||
request<IntegrationConnectOauthOutput>(
|
request<IntegrationConnectOauthOutput>(
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -865,9 +848,7 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
},
|
attemptStatus: (input: IntegrationAttemptStatusInput, requestOptions?: RequestOptions) =>
|
||||||
attempt: {
|
|
||||||
status: (input: IntegrationAttemptStatusInput, requestOptions?: RequestOptions) =>
|
|
||||||
request<IntegrationAttemptStatusOutput>(
|
request<IntegrationAttemptStatusOutput>(
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
@@ -879,7 +860,7 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
complete: (input: IntegrationAttemptCompleteInput, requestOptions?: RequestOptions) =>
|
attemptComplete: (input: IntegrationAttemptCompleteInput, requestOptions?: RequestOptions) =>
|
||||||
request<IntegrationAttemptCompleteOutput>(
|
request<IntegrationAttemptCompleteOutput>(
|
||||||
{
|
{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@@ -892,7 +873,7 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
cancel: (input: IntegrationAttemptCancelInput, requestOptions?: RequestOptions) =>
|
attemptCancel: (input: IntegrationAttemptCancelInput, requestOptions?: RequestOptions) =>
|
||||||
request<IntegrationAttemptCancelOutput>(
|
request<IntegrationAttemptCancelOutput>(
|
||||||
{
|
{
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
@@ -905,7 +886,6 @@ export function make(options: ClientOptions) {
|
|||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
|
||||||
"server.mcp": {
|
"server.mcp": {
|
||||||
list: (input?: ServerMcpListInput, requestOptions?: RequestOptions) =>
|
list: (input?: ServerMcpListInput, requestOptions?: RequestOptions) =>
|
||||||
request<ServerMcpListOutput>(
|
request<ServerMcpListOutput>(
|
||||||
@@ -919,9 +899,8 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
resource: {
|
catalog: (input?: ServerMcpCatalogInput, requestOptions?: RequestOptions) =>
|
||||||
catalog: (input?: ServerMcpResourceCatalogInput, requestOptions?: RequestOptions) =>
|
request<ServerMcpCatalogOutput>(
|
||||||
request<ServerMcpResourceCatalogOutput>(
|
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
path: `/api/mcp/resource`,
|
path: `/api/mcp/resource`,
|
||||||
@@ -933,7 +912,6 @@ export function make(options: ClientOptions) {
|
|||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
|
||||||
credential: {
|
credential: {
|
||||||
update: (input: CredentialUpdateInput, requestOptions?: RequestOptions) =>
|
update: (input: CredentialUpdateInput, requestOptions?: RequestOptions) =>
|
||||||
request<CredentialUpdateOutput>(
|
request<CredentialUpdateOutput>(
|
||||||
@@ -993,9 +971,8 @@ export function make(options: ClientOptions) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
request: {
|
listRequests: (input?: FormListRequestsInput, requestOptions?: RequestOptions) =>
|
||||||
list: (input?: FormRequestListInput, requestOptions?: RequestOptions) =>
|
request<FormListRequestsOutput>(
|
||||||
request<FormRequestListOutput>(
|
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
path: `/api/form/request`,
|
path: `/api/form/request`,
|
||||||
@@ -1006,7 +983,6 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
},
|
|
||||||
list: (input: FormListInput, requestOptions?: RequestOptions) =>
|
list: (input: FormListInput, requestOptions?: RequestOptions) =>
|
||||||
request<{ readonly data: FormListOutput }>(
|
request<{ readonly data: FormListOutput }>(
|
||||||
{
|
{
|
||||||
@@ -1084,9 +1060,8 @@ export function make(options: ClientOptions) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
permission: {
|
permission: {
|
||||||
request: {
|
listRequests: (input?: PermissionListRequestsInput, requestOptions?: RequestOptions) =>
|
||||||
list: (input?: PermissionRequestListInput, requestOptions?: RequestOptions) =>
|
request<PermissionListRequestsOutput>(
|
||||||
request<PermissionRequestListOutput>(
|
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
path: `/api/permission/request`,
|
path: `/api/permission/request`,
|
||||||
@@ -1097,10 +1072,8 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
},
|
listSaved: (input?: PermissionListSavedInput, requestOptions?: RequestOptions) =>
|
||||||
saved: {
|
request<{ readonly data: PermissionListSavedOutput }>(
|
||||||
list: (input?: PermissionSavedListInput, requestOptions?: RequestOptions) =>
|
|
||||||
request<{ readonly data: PermissionSavedListOutput }>(
|
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
path: `/api/permission/saved`,
|
path: `/api/permission/saved`,
|
||||||
@@ -1111,8 +1084,8 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
).then((value) => value.data),
|
).then((value) => value.data),
|
||||||
remove: (input: PermissionSavedRemoveInput, requestOptions?: RequestOptions) =>
|
removeSaved: (input: PermissionRemoveSavedInput, requestOptions?: RequestOptions) =>
|
||||||
request<PermissionSavedRemoveOutput>(
|
request<PermissionRemoveSavedOutput>(
|
||||||
{
|
{
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
path: `/api/permission/saved/${encodeURIComponent(input.id)}`,
|
path: `/api/permission/saved/${encodeURIComponent(input.id)}`,
|
||||||
@@ -1122,7 +1095,6 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
},
|
|
||||||
create: (input: PermissionCreateInput, requestOptions?: RequestOptions) =>
|
create: (input: PermissionCreateInput, requestOptions?: RequestOptions) =>
|
||||||
request<{ readonly data: PermissionCreateOutput }>(
|
request<{ readonly data: PermissionCreateOutput }>(
|
||||||
{
|
{
|
||||||
@@ -1404,9 +1376,8 @@ export function make(options: ClientOptions) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
question: {
|
question: {
|
||||||
request: {
|
listRequests: (input?: QuestionListRequestsInput, requestOptions?: RequestOptions) =>
|
||||||
list: (input?: QuestionRequestListInput, requestOptions?: RequestOptions) =>
|
request<QuestionListRequestsOutput>(
|
||||||
request<QuestionRequestListOutput>(
|
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
path: `/api/question/request`,
|
path: `/api/question/request`,
|
||||||
@@ -1417,7 +1388,6 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
},
|
|
||||||
list: (input: QuestionListInput, requestOptions?: RequestOptions) =>
|
list: (input: QuestionListInput, requestOptions?: RequestOptions) =>
|
||||||
request<{ readonly data: QuestionListOutput }>(
|
request<{ readonly data: QuestionListOutput }>(
|
||||||
{
|
{
|
||||||
@@ -1534,9 +1504,8 @@ export function make(options: ClientOptions) {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
debug: {
|
debug: {
|
||||||
location: {
|
location: (requestOptions?: RequestOptions) =>
|
||||||
list: (requestOptions?: RequestOptions) =>
|
request<DebugLocationOutput>(
|
||||||
request<DebugLocationListOutput>(
|
|
||||||
{
|
{
|
||||||
method: "GET",
|
method: "GET",
|
||||||
path: `/api/debug/location`,
|
path: `/api/debug/location`,
|
||||||
@@ -1546,8 +1515,8 @@ export function make(options: ClientOptions) {
|
|||||||
},
|
},
|
||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
evict: (input?: DebugLocationEvictInput, requestOptions?: RequestOptions) =>
|
evictLocation: (input?: DebugEvictLocationInput, requestOptions?: RequestOptions) =>
|
||||||
request<DebugLocationEvictOutput>(
|
request<DebugEvictLocationOutput>(
|
||||||
{
|
{
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
path: `/api/debug/location`,
|
path: `/api/debug/location`,
|
||||||
@@ -1559,7 +1528,6 @@ export function make(options: ClientOptions) {
|
|||||||
requestOptions,
|
requestOptions,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -526,20 +526,6 @@ export type SessionRenameInput = {
|
|||||||
|
|
||||||
export type SessionRenameOutput = void
|
export type SessionRenameOutput = void
|
||||||
|
|
||||||
export type SessionMoveInput = {
|
|
||||||
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
|
||||||
readonly destination: {
|
|
||||||
readonly destination: { readonly directory: string }
|
|
||||||
readonly moveChanges?: boolean | undefined
|
|
||||||
}["destination"]
|
|
||||||
readonly moveChanges?: {
|
|
||||||
readonly destination: { readonly directory: string }
|
|
||||||
readonly moveChanges?: boolean | undefined
|
|
||||||
}["moveChanges"]
|
|
||||||
}
|
|
||||||
|
|
||||||
export type SessionMoveOutput = void
|
|
||||||
|
|
||||||
export type SessionPromptInput = {
|
export type SessionPromptInput = {
|
||||||
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
||||||
readonly id?: {
|
readonly id?: {
|
||||||
@@ -1439,13 +1425,6 @@ export type SessionLogOutput =
|
|||||||
readonly sessionID: string
|
readonly sessionID: string
|
||||||
readonly assistantMessageID: string
|
readonly assistantMessageID: string
|
||||||
readonly error: { readonly type: string; readonly message: string }
|
readonly error: { readonly type: string; readonly message: string }
|
||||||
readonly cost?: number
|
|
||||||
readonly tokens?: {
|
|
||||||
readonly input: number
|
|
||||||
readonly output: number
|
|
||||||
readonly reasoning: number
|
|
||||||
readonly cache: { readonly read: number; readonly write: number }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
@@ -2508,13 +2487,13 @@ export type ServerMcpListOutput = {
|
|||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ServerMcpResourceCatalogInput = {
|
export type ServerMcpCatalogInput = {
|
||||||
readonly location?: {
|
readonly location?: {
|
||||||
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
||||||
}["location"]
|
}["location"]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ServerMcpResourceCatalogOutput = {
|
export type ServerMcpCatalogOutput = {
|
||||||
readonly location: {
|
readonly location: {
|
||||||
readonly directory: string
|
readonly directory: string
|
||||||
readonly workspaceID?: string
|
readonly workspaceID?: string
|
||||||
@@ -2585,13 +2564,13 @@ export type ProjectDirectoriesInput = {
|
|||||||
|
|
||||||
export type ProjectDirectoriesOutput = ReadonlyArray<{ readonly directory: string; readonly strategy?: string }>
|
export type ProjectDirectoriesOutput = ReadonlyArray<{ readonly directory: string; readonly strategy?: string }>
|
||||||
|
|
||||||
export type FormRequestListInput = {
|
export type FormListRequestsInput = {
|
||||||
readonly location?: {
|
readonly location?: {
|
||||||
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
||||||
}["location"]
|
}["location"]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FormRequestListOutput = {
|
export type FormListRequestsOutput = {
|
||||||
readonly location: {
|
readonly location: {
|
||||||
readonly directory: string
|
readonly directory: string
|
||||||
readonly workspaceID?: string
|
readonly workspaceID?: string
|
||||||
@@ -3659,13 +3638,13 @@ export type FormCancelInput = {
|
|||||||
|
|
||||||
export type FormCancelOutput = void
|
export type FormCancelOutput = void
|
||||||
|
|
||||||
export type PermissionRequestListInput = {
|
export type PermissionListRequestsInput = {
|
||||||
readonly location?: {
|
readonly location?: {
|
||||||
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
||||||
}["location"]
|
}["location"]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PermissionRequestListOutput = {
|
export type PermissionListRequestsOutput = {
|
||||||
readonly location: {
|
readonly location: {
|
||||||
readonly directory: string
|
readonly directory: string
|
||||||
readonly workspaceID?: string
|
readonly workspaceID?: string
|
||||||
@@ -3682,9 +3661,9 @@ export type PermissionRequestListOutput = {
|
|||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PermissionSavedListInput = { readonly projectID?: { readonly projectID?: string | undefined }["projectID"] }
|
export type PermissionListSavedInput = { readonly projectID?: { readonly projectID?: string | undefined }["projectID"] }
|
||||||
|
|
||||||
export type PermissionSavedListOutput = {
|
export type PermissionListSavedOutput = {
|
||||||
readonly data: ReadonlyArray<{
|
readonly data: ReadonlyArray<{
|
||||||
readonly id: string
|
readonly id: string
|
||||||
readonly projectID: string
|
readonly projectID: string
|
||||||
@@ -3693,9 +3672,9 @@ export type PermissionSavedListOutput = {
|
|||||||
}>
|
}>
|
||||||
}["data"]
|
}["data"]
|
||||||
|
|
||||||
export type PermissionSavedRemoveInput = { readonly id: { readonly id: string }["id"] }
|
export type PermissionRemoveSavedInput = { readonly id: { readonly id: string }["id"] }
|
||||||
|
|
||||||
export type PermissionSavedRemoveOutput = void
|
export type PermissionRemoveSavedOutput = void
|
||||||
|
|
||||||
export type PermissionCreateInput = {
|
export type PermissionCreateInput = {
|
||||||
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
readonly sessionID: { readonly sessionID: string }["sessionID"]
|
||||||
@@ -4549,23 +4528,6 @@ export type EventSubscribeOutput =
|
|||||||
readonly location?: { readonly directory: string; readonly workspaceID?: string }
|
readonly location?: { readonly directory: string; readonly workspaceID?: string }
|
||||||
readonly data: { readonly sessionID: string; readonly title: string }
|
readonly data: { readonly sessionID: string; readonly title: string }
|
||||||
}
|
}
|
||||||
| {
|
|
||||||
readonly id: string
|
|
||||||
readonly created: number
|
|
||||||
readonly metadata?: { readonly [x: string]: unknown }
|
|
||||||
readonly type: "session.usage.updated"
|
|
||||||
readonly location?: { readonly directory: string; readonly workspaceID?: string }
|
|
||||||
readonly data: {
|
|
||||||
readonly sessionID: string
|
|
||||||
readonly cost: number
|
|
||||||
readonly tokens: {
|
|
||||||
readonly input: number
|
|
||||||
readonly output: number
|
|
||||||
readonly reasoning: number
|
|
||||||
readonly cache: { readonly read: number; readonly write: number }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
| {
|
| {
|
||||||
readonly id: string
|
readonly id: string
|
||||||
readonly created: number
|
readonly created: number
|
||||||
@@ -4789,13 +4751,6 @@ export type EventSubscribeOutput =
|
|||||||
readonly sessionID: string
|
readonly sessionID: string
|
||||||
readonly assistantMessageID: string
|
readonly assistantMessageID: string
|
||||||
readonly error: { readonly type: string; readonly message: string }
|
readonly error: { readonly type: string; readonly message: string }
|
||||||
readonly cost?: number
|
|
||||||
readonly tokens?: {
|
|
||||||
readonly input: number
|
|
||||||
readonly output: number
|
|
||||||
readonly reasoning: number
|
|
||||||
readonly cache: { readonly read: number; readonly write: number }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
@@ -6049,13 +6004,13 @@ export type ShellRemoveInput = {
|
|||||||
|
|
||||||
export type ShellRemoveOutput = void
|
export type ShellRemoveOutput = void
|
||||||
|
|
||||||
export type QuestionRequestListInput = {
|
export type QuestionListRequestsInput = {
|
||||||
readonly location?: {
|
readonly location?: {
|
||||||
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
||||||
}["location"]
|
}["location"]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type QuestionRequestListOutput = {
|
export type QuestionListRequestsOutput = {
|
||||||
readonly location: {
|
readonly location: {
|
||||||
readonly directory: string
|
readonly directory: string
|
||||||
readonly workspaceID?: string
|
readonly workspaceID?: string
|
||||||
@@ -6221,12 +6176,12 @@ export type VcsDiffOutput = {
|
|||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DebugLocationListOutput = ReadonlyArray<{ readonly directory: string; readonly workspaceID?: string }>
|
export type DebugLocationOutput = ReadonlyArray<{ readonly directory: string; readonly workspaceID?: string }>
|
||||||
|
|
||||||
export type DebugLocationEvictInput = {
|
export type DebugEvictLocationInput = {
|
||||||
readonly location?: {
|
readonly location?: {
|
||||||
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
readonly location?: { readonly directory?: string | undefined; readonly workspace?: string | undefined } | undefined
|
||||||
}["location"]
|
}["location"]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DebugLocationEvictOutput = void
|
export type DebugEvictLocationOutput = void
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import { SessionMessage } from "@opencode-ai/schema/session-message"
|
|||||||
import { Workspace } from "@opencode-ai/schema/workspace"
|
import { Workspace } from "@opencode-ai/schema/workspace"
|
||||||
import { Api } from "@opencode-ai/server/api"
|
import { Api } from "@opencode-ai/server/api"
|
||||||
import { compile, emitPromise } from "@opencode-ai/httpapi-codegen"
|
import { compile, emitPromise } from "@opencode-ai/httpapi-codegen"
|
||||||
import { ClientApi, groupNames, promiseOmitEndpoints } from "../src/contract"
|
import { ClientApi, endpointNames, groupNames, promiseOmitEndpoints } from "../src/contract"
|
||||||
|
|
||||||
const Client = await import("../src/effect")
|
const Client = await import("../src/effect")
|
||||||
|
|
||||||
@@ -49,8 +49,8 @@ test("Core and Server reuse the authoritative Schema and Protocol values", () =>
|
|||||||
})
|
})
|
||||||
|
|
||||||
test("client and Server contracts generate identically", () => {
|
test("client and Server contracts generate identically", () => {
|
||||||
const server = compile(Api, { groupNames, omitEndpoints: promiseOmitEndpoints })
|
const server = compile(Api, { groupNames, endpointNames, omitEndpoints: promiseOmitEndpoints })
|
||||||
const client = compile(ClientApi, { groupNames, omitEndpoints: promiseOmitEndpoints })
|
const client = compile(ClientApi, { groupNames, endpointNames, omitEndpoints: promiseOmitEndpoints })
|
||||||
|
|
||||||
expect(emitPromise(client)).toEqual(emitPromise(server))
|
expect(emitPromise(client)).toEqual(emitPromise(server))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -33,11 +33,16 @@ test("exposes every standard HTTP API group", () => {
|
|||||||
"debug",
|
"debug",
|
||||||
])
|
])
|
||||||
expect(Object.keys(client.debug)).toEqual(["location"])
|
expect(Object.keys(client.debug)).toEqual(["location"])
|
||||||
expect(Object.keys(client.debug.location)).toEqual(["list", "evict"])
|
|
||||||
expect(Object.keys(client.message)).toEqual(["list"])
|
expect(Object.keys(client.message)).toEqual(["list"])
|
||||||
expect(Object.keys(client.integration)).toEqual(["list", "get", "connect", "attempt"])
|
expect(Object.keys(client.integration)).toEqual([
|
||||||
expect(Object.keys(client.integration.connect)).toEqual(["key", "oauth"])
|
"list",
|
||||||
expect(Object.keys(client.integration.attempt)).toEqual(["status", "complete", "cancel"])
|
"get",
|
||||||
|
"connectKey",
|
||||||
|
"connectOauth",
|
||||||
|
"attemptStatus",
|
||||||
|
"attemptComplete",
|
||||||
|
"attemptCancel",
|
||||||
|
])
|
||||||
expect(Object.keys(client.file)).toEqual(["read", "list", "find"])
|
expect(Object.keys(client.file)).toEqual(["read", "list", "find"])
|
||||||
expect(Object.keys(client.vcs)).toEqual(["status", "diff"])
|
expect(Object.keys(client.vcs)).toEqual(["status", "diff"])
|
||||||
expect(Object.keys(client.pty)).toEqual(["list", "create", "get", "update", "remove"])
|
expect(Object.keys(client.pty)).toEqual(["list", "create", "get", "update", "remove"])
|
||||||
@@ -61,7 +66,7 @@ test("MCP resource catalog uses the public HTTP contract", async () => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const result = await client["server.mcp"].resource.catalog({ location: { directory: "/tmp/project" } })
|
const result = await client["server.mcp"].catalog({ location: { directory: "/tmp/project" } })
|
||||||
|
|
||||||
expect(result.data.resources[0]?.uri).toBe("docs://readme")
|
expect(result.data.resources[0]?.uri).toBe("docs://readme")
|
||||||
expect(request?.method).toBe("GET")
|
expect(request?.method).toBe("GET")
|
||||||
|
|||||||
+3186
-3410
File diff suppressed because it is too large
Load Diff
@@ -177,13 +177,13 @@ describe("OpenAPI.fromSpec", () => {
|
|||||||
const spec = await opencodeSpec()
|
const spec = await opencodeSpec()
|
||||||
const result = OpenAPI.fromSpec({ spec, baseUrl })
|
const result = OpenAPI.fromSpec({ spec, baseUrl })
|
||||||
|
|
||||||
expect(result.skipped).toHaveLength(4)
|
expect(result.skipped).toHaveLength(5)
|
||||||
expect(result.skipped).toContainEqual({
|
expect(result.skipped).toContainEqual({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
path: "/api/pty/{ptyID}/connect",
|
path: "/api/pty/{ptyID}/connect",
|
||||||
reason: "WebSocket operations are not supported",
|
reason: "WebSocket operations are not supported",
|
||||||
})
|
})
|
||||||
expect(result.skipped.filter((item) => item.reason === "SSE operations are not supported")).toHaveLength(2)
|
expect(result.skipped.filter((item) => item.reason === "SSE operations are not supported")).toHaveLength(3)
|
||||||
expect(result.skipped).toContainEqual({
|
expect(result.skipped).toContainEqual({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
path: "/api/fs/read/*",
|
path: "/api/fs/read/*",
|
||||||
@@ -210,11 +210,11 @@ describe("OpenAPI.fromSpec", () => {
|
|||||||
if (!Tool.isDefinition(instructionPut)) throw new Error("v2.session.instructions.entry.put was not generated")
|
if (!Tool.isDefinition(instructionPut)) throw new Error("v2.session.instructions.entry.put was not generated")
|
||||||
expect(inputTypeScript(instructionPut)).toBe("{ sessionID: string; key: string; value: unknown }")
|
expect(inputTypeScript(instructionPut)).toBe("{ sessionID: string; key: string; value: unknown }")
|
||||||
expect(toolAt(result.tools, "v2_session_instructions_entry_put_2")).toBeUndefined()
|
expect(toolAt(result.tools, "v2_session_instructions_entry_put_2")).toBeUndefined()
|
||||||
expect(Tool.isDefinition(toolAt(result.tools, "v2.pty.connect"))).toBe(false)
|
expect(toolAt(result.tools, "v2.pty.connect")).toBeUndefined()
|
||||||
expect(toolAt(result.tools, "v2.session.log")).toBeUndefined()
|
expect(toolAt(result.tools, "v2.session.log")).toBeUndefined()
|
||||||
expect(toolAt(result.tools, "v2.event.subscribe")).toBeUndefined()
|
expect(toolAt(result.tools, "v2.event.subscribe")).toBeUndefined()
|
||||||
expect(toolAt(result.tools, "v2.fs.read")).toBeUndefined()
|
expect(toolAt(result.tools, "v2.fs.read")).toBeUndefined()
|
||||||
expect(toolAt(result.tools, "v2.pty.connect.token")).not.toBeUndefined()
|
expect(toolAt(result.tools, "v2.pty.connectToken")).not.toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("preserves operation path sanitization and collision handling", () => {
|
test("preserves operation path sanitization and collision handling", () => {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import type {
|
|||||||
JSONValue,
|
JSONValue,
|
||||||
LanguageModelV3,
|
LanguageModelV3,
|
||||||
LanguageModelV3CallOptions,
|
LanguageModelV3CallOptions,
|
||||||
LanguageModelV3FinishReason,
|
|
||||||
LanguageModelV3FunctionTool,
|
LanguageModelV3FunctionTool,
|
||||||
LanguageModelV3Message,
|
LanguageModelV3Message,
|
||||||
LanguageModelV3Prompt,
|
LanguageModelV3Prompt,
|
||||||
@@ -625,8 +624,8 @@ function usage(input: Extract<LanguageModelV3StreamPart, { type: "finish" }>["us
|
|||||||
return Object.values(output).some((value) => value !== undefined) ? output : undefined
|
return Object.values(output).some((value) => value !== undefined) ? output : undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishReason(value: LanguageModelV3FinishReason): FinishReason {
|
function finishReason(value: unknown): FinishReason {
|
||||||
return value.unified === "other" ? "unknown" : value.unified
|
return Schema.is(FinishReason)(value) ? value : "unknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
function providerMetadata(value: unknown) {
|
function providerMetadata(value: unknown) {
|
||||||
|
|||||||
@@ -200,6 +200,6 @@ export const node = makeLocationNode({ service: Service, layer, deps: [FSUtil.no
|
|||||||
// TODO: Publish watcher/file-edit events after V2 watcher integration exists.
|
// TODO: Publish watcher/file-edit events after V2 watcher integration exists.
|
||||||
// TODO: Add snapshots / undo after V2 snapshot design exists.
|
// TODO: Add snapshots / undo after V2 snapshot design exists.
|
||||||
// TODO: Notify LSP and collect diagnostics after V2 LSP runtime exists.
|
// TODO: Notify LSP and collect diagnostics after V2 LSP runtime exists.
|
||||||
// TODO: Design multi-file transactions / rollback if patch needs atomic edits.
|
// TODO: Design multi-file transactions / rollback if apply_patch needs atomic edits.
|
||||||
// Until then, edits are sequential and report partial application.
|
// Until then, edits are sequential and report partial application.
|
||||||
// TODO: Define crash recovery and idempotency for side effects between Tool.Called and durable settlement.
|
// TODO: Define crash recovery and idempotency for side effects between Tool.Called and durable settlement.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as PluginV2 from "./plugin"
|
export * as PluginV2 from "./plugin"
|
||||||
|
|
||||||
import type { Plugin } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { Plugin } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Event, ID, type Info } from "@opencode-ai/schema/plugin"
|
import { Event, ID, type Info } from "@opencode-ai/schema/plugin"
|
||||||
import { makeLocationNode } from "./effect/app-node"
|
import { makeLocationNode } from "./effect/app-node"
|
||||||
import { Context, Effect, Exit, Layer, Scope, Semaphore } from "effect"
|
import { Context, Effect, Exit, Layer, Scope, Semaphore } from "effect"
|
||||||
@@ -18,7 +18,6 @@ import { SkillV2 } from "./skill"
|
|||||||
import { State } from "./state"
|
import { State } from "./state"
|
||||||
import { ToolRegistry } from "./tool/registry"
|
import { ToolRegistry } from "./tool/registry"
|
||||||
import { ToolHooks } from "./tool/hooks"
|
import { ToolHooks } from "./tool/hooks"
|
||||||
import { PluginHooks } from "./plugin/hooks"
|
|
||||||
|
|
||||||
export interface Interface {
|
export interface Interface {
|
||||||
readonly activate: (plugins: readonly { readonly plugin: Plugin; readonly version?: string }[]) => Effect.Effect<void>
|
readonly activate: (plugins: readonly { readonly plugin: Plugin; readonly version?: string }[]) => Effect.Effect<void>
|
||||||
@@ -58,13 +57,12 @@ const layer = Layer.effect(
|
|||||||
generation.length === definitions.length &&
|
generation.length === definitions.length &&
|
||||||
generation.every(
|
generation.every(
|
||||||
(plugin, index) => plugin.id === definitions[index]?.id && plugin.version === definitions[index]?.version,
|
(plugin, index) => plugin.id === definitions[index]?.id && plugin.version === definitions[index]?.version,
|
||||||
) &&
|
)
|
||||||
definitions.every((definition) => active.has(definition.id))
|
|
||||||
) {
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
generation = undefined
|
generation = undefined
|
||||||
yield* State.batch(
|
const exit = yield* State.batch(
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const scopes = Array.from(active.values()).toReversed()
|
const scopes = Array.from(active.values()).toReversed()
|
||||||
active.clear()
|
active.clear()
|
||||||
@@ -83,17 +81,13 @@ const layer = Layer.effect(
|
|||||||
Effect.onExit((exit) => (Exit.isFailure(exit) ? Scope.close(child, exit) : Effect.void)),
|
Effect.onExit((exit) => (Exit.isFailure(exit) ? Scope.close(child, exit) : Effect.void)),
|
||||||
Effect.exit,
|
Effect.exit,
|
||||||
)
|
)
|
||||||
if (Exit.isFailure(loaded)) {
|
if (Exit.isFailure(loaded)) return loaded
|
||||||
yield* Effect.logWarning("failed to load plugin", {
|
|
||||||
"plugin.id": definition.id,
|
|
||||||
cause: loaded.cause,
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
active.set(definition.id, child)
|
active.set(definition.id, child)
|
||||||
}
|
}
|
||||||
|
return Exit.void
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
if (Exit.isFailure(exit)) return yield* exit
|
||||||
generation = definitions.map((definition) => ({
|
generation = definitions.map((definition) => ({
|
||||||
id: definition.id,
|
id: definition.id,
|
||||||
...(definition.version === undefined ? {} : { version: definition.version }),
|
...(definition.version === undefined ? {} : { version: definition.version }),
|
||||||
@@ -137,7 +131,6 @@ export const node = makeLocationNode({
|
|||||||
SkillV2.node,
|
SkillV2.node,
|
||||||
ToolRegistry.toolsNode,
|
ToolRegistry.toolsNode,
|
||||||
ToolHooks.node,
|
ToolHooks.node,
|
||||||
PluginHooks.node,
|
|
||||||
PluginRuntime.node,
|
PluginRuntime.node,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
export * as PluginHooks from "./hooks"
|
|
||||||
|
|
||||||
import type { AISDKHooks } from "@opencode-ai/plugin/v2/effect/aisdk"
|
|
||||||
import type { SessionHooks } from "@opencode-ai/plugin/v2/effect/session"
|
|
||||||
import type { ToolHooks } from "@opencode-ai/plugin/v2/effect/tool"
|
|
||||||
import { Context, Effect, Layer, Scope } from "effect"
|
|
||||||
import { makeLocationNode } from "../effect/app-node"
|
|
||||||
import { State } from "../state"
|
|
||||||
|
|
||||||
export interface Domains {
|
|
||||||
readonly aisdk: AISDKHooks
|
|
||||||
readonly session: SessionHooks
|
|
||||||
readonly tool: ToolHooks
|
|
||||||
}
|
|
||||||
|
|
||||||
type Callback<Event> = (event: Event) => Effect.Effect<void>
|
|
||||||
|
|
||||||
export interface Interface {
|
|
||||||
readonly register: <Domain extends keyof Domains, Name extends keyof Domains[Domain]>(
|
|
||||||
domain: Domain,
|
|
||||||
name: Name,
|
|
||||||
callback: Callback<Domains[Domain][Name]>,
|
|
||||||
) => Effect.Effect<State.Registration, never, Scope.Scope>
|
|
||||||
readonly trigger: <Domain extends keyof Domains, Name extends keyof Domains[Domain]>(
|
|
||||||
domain: Domain,
|
|
||||||
name: Name,
|
|
||||||
event: Domains[Domain][Name],
|
|
||||||
) => Effect.Effect<Domains[Domain][Name]>
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Service extends Context.Service<Service, Interface>()("@opencode/v2/PluginHooks") {}
|
|
||||||
|
|
||||||
const layer = Layer.effect(
|
|
||||||
Service,
|
|
||||||
Effect.gen(function* () {
|
|
||||||
const callbacks = new Map<string, Function[]>()
|
|
||||||
const key = (domain: keyof Domains, name: PropertyKey) => `${domain}.${String(name)}`
|
|
||||||
|
|
||||||
const register: Interface["register"] = Effect.fn("PluginHooks.register")(function* (domain, name, callback) {
|
|
||||||
const scope = yield* Scope.Scope
|
|
||||||
const id = key(domain, name)
|
|
||||||
let active = true
|
|
||||||
callbacks.set(id, [...(callbacks.get(id) ?? []), callback])
|
|
||||||
const dispose = Effect.sync(() => {
|
|
||||||
if (!active) return
|
|
||||||
active = false
|
|
||||||
const next = (callbacks.get(id) ?? []).filter((item) => item !== callback)
|
|
||||||
if (next.length === 0) callbacks.delete(id)
|
|
||||||
else callbacks.set(id, next)
|
|
||||||
})
|
|
||||||
yield* Scope.addFinalizer(scope, dispose)
|
|
||||||
return { dispose }
|
|
||||||
})
|
|
||||||
|
|
||||||
const trigger: Interface["trigger"] = Effect.fn("PluginHooks.trigger")(function* (domain, name, event) {
|
|
||||||
for (const callback of callbacks.get(key(domain, name)) ?? []) {
|
|
||||||
const result: Effect.Effect<void> = Reflect.apply(callback, undefined, [event])
|
|
||||||
yield* result
|
|
||||||
}
|
|
||||||
return event
|
|
||||||
})
|
|
||||||
|
|
||||||
return Service.of({ register, trigger })
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
export const node = makeLocationNode({ service: Service, layer, deps: [] })
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as PluginHost from "./host"
|
export * as PluginHost from "./host"
|
||||||
|
|
||||||
import type { Plugin } from "@opencode-ai/plugin/v2/effect"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { EventManifest } from "@opencode-ai/schema/event-manifest"
|
import { EventManifest } from "@opencode-ai/schema/event-manifest"
|
||||||
import { Effect, Schema, Stream } from "effect"
|
import { Effect, Schema, Stream } from "effect"
|
||||||
import { AgentV2 } from "../agent"
|
import { AgentV2 } from "../agent"
|
||||||
@@ -22,7 +22,6 @@ import { Tool } from "../tool/tool"
|
|||||||
import { Tools } from "../tool/tools"
|
import { Tools } from "../tool/tools"
|
||||||
import { ToolHooks } from "../tool/hooks"
|
import { ToolHooks } from "../tool/hooks"
|
||||||
import { WorkspaceV2 } from "../workspace"
|
import { WorkspaceV2 } from "../workspace"
|
||||||
import { PluginHooks } from "./hooks"
|
|
||||||
|
|
||||||
const mutable = <T>(value: T) => value as DeepMutable<T>
|
const mutable = <T>(value: T) => value as DeepMutable<T>
|
||||||
export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Interface) {
|
export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Interface) {
|
||||||
@@ -37,7 +36,6 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
const skill = yield* SkillV2.Service
|
const skill = yield* SkillV2.Service
|
||||||
const tools = yield* Tools.Service
|
const tools = yield* Tools.Service
|
||||||
const toolHooks = yield* ToolHooks.Service
|
const toolHooks = yield* ToolHooks.Service
|
||||||
const hooks = yield* PluginHooks.Service
|
|
||||||
const runtime = yield* PluginRuntime.Service
|
const runtime = yield* PluginRuntime.Service
|
||||||
const locationInfo = () =>
|
const locationInfo = () =>
|
||||||
new Location.Info({
|
new Location.Info({
|
||||||
@@ -45,7 +43,7 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
workspaceID: location.workspaceID,
|
workspaceID: location.workspaceID,
|
||||||
project: location.project,
|
project: location.project,
|
||||||
})
|
})
|
||||||
const locationRef = (input?: Parameters<Plugin.Context["agent"]["list"]>[0]) =>
|
const locationRef = (input?: Parameters<PluginContext["agent"]["list"]>[0]) =>
|
||||||
input?.location === undefined
|
input?.location === undefined
|
||||||
? undefined
|
? undefined
|
||||||
: Location.Ref.make({
|
: Location.Ref.make({
|
||||||
@@ -81,32 +79,32 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
aisdk: {
|
aisdk: {
|
||||||
hook: (name, callback) => {
|
sdk: (callback) =>
|
||||||
if (name === "sdk") {
|
aisdk.hook.sdk((event) => {
|
||||||
return aisdk.hook.sdk((event) => {
|
|
||||||
const output = {
|
const output = {
|
||||||
model: mutable(event.model),
|
model: mutable(event.model),
|
||||||
package: event.package,
|
package: event.package,
|
||||||
options: event.options,
|
options: event.options,
|
||||||
sdk: event.sdk,
|
sdk: event.sdk,
|
||||||
}
|
}
|
||||||
return Reflect.apply(callback, undefined, [output]).pipe(
|
const result = callback(output)
|
||||||
|
return Effect.suspend(() => (Effect.isEffect(result) ? result : Effect.void)).pipe(
|
||||||
Effect.tap(() => Effect.sync(() => (event.sdk = output.sdk))),
|
Effect.tap(() => Effect.sync(() => (event.sdk = output.sdk))),
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
}
|
language: (callback) =>
|
||||||
return aisdk.hook.language((event) => {
|
aisdk.hook.language((event) => {
|
||||||
const output = {
|
const output = {
|
||||||
model: mutable(event.model),
|
model: mutable(event.model),
|
||||||
options: event.options,
|
|
||||||
sdk: event.sdk,
|
sdk: event.sdk,
|
||||||
|
options: event.options,
|
||||||
language: event.language,
|
language: event.language,
|
||||||
}
|
}
|
||||||
return Reflect.apply(callback, undefined, [output]).pipe(
|
const result = callback(output)
|
||||||
|
return Effect.suspend(() => (Effect.isEffect(result) ? result : Effect.void)).pipe(
|
||||||
Effect.tap(() => Effect.sync(() => (event.language = output.language))),
|
Effect.tap(() => Effect.sync(() => (event.language = output.language))),
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
},
|
|
||||||
},
|
},
|
||||||
catalog: {
|
catalog: {
|
||||||
provider: {
|
provider: {
|
||||||
@@ -166,14 +164,13 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
integration: {
|
integration: {
|
||||||
list: () => response(integration.list()),
|
list: () => response(integration.list()),
|
||||||
get: (input) => response(integration.get(Integration.ID.make(input.integrationID))),
|
get: (input) => response(integration.get(Integration.ID.make(input.integrationID))),
|
||||||
connect: {
|
connectKey: (input) =>
|
||||||
key: (input) =>
|
|
||||||
integration.connection.key({
|
integration.connection.key({
|
||||||
integrationID: Integration.ID.make(input.integrationID),
|
integrationID: Integration.ID.make(input.integrationID),
|
||||||
key: input.key,
|
key: input.key,
|
||||||
label: input.label,
|
label: input.label,
|
||||||
}),
|
}),
|
||||||
oauth: (input) =>
|
connectOauth: (input) =>
|
||||||
response(
|
response(
|
||||||
integration.connection.oauth({
|
integration.connection.oauth({
|
||||||
integrationID: Integration.ID.make(input.integrationID),
|
integrationID: Integration.ID.make(input.integrationID),
|
||||||
@@ -182,13 +179,10 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
label: input.label,
|
label: input.label,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
},
|
attemptStatus: (input) => response(integration.attempt.status(Integration.AttemptID.make(input.attemptID))),
|
||||||
attempt: {
|
attemptComplete: (input) =>
|
||||||
status: (input) => response(integration.attempt.status(Integration.AttemptID.make(input.attemptID))),
|
|
||||||
complete: (input) =>
|
|
||||||
integration.attempt.complete({ attemptID: Integration.AttemptID.make(input.attemptID), code: input.code }),
|
integration.attempt.complete({ attemptID: Integration.AttemptID.make(input.attemptID), code: input.code }),
|
||||||
cancel: (input) => integration.attempt.cancel(Integration.AttemptID.make(input.attemptID)),
|
attemptCancel: (input) => integration.attempt.cancel(Integration.AttemptID.make(input.attemptID)),
|
||||||
},
|
|
||||||
reload: integration.reload,
|
reload: integration.reload,
|
||||||
connection: {
|
connection: {
|
||||||
active: (id) => integration.connection.active(Integration.ID.make(id)),
|
active: (id) => integration.connection.active(Integration.ID.make(id)),
|
||||||
@@ -323,12 +317,11 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
registrations,
|
registrations,
|
||||||
(registration) => tools.register({ [registration.name]: registration.tool }, registration.options),
|
(registration) => tools.register({ [registration.name]: registration.tool }, registration.options),
|
||||||
{ discard: true },
|
{ discard: true },
|
||||||
).pipe(Effect.orDie)
|
)
|
||||||
return { dispose: Effect.void }
|
|
||||||
}),
|
}),
|
||||||
hook: (name, callback) => {
|
execute: {
|
||||||
if (name === "execute.before") {
|
before: (callback) =>
|
||||||
return toolHooks.hook.before((event) => {
|
toolHooks.hook.before((event) => {
|
||||||
const output = {
|
const output = {
|
||||||
tool: event.tool,
|
tool: event.tool,
|
||||||
sessionID: event.sessionID,
|
sessionID: event.sessionID,
|
||||||
@@ -337,12 +330,13 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
toolCallID: event.toolCallID,
|
toolCallID: event.toolCallID,
|
||||||
input: event.input,
|
input: event.input,
|
||||||
}
|
}
|
||||||
return Reflect.apply(callback, undefined, [output]).pipe(
|
const result = callback(output)
|
||||||
|
return Effect.suspend(() => (Effect.isEffect(result) ? result : Effect.void)).pipe(
|
||||||
Effect.tap(() => Effect.sync(() => (event.input = output.input))),
|
Effect.tap(() => Effect.sync(() => (event.input = output.input))),
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
}
|
after: (callback) =>
|
||||||
return toolHooks.hook.after((event) => {
|
toolHooks.hook.after((event) => {
|
||||||
const output = {
|
const output = {
|
||||||
tool: event.tool,
|
tool: event.tool,
|
||||||
sessionID: event.sessionID,
|
sessionID: event.sessionID,
|
||||||
@@ -354,7 +348,8 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
output: event.output,
|
output: event.output,
|
||||||
outputPaths: event.outputPaths,
|
outputPaths: event.outputPaths,
|
||||||
}
|
}
|
||||||
return Reflect.apply(callback, undefined, [output]).pipe(
|
const result = callback(output)
|
||||||
|
return Effect.suspend(() => (Effect.isEffect(result) ? result : Effect.void)).pipe(
|
||||||
Effect.tap(() =>
|
Effect.tap(() =>
|
||||||
Effect.sync(() => {
|
Effect.sync(() => {
|
||||||
event.result = output.result
|
event.result = output.result
|
||||||
@@ -363,11 +358,10 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
session: {
|
session: {
|
||||||
hook: (name, callback) => hooks.register("session", name, callback),
|
|
||||||
create: (input) =>
|
create: (input) =>
|
||||||
runtime.session.create({
|
runtime.session.create({
|
||||||
id: input?.id,
|
id: input?.id,
|
||||||
@@ -381,5 +375,5 @@ export const make = Effect.fn("PluginHost.make")(function* (plugin: PluginV2.Int
|
|||||||
command: runtime.session.command,
|
command: runtime.session.command,
|
||||||
interrupt: (input) => runtime.session.interrupt(input.sessionID),
|
interrupt: (input) => runtime.session.interrupt(input.sessionID),
|
||||||
},
|
},
|
||||||
} satisfies Plugin.Context
|
} satisfies PluginContext
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as PluginInternal from "./internal"
|
export * as PluginInternal from "./internal"
|
||||||
|
|
||||||
import type { Plugin } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { Plugin } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Context, Effect, Scope } from "effect"
|
import { Context, Effect, Scope } from "effect"
|
||||||
import { HttpClient } from "effect/unstable/http"
|
import { HttpClient } from "effect/unstable/http"
|
||||||
import { AgentV2 } from "../agent"
|
import { AgentV2 } from "../agent"
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
export * as PluginPromise from "./promise"
|
export * as PluginPromise from "./promise"
|
||||||
|
|
||||||
import { Plugin } from "@opencode-ai/plugin/v2/effect"
|
import { define } from "@opencode-ai/plugin/v2/effect"
|
||||||
|
import type { Plugin, PluginContext } from "@opencode-ai/plugin/v2/promise"
|
||||||
import { Effect, Scope, Stream } from "effect"
|
import { Effect, Scope, Stream } from "effect"
|
||||||
|
|
||||||
type HostRegistration = { readonly dispose: Effect.Effect<void> }
|
type HostRegistration = { readonly dispose: Effect.Effect<void> }
|
||||||
type Registration = { readonly dispose: () => Promise<void> }
|
type Registration = { readonly dispose: () => Promise<void> }
|
||||||
type PromisePlugin = import("@opencode-ai/plugin/v2/plugin").Plugin
|
|
||||||
type PromisePluginContext = import("@opencode-ai/plugin/v2/plugin").Context
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapts a Promise plugin into an Effect plugin so the existing Effect-only
|
* Adapts a Promise plugin into an Effect plugin so the existing Effect-only
|
||||||
@@ -17,8 +16,8 @@ type PromisePluginContext = import("@opencode-ai/plugin/v2/plugin").Context
|
|||||||
* preserves boot-time batching, so Promise-plugin transforms still coalesce
|
* preserves boot-time batching, so Promise-plugin transforms still coalesce
|
||||||
* into one reload per domain.
|
* into one reload per domain.
|
||||||
*/
|
*/
|
||||||
export function fromPromise(plugin: PromisePlugin) {
|
export function fromPromise(plugin: Plugin) {
|
||||||
return Plugin.define({
|
return define({
|
||||||
id: plugin.id,
|
id: plugin.id,
|
||||||
effect: (host) =>
|
effect: (host) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
@@ -44,7 +43,7 @@ export function fromPromise(plugin: PromisePlugin) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
const context2: PromisePluginContext = {
|
const context2: PluginContext = {
|
||||||
options: host.options,
|
options: host.options,
|
||||||
agent: {
|
agent: {
|
||||||
list: (input) => run(host.agent.list(input)),
|
list: (input) => run(host.agent.list(input)),
|
||||||
@@ -52,8 +51,10 @@ export function fromPromise(plugin: PromisePlugin) {
|
|||||||
reload: () => run(host.agent.reload()),
|
reload: () => run(host.agent.reload()),
|
||||||
},
|
},
|
||||||
aisdk: {
|
aisdk: {
|
||||||
hook: (name, callback) =>
|
sdk: (callback) =>
|
||||||
register(host.aisdk.hook(name, (event) => Effect.promise(() => Promise.resolve(callback(event))))),
|
register(host.aisdk.sdk((event) => Effect.promise(() => Promise.resolve(callback(event))))),
|
||||||
|
language: (callback) =>
|
||||||
|
register(host.aisdk.language((event) => Effect.promise(() => Promise.resolve(callback(event))))),
|
||||||
},
|
},
|
||||||
catalog: {
|
catalog: {
|
||||||
provider: {
|
provider: {
|
||||||
@@ -78,15 +79,11 @@ export function fromPromise(plugin: PromisePlugin) {
|
|||||||
integration: {
|
integration: {
|
||||||
list: (input) => run(host.integration.list(input)),
|
list: (input) => run(host.integration.list(input)),
|
||||||
get: (input) => run(host.integration.get(input)),
|
get: (input) => run(host.integration.get(input)),
|
||||||
connect: {
|
connectKey: (input) => run(host.integration.connectKey(input)),
|
||||||
key: (input) => run(host.integration.connect.key(input)),
|
connectOauth: (input) => run(host.integration.connectOauth(input)),
|
||||||
oauth: (input) => run(host.integration.connect.oauth(input)),
|
attemptStatus: (input) => run(host.integration.attemptStatus(input)),
|
||||||
},
|
attemptComplete: (input) => run(host.integration.attemptComplete(input)),
|
||||||
attempt: {
|
attemptCancel: (input) => run(host.integration.attemptCancel(input)),
|
||||||
status: (input) => run(host.integration.attempt.status(input)),
|
|
||||||
complete: (input) => run(host.integration.attempt.complete(input)),
|
|
||||||
cancel: (input) => run(host.integration.attempt.cancel(input)),
|
|
||||||
},
|
|
||||||
transform: transform(host.integration),
|
transform: transform(host.integration),
|
||||||
reload: () => run(host.integration.reload()),
|
reload: () => run(host.integration.reload()),
|
||||||
connection: {
|
connection: {
|
||||||
@@ -107,19 +104,12 @@ export function fromPromise(plugin: PromisePlugin) {
|
|||||||
transform: transform(host.skill),
|
transform: transform(host.skill),
|
||||||
reload: () => run(host.skill.reload()),
|
reload: () => run(host.skill.reload()),
|
||||||
},
|
},
|
||||||
tool: {
|
|
||||||
transform: transform(host.tool),
|
|
||||||
hook: (name, callback) =>
|
|
||||||
register(host.tool.hook(name, (event) => Effect.promise(() => Promise.resolve(callback(event))))),
|
|
||||||
},
|
|
||||||
session: {
|
session: {
|
||||||
create: (input) => run(host.session.create(input)),
|
create: (input) => run(host.session.create(input)),
|
||||||
get: (input) => run(host.session.get(input)),
|
get: (input) => run(host.session.get(input)),
|
||||||
prompt: (input) => run(host.session.prompt(input)),
|
prompt: (input) => run(host.session.prompt(input)),
|
||||||
command: (input) => run(host.session.command(input)),
|
command: (input) => run(host.session.command(input)),
|
||||||
interrupt: (input) => run(host.session.interrupt(input)),
|
interrupt: (input) => run(host.session.interrupt(input)),
|
||||||
hook: (name, callback) =>
|
|
||||||
register(host.session.hook(name, (event) => Effect.promise(() => Promise.resolve(callback(event))))),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const AlibabaPlugin = define({
|
export const AlibabaPlugin = define({
|
||||||
id: "opencode.provider.alibaba",
|
id: "opencode.provider.alibaba",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/alibaba") return
|
if (evt.package !== "@ai-sdk/alibaba") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/alibaba"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/alibaba"))
|
||||||
|
|||||||
@@ -75,8 +75,7 @@ export const AmazonBedrockPlugin = define({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (!["@ai-sdk/amazon-bedrock", "@ai-sdk/amazon-bedrock/mantle"].includes(evt.package)) return
|
if (!["@ai-sdk/amazon-bedrock", "@ai-sdk/amazon-bedrock/mantle"].includes(evt.package)) return
|
||||||
const options = { ...evt.options }
|
const options = { ...evt.options }
|
||||||
@@ -109,8 +108,7 @@ export const AmazonBedrockPlugin = define({
|
|||||||
evt.sdk = mod.createAmazonBedrock(options)
|
evt.sdk = mod.createAmazonBedrock(options)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.amazonBedrock) return
|
if (evt.model.providerID !== ProviderV2.ID.amazonBedrock) return
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -17,8 +17,7 @@ export const AnthropicPlugin = define({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/anthropic") return
|
if (evt.package !== "@ai-sdk/anthropic") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/anthropic"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/anthropic"))
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ export const AzurePlugin = define({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/azure") return
|
if (evt.package !== "@ai-sdk/azure") return
|
||||||
if (evt.model.providerID === ProviderV2.ID.azure) {
|
if (evt.model.providerID === ProviderV2.ID.azure) {
|
||||||
@@ -45,8 +44,7 @@ export const AzurePlugin = define({
|
|||||||
evt.sdk = mod.createAzure(evt.options)
|
evt.sdk = mod.createAzure(evt.options)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.azure) return
|
if (evt.model.providerID !== ProviderV2.ID.azure) return
|
||||||
evt.language = selectLanguage(
|
evt.language = selectLanguage(
|
||||||
@@ -77,8 +75,7 @@ export const AzureCognitiveServicesPlugin = define({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.make("azure-cognitive-services")) return
|
if (evt.model.providerID !== ProviderV2.ID.make("azure-cognitive-services")) return
|
||||||
evt.language = selectLanguage(
|
evt.language = selectLanguage(
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ export const CerebrasPlugin = define({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/cerebras") return
|
if (evt.package !== "@ai-sdk/cerebras") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/cerebras"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/cerebras"))
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const CloudflareAIGatewayPlugin = define({
|
export const CloudflareAIGatewayPlugin = define({
|
||||||
id: "opencode.provider.cloudflare-ai-gateway",
|
id: "opencode.provider.cloudflare-ai-gateway",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "ai-gateway-provider") return
|
if (evt.package !== "ai-gateway-provider") return
|
||||||
if (evt.options.baseURL) return
|
if (evt.options.baseURL) return
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ export const CloudflareWorkersAIPlugin = define({
|
|||||||
if (accountId) provider.settings = { ...provider.settings, baseURL: workersEndpoint(accountId) }
|
if (accountId) provider.settings = { ...provider.settings, baseURL: workersEndpoint(accountId) }
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== providerID) return
|
if (evt.model.providerID !== providerID) return
|
||||||
if (evt.package !== "@ai-sdk/openai-compatible") return
|
if (evt.package !== "@ai-sdk/openai-compatible") return
|
||||||
@@ -36,8 +35,7 @@ export const CloudflareWorkersAIPlugin = define({
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== providerID) return
|
if (evt.model.providerID !== providerID) return
|
||||||
evt.language = evt.sdk.languageModel(evt.model.modelID ?? evt.model.id)
|
evt.language = evt.sdk.languageModel(evt.model.modelID ?? evt.model.id)
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const CoherePlugin = define({
|
export const CoherePlugin = define({
|
||||||
id: "opencode.provider.cohere",
|
id: "opencode.provider.cohere",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/cohere") return
|
if (evt.package !== "@ai-sdk/cohere") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/cohere"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/cohere"))
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const DeepInfraPlugin = define({
|
export const DeepInfraPlugin = define({
|
||||||
id: "opencode.provider.deepinfra",
|
id: "opencode.provider.deepinfra",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/deepinfra") return
|
if (evt.package !== "@ai-sdk/deepinfra") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/deepinfra"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/deepinfra"))
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ export const DynamicProviderPlugin = define({
|
|||||||
id: "opencode.provider.dynamic",
|
id: "opencode.provider.dynamic",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
const npm = yield* Npm.Service
|
const npm = yield* Npm.Service
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.sdk) return
|
if (evt.sdk) return
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const GatewayPlugin = define({
|
export const GatewayPlugin = define({
|
||||||
id: "opencode.provider.gateway",
|
id: "opencode.provider.gateway",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/gateway") return
|
if (evt.package !== "@ai-sdk/gateway") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/gateway"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/gateway"))
|
||||||
|
|||||||
@@ -23,16 +23,14 @@ export const GithubCopilotPlugin = define({
|
|||||||
model.enabled = false
|
model.enabled = false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/github-copilot") return
|
if (evt.package !== "@ai-sdk/github-copilot") return
|
||||||
const mod = yield* Effect.promise(() => import("../../github-copilot/copilot-provider"))
|
const mod = yield* Effect.promise(() => import("../../github-copilot/copilot-provider"))
|
||||||
evt.sdk = mod.createOpenaiCompatible(evt.options)
|
evt.sdk = mod.createOpenaiCompatible(evt.options)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.githubCopilot) return
|
if (evt.model.providerID !== ProviderV2.ID.githubCopilot) return
|
||||||
if (evt.sdk.responses === undefined && evt.sdk.chat === undefined) {
|
if (evt.sdk.responses === undefined && evt.sdk.chat === undefined) {
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import { ProviderV2 } from "../../provider"
|
|||||||
export const GitLabPlugin = define({
|
export const GitLabPlugin = define({
|
||||||
id: "opencode.provider.gitlab",
|
id: "opencode.provider.gitlab",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "gitlab-ai-provider") return
|
if (evt.package !== "gitlab-ai-provider") return
|
||||||
const mod = yield* Effect.promise(() => import("gitlab-ai-provider"))
|
const mod = yield* Effect.promise(() => import("gitlab-ai-provider"))
|
||||||
@@ -32,8 +31,7 @@ export const GitLabPlugin = define({
|
|||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.gitlab) return
|
if (evt.model.providerID !== ProviderV2.ID.gitlab) return
|
||||||
const featureFlags =
|
const featureFlags =
|
||||||
|
|||||||
@@ -85,8 +85,7 @@ export const GoogleVertexPlugin = define({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID === ProviderV2.ID.googleVertex && evt.package.includes("@ai-sdk/openai-compatible")) {
|
if (evt.model.providerID === ProviderV2.ID.googleVertex && evt.package.includes("@ai-sdk/openai-compatible")) {
|
||||||
evt.options.fetch = authFetch(evt.options.fetch)
|
evt.options.fetch = authFetch(evt.options.fetch)
|
||||||
@@ -105,8 +104,7 @@ export const GoogleVertexPlugin = define({
|
|||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.googleVertex) return
|
if (evt.model.providerID !== ProviderV2.ID.googleVertex) return
|
||||||
evt.language = evt.sdk.languageModel(String(evt.model.modelID ?? evt.model.id).trim())
|
evt.language = evt.sdk.languageModel(String(evt.model.modelID ?? evt.model.id).trim())
|
||||||
@@ -137,8 +135,7 @@ export const GoogleVertexAnthropicPlugin = define({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/google-vertex/anthropic") return
|
if (evt.package !== "@ai-sdk/google-vertex/anthropic") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/google-vertex/anthropic"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/google-vertex/anthropic"))
|
||||||
@@ -164,8 +161,7 @@ export const GoogleVertexAnthropicPlugin = define({
|
|||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.make("google-vertex-anthropic")) return
|
if (evt.model.providerID !== ProviderV2.ID.make("google-vertex-anthropic")) return
|
||||||
evt.language = evt.sdk.languageModel(String(evt.model.modelID ?? evt.model.id).trim())
|
evt.language = evt.sdk.languageModel(String(evt.model.modelID ?? evt.model.id).trim())
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const GooglePlugin = define({
|
export const GooglePlugin = define({
|
||||||
id: "opencode.provider.google",
|
id: "opencode.provider.google",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/google") return
|
if (evt.package !== "@ai-sdk/google") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/google"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/google"))
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const GroqPlugin = define({
|
export const GroqPlugin = define({
|
||||||
id: "opencode.provider.groq",
|
id: "opencode.provider.groq",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/groq") return
|
if (evt.package !== "@ai-sdk/groq") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/groq"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/groq"))
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const MistralPlugin = define({
|
export const MistralPlugin = define({
|
||||||
id: "opencode.provider.mistral",
|
id: "opencode.provider.mistral",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/mistral") return
|
if (evt.package !== "@ai-sdk/mistral") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/mistral"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/mistral"))
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const OpenAICompatiblePlugin = define({
|
export const OpenAICompatiblePlugin = define({
|
||||||
id: "opencode.provider.openai-compatible",
|
id: "opencode.provider.openai-compatible",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.sdk) return
|
if (evt.sdk) return
|
||||||
if (!evt.package.includes("@ai-sdk/openai-compatible")) return
|
if (!evt.package.includes("@ai-sdk/openai-compatible")) return
|
||||||
|
|||||||
@@ -210,16 +210,14 @@ export const OpenAIPlugin = define({
|
|||||||
Effect.forkScoped({ startImmediately: true }),
|
Effect.forkScoped({ startImmediately: true }),
|
||||||
)
|
)
|
||||||
yield* refresh().pipe(Effect.forkScoped)
|
yield* refresh().pipe(Effect.forkScoped)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/openai") return
|
if (evt.package !== "@ai-sdk/openai") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/openai"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/openai"))
|
||||||
evt.sdk = mod.createOpenAI(evt.options)
|
evt.sdk = mod.createOpenAI(evt.options)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.openai) return
|
if (evt.model.providerID !== ProviderV2.ID.openai) return
|
||||||
evt.language = evt.sdk.responses(evt.model.modelID ?? evt.model.id)
|
evt.language = evt.sdk.responses(evt.model.modelID ?? evt.model.id)
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ export const OpenRouterPlugin = define({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@openrouter/ai-sdk-provider") return
|
if (evt.package !== "@openrouter/ai-sdk-provider") return
|
||||||
const mod = yield* Effect.promise(() => import("@openrouter/ai-sdk-provider"))
|
const mod = yield* Effect.promise(() => import("@openrouter/ai-sdk-provider"))
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const PerplexityPlugin = define({
|
export const PerplexityPlugin = define({
|
||||||
id: "opencode.provider.perplexity",
|
id: "opencode.provider.perplexity",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/perplexity") return
|
if (evt.package !== "@ai-sdk/perplexity") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/perplexity"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/perplexity"))
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ export const SapAICorePlugin = define({
|
|||||||
id: "opencode.provider.sap-ai-core",
|
id: "opencode.provider.sap-ai-core",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
const npm = yield* Npm.Service
|
const npm = yield* Npm.Service
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.make("sap-ai-core")) return
|
if (evt.model.providerID !== ProviderV2.ID.make("sap-ai-core")) return
|
||||||
const serviceKey =
|
const serviceKey =
|
||||||
@@ -38,8 +37,7 @@ export const SapAICorePlugin = define({
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.make("sap-ai-core")) return
|
if (evt.model.providerID !== ProviderV2.ID.make("sap-ai-core")) return
|
||||||
evt.language = evt.sdk(evt.model.modelID ?? evt.model.id)
|
evt.language = evt.sdk(evt.model.modelID ?? evt.model.id)
|
||||||
|
|||||||
@@ -67,8 +67,7 @@ export function cortexFetch(upstream: FetchLike = fetch) {
|
|||||||
export const SnowflakeCortexPlugin = define({
|
export const SnowflakeCortexPlugin = define({
|
||||||
id: "opencode.provider.snowflake-cortex",
|
id: "opencode.provider.snowflake-cortex",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.make("snowflake-cortex")) return
|
if (evt.model.providerID !== ProviderV2.ID.make("snowflake-cortex")) return
|
||||||
const token =
|
const token =
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const TogetherAIPlugin = define({
|
export const TogetherAIPlugin = define({
|
||||||
id: "opencode.provider.togetherai",
|
id: "opencode.provider.togetherai",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/togetherai") return
|
if (evt.package !== "@ai-sdk/togetherai") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/togetherai"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/togetherai"))
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { define } from "@opencode-ai/plugin/v2/effect/plugin"
|
|||||||
export const VenicePlugin = define({
|
export const VenicePlugin = define({
|
||||||
id: "opencode.provider.venice",
|
id: "opencode.provider.venice",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "venice-ai-sdk-provider") return
|
if (evt.package !== "venice-ai-sdk-provider") return
|
||||||
const mod = yield* Effect.promise(() => import("venice-ai-sdk-provider"))
|
const mod = yield* Effect.promise(() => import("venice-ai-sdk-provider"))
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ export const VercelPlugin = define({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/vercel") return
|
if (evt.package !== "@ai-sdk/vercel") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/vercel"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/vercel"))
|
||||||
|
|||||||
@@ -5,16 +5,14 @@ import { ProviderV2 } from "../../provider"
|
|||||||
export const XAIPlugin = define({
|
export const XAIPlugin = define({
|
||||||
id: "opencode.provider.xai",
|
id: "opencode.provider.xai",
|
||||||
effect: Effect.fn(function* (ctx) {
|
effect: Effect.fn(function* (ctx) {
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.sdk(
|
||||||
"sdk",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.package !== "@ai-sdk/xai") return
|
if (evt.package !== "@ai-sdk/xai") return
|
||||||
const mod = yield* Effect.promise(() => import("@ai-sdk/xai"))
|
const mod = yield* Effect.promise(() => import("@ai-sdk/xai"))
|
||||||
evt.sdk = mod.createXai(evt.options)
|
evt.sdk = mod.createXai(evt.options)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* ctx.aisdk.hook(
|
yield* ctx.aisdk.language(
|
||||||
"language",
|
|
||||||
Effect.fn(function* (evt) {
|
Effect.fn(function* (evt) {
|
||||||
if (evt.model.providerID !== ProviderV2.ID.make("xai")) return
|
if (evt.model.providerID !== ProviderV2.ID.make("xai")) return
|
||||||
evt.language = evt.sdk.responses(evt.model.modelID ?? evt.model.id)
|
evt.language = evt.sdk.responses(evt.model.modelID ?? evt.model.id)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as SdkPlugins from "./sdk"
|
export * as SdkPlugins from "./sdk"
|
||||||
|
|
||||||
import type { Plugin } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { Plugin } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Context, Effect, Layer } from "effect"
|
import { Context, Effect, Layer } from "effect"
|
||||||
import { makeGlobalNode } from "../effect/app-node"
|
import { makeGlobalNode } from "../effect/app-node"
|
||||||
import { EventV2 } from "../event"
|
import { EventV2 } from "../event"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as PluginSupervisor from "./supervisor"
|
export * as PluginSupervisor from "./supervisor"
|
||||||
|
|
||||||
import type { Plugin } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { Plugin } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Event } from "@opencode-ai/schema/config"
|
import { Event } from "@opencode-ai/schema/config"
|
||||||
import { Context, Effect, Fiber, Layer, Option, Schema, Semaphore, Stream } from "effect"
|
import { Context, Effect, Fiber, Layer, Option, Schema, Semaphore, Stream } from "effect"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
|||||||
@@ -143,7 +143,6 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
|
|||||||
|
|
||||||
return Effect.gen(function* () {
|
return Effect.gen(function* () {
|
||||||
yield* SessionEvent.All.match(event, {
|
yield* SessionEvent.All.match(event, {
|
||||||
"session.usage.updated": () => Effect.void,
|
|
||||||
"session.agent.selected": (event) => {
|
"session.agent.selected": (event) => {
|
||||||
return adapter.appendMessage(
|
return adapter.appendMessage(
|
||||||
SessionMessage.AgentSelected.make({
|
SessionMessage.AgentSelected.make({
|
||||||
@@ -297,10 +296,6 @@ export function update(adapter: Adapter, event: SessionEvent.Event) {
|
|||||||
draft.finish = "error"
|
draft.finish = "error"
|
||||||
draft.error = castDraft(event.data.error)
|
draft.error = castDraft(event.data.error)
|
||||||
draft.retry = undefined
|
draft.retry = undefined
|
||||||
if (event.data.cost !== undefined && event.data.tokens !== undefined) {
|
|
||||||
draft.cost = event.data.cost
|
|
||||||
draft.tokens = castDraft(event.data.tokens)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
"session.text.started": (event) => {
|
"session.text.started": (event) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export * as SessionProjector from "./projector"
|
export * as SessionProjector from "./projector"
|
||||||
|
|
||||||
import { and, asc, desc, eq, gt, gte, inArray, lt, or, sql } from "drizzle-orm"
|
import { and, asc, desc, eq, gt, gte, inArray, lt, or, sql } from "drizzle-orm"
|
||||||
import { DateTime, Effect, Layer, Schema, Stream } from "effect"
|
import { DateTime, Effect, Layer, Schema } from "effect"
|
||||||
import { Database } from "../database/database"
|
import { Database } from "../database/database"
|
||||||
import { EventV2 } from "../event"
|
import { EventV2 } from "../event"
|
||||||
import { makeGlobalNode } from "../effect/app-node"
|
import { makeGlobalNode } from "../effect/app-node"
|
||||||
@@ -48,6 +48,11 @@ type Usage = {
|
|||||||
|
|
||||||
const ForkBatchSize = 500
|
const ForkBatchSize = 500
|
||||||
|
|
||||||
|
const emptyUsage = (): Usage => ({
|
||||||
|
cost: 0,
|
||||||
|
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
||||||
|
})
|
||||||
|
|
||||||
const forkTitle = (value: string) => {
|
const forkTitle = (value: string) => {
|
||||||
const match = value.match(/^(.+) \(fork #(\d+)\)$/)
|
const match = value.match(/^(.+) \(fork #(\d+)\)$/)
|
||||||
if (match) return `${match[1]} (fork #${Number.parseInt(match[2], 10) + 1})`
|
if (match) return `${match[1]} (fork #${Number.parseInt(match[2], 10) + 1})`
|
||||||
@@ -62,6 +67,22 @@ function usage(part: (typeof SessionV1.Event.PartUpdated.Type)["data"]["part"] |
|
|||||||
return { cost: value.cost as Usage["cost"], tokens: value.tokens as Usage["tokens"] }
|
return { cost: value.cost as Usage["cost"], tokens: value.tokens as Usage["tokens"] }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addUsage(target: Usage, value: Usage) {
|
||||||
|
target.cost += value.cost
|
||||||
|
target.tokens.input += value.tokens.input
|
||||||
|
target.tokens.output += value.tokens.output
|
||||||
|
target.tokens.reasoning += value.tokens.reasoning
|
||||||
|
target.tokens.cache.read += value.tokens.cache.read
|
||||||
|
target.tokens.cache.write += value.tokens.cache.write
|
||||||
|
}
|
||||||
|
|
||||||
|
function messageUsage(row: typeof SessionMessageTable.$inferSelect): Usage | undefined {
|
||||||
|
if (row.type !== "assistant") return undefined
|
||||||
|
const message = decodeMessage({ ...row.data, id: row.id, type: row.type })
|
||||||
|
if (message.type !== "assistant" || message.cost === undefined || message.tokens === undefined) return undefined
|
||||||
|
return { cost: message.cost, tokens: message.tokens }
|
||||||
|
}
|
||||||
|
|
||||||
function sessionRow(info: SessionV1.SessionInfo): typeof SessionTable.$inferInsert {
|
function sessionRow(info: SessionV1.SessionInfo): typeof SessionTable.$inferInsert {
|
||||||
return {
|
return {
|
||||||
id: info.id,
|
id: info.id,
|
||||||
@@ -130,37 +151,6 @@ function applyUsage(
|
|||||||
.pipe(Effect.orDie)
|
.pipe(Effect.orDie)
|
||||||
}
|
}
|
||||||
|
|
||||||
const publishSessionUsage = Effect.fn("SessionProjector.publishUsage")(function* (
|
|
||||||
db: DatabaseService,
|
|
||||||
events: EventV2.Interface,
|
|
||||||
sessionID: (typeof SessionEvent.Step.Ended.Type)["data"]["sessionID"],
|
|
||||||
) {
|
|
||||||
const row = yield* db
|
|
||||||
.select({
|
|
||||||
cost: SessionTable.cost,
|
|
||||||
input: SessionTable.tokens_input,
|
|
||||||
output: SessionTable.tokens_output,
|
|
||||||
reasoning: SessionTable.tokens_reasoning,
|
|
||||||
cacheRead: SessionTable.tokens_cache_read,
|
|
||||||
cacheWrite: SessionTable.tokens_cache_write,
|
|
||||||
})
|
|
||||||
.from(SessionTable)
|
|
||||||
.where(eq(SessionTable.id, sessionID))
|
|
||||||
.get()
|
|
||||||
.pipe(Effect.orDie)
|
|
||||||
if (!row) return
|
|
||||||
yield* events.publish(SessionEvent.UsageUpdated, {
|
|
||||||
sessionID,
|
|
||||||
cost: row.cost,
|
|
||||||
tokens: {
|
|
||||||
input: row.input,
|
|
||||||
output: row.output,
|
|
||||||
reasoning: row.reasoning,
|
|
||||||
cache: { read: row.cacheRead, write: row.cacheWrite },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const projectFork = Effect.fn("SessionProjector.projectFork")(function* (
|
const projectFork = Effect.fn("SessionProjector.projectFork")(function* (
|
||||||
db: DatabaseService,
|
db: DatabaseService,
|
||||||
event: typeof SessionEvent.Forked.Type,
|
event: typeof SessionEvent.Forked.Type,
|
||||||
@@ -197,7 +187,7 @@ const projectFork = Effect.fn("SessionProjector.projectFork")(function* (
|
|||||||
.limit(1)
|
.limit(1)
|
||||||
.get()
|
.get()
|
||||||
.pipe(Effect.orDie)
|
.pipe(Effect.orDie)
|
||||||
const copiedSeq = copied?.seq
|
const copiedSeq = copied?.seq ?? 0
|
||||||
|
|
||||||
const stored = yield* db
|
const stored = yield* db
|
||||||
.insert(SessionTable)
|
.insert(SessionTable)
|
||||||
@@ -247,8 +237,9 @@ const projectFork = Effect.fn("SessionProjector.projectFork")(function* (
|
|||||||
.pipe(Effect.orDie)
|
.pipe(Effect.orDie)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const usage = emptyUsage()
|
||||||
let cursor = -1
|
let cursor = -1
|
||||||
while (copiedSeq !== undefined) {
|
while (true) {
|
||||||
const rows = yield* db
|
const rows = yield* db
|
||||||
.select()
|
.select()
|
||||||
.from(SessionMessageTable)
|
.from(SessionMessageTable)
|
||||||
@@ -256,7 +247,7 @@ const projectFork = Effect.fn("SessionProjector.projectFork")(function* (
|
|||||||
and(
|
and(
|
||||||
eq(SessionMessageTable.session_id, event.data.parentID),
|
eq(SessionMessageTable.session_id, event.data.parentID),
|
||||||
gt(SessionMessageTable.seq, cursor),
|
gt(SessionMessageTable.seq, cursor),
|
||||||
lt(SessionMessageTable.seq, copiedSeq + 1),
|
copiedSeq === 0 ? undefined : lt(SessionMessageTable.seq, copiedSeq + 1),
|
||||||
sql`${SessionMessageTable.type} != 'compaction' or json_extract(${SessionMessageTable.data}, '$.status') not in ('queued', 'running')`,
|
sql`${SessionMessageTable.type} != 'compaction' or json_extract(${SessionMessageTable.data}, '$.status') not in ('queued', 'running')`,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -327,9 +318,27 @@ const projectFork = Effect.fn("SessionProjector.projectFork")(function* (
|
|||||||
.pipe(Effect.orDie)
|
.pipe(Effect.orDie)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const row of rows) {
|
||||||
|
const value = messageUsage(row)
|
||||||
|
if (value) addUsage(usage, value)
|
||||||
|
}
|
||||||
cursor = rows.at(-1)!.seq
|
cursor = rows.at(-1)!.seq
|
||||||
}
|
}
|
||||||
if (copiedSeq !== undefined) yield* EventV2.reserveSequence(db, event.data.sessionID, copiedSeq)
|
|
||||||
|
yield* db
|
||||||
|
.update(SessionTable)
|
||||||
|
.set({
|
||||||
|
cost: usage.cost,
|
||||||
|
tokens_input: usage.tokens.input,
|
||||||
|
tokens_output: usage.tokens.output,
|
||||||
|
tokens_reasoning: usage.tokens.reasoning,
|
||||||
|
tokens_cache_read: usage.tokens.cache.read,
|
||||||
|
tokens_cache_write: usage.tokens.cache.write,
|
||||||
|
})
|
||||||
|
.where(eq(SessionTable.id, event.data.sessionID))
|
||||||
|
.run()
|
||||||
|
.pipe(Effect.orDie)
|
||||||
|
if (copiedSeq > 0) yield* EventV2.reserveSequence(db, event.data.sessionID, copiedSeq)
|
||||||
})
|
})
|
||||||
|
|
||||||
function run(db: DatabaseService, event: MessageEvent) {
|
function run(db: DatabaseService, event: MessageEvent) {
|
||||||
@@ -688,19 +697,8 @@ const layer = Layer.effectDiscard(
|
|||||||
yield* events.project(SessionEvent.Shell.Started, (event) => run(db, event))
|
yield* events.project(SessionEvent.Shell.Started, (event) => run(db, event))
|
||||||
yield* events.project(SessionEvent.Shell.Ended, (event) => run(db, event))
|
yield* events.project(SessionEvent.Shell.Ended, (event) => run(db, event))
|
||||||
yield* events.project(SessionEvent.Step.Started, (event) => run(db, event))
|
yield* events.project(SessionEvent.Step.Started, (event) => run(db, event))
|
||||||
yield* events.project(SessionEvent.Step.Ended, (event) =>
|
yield* events.project(SessionEvent.Step.Ended, (event) => run(db, event))
|
||||||
Effect.gen(function* () {
|
yield* events.project(SessionEvent.Step.Failed, (event) => run(db, event))
|
||||||
yield* run(db, event)
|
|
||||||
yield* applyUsage(db, event.data.sessionID, event.data)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
yield* events.project(SessionEvent.Step.Failed, (event) =>
|
|
||||||
Effect.gen(function* () {
|
|
||||||
yield* run(db, event)
|
|
||||||
if (event.data.cost !== undefined && event.data.tokens !== undefined)
|
|
||||||
yield* applyUsage(db, event.data.sessionID, { cost: event.data.cost, tokens: event.data.tokens })
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
yield* events.project(SessionEvent.Text.Started, (event) => run(db, event))
|
yield* events.project(SessionEvent.Text.Started, (event) => run(db, event))
|
||||||
yield* events.project(SessionEvent.Text.Ended, (event) => run(db, event))
|
yield* events.project(SessionEvent.Text.Ended, (event) => run(db, event))
|
||||||
yield* events.project(SessionEvent.Tool.Input.Started, (event) => run(db, event))
|
yield* events.project(SessionEvent.Tool.Input.Started, (event) => run(db, event))
|
||||||
@@ -792,17 +790,6 @@ const layer = Layer.effectDiscard(
|
|||||||
yield* InstructionCheckpoint.reset(db, event.data.sessionID)
|
yield* InstructionCheckpoint.reset(db, event.data.sessionID)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
yield* events.subscribe([SessionEvent.Step.Ended, SessionEvent.Step.Failed]).pipe(
|
|
||||||
Stream.runForEach((event) => {
|
|
||||||
if (
|
|
||||||
event.type === SessionEvent.Step.Failed.type &&
|
|
||||||
(event.data.cost === undefined || event.data.tokens === undefined)
|
|
||||||
)
|
|
||||||
return Effect.void
|
|
||||||
return publishSessionUsage(db, events, event.data.sessionID)
|
|
||||||
}),
|
|
||||||
Effect.forkScoped({ startImmediately: true }),
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import { Config } from "../../config"
|
|||||||
import { Database } from "../../database/database"
|
import { Database } from "../../database/database"
|
||||||
import { EventV2 } from "../../event"
|
import { EventV2 } from "../../event"
|
||||||
import { Location } from "../../location"
|
import { Location } from "../../location"
|
||||||
import { ModelV2 } from "../../model"
|
|
||||||
import { PermissionV2 } from "../../permission"
|
import { PermissionV2 } from "../../permission"
|
||||||
import { Instructions } from "../../instructions/index"
|
import { Instructions } from "../../instructions/index"
|
||||||
import { InstructionBuiltIns } from "../../instructions/builtins"
|
import { InstructionBuiltIns } from "../../instructions/builtins"
|
||||||
@@ -50,32 +49,6 @@ import { llmClient } from "../../effect/app-node-platform"
|
|||||||
import { StepFailedError, UserInterruptedError } from "../error"
|
import { StepFailedError, UserInterruptedError } from "../error"
|
||||||
import { toSessionError } from "../to-session-error"
|
import { toSessionError } from "../to-session-error"
|
||||||
import { SessionRunnerRetry } from "./retry"
|
import { SessionRunnerRetry } from "./retry"
|
||||||
import type { SessionHooks } from "@opencode-ai/plugin/v2/effect/session"
|
|
||||||
import { PluginHooks } from "../../plugin/hooks"
|
|
||||||
|
|
||||||
type StepTokens = {
|
|
||||||
readonly input: number
|
|
||||||
readonly output: number
|
|
||||||
readonly reasoning: number
|
|
||||||
readonly cache: { readonly read: number; readonly write: number }
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(#35765): Use Copilot's reported billed amount once billing has a dedicated typed runtime contract.
|
|
||||||
export function calculateCost(costs: ModelV2.Info["cost"], tokens: StepTokens) {
|
|
||||||
const context = tokens.input + tokens.cache.read + tokens.cache.write
|
|
||||||
const tier = costs
|
|
||||||
.filter((cost) => cost.tier?.type === "context" && context > cost.tier.size)
|
|
||||||
.toSorted((a, b) => (b.tier?.size ?? 0) - (a.tier?.size ?? 0))[0]
|
|
||||||
const cost = tier ?? costs.find((cost) => cost.tier === undefined)
|
|
||||||
if (!cost) return 0
|
|
||||||
return (
|
|
||||||
(tokens.input * cost.input +
|
|
||||||
(tokens.output + tokens.reasoning) * cost.output +
|
|
||||||
tokens.cache.read * cost.cache.read +
|
|
||||||
tokens.cache.write * cost.cache.write) /
|
|
||||||
1_000_000
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs one durable coding-agent Session until it settles.
|
* Runs one durable coding-agent Session until it settles.
|
||||||
@@ -134,7 +107,6 @@ const layer = Layer.effect(
|
|||||||
const llm = yield* LLMClient.Service
|
const llm = yield* LLMClient.Service
|
||||||
const agents = yield* AgentV2.Service
|
const agents = yield* AgentV2.Service
|
||||||
const tools = yield* ToolRegistry.Service
|
const tools = yield* ToolRegistry.Service
|
||||||
const hooks = yield* PluginHooks.Service
|
|
||||||
const models = yield* SessionRunnerModel.Service
|
const models = yield* SessionRunnerModel.Service
|
||||||
const store = yield* SessionStore.Service
|
const store = yield* SessionStore.Service
|
||||||
const location = yield* Location.Service
|
const location = yield* Location.Service
|
||||||
@@ -255,34 +227,10 @@ const layer = Layer.effect(
|
|||||||
tools: toolMaterialization?.definitions ?? [],
|
tools: toolMaterialization?.definitions ?? [],
|
||||||
toolChoice: isLastStep ? "none" : undefined,
|
toolChoice: isLastStep ? "none" : undefined,
|
||||||
})
|
})
|
||||||
const availableTools = new Map(request.tools.map((tool) => [tool.name, tool]))
|
|
||||||
const requestEvent: SessionHooks["request"] = {
|
|
||||||
sessionID: session.id,
|
|
||||||
agent: agent.id,
|
|
||||||
model: resolved.ref,
|
|
||||||
system: [...request.system],
|
|
||||||
messages: [...request.messages],
|
|
||||||
tools: Object.fromEntries(
|
|
||||||
request.tools.map((tool) => [tool.name, { description: tool.description, input: { ...tool.inputSchema } }]),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
// Plugins may reshape the draft, but cannot advertise tools excluded earlier
|
|
||||||
// by permissions or registration state.
|
|
||||||
yield* hooks.trigger("session", "request", requestEvent)
|
|
||||||
const hookedRequest = LLM.updateRequest(request, {
|
|
||||||
system: requestEvent.system,
|
|
||||||
messages: requestEvent.messages,
|
|
||||||
tools: Object.entries(requestEvent.tools).flatMap(([name, tool]) => {
|
|
||||||
const registered = availableTools.get(name)
|
|
||||||
if (!registered) return []
|
|
||||||
return [{ ...registered, description: tool.description, inputSchema: tool.input }]
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
const advertisedTools = new Set(hookedRequest.tools.map((tool) => tool.name))
|
|
||||||
// Automatic compaction completed; rebuild the request from compacted history.
|
// Automatic compaction completed; rebuild the request from compacted history.
|
||||||
if (
|
if (
|
||||||
!(yield* SessionInput.pendingCompaction(db, session.id)) &&
|
!(yield* SessionInput.pendingCompaction(db, session.id)) &&
|
||||||
(yield* compaction.compactIfNeeded({ sessionID: session.id, messages: context, request: hookedRequest }))
|
(yield* compaction.compactIfNeeded({ sessionID: session.id, messages: context, request }))
|
||||||
)
|
)
|
||||||
return { _tag: "RestartAfterCompaction", step: currentStep } as const
|
return { _tag: "RestartAfterCompaction", step: currentStep } as const
|
||||||
const startSnapshot = yield* snapshots.capture()
|
const startSnapshot = yield* snapshots.capture()
|
||||||
@@ -303,7 +251,7 @@ const layer = Layer.effect(
|
|||||||
const publish = (event: LLMEvent, outputPaths: ReadonlyArray<string> = [], error?: SessionError.Error) =>
|
const publish = (event: LLMEvent, outputPaths: ReadonlyArray<string> = [], error?: SessionError.Error) =>
|
||||||
serialized(publisher.publish(event, outputPaths, error))
|
serialized(publisher.publish(event, outputPaths, error))
|
||||||
let overflowFailure: ProviderErrorEvent | undefined
|
let overflowFailure: ProviderErrorEvent | undefined
|
||||||
const providerStream = llm.stream(hookedRequest).pipe(
|
const providerStream = llm.stream(request).pipe(
|
||||||
Stream.runForEach((event) =>
|
Stream.runForEach((event) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
if (overflowFailure || publisher.hasProviderError()) return
|
if (overflowFailure || publisher.hasProviderError()) return
|
||||||
@@ -315,11 +263,11 @@ const layer = Layer.effect(
|
|||||||
}
|
}
|
||||||
yield* publish(event)
|
yield* publish(event)
|
||||||
if (event.type !== "tool-call" || event.providerExecuted) return
|
if (event.type !== "tool-call" || event.providerExecuted) return
|
||||||
if (!toolMaterialization || !advertisedTools.has(event.name)) {
|
if (!toolMaterialization) {
|
||||||
yield* serialized(
|
yield* serialized(
|
||||||
publisher.failUnsettledTools({
|
publisher.failUnsettledTools({
|
||||||
type: "tool.execution",
|
type: "tool.execution",
|
||||||
message: `Tool is not available for this request: ${event.name}`,
|
message: "Tools are disabled after the maximum agent steps",
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@@ -364,11 +312,6 @@ const layer = Layer.effect(
|
|||||||
Effect.ensuring(serialized(publisher.flush())),
|
Effect.ensuring(serialized(publisher.flush())),
|
||||||
)
|
)
|
||||||
|
|
||||||
const stepUsage = (settlement: NonNullable<ReturnType<typeof publisher.stepSettlement>>) => ({
|
|
||||||
cost: calculateCost(resolved.cost, settlement.tokens),
|
|
||||||
tokens: settlement.tokens,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Captures the end snapshot, diffs it against the step's start, and durably ends the
|
// Captures the end snapshot, diffs it against the step's start, and durably ends the
|
||||||
// assistant step.
|
// assistant step.
|
||||||
const publishStepEnd = (settlement: NonNullable<ReturnType<typeof publisher.stepSettlement>>) =>
|
const publishStepEnd = (settlement: NonNullable<ReturnType<typeof publisher.stepSettlement>>) =>
|
||||||
@@ -385,7 +328,8 @@ const layer = Layer.effect(
|
|||||||
sessionID: session.id,
|
sessionID: session.id,
|
||||||
assistantMessageID: yield* publisher.startAssistant(),
|
assistantMessageID: yield* publisher.startAssistant(),
|
||||||
finish: settlement.finish,
|
finish: settlement.finish,
|
||||||
...stepUsage(settlement),
|
cost: 0,
|
||||||
|
tokens: settlement.tokens,
|
||||||
snapshot: endSnapshot,
|
snapshot: endSnapshot,
|
||||||
files,
|
files,
|
||||||
}),
|
}),
|
||||||
@@ -508,8 +452,7 @@ const layer = Layer.effect(
|
|||||||
const stepEndedCleanly =
|
const stepEndedCleanly =
|
||||||
!streamInterrupted && !toolsInterrupted && infraError === undefined && !providerFailed && !stepFailure
|
!streamInterrupted && !toolsInterrupted && infraError === undefined && !providerFailed && !stepFailure
|
||||||
if (stepSettlement && stepEndedCleanly) yield* publishStepEnd(stepSettlement)
|
if (stepSettlement && stepEndedCleanly) yield* publishStepEnd(stepSettlement)
|
||||||
if (stepFailure)
|
if (stepFailure) yield* serialized(publisher.publishStepFailure())
|
||||||
yield* serialized(publisher.publishStepFailure(stepSettlement ? stepUsage(stepSettlement) : undefined))
|
|
||||||
|
|
||||||
if (stream._tag === "Failure") return yield* Effect.failCause(stream.cause)
|
if (stream._tag === "Failure") return yield* Effect.failCause(stream.cause)
|
||||||
if (userDeclined) return yield* Effect.interrupt
|
if (userDeclined) return yield* Effect.interrupt
|
||||||
@@ -652,7 +595,6 @@ export const node = makeLocationNode({
|
|||||||
llmClient,
|
llmClient,
|
||||||
AgentV2.node,
|
AgentV2.node,
|
||||||
ToolRegistry.node,
|
ToolRegistry.node,
|
||||||
PluginHooks.node,
|
|
||||||
SessionRunnerModel.node,
|
SessionRunnerModel.node,
|
||||||
SessionStore.node,
|
SessionStore.node,
|
||||||
Location.node,
|
Location.node,
|
||||||
|
|||||||
@@ -82,8 +82,6 @@ export interface Resolved {
|
|||||||
readonly model: Model
|
readonly model: Model
|
||||||
/** Selected catalog identity. Durable records and displays must use this, never the API model id. */
|
/** Selected catalog identity. Durable records and displays must use this, never the API model id. */
|
||||||
readonly ref: ModelV2.Ref
|
readonly ref: ModelV2.Ref
|
||||||
/** Catalog pricing in dollars per million tokens. */
|
|
||||||
readonly cost: ModelV2.Info["cost"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Interface {
|
export interface Interface {
|
||||||
@@ -96,14 +94,13 @@ export class Service extends Context.Service<Service, Interface>()("@opencode/v2
|
|||||||
export const layerWith = (resolve: Interface["resolve"]) => Layer.succeed(Service, Service.of({ resolve }))
|
export const layerWith = (resolve: Interface["resolve"]) => Layer.succeed(Service, Service.of({ resolve }))
|
||||||
|
|
||||||
/** Builds a Resolved whose catalog identity mirrors the route model. Test or embedding seam. */
|
/** Builds a Resolved whose catalog identity mirrors the route model. Test or embedding seam. */
|
||||||
export const resolved = (model: Model, variant?: ModelV2.VariantID, cost: ModelV2.Info["cost"] = []): Resolved => ({
|
export const resolved = (model: Model, variant?: ModelV2.VariantID): Resolved => ({
|
||||||
model,
|
model,
|
||||||
ref: ModelV2.Ref.make({
|
ref: ModelV2.Ref.make({
|
||||||
id: ModelV2.ID.make(model.id),
|
id: ModelV2.ID.make(model.id),
|
||||||
providerID: ProviderV2.ID.make(model.provider),
|
providerID: ProviderV2.ID.make(model.provider),
|
||||||
...(variant === undefined ? {} : { variant }),
|
...(variant === undefined ? {} : { variant }),
|
||||||
}),
|
}),
|
||||||
cost,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const apiKey = (model: ModelV2.Info, credential?: Credential.Value) => {
|
const apiKey = (model: ModelV2.Info, credential?: Credential.Value) => {
|
||||||
@@ -344,7 +341,6 @@ const layer = Layer.effect(
|
|||||||
providerID: selected.providerID,
|
providerID: selected.providerID,
|
||||||
...(session.model?.variant === undefined ? {} : { variant: session.model.variant }),
|
...(session.model?.variant === undefined ? {} : { variant: session.model.variant }),
|
||||||
}),
|
}),
|
||||||
cost: selected.cost,
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -101,36 +101,27 @@ export const createLLMEventPublisher = (events: EventV2.Interface, input: Input)
|
|||||||
ended: (id: string, value: string, ordinal: number, state?: Record<string, unknown>) => Effect.Effect<void>,
|
ended: (id: string, value: string, ordinal: number, state?: Record<string, unknown>) => Effect.Effect<void>,
|
||||||
single = false,
|
single = false,
|
||||||
) => {
|
) => {
|
||||||
const chunks = new Map<
|
const chunks = new Map<string, { readonly ordinal: number; readonly values: string[] }>()
|
||||||
string,
|
|
||||||
{ readonly ordinal: number; readonly values: string[]; state?: Record<string, unknown> }
|
|
||||||
>()
|
|
||||||
let nextOrdinal = 0
|
let nextOrdinal = 0
|
||||||
const start = (id: string, state?: Record<string, unknown>) =>
|
const start = (id: string) =>
|
||||||
Effect.suspend(() => {
|
Effect.suspend(() => {
|
||||||
if (chunks.has(id)) return Effect.die(new Error(`Duplicate ${name} start: ${id}`))
|
if (chunks.has(id)) return Effect.die(new Error(`Duplicate ${name} start: ${id}`))
|
||||||
if (single && chunks.size > 0) return Effect.die(new Error(`${name} start before end: ${id}`))
|
if (single && chunks.size > 0) return Effect.die(new Error(`${name} start before end: ${id}`))
|
||||||
const ordinal = nextOrdinal++
|
const ordinal = nextOrdinal++
|
||||||
chunks.set(id, { ordinal, values: [], state })
|
chunks.set(id, { ordinal, values: [] })
|
||||||
return Effect.succeed(ordinal)
|
return Effect.succeed(ordinal)
|
||||||
})
|
})
|
||||||
const append = (id: string, value: string, state?: Record<string, unknown>) =>
|
const append = (id: string, value: string) =>
|
||||||
Effect.suspend(() => {
|
Effect.suspend(() => {
|
||||||
const current = chunks.get(id)
|
const current = chunks.get(id)
|
||||||
if (!current) return Effect.die(new Error(`${name} delta before start: ${id}`))
|
if (!current) return Effect.die(new Error(`${name} delta before start: ${id}`))
|
||||||
current.values.push(value)
|
current.values.push(value)
|
||||||
if (state !== undefined) current.state = { ...current.state, ...state }
|
|
||||||
return Effect.succeed(current.ordinal)
|
return Effect.succeed(current.ordinal)
|
||||||
})
|
})
|
||||||
const end = Effect.fnUntraced(function* (id: string, state?: Record<string, unknown>) {
|
const end = Effect.fnUntraced(function* (id: string, state?: Record<string, unknown>) {
|
||||||
const current = chunks.get(id)
|
const current = chunks.get(id)
|
||||||
if (!current) return yield* Effect.die(new Error(`${name} end before start: ${id}`))
|
if (!current) return yield* Effect.die(new Error(`${name} end before start: ${id}`))
|
||||||
yield* ended(
|
yield* ended(id, current.values.join(""), current.ordinal, state)
|
||||||
id,
|
|
||||||
current.values.join(""),
|
|
||||||
current.ordinal,
|
|
||||||
state === undefined ? current.state : { ...current.state, ...state },
|
|
||||||
)
|
|
||||||
chunks.delete(id)
|
chunks.delete(id)
|
||||||
})
|
})
|
||||||
const flush = Effect.fnUntraced(function* () {
|
const flush = Effect.fnUntraced(function* () {
|
||||||
@@ -225,10 +216,7 @@ export const createLLMEventPublisher = (events: EventV2.Interface, input: Input)
|
|||||||
if (replace || stepFailure === undefined) stepFailure = error
|
if (replace || stepFailure === undefined) stepFailure = error
|
||||||
})
|
})
|
||||||
|
|
||||||
const publishStepFailure = Effect.fnUntraced(function* (usage?: {
|
const publishStepFailure = Effect.fnUntraced(function* () {
|
||||||
readonly cost: number
|
|
||||||
readonly tokens: ReturnType<typeof tokens>
|
|
||||||
}) {
|
|
||||||
if (stepFailed || stepFailure === undefined) return
|
if (stepFailed || stepFailure === undefined) return
|
||||||
const assistantMessageID = yield* startAssistant()
|
const assistantMessageID = yield* startAssistant()
|
||||||
stepFailed = true
|
stepFailed = true
|
||||||
@@ -236,7 +224,6 @@ export const createLLMEventPublisher = (events: EventV2.Interface, input: Input)
|
|||||||
sessionID: input.sessionID,
|
sessionID: input.sessionID,
|
||||||
assistantMessageID,
|
assistantMessageID,
|
||||||
error: stepFailure,
|
error: stepFailure,
|
||||||
...usage,
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -297,7 +284,7 @@ export const createLLMEventPublisher = (events: EventV2.Interface, input: Input)
|
|||||||
return
|
return
|
||||||
case "reasoning-start":
|
case "reasoning-start":
|
||||||
retryEvidence = true
|
retryEvidence = true
|
||||||
const startedReasoningOrdinal = yield* reasoning.start(event.id, providerState(event.providerMetadata))
|
const startedReasoningOrdinal = yield* reasoning.start(event.id)
|
||||||
yield* events.publish(SessionEvent.Reasoning.Started, {
|
yield* events.publish(SessionEvent.Reasoning.Started, {
|
||||||
sessionID: input.sessionID,
|
sessionID: input.sessionID,
|
||||||
assistantMessageID: yield* startAssistant(),
|
assistantMessageID: yield* startAssistant(),
|
||||||
@@ -306,11 +293,7 @@ export const createLLMEventPublisher = (events: EventV2.Interface, input: Input)
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
case "reasoning-delta":
|
case "reasoning-delta":
|
||||||
const deltaReasoningOrdinal = yield* reasoning.append(
|
const deltaReasoningOrdinal = yield* reasoning.append(event.id, event.text)
|
||||||
event.id,
|
|
||||||
event.text,
|
|
||||||
providerState(event.providerMetadata),
|
|
||||||
)
|
|
||||||
yield* events.publish(SessionEvent.Reasoning.Delta, {
|
yield* events.publish(SessionEvent.Reasoning.Delta, {
|
||||||
sessionID: input.sessionID,
|
sessionID: input.sessionID,
|
||||||
assistantMessageID: yield* currentAssistantMessageID(),
|
assistantMessageID: yield* currentAssistantMessageID(),
|
||||||
@@ -426,12 +409,12 @@ export const createLLMEventPublisher = (events: EventV2.Interface, input: Input)
|
|||||||
case "step-finish":
|
case "step-finish":
|
||||||
yield* flush()
|
yield* flush()
|
||||||
if (stepSettlement) return yield* Effect.die(new Error("Duplicate step finish"))
|
if (stepSettlement) return yield* Effect.die(new Error("Duplicate step finish"))
|
||||||
stepSettlement = { finish: event.reason, tokens: tokens(event.usage) }
|
|
||||||
if (event.reason === "content-filter") {
|
if (event.reason === "content-filter") {
|
||||||
providerFailed = true
|
providerFailed = true
|
||||||
yield* failAssistant({ type: "provider.content-filter", message: "Provider blocked the response" }, true)
|
yield* failAssistant({ type: "provider.content-filter", message: "Provider blocked the response" }, true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
stepSettlement = { finish: event.reason, tokens: tokens(event.usage) }
|
||||||
return
|
return
|
||||||
case "finish":
|
case "finish":
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ Registrations are scoped:
|
|||||||
|
|
||||||
## Permissions
|
## Permissions
|
||||||
|
|
||||||
The registry has no `PermissionV2.Service` dependency and performs no execution authorization. An internal built-in-only operation attaches a permission action solely to preserve whole-tool definition filtering; it is not part of public `Tool.make`. Most tools default to their registered name; `edit`, `write`, and `patch` declare the shared `edit` action.
|
The registry has no `PermissionV2.Service` dependency and performs no execution authorization. An internal built-in-only operation attaches a permission action solely to preserve whole-tool definition filtering; it is not part of public `Tool.make`. Most tools default to their registered name; `edit`, `write`, and `apply_patch` declare the shared `edit` action.
|
||||||
|
|
||||||
Definition filtering is catalog visibility, not execution authorization. A call still executes the captured leaf policy if it reaches settlement.
|
Definition filtering is catalog visibility, not execution authorization. A call still executes the captured leaf policy if it reaches settlement.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as ApplyPatchTool from "./apply-patch"
|
export * as ApplyPatchTool from "./apply-patch"
|
||||||
|
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import { FileDiff } from "@opencode-ai/schema/file-diff"
|
import { FileDiff } from "@opencode-ai/schema/file-diff"
|
||||||
import { createTwoFilesPatch, diffLines } from "diff"
|
import { createTwoFilesPatch, diffLines } from "diff"
|
||||||
@@ -12,7 +12,7 @@ import { Patch } from "../patch"
|
|||||||
import { PermissionV2 } from "../permission"
|
import { PermissionV2 } from "../permission"
|
||||||
import { Tool } from "./tool"
|
import { Tool } from "./tool"
|
||||||
|
|
||||||
export const name = "patch"
|
export const name = "apply_patch"
|
||||||
|
|
||||||
export const Input = Schema.Struct({
|
export const Input = Schema.Struct({
|
||||||
patchText: Schema.String.annotate({
|
patchText: Schema.String.annotate({
|
||||||
@@ -91,11 +91,11 @@ export const Plugin = {
|
|||||||
if (!input.patchText.trim()) return yield* new ToolFailure({ message: "patchText is required" })
|
if (!input.patchText.trim()) return yield* new ToolFailure({ message: "patchText is required" })
|
||||||
const hunks = yield* Effect.try({
|
const hunks = yield* Effect.try({
|
||||||
try: () => Patch.parse(input.patchText),
|
try: () => Patch.parse(input.patchText),
|
||||||
catch: (cause) => new ToolFailure({ message: `patch verification failed: ${String(cause)}` }),
|
catch: (cause) => new ToolFailure({ message: `apply_patch verification failed: ${String(cause)}` }),
|
||||||
})
|
})
|
||||||
if (hunks.length === 0) return yield* new ToolFailure({ message: "patch rejected: empty patch" })
|
if (hunks.length === 0) return yield* new ToolFailure({ message: "patch rejected: empty patch" })
|
||||||
const move = hunks.find((hunk) => hunk.type === "update" && hunk.movePath !== undefined)
|
const move = hunks.find((hunk) => hunk.type === "update" && hunk.movePath !== undefined)
|
||||||
if (move) return yield* new ToolFailure({ message: "patch moves are not supported yet" })
|
if (move) return yield* new ToolFailure({ message: "apply_patch moves are not supported yet" })
|
||||||
|
|
||||||
const targets: Array<{ readonly hunk: Patch.Hunk; readonly target: LocationMutation.Target }> = []
|
const targets: Array<{ readonly hunk: Patch.Hunk; readonly target: LocationMutation.Target }> = []
|
||||||
for (const hunk of hunks)
|
for (const hunk of hunks)
|
||||||
@@ -194,19 +194,6 @@ export const Plugin = {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.pipe(Effect.orDie)
|
.pipe(Effect.orDie)
|
||||||
|
|
||||||
yield* ctx.session.hook("request", (event) =>
|
|
||||||
Effect.sync(() => {
|
|
||||||
const usePatch =
|
|
||||||
event.model.providerID.toLowerCase() === "openai" || event.model.id.toLowerCase().includes("gpt")
|
|
||||||
if (usePatch) {
|
|
||||||
delete event.tools.edit
|
|
||||||
delete event.tools.write
|
|
||||||
return
|
|
||||||
}
|
|
||||||
delete event.tools.patch
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
export * as EditTool from "./edit"
|
export * as EditTool from "./edit"
|
||||||
|
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import { FileDiff } from "@opencode-ai/schema/file-diff"
|
import { FileDiff } from "@opencode-ai/schema/file-diff"
|
||||||
import { createTwoFilesPatch, diffLines } from "diff"
|
import { createTwoFilesPatch, diffLines } from "diff"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
export * as GlobTool from "./glob"
|
export * as GlobTool from "./glob"
|
||||||
|
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Effect, Schema } from "effect"
|
import { Effect, Schema } from "effect"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { FileSystem } from "../filesystem"
|
import { FileSystem } from "../filesystem"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as GrepTool from "./grep"
|
export * as GrepTool from "./grep"
|
||||||
|
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import { Effect, Schema } from "effect"
|
import { Effect, Schema } from "effect"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as QuestionTool from "./question"
|
export * as QuestionTool from "./question"
|
||||||
|
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import { Effect, Schema } from "effect"
|
import { Effect, Schema } from "effect"
|
||||||
import { Form } from "../form"
|
import { Form } from "../form"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as ReadTool from "./read"
|
export * as ReadTool from "./read"
|
||||||
|
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { dirname } from "path"
|
import { dirname } from "path"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import { Effect, Schema } from "effect"
|
import { Effect, Schema } from "effect"
|
||||||
|
|||||||
@@ -191,8 +191,12 @@ const registryLayer = Layer.effect(
|
|||||||
const registration = entries.at(-1)?.registration
|
const registration = entries.at(-1)?.registration
|
||||||
if (registration) registrations.set(name, registration)
|
if (registration) registrations.set(name, registration)
|
||||||
}
|
}
|
||||||
|
// OpenAI/GPT models use apply_patch; every other model uses edit and write.
|
||||||
|
const usePatch = input.model.provider.toLowerCase() === "openai" || input.model.id.toLowerCase().includes("gpt")
|
||||||
for (const [name, registration] of registrations) {
|
for (const [name, registration] of registrations) {
|
||||||
|
const wrongEditTool = name === "apply_patch" ? !usePatch : (name === "edit" || name === "write") && usePatch
|
||||||
if (
|
if (
|
||||||
|
wrongEditTool ||
|
||||||
(registration.deferred && !Flag.CODEMODE_ENABLED) ||
|
(registration.deferred && !Flag.CODEMODE_ENABLED) ||
|
||||||
whollyDisabled(permission(registration.tool, name), input.permissions ?? [])
|
whollyDisabled(permission(registration.tool, name), input.permissions ?? [])
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ export * as ShellTool from "./shell"
|
|||||||
|
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Effect, Schema, Scope } from "effect"
|
import { Effect, Schema, Scope } from "effect"
|
||||||
import { FSUtil } from "../fs-util"
|
import { FSUtil } from "../fs-util"
|
||||||
import { LocationMutation } from "../location-mutation"
|
import { LocationMutation } from "../location-mutation"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as SkillTool from "./skill"
|
export * as SkillTool from "./skill"
|
||||||
|
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import { Effect, Schema } from "effect"
|
import { Effect, Schema } from "effect"
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
export * as SubagentTool from "./subagent"
|
export * as SubagentTool from "./subagent"
|
||||||
|
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Effect, Schema, Scope } from "effect"
|
import { Effect, Schema, Scope } from "effect"
|
||||||
import { AgentV2 } from "../agent"
|
import { AgentV2 } from "../agent"
|
||||||
import { PluginRuntime } from "../plugin/runtime"
|
import { PluginRuntime } from "../plugin/runtime"
|
||||||
import { PermissionV2 } from "../permission"
|
|
||||||
import { SessionSchema } from "../session/schema"
|
import { SessionSchema } from "../session/schema"
|
||||||
import { Tool } from "./tool"
|
import { Tool } from "./tool"
|
||||||
|
|
||||||
@@ -43,7 +42,6 @@ export const Plugin = {
|
|||||||
effect: Effect.fn("SubagentTool.Plugin")(function* (ctx: PluginContext) {
|
effect: Effect.fn("SubagentTool.Plugin")(function* (ctx: PluginContext) {
|
||||||
const runtime = yield* PluginRuntime.Service
|
const runtime = yield* PluginRuntime.Service
|
||||||
const agents = yield* AgentV2.Service
|
const agents = yield* AgentV2.Service
|
||||||
const permission = yield* PermissionV2.Service
|
|
||||||
const scope = yield* Scope.Scope
|
const scope = yield* Scope.Scope
|
||||||
|
|
||||||
// Concatenate the child's final completed assistant text. Distinguishes "completed with no
|
// Concatenate the child's final completed assistant text. Distinguishes "completed with no
|
||||||
@@ -116,20 +114,6 @@ export const Plugin = {
|
|||||||
if (agent === undefined) return yield* new ToolFailure({ message: `Unknown agent: ${input.agent}` })
|
if (agent === undefined) return yield* new ToolFailure({ message: `Unknown agent: ${input.agent}` })
|
||||||
if (agent.mode === "primary")
|
if (agent.mode === "primary")
|
||||||
return yield* new ToolFailure({ message: `Agent ${input.agent} cannot run as a subagent` })
|
return yield* new ToolFailure({ message: `Agent ${input.agent} cannot run as a subagent` })
|
||||||
yield* permission
|
|
||||||
.assert({
|
|
||||||
action: name,
|
|
||||||
resources: [agent.id],
|
|
||||||
save: [agent.id],
|
|
||||||
sessionID: context.sessionID,
|
|
||||||
agent: context.agent,
|
|
||||||
source: {
|
|
||||||
type: "tool",
|
|
||||||
messageID: context.assistantMessageID,
|
|
||||||
callID: context.toolCallID,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.pipe(Effect.mapError((error) => new ToolFailure({ message: `Subagent denied: ${agent.id}`, error })))
|
|
||||||
|
|
||||||
// Model selection is policy/config/session state, not an LLM-facing tool argument.
|
// Model selection is policy/config/session state, not an LLM-facing tool argument.
|
||||||
const model = agent.model ?? parent.model
|
const model = agent.model ?? parent.model
|
||||||
@@ -192,32 +176,5 @@ export const Plugin = {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.pipe(Effect.orDie)
|
.pipe(Effect.orDie)
|
||||||
|
|
||||||
yield* ctx.session.hook("request", (event) =>
|
|
||||||
Effect.gen(function* () {
|
|
||||||
const tool = event.tools[name]
|
|
||||||
if (!tool) return
|
|
||||||
const selected = yield* agents.resolve(event.agent)
|
|
||||||
if (!selected) return
|
|
||||||
const available = (yield* agents.list())
|
|
||||||
.filter(
|
|
||||||
(agent) =>
|
|
||||||
agent.mode !== "primary" &&
|
|
||||||
!agent.hidden &&
|
|
||||||
PermissionV2.evaluate(name, agent.id, selected.permissions).effect !== "deny",
|
|
||||||
)
|
|
||||||
.toSorted((a, b) => a.id.localeCompare(b.id))
|
|
||||||
if (available.length === 0) return
|
|
||||||
tool.description = [
|
|
||||||
tool.description,
|
|
||||||
"",
|
|
||||||
"Available subagents:",
|
|
||||||
...available.map(
|
|
||||||
(agent) =>
|
|
||||||
`- ${agent.id}: ${agent.description ?? "This subagent should only be called when explicitly requested."}`,
|
|
||||||
),
|
|
||||||
].join("\n")
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as TodoWriteTool from "./todowrite"
|
export * as TodoWriteTool from "./todowrite"
|
||||||
|
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import { Effect, Schema } from "effect"
|
import { Effect, Schema } from "effect"
|
||||||
import { PermissionV2 } from "../permission"
|
import { PermissionV2 } from "../permission"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as WebFetchTool from "./webfetch"
|
export * as WebFetchTool from "./webfetch"
|
||||||
|
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import { Duration, Effect, Schema } from "effect"
|
import { Duration, Effect, Schema } from "effect"
|
||||||
import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
|
import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export * as WebSearchTool from "./websearch"
|
export * as WebSearchTool from "./websearch"
|
||||||
|
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import { Context, Duration, Effect, Layer, Schema } from "effect"
|
import { Context, Duration, Effect, Layer, Schema } from "effect"
|
||||||
import { HttpClient, HttpClientRequest } from "effect/unstable/http"
|
import { HttpClient, HttpClientRequest } from "effect/unstable/http"
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
export * as WriteTool from "./write"
|
export * as WriteTool from "./write"
|
||||||
|
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { ToolFailure } from "@opencode-ai/llm"
|
import { ToolFailure } from "@opencode-ai/llm"
|
||||||
import { Effect, Schema } from "effect"
|
import { Effect, Schema } from "effect"
|
||||||
import { FileMutation } from "../file-mutation"
|
import { FileMutation } from "../file-mutation"
|
||||||
|
|||||||
@@ -51,11 +51,13 @@ it.effect("projects request settings, headers, and body overlays", () =>
|
|||||||
apiKey: "secret",
|
apiKey: "secret",
|
||||||
thinkingConfig: { thinkingBudget: 1024 },
|
thinkingConfig: { thinkingBudget: 1024 },
|
||||||
})
|
})
|
||||||
const resolved = yield* aisdk.model({
|
const resolved = yield* aisdk.model(
|
||||||
|
{
|
||||||
...input,
|
...input,
|
||||||
headers: { "x-test": "header" },
|
headers: { "x-test": "header" },
|
||||||
body: { safety_setting: "strict" },
|
body: { safety_setting: "strict" },
|
||||||
})
|
},
|
||||||
|
)
|
||||||
const prepared = yield* LLMClient.prepare<LanguageModelV3CallOptions>(
|
const prepared = yield* LLMClient.prepare<LanguageModelV3CallOptions>(
|
||||||
LLM.request({ model: resolved, prompt: "Hello" }),
|
LLM.request({ model: resolved, prompt: "Hello" }),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Plugin } from "@opencode-ai/plugin/v2"
|
import { define } from "@opencode-ai/plugin/v2/promise"
|
||||||
|
|
||||||
export default Plugin.define({
|
export default define({
|
||||||
id: "directory-plugin",
|
id: "directory-plugin",
|
||||||
setup: async (ctx) => {
|
setup: async (ctx) => {
|
||||||
await ctx.agent.transform((agents) => {
|
await ctx.agent.transform((agents) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Plugin } from "@opencode-ai/plugin/v2"
|
import { define } from "@opencode-ai/plugin/v2/promise"
|
||||||
|
|
||||||
export default Plugin.define({
|
export default define({
|
||||||
id: "folder-plugin",
|
id: "folder-plugin",
|
||||||
setup: async (ctx) => {
|
setup: async (ctx) => {
|
||||||
await ctx.agent.transform((agents) => {
|
await ctx.agent.transform((agents) => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import fs from "fs/promises"
|
|||||||
import path from "path"
|
import path from "path"
|
||||||
import { pathToFileURL } from "url"
|
import { pathToFileURL } from "url"
|
||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
import { Plugin as EffectPlugin } from "@opencode-ai/plugin/v2/effect"
|
import { define } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Config as ConfigSchema } from "@opencode-ai/schema/config"
|
import { Config as ConfigSchema } from "@opencode-ai/schema/config"
|
||||||
import { Plugin } from "@opencode-ai/schema/plugin"
|
import { Plugin } from "@opencode-ai/schema/plugin"
|
||||||
import { AgentV2 } from "@opencode-ai/core/agent"
|
import { AgentV2 } from "@opencode-ai/core/agent"
|
||||||
@@ -178,7 +178,7 @@ describe("PluginSupervisor config", () => {
|
|||||||
it.live("loads user plugins before internal post plugins", () =>
|
it.live("loads user plugins before internal post plugins", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const sdk = yield* SdkPlugins.Service
|
const sdk = yield* SdkPlugins.Service
|
||||||
yield* sdk.register(EffectPlugin.define({ id: "sdk-order", effect: () => Effect.void }))
|
yield* sdk.register(define({ id: "sdk-order", effect: () => Effect.void }))
|
||||||
yield* withLocation(
|
yield* withLocation(
|
||||||
{
|
{
|
||||||
plugins: [
|
plugins: [
|
||||||
@@ -275,7 +275,7 @@ function mutablePlugin(description: string) {
|
|||||||
return `
|
return `
|
||||||
import { define } from ${JSON.stringify(plugin)}
|
import { define } from ${JSON.stringify(plugin)}
|
||||||
|
|
||||||
export default EffectPlugin.define({
|
export default define({
|
||||||
id: "mutable-plugin",
|
id: "mutable-plugin",
|
||||||
setup: async (ctx) => {
|
setup: async (ctx) => {
|
||||||
await ctx.agent.transform((agents) => {
|
await ctx.agent.transform((agents) => {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { SessionMessage } from "@opencode-ai/core/session/message"
|
|||||||
import { ToolRegistry } from "@opencode-ai/core/tool/registry"
|
import { ToolRegistry } from "@opencode-ai/core/tool/registry"
|
||||||
import { Tool } from "@opencode-ai/core/tool/tool"
|
import { Tool } from "@opencode-ai/core/tool/tool"
|
||||||
import { Tools } from "@opencode-ai/core/tool/tools"
|
import { Tools } from "@opencode-ai/core/tool/tools"
|
||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Effect, type Scope } from "effect"
|
import { Effect, type Scope } from "effect"
|
||||||
|
|
||||||
export const toolIdentity = {
|
export const toolIdentity = {
|
||||||
@@ -66,10 +66,12 @@ export const registerToolPlugin = <R>(plugin: {
|
|||||||
registrations,
|
registrations,
|
||||||
(registration) => tools.register({ [registration.name]: registration.tool }, registration.options),
|
(registration) => tools.register({ [registration.name]: registration.tool }, registration.options),
|
||||||
{ discard: true },
|
{ discard: true },
|
||||||
).pipe(Effect.orDie)
|
)
|
||||||
return { dispose: Effect.void }
|
|
||||||
}),
|
}),
|
||||||
hook: () => Effect.die("registerToolPlugin does not support tool hooks"),
|
execute: {
|
||||||
|
before: () => Effect.die("registerToolPlugin does not support tool hooks"),
|
||||||
|
after: () => Effect.die("registerToolPlugin does not support tool hooks"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
yield* plugin.effect(context as PluginContext)
|
yield* plugin.effect(context as PluginContext)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { describe, expect } from "bun:test"
|
|||||||
import { Config } from "@opencode-ai/schema/config"
|
import { Config } from "@opencode-ai/schema/config"
|
||||||
import { Plugin } from "@opencode-ai/schema/plugin"
|
import { Plugin } from "@opencode-ai/schema/plugin"
|
||||||
import { Context, DateTime, Effect, Equal, Hash, RcMap, Schema, Stream } from "effect"
|
import { Context, DateTime, Effect, Equal, Hash, RcMap, Schema, Stream } from "effect"
|
||||||
import { Plugin as EffectPlugin } from "@opencode-ai/plugin/v2/effect"
|
import { define } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { AgentV2 } from "@opencode-ai/core/agent"
|
import { AgentV2 } from "@opencode-ai/core/agent"
|
||||||
import { Catalog } from "@opencode-ai/core/catalog"
|
import { Catalog } from "@opencode-ai/core/catalog"
|
||||||
import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
|
import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
|
||||||
@@ -44,7 +44,7 @@ describe("LocationServiceMap", () => {
|
|||||||
const sdk = yield* SdkPlugins.Service
|
const sdk = yield* SdkPlugins.Service
|
||||||
const locations = yield* LocationServiceMap.Service
|
const locations = yield* LocationServiceMap.Service
|
||||||
const id = AgentV2.ID.make("persistent-sdk-agent")
|
const id = AgentV2.ID.make("persistent-sdk-agent")
|
||||||
const plugin = EffectPlugin.define({
|
const plugin = define({
|
||||||
id: "persistent-sdk-plugin",
|
id: "persistent-sdk-plugin",
|
||||||
effect: (ctx) => ctx.agent.transform((agents) => agents.update(id, () => {})),
|
effect: (ctx) => ctx.agent.transform((agents) => agents.update(id, () => {})),
|
||||||
})
|
})
|
||||||
@@ -432,7 +432,7 @@ describe("LocationServiceMap", () => {
|
|||||||
Effect.flatMap((dir) =>
|
Effect.flatMap((dir) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugins = yield* PluginV2.Service
|
const plugins = yield* PluginV2.Service
|
||||||
const reviewer = EffectPlugin.define({
|
const reviewer = define({
|
||||||
id: "reviewer",
|
id: "reviewer",
|
||||||
effect: (ctx) =>
|
effect: (ctx) =>
|
||||||
ctx.agent
|
ctx.agent
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
import { describe, expect, it } from "bun:test"
|
|
||||||
import { Message, SystemPart } from "@opencode-ai/llm"
|
|
||||||
import { Agent } from "@opencode-ai/schema/agent"
|
|
||||||
import { Model } from "@opencode-ai/schema/model"
|
|
||||||
import { Provider } from "@opencode-ai/schema/provider"
|
|
||||||
import { Session } from "@opencode-ai/schema/session"
|
|
||||||
import { Effect, Layer } from "effect"
|
|
||||||
import { PluginHooks } from "../src/plugin/hooks"
|
|
||||||
|
|
||||||
describe("PluginHooks", () => {
|
|
||||||
it("registers scoped domain hooks and triggers them sequentially", async () => {
|
|
||||||
const seen: string[] = []
|
|
||||||
const program = Effect.gen(function* () {
|
|
||||||
const hooks = yield* PluginHooks.Service
|
|
||||||
yield* hooks.register("session", "request", (event) =>
|
|
||||||
Effect.sync(() => {
|
|
||||||
seen.push("first")
|
|
||||||
event.system.push(SystemPart.make("second"))
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
yield* hooks.register("session", "request", (event) =>
|
|
||||||
Effect.sync(() => {
|
|
||||||
seen.push(event.system[1]?.text ?? "missing")
|
|
||||||
event.messages = [Message.user("changed")]
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
const event = {
|
|
||||||
sessionID: Session.ID.make("ses_hooks"),
|
|
||||||
agent: Agent.ID.make("build"),
|
|
||||||
model: Model.Ref.make({ providerID: Provider.ID.make("test"), id: Model.ID.make("model") }),
|
|
||||||
system: [SystemPart.make("first")],
|
|
||||||
messages: [Message.user("original")],
|
|
||||||
tools: {},
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(yield* hooks.trigger("session", "request", event)).toBe(event)
|
|
||||||
expect(seen).toEqual(["first", "second"])
|
|
||||||
expect(event.messages).toEqual([Message.user("changed")])
|
|
||||||
})
|
|
||||||
|
|
||||||
await Effect.runPromise(
|
|
||||||
Effect.scoped(program).pipe(
|
|
||||||
Effect.provide(PluginHooks.node.implementation as Layer.Layer<PluginHooks.Service>),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
import { Context, Effect, Exit, Fiber, Schema, Stream } from "effect"
|
import { Context, Effect, Exit, Fiber, Schema, Stream } from "effect"
|
||||||
import { Plugin as EffectPlugin } from "@opencode-ai/plugin/v2/effect"
|
import { define } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Config as ConfigSchema } from "@opencode-ai/schema/config"
|
import { Config as ConfigSchema } from "@opencode-ai/schema/config"
|
||||||
import { Plugin } from "@opencode-ai/schema/plugin"
|
import { Plugin } from "@opencode-ai/schema/plugin"
|
||||||
import { AgentV2 } from "@opencode-ai/core/agent"
|
import { AgentV2 } from "@opencode-ai/core/agent"
|
||||||
@@ -49,7 +49,7 @@ describe("PluginV2", () => {
|
|||||||
.pipe(Stream.take(2), Stream.runCollect, Effect.forkScoped({ startImmediately: true }))
|
.pipe(Stream.take(2), Stream.runCollect, Effect.forkScoped({ startImmediately: true }))
|
||||||
|
|
||||||
const managed = () =>
|
const managed = () =>
|
||||||
EffectPlugin.define({
|
define({
|
||||||
id: "managed",
|
id: "managed",
|
||||||
effect: (ctx) =>
|
effect: (ctx) =>
|
||||||
ctx.agent
|
ctx.agent
|
||||||
@@ -97,40 +97,25 @@ describe("PluginV2", () => {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
it.effect("skips failed plugins and loads the rest", () =>
|
it.effect("retries the same generation after materialization fails", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugins = yield* PluginV2.Service
|
const plugins = yield* PluginV2.Service
|
||||||
const agents = yield* AgentV2.Service
|
|
||||||
let fail = true
|
let fail = true
|
||||||
const good = EffectPlugin.define({
|
const plugin = define({
|
||||||
id: "good",
|
id: "retry",
|
||||||
effect: (ctx) =>
|
effect: (ctx) =>
|
||||||
ctx.agent
|
ctx.agent
|
||||||
.transform((agents) =>
|
.transform(() => {
|
||||||
agents.update("configured", (agent) => {
|
if (fail) throw new Error("materialization failed")
|
||||||
agent.description = "loaded"
|
})
|
||||||
}),
|
|
||||||
)
|
|
||||||
.pipe(Effect.asVoid),
|
.pipe(Effect.asVoid),
|
||||||
})
|
})
|
||||||
const bad = EffectPlugin.define({
|
|
||||||
id: "bad",
|
|
||||||
effect: () => {
|
|
||||||
if (fail) return Effect.die(new Error("materialization failed"))
|
|
||||||
return Effect.void
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
yield* plugins.activate([{ plugin: good }, { plugin: bad }])
|
|
||||||
expect(yield* plugins.list()).toEqual([{ id: Plugin.ID.make("good") }])
|
|
||||||
expect((yield* agents.get(AgentV2.ID.make("configured")))?.description).toBe("loaded")
|
|
||||||
|
|
||||||
|
expect(Exit.isFailure(yield* plugins.activate([{ plugin }]).pipe(Effect.exit))).toBe(true)
|
||||||
fail = false
|
fail = false
|
||||||
yield* plugins.activate([{ plugin: good }, { plugin: bad }])
|
yield* plugins.activate([{ plugin }])
|
||||||
expect(yield* plugins.list()).toEqual([
|
|
||||||
{ id: Plugin.ID.make("good") },
|
expect(yield* plugins.list()).toEqual([{ id: Plugin.ID.make("retry") }])
|
||||||
{ id: Plugin.ID.make("bad") },
|
|
||||||
])
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -157,7 +142,7 @@ describe("PluginV2", () => {
|
|||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugins = yield* PluginV2.Service
|
const plugins = yield* PluginV2.Service
|
||||||
let visible = true
|
let visible = true
|
||||||
const plugin = EffectPlugin.define({
|
const plugin = define({
|
||||||
id: "isolated",
|
id: "isolated",
|
||||||
effect: () =>
|
effect: () =>
|
||||||
Effect.serviceOption(Secret).pipe(
|
Effect.serviceOption(Secret).pipe(
|
||||||
@@ -176,7 +161,7 @@ describe("PluginV2", () => {
|
|||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
const plugins = yield* PluginV2.Service
|
const plugins = yield* PluginV2.Service
|
||||||
const registry = yield* ToolRegistry.Service
|
const registry = yield* ToolRegistry.Service
|
||||||
const plugin = EffectPlugin.define({
|
const plugin = define({
|
||||||
id: "tool-plugin",
|
id: "tool-plugin",
|
||||||
effect: (ctx) =>
|
effect: (ctx) =>
|
||||||
ctx.tool
|
ctx.tool
|
||||||
@@ -217,7 +202,7 @@ describe("PluginV2", () => {
|
|||||||
output: Schema.Struct({ ok: Schema.Boolean }),
|
output: Schema.Struct({ ok: Schema.Boolean }),
|
||||||
execute: () => Effect.succeed({ ok: true }),
|
execute: () => Effect.succeed({ ok: true }),
|
||||||
})
|
})
|
||||||
const plugin = EffectPlugin.define({
|
const plugin = define({
|
||||||
id: "grouped-tools",
|
id: "grouped-tools",
|
||||||
effect: (ctx) =>
|
effect: (ctx) =>
|
||||||
ctx.tool
|
ctx.tool
|
||||||
@@ -249,7 +234,7 @@ describe("PluginV2", () => {
|
|||||||
after?: { input: unknown; result: unknown; output: unknown }
|
after?: { input: unknown; result: unknown; output: unknown }
|
||||||
} = {}
|
} = {}
|
||||||
|
|
||||||
const plugin = EffectPlugin.define({
|
const plugin = define({
|
||||||
id: "tool-hooks",
|
id: "tool-hooks",
|
||||||
effect: (ctx) =>
|
effect: (ctx) =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
@@ -267,23 +252,19 @@ describe("PluginV2", () => {
|
|||||||
)
|
)
|
||||||
.pipe(Effect.orDie)
|
.pipe(Effect.orDie)
|
||||||
|
|
||||||
yield* ctx.tool
|
yield* ctx.tool.execute
|
||||||
.hook("execute.before", (event) =>
|
.before((event) => {
|
||||||
Effect.sync(() => {
|
|
||||||
seen.before = event.input
|
seen.before = event.input
|
||||||
event.input = { text: "before-mutated" }
|
event.input = { text: "before-mutated" }
|
||||||
}),
|
})
|
||||||
)
|
|
||||||
.pipe(Effect.asVoid)
|
.pipe(Effect.asVoid)
|
||||||
|
|
||||||
yield* ctx.tool
|
yield* ctx.tool.execute
|
||||||
.hook("execute.after", (event) =>
|
.after((event) => {
|
||||||
Effect.sync(() => {
|
|
||||||
seen.after = { input: event.input, result: event.result, output: event.output }
|
seen.after = { input: event.input, result: event.result, output: event.output }
|
||||||
event.result = { type: "text", value: "after-mutated" }
|
event.result = { type: "text", value: "after-mutated" }
|
||||||
event.output = { structured: { rewritten: true }, content: [] }
|
event.output = { structured: { rewritten: true }, content: [] }
|
||||||
}),
|
})
|
||||||
)
|
|
||||||
.pipe(Effect.asVoid)
|
.pipe(Effect.asVoid)
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { Integration } from "@opencode-ai/core/integration"
|
|||||||
import { Location } from "@opencode-ai/core/location"
|
import { Location } from "@opencode-ai/core/location"
|
||||||
import { Npm } from "@opencode-ai/core/npm"
|
import { Npm } from "@opencode-ai/core/npm"
|
||||||
import { PluginV2 } from "@opencode-ai/core/plugin"
|
import { PluginV2 } from "@opencode-ai/core/plugin"
|
||||||
import { PluginHooks } from "@opencode-ai/core/plugin/hooks"
|
|
||||||
import { PluginRuntime } from "@opencode-ai/core/plugin/runtime"
|
import { PluginRuntime } from "@opencode-ai/core/plugin/runtime"
|
||||||
import { Reference } from "@opencode-ai/core/reference"
|
import { Reference } from "@opencode-ai/core/reference"
|
||||||
import { SkillV2 } from "@opencode-ai/core/skill"
|
import { SkillV2 } from "@opencode-ai/core/skill"
|
||||||
@@ -47,7 +46,6 @@ export const PluginTestLayer = AppNodeBuilder.build(
|
|||||||
CommandV2.node,
|
CommandV2.node,
|
||||||
Integration.node,
|
Integration.node,
|
||||||
PluginRuntime.node,
|
PluginRuntime.node,
|
||||||
PluginHooks.node,
|
|
||||||
Reference.node,
|
Reference.node,
|
||||||
SkillV2.node,
|
SkillV2.node,
|
||||||
ToolHooks.node,
|
ToolHooks.node,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Plugin } from "@opencode-ai/plugin/v2/effect"
|
import { define } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
|
|
||||||
export default Plugin.define({
|
export default define({
|
||||||
id: "config-effect-plugin",
|
id: "config-effect-plugin",
|
||||||
effect: (ctx) =>
|
effect: (ctx) =>
|
||||||
ctx.agent
|
ctx.agent
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Plugin } from "@opencode-ai/plugin/v2"
|
import { define } from "@opencode-ai/plugin/v2/promise"
|
||||||
|
|
||||||
export default Plugin.define({
|
export default define({
|
||||||
id: "config-promise-plugin",
|
id: "config-promise-plugin",
|
||||||
setup: async (ctx) => {
|
setup: async (ctx) => {
|
||||||
await ctx.agent.transform((agents) => {
|
await ctx.agent.transform((agents) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Plugin } from "@opencode-ai/plugin/v2/effect"
|
import { define } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
|
|
||||||
export default Plugin.define({
|
export default define({
|
||||||
id: "failing-plugin",
|
id: "failing-plugin",
|
||||||
effect: () => Effect.die("plugin failed"),
|
effect: () => Effect.die("plugin failed"),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Plugin } from "@opencode-ai/plugin/v2/effect"
|
import { define } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
|
|
||||||
export default Plugin.define({
|
export default define({
|
||||||
id: "variant-source",
|
id: "variant-source",
|
||||||
effect: (ctx) =>
|
effect: (ctx) =>
|
||||||
ctx.catalog
|
ctx.catalog
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Context as PluginContext } from "@opencode-ai/plugin/v2/effect/plugin"
|
import type { PluginContext } from "@opencode-ai/plugin/v2/effect"
|
||||||
import { AgentV2 } from "@opencode-ai/core/agent"
|
import { AgentV2 } from "@opencode-ai/core/agent"
|
||||||
import { Catalog } from "@opencode-ai/core/catalog"
|
import { Catalog } from "@opencode-ai/core/catalog"
|
||||||
import { Credential } from "@opencode-ai/core/credential"
|
import { Credential } from "@opencode-ai/core/credential"
|
||||||
@@ -19,7 +19,8 @@ export function host(overrides: Overrides = {}): PluginContext {
|
|||||||
reload: () => Effect.die("unused agent.reload"),
|
reload: () => Effect.die("unused agent.reload"),
|
||||||
},
|
},
|
||||||
aisdk: overrides.aisdk ?? {
|
aisdk: overrides.aisdk ?? {
|
||||||
hook: () => Effect.die("unused aisdk.hook"),
|
sdk: () => Effect.die("unused aisdk.sdk"),
|
||||||
|
language: () => Effect.die("unused aisdk.language"),
|
||||||
},
|
},
|
||||||
catalog: overrides.catalog ?? {
|
catalog: overrides.catalog ?? {
|
||||||
provider: {
|
provider: {
|
||||||
@@ -44,15 +45,11 @@ export function host(overrides: Overrides = {}): PluginContext {
|
|||||||
integration: overrides.integration ?? {
|
integration: overrides.integration ?? {
|
||||||
list: () => Effect.die("unused integration.list"),
|
list: () => Effect.die("unused integration.list"),
|
||||||
get: () => Effect.die("unused integration.get"),
|
get: () => Effect.die("unused integration.get"),
|
||||||
connect: {
|
connectKey: () => Effect.die("unused integration.connectKey"),
|
||||||
key: () => Effect.die("unused integration.connect.key"),
|
connectOauth: () => Effect.die("unused integration.connectOauth"),
|
||||||
oauth: () => Effect.die("unused integration.connect.oauth"),
|
attemptStatus: () => Effect.die("unused integration.attemptStatus"),
|
||||||
},
|
attemptComplete: () => Effect.die("unused integration.attemptComplete"),
|
||||||
attempt: {
|
attemptCancel: () => Effect.die("unused integration.attemptCancel"),
|
||||||
status: () => Effect.die("unused integration.attempt.status"),
|
|
||||||
complete: () => Effect.die("unused integration.attempt.complete"),
|
|
||||||
cancel: () => Effect.die("unused integration.attempt.cancel"),
|
|
||||||
},
|
|
||||||
transform: () => Effect.die("unused integration.transform"),
|
transform: () => Effect.die("unused integration.transform"),
|
||||||
reload: () => Effect.die("unused integration.reload"),
|
reload: () => Effect.die("unused integration.reload"),
|
||||||
connection: {
|
connection: {
|
||||||
@@ -75,7 +72,10 @@ export function host(overrides: Overrides = {}): PluginContext {
|
|||||||
},
|
},
|
||||||
tool: overrides.tool ?? {
|
tool: overrides.tool ?? {
|
||||||
transform: () => Effect.die("unused tool.transform"),
|
transform: () => Effect.die("unused tool.transform"),
|
||||||
hook: () => Effect.die("unused tool.hook"),
|
execute: {
|
||||||
|
before: () => Effect.die("unused tool.execute.before"),
|
||||||
|
after: () => Effect.die("unused tool.execute.after"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
session: overrides.session ?? {
|
session: overrides.session ?? {
|
||||||
create: () => Effect.die("unused session.create"),
|
create: () => Effect.die("unused session.create"),
|
||||||
@@ -83,7 +83,6 @@ export function host(overrides: Overrides = {}): PluginContext {
|
|||||||
prompt: () => Effect.die("unused session.prompt"),
|
prompt: () => Effect.die("unused session.prompt"),
|
||||||
command: () => Effect.die("unused session.command"),
|
command: () => Effect.die("unused session.command"),
|
||||||
interrupt: () => Effect.die("unused session.interrupt"),
|
interrupt: () => Effect.die("unused session.interrupt"),
|
||||||
hook: () => Effect.die("unused session.hook"),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,15 +188,11 @@ export function integrationHost(integration: Integration.Interface): PluginConte
|
|||||||
return {
|
return {
|
||||||
list: () => Effect.die("unused integration.list"),
|
list: () => Effect.die("unused integration.list"),
|
||||||
get: () => Effect.die("unused integration.get"),
|
get: () => Effect.die("unused integration.get"),
|
||||||
connect: {
|
connectKey: () => Effect.die("unused integration.connectKey"),
|
||||||
key: () => Effect.die("unused integration.connect.key"),
|
connectOauth: () => Effect.die("unused integration.connectOauth"),
|
||||||
oauth: () => Effect.die("unused integration.connect.oauth"),
|
attemptStatus: () => Effect.die("unused integration.attemptStatus"),
|
||||||
},
|
attemptComplete: () => Effect.die("unused integration.attemptComplete"),
|
||||||
attempt: {
|
attemptCancel: () => Effect.die("unused integration.attemptCancel"),
|
||||||
status: () => Effect.die("unused integration.attempt.status"),
|
|
||||||
complete: () => Effect.die("unused integration.attempt.complete"),
|
|
||||||
cancel: () => Effect.die("unused integration.attempt.cancel"),
|
|
||||||
},
|
|
||||||
reload: integration.reload,
|
reload: integration.reload,
|
||||||
connection: {
|
connection: {
|
||||||
active: (id) => integration.connection.active(Integration.ID.make(id)),
|
active: (id) => integration.connection.active(Integration.ID.make(id)),
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { AgentV2 } from "@opencode-ai/core/agent"
|
|||||||
import { PluginV2 } from "@opencode-ai/core/plugin"
|
import { PluginV2 } from "@opencode-ai/core/plugin"
|
||||||
import { PluginHost } from "@opencode-ai/core/plugin/host"
|
import { PluginHost } from "@opencode-ai/core/plugin/host"
|
||||||
import { PluginPromise } from "@opencode-ai/core/plugin/promise"
|
import { PluginPromise } from "@opencode-ai/core/plugin/promise"
|
||||||
import { Plugin } from "@opencode-ai/plugin/v2"
|
import { define } from "@opencode-ai/plugin/v2/promise"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
import { PluginTestLayer } from "./fixture"
|
import { PluginTestLayer } from "./fixture"
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ describe("fromPromise", () => {
|
|||||||
const plugin = yield* PluginV2.Service
|
const plugin = yield* PluginV2.Service
|
||||||
const host = yield* PluginHost.make(plugin)
|
const host = yield* PluginHost.make(plugin)
|
||||||
const seen: string[] = []
|
const seen: string[] = []
|
||||||
const promisePlugin = Plugin.define({
|
const promisePlugin = define({
|
||||||
id: "promise-client-reads",
|
id: "promise-client-reads",
|
||||||
setup: async (ctx) => {
|
setup: async (ctx) => {
|
||||||
const results = await Promise.all([
|
const results = await Promise.all([
|
||||||
@@ -46,7 +46,7 @@ describe("fromPromise", () => {
|
|||||||
const plugin = yield* PluginV2.Service
|
const plugin = yield* PluginV2.Service
|
||||||
const host = yield* PluginHost.make(plugin)
|
const host = yield* PluginHost.make(plugin)
|
||||||
|
|
||||||
const promisePlugin = Plugin.define({
|
const promisePlugin = define({
|
||||||
id: "promise-example",
|
id: "promise-example",
|
||||||
setup: async (ctx) => {
|
setup: async (ctx) => {
|
||||||
expect(ctx.options.mode).toBe("strict")
|
expect(ctx.options.mode).toBe("strict")
|
||||||
@@ -75,7 +75,7 @@ describe("fromPromise", () => {
|
|||||||
const plugin = yield* PluginV2.Service
|
const plugin = yield* PluginV2.Service
|
||||||
const host = yield* PluginHost.make(plugin)
|
const host = yield* PluginHost.make(plugin)
|
||||||
|
|
||||||
const promisePlugin = Plugin.define({
|
const promisePlugin = define({
|
||||||
id: "promise-dispose",
|
id: "promise-dispose",
|
||||||
setup: async (ctx) => {
|
setup: async (ctx) => {
|
||||||
const registration = await ctx.agent.transform((draft) => {
|
const registration = await ctx.agent.transform((draft) => {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user