chore: generate

This commit is contained in:
opencode-agent[bot]
2026-05-21 00:55:10 +00:00
parent 8643c0721e
commit 93131b6e4c
15 changed files with 344 additions and 43 deletions
+18 -16
View File
@@ -132,9 +132,14 @@ export const layer = Layer.effect(
} }
const clone = (input: HashMap.HashMap<ProviderV2.ID, ProviderRecord>) => const clone = (input: HashMap.HashMap<ProviderV2.ID, ProviderRecord>) =>
HashMap.fromIterable(HashMap.toEntries(input).map(([key, value]) => [key, { ...value, models: new Map(value.models) }] as const)) HashMap.fromIterable(
HashMap.toEntries(input).map(([key, value]) => [key, { ...value, models: new Map(value.models) }] as const),
)
const context = (draft: { records: HashMap.HashMap<ProviderV2.ID, ProviderRecord>; data: ProviderRecord[] }): Context => { const context = (draft: {
records: HashMap.HashMap<ProviderV2.ID, ProviderRecord>
data: ProviderRecord[]
}): Context => {
const result: Context = { const result: Context = {
data: draft.data, data: draft.data,
updateProvider: (providerID, fn) => result.provider.update(providerID, fn), updateProvider: (providerID, fn) => result.provider.update(providerID, fn),
@@ -164,13 +169,10 @@ export const layer = Layer.effect(
model: { model: {
update: (providerID, modelID, fn) => { update: (providerID, modelID, fn) => {
const current = Option.getOrThrow(HashMap.get(draft.records, providerID)) const current = Option.getOrThrow(HashMap.get(draft.records, providerID))
const model = produce( const model = produce(current.models.get(modelID) ?? ModelV2.Info.empty(providerID, modelID), (draft) => {
current.models.get(modelID) ?? ModelV2.Info.empty(providerID, modelID), fn(draft)
(draft) => { normalizeEndpoint(draft)
fn(draft) })
normalizeEndpoint(draft)
},
)
const next = { const next = {
provider: current.provider, provider: current.provider,
models: new Map(current.models).set(modelID, new ModelV2.Info({ ...model, id: modelID, providerID })), models: new Map(current.models).set(modelID, new ModelV2.Info({ ...model, id: modelID, providerID })),
@@ -226,9 +228,12 @@ export const layer = Layer.effect(
const loader = { update: (_ctx: Context) => {} } const loader = { update: (_ctx: Context) => {} }
loaders = [...loaders, loader] loaders = [...loaders, loader]
const scope = yield* Scope.Scope const scope = yield* Scope.Scope
yield* Scope.addFinalizer(scope, Effect.sync(() => { yield* Scope.addFinalizer(
loaders = loaders.filter((item) => item !== loader) scope,
}).pipe(Effect.andThen(rebuild()))) Effect.sync(() => {
loaders = loaders.filter((item) => item !== loader)
}).pipe(Effect.andThen(rebuild())),
)
return Effect.fnUntraced(function* (update) { return Effect.fnUntraced(function* (update) {
loader.update = update loader.update = update
yield* rebuild() yield* rebuild()
@@ -349,7 +354,4 @@ export const layer = Layer.effect(
const SMALL_MODEL_RE = /\b(nano|flash|lite|mini|haiku|small|fast)\b/ const SMALL_MODEL_RE = /\b(nano|flash|lite|mini|haiku|small|fast)\b/
export const defaultLayer = layer.pipe( export const defaultLayer = layer.pipe(Layer.provide(EventV2.defaultLayer), Layer.provide(PluginV2.defaultLayer))
Layer.provide(EventV2.defaultLayer),
Layer.provide(PluginV2.defaultLayer),
)
@@ -10,8 +10,8 @@ export const AnthropicPlugin = PluginV2.define({
if (item.provider.endpoint.type !== "aisdk") continue if (item.provider.endpoint.type !== "aisdk") continue
if (item.provider.endpoint.package !== "@ai-sdk/anthropic") continue if (item.provider.endpoint.package !== "@ai-sdk/anthropic") continue
evt.provider.update(item.provider.id, (provider) => { evt.provider.update(item.provider.id, (provider) => {
provider.options.headers["anthropic-beta"] = provider.options.headers["anthropic-beta"] =
"interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14" "interleaved-thinking-2025-05-14,fine-grained-tool-streaming-2025-05-14"
}) })
} }
}), }),
@@ -60,7 +60,11 @@ export const GoogleVertexPlugin = PluginV2.define({
"catalog.transform": Effect.fn(function* (evt) { "catalog.transform": Effect.fn(function* (evt) {
for (const item of evt.data) { for (const item of evt.data) {
if (item.provider.endpoint.type !== "aisdk") continue if (item.provider.endpoint.type !== "aisdk") continue
if (item.provider.endpoint.package !== "@ai-sdk/google-vertex" && !item.provider.endpoint.package.includes("@ai-sdk/openai-compatible")) continue if (
item.provider.endpoint.package !== "@ai-sdk/google-vertex" &&
!item.provider.endpoint.package.includes("@ai-sdk/openai-compatible")
)
continue
const project = resolveProject(item.provider.options.aisdk.provider) const project = resolveProject(item.provider.options.aisdk.provider)
const location = String(resolveLocation(item.provider.options.aisdk.provider)) const location = String(resolveLocation(item.provider.options.aisdk.provider))
evt.provider.update(item.provider.id, (provider) => { evt.provider.update(item.provider.id, (provider) => {
+3 -3
View File
@@ -11,9 +11,9 @@ export const NvidiaPlugin = PluginV2.define({
if (item.provider.endpoint.package !== "@ai-sdk/openai-compatible") continue if (item.provider.endpoint.package !== "@ai-sdk/openai-compatible") continue
if (item.provider.endpoint.url !== "https://integrate.api.nvidia.com/v1") continue if (item.provider.endpoint.url !== "https://integrate.api.nvidia.com/v1") continue
evt.provider.update(item.provider.id, (provider) => { evt.provider.update(item.provider.id, (provider) => {
provider.options.headers["HTTP-Referer"] = "https://opencode.ai/" provider.options.headers["HTTP-Referer"] = "https://opencode.ai/"
provider.options.headers["X-Title"] = "opencode" provider.options.headers["X-Title"] = "opencode"
provider.options.headers["X-BILLING-INVOKE-ORIGIN"] ??= "OpenCode" provider.options.headers["X-BILLING-INVOKE-ORIGIN"] ??= "OpenCode"
}) })
} }
}), }),
+35 -8
View File
@@ -26,7 +26,11 @@ describe("CatalogV2", () => {
yield* load((catalog) => yield* load((catalog) =>
catalog.provider.update(providerID, (provider) => { catalog.provider.update(providerID, (provider) => {
provider.endpoint = { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://default.example.com" } provider.endpoint = {
type: "aisdk",
package: "@ai-sdk/openai-compatible",
url: "https://default.example.com",
}
provider.options.aisdk.provider.baseURL = "https://override.example.com" provider.options.aisdk.provider.baseURL = "https://override.example.com"
}), }),
) )
@@ -48,7 +52,11 @@ describe("CatalogV2", () => {
yield* load((catalog) => { yield* load((catalog) => {
catalog.provider.update(providerID, (provider) => { catalog.provider.update(providerID, (provider) => {
provider.endpoint = { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://provider.example.com" } provider.endpoint = {
type: "aisdk",
package: "@ai-sdk/openai-compatible",
url: "https://provider.example.com",
}
}) })
catalog.model.update(providerID, modelID, (model) => { catalog.model.update(providerID, modelID, (model) => {
model.endpoint = { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://model.example.com" } model.endpoint = { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://model.example.com" }
@@ -73,7 +81,11 @@ describe("CatalogV2", () => {
yield* load((catalog) => { yield* load((catalog) => {
catalog.provider.update(providerID, (provider) => { catalog.provider.update(providerID, (provider) => {
provider.endpoint = { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://provider.example.com" } provider.endpoint = {
type: "aisdk",
package: "@ai-sdk/openai-compatible",
url: "https://provider.example.com",
}
}) })
catalog.model.update(providerID, modelID, () => {}) catalog.model.update(providerID, modelID, () => {})
}) })
@@ -125,11 +137,20 @@ describe("CatalogV2", () => {
const providerID = ProviderV2.ID.make("test") const providerID = ProviderV2.ID.make("test")
const load = yield* catalog.loader() const load = yield* catalog.loader()
yield* load((catalog) => catalog.provider.update(providerID, (provider) => { provider.name = "Before" })) yield* load((catalog) =>
catalog.provider.update(providerID, (provider) => {
provider.name = "Before"
}),
)
yield* plugin.add({ yield* plugin.add({
id: PluginV2.ID.make("test-transform"), id: PluginV2.ID.make("test-transform"),
effect: Effect.succeed({ effect: Effect.succeed({
"catalog.transform": (evt) => Effect.sync(() => evt.provider.update(providerID, (provider) => { provider.name = "After" })), "catalog.transform": (evt) =>
Effect.sync(() =>
evt.provider.update(providerID, (provider) => {
provider.name = "After"
}),
),
}), }),
}) })
yield* Effect.yieldNow yield* Effect.yieldNow
@@ -176,9 +197,15 @@ describe("CatalogV2", () => {
const load = yield* catalog.loader() const load = yield* catalog.loader()
yield* load((catalog) => { yield* load((catalog) => {
catalog.provider.update(providerID, (provider) => { provider.enabled = { via: "custom", data: {} } }) catalog.provider.update(providerID, (provider) => {
catalog.model.update(providerID, ModelV2.ID.make("old"), (model) => { model.time.released = DateTime.makeUnsafe(1000) }) provider.enabled = { via: "custom", data: {} }
catalog.model.update(providerID, ModelV2.ID.make("new"), (model) => { model.time.released = DateTime.makeUnsafe(2000) }) })
catalog.model.update(providerID, ModelV2.ID.make("old"), (model) => {
model.time.released = DateTime.makeUnsafe(1000)
})
catalog.model.update(providerID, ModelV2.ID.make("new"), (model) => {
model.time.released = DateTime.makeUnsafe(2000)
})
}) })
expect(Option.getOrUndefined(yield* catalog.model.default())?.id).toMatch("new") expect(Option.getOrUndefined(yield* catalog.model.default())?.id).toMatch("new")
@@ -31,7 +31,10 @@ describe("CerebrasPlugin", () => {
item.options.headers.Existing = "1" item.options.headers.Existing = "1"
}) })
}) })
expect((yield* catalog.provider.get(ProviderV2.ID.make("cerebras"))).options.headers).toEqual({ Existing: "1", "X-Cerebras-3rd-Party-Integration": "opencode" }) expect((yield* catalog.provider.get(ProviderV2.ID.make("cerebras"))).options.headers).toEqual({
Existing: "1",
"X-Cerebras-3rd-Party-Integration": "opencode",
})
}), }),
) )
@@ -157,7 +157,9 @@ describe("GithubCopilotPlugin", () => {
catalog.provider.update(ProviderV2.ID.make("github-copilot"), () => {}) catalog.provider.update(ProviderV2.ID.make("github-copilot"), () => {})
catalog.model.update(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5-chat-latest"), () => {}) catalog.model.update(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5-chat-latest"), () => {})
}) })
expect((yield* catalog.model.get(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5-chat-latest"))).enabled).toBe(false) expect(
(yield* catalog.model.get(ProviderV2.ID.make("github-copilot"), ModelV2.ID.make("gpt-5-chat-latest"))).enabled,
).toBe(false)
}), }),
) )
@@ -171,7 +173,9 @@ describe("GithubCopilotPlugin", () => {
catalog.provider.update(ProviderV2.ID.make("custom-copilot"), () => {}) catalog.provider.update(ProviderV2.ID.make("custom-copilot"), () => {})
catalog.model.update(ProviderV2.ID.make("custom-copilot"), ModelV2.ID.make("gpt-5-chat-latest"), () => {}) catalog.model.update(ProviderV2.ID.make("custom-copilot"), ModelV2.ID.make("gpt-5-chat-latest"), () => {})
}) })
expect((yield* catalog.model.get(ProviderV2.ID.make("custom-copilot"), ModelV2.ID.make("gpt-5-chat-latest"))).enabled).toBe(true) expect(
(yield* catalog.model.get(ProviderV2.ID.make("custom-copilot"), ModelV2.ID.make("gpt-5-chat-latest"))).enabled,
).toBe(true)
}), }),
) )
@@ -50,7 +50,9 @@ describe("KiloPlugin", () => {
yield* plugin.add(KiloPlugin) yield* plugin.add(KiloPlugin)
const load = yield* catalog.loader() const load = yield* catalog.loader()
yield* load((catalog) => { yield* load((catalog) => {
const item = provider("kilo", { endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.kilo.ai/api/gateway" } }) const item = provider("kilo", {
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.kilo.ai/api/gateway" },
})
catalog.provider.update(item.id, (draft) => { catalog.provider.update(item.id, (draft) => {
draft.endpoint = item.endpoint draft.endpoint = item.endpoint
}) })
@@ -58,7 +58,9 @@ describe("LLMGatewayPlugin", () => {
yield* plugin.add(LLMGatewayPlugin) yield* plugin.add(LLMGatewayPlugin)
const load = yield* catalog.loader() const load = yield* catalog.loader()
yield* load((catalog) => { yield* load((catalog) => {
const item = provider("llmgateway", { endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.llmgateway.io/v1" } }) const item = provider("llmgateway", {
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://api.llmgateway.io/v1" },
})
catalog.provider.update(item.id, (draft) => { catalog.provider.update(item.id, (draft) => {
draft.endpoint = item.endpoint draft.endpoint = item.endpoint
}) })
@@ -102,7 +102,9 @@ describe("OpenAIPlugin", () => {
catalog.provider.update(item.id, () => {}) catalog.provider.update(item.id, () => {})
catalog.model.update(item.id, ModelV2.ID.make("gpt-5-chat-latest"), () => {}) catalog.model.update(item.id, ModelV2.ID.make("gpt-5-chat-latest"), () => {})
}) })
expect((yield* catalog.model.get(ProviderV2.ID.make("custom-openai"), ModelV2.ID.make("gpt-5-chat-latest"))).enabled).toBe(true) expect(
(yield* catalog.model.get(ProviderV2.ID.make("custom-openai"), ModelV2.ID.make("gpt-5-chat-latest"))).enabled,
).toBe(true)
}), }),
) )
}) })
@@ -77,7 +77,9 @@ describe("OpenRouterPlugin", () => {
yield* plugin.add(OpenRouterPlugin) yield* plugin.add(OpenRouterPlugin)
const load = yield* catalog.loader() const load = yield* catalog.loader()
yield* load((catalog) => { yield* load((catalog) => {
const openrouter = provider("openrouter", { endpoint: { type: "aisdk", package: "@openrouter/ai-sdk-provider" } }) const openrouter = provider("openrouter", {
endpoint: { type: "aisdk", package: "@openrouter/ai-sdk-provider" },
})
catalog.provider.update(openrouter.id, (item) => { catalog.provider.update(openrouter.id, (item) => {
item.endpoint = openrouter.endpoint item.endpoint = openrouter.endpoint
}) })
@@ -91,8 +93,12 @@ describe("OpenRouterPlugin", () => {
} }
}) })
expect((yield* catalog.model.get(ProviderV2.ID.make("openrouter"), ModelV2.ID.make("openai/gpt-5-chat"))).enabled).toBe(false) expect(
expect((yield* catalog.model.get(ProviderV2.ID.make("openrouter"), ModelV2.ID.make("openai/gpt-5"))).enabled).toBe(true) (yield* catalog.model.get(ProviderV2.ID.make("openrouter"), ModelV2.ID.make("openai/gpt-5-chat"))).enabled,
).toBe(false)
expect(
(yield* catalog.model.get(ProviderV2.ID.make("openrouter"), ModelV2.ID.make("openai/gpt-5"))).enabled,
).toBe(true)
expect((yield* catalog.model.get(ProviderV2.ID.openai, ModelV2.ID.make("openai/gpt-5-chat"))).enabled).toBe(true) expect((yield* catalog.model.get(ProviderV2.ID.openai, ModelV2.ID.make("openai/gpt-5-chat"))).enabled).toBe(true)
}), }),
) )
@@ -108,7 +114,8 @@ describe("OpenRouterPlugin", () => {
catalog.model.update(ProviderV2.ID.make("custom-openrouter"), ModelV2.ID.make("gpt-5-chat-latest"), () => {}) catalog.model.update(ProviderV2.ID.make("custom-openrouter"), ModelV2.ID.make("gpt-5-chat-latest"), () => {})
}) })
expect( expect(
(yield* catalog.model.get(ProviderV2.ID.make("custom-openrouter"), ModelV2.ID.make("gpt-5-chat-latest"))).enabled, (yield* catalog.model.get(ProviderV2.ID.make("custom-openrouter"), ModelV2.ID.make("gpt-5-chat-latest")))
.enabled,
).toBe(true) ).toBe(true)
}), }),
) )
@@ -43,7 +43,9 @@ describe("VercelPlugin", () => {
draft.endpoint = item.endpoint draft.endpoint = item.endpoint
}) })
}) })
expect((yield* catalog.provider.get(ProviderV2.ID.make("vercel"))).options.headers).not.toHaveProperty("HTTP-Referer") expect((yield* catalog.provider.get(ProviderV2.ID.make("vercel"))).options.headers).not.toHaveProperty(
"HTTP-Referer",
)
expect((yield* catalog.provider.get(ProviderV2.ID.make("vercel"))).options.headers).not.toHaveProperty("X-Title") expect((yield* catalog.provider.get(ProviderV2.ID.make("vercel"))).options.headers).not.toHaveProperty("X-Title")
}), }),
) )
@@ -24,7 +24,9 @@ describe("ZenmuxPlugin", () => {
yield* plugin.add(ZenmuxPlugin) yield* plugin.add(ZenmuxPlugin)
const load = yield* catalog.loader() const load = yield* catalog.loader()
yield* load((catalog) => { yield* load((catalog) => {
const item = provider("zenmux", { endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" } }) const item = provider("zenmux", {
endpoint: { type: "aisdk", package: "@ai-sdk/openai-compatible", url: "https://zenmux.ai/api/v1" },
})
catalog.provider.update(item.id, (draft) => { catalog.provider.update(item.id, (draft) => {
draft.endpoint = item.endpoint draft.endpoint = item.endpoint
}) })
+63
View File
@@ -78,6 +78,10 @@ export type Event =
| EventSessionNextCompactionDelta | EventSessionNextCompactionDelta
| EventSessionNextCompactionEnded | EventSessionNextCompactionEnded
| EventCatalogModelUpdated | EventCatalogModelUpdated
| EventModelsDevRefreshed
| EventAccountAdded
| EventAccountRemoved
| EventAccountSwitched
export type OAuth = { export type OAuth = {
type: "oauth" type: "oauth"
@@ -874,6 +878,7 @@ export type GlobalEvent = {
| EventSessionNextCompactionDelta | EventSessionNextCompactionDelta
| EventSessionNextCompactionEnded | EventSessionNextCompactionEnded
| EventCatalogModelUpdated | EventCatalogModelUpdated
| EventModelsDevRefreshed
| SyncEventMessageUpdated | SyncEventMessageUpdated
| SyncEventMessageRemoved | SyncEventMessageRemoved
| SyncEventMessagePartUpdated | SyncEventMessagePartUpdated
@@ -3284,6 +3289,14 @@ export type EventCatalogModelUpdated = {
} }
} }
export type EventModelsDevRefreshed = {
id: string
type: "models-dev.refreshed"
properties: {
[key: string]: unknown
}
}
export type SessionInfo = { export type SessionInfo = {
id: string id: string
parentID?: string parentID?: string
@@ -3695,6 +3708,56 @@ export type ModelV2Info1 = {
} }
} }
export type AccountV2oAuthCredential = {
type: "oauth"
refresh: string
access: string
expires: number
}
export type AccountV2ApiKeyCredential = {
type: "api"
key: string
metadata?: {
[key: string]: string
}
}
export type AccountV2Credential = AccountV2oAuthCredential | AccountV2ApiKeyCredential
export type AccountV2Info = {
id: string
serviceID: string
description: string
credential: AccountV2Credential
}
export type EventAccountAdded = {
id: string
type: "account.added"
properties: {
account: AccountV2Info
}
}
export type EventAccountRemoved = {
id: string
type: "account.removed"
properties: {
account: AccountV2Info
}
}
export type EventAccountSwitched = {
id: string
type: "account.switched"
properties: {
serviceID: string
from?: string
to?: string
}
}
export type BadRequestError = { export type BadRequestError = {
name: "BadRequest" name: "BadRequest"
data: { data: {
+182 -1
View File
@@ -10567,6 +10567,18 @@
}, },
{ {
"$ref": "#/components/schemas/EventSessionNextCompactionEnded" "$ref": "#/components/schemas/EventSessionNextCompactionEnded"
},
{
"$ref": "#/components/schemas/EventModels-devRefreshed"
},
{
"$ref": "#/components/schemas/EventAccountAdded"
},
{
"$ref": "#/components/schemas/EventAccountRemoved"
},
{
"$ref": "#/components/schemas/EventAccountSwitched"
} }
] ]
}, },
@@ -12979,6 +12991,9 @@
{ {
"$ref": "#/components/schemas/EventSessionNextCompactionEnded" "$ref": "#/components/schemas/EventSessionNextCompactionEnded"
}, },
{
"$ref": "#/components/schemas/EventModels-devRefreshed"
},
{ {
"$ref": "#/components/schemas/SyncEventMessageUpdated" "$ref": "#/components/schemas/SyncEventMessageUpdated"
}, },
@@ -20308,6 +20323,24 @@
"required": ["id", "type", "properties"], "required": ["id", "type", "properties"],
"additionalProperties": false "additionalProperties": false
}, },
"EventModels-devRefreshed": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string",
"enum": ["models-dev.refreshed"]
},
"properties": {
"type": "object",
"properties": {}
}
},
"required": ["id", "type", "properties"],
"additionalProperties": false
},
"SessionInfo": { "SessionInfo": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -21021,7 +21054,7 @@
"properties": { "properties": {
"via": { "via": {
"type": "string", "type": "string",
"enum": ["auth"] "enum": ["account"]
}, },
"service": { "service": {
"type": "string" "type": "string"
@@ -21543,6 +21576,154 @@
], ],
"additionalProperties": false "additionalProperties": false
}, },
"AccountV2OAuthCredential": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["oauth"]
},
"refresh": {
"type": "string"
},
"access": {
"type": "string"
},
"expires": {
"type": "integer",
"minimum": 0
}
},
"required": ["type", "refresh", "access", "expires"],
"additionalProperties": false
},
"AccountV2ApiKeyCredential": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": ["api"]
},
"key": {
"type": "string"
},
"metadata": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"required": ["type", "key"],
"additionalProperties": false
},
"AccountV2Credential": {
"anyOf": [
{
"$ref": "#/components/schemas/AccountV2OAuthCredential"
},
{
"$ref": "#/components/schemas/AccountV2ApiKeyCredential"
}
]
},
"AccountV2Info": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"serviceID": {
"type": "string"
},
"description": {
"type": "string"
},
"credential": {
"$ref": "#/components/schemas/AccountV2Credential"
}
},
"required": ["id", "serviceID", "description", "credential"],
"additionalProperties": false
},
"EventAccountAdded": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string",
"enum": ["account.added"]
},
"properties": {
"type": "object",
"properties": {
"account": {
"$ref": "#/components/schemas/AccountV2Info"
}
},
"required": ["account"],
"additionalProperties": false
}
},
"required": ["id", "type", "properties"],
"additionalProperties": false
},
"EventAccountRemoved": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string",
"enum": ["account.removed"]
},
"properties": {
"type": "object",
"properties": {
"account": {
"$ref": "#/components/schemas/AccountV2Info"
}
},
"required": ["account"],
"additionalProperties": false
}
},
"required": ["id", "type", "properties"],
"additionalProperties": false
},
"EventAccountSwitched": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"type": {
"type": "string",
"enum": ["account.switched"]
},
"properties": {
"type": "object",
"properties": {
"serviceID": {
"type": "string"
},
"from": {
"type": "string"
},
"to": {
"type": "string"
}
},
"required": ["serviceID"],
"additionalProperties": false
}
},
"required": ["id", "type", "properties"],
"additionalProperties": false
},
"BadRequestError": { "BadRequestError": {
"type": "object", "type": "object",
"required": ["name", "data"], "required": ["name", "data"],