summaryrefslogtreecommitdiffhomepage
path: root/packages/sdk
diff options
context:
space:
mode:
authorDax <[email protected]>2025-08-07 16:32:12 -0400
committerGitHub <[email protected]>2025-08-07 16:32:12 -0400
commitc34aec060f2abb78486857b0e0d678cac52e2fab (patch)
tree7d2b42a0c87ab016ffbc096e332b186ec4bce7ac /packages/sdk
parent12f1ad521fef2e1fa6f1b0ce6ec939664d61899f (diff)
downloadopencode-c34aec060f2abb78486857b0e0d678cac52e2fab.tar.gz
opencode-c34aec060f2abb78486857b0e0d678cac52e2fab.zip
Merge agent and mode into one (#1689)
The concept of mode has been deprecated, there is now only the agent field in the config. An agent can be cycled through as your primary agent with <tab> or you can spawn a subagent by @ mentioning it. if you include a description of when to use it, the primary agent will try to automatically use it Full docs here: https://opencode.ai/docs/agents/
Diffstat (limited to 'packages/sdk')
-rw-r--r--packages/sdk/go/.stats.yml6
-rw-r--r--packages/sdk/go/api.md7
-rw-r--r--packages/sdk/go/app.go140
-rw-r--r--packages/sdk/go/app_test.go30
-rw-r--r--packages/sdk/go/config.go306
-rw-r--r--packages/sdk/go/internal/requestconfig/requestconfig.go8
-rw-r--r--packages/sdk/go/session.go146
-rw-r--r--packages/sdk/go/session_test.go2
-rw-r--r--packages/sdk/go/tui.go2
-rw-r--r--packages/sdk/stainless/stainless.yml6
10 files changed, 507 insertions, 146 deletions
diff --git a/packages/sdk/go/.stats.yml b/packages/sdk/go/.stats.yml
index 013bb9ac2..a2023f0e4 100644
--- a/packages/sdk/go/.stats.yml
+++ b/packages/sdk/go/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 34
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-52fd0b61e84fdc1cdd31ec12e1600510e9dd2f9d4fb20c2315b4975cb763ee98.yml
-openapi_spec_hash: e851b8d5a2412f5fc9be82ab88ebdfde
-config_hash: 11a6f0803eb407367c3f677d3e524c37
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/opencode%2Fopencode-da1c340135c3dd6b1edb4e00e7039d2ac54d59271683a8b6ed528e51137ce41a.yml
+openapi_spec_hash: 0cdd9b6273d72f5a6f484a2999ff0632
+config_hash: 7581d5948150d4ef7dd7b13d0845dbeb
diff --git a/packages/sdk/go/api.md b/packages/sdk/go/api.md
index 672460b99..d71951994 100644
--- a/packages/sdk/go/api.md
+++ b/packages/sdk/go/api.md
@@ -18,18 +18,18 @@ Methods:
Response Types:
+- <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#Agent">Agent</a>
- <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#App">App</a>
-- <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#Mode">Mode</a>
- <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#Model">Model</a>
- <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#Provider">Provider</a>
- <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#AppProvidersResponse">AppProvidersResponse</a>
Methods:
+- <code title="get /agent">client.App.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#AppService.Agents">Agents</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>) ([]<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#Agent">Agent</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /app">client.App.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#AppService.Get">Get</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>) (<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#App">App</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /app/init">client.App.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#AppService.Init">Init</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>) (<a href="https://pkg.go.dev/builtin#bool">bool</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="post /log">client.App.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#AppService.Log">Log</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, body <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#AppLogParams">AppLogParams</a>) (<a href="https://pkg.go.dev/builtin#bool">bool</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
-- <code title="get /mode">client.App.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#AppService.Modes">Modes</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>) ([]<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#Mode">Mode</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
- <code title="get /config/providers">client.App.<a href="https://pkg.go.dev/github.com/sst/opencode-sdk-go#AppService.Providers">Providers</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>) (<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#AppProvidersResponse">AppProvidersResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
# Find
@@ -65,7 +65,6 @@ Response Types:
- <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#KeybindsConfig">KeybindsConfig</a>
- <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#McpLocalConfig">McpLocalConfig</a>
- <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#McpRemoteConfig">McpRemoteConfig</a>
-- <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#ModeConfig">ModeConfig</a>
Methods:
@@ -75,6 +74,7 @@ Methods:
Params Types:
+- <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#AgentPartInputParam">AgentPartInputParam</a>
- <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#FilePartInputParam">FilePartInputParam</a>
- <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#FilePartSourceUnionParam">FilePartSourceUnionParam</a>
- <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#FilePartSourceTextParam">FilePartSourceTextParam</a>
@@ -84,6 +84,7 @@ Params Types:
Response Types:
+- <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#AgentPart">AgentPart</a>
- <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#AssistantMessage">AssistantMessage</a>
- <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#FilePart">FilePart</a>
- <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#FilePartSource">FilePartSource</a>
diff --git a/packages/sdk/go/app.go b/packages/sdk/go/app.go
index 0a7d14e72..3a0161a16 100644
--- a/packages/sdk/go/app.go
+++ b/packages/sdk/go/app.go
@@ -31,6 +31,14 @@ func NewAppService(opts ...option.RequestOption) (r *AppService) {
return
}
+// List all agents
+func (r *AppService) Agents(ctx context.Context, opts ...option.RequestOption) (res *[]Agent, err error) {
+ opts = append(r.Options[:], opts...)
+ path := "agent"
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
+ return
+}
+
// Get app info
func (r *AppService) Get(ctx context.Context, opts ...option.RequestOption) (res *App, err error) {
opts = append(r.Options[:], opts...)
@@ -55,14 +63,6 @@ func (r *AppService) Log(ctx context.Context, body AppLogParams, opts ...option.
return
}
-// List all modes
-func (r *AppService) Modes(ctx context.Context, opts ...option.RequestOption) (res *[]Mode, err error) {
- opts = append(r.Options[:], opts...)
- path := "mode"
- err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
- return
-}
-
// List all providers
func (r *AppService) Providers(ctx context.Context, opts ...option.RequestOption) (res *AppProvidersResponse, err error) {
opts = append(r.Options[:], opts...)
@@ -71,6 +71,78 @@ func (r *AppService) Providers(ctx context.Context, opts ...option.RequestOption
return
}
+type Agent struct {
+ Mode AgentMode `json:"mode,required"`
+ Name string `json:"name,required"`
+ Tools map[string]bool `json:"tools,required"`
+ Description string `json:"description"`
+ Model AgentModel `json:"model"`
+ Prompt string `json:"prompt"`
+ Temperature float64 `json:"temperature"`
+ TopP float64 `json:"topP"`
+ JSON agentJSON `json:"-"`
+}
+
+// agentJSON contains the JSON metadata for the struct [Agent]
+type agentJSON struct {
+ Mode apijson.Field
+ Name apijson.Field
+ Tools apijson.Field
+ Description apijson.Field
+ Model apijson.Field
+ Prompt apijson.Field
+ Temperature apijson.Field
+ TopP apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
+}
+
+func (r *Agent) UnmarshalJSON(data []byte) (err error) {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func (r agentJSON) RawJSON() string {
+ return r.raw
+}
+
+type AgentMode string
+
+const (
+ AgentModeSubagent AgentMode = "subagent"
+ AgentModePrimary AgentMode = "primary"
+ AgentModeAll AgentMode = "all"
+)
+
+func (r AgentMode) IsKnown() bool {
+ switch r {
+ case AgentModeSubagent, AgentModePrimary, AgentModeAll:
+ return true
+ }
+ return false
+}
+
+type AgentModel struct {
+ ModelID string `json:"modelID,required"`
+ ProviderID string `json:"providerID,required"`
+ JSON agentModelJSON `json:"-"`
+}
+
+// agentModelJSON contains the JSON metadata for the struct [AgentModel]
+type agentModelJSON struct {
+ ModelID apijson.Field
+ ProviderID apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
+}
+
+func (r *AgentModel) UnmarshalJSON(data []byte) (err error) {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func (r agentModelJSON) RawJSON() string {
+ return r.raw
+}
+
type App struct {
Git bool `json:"git,required"`
Hostname string `json:"hostname,required"`
@@ -145,58 +217,6 @@ func (r appTimeJSON) RawJSON() string {
return r.raw
}
-type Mode struct {
- Name string `json:"name,required"`
- Tools map[string]bool `json:"tools,required"`
- Model ModeModel `json:"model"`
- Prompt string `json:"prompt"`
- Temperature float64 `json:"temperature"`
- TopP float64 `json:"topP"`
- JSON modeJSON `json:"-"`
-}
-
-// modeJSON contains the JSON metadata for the struct [Mode]
-type modeJSON struct {
- Name apijson.Field
- Tools apijson.Field
- Model apijson.Field
- Prompt apijson.Field
- Temperature apijson.Field
- TopP apijson.Field
- raw string
- ExtraFields map[string]apijson.Field
-}
-
-func (r *Mode) UnmarshalJSON(data []byte) (err error) {
- return apijson.UnmarshalRoot(data, r)
-}
-
-func (r modeJSON) RawJSON() string {
- return r.raw
-}
-
-type ModeModel struct {
- ModelID string `json:"modelID,required"`
- ProviderID string `json:"providerID,required"`
- JSON modeModelJSON `json:"-"`
-}
-
-// modeModelJSON contains the JSON metadata for the struct [ModeModel]
-type modeModelJSON struct {
- ModelID apijson.Field
- ProviderID apijson.Field
- raw string
- ExtraFields map[string]apijson.Field
-}
-
-func (r *ModeModel) UnmarshalJSON(data []byte) (err error) {
- return apijson.UnmarshalRoot(data, r)
-}
-
-func (r modeModelJSON) RawJSON() string {
- return r.raw
-}
-
type Model struct {
ID string `json:"id,required"`
Attachment bool `json:"attachment,required"`
diff --git a/packages/sdk/go/app_test.go b/packages/sdk/go/app_test.go
index 16bb8ff88..2ade6c7ec 100644
--- a/packages/sdk/go/app_test.go
+++ b/packages/sdk/go/app_test.go
@@ -13,7 +13,7 @@ import (
"github.com/sst/opencode-sdk-go/option"
)
-func TestAppGet(t *testing.T) {
+func TestAppAgents(t *testing.T) {
t.Skip("skipped: tests are disabled for the time being")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
@@ -25,7 +25,7 @@ func TestAppGet(t *testing.T) {
client := opencode.NewClient(
option.WithBaseURL(baseURL),
)
- _, err := client.App.Get(context.TODO())
+ _, err := client.App.Agents(context.TODO())
if err != nil {
var apierr *opencode.Error
if errors.As(err, &apierr) {
@@ -35,7 +35,7 @@ func TestAppGet(t *testing.T) {
}
}
-func TestAppInit(t *testing.T) {
+func TestAppGet(t *testing.T) {
t.Skip("skipped: tests are disabled for the time being")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
@@ -47,7 +47,7 @@ func TestAppInit(t *testing.T) {
client := opencode.NewClient(
option.WithBaseURL(baseURL),
)
- _, err := client.App.Init(context.TODO())
+ _, err := client.App.Get(context.TODO())
if err != nil {
var apierr *opencode.Error
if errors.As(err, &apierr) {
@@ -57,7 +57,7 @@ func TestAppInit(t *testing.T) {
}
}
-func TestAppLogWithOptionalParams(t *testing.T) {
+func TestAppInit(t *testing.T) {
t.Skip("skipped: tests are disabled for the time being")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
@@ -69,14 +69,7 @@ func TestAppLogWithOptionalParams(t *testing.T) {
client := opencode.NewClient(
option.WithBaseURL(baseURL),
)
- _, err := client.App.Log(context.TODO(), opencode.AppLogParams{
- Level: opencode.F(opencode.AppLogParamsLevelDebug),
- Message: opencode.F("message"),
- Service: opencode.F("service"),
- Extra: opencode.F(map[string]interface{}{
- "foo": "bar",
- }),
- })
+ _, err := client.App.Init(context.TODO())
if err != nil {
var apierr *opencode.Error
if errors.As(err, &apierr) {
@@ -86,7 +79,7 @@ func TestAppLogWithOptionalParams(t *testing.T) {
}
}
-func TestAppModes(t *testing.T) {
+func TestAppLogWithOptionalParams(t *testing.T) {
t.Skip("skipped: tests are disabled for the time being")
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
@@ -98,7 +91,14 @@ func TestAppModes(t *testing.T) {
client := opencode.NewClient(
option.WithBaseURL(baseURL),
)
- _, err := client.App.Modes(context.TODO())
+ _, err := client.App.Log(context.TODO(), opencode.AppLogParams{
+ Level: opencode.F(opencode.AppLogParamsLevelDebug),
+ Message: opencode.F("message"),
+ Service: opencode.F("service"),
+ Extra: opencode.F(map[string]interface{}{
+ "foo": "bar",
+ }),
+ })
if err != nil {
var apierr *opencode.Error
if errors.As(err, &apierr) {
diff --git a/packages/sdk/go/config.go b/packages/sdk/go/config.go
index 911bb2a30..a7b75a1bf 100644
--- a/packages/sdk/go/config.go
+++ b/packages/sdk/go/config.go
@@ -43,7 +43,7 @@ func (r *ConfigService) Get(ctx context.Context, opts ...option.RequestOption) (
type Config struct {
// JSON schema reference for configuration validation
Schema string `json:"$schema"`
- // Modes configuration, see https://opencode.ai/docs/modes
+ // Agent configuration, see https://opencode.ai/docs/agent
Agent ConfigAgent `json:"agent"`
// @deprecated Use 'share' field instead. Share newly created sessions
// automatically
@@ -63,7 +63,7 @@ type Config struct {
Lsp map[string]ConfigLsp `json:"lsp"`
// MCP (Model Context Protocol) server configurations
Mcp map[string]ConfigMcp `json:"mcp"`
- // Modes configuration, see https://opencode.ai/docs/modes
+ // @deprecated Use `agent` field instead.
Mode ConfigMode `json:"mode"`
// Model to use in the format of provider/model, eg anthropic/claude-2
Model string `json:"model"`
@@ -119,16 +119,20 @@ func (r configJSON) RawJSON() string {
return r.raw
}
-// Modes configuration, see https://opencode.ai/docs/modes
+// Agent configuration, see https://opencode.ai/docs/agent
type ConfigAgent struct {
+ Build ConfigAgentBuild `json:"build"`
General ConfigAgentGeneral `json:"general"`
+ Plan ConfigAgentPlan `json:"plan"`
ExtraFields map[string]ConfigAgent `json:"-,extras"`
JSON configAgentJSON `json:"-"`
}
// configAgentJSON contains the JSON metadata for the struct [ConfigAgent]
type configAgentJSON struct {
+ Build apijson.Field
General apijson.Field
+ Plan apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
@@ -141,16 +145,82 @@ func (r configAgentJSON) RawJSON() string {
return r.raw
}
+type ConfigAgentBuild struct {
+ // Description of when to use the agent
+ Description string `json:"description"`
+ Disable bool `json:"disable"`
+ Mode ConfigAgentBuildMode `json:"mode"`
+ Model string `json:"model"`
+ Prompt string `json:"prompt"`
+ Temperature float64 `json:"temperature"`
+ Tools map[string]bool `json:"tools"`
+ TopP float64 `json:"top_p"`
+ JSON configAgentBuildJSON `json:"-"`
+}
+
+// configAgentBuildJSON contains the JSON metadata for the struct
+// [ConfigAgentBuild]
+type configAgentBuildJSON struct {
+ Description apijson.Field
+ Disable apijson.Field
+ Mode apijson.Field
+ Model apijson.Field
+ Prompt apijson.Field
+ Temperature apijson.Field
+ Tools apijson.Field
+ TopP apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
+}
+
+func (r *ConfigAgentBuild) UnmarshalJSON(data []byte) (err error) {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func (r configAgentBuildJSON) RawJSON() string {
+ return r.raw
+}
+
+type ConfigAgentBuildMode string
+
+const (
+ ConfigAgentBuildModeSubagent ConfigAgentBuildMode = "subagent"
+ ConfigAgentBuildModePrimary ConfigAgentBuildMode = "primary"
+ ConfigAgentBuildModeAll ConfigAgentBuildMode = "all"
+)
+
+func (r ConfigAgentBuildMode) IsKnown() bool {
+ switch r {
+ case ConfigAgentBuildModeSubagent, ConfigAgentBuildModePrimary, ConfigAgentBuildModeAll:
+ return true
+ }
+ return false
+}
+
type ConfigAgentGeneral struct {
- Description string `json:"description,required"`
+ // Description of when to use the agent
+ Description string `json:"description"`
+ Disable bool `json:"disable"`
+ Mode ConfigAgentGeneralMode `json:"mode"`
+ Model string `json:"model"`
+ Prompt string `json:"prompt"`
+ Temperature float64 `json:"temperature"`
+ Tools map[string]bool `json:"tools"`
+ TopP float64 `json:"top_p"`
JSON configAgentGeneralJSON `json:"-"`
- ModeConfig
}
// configAgentGeneralJSON contains the JSON metadata for the struct
// [ConfigAgentGeneral]
type configAgentGeneralJSON struct {
Description apijson.Field
+ Disable apijson.Field
+ Mode apijson.Field
+ Model apijson.Field
+ Prompt apijson.Field
+ Temperature apijson.Field
+ Tools apijson.Field
+ TopP apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
@@ -163,6 +233,73 @@ func (r configAgentGeneralJSON) RawJSON() string {
return r.raw
}
+type ConfigAgentGeneralMode string
+
+const (
+ ConfigAgentGeneralModeSubagent ConfigAgentGeneralMode = "subagent"
+ ConfigAgentGeneralModePrimary ConfigAgentGeneralMode = "primary"
+ ConfigAgentGeneralModeAll ConfigAgentGeneralMode = "all"
+)
+
+func (r ConfigAgentGeneralMode) IsKnown() bool {
+ switch r {
+ case ConfigAgentGeneralModeSubagent, ConfigAgentGeneralModePrimary, ConfigAgentGeneralModeAll:
+ return true
+ }
+ return false
+}
+
+type ConfigAgentPlan struct {
+ // Description of when to use the agent
+ Description string `json:"description"`
+ Disable bool `json:"disable"`
+ Mode ConfigAgentPlanMode `json:"mode"`
+ Model string `json:"model"`
+ Prompt string `json:"prompt"`
+ Temperature float64 `json:"temperature"`
+ Tools map[string]bool `json:"tools"`
+ TopP float64 `json:"top_p"`
+ JSON configAgentPlanJSON `json:"-"`
+}
+
+// configAgentPlanJSON contains the JSON metadata for the struct [ConfigAgentPlan]
+type configAgentPlanJSON struct {
+ Description apijson.Field
+ Disable apijson.Field
+ Mode apijson.Field
+ Model apijson.Field
+ Prompt apijson.Field
+ Temperature apijson.Field
+ Tools apijson.Field
+ TopP apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
+}
+
+func (r *ConfigAgentPlan) UnmarshalJSON(data []byte) (err error) {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func (r configAgentPlanJSON) RawJSON() string {
+ return r.raw
+}
+
+type ConfigAgentPlanMode string
+
+const (
+ ConfigAgentPlanModeSubagent ConfigAgentPlanMode = "subagent"
+ ConfigAgentPlanModePrimary ConfigAgentPlanMode = "primary"
+ ConfigAgentPlanModeAll ConfigAgentPlanMode = "all"
+)
+
+func (r ConfigAgentPlanMode) IsKnown() bool {
+ switch r {
+ case ConfigAgentPlanModeSubagent, ConfigAgentPlanModePrimary, ConfigAgentPlanModeAll:
+ return true
+ }
+ return false
+}
+
type ConfigExperimental struct {
Hook ConfigExperimentalHook `json:"hook"`
JSON configExperimentalJSON `json:"-"`
@@ -516,11 +653,11 @@ func (r ConfigMcpType) IsKnown() bool {
return false
}
-// Modes configuration, see https://opencode.ai/docs/modes
+// @deprecated Use `agent` field instead.
type ConfigMode struct {
- Build ModeConfig `json:"build"`
- Plan ModeConfig `json:"plan"`
- ExtraFields map[string]ModeConfig `json:"-,extras"`
+ Build ConfigModeBuild `json:"build"`
+ Plan ConfigModePlan `json:"plan"`
+ ExtraFields map[string]ConfigMode `json:"-,extras"`
JSON configModeJSON `json:"-"`
}
@@ -540,6 +677,108 @@ func (r configModeJSON) RawJSON() string {
return r.raw
}
+type ConfigModeBuild struct {
+ // Description of when to use the agent
+ Description string `json:"description"`
+ Disable bool `json:"disable"`
+ Mode ConfigModeBuildMode `json:"mode"`
+ Model string `json:"model"`
+ Prompt string `json:"prompt"`
+ Temperature float64 `json:"temperature"`
+ Tools map[string]bool `json:"tools"`
+ TopP float64 `json:"top_p"`
+ JSON configModeBuildJSON `json:"-"`
+}
+
+// configModeBuildJSON contains the JSON metadata for the struct [ConfigModeBuild]
+type configModeBuildJSON struct {
+ Description apijson.Field
+ Disable apijson.Field
+ Mode apijson.Field
+ Model apijson.Field
+ Prompt apijson.Field
+ Temperature apijson.Field
+ Tools apijson.Field
+ TopP apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
+}
+
+func (r *ConfigModeBuild) UnmarshalJSON(data []byte) (err error) {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func (r configModeBuildJSON) RawJSON() string {
+ return r.raw
+}
+
+type ConfigModeBuildMode string
+
+const (
+ ConfigModeBuildModeSubagent ConfigModeBuildMode = "subagent"
+ ConfigModeBuildModePrimary ConfigModeBuildMode = "primary"
+ ConfigModeBuildModeAll ConfigModeBuildMode = "all"
+)
+
+func (r ConfigModeBuildMode) IsKnown() bool {
+ switch r {
+ case ConfigModeBuildModeSubagent, ConfigModeBuildModePrimary, ConfigModeBuildModeAll:
+ return true
+ }
+ return false
+}
+
+type ConfigModePlan struct {
+ // Description of when to use the agent
+ Description string `json:"description"`
+ Disable bool `json:"disable"`
+ Mode ConfigModePlanMode `json:"mode"`
+ Model string `json:"model"`
+ Prompt string `json:"prompt"`
+ Temperature float64 `json:"temperature"`
+ Tools map[string]bool `json:"tools"`
+ TopP float64 `json:"top_p"`
+ JSON configModePlanJSON `json:"-"`
+}
+
+// configModePlanJSON contains the JSON metadata for the struct [ConfigModePlan]
+type configModePlanJSON struct {
+ Description apijson.Field
+ Disable apijson.Field
+ Mode apijson.Field
+ Model apijson.Field
+ Prompt apijson.Field
+ Temperature apijson.Field
+ Tools apijson.Field
+ TopP apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
+}
+
+func (r *ConfigModePlan) UnmarshalJSON(data []byte) (err error) {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func (r configModePlanJSON) RawJSON() string {
+ return r.raw
+}
+
+type ConfigModePlanMode string
+
+const (
+ ConfigModePlanModeSubagent ConfigModePlanMode = "subagent"
+ ConfigModePlanModePrimary ConfigModePlanMode = "primary"
+ ConfigModePlanModeAll ConfigModePlanMode = "all"
+)
+
+func (r ConfigModePlanMode) IsKnown() bool {
+ switch r {
+ case ConfigModePlanModeSubagent, ConfigModePlanModePrimary, ConfigModePlanModeAll:
+ return true
+ }
+ return false
+}
+
type ConfigPermission struct {
Bash ConfigPermissionBashUnion `json:"bash"`
Edit ConfigPermissionEdit `json:"edit"`
@@ -588,11 +827,12 @@ type ConfigPermissionBashString string
const (
ConfigPermissionBashStringAsk ConfigPermissionBashString = "ask"
ConfigPermissionBashStringAllow ConfigPermissionBashString = "allow"
+ ConfigPermissionBashStringDeny ConfigPermissionBashString = "deny"
)
func (r ConfigPermissionBashString) IsKnown() bool {
switch r {
- case ConfigPermissionBashStringAsk, ConfigPermissionBashStringAllow:
+ case ConfigPermissionBashStringAsk, ConfigPermissionBashStringAllow, ConfigPermissionBashStringDeny:
return true
}
return false
@@ -609,11 +849,12 @@ type ConfigPermissionBashMapItem string
const (
ConfigPermissionBashMapAsk ConfigPermissionBashMapItem = "ask"
ConfigPermissionBashMapAllow ConfigPermissionBashMapItem = "allow"
+ ConfigPermissionBashMapDeny ConfigPermissionBashMapItem = "deny"
)
func (r ConfigPermissionBashMapItem) IsKnown() bool {
switch r {
- case ConfigPermissionBashMapAsk, ConfigPermissionBashMapAllow:
+ case ConfigPermissionBashMapAsk, ConfigPermissionBashMapAllow, ConfigPermissionBashMapDeny:
return true
}
return false
@@ -624,11 +865,12 @@ type ConfigPermissionEdit string
const (
ConfigPermissionEditAsk ConfigPermissionEdit = "ask"
ConfigPermissionEditAllow ConfigPermissionEdit = "allow"
+ ConfigPermissionEditDeny ConfigPermissionEdit = "deny"
)
func (r ConfigPermissionEdit) IsKnown() bool {
switch r {
- case ConfigPermissionEditAsk, ConfigPermissionEditAllow:
+ case ConfigPermissionEditAsk, ConfigPermissionEditAllow, ConfigPermissionEditDeny:
return true
}
return false
@@ -866,9 +1108,13 @@ type KeybindsConfig struct {
SessionShare string `json:"session_share,required"`
// Unshare current session
SessionUnshare string `json:"session_unshare,required"`
- // Next mode
+ // Next agent
+ SwitchAgent string `json:"switch_agent,required"`
+ // Previous agent
+ SwitchAgentReverse string `json:"switch_agent_reverse,required"`
+ // @deprecated use switch_agent. Next mode
SwitchMode string `json:"switch_mode,required"`
- // Previous Mode
+ // @deprecated use switch_agent_reverse. Previous mode
SwitchModeReverse string `json:"switch_mode_reverse,required"`
// List available themes
ThemeList string `json:"theme_list,required"`
@@ -913,6 +1159,8 @@ type keybindsConfigJSON struct {
SessionNew apijson.Field
SessionShare apijson.Field
SessionUnshare apijson.Field
+ SwitchAgent apijson.Field
+ SwitchAgentReverse apijson.Field
SwitchMode apijson.Field
SwitchModeReverse apijson.Field
ThemeList apijson.Field
@@ -1022,33 +1270,3 @@ func (r McpRemoteConfigType) IsKnown() bool {
}
return false
}
-
-type ModeConfig struct {
- Disable bool `json:"disable"`
- Model string `json:"model"`
- Prompt string `json:"prompt"`
- Temperature float64 `json:"temperature"`
- Tools map[string]bool `json:"tools"`
- TopP float64 `json:"top_p"`
- JSON modeConfigJSON `json:"-"`
-}
-
-// modeConfigJSON contains the JSON metadata for the struct [ModeConfig]
-type modeConfigJSON struct {
- Disable apijson.Field
- Model apijson.Field
- Prompt apijson.Field
- Temperature apijson.Field
- Tools apijson.Field
- TopP apijson.Field
- raw string
- ExtraFields map[string]apijson.Field
-}
-
-func (r *ModeConfig) UnmarshalJSON(data []byte) (err error) {
- return apijson.UnmarshalRoot(data, r)
-}
-
-func (r modeConfigJSON) RawJSON() string {
- return r.raw
-}
diff --git a/packages/sdk/go/internal/requestconfig/requestconfig.go b/packages/sdk/go/internal/requestconfig/requestconfig.go
index 91b70cca5..53bf9f58c 100644
--- a/packages/sdk/go/internal/requestconfig/requestconfig.go
+++ b/packages/sdk/go/internal/requestconfig/requestconfig.go
@@ -133,11 +133,13 @@ func NewRequestConfig(ctx context.Context, method string, u string, body interfa
// Fallback to json serialization if none of the serialization functions that we expect
// to see is present.
if body != nil && !hasSerializationFunc {
- content, err := json.Marshal(body)
- if err != nil {
+ buf := new(bytes.Buffer)
+ enc := json.NewEncoder(buf)
+ enc.SetEscapeHTML(true)
+ if err := enc.Encode(body); err != nil {
return nil, err
}
- reader = bytes.NewBuffer(content)
+ reader = buf
}
req, err := http.NewRequestWithContext(ctx, method, u, nil)
diff --git a/packages/sdk/go/session.go b/packages/sdk/go/session.go
index d38c37e0e..bae17cf2a 100644
--- a/packages/sdk/go/session.go
+++ b/packages/sdk/go/session.go
@@ -190,6 +190,113 @@ func (r *SessionService) Unshare(ctx context.Context, id string, opts ...option.
return
}
+type AgentPart struct {
+ ID string `json:"id,required"`
+ MessageID string `json:"messageID,required"`
+ Name string `json:"name,required"`
+ SessionID string `json:"sessionID,required"`
+ Type AgentPartType `json:"type,required"`
+ Source AgentPartSource `json:"source"`
+ JSON agentPartJSON `json:"-"`
+}
+
+// agentPartJSON contains the JSON metadata for the struct [AgentPart]
+type agentPartJSON struct {
+ ID apijson.Field
+ MessageID apijson.Field
+ Name apijson.Field
+ SessionID apijson.Field
+ Type apijson.Field
+ Source apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
+}
+
+func (r *AgentPart) UnmarshalJSON(data []byte) (err error) {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func (r agentPartJSON) RawJSON() string {
+ return r.raw
+}
+
+func (r AgentPart) implementsPart() {}
+
+type AgentPartType string
+
+const (
+ AgentPartTypeAgent AgentPartType = "agent"
+)
+
+func (r AgentPartType) IsKnown() bool {
+ switch r {
+ case AgentPartTypeAgent:
+ return true
+ }
+ return false
+}
+
+type AgentPartSource struct {
+ End int64 `json:"end,required"`
+ Start int64 `json:"start,required"`
+ Value string `json:"value,required"`
+ JSON agentPartSourceJSON `json:"-"`
+}
+
+// agentPartSourceJSON contains the JSON metadata for the struct [AgentPartSource]
+type agentPartSourceJSON struct {
+ End apijson.Field
+ Start apijson.Field
+ Value apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
+}
+
+func (r *AgentPartSource) UnmarshalJSON(data []byte) (err error) {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func (r agentPartSourceJSON) RawJSON() string {
+ return r.raw
+}
+
+type AgentPartInputParam struct {
+ Name param.Field[string] `json:"name,required"`
+ Type param.Field[AgentPartInputType] `json:"type,required"`
+ ID param.Field[string] `json:"id"`
+ Source param.Field[AgentPartInputSourceParam] `json:"source"`
+}
+
+func (r AgentPartInputParam) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
+func (r AgentPartInputParam) implementsSessionChatParamsPartUnion() {}
+
+type AgentPartInputType string
+
+const (
+ AgentPartInputTypeAgent AgentPartInputType = "agent"
+)
+
+func (r AgentPartInputType) IsKnown() bool {
+ switch r {
+ case AgentPartInputTypeAgent:
+ return true
+ }
+ return false
+}
+
+type AgentPartInputSourceParam struct {
+ End param.Field[int64] `json:"end,required"`
+ Start param.Field[int64] `json:"start,required"`
+ Value param.Field[string] `json:"value,required"`
+}
+
+func (r AgentPartInputSourceParam) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
type AssistantMessage struct {
ID string `json:"id,required"`
Cost float64 `json:"cost,required"`
@@ -855,11 +962,13 @@ type Part struct {
Cost float64 `json:"cost"`
Filename string `json:"filename"`
// This field can have the runtime type of [[]string].
- Files interface{} `json:"files"`
- Hash string `json:"hash"`
- Mime string `json:"mime"`
- Snapshot string `json:"snapshot"`
- Source FilePartSource `json:"source"`
+ Files interface{} `json:"files"`
+ Hash string `json:"hash"`
+ Mime string `json:"mime"`
+ Name string `json:"name"`
+ Snapshot string `json:"snapshot"`
+ // This field can have the runtime type of [FilePartSource], [AgentPartSource].
+ Source interface{} `json:"source"`
// This field can have the runtime type of [ToolPartState].
State interface{} `json:"state"`
Synthetic bool `json:"synthetic"`
@@ -886,6 +995,7 @@ type partJSON struct {
Files apijson.Field
Hash apijson.Field
Mime apijson.Field
+ Name apijson.Field
Snapshot apijson.Field
Source apijson.Field
State apijson.Field
@@ -916,13 +1026,13 @@ func (r *Part) UnmarshalJSON(data []byte) (err error) {
// for more type safety.
//
// Possible runtime types of the union are [TextPart], [FilePart], [ToolPart],
-// [StepStartPart], [StepFinishPart], [SnapshotPart], [PartPatchPart].
+// [StepStartPart], [StepFinishPart], [SnapshotPart], [PartPatchPart], [AgentPart].
func (r Part) AsUnion() PartUnion {
return r.union
}
// Union satisfied by [TextPart], [FilePart], [ToolPart], [StepStartPart],
-// [StepFinishPart], [SnapshotPart] or [PartPatchPart].
+// [StepFinishPart], [SnapshotPart], [PartPatchPart] or [AgentPart].
type PartUnion interface {
implementsPart()
}
@@ -966,6 +1076,11 @@ func init() {
Type: reflect.TypeOf(PartPatchPart{}),
DiscriminatorValue: "patch",
},
+ apijson.UnionVariant{
+ TypeFilter: gjson.JSON,
+ Type: reflect.TypeOf(AgentPart{}),
+ DiscriminatorValue: "agent",
+ },
)
}
@@ -1025,11 +1140,12 @@ const (
PartTypeStepFinish PartType = "step-finish"
PartTypeSnapshot PartType = "snapshot"
PartTypePatch PartType = "patch"
+ PartTypeAgent PartType = "agent"
)
func (r PartType) IsKnown() bool {
switch r {
- case PartTypeText, PartTypeFile, PartTypeTool, PartTypeStepStart, PartTypeStepFinish, PartTypeSnapshot, PartTypePatch:
+ case PartTypeText, PartTypeFile, PartTypeTool, PartTypeStepStart, PartTypeStepFinish, PartTypeSnapshot, PartTypePatch, PartTypeAgent:
return true
}
return false
@@ -2080,8 +2196,8 @@ type SessionChatParams struct {
ModelID param.Field[string] `json:"modelID,required"`
Parts param.Field[[]SessionChatParamsPartUnion] `json:"parts,required"`
ProviderID param.Field[string] `json:"providerID,required"`
+ Agent param.Field[string] `json:"agent"`
MessageID param.Field[string] `json:"messageID"`
- Mode param.Field[string] `json:"mode"`
System param.Field[string] `json:"system"`
Tools param.Field[map[string]bool] `json:"tools"`
}
@@ -2095,7 +2211,8 @@ type SessionChatParamsPart struct {
ID param.Field[string] `json:"id"`
Filename param.Field[string] `json:"filename"`
Mime param.Field[string] `json:"mime"`
- Source param.Field[FilePartSourceUnionParam] `json:"source"`
+ Name param.Field[string] `json:"name"`
+ Source param.Field[interface{}] `json:"source"`
Synthetic param.Field[bool] `json:"synthetic"`
Text param.Field[string] `json:"text"`
Time param.Field[interface{}] `json:"time"`
@@ -2108,7 +2225,7 @@ func (r SessionChatParamsPart) MarshalJSON() (data []byte, err error) {
func (r SessionChatParamsPart) implementsSessionChatParamsPartUnion() {}
-// Satisfied by [TextPartInputParam], [FilePartInputParam],
+// Satisfied by [TextPartInputParam], [FilePartInputParam], [AgentPartInputParam],
// [SessionChatParamsPart].
type SessionChatParamsPartUnion interface {
implementsSessionChatParamsPartUnion()
@@ -2117,13 +2234,14 @@ type SessionChatParamsPartUnion interface {
type SessionChatParamsPartsType string
const (
- SessionChatParamsPartsTypeText SessionChatParamsPartsType = "text"
- SessionChatParamsPartsTypeFile SessionChatParamsPartsType = "file"
+ SessionChatParamsPartsTypeText SessionChatParamsPartsType = "text"
+ SessionChatParamsPartsTypeFile SessionChatParamsPartsType = "file"
+ SessionChatParamsPartsTypeAgent SessionChatParamsPartsType = "agent"
)
func (r SessionChatParamsPartsType) IsKnown() bool {
switch r {
- case SessionChatParamsPartsTypeText, SessionChatParamsPartsTypeFile:
+ case SessionChatParamsPartsTypeText, SessionChatParamsPartsTypeFile, SessionChatParamsPartsTypeAgent:
return true
}
return false
diff --git a/packages/sdk/go/session_test.go b/packages/sdk/go/session_test.go
index ab9fbcf7b..b8158f099 100644
--- a/packages/sdk/go/session_test.go
+++ b/packages/sdk/go/session_test.go
@@ -129,8 +129,8 @@ func TestSessionChatWithOptionalParams(t *testing.T) {
}),
}}),
ProviderID: opencode.F("providerID"),
+ Agent: opencode.F("agent"),
MessageID: opencode.F("msg"),
- Mode: opencode.F("mode"),
System: opencode.F("system"),
Tools: opencode.F(map[string]bool{
"foo": true,
diff --git a/packages/sdk/go/tui.go b/packages/sdk/go/tui.go
index 30657890d..986b73aa5 100644
--- a/packages/sdk/go/tui.go
+++ b/packages/sdk/go/tui.go
@@ -47,7 +47,7 @@ func (r *TuiService) ClearPrompt(ctx context.Context, opts ...option.RequestOpti
return
}
-// Execute a TUI command (e.g. switch_mode)
+// Execute a TUI command (e.g. switch_agent)
func (r *TuiService) ExecuteCommand(ctx context.Context, body TuiExecuteCommandParams, opts ...option.RequestOption) (res *bool, err error) {
opts = append(r.Options[:], opts...)
path := "tui/execute-command"
diff --git a/packages/sdk/stainless/stainless.yml b/packages/sdk/stainless/stainless.yml
index b9d69cdef..3a8da4061 100644
--- a/packages/sdk/stainless/stainless.yml
+++ b/packages/sdk/stainless/stainless.yml
@@ -51,12 +51,12 @@ resources:
logLevel: LogLevel
provider: Provider
model: Model
- mode: Mode
+ agent: Agent
methods:
get: get /app
init: post /app/init
log: post /log
- modes: get /mode
+ agents: get /agent
providers: get /config/providers
find:
@@ -99,6 +99,8 @@ resources:
fileSource: FileSource
symbolSource: SymbolSource
toolPart: ToolPart
+ agentPart: AgentPart
+ agentPartInput: AgentPartInput
stepStartPart: StepStartPart
stepFinishPart: StepFinishPart
snapshotPart: SnapshotPart