summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-05-28 12:53:22 -0400
committerDax Raad <[email protected]>2025-05-28 12:53:22 -0400
commit55a6fcdd3f5b3c55712e5cfc9dd4d994da38d4c8 (patch)
treeaef660f4e7b0fae135dc1f90cf6920b53238ed5b
parent4132fcc1b286af5e61bf5eaa89f789988362f995 (diff)
downloadopencode-55a6fcdd3f5b3c55712e5cfc9dd4d994da38d4c8.tar.gz
opencode-55a6fcdd3f5b3c55712e5cfc9dd4d994da38d4c8.zip
add provider_list
-rw-r--r--js/bun.lock6
-rw-r--r--js/package.json2
-rw-r--r--js/src/app/config.ts35
-rw-r--r--js/src/bun/index.ts25
-rw-r--r--js/src/global/index.ts20
-rw-r--r--js/src/index.ts17
-rw-r--r--js/src/llm/llm.ts109
-rw-r--r--js/src/llm/models/anthropic.ts0
-rw-r--r--js/src/llm/models/index.ts1
-rw-r--r--js/src/llm/models/model.ts11
-rw-r--r--js/src/server/server.ts35
-rw-r--r--js/src/session/session.ts58
-rw-r--r--pkg/client/gen/openapi.json90
-rw-r--r--pkg/client/generated-client.go125
14 files changed, 458 insertions, 76 deletions
diff --git a/js/bun.lock b/js/bun.lock
index 971ed8b93..eda3a2994 100644
--- a/js/bun.lock
+++ b/js/bun.lock
@@ -12,9 +12,11 @@
"cac": "^6.7.14",
"clipanion": "^4.0.0-rc.4",
"diff": "^8.0.2",
+ "env-paths": "^3.0.0",
"hono": "^4.7.10",
"hono-openapi": "^0.4.8",
"jsdom": "^26.1.0",
+ "remeda": "^2.22.3",
"ts-lsp-client": "^1.0.3",
"turndown": "^7.2.0",
"vscode-jsonrpc": "^8.2.1",
@@ -170,6 +172,8 @@
"entities": ["[email protected]", "", {}, "sha512-aKstq2TDOndCn4diEyp9Uq/Flu2i1GlLkc6XIDQSDMuaFE3OPW5OphLCyQ5SpSJZTb4reN+kTcYru5yIfXoRPw=="],
+ "env-paths": ["[email protected]", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="],
+
"environment": ["[email protected]", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="],
"es-toolkit": ["[email protected]", "", {}, "sha512-OT3AxczYYd3W50bCj4V0hKoOAfqIy9tof0leNQYekEDxVKir3RTVTJOLij7VAe6fsCNsGhC0JqIkURpMXTCSEA=="],
@@ -290,6 +294,8 @@
"real-require": ["[email protected]", "", {}, "sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg=="],
+ "remeda": ["[email protected]", "", { "dependencies": { "type-fest": "^4.40.1" } }, "sha512-Ka6965m9Zu9OLsysWxVf3jdJKmp6+PKzDv7HWHinEevf0JOJ9y02YpjiC/sKxRpCqGhVyvm1U+0YIj+E6DMgKw=="],
+
"restore-cursor": ["[email protected]", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="],
"rfdc": ["[email protected]", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="],
diff --git a/js/package.json b/js/package.json
index 70d4f82a8..9cc015a7b 100644
--- a/js/package.json
+++ b/js/package.json
@@ -28,9 +28,11 @@
"cac": "^6.7.14",
"clipanion": "^4.0.0-rc.4",
"diff": "^8.0.2",
+ "env-paths": "^3.0.0",
"hono": "^4.7.10",
"hono-openapi": "^0.4.8",
"jsdom": "^26.1.0",
+ "remeda": "^2.22.3",
"ts-lsp-client": "^1.0.3",
"turndown": "^7.2.0",
"vscode-jsonrpc": "^8.2.1",
diff --git a/js/src/app/config.ts b/js/src/app/config.ts
index 947298c67..77a1f606f 100644
--- a/js/src/app/config.ts
+++ b/js/src/app/config.ts
@@ -1,25 +1,34 @@
import path from "node:path";
import { Log } from "../util/log";
import { z } from "zod";
+import { LLM } from "../llm/llm";
export namespace Config {
const log = Log.create({ service: "config" });
+ export const Model = z.object({
+ name: z.string().optional(),
+ cost: z.object({
+ input: z.number(),
+ inputCached: z.number(),
+ output: z.number(),
+ outputCached: z.number(),
+ }),
+ contextWindow: z.number(),
+ maxTokens: z.number(),
+ attachment: z.boolean(),
+ });
+ export type Model = z.output<typeof Model>;
+
+ export const Provider = z.object({
+ options: z.record(z.string(), z.any()).optional(),
+ models: z.record(z.string(), Model).optional(),
+ });
+ export type Provider = z.output<typeof Provider>;
+
export const Info = z
.object({
- providers: z
- .object({
- anthropic: z
- .object({
- apiKey: z.string().optional(),
- headers: z.record(z.string(), z.string()).optional(),
- baseURL: z.string().optional(),
- })
- .strict()
- .optional(),
- })
- .strict()
- .optional(),
+ providers: z.record(z.string(), Provider).optional(),
})
.strict();
diff --git a/js/src/bun/index.ts b/js/src/bun/index.ts
new file mode 100644
index 000000000..e921c825a
--- /dev/null
+++ b/js/src/bun/index.ts
@@ -0,0 +1,25 @@
+import path from "node:path";
+import { Log } from "../util/log";
+export namespace BunProc {
+ const log = Log.create({ service: "bun" });
+
+ export function run(
+ cmd: string[],
+ options?: Bun.SpawnOptions.OptionsObject<any, any, any>,
+ ) {
+ const root = path.resolve(process.cwd(), process.argv0);
+ log.info("running", {
+ cmd: [root, ...cmd],
+ options,
+ });
+ const result = Bun.spawnSync([root, ...cmd], {
+ ...options,
+ argv0: "bun",
+ env: {
+ ...process.env,
+ ...options?.env,
+ },
+ });
+ return result;
+ }
+}
diff --git a/js/src/global/index.ts b/js/src/global/index.ts
new file mode 100644
index 000000000..1e097f38c
--- /dev/null
+++ b/js/src/global/index.ts
@@ -0,0 +1,20 @@
+import envpaths from "env-paths";
+import fs from "fs/promises";
+const paths = envpaths("opencode", {
+ suffix: "",
+});
+
+await Promise.all([
+ fs.mkdir(paths.config, { recursive: true }),
+ fs.mkdir(paths.cache, { recursive: true }),
+]);
+
+export namespace Global {
+ export function config() {
+ return paths.config;
+ }
+
+ export function cache() {
+ return paths.cache;
+ }
+}
diff --git a/js/src/index.ts b/js/src/index.ts
index dc80206f7..3758ad718 100644
--- a/js/src/index.ts
+++ b/js/src/index.ts
@@ -7,6 +7,7 @@ import { Session } from "./session/session";
import cac from "cac";
import { Share } from "./share/share";
import { Storage } from "./storage/storage";
+import { LLM } from "./llm/llm";
const cli = cac("opencode");
@@ -90,9 +91,19 @@ cli
}
});
- const result = await Session.chat(session.id, {
- type: "text",
- text: message.join(" "),
+ const providers = await LLM.providers();
+ const providerID = Object.keys(providers)[0];
+ const modelID = Object.keys(providers[providerID].info.models!)[0];
+ const result = await Session.chat({
+ sessionID: session.id,
+ providerID,
+ modelID,
+ parts: [
+ {
+ type: "text",
+ text: message.join(" "),
+ },
+ ],
});
for (const part of result.parts) {
diff --git a/js/src/llm/llm.ts b/js/src/llm/llm.ts
index 5d962219c..c0ab38530 100644
--- a/js/src/llm/llm.ts
+++ b/js/src/llm/llm.ts
@@ -1,9 +1,13 @@
import { App } from "../app";
import { Log } from "../util/log";
+import { mergeDeep } from "remeda";
+import path from "node:path";
-import { createAnthropic } from "@ai-sdk/anthropic";
import type { LanguageModel, Provider } from "ai";
import { NoSuchModelError } from "ai";
+import type { Config } from "../app/config";
+import { BunProc } from "../bun";
+import { Global } from "../global";
export namespace LLM {
const log = Log.create({ service: "llm" });
@@ -14,17 +18,67 @@ export namespace LLM {
}
}
+ const NATIVE_PROVIDERS: Record<string, Config.Provider> = {
+ anthropic: {
+ models: {
+ "claude-sonnet-4-20250514": {
+ name: "Claude 4 Sonnet",
+ cost: {
+ input: 3.0,
+ inputCached: 3.75,
+ output: 15.0,
+ outputCached: 0.3,
+ },
+ contextWindow: 200000,
+ maxTokens: 50000,
+ attachment: true,
+ },
+ },
+ },
+ };
+
+ const AUTODETECT: Record<string, string[]> = {
+ anthropic: ["ANTHROPIC_API_KEY"],
+ };
+
const state = App.state("llm", async (app) => {
- const providers: Provider[] = [];
-
- if (process.env["ANTHROPIC_API_KEY"] || app.config.providers?.anthropic) {
- log.info("loaded anthropic");
- const provider = createAnthropic({
- apiKey: app.config.providers?.anthropic?.apiKey,
- baseURL: app.config.providers?.anthropic?.baseURL,
- headers: app.config.providers?.anthropic?.headers,
- });
- providers.push(provider);
+ const providers: Record<
+ string,
+ {
+ info: Config.Provider;
+ instance: Provider;
+ }
+ > = {};
+
+ const list = mergeDeep(NATIVE_PROVIDERS, app.config.providers ?? {});
+
+ for (const [providerID, providerInfo] of Object.entries(list)) {
+ if (
+ !app.config.providers?.[providerID] &&
+ !AUTODETECT[providerID]?.some((env) => process.env[env])
+ )
+ continue;
+ const dir = path.join(
+ Global.cache(),
+ `node_modules`,
+ `@ai-sdk`,
+ providerID,
+ );
+ if (!(await Bun.file(path.join(dir, "package.json")).exists())) {
+ BunProc.run(["add", "--exact", `@ai-sdk/${providerID}@alpha`], {
+ cwd: Global.cache(),
+ });
+ }
+ const mod = await import(
+ path.join(Global.cache(), `node_modules`, `@ai-sdk`, providerID)
+ );
+ const fn = mod[Object.keys(mod).find((key) => key.startsWith("create"))!];
+ const loaded = fn(providerInfo.options);
+ log.info("loaded", { provider: providerID });
+ providers[providerID] = {
+ info: providerInfo,
+ instance: loaded,
+ };
}
return {
@@ -37,23 +91,24 @@ export namespace LLM {
return state().then((state) => state.providers);
}
- export async function findModel(model: string) {
+ export async function findModel(providerID: string, modelID: string) {
+ const key = `${providerID}/${modelID}`;
const s = await state();
- if (s.models.has(model)) {
- return s.models.get(model)!;
- }
- log.info("loading", { model });
- for (const provider of s.providers) {
- try {
- const match = provider.languageModel(model);
- log.info("found", { model });
- s.models.set(model, match);
- return match;
- } catch (e) {
- if (e instanceof NoSuchModelError) continue;
- throw e;
- }
+ if (s.models.has(key)) return s.models.get(key)!;
+ const provider = s.providers[providerID];
+ if (!provider) throw new ModelNotFoundError(modelID);
+ log.info("loading", {
+ providerID,
+ modelID,
+ });
+ try {
+ const match = provider.instance.languageModel(modelID);
+ log.info("found", { providerID, modelID });
+ s.models.set(key, match);
+ return match;
+ } catch (e) {
+ if (e instanceof NoSuchModelError) throw new ModelNotFoundError(modelID);
+ throw e;
}
- throw new ModelNotFoundError(model);
}
}
diff --git a/js/src/llm/models/anthropic.ts b/js/src/llm/models/anthropic.ts
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/js/src/llm/models/anthropic.ts
diff --git a/js/src/llm/models/index.ts b/js/src/llm/models/index.ts
new file mode 100644
index 000000000..f974b4d3e
--- /dev/null
+++ b/js/src/llm/models/index.ts
@@ -0,0 +1 @@
+export * as anthropic from "./anthropic";
diff --git a/js/src/llm/models/model.ts b/js/src/llm/models/model.ts
new file mode 100644
index 000000000..e78dbb87f
--- /dev/null
+++ b/js/src/llm/models/model.ts
@@ -0,0 +1,11 @@
+export interface ModelInfo {
+ cost: {
+ input: number;
+ inputCached: number;
+ output: number;
+ outputCached: number;
+ };
+ contextWindow: number;
+ maxTokens: number;
+ attachment: boolean;
+}
diff --git a/js/src/server/server.ts b/js/src/server/server.ts
index 410463240..57f52a37c 100644
--- a/js/src/server/server.ts
+++ b/js/src/server/server.ts
@@ -7,11 +7,18 @@ import { Session } from "../session/session";
import { resolver, validator as zValidator } from "hono-openapi/zod";
import { z } from "zod";
import "zod-openapi/extend";
+import { Config } from "../app/config";
+import { LLM } from "../llm/llm";
const SessionInfo = Session.Info.openapi({
ref: "Session.Info",
});
+const ProviderInfo = Config.Provider.openapi({
+ ref: "Provider.Info",
+});
+type ProviderInfo = z.output<typeof ProviderInfo>;
+
export namespace Server {
const log = Log.create({ service: "server" });
const PORT = 16713;
@@ -156,14 +163,40 @@ export namespace Server {
"json",
z.object({
sessionID: z.string(),
+ providerID: z.string(),
+ modelID: z.string(),
parts: z.custom<Session.Message["parts"]>(),
}),
),
async (c) => {
const body = c.req.valid("json");
- const msg = await Session.chat(body.sessionID, ...body.parts);
+ const msg = await Session.chat(body);
return c.json(msg);
},
+ )
+ .post(
+ "/provider_list",
+ describeRoute({
+ description: "List all providers",
+ responses: {
+ 200: {
+ description: "List of providers",
+ content: {
+ "application/json": {
+ schema: resolver(z.record(z.string(), ProviderInfo)),
+ },
+ },
+ },
+ },
+ }),
+ async (c) => {
+ const providers = await LLM.providers();
+ const result: Record<string, ProviderInfo> = {};
+ for (const [providerID, provider] of Object.entries(providers)) {
+ result[providerID] = provider.info;
+ }
+ return c.json(result);
+ },
);
return result;
diff --git a/js/src/session/session.ts b/js/src/session/session.ts
index 7447f4916..06c51625f 100644
--- a/js/src/session/session.ts
+++ b/js/src/session/session.ts
@@ -127,19 +127,19 @@ export namespace Session {
}
}
- export async function chat(
- sessionID: string,
- ...parts: UIMessagePart<UIDataTypes>[]
- ) {
- const model = await LLM.findModel("claude-sonnet-4-20250514");
- const session = await get(sessionID);
- const l = log.clone().tag("session", sessionID);
+ export async function chat(input: {
+ sessionID: string;
+ providerID: string;
+ modelID: string;
+ parts: UIMessagePart<UIDataTypes>[];
+ }) {
+ const l = log.clone().tag("session", input.sessionID);
l.info("chatting");
-
- const msgs = await messages(sessionID);
+ const model = await LLM.findModel(input.providerID, input.modelID);
+ const msgs = await messages(input.sessionID);
async function write(msg: Message) {
return Storage.writeJSON(
- "session/message/" + sessionID + "/" + msg.id,
+ "session/message/" + input.sessionID + "/" + msg.id,
msg,
);
}
@@ -155,7 +155,7 @@ export namespace Session {
},
],
metadata: {
- sessionID,
+ sessionID: input.sessionID,
time: {
created: Date.now(),
},
@@ -171,7 +171,7 @@ export namespace Session {
});
}
msgs.push(system);
- state().messages.set(sessionID, msgs);
+ state().messages.set(input.sessionID, msgs);
generateText({
messages: convertToModelMessages([
{
@@ -185,12 +185,12 @@ export namespace Session {
},
{
role: "user",
- parts,
+ parts: input.parts,
},
]),
model,
}).then((result) => {
- return Session.update(sessionID, (draft) => {
+ return Session.update(input.sessionID, (draft) => {
draft.title = result.text;
});
});
@@ -199,21 +199,33 @@ export namespace Session {
const msg: Message = {
role: "user",
id: Identifier.ascending("message"),
- parts,
+ parts: input.parts,
metadata: {
time: {
created: Date.now(),
},
- sessionID,
+ sessionID: input.sessionID,
tool: {},
},
};
msgs.push(msg);
await write(msg);
+ const next: Message = {
+ id: Identifier.ascending("message"),
+ role: "assistant",
+ parts: [],
+ metadata: {
+ time: {
+ created: Date.now(),
+ },
+ sessionID: input.sessionID,
+ tool: {},
+ },
+ };
const result = streamText({
onStepFinish: (step) => {
- update(sessionID, (draft) => {
+ update(input.sessionID, (draft) => {
draft.tokens.input += step.usage.inputTokens || 0;
draft.tokens.output += step.usage.outputTokens || 0;
draft.tokens.reasoning += step.usage.reasoningTokens || 0;
@@ -225,18 +237,6 @@ export namespace Session {
tools,
model,
});
- const next: Message = {
- id: Identifier.ascending("message"),
- role: "assistant",
- parts: [],
- metadata: {
- time: {
- created: Date.now(),
- },
- sessionID,
- tool: {},
- },
- };
msgs.push(next);
let text: TextUIPart | undefined;
diff --git a/pkg/client/gen/openapi.json b/pkg/client/gen/openapi.json
index 478eb02ae..b7e40b7f9 100644
--- a/pkg/client/gen/openapi.json
+++ b/pkg/client/gen/openapi.json
@@ -167,16 +167,46 @@
"sessionID": {
"type": "string"
},
+ "providerID": {
+ "type": "string"
+ },
+ "modelID": {
+ "type": "string"
+ },
"parts": {}
},
"required": [
- "sessionID"
+ "sessionID",
+ "providerID",
+ "modelID"
]
}
}
}
}
}
+ },
+ "/provider_list": {
+ "post": {
+ "responses": {
+ "200": {
+ "description": "List of providers",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/Provider.Info"
+ }
+ }
+ }
+ }
+ }
+ },
+ "operationId": "postProvider_list",
+ "parameters": [],
+ "description": "List all providers"
+ }
}
},
"components": {
@@ -219,6 +249,64 @@
"title",
"tokens"
]
+ },
+ "Provider.Info": {
+ "type": "object",
+ "properties": {
+ "options": {
+ "type": "object",
+ "additionalProperties": {}
+ },
+ "models": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "cost": {
+ "type": "object",
+ "properties": {
+ "input": {
+ "type": "number"
+ },
+ "inputCached": {
+ "type": "number"
+ },
+ "output": {
+ "type": "number"
+ },
+ "outputCached": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "input",
+ "inputCached",
+ "output",
+ "outputCached"
+ ]
+ },
+ "contextWindow": {
+ "type": "number"
+ },
+ "maxTokens": {
+ "type": "number"
+ },
+ "attachment": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "cost",
+ "contextWindow",
+ "maxTokens",
+ "attachment"
+ ]
+ }
+ }
+ }
}
}
}
diff --git a/pkg/client/generated-client.go b/pkg/client/generated-client.go
index 46fb60205..89d6a9273 100644
--- a/pkg/client/generated-client.go
+++ b/pkg/client/generated-client.go
@@ -14,6 +14,23 @@ import (
"strings"
)
+// ProviderInfo defines model for Provider.Info.
+type ProviderInfo struct {
+ Models *map[string]struct {
+ Attachment bool `json:"attachment"`
+ ContextWindow float32 `json:"contextWindow"`
+ Cost struct {
+ Input float32 `json:"input"`
+ InputCached float32 `json:"inputCached"`
+ Output float32 `json:"output"`
+ OutputCached float32 `json:"outputCached"`
+ } `json:"cost"`
+ MaxTokens float32 `json:"maxTokens"`
+ Name *string `json:"name,omitempty"`
+ } `json:"models,omitempty"`
+ Options *map[string]interface{} `json:"options,omitempty"`
+}
+
// SessionInfo defines model for Session.Info.
type SessionInfo struct {
Id string `json:"id"`
@@ -28,8 +45,10 @@ type SessionInfo struct {
// PostSessionChatJSONBody defines parameters for PostSessionChat.
type PostSessionChatJSONBody struct {
- Parts *interface{} `json:"parts,omitempty"`
- SessionID string `json:"sessionID"`
+ ModelID string `json:"modelID"`
+ Parts *interface{} `json:"parts,omitempty"`
+ ProviderID string `json:"providerID"`
+ SessionID string `json:"sessionID"`
}
// PostSessionMessagesJSONBody defines parameters for PostSessionMessages.
@@ -124,6 +143,9 @@ func WithRequestEditorFn(fn RequestEditorFn) ClientOption {
// The interface specification for the client above.
type ClientInterface interface {
+ // PostProviderList request
+ PostProviderList(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error)
+
// PostSessionChatWithBody request with any body
PostSessionChatWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error)
@@ -146,6 +168,18 @@ type ClientInterface interface {
PostSessionShare(ctx context.Context, body PostSessionShareJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error)
}
+func (c *Client) PostProviderList(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) {
+ req, err := NewPostProviderListRequest(c.Server)
+ 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) PostSessionChatWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) {
req, err := NewPostSessionChatRequestWithBody(c.Server, contentType, body)
if err != nil {
@@ -242,6 +276,33 @@ func (c *Client) PostSessionShare(ctx context.Context, body PostSessionShareJSON
return c.Client.Do(req)
}
+// NewPostProviderListRequest generates requests for PostProviderList
+func NewPostProviderListRequest(server string) (*http.Request, error) {
+ var err error
+
+ serverURL, err := url.Parse(server)
+ if err != nil {
+ return nil, err
+ }
+
+ operationPath := fmt.Sprintf("/provider_list")
+ if operationPath[0] == '/' {
+ operationPath = "." + operationPath
+ }
+
+ queryURL, err := serverURL.Parse(operationPath)
+ if err != nil {
+ return nil, err
+ }
+
+ req, err := http.NewRequest("POST", queryURL.String(), nil)
+ if err != nil {
+ return nil, err
+ }
+
+ return req, nil
+}
+
// NewPostSessionChatRequest calls the generic PostSessionChat builder with application/json body
func NewPostSessionChatRequest(server string, body PostSessionChatJSONRequestBody) (*http.Request, error) {
var bodyReader io.Reader
@@ -459,6 +520,9 @@ func WithBaseURL(baseURL string) ClientOption {
// ClientWithResponsesInterface is the interface specification for the client with responses above.
type ClientWithResponsesInterface interface {
+ // PostProviderListWithResponse request
+ PostProviderListWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*PostProviderListResponse, error)
+
// PostSessionChatWithBodyWithResponse request with any body
PostSessionChatWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostSessionChatResponse, error)
@@ -481,6 +545,28 @@ type ClientWithResponsesInterface interface {
PostSessionShareWithResponse(ctx context.Context, body PostSessionShareJSONRequestBody, reqEditors ...RequestEditorFn) (*PostSessionShareResponse, error)
}
+type PostProviderListResponse struct {
+ Body []byte
+ HTTPResponse *http.Response
+ JSON200 *map[string]ProviderInfo
+}
+
+// Status returns HTTPResponse.Status
+func (r PostProviderListResponse) Status() string {
+ if r.HTTPResponse != nil {
+ return r.HTTPResponse.Status
+ }
+ return http.StatusText(0)
+}
+
+// StatusCode returns HTTPResponse.StatusCode
+func (r PostProviderListResponse) StatusCode() int {
+ if r.HTTPResponse != nil {
+ return r.HTTPResponse.StatusCode
+ }
+ return 0
+}
+
type PostSessionChatResponse struct {
Body []byte
HTTPResponse *http.Response
@@ -599,6 +685,15 @@ func (r PostSessionShareResponse) StatusCode() int {
return 0
}
+// PostProviderListWithResponse request returning *PostProviderListResponse
+func (c *ClientWithResponses) PostProviderListWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*PostProviderListResponse, error) {
+ rsp, err := c.PostProviderList(ctx, reqEditors...)
+ if err != nil {
+ return nil, err
+ }
+ return ParsePostProviderListResponse(rsp)
+}
+
// PostSessionChatWithBodyWithResponse request with arbitrary body returning *PostSessionChatResponse
func (c *ClientWithResponses) PostSessionChatWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*PostSessionChatResponse, error) {
rsp, err := c.PostSessionChatWithBody(ctx, contentType, body, reqEditors...)
@@ -668,6 +763,32 @@ func (c *ClientWithResponses) PostSessionShareWithResponse(ctx context.Context,
return ParsePostSessionShareResponse(rsp)
}
+// ParsePostProviderListResponse parses an HTTP response from a PostProviderListWithResponse call
+func ParsePostProviderListResponse(rsp *http.Response) (*PostProviderListResponse, error) {
+ bodyBytes, err := io.ReadAll(rsp.Body)
+ defer func() { _ = rsp.Body.Close() }()
+ if err != nil {
+ return nil, err
+ }
+
+ response := &PostProviderListResponse{
+ Body: bodyBytes,
+ HTTPResponse: rsp,
+ }
+
+ switch {
+ case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200:
+ var dest map[string]ProviderInfo
+ if err := json.Unmarshal(bodyBytes, &dest); err != nil {
+ return nil, err
+ }
+ response.JSON200 = &dest
+
+ }
+
+ return response, nil
+}
+
// ParsePostSessionChatResponse parses an HTTP response from a PostSessionChatWithResponse call
func ParsePostSessionChatResponse(rsp *http.Response) (*PostSessionChatResponse, error) {
bodyBytes, err := io.ReadAll(rsp.Body)