mirror of
https://github.com/sst/opencode.git
synced 2025-12-23 10:11:41 +00:00
wip(share): more styling
This commit is contained in:
parent
46a76a778a
commit
3fb57044d1
4 changed files with 59 additions and 15 deletions
|
|
@ -1,9 +1,11 @@
|
|||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"plugin": ["opencode-openai-codex-auth"],
|
||||
// "enterprise": {
|
||||
// "url": "http://localhost:3000",
|
||||
// },
|
||||
"plugin": [
|
||||
"opencode-openai-codex-auth"
|
||||
],
|
||||
"enterprise": {
|
||||
"url": "http://localhost:3000",
|
||||
},
|
||||
"provider": {
|
||||
"opencode": {
|
||||
"options": {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { FileDiff, Message, Part, Session, SessionStatus } from "@opencode-ai/sdk"
|
||||
import { FileDiff, Message, Model, Part, Session, SessionStatus } from "@opencode-ai/sdk"
|
||||
import { fn } from "@opencode-ai/util/fn"
|
||||
import { iife } from "@opencode-ai/util/iife"
|
||||
import z from "zod"
|
||||
|
|
@ -32,6 +32,10 @@ export namespace Share {
|
|||
type: z.literal("session_status"),
|
||||
data: z.custom<SessionStatus>(),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("model"),
|
||||
data: z.custom<Model[]>(),
|
||||
}),
|
||||
])
|
||||
export type Data = z.infer<typeof Data>
|
||||
|
||||
|
|
@ -111,6 +115,9 @@ export namespace Share {
|
|||
case "session_status":
|
||||
await Storage.write(["share_data", input.share.id, "session_status"], item.data)
|
||||
break
|
||||
case "model":
|
||||
await Storage.write(["share_data", input.share.id, "model"], item.data)
|
||||
break
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { FileDiff, Message, Part, Session, SessionStatus, UserMessage } from "@opencode-ai/sdk"
|
||||
import { FileDiff, Message, Model, Part, Session, SessionStatus, UserMessage } from "@opencode-ai/sdk"
|
||||
import { SessionTurn } from "@opencode-ai/ui/session-turn"
|
||||
import { SessionReview } from "@opencode-ai/ui/session-review"
|
||||
import { DataProvider, useData } from "@opencode-ai/ui/context"
|
||||
import { DataProvider } from "@opencode-ai/ui/context"
|
||||
import { createAsync, query, RouteDefinition, useParams } from "@solidjs/router"
|
||||
import { createMemo, Show } from "solid-js"
|
||||
import { Share } from "~/core/share"
|
||||
|
|
@ -29,6 +29,9 @@ const getData = query(async (sessionID) => {
|
|||
part: {
|
||||
[messageID: string]: Part[]
|
||||
}
|
||||
model: {
|
||||
[sessionID: string]: Model[]
|
||||
}
|
||||
} = {
|
||||
session: [],
|
||||
session_diff: {
|
||||
|
|
@ -41,6 +44,7 @@ const getData = query(async (sessionID) => {
|
|||
},
|
||||
message: {},
|
||||
part: {},
|
||||
model: {},
|
||||
}
|
||||
for (const item of data) {
|
||||
switch (item.type) {
|
||||
|
|
@ -61,6 +65,9 @@ const getData = query(async (sessionID) => {
|
|||
result.part[item.data.messageID] = result.part[item.data.messageID] ?? []
|
||||
result.part[item.data.messageID].push(item.data)
|
||||
break
|
||||
case "model":
|
||||
result.model[sessionID] = item.data
|
||||
break
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
|
@ -82,15 +89,14 @@ export default function () {
|
|||
{(data) => (
|
||||
<DataProvider data={data()}>
|
||||
{iife(() => {
|
||||
const data = useData()
|
||||
const [store, setStore] = createStore({
|
||||
messageId: undefined as string | undefined,
|
||||
})
|
||||
const match = createMemo(() => Binary.search(data.session, params.sessionID!, (s) => s.id))
|
||||
const match = createMemo(() => Binary.search(data().session, params.sessionID!, (s) => s.id))
|
||||
if (!match().found) throw new Error(`Session ${params.sessionID} not found`)
|
||||
const info = createMemo(() => data.session[match().index])
|
||||
const info = createMemo(() => data().session[match().index])
|
||||
const messages = createMemo(() =>
|
||||
params.sessionID ? (data.message[params.sessionID]?.filter((m) => m.role === "user") ?? []) : [],
|
||||
params.sessionID ? (data().message[params.sessionID]?.filter((m) => m.role === "user") ?? []) : [],
|
||||
)
|
||||
const firstUserMessage = createMemo(() => messages().at(0))
|
||||
const activeMessage = createMemo(
|
||||
|
|
@ -104,8 +110,9 @@ export default function () {
|
|||
}
|
||||
}
|
||||
const provider = createMemo(() => activeMessage()?.model?.providerID)
|
||||
const model = createMemo(() => activeMessage()?.model?.modelID)
|
||||
const diffs = createMemo(() => data.session_diff[params.sessionID!] ?? [])
|
||||
const modelID = createMemo(() => activeMessage()?.model?.modelID)
|
||||
const model = createMemo(() => data().model[params.sessionID!]?.find((m) => m.id === modelID()))
|
||||
const diffs = createMemo(() => data().session_diff[params.sessionID!] ?? [])
|
||||
|
||||
return (
|
||||
<div class="relative bg-background-stronger w-screen h-screen overflow-hidden flex flex-col">
|
||||
|
|
@ -152,7 +159,7 @@ export default function () {
|
|||
src={`https://models.dev/logos/${provider()}.svg`}
|
||||
class="size-4 shrink-0 dark:invert"
|
||||
/>
|
||||
<div class="text-12-regular text-text-base">{model()}</div>
|
||||
<div class="text-12-regular text-text-base">{model()?.name ?? modelID()}</div>
|
||||
</div>
|
||||
<div class="text-12-regular text-text-weaker">
|
||||
{DateTime.fromMillis(info().time.created).toFormat("dd MMM yyyy, HH:mm")}
|
||||
|
|
@ -163,7 +170,7 @@ export default function () {
|
|||
<div class="flex items-start justify-start h-full min-h-0">
|
||||
<Show when={messages().length > 1}>
|
||||
<MessageNav
|
||||
classList={{ "mt-3 mr-3": true }}
|
||||
classList={{ "mt-2 mr-3": true }}
|
||||
messages={messages()}
|
||||
current={activeMessage()}
|
||||
onMessageSelect={setActiveMessage}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { Bus } from "@/bus"
|
||||
import { Config } from "@/config/config"
|
||||
import type { ModelsDev } from "@/provider/models"
|
||||
import { Provider } from "@/provider/provider"
|
||||
import { Session } from "@/session"
|
||||
import { MessageV2 } from "@/session/message-v2"
|
||||
import { Storage } from "@/storage/storage"
|
||||
|
|
@ -26,6 +28,18 @@ export namespace ShareNext {
|
|||
data: evt.properties.info,
|
||||
},
|
||||
])
|
||||
if (evt.properties.info.role === "user") {
|
||||
await sync(evt.properties.info.sessionID, [
|
||||
{
|
||||
type: "model",
|
||||
data: [
|
||||
await Provider.getModel(evt.properties.info.model.providerID, evt.properties.info.model.modelID).then(
|
||||
(m) => m.info,
|
||||
),
|
||||
],
|
||||
},
|
||||
])
|
||||
}
|
||||
})
|
||||
Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => {
|
||||
await sync(evt.properties.part.sessionID, [
|
||||
|
|
@ -90,6 +104,10 @@ export namespace ShareNext {
|
|||
type: "session_diff"
|
||||
data: SDK.FileDiff[]
|
||||
}
|
||||
| {
|
||||
type: "model"
|
||||
data: ModelsDev.Model[]
|
||||
}
|
||||
|
||||
async function sync(sessionID: string, data: Data[]) {
|
||||
const url = await Config.get().then((x) => x.enterprise!.url)
|
||||
|
|
@ -129,6 +147,12 @@ export namespace ShareNext {
|
|||
const session = await Session.get(sessionID)
|
||||
const diffs = await Session.diff(sessionID)
|
||||
const messages = await Array.fromAsync(MessageV2.stream(sessionID))
|
||||
const models = await Promise.all(
|
||||
messages
|
||||
.filter((m) => m.info.role === "user")
|
||||
.map((m) => (m.info as SDK.UserMessage).model)
|
||||
.map((m) => Provider.getModel(m.providerID, m.modelID).then((m) => m.info)),
|
||||
)
|
||||
await sync(sessionID, [
|
||||
{
|
||||
type: "session",
|
||||
|
|
@ -143,6 +167,10 @@ export namespace ShareNext {
|
|||
type: "session_diff",
|
||||
data: diffs,
|
||||
},
|
||||
{
|
||||
type: "model",
|
||||
data: models,
|
||||
},
|
||||
])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue