Skip to content

Commit b8d2aeb

Browse files
committed
feat: thinking blocks rendered in tui and share page
1 parent 20e818a commit b8d2aeb

17 files changed

Lines changed: 324 additions & 55 deletions

File tree

‎packages/opencode/src/provider/transform.ts‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,22 @@ export namespace ProviderTransform {
8787
return {
8888
reasoningEffort: "minimal",
8989
textVerbosity: "low",
90+
// reasoningSummary: "auto",
91+
// include: ["reasoning.encrypted_content"],
9092
}
9193
}
94+
// if (modelID.includes("claude")) {
95+
// return {
96+
// thinking: {
97+
// type: "enabled",
98+
// budgetTokens: 32000,
99+
// },
100+
// }
101+
// }
102+
// if (_providerID === "bedrock") {
103+
// return {
104+
// reasoningConfig: { type: "enabled", budgetTokens: 32000 },
105+
// }
106+
// }
92107
}
93108
}

‎packages/opencode/src/session/index.ts‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,7 @@ export namespace Session {
10061006
async process(stream: StreamTextResult<Record<string, AITool>, never>) {
10071007
try {
10081008
let currentText: MessageV2.TextPart | undefined
1009+
let reasoningMap: Record<string, MessageV2.ReasoningPart> = {}
10091010

10101011
for await (const value of stream.fullStream) {
10111012
log.info("part", {
@@ -1016,12 +1017,41 @@ export namespace Session {
10161017
break
10171018

10181019
case "reasoning-start":
1020+
if (value.id in reasoningMap) {
1021+
continue
1022+
}
1023+
reasoningMap[value.id] = {
1024+
id: Identifier.ascending("part"),
1025+
messageID: assistantMsg.id,
1026+
sessionID: assistantMsg.sessionID,
1027+
type: "reasoning",
1028+
text: "",
1029+
time: {
1030+
start: Date.now(),
1031+
},
1032+
}
10191033
break
10201034

10211035
case "reasoning-delta":
1036+
if (value.id in reasoningMap) {
1037+
const part = reasoningMap[value.id]
1038+
part.text += value.text
1039+
if (part.text) await updatePart(part)
1040+
}
10221041
break
10231042

10241043
case "reasoning-end":
1044+
if (value.id in reasoningMap) {
1045+
const part = reasoningMap[value.id]
1046+
part.text = part.text.trimEnd()
1047+
part.providerMetadata = value.providerMetadata
1048+
part.time = {
1049+
start: Date.now(),
1050+
end: Date.now(),
1051+
}
1052+
await updatePart(part)
1053+
delete reasoningMap[value.id]
1054+
}
10251055
break
10261056

10271057
case "tool-input-start":

‎packages/opencode/src/session/message-v2.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,21 @@ export namespace MessageV2 {
118118
})
119119
export type TextPart = z.infer<typeof TextPart>
120120

121+
export const ReasoningPart = PartBase.extend({
122+
type: z.literal("reasoning"),
123+
text: z.string(),
124+
providerMetadata: z.record(z.any()).optional(),
125+
time: z
126+
.object({
127+
start: z.number(),
128+
end: z.number().optional(),
129+
})
130+
.optional(),
131+
}).openapi({
132+
ref: "ReasoningPart",
133+
})
134+
export type ReasoningPart = z.infer<typeof ReasoningPart>
135+
121136
export const ToolPart = PartBase.extend({
122137
type: z.literal("tool"),
123138
callID: z.string(),
@@ -229,6 +244,7 @@ export namespace MessageV2 {
229244
export const Part = z
230245
.discriminatedUnion("type", [
231246
TextPart,
247+
ReasoningPart,
232248
FilePart,
233249
ToolPart,
234250
StepStartPart,

‎packages/sdk/go/.stats.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 34
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-da1c340135c3dd6b1edb4e00e7039d2ac54d59271683a8b6ed528e51137ce41a.yml
3-
openapi_spec_hash: 0cdd9b6273d72f5a6f484a2999ff0632
4-
config_hash: 7581d5948150d4ef7dd7b13d0845dbeb
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-b86cf7bb8df4f60ebe8b8f51e281c8076cfdccc8554178c1b78beca4b025f0ff.yml
3+
openapi_spec_hash: 47633b7481d91708643ea7b43fffffe6
4+
config_hash: bd7f6435ed0c0005f373b5526c07a055

‎packages/sdk/go/api.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ Response Types:
9292
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#FileSource">FileSource</a>
9393
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Message">Message</a>
9494
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Part">Part</a>
95+
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#ReasoningPart">ReasoningPart</a>
9596
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#Session">Session</a>
9697
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#SnapshotPart">SnapshotPart</a>
9798
- <a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go">opencode</a>.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#StepFinishPart">StepFinishPart</a>

‎packages/sdk/go/config.go‎

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,10 @@ type Config struct {
7474
// Control sharing behavior:'manual' allows manual sharing via commands, 'auto'
7575
// enables automatic sharing, 'disabled' disables all sharing
7676
Share ConfigShare `json:"share"`
77-
// Small model to use for tasks like title generation in the
78-
// format of provider/model
77+
// Small model to use for tasks like title generation in the format of
78+
// provider/model
7979
SmallModel string `json:"small_model"`
80+
Snapshot bool `json:"snapshot"`
8081
// Theme name to use for the interface
8182
Theme string `json:"theme"`
8283
// Custom username to display in conversations instead of system username
@@ -105,6 +106,7 @@ type configJSON struct {
105106
Provider apijson.Field
106107
Share apijson.Field
107108
SmallModel apijson.Field
109+
Snapshot apijson.Field
108110
Theme apijson.Field
109111
Username apijson.Field
110112
raw string
@@ -780,16 +782,18 @@ func (r ConfigModePlanMode) IsKnown() bool {
780782
}
781783

782784
type ConfigPermission struct {
783-
Bash ConfigPermissionBashUnion `json:"bash"`
784-
Edit ConfigPermissionEdit `json:"edit"`
785-
JSON configPermissionJSON `json:"-"`
785+
Bash ConfigPermissionBashUnion `json:"bash"`
786+
Edit ConfigPermissionEdit `json:"edit"`
787+
Webfetch ConfigPermissionWebfetch `json:"webfetch"`
788+
JSON configPermissionJSON `json:"-"`
786789
}
787790

788791
// configPermissionJSON contains the JSON metadata for the struct
789792
// [ConfigPermission]
790793
type configPermissionJSON struct {
791794
Bash apijson.Field
792795
Edit apijson.Field
796+
Webfetch apijson.Field
793797
raw string
794798
ExtraFields map[string]apijson.Field
795799
}
@@ -876,6 +880,22 @@ func (r ConfigPermissionEdit) IsKnown() bool {
876880
return false
877881
}
878882

883+
type ConfigPermissionWebfetch string
884+
885+
const (
886+
ConfigPermissionWebfetchAsk ConfigPermissionWebfetch = "ask"
887+
ConfigPermissionWebfetchAllow ConfigPermissionWebfetch = "allow"
888+
ConfigPermissionWebfetchDeny ConfigPermissionWebfetch = "deny"
889+
)
890+
891+
func (r ConfigPermissionWebfetch) IsKnown() bool {
892+
switch r {
893+
case ConfigPermissionWebfetchAsk, ConfigPermissionWebfetchAllow, ConfigPermissionWebfetchDeny:
894+
return true
895+
}
896+
return false
897+
}
898+
879899
type ConfigProvider struct {
880900
Models map[string]ConfigProviderModel `json:"models,required"`
881901
ID string `json:"id"`

‎packages/sdk/go/scripts/mock‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ echo "==> Starting mock server with URL ${URL}"
2121

2222
# Run prism mock on the given spec
2323
if [ "$1" == "--daemon" ]; then
24-
npm exec --package=@stainless-api/prism-cli@5.8.5 -- prism mock "$URL" &> .prism.log &
24+
npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL" &> .prism.log &
2525

2626
# Wait for server to come online
2727
echo -n "Waiting for server"
@@ -37,5 +37,5 @@ if [ "$1" == "--daemon" ]; then
3737

3838
echo
3939
else
40-
npm exec --package=@stainless-api/prism-cli@5.8.5 -- prism mock "$URL"
40+
npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock "$URL"
4141
fi

‎packages/sdk/go/scripts/test‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ elif ! prism_is_running ; then
4343
echo -e "To run the server, pass in the path or url of your OpenAPI"
4444
echo -e "spec to the prism command:"
4545
echo
46-
echo -e " \$ ${YELLOW}npm exec --package=@stoplight/prism-cli@~5.3.2 -- prism mock path/to/your.openapi.yml${NC}"
46+
echo -e " \$ ${YELLOW}npm exec --package=@stainless-api/prism-cli@5.15.0 -- prism mock path/to/your.openapi.yml${NC}"
4747
echo
4848

4949
exit 1

0 commit comments

Comments
 (0)