mirror of
https://github.com/sst/opencode.git
synced 2025-12-23 10:11:41 +00:00
chore: cleanup
This commit is contained in:
parent
78484f545c
commit
bf420e7df6
3 changed files with 25 additions and 50 deletions
|
|
@ -8,6 +8,7 @@ import {
|
|||
ToolPart,
|
||||
UserMessage,
|
||||
} from "@opencode-ai/sdk/v2"
|
||||
import { useData } from "../context"
|
||||
import { useDiffComponent } from "../context/diff"
|
||||
import { BasicTool } from "./basic-tool"
|
||||
import { GenericTool } from "./basic-tool"
|
||||
|
|
@ -16,26 +17,34 @@ import { Icon } from "./icon"
|
|||
import { Checkbox } from "./checkbox"
|
||||
import { DiffChanges } from "./diff-changes"
|
||||
import { Markdown } from "./markdown"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/util/path"
|
||||
import { sanitizePart } from "@opencode-ai/util/sanitize"
|
||||
import { getDirectory as _getDirectory, getFilename } from "@opencode-ai/util/path"
|
||||
|
||||
export interface MessageProps {
|
||||
message: MessageType
|
||||
parts: PartType[]
|
||||
sanitize?: RegExp
|
||||
}
|
||||
|
||||
export interface MessagePartProps {
|
||||
part: PartType
|
||||
message: MessageType
|
||||
hideDetails?: boolean
|
||||
sanitize?: RegExp
|
||||
}
|
||||
|
||||
export type PartComponent = Component<MessagePartProps>
|
||||
|
||||
export const PART_MAPPING: Record<string, PartComponent | undefined> = {}
|
||||
|
||||
function relativizeProjectPaths(text: string, directory?: string) {
|
||||
if (!text) return ""
|
||||
if (!directory) return text
|
||||
return text.split(directory).join("")
|
||||
}
|
||||
|
||||
function getDirectory(path: string | undefined) {
|
||||
const data = useData()
|
||||
return relativizeProjectPaths(_getDirectory(path), data.directory)
|
||||
}
|
||||
|
||||
export function registerPartComponent(type: string, component: PartComponent) {
|
||||
PART_MAPPING[type] = component
|
||||
}
|
||||
|
|
@ -48,26 +57,20 @@ export function Message(props: MessageProps) {
|
|||
</Match>
|
||||
<Match when={props.message.role === "assistant" && props.message}>
|
||||
{(assistantMessage) => (
|
||||
<AssistantMessageDisplay
|
||||
message={assistantMessage() as AssistantMessage}
|
||||
parts={props.parts}
|
||||
sanitize={props.sanitize}
|
||||
/>
|
||||
<AssistantMessageDisplay message={assistantMessage() as AssistantMessage} parts={props.parts} />
|
||||
)}
|
||||
</Match>
|
||||
</Switch>
|
||||
)
|
||||
}
|
||||
|
||||
export function AssistantMessageDisplay(props: { message: AssistantMessage; parts: PartType[]; sanitize?: RegExp }) {
|
||||
export function AssistantMessageDisplay(props: { message: AssistantMessage; parts: PartType[] }) {
|
||||
const filteredParts = createMemo(() => {
|
||||
return props.parts?.filter((x) => {
|
||||
return x.type !== "tool" || (x as ToolPart).tool !== "todoread"
|
||||
})
|
||||
})
|
||||
return (
|
||||
<For each={filteredParts()}>{(part) => <Part part={part} message={props.message} sanitize={props.sanitize} />}</For>
|
||||
)
|
||||
return <For each={filteredParts()}>{(part) => <Part part={part} message={props.message} />}</For>
|
||||
}
|
||||
|
||||
export function UserMessageDisplay(props: { message: UserMessage; parts: PartType[] }) {
|
||||
|
|
@ -82,10 +85,9 @@ export function UserMessageDisplay(props: { message: UserMessage; parts: PartTyp
|
|||
|
||||
export function Part(props: MessagePartProps) {
|
||||
const component = createMemo(() => PART_MAPPING[props.part.type])
|
||||
const part = createMemo(() => sanitizePart(props.part, props.sanitize))
|
||||
return (
|
||||
<Show when={component()}>
|
||||
<Dynamic component={component()} part={part()} message={props.message} hideDetails={props.hideDetails} />
|
||||
<Dynamic component={component()} part={props.part} message={props.message} hideDetails={props.hideDetails} />
|
||||
</Show>
|
||||
)
|
||||
}
|
||||
|
|
@ -173,12 +175,15 @@ PART_MAPPING["tool"] = function ToolPartDisplay(props) {
|
|||
}
|
||||
|
||||
PART_MAPPING["text"] = function TextPartDisplay(props) {
|
||||
const data = useData()
|
||||
const part = props.part as TextPart
|
||||
const sanitized = createMemo(() => (props.sanitize ? (sanitizePart(part, props.sanitize) as TextPart) : part))
|
||||
const content = createMemo(() => (part.text ?? "").trim())
|
||||
const displayText = createMemo(() => relativizeProjectPaths(content(), data.directory))
|
||||
|
||||
return (
|
||||
<Show when={part.text.trim()}>
|
||||
<Show when={displayText()}>
|
||||
<div data-component="text-part">
|
||||
<Markdown text={sanitized().text.trim()} />
|
||||
<Markdown text={displayText()} />
|
||||
</div>
|
||||
</Show>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ export function SessionTurn(
|
|||
) {
|
||||
const data = useData()
|
||||
const diffComponent = useDiffComponent()
|
||||
const sanitizer = createMemo(() => (data.directory ? new RegExp(`${data.directory}/`, "g") : undefined))
|
||||
const messages = createMemo(() => (props.sessionID ? (data.store.message[props.sessionID] ?? []) : []))
|
||||
const userMessages = createMemo(() =>
|
||||
messages()
|
||||
|
|
@ -208,7 +207,7 @@ export function SessionTurn(
|
|||
</div>
|
||||
</div>
|
||||
<div data-slot="session-turn-message-content">
|
||||
<Message message={message()} parts={parts()} sanitize={sanitizer()} />
|
||||
<Message message={message()} parts={parts()} />
|
||||
</div>
|
||||
{/* Response */}
|
||||
<div data-slot="session-turn-response-section">
|
||||
|
|
@ -252,11 +251,10 @@ export function SessionTurn(
|
|||
<Message
|
||||
message={assistantMessage}
|
||||
parts={parts().filter((p) => p?.id !== last()?.id)}
|
||||
sanitize={sanitizer()}
|
||||
/>
|
||||
</Match>
|
||||
<Match when={true}>
|
||||
<Message message={assistantMessage} parts={parts()} sanitize={sanitizer()} />
|
||||
<Message message={assistantMessage} parts={parts()} />
|
||||
</Match>
|
||||
</Switch>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
import type { Part } from "@opencode-ai/sdk/v2/client"
|
||||
|
||||
export const sanitize = (text: string | undefined, remove?: RegExp) => (remove ? text?.replace(remove, "") : text) ?? ""
|
||||
|
||||
export const sanitizePart = (part: Part, remove: RegExp | undefined) => {
|
||||
if (part.type === "text") {
|
||||
part.text = sanitize(part.text, remove)
|
||||
} else if (part.type === "reasoning") {
|
||||
part.text = sanitize(part.text, remove)
|
||||
} else if (part.type === "tool") {
|
||||
if (part.state.status === "completed" || part.state.status === "error") {
|
||||
for (const key in part.state.metadata) {
|
||||
if (typeof part.state.metadata[key] === "string") {
|
||||
part.state.metadata[key] = sanitize(part.state.metadata[key] as string, remove)
|
||||
}
|
||||
}
|
||||
for (const key in part.state.input) {
|
||||
if (typeof part.state.input[key] === "string") {
|
||||
part.state.input[key] = sanitize(part.state.input[key] as string, remove)
|
||||
}
|
||||
}
|
||||
if ("error" in part.state) {
|
||||
part.state.error = sanitize(part.state.error as string, remove)
|
||||
}
|
||||
}
|
||||
}
|
||||
return part
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue