refactor(app): route backend through adapters
This commit is contained in:
parent
4c0feeebb4
commit
08ea08e830
130 changed files with 5302 additions and 1953 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import type { FileContent } from "@opencode-ai/sdk/v2"
|
||||
import type { FileContent } from "../context/data-types"
|
||||
import { createEffect, createMemo, Match, on, onCleanup, Show, Switch, untrack, type JSX } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { useI18n } from "@opencode-ai/ui/context/i18n"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { describe, expect, test } from "bun:test"
|
||||
import type { FilePart } from "@opencode-ai/sdk/v2"
|
||||
import type { FilePart } from "../context/data-types"
|
||||
import { attached, inline, kind } from "./message-file"
|
||||
|
||||
function file(part: Partial<FilePart> = {}): FilePart {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { FilePart } from "@opencode-ai/sdk/v2"
|
||||
import type { FilePart } from "../context/data-types"
|
||||
|
||||
export function attached(part: FilePart) {
|
||||
return part.url.startsWith("data:")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { UserMessage } from "@opencode-ai/sdk/v2"
|
||||
import type { UserMessage } from "../context/data-types"
|
||||
import { HoverCard } from "@kobalte/core/hover-card"
|
||||
import { ComponentProps, For, Match, Show, createSignal, splitProps, Switch } from "solid-js"
|
||||
import { DiffChanges } from "@opencode-ai/ui/diff-changes"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import {
|
|||
UserMessage,
|
||||
QuestionAnswer,
|
||||
QuestionInfo,
|
||||
} from "@opencode-ai/sdk/v2"
|
||||
} from "../context/data-types"
|
||||
import { useData } from "../context"
|
||||
import { useFileComponent } from "@opencode-ai/ui/context/file"
|
||||
import { useDialog } from "@opencode-ai/ui/context/dialog"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { parseDiffFromFile, parsePatchFiles, type FileDiffMetadata } from "@pierre/diffs"
|
||||
import { parsePatch } from "diff"
|
||||
import type { FileDiffInfo, VcsFileDiff } from "@opencode-ai/sdk/v2"
|
||||
import type { SnapshotFileDiff as FileDiffInfo, VcsFileDiff } from "../context/data-types"
|
||||
|
||||
type LegacyDiff = {
|
||||
file: string
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { createEffect, createMemo, createSignal, on, onCleanup, Show } from "solid-js"
|
||||
import type { SessionStatus } from "@opencode-ai/sdk/v2/client"
|
||||
import type { SessionStatus } from "../context/data-types"
|
||||
import { useI18n } from "@opencode-ai/ui/context/i18n"
|
||||
import { Card } from "@opencode-ai/ui/card"
|
||||
import { Tooltip } from "@opencode-ai/ui/tooltip"
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { getDirectory, getFilename } from "@opencode-ai/core/util/path"
|
|||
import { checksum } from "@opencode-ai/core/util/encode"
|
||||
import { createEffect, createMemo, For, Match, onCleanup, Show, Switch, untrack, type JSX } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { type FileContent, type FileDiffInfo, type VcsFileDiff } from "@opencode-ai/sdk/v2"
|
||||
import type { FileContent, SnapshotFileDiff as FileDiffInfo, VcsFileDiff } from "../context/data-types"
|
||||
import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
|
||||
import { type SelectedLineRange } from "@pierre/diffs"
|
||||
import { Dynamic } from "solid-js/web"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import {
|
||||
import type {
|
||||
AssistantMessage,
|
||||
type FileDiffInfo,
|
||||
Message as MessageType,
|
||||
Part as PartType,
|
||||
type UserMessage,
|
||||
} from "@opencode-ai/sdk/v2/client"
|
||||
import type { SessionStatus } from "@opencode-ai/sdk/v2"
|
||||
SessionStatus,
|
||||
SnapshotFileDiff as FileDiffInfo,
|
||||
UserMessage,
|
||||
} from "../context/data-types"
|
||||
import { useData } from "../context"
|
||||
import { useFileComponent } from "@opencode-ai/ui/context/file"
|
||||
|
||||
|
|
@ -436,7 +436,7 @@ export function SessionTurn(
|
|||
</Show>
|
||||
</div>
|
||||
</Show>
|
||||
<SessionRetry status={status()} show={active()} />
|
||||
<SessionRetry status={((value) => (value.type === "running" ? { type: "busy" as const } : value))(status())} show={active()} />
|
||||
<Show when={edited() > 0 && !working()}>
|
||||
<div
|
||||
data-slot="session-turn-diffs"
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import type {
|
|||
ToolPart,
|
||||
FilePart,
|
||||
AgentPart,
|
||||
} from "@opencode-ai/sdk/v2"
|
||||
} from "../context/data-types"
|
||||
import { DataProvider } from "../context/data"
|
||||
import { FileComponentProvider } from "@opencode-ai/ui/context/file"
|
||||
import { SessionTurn } from "./session-turn"
|
||||
|
|
|
|||
212
packages/session-ui/src/context/data-types.ts
Normal file
212
packages/session-ui/src/context/data-types.ts
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
export type Session = {
|
||||
id: string
|
||||
slug: string
|
||||
projectID: string
|
||||
directory: string
|
||||
title: string
|
||||
version: string
|
||||
parentID?: string
|
||||
time: { created: number; updated: number; archived?: number }
|
||||
revert?: { messageID: string }
|
||||
}
|
||||
|
||||
export type SessionStatus =
|
||||
| { type: "idle" }
|
||||
| { type: "busy" }
|
||||
| { type: "running" }
|
||||
| {
|
||||
type: "retry"
|
||||
attempt: number
|
||||
message: string
|
||||
next: number
|
||||
action?: { reason: string; provider: string; title: string; message: string; label: string; link?: string }
|
||||
}
|
||||
|
||||
export type Todo = {
|
||||
content: string
|
||||
status: string
|
||||
priority: string
|
||||
}
|
||||
|
||||
export type QuestionInfo = {
|
||||
question: string
|
||||
header: string
|
||||
options: Array<{ label: string; description: string }>
|
||||
multiple?: boolean
|
||||
custom?: boolean
|
||||
}
|
||||
|
||||
export type QuestionAnswer = string[]
|
||||
|
||||
export type SnapshotFileDiff = {
|
||||
file: string
|
||||
patch?: string
|
||||
additions: number
|
||||
deletions: number
|
||||
status?: "added" | "deleted" | "modified"
|
||||
}
|
||||
|
||||
export type VcsFileDiff = SnapshotFileDiff & { file: string }
|
||||
type SummaryFileDiff = Omit<SnapshotFileDiff, "file"> & { file?: string }
|
||||
|
||||
export type FileContent = {
|
||||
readonly type: "text" | "binary"
|
||||
readonly content: string
|
||||
readonly diff?: string
|
||||
readonly patch?: {
|
||||
readonly oldFileName: string
|
||||
readonly newFileName: string
|
||||
readonly oldHeader?: string
|
||||
readonly newHeader?: string
|
||||
readonly hunks: readonly {
|
||||
readonly oldStart: number
|
||||
readonly oldLines: number
|
||||
readonly newStart: number
|
||||
readonly newLines: number
|
||||
readonly lines: readonly string[]
|
||||
}[]
|
||||
readonly index?: string
|
||||
}
|
||||
readonly encoding?: "base64"
|
||||
readonly mimeType?: string
|
||||
}
|
||||
|
||||
export type MessageError =
|
||||
| { name: "ProviderAuthError"; data: { providerID: string; message: string } }
|
||||
| { name: "UnknownError"; data: { message: string; ref?: string } }
|
||||
| { name: "MessageOutputLengthError"; data: Record<string, unknown> }
|
||||
| { name: "MessageAbortedError"; data: { message: string } }
|
||||
| { name: "StructuredOutputError"; data: { message: string; retries: number } }
|
||||
| { name: "ContextOverflowError"; data: { message: string; responseBody?: string } }
|
||||
| { name: "ContentFilterError"; data: { message: string } }
|
||||
| {
|
||||
name: "APIError"
|
||||
data: {
|
||||
message: string
|
||||
statusCode?: number
|
||||
isRetryable: boolean
|
||||
responseHeaders?: Record<string, string>
|
||||
responseBody?: string
|
||||
metadata?: Record<string, string>
|
||||
}
|
||||
}
|
||||
|
||||
export type Message =
|
||||
| {
|
||||
id: string
|
||||
sessionID: string
|
||||
role: "user"
|
||||
time: { created: number }
|
||||
agent: string
|
||||
model: { providerID: string; modelID: string; variant?: string }
|
||||
system?: string
|
||||
summary?: { title?: string; body?: string; diffs: SummaryFileDiff[] }
|
||||
}
|
||||
| {
|
||||
id: string
|
||||
sessionID: string
|
||||
role: "assistant"
|
||||
time: { created: number; completed?: number }
|
||||
parentID: string
|
||||
modelID: string
|
||||
providerID: string
|
||||
mode: string
|
||||
agent: string
|
||||
path: { cwd: string; root: string }
|
||||
cost: number
|
||||
tokens: { input: number; output: number; reasoning: number; cache: { read: number; write: number } }
|
||||
error?: MessageError
|
||||
finish?: string
|
||||
}
|
||||
|
||||
export type UserMessage = Extract<Message, { role: "user" }>
|
||||
export type AssistantMessage = Extract<Message, { role: "assistant" }>
|
||||
|
||||
type PartBase = { id: string; sessionID: string; messageID: string }
|
||||
export type FilePart = PartBase & {
|
||||
type: "file"
|
||||
mime: string
|
||||
filename?: string
|
||||
url: string
|
||||
source?:
|
||||
| { type: "file"; path: string; text: { value: string; start: number; end: number } }
|
||||
| {
|
||||
type: "symbol"
|
||||
path: string
|
||||
range: {
|
||||
start: { line: number; character: number }
|
||||
end: { line: number; character: number }
|
||||
}
|
||||
name: string
|
||||
kind: number
|
||||
text: { value: string; start: number; end: number }
|
||||
}
|
||||
| { type: "resource"; clientName: string; uri: string; text: { value: string; start: number; end: number } }
|
||||
}
|
||||
type ToolState =
|
||||
| { status: "pending"; input: Record<string, unknown>; raw: string }
|
||||
| {
|
||||
status: "running"
|
||||
input: Record<string, unknown>
|
||||
title?: string
|
||||
metadata?: Record<string, unknown>
|
||||
time: { start: number }
|
||||
}
|
||||
| {
|
||||
status: "completed"
|
||||
input: Record<string, unknown>
|
||||
output: string
|
||||
title: string
|
||||
metadata: Record<string, unknown>
|
||||
time: { start: number; end: number; compacted?: number }
|
||||
attachments?: FilePart[]
|
||||
}
|
||||
| {
|
||||
status: "error"
|
||||
input: Record<string, unknown>
|
||||
error: string
|
||||
metadata?: Record<string, unknown>
|
||||
time: { start: number; end: number }
|
||||
}
|
||||
|
||||
export type Part =
|
||||
| (PartBase & {
|
||||
type: "text"
|
||||
text: string
|
||||
synthetic?: boolean
|
||||
ignored?: boolean
|
||||
time?: { start: number; end?: number }
|
||||
metadata?: Record<string, unknown>
|
||||
})
|
||||
| (PartBase & {
|
||||
type: "reasoning"
|
||||
text: string
|
||||
metadata?: Record<string, unknown>
|
||||
time: { start: number; end?: number }
|
||||
})
|
||||
| FilePart
|
||||
| (PartBase & { type: "agent"; name: string; source?: { value: string; start: number; end: number } })
|
||||
| (PartBase & { type: "tool"; callID: string; tool: string; state: ToolState; metadata?: Record<string, unknown> })
|
||||
| (PartBase & { type: "subtask"; prompt: string; description: string; agent: string })
|
||||
| (PartBase & { type: "step-start"; snapshot?: string })
|
||||
| (PartBase & {
|
||||
type: "step-finish"
|
||||
reason: string
|
||||
snapshot?: string
|
||||
cost: number
|
||||
tokens: { input: number; output: number; reasoning: number; cache: { read: number; write: number } }
|
||||
})
|
||||
| (PartBase & { type: "snapshot"; snapshot: string })
|
||||
| (PartBase & { type: "patch"; hash: string; files: string[] })
|
||||
| (PartBase & {
|
||||
type: "retry"
|
||||
attempt: number
|
||||
error: Extract<MessageError, { name: "APIError" }>
|
||||
time: { created: number }
|
||||
})
|
||||
| (PartBase & { type: "compaction"; auto: boolean })
|
||||
|
||||
export type TextPart = Extract<Part, { type: "text" }>
|
||||
export type ReasoningPart = Extract<Part, { type: "reasoning" }>
|
||||
export type ToolPart = Extract<Part, { type: "tool" }>
|
||||
export type AgentPart = Extract<Part, { type: "agent" }>
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
import type { FileDiffInfo, Message, Part, Provider, Session, SessionStatus } from "@opencode-ai/sdk/v2"
|
||||
import type { Message, Part, Session, SessionStatus, SnapshotFileDiff as FileDiffInfo } from "./data-types"
|
||||
import { createSimpleContext } from "@opencode-ai/ui/context"
|
||||
import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
|
||||
|
||||
export type NormalizedProviderListResponse = {
|
||||
all: Map<string, Provider>
|
||||
all: ReadonlyMap<string, { name: string; models: Readonly<Record<string, { name: string }>> }>
|
||||
default: {
|
||||
[key: string]: string
|
||||
}
|
||||
connected: Array<string>
|
||||
connected: readonly string[]
|
||||
}
|
||||
|
||||
type Data = {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { FileContent } from "@opencode-ai/sdk/v2"
|
||||
import type { FileContent } from "../context/data-types"
|
||||
|
||||
export type MediaKind = "image" | "audio" | "svg"
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { useFileComponent } from "@opencode-ai/ui/context/file"
|
|||
import { useI18n } from "@opencode-ai/ui/context/i18n"
|
||||
import { mediaKindFromPath } from "../../pierre/media"
|
||||
import { cloneSelectedLineRange, previewSelectedLines } from "../../pierre/selection-bridge"
|
||||
import type { FileContent, FileDiffInfo, VcsFileDiff } from "@opencode-ai/sdk/v2"
|
||||
import type { FileContent, SnapshotFileDiff as FileDiffInfo, VcsFileDiff } from "../../context/data-types"
|
||||
import { createEffect, createMemo, onCleanup, Show, untrack } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { Dynamic } from "solid-js/web"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue