Skip to content

Commit 2a629f8

Browse files
authored
Merge branch 'dev' into fix/lsp-error-message-improvement
2 parents b4902fd + 66d409d commit 2a629f8

142 files changed

Lines changed: 23061 additions & 1360 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/TEAM_MEMBERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ rekram1-node
1414
thdxr
1515
simonklee
1616
vimtor
17+
starptech

.opencode/tool/github-triage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { tool } from "@opencode-ai/plugin"
44
const TEAM = {
55
tui: ["kommander", "simonklee"],
66
desktop_web: ["Hona", "Brendonovich"],
7-
core: ["jlongster", "rekram1-node", "nexxeln", "kitlangton"],
8-
inference: ["fwang", "MrMushrooooom"],
7+
core: ["jlongster", "rekram1-node", "nexxeln", "kitlangton", "starptech"],
8+
inference: ["fwang", "MrMushrooooom", "starptech"],
99
windows: ["Hona"],
1010
} as const
1111

packages/app/src/context/global-sync.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,13 @@ function createGlobalSync() {
422422

423423
const updateConfigMutation = useMutation(() => ({
424424
mutationFn: (config: Config) => globalSDK.client.global.config.update({ config }),
425-
onSuccess: () => bootstrap.refetch(),
425+
onSuccess: () => {
426+
bootstrap.refetch()
427+
// Invalidate all provider queries so newly configured custom providers
428+
// appear immediately in the available provider list across all directories.
429+
queryClient.invalidateQueries({ queryKey: [null, "providers"] })
430+
queryClient.invalidateQueries({ predicate: (query) => query.queryKey[1] === "providers" })
431+
},
426432
}))
427433

428434
return {

packages/app/src/pages/session/message-timeline.tsx

Lines changed: 41 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,4 @@
1-
import {
2-
createEffect,
3-
createMemo,
4-
createSignal,
5-
For,
6-
Index,
7-
Match,
8-
Switch,
9-
on,
10-
onCleanup,
11-
Show,
12-
mapArray,
13-
untrack,
14-
type Accessor,
15-
type JSX,
16-
} from "solid-js"
1+
import { createEffect, createMemo, createSignal, For, Index, on, onCleanup, Show, mapArray, type JSX } from "solid-js"
172
import { createStore, produce } from "solid-js/store"
183
import { Dynamic } from "solid-js/web"
194
import { useNavigate } from "@solidjs/router"
@@ -995,26 +980,26 @@ export function MessageTimeline(props: {
995980

996981
const getMsgPart = (messageID: string, partID: string) => getMsgParts(messageID).find((part) => part.id === partID)
997982

998-
const renderAssistantPartGroup = (row: Accessor<TimelineRowMap["AssistantPart"]>) => {
999-
if (untrack(row).group.type === "context") {
983+
const renderAssistantPartGroup = (row: TimelineRowMap["AssistantPart"]) => {
984+
if (row.group.type === "context") {
1000985
const parts = createMemo(() => {
1001-
const group = row().group
986+
const group = row.group
1002987
if (group.type !== "context") return emptyTools
1003988
return group.refs
1004989
.map((ref) => getMsgPart(ref.messageID, ref.partID))
1005990
.filter((part): part is ToolPart => part?.type === "tool")
1006991
})
1007992

1008-
return <ContextToolGroup parts={parts()} busy={workingTurn(row().userMessageID) && row().lastAssistantPart} />
993+
return <ContextToolGroup parts={parts()} busy={workingTurn(row.userMessageID) && row.lastAssistantPart} />
1009994
}
1010995

1011996
const message = createMemo(() => {
1012-
const group = row().group
997+
const group = row.group
1013998
if (group.type !== "part") return
1014999
return messageByID().get(group.ref.messageID)
10151000
})
10161001
const part = createMemo(() => {
1017-
const group = row().group
1002+
const group = row.group
10181003
if (group.type !== "part") return
10191004
return getMsgPart(group.ref.messageID, group.ref.partID)
10201005
})
@@ -1027,8 +1012,8 @@ export function MessageTimeline(props: {
10271012
<MessagePart
10281013
part={part()}
10291014
message={message()}
1030-
showAssistantCopyPartID={assistantCopyPartID(row().userMessageID)}
1031-
turnDurationMs={turnDurationMs(row().userMessageID)}
1015+
showAssistantCopyPartID={assistantCopyPartID(row.userMessageID)}
1016+
turnDurationMs={turnDurationMs(row.userMessageID)}
10321017
defaultOpen={partDefaultOpen(
10331018
part(),
10341019
settings.general.shellToolPartsExpanded(),
@@ -1043,25 +1028,25 @@ export function MessageTimeline(props: {
10431028
)
10441029
}
10451030

1046-
function TimelineRowFrame(input: { row: Accessor<FramedTimelineRow>; children: JSX.Element }) {
1031+
function TimelineRowFrame(input: { row: FramedTimelineRow; children: JSX.Element }) {
10471032
const anchor = () => {
1048-
const row = input.row()
1033+
const row = input.row
10491034
return row._tag === "CommentStrip" || (row._tag === "UserMessage" && row.anchor)
10501035
}
10511036
const previousUserMessage = () => {
1052-
const row = input.row()
1037+
const row = input.row
10531038
return (row._tag === "CommentStrip" || row._tag === "UserMessage") && row.previousUserMessage
10541039
}
10551040
const previousAssistantPart = () => {
1056-
const row = input.row()
1041+
const row = input.row
10571042
return row._tag === "AssistantPart" && row.previousAssistantPart
10581043
}
10591044

10601045
return (
10611046
<div
1062-
id={anchor() ? props.anchor(input.row().userMessageID) : undefined}
1063-
data-message-id={input.row().userMessageID}
1064-
data-timeline-row={input.row()._tag}
1047+
id={anchor() ? props.anchor(input.row.userMessageID) : undefined}
1048+
data-message-id={input.row.userMessageID}
1049+
data-timeline-row={input.row._tag}
10651050
classList={{
10661051
"min-w-0 w-full max-w-full": true,
10671052
"md:max-w-200 2xl:max-w-[1000px]": props.centered,
@@ -1077,15 +1062,14 @@ export function MessageTimeline(props: {
10771062
)
10781063
}
10791064

1080-
const renderTimelineRow = (row: Accessor<TimelineRow.TimelineRow>) => {
1081-
switch (row()._tag) {
1065+
const renderTimelineRow = (row: TimelineRow.TimelineRow) => {
1066+
switch (row._tag) {
10821067
case "CommentStrip": {
1083-
const commentStripRow = row as Accessor<TimelineRowByTag<"CommentStrip">>
10841068
const comments = createMemo(() =>
1085-
getMsgParts(commentStripRow().userMessageID).flatMap((part) => MessageComment.fromPart(part) ?? []),
1069+
getMsgParts(row.userMessageID).flatMap((part) => MessageComment.fromPart(part) ?? []),
10861070
)
10871071
return (
1088-
<TimelineRowFrame row={commentStripRow}>
1072+
<TimelineRowFrame row={row}>
10891073
<div class="w-full px-4 md:px-5 pb-2">
10901074
<div class="ml-auto max-w-[82%] overflow-x-auto no-scrollbar">
10911075
<div class="flex w-max min-w-full justify-end gap-2">
@@ -1118,22 +1102,17 @@ export function MessageTimeline(props: {
11181102
)
11191103
}
11201104
case "UserMessage": {
1121-
const userMessageRow = row as Accessor<TimelineRowByTag<"UserMessage">>
11221105
const message = createMemo(() => {
1123-
const m = messageByID().get(userMessageRow().userMessageID)
1106+
const m = messageByID().get(row.userMessageID)
11241107
if (m?.role === "user") return m
11251108
})
11261109
return (
1127-
<TimelineRowFrame row={userMessageRow}>
1110+
<TimelineRowFrame row={row}>
11281111
<Show when={message()}>
11291112
{(message) => (
11301113
<div data-slot="session-turn-message-container" class="w-full px-4 md:px-5">
11311114
<div data-slot="session-turn-message-content" aria-live="off">
1132-
<Message
1133-
message={message()}
1134-
parts={getMsgParts(userMessageRow().userMessageID)}
1135-
actions={props.actions}
1136-
/>
1115+
<Message message={message()} parts={getMsgParts(row.userMessageID)} actions={props.actions} />
11371116
</div>
11381117
</div>
11391118
)}
@@ -1142,14 +1121,13 @@ export function MessageTimeline(props: {
11421121
)
11431122
}
11441123
case "TurnDivider": {
1145-
const turnDividerRow = row as Accessor<TimelineRowByTag<"TurnDivider">>
11461124
return (
1147-
<TimelineRowFrame row={turnDividerRow}>
1125+
<TimelineRowFrame row={row}>
11481126
<div data-slot="session-turn-message-container" class="w-full px-4 md:px-5">
11491127
<div data-slot="session-turn-compaction">
11501128
<MessageDivider
11511129
label={language.t(
1152-
turnDividerRow().label === "compaction" ? "ui.messagePart.compaction" : "ui.message.interrupted",
1130+
row.label === "compaction" ? "ui.messagePart.compaction" : "ui.message.interrupted",
11531131
)}
11541132
/>
11551133
</div>
@@ -1158,60 +1136,52 @@ export function MessageTimeline(props: {
11581136
)
11591137
}
11601138
case "AssistantPart": {
1161-
const assistantPartRow = row as Accessor<TimelineRowByTag<"AssistantPart">>
11621139
return (
1163-
<TimelineRowFrame row={assistantPartRow}>
1140+
<TimelineRowFrame row={row}>
11641141
<div data-slot="session-turn-message-container" class="w-full px-4 md:px-5">
1165-
<div
1166-
data-slot="session-turn-assistant-content"
1167-
aria-hidden={workingTurn(assistantPartRow().userMessageID)}
1168-
>
1169-
{renderAssistantPartGroup(assistantPartRow)}
1142+
<div data-slot="session-turn-assistant-content" aria-hidden={workingTurn(row.userMessageID)}>
1143+
{renderAssistantPartGroup(row)}
11701144
</div>
11711145
</div>
11721146
</TimelineRowFrame>
11731147
)
11741148
}
11751149
case "Thinking": {
1176-
const thinkingRow = row as Accessor<TimelineRowByTag<"Thinking">>
11771150
return (
1178-
<TimelineRowFrame row={thinkingRow}>
1151+
<TimelineRowFrame row={row}>
11791152
<div data-slot="session-turn-message-container" class="w-full px-4 md:px-5">
11801153
<TimelineThinkingRow
1181-
reasoningHeading={thinkingRow().reasoningHeading}
1154+
reasoningHeading={row.reasoningHeading}
11821155
showReasoningSummaries={settings.general.showReasoningSummaries()}
11831156
/>
11841157
</div>
11851158
</TimelineRowFrame>
11861159
)
11871160
}
11881161
case "Retry": {
1189-
const retryRow = row as Accessor<TimelineRowByTag<"Retry">>
11901162
return (
1191-
<TimelineRowFrame row={retryRow}>
1163+
<TimelineRowFrame row={row}>
11921164
<div data-slot="session-turn-message-container" class="w-full px-4 md:px-5">
1193-
<SessionRetry status={sessionStatus()} show={activeMessageID() === retryRow().userMessageID} />
1165+
<SessionRetry status={sessionStatus()} show={activeMessageID() === row.userMessageID} />
11941166
</div>
11951167
</TimelineRowFrame>
11961168
)
11971169
}
11981170
case "DiffSummary": {
1199-
const diffSummaryRow = row as Accessor<TimelineRowByTag<"DiffSummary">>
12001171
return (
1201-
<TimelineRowFrame row={diffSummaryRow}>
1172+
<TimelineRowFrame row={row}>
12021173
<div data-slot="session-turn-message-container" class="w-full px-4 md:px-5">
1203-
<TimelineDiffSummaryRow diffs={diffSummaryRow().diffs} />
1174+
<TimelineDiffSummaryRow diffs={row.diffs} />
12041175
</div>
12051176
</TimelineRowFrame>
12061177
)
12071178
}
12081179
case "Error": {
1209-
const errorRow = row as Accessor<TimelineRowByTag<"Error">>
12101180
return (
1211-
<TimelineRowFrame row={errorRow}>
1181+
<TimelineRowFrame row={row}>
12121182
<div data-slot="session-turn-message-container" class="w-full px-4 md:px-5">
12131183
<Card variant="error" class="error-card">
1214-
{errorRow().text}
1184+
{row.text}
12151185
</Card>
12161186
</div>
12171187
</TimelineRowFrame>
@@ -1223,7 +1193,11 @@ export function MessageTimeline(props: {
12231193
}
12241194

12251195
function TimelineRowView(props: { rowKey: string }) {
1226-
return <Show when={timelineRowByKey().get(props.rowKey)}>{(item) => renderTimelineRow(item)}</Show>
1196+
return (
1197+
<Show when={timelineRowByKey().get(props.rowKey)} keyed>
1198+
{(item) => renderTimelineRow(item)}
1199+
</Show>
1200+
)
12271201
}
12281202

12291203
return (

0 commit comments

Comments
 (0)