diff --git a/packages/opencode/src/provider/models.ts b/packages/opencode/src/provider/models.ts index 8d2800f8..af4e88df 100644 --- a/packages/opencode/src/provider/models.ts +++ b/packages/opencode/src/provider/models.ts @@ -7,31 +7,40 @@ export namespace ModelsDev { const log = Log.create({ service: "models.dev" }) const filepath = path.join(Global.Path.cache, "models.json") - export const Model = z.object({ - name: z.string(), - attachment: z.boolean(), - reasoning: z.boolean(), - temperature: z.boolean(), - cost: z.object({ - input: z.number(), - output: z.number(), - inputCached: z.number(), - outputCached: z.number(), - }), - limit: z.object({ - context: z.number(), - output: z.number(), - }), - id: z.string(), - }) + export const Model = z + .object({ + name: z.string(), + attachment: z.boolean(), + reasoning: z.boolean(), + temperature: z.boolean(), + cost: z.object({ + input: z.number(), + output: z.number(), + inputCached: z.number(), + outputCached: z.number(), + }), + limit: z.object({ + context: z.number(), + output: z.number(), + }), + id: z.string(), + }) + .openapi({ + ref: "Model.Info", + }) export type Model = z.infer - export const Provider = z.object({ - name: z.string(), - env: z.array(z.string()), - id: z.string(), - models: z.record(Model), - }) + export const Provider = z + .object({ + name: z.string(), + env: z.array(z.string()), + id: z.string(), + models: z.record(Model), + }) + .openapi({ + ref: "Provider.Info", + }) + export type Provider = z.infer export async function get() { diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go index 3917330e..69900a0b 100644 --- a/packages/tui/internal/app/app.go +++ b/packages/tui/internal/app/app.go @@ -23,7 +23,7 @@ type App struct { Config *config.Config Client *client.ClientWithResponses Provider *client.ProviderInfo - Model *client.ProviderModel + Model *client.ModelInfo Session *client.SessionInfo Messages []client.MessageInfo Status status.Service @@ -61,20 +61,25 @@ func New(ctx context.Context, version string, httpClient *client.ClientWithRespo } providers := []client.ProviderInfo{} var defaultProvider *client.ProviderInfo - var defaultModel *client.ProviderModel + var defaultModel *client.ModelInfo - for i, provider := range providersResponse.JSON200.Providers { - if i == 0 || provider.Id == "anthropic" { - defaultProvider = &providersResponse.JSON200.Providers[i] - if match, ok := providersResponse.JSON200.Default[provider.Id]; ok { - model := defaultProvider.Models[match] - defaultModel = &model - } else { - for _, model := range provider.Models { - defaultModel = &model - break - } - } + var anthropic *client.ProviderInfo + for _, provider := range providersResponse.JSON200.Providers { + if provider.Id == "anthropic" { + anthropic = &provider + } + } + + // default to anthropic if available + if anthropic != nil { + defaultProvider = anthropic + defaultModel = getDefaultModel(providersResponse, *anthropic) + } + + for _, provider := range providersResponse.JSON200.Providers { + if defaultProvider == nil || defaultModel == nil { + defaultProvider = &provider + defaultModel = getDefaultModel(providersResponse, provider) } providers = append(providers, provider) } @@ -91,7 +96,7 @@ func New(ctx context.Context, version string, httpClient *client.ClientWithRespo } var currentProvider *client.ProviderInfo - var currentModel *client.ProviderModel + var currentModel *client.ModelInfo for _, provider := range providers { if provider.Id == appConfig.Provider { currentProvider = &provider @@ -121,6 +126,18 @@ func New(ctx context.Context, version string, httpClient *client.ClientWithRespo return app, nil } +func getDefaultModel(response *client.PostProviderListResponse, provider client.ProviderInfo) *client.ModelInfo { + if match, ok := response.JSON200.Default[provider.Id]; ok { + model := provider.Models[match] + return &model + } else { + for _, model := range provider.Models { + return &model + } + } + return nil +} + type Attachment struct { FilePath string FileName string diff --git a/packages/tui/internal/components/chat/editor.go b/packages/tui/internal/components/chat/editor.go index 8d977f5e..f78bd192 100644 --- a/packages/tui/internal/components/chat/editor.go +++ b/packages/tui/internal/components/chat/editor.go @@ -284,7 +284,7 @@ func (m *editorComponent) View() string { model := "" if m.app.Model != nil { - model = base(*m.app.Model.Name) + muted(" • /model") + model = base(m.app.Model.Name) + muted(" • /model") } space := m.width - 2 - lipgloss.Width(model) - lipgloss.Width(hint) diff --git a/packages/tui/internal/components/chat/message.go b/packages/tui/internal/components/chat/message.go index 2c2cd03f..82e749af 100644 --- a/packages/tui/internal/components/chat/message.go +++ b/packages/tui/internal/components/chat/message.go @@ -212,7 +212,7 @@ func renderText(message client.MessageInfo, text string, author string) string { func renderToolInvocation( toolCall client.MessageToolInvocationToolCall, result *string, - metadata map[string]any, + metadata client.MessageInfo_Metadata_Tool_AdditionalProperties, showResult bool, ) string { ignoredTools := []string{"opencode_todoread"} @@ -264,27 +264,26 @@ func renderToolInvocation( body = *result } - if metadata["error"] != nil && metadata["message"] != nil { - body = "" - error = styles.BaseStyle(). - Foreground(t.Error()). - Render(metadata["message"].(string)) - error = renderContentBlock(error, WithBorderColor(t.Error()), WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1)) + if e, ok := metadata.Get("error"); ok && e.(bool) == true { + if m, ok := metadata.Get("message"); ok { + body = "" // don't show the body if there's an error + error = styles.BaseStyle(). + Foreground(t.Error()). + Render(m.(string)) + error = renderContentBlock(error, WithBorderColor(t.Error()), WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1)) + } } elapsed := "" - if metadata["time"] != nil { - timeMap := metadata["time"].(map[string]any) - start := timeMap["start"].(float64) - end := timeMap["end"].(float64) - durationMs := end - start - duration := time.Duration(durationMs * float64(time.Millisecond)) - roundedDuration := time.Duration(duration.Round(time.Millisecond)) - if durationMs > 1000 { - roundedDuration = time.Duration(duration.Round(time.Second)) - } - elapsed = styles.Muted().Render(roundedDuration.String()) + start := metadata.Time.Start + end := metadata.Time.End + durationMs := end - start + duration := time.Duration(durationMs * float32(time.Millisecond)) + roundedDuration := time.Duration(duration.Round(time.Millisecond)) + if durationMs > 1000 { + roundedDuration = time.Duration(duration.Round(time.Second)) } + elapsed = styles.Muted().Render(roundedDuration.String()) title := "" switch toolCall.ToolName { @@ -292,16 +291,16 @@ func renderToolInvocation( toolArgs = renderArgs(&toolArgsMap, "filePath") title = fmt.Sprintf("Read: %s %s", toolArgs, elapsed) body = "" - if metadata["preview"] != nil && toolArgsMap["filePath"] != nil { + if preview, ok := metadata.Get("preview"); ok && toolArgsMap["filePath"] != nil { filename := toolArgsMap["filePath"].(string) - body = metadata["preview"].(string) + body = preview.(string) body = renderFile(filename, body, WithTruncate(6)) } case "opencode_edit": filename := toolArgsMap["filePath"].(string) title = fmt.Sprintf("Edit: %s %s", relative(filename), elapsed) - if metadata["diff"] != nil { - patch := metadata["diff"].(string) + if d, ok := metadata.Get("diff"); ok { + patch := d.(string) diffWidth := min(layout.Current.Viewport.Width, 120) formattedDiff, _ := diff.FormatDiff(filename, patch, diff.WithTotalWidth(diffWidth)) body = strings.TrimSpace(formattedDiff) @@ -322,9 +321,9 @@ func renderToolInvocation( case "opencode_bash": description := toolArgsMap["description"].(string) title = fmt.Sprintf("Shell: %s %s", description, elapsed) - if metadata["stdout"] != nil { + if stdout, ok := metadata.Get("stdout"); ok { command := toolArgsMap["command"].(string) - stdout := metadata["stdout"].(string) + stdout := stdout.(string) body = fmt.Sprintf("```console\n> %s\n%s```", command, stdout) body = toMarkdown(body, innerWidth, t.BackgroundSubtle()) body = renderContentBlock(body, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1)) @@ -339,9 +338,10 @@ func renderToolInvocation( body = renderContentBlock(body, WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1)) case "opencode_todowrite": title = fmt.Sprintf("Planning... %s", elapsed) - if finished && metadata["todos"] != nil { + + if to, ok := metadata.Get("todos"); ok && finished { body = "" - todos := metadata["todos"].([]any) + todos := to.([]any) for _, todo := range todos { t := todo.(map[string]any) content := t["content"].(string) diff --git a/packages/tui/internal/components/chat/messages.go b/packages/tui/internal/components/chat/messages.go index 3985ee0d..ef35a353 100644 --- a/packages/tui/internal/components/chat/messages.go +++ b/packages/tui/internal/components/chat/messages.go @@ -118,7 +118,6 @@ type blockType int const ( none blockType = iota - systemTextBlock userTextBlock assistantTextBlock toolInvocationBlock @@ -134,10 +133,6 @@ func (m *messagesComponent) renderView() { blocks := make([]string, 0) previousBlockType := none for _, message := range m.app.Messages { - if message.Role == client.System { - continue // ignoring system messages for now - } - var content string var cached bool @@ -174,15 +169,13 @@ func (m *messagesComponent) renderView() { previousBlockType = userTextBlock } else if message.Role == client.Assistant { previousBlockType = assistantTextBlock - } else if message.Role == client.System { - previousBlockType = systemTextBlock } case client.MessagePartToolInvocation: toolInvocationPart := part.(client.MessagePartToolInvocation) toolCall, _ := toolInvocationPart.ToolInvocation.AsMessageToolInvocationToolCall() - metadata := map[string]any{} + metadata := client.MessageInfo_Metadata_Tool_AdditionalProperties{} if _, ok := message.Metadata.Tool[toolCall.ToolCallId]; ok { - metadata = message.Metadata.Tool[toolCall.ToolCallId].(map[string]any) + metadata = message.Metadata.Tool[toolCall.ToolCallId] } var result *string resultPart, resultError := toolInvocationPart.ToolInvocation.AsMessageToolInvocationToolResult() @@ -215,14 +208,16 @@ func (m *messagesComponent) renderView() { } error := "" - errorValue, _ := message.Metadata.Error.ValueByDiscriminator() - switch errorValue.(type) { - case client.UnknownError: - clientError := errorValue.(client.UnknownError) - error = clientError.Data.Message - error = renderContentBlock(error, WithBorderColor(t.Error()), WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1)) - blocks = append(blocks, error) - previousBlockType = errorBlock + if message.Metadata.Error != nil { + errorValue, _ := message.Metadata.Error.ValueByDiscriminator() + switch errorValue.(type) { + case client.UnknownError: + clientError := errorValue.(client.UnknownError) + error = clientError.Data.Message + error = renderContentBlock(error, WithBorderColor(t.Error()), WithFullWidth(), WithPaddingTop(1), WithPaddingBottom(1)) + blocks = append(blocks, error) + previousBlockType = errorBlock + } } } diff --git a/packages/tui/internal/components/dialog/models.go b/packages/tui/internal/components/dialog/models.go index ca656150..ed2ab335 100644 --- a/packages/tui/internal/components/dialog/models.go +++ b/packages/tui/internal/components/dialog/models.go @@ -125,9 +125,9 @@ func (m *modelDialog) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil } -func (m *modelDialog) models() []client.ProviderModel { - models := slices.SortedFunc(maps.Values(m.provider.Models), func(a, b client.ProviderModel) int { - return strings.Compare(*a.Name, *b.Name) +func (m *modelDialog) models() []client.ModelInfo { + models := slices.SortedFunc(maps.Values(m.provider.Models), func(a, b client.ModelInfo) int { + return strings.Compare(a.Name, b.Name) }) return models } @@ -205,7 +205,7 @@ func (m *modelDialog) View() string { Foreground(t.BackgroundElement()). Bold(true) } - modelItems = append(modelItems, itemStyle.Render(*models[i].Name)) + modelItems = append(modelItems, itemStyle.Render(models[i].Name)) } scrollIndicator := m.getScrollIndicators(maxDialogWidth) diff --git a/packages/tui/internal/state/state.go b/packages/tui/internal/state/state.go index d2cbf039..c5322e7b 100644 --- a/packages/tui/internal/state/state.go +++ b/packages/tui/internal/state/state.go @@ -7,7 +7,7 @@ import ( type SessionSelectedMsg = *client.SessionInfo type ModelSelectedMsg struct { Provider client.ProviderInfo - Model client.ProviderModel + Model client.ModelInfo } type SessionClearedMsg struct{} @@ -17,5 +17,3 @@ type CompactSessionMsg struct{} type StateUpdatedMsg struct { State map[string]any } - -// TODO: store in CONFIG/tui.yaml diff --git a/packages/tui/pkg/client/gen/openapi.json b/packages/tui/pkg/client/gen/openapi.json index e8dfa9ee..c062192e 100644 --- a/packages/tui/pkg/client/gen/openapi.json +++ b/packages/tui/pkg/client/gen/openapi.json @@ -439,6 +439,45 @@ "parameters": [], "description": "List all providers" } + }, + "/file_search": { + "post": { + "responses": { + "200": { + "description": "Search for files", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "operationId": "postFile_search", + "parameters": [], + "description": "Search for files", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ] + } + } + } + } + } } }, "components": { @@ -618,7 +657,6 @@ "role": { "type": "string", "enum": [ - "system", "user", "assistant" ] @@ -668,17 +706,65 @@ }, "tool": { "type": "object", - "additionalProperties": {} + "additionalProperties": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "time": { + "type": "object", + "properties": { + "start": { + "type": "number" + }, + "end": { + "type": "number" + } + }, + "required": [ + "start", + "end" + ] + } + }, + "required": [ + "title", + "time" + ], + "additionalProperties": {} + } }, "assistant": { "type": "object", "properties": { + "system": { + "type": "array", + "items": { + "type": "string" + } + }, "modelID": { "type": "string" }, "providerID": { "type": "string" }, + "path": { + "type": "object", + "properties": { + "cwd": { + "type": "string" + }, + "root": { + "type": "string" + } + }, + "required": [ + "cwd", + "root" + ] + }, "cost": { "type": "number" }, @@ -706,8 +792,10 @@ } }, "required": [ + "system", "modelID", "providerID", + "path", "cost", "tokens" ] @@ -715,7 +803,6 @@ }, "required": [ "time", - "error", "sessionID", "tool" ] @@ -1036,10 +1123,18 @@ "properties": { "part": { "$ref": "#/components/schemas/Message.Part" + }, + "sessionID": { + "type": "string" + }, + "messageID": { + "type": "string" } }, "required": [ - "part" + "part", + "sessionID", + "messageID" ] } }, @@ -1079,6 +1174,10 @@ "type": "string", "pattern": "^ses" }, + "parentID": { + "type": "string", + "pattern": "^ses" + }, "share": { "type": "object", "properties": { @@ -1146,10 +1245,7 @@ } } } - }, - "required": [ - "error" - ] + } } }, "required": [ @@ -1220,31 +1316,35 @@ "Provider.Info": { "type": "object", "properties": { - "id": { + "name": { "type": "string" }, - "name": { + "env": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { "type": "string" }, "models": { "type": "object", "additionalProperties": { - "$ref": "#/components/schemas/Provider.Model" + "$ref": "#/components/schemas/Model.Info" } } }, "required": [ - "id", "name", + "env", + "id", "models" ] }, - "Provider.Model": { + "Model.Info": { "type": "object", "properties": { - "id": { - "type": "string" - }, "name": { "type": "string" }, @@ -1254,16 +1354,19 @@ "reasoning": { "type": "boolean" }, + "temperature": { + "type": "boolean" + }, "cost": { "type": "object", "properties": { "input": { "type": "number" }, - "inputCached": { + "output": { "type": "number" }, - "output": { + "inputCached": { "type": "number" }, "outputCached": { @@ -1272,8 +1375,8 @@ }, "required": [ "input", - "inputCached", "output", + "inputCached", "outputCached" ] }, @@ -1291,13 +1394,19 @@ "context", "output" ] + }, + "id": { + "type": "string" } }, "required": [ - "id", + "name", "attachment", + "reasoning", + "temperature", "cost", - "limit" + "limit", + "id" ] } } diff --git a/packages/tui/pkg/client/generated-client.go b/packages/tui/pkg/client/generated-client.go index 5e5a3441..4e8736d6 100644 --- a/packages/tui/pkg/client/generated-client.go +++ b/packages/tui/pkg/client/generated-client.go @@ -20,7 +20,6 @@ import ( // Defines values for MessageInfoRole. const ( Assistant MessageInfoRole = "assistant" - System MessageInfoRole = "system" User MessageInfoRole = "user" ) @@ -61,7 +60,9 @@ type EventLspClientDiagnostics struct { // EventMessagePartUpdated defines model for Event.message.part.updated. type EventMessagePartUpdated struct { Properties struct { - Part MessagePart `json:"part"` + MessageID string `json:"messageID"` + Part MessagePart `json:"part"` + SessionID string `json:"sessionID"` } `json:"properties"` Type string `json:"type"` } @@ -83,7 +84,7 @@ type EventPermissionUpdated struct { // EventSessionError defines model for Event.session.error. type EventSessionError struct { Properties struct { - Error EventSessionError_Properties_Error `json:"error"` + Error *EventSessionError_Properties_Error `json:"error,omitempty"` } `json:"properties"` Type string `json:"type"` } @@ -115,23 +116,28 @@ type MessageInfo struct { Id string `json:"id"` Metadata struct { Assistant *struct { - Cost float32 `json:"cost"` - ModelID string `json:"modelID"` - ProviderID string `json:"providerID"` - Summary *bool `json:"summary,omitempty"` + Cost float32 `json:"cost"` + ModelID string `json:"modelID"` + Path struct { + Cwd string `json:"cwd"` + Root string `json:"root"` + } `json:"path"` + ProviderID string `json:"providerID"` + Summary *bool `json:"summary,omitempty"` + System []string `json:"system"` Tokens struct { Input float32 `json:"input"` Output float32 `json:"output"` Reasoning float32 `json:"reasoning"` } `json:"tokens"` } `json:"assistant,omitempty"` - Error MessageInfo_Metadata_Error `json:"error"` - SessionID string `json:"sessionID"` + Error *MessageInfo_Metadata_Error `json:"error,omitempty"` + SessionID string `json:"sessionID"` Time struct { Completed *float32 `json:"completed,omitempty"` Created float32 `json:"created"` } `json:"time"` - Tool map[string]interface{} `json:"tool"` + Tool map[string]MessageInfo_Metadata_Tool_AdditionalProperties `json:"tool"` } `json:"metadata"` Parts []MessagePart `json:"parts"` Role MessageInfoRole `json:"role"` @@ -142,6 +148,16 @@ type MessageInfo_Metadata_Error struct { union json.RawMessage } +// MessageInfo_Metadata_Tool_AdditionalProperties defines model for MessageInfo.Metadata.Tool.AdditionalProperties. +type MessageInfo_Metadata_Tool_AdditionalProperties struct { + Time struct { + End float32 `json:"end"` + Start float32 `json:"start"` + } `json:"time"` + Title string `json:"title"` + AdditionalProperties map[string]interface{} `json:"-"` +} + // MessageInfoRole defines model for MessageInfo.Role. type MessageInfoRole string @@ -224,15 +240,8 @@ type MessageToolInvocationToolResult struct { ToolName string `json:"toolName"` } -// ProviderInfo defines model for Provider.Info. -type ProviderInfo struct { - Id string `json:"id"` - Models map[string]ProviderModel `json:"models"` - Name string `json:"name"` -} - -// ProviderModel defines model for Provider.Model. -type ProviderModel struct { +// ModelInfo defines model for Model.Info. +type ModelInfo struct { Attachment bool `json:"attachment"` Cost struct { Input float32 `json:"input"` @@ -245,8 +254,17 @@ type ProviderModel struct { Context float32 `json:"context"` Output float32 `json:"output"` } `json:"limit"` - Name *string `json:"name,omitempty"` - Reasoning *bool `json:"reasoning,omitempty"` + Name string `json:"name"` + Reasoning bool `json:"reasoning"` + Temperature bool `json:"temperature"` +} + +// ProviderInfo defines model for Provider.Info. +type ProviderInfo struct { + Env []string `json:"env"` + Id string `json:"id"` + Models map[string]ModelInfo `json:"models"` + Name string `json:"name"` } // ProviderAuthError defines model for ProviderAuthError. @@ -279,8 +297,9 @@ type PermissionInfo struct { // SessionInfo defines model for session.info. type SessionInfo struct { - Id string `json:"id"` - Share *struct { + Id string `json:"id"` + ParentID *string `json:"parentID,omitempty"` + Share *struct { Secret string `json:"secret"` Url string `json:"url"` } `json:"share,omitempty"` @@ -291,6 +310,11 @@ type SessionInfo struct { Title string `json:"title"` } +// PostFileSearchJSONBody defines parameters for PostFileSearch. +type PostFileSearchJSONBody struct { + Query string `json:"query"` +} + // PostSessionAbortJSONBody defines parameters for PostSessionAbort. type PostSessionAbortJSONBody struct { SessionID string `json:"sessionID"` @@ -328,6 +352,9 @@ type PostSessionSummarizeJSONBody struct { SessionID string `json:"sessionID"` } +// PostFileSearchJSONRequestBody defines body for PostFileSearch for application/json ContentType. +type PostFileSearchJSONRequestBody PostFileSearchJSONBody + // PostSessionAbortJSONRequestBody defines body for PostSessionAbort for application/json ContentType. type PostSessionAbortJSONRequestBody PostSessionAbortJSONBody @@ -346,6 +373,85 @@ type PostSessionShareJSONRequestBody PostSessionShareJSONBody // PostSessionSummarizeJSONRequestBody defines body for PostSessionSummarize for application/json ContentType. type PostSessionSummarizeJSONRequestBody PostSessionSummarizeJSONBody +// Getter for additional properties for MessageInfo_Metadata_Tool_AdditionalProperties. Returns the specified +// element and whether it was found +func (a MessageInfo_Metadata_Tool_AdditionalProperties) Get(fieldName string) (value interface{}, found bool) { + if a.AdditionalProperties != nil { + value, found = a.AdditionalProperties[fieldName] + } + return +} + +// Setter for additional properties for MessageInfo_Metadata_Tool_AdditionalProperties +func (a *MessageInfo_Metadata_Tool_AdditionalProperties) Set(fieldName string, value interface{}) { + if a.AdditionalProperties == nil { + a.AdditionalProperties = make(map[string]interface{}) + } + a.AdditionalProperties[fieldName] = value +} + +// Override default JSON handling for MessageInfo_Metadata_Tool_AdditionalProperties to handle AdditionalProperties +func (a *MessageInfo_Metadata_Tool_AdditionalProperties) UnmarshalJSON(b []byte) error { + object := make(map[string]json.RawMessage) + err := json.Unmarshal(b, &object) + if err != nil { + return err + } + + if raw, found := object["time"]; found { + err = json.Unmarshal(raw, &a.Time) + if err != nil { + return fmt.Errorf("error reading 'time': %w", err) + } + delete(object, "time") + } + + if raw, found := object["title"]; found { + err = json.Unmarshal(raw, &a.Title) + if err != nil { + return fmt.Errorf("error reading 'title': %w", err) + } + delete(object, "title") + } + + if len(object) != 0 { + a.AdditionalProperties = make(map[string]interface{}) + for fieldName, fieldBuf := range object { + var fieldVal interface{} + err := json.Unmarshal(fieldBuf, &fieldVal) + if err != nil { + return fmt.Errorf("error unmarshaling field %s: %w", fieldName, err) + } + a.AdditionalProperties[fieldName] = fieldVal + } + } + return nil +} + +// Override default JSON handling for MessageInfo_Metadata_Tool_AdditionalProperties to handle AdditionalProperties +func (a MessageInfo_Metadata_Tool_AdditionalProperties) MarshalJSON() ([]byte, error) { + var err error + object := make(map[string]json.RawMessage) + + object["time"], err = json.Marshal(a.Time) + if err != nil { + return nil, fmt.Errorf("error marshaling 'time': %w", err) + } + + object["title"], err = json.Marshal(a.Title) + if err != nil { + return nil, fmt.Errorf("error marshaling 'title': %w", err) + } + + for fieldName, field := range a.AdditionalProperties { + object[fieldName], err = json.Marshal(field) + if err != nil { + return nil, fmt.Errorf("error marshaling '%s': %w", fieldName, err) + } + } + return json.Marshal(object) +} + // AsEventStorageWrite returns the union data inside the Event as a EventStorageWrite func (t Event) AsEventStorageWrite() (EventStorageWrite, error) { var body EventStorageWrite @@ -1173,6 +1279,11 @@ type ClientInterface interface { // GetEvent request GetEvent(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) + // PostFileSearchWithBody request with any body + PostFileSearchWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + PostFileSearch(ctx context.Context, body PostFileSearchJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // PostPathGet request PostPathGet(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -1252,6 +1363,30 @@ func (c *Client) GetEvent(ctx context.Context, reqEditors ...RequestEditorFn) (* return c.Client.Do(req) } +func (c *Client) PostFileSearchWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostFileSearchRequestWithBody(c.Server, contentType, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + +func (c *Client) PostFileSearch(ctx context.Context, body PostFileSearchJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewPostFileSearchRequest(c.Server, body) + if err != nil { + return nil, err + } + req = req.WithContext(ctx) + if err := c.applyEditors(ctx, req, reqEditors); err != nil { + return nil, err + } + return c.Client.Do(req) +} + func (c *Client) PostPathGet(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { req, err := NewPostPathGetRequest(c.Server) if err != nil { @@ -1525,6 +1660,46 @@ func NewGetEventRequest(server string) (*http.Request, error) { return req, nil } +// NewPostFileSearchRequest calls the generic PostFileSearch builder with application/json body +func NewPostFileSearchRequest(server string, body PostFileSearchJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) + if err != nil { + return nil, err + } + bodyReader = bytes.NewReader(buf) + return NewPostFileSearchRequestWithBody(server, "application/json", bodyReader) +} + +// NewPostFileSearchRequestWithBody generates requests for PostFileSearch with any type of body +func NewPostFileSearchRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error + + serverURL, err := url.Parse(server) + if err != nil { + return nil, err + } + + operationPath := fmt.Sprintf("/file_search") + if operationPath[0] == '/' { + operationPath = "." + operationPath + } + + queryURL, err := serverURL.Parse(operationPath) + if err != nil { + return nil, err + } + + req, err := http.NewRequest("POST", queryURL.String(), body) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", contentType) + + return req, nil +} + // NewPostPathGetRequest generates requests for PostPathGet func NewPostPathGetRequest(server string) (*http.Request, error) { var err error @@ -1925,6 +2100,11 @@ type ClientWithResponsesInterface interface { // GetEventWithResponse request GetEventWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetEventResponse, error) + // PostFileSearchWithBodyWithResponse request with any body + PostFileSearchWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostFileSearchResponse, error) + + PostFileSearchWithResponse(ctx context.Context, body PostFileSearchJSONRequestBody, reqEditors ...RequestEditorFn) (*PostFileSearchResponse, error) + // PostPathGetWithResponse request PostPathGetWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*PostPathGetResponse, error) @@ -2034,6 +2214,28 @@ func (r GetEventResponse) StatusCode() int { return 0 } +type PostFileSearchResponse struct { + Body []byte + HTTPResponse *http.Response + JSON200 *[]string +} + +// Status returns HTTPResponse.Status +func (r PostFileSearchResponse) Status() string { + if r.HTTPResponse != nil { + return r.HTTPResponse.Status + } + return http.StatusText(0) +} + +// StatusCode returns HTTPResponse.StatusCode +func (r PostFileSearchResponse) StatusCode() int { + if r.HTTPResponse != nil { + return r.HTTPResponse.StatusCode + } + return 0 +} + type PostPathGetResponse struct { Body []byte HTTPResponse *http.Response @@ -2290,6 +2492,23 @@ func (c *ClientWithResponses) GetEventWithResponse(ctx context.Context, reqEdito return ParseGetEventResponse(rsp) } +// PostFileSearchWithBodyWithResponse request with arbitrary body returning *PostFileSearchResponse +func (c *ClientWithResponses) PostFileSearchWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostFileSearchResponse, error) { + rsp, err := c.PostFileSearchWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostFileSearchResponse(rsp) +} + +func (c *ClientWithResponses) PostFileSearchWithResponse(ctx context.Context, body PostFileSearchJSONRequestBody, reqEditors ...RequestEditorFn) (*PostFileSearchResponse, error) { + rsp, err := c.PostFileSearch(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParsePostFileSearchResponse(rsp) +} + // PostPathGetWithResponse request returning *PostPathGetResponse func (c *ClientWithResponses) PostPathGetWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*PostPathGetResponse, error) { rsp, err := c.PostPathGet(ctx, reqEditors...) @@ -2506,6 +2725,32 @@ func ParseGetEventResponse(rsp *http.Response) (*GetEventResponse, error) { return response, nil } +// ParsePostFileSearchResponse parses an HTTP response from a PostFileSearchWithResponse call +func ParsePostFileSearchResponse(rsp *http.Response) (*PostFileSearchResponse, error) { + bodyBytes, err := io.ReadAll(rsp.Body) + defer func() { _ = rsp.Body.Close() }() + if err != nil { + return nil, err + } + + response := &PostFileSearchResponse{ + Body: bodyBytes, + HTTPResponse: rsp, + } + + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest []string + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON200 = &dest + + } + + return response, nil +} + // ParsePostPathGetResponse parses an HTTP response from a PostPathGetWithResponse call func ParsePostPathGetResponse(rsp *http.Response) (*PostPathGetResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body)