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/
This commit is contained in:
Dax
2025-08-07 16:32:12 -04:00
committed by GitHub
parent 12f1ad521f
commit c34aec060f
42 changed files with 1755 additions and 930 deletions

View File

@@ -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

View File

@@ -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>

View File

@@ -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"`

View File

@@ -13,6 +13,28 @@ import (
"github.com/sst/opencode-sdk-go/option"
)
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 {
baseURL = envURL
}
if !testutil.CheckTestServer(t, baseURL) {
return
}
client := opencode.NewClient(
option.WithBaseURL(baseURL),
)
_, err := client.App.Agents(context.TODO())
if err != nil {
var apierr *opencode.Error
if errors.As(err, &apierr) {
t.Log(string(apierr.DumpRequest(true)))
}
t.Fatalf("err should be nil: %s", err.Error())
}
}
func TestAppGet(t *testing.T) {
t.Skip("skipped: tests are disabled for the time being")
baseURL := "http://localhost:4010"
@@ -86,28 +108,6 @@ func TestAppLogWithOptionalParams(t *testing.T) {
}
}
func TestAppModes(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 {
baseURL = envURL
}
if !testutil.CheckTestServer(t, baseURL) {
return
}
client := opencode.NewClient(
option.WithBaseURL(baseURL),
)
_, err := client.App.Modes(context.TODO())
if err != nil {
var apierr *opencode.Error
if errors.As(err, &apierr) {
t.Log(string(apierr.DumpRequest(true)))
}
t.Fatalf("err should be nil: %s", err.Error())
}
}
func TestAppProviders(t *testing.T) {
t.Skip("skipped: tests are disabled for the time being")
baseURL := "http://localhost:4010"

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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,

View File

@@ -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"