Merge branch 'main' into fix/provider-scoped-model-id-resolution

This commit is contained in:
ringotypowriter
2026-02-22 17:00:51 +08:00
27 changed files with 3694 additions and 132 deletions
+2
View File
@@ -17,6 +17,8 @@
"@ai-sdk/mcp": "^1.0.6",
"@ai-sdk/openai": "^3.0.7",
"@mozilla/readability": "^0.6.0",
"@types/jsdom": "^27.0.0",
"@types/turndown": "^5.0.6",
"ai": "^6.0.25",
"jsdom": "^27.4.0",
"toml": "^3.0.0",
+6 -50
View File
@@ -31,6 +31,7 @@ import type { GatewayInputAttachment } from './types/attachment'
import { getMCPTools } from './tools/mcp'
import { getTools } from './tools'
import { buildIdentityHeaders } from './utils/headers'
import { createFS } from './utils'
const buildStepUsages = (
steps: { usage: LanguageModelUsage; response: { messages: unknown[] } }[],
@@ -77,6 +78,7 @@ export const createAgent = (
) => {
const model = createModel(modelConfig)
const enabledSkills: AgentSkill[] = []
const fs = createFS({ fetch, botId: identity.botId })
const enableSkill = (skill: string) => {
const agentSkill = skills.find((s) => s.name === skill)
@@ -90,58 +92,12 @@ export const createAgent = (
}
const loadSystemFiles = async () => {
if (!auth?.bearer || !identity.botId) {
return {
identityContent: '',
soulContent: '',
toolsContent: '',
}
}
const readViaMCP = async (path: string): Promise<string> => {
const url = `${auth.baseUrl.replace(/\/$/, '')}/bots/${identity.botId}/tools`
const headers: Record<string, string> = {
'Content-Type': 'application/json',
Accept: 'application/json, text/event-stream',
Authorization: `Bearer ${auth.bearer}`,
}
if (identity.channelIdentityId) {
headers['X-Memoh-Channel-Identity-Id'] = identity.channelIdentityId
}
const body = JSON.stringify({
jsonrpc: '2.0',
id: `read-${path}`,
method: 'tools/call',
params: { name: 'read', arguments: { path } },
})
const response = await fetch(url, { method: 'POST', headers, body })
if (!response.ok) return ''
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const data = await response.json().catch(() => ({})) as any
const structured =
data?.result?.structuredContent ?? data?.result?.content?.[0]?.text
if (typeof structured === 'string') {
try {
const parsed = JSON.parse(structured)
return typeof parsed?.content === 'string' ? parsed.content : ''
} catch {
return structured
}
}
if (typeof structured === 'object' && structured?.content) {
return typeof structured.content === 'string' ? structured.content : ''
}
return ''
}
const [identityContent, soulContent, toolsContent] = await Promise.all([
readViaMCP('IDENTITY.md'),
readViaMCP('SOUL.md'),
readViaMCP('TOOLS.md'),
fs.readText('/data/IDENTITY.md'),
fs.readText('/data/SOUL.md'),
fs.readText('/data/TOOLS.md'),
])
return {
identityContent,
soulContent,
toolsContent,
}
return { identityContent, soulContent, toolsContent }
}
const generateSystemPrompt = async () => {
+39 -51
View File
@@ -1,9 +1,13 @@
import { tool } from 'ai'
import { tool, type ModelMessage } from 'ai'
import { z } from 'zod'
import { createAgent } from '../agent'
import { ModelConfig, AgentAuthContext } from '../types'
import { AuthFetcher } from '../types'
import { AgentAction, IdentityContext } from '../types/agent'
import type { ModelConfig, AgentAuthContext, AuthFetcher } from '../types'
import { AgentAction, type IdentityContext } from '../types/agent'
import {
createSubagentClient,
toSubagentUsage,
addUsage,
} from '../utils/subagent'
export interface SubagentToolParams {
fetch: AuthFetcher
@@ -14,7 +18,7 @@ export interface SubagentToolParams {
export const getSubagentTools = ({ fetch, model, identity, auth }: SubagentToolParams) => {
const botId = identity.botId.trim()
const base = `/bots/${botId}/subagents`
const client = createSubagentClient(fetch, botId)
const listSubagents = tool({
description: 'List subagents for current user',
@@ -23,27 +27,7 @@ export const getSubagentTools = ({ fetch, model, identity, auth }: SubagentToolP
if (!botId) {
throw new Error('bot_id is required')
}
const response = await fetch(base, { method: 'GET' })
return response.json()
},
})
const createSubagent = tool({
description: 'Create a new subagent',
inputSchema: z.object({
name: z.string(),
description: z.string(),
}),
execute: async ({ name, description }) => {
if (!botId) {
throw new Error('bot_id is required')
}
const response = await fetch(base, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, description }),
})
return response.json()
return client.list()
},
})
@@ -56,51 +40,56 @@ export const getSubagentTools = ({ fetch, model, identity, auth }: SubagentToolP
if (!botId) {
throw new Error('bot_id is required')
}
const response = await fetch(`${base}/${id}`, { method: 'DELETE' })
return response.status === 204 ? { success: true } : response.json()
return client.remove(id)
},
})
const querySubagent = tool({
description: 'Query a subagent',
description: 'Query a subagent. If the subagent does not exist it will be created automatically.',
inputSchema: z.object({
name: z.string(),
name: z.string().describe('The name of the subagent'),
description: z.string().describe('A short description of the subagent purpose (used when creating)'),
query: z.string().describe('The prompt to ask the subagent to do.'),
}),
execute: async ({ name, query }) => {
execute: async ({ name, description, query }) => {
if (!botId) {
throw new Error('bot_id is required')
}
const listResponse = await fetch(base, { method: 'GET' })
const listPayload = await listResponse.json()
const items = Array.isArray(listPayload?.items) ? listPayload.items : []
const target = items.find((item: { name?: string }) => item?.name === name)
if (!target?.id) {
throw new Error(`subagent not found: ${name}`)
}
const contextResponse = await fetch(`${base}/${target.id}/context`, { method: 'GET' })
const contextPayload = await contextResponse.json()
const contextMessages = Array.isArray(contextPayload?.messages) ? contextPayload.messages : []
// Get or create the subagent
const target = await client.getOrCreate({ name, description })
// Load persisted context (messages + usage)
const ctx = await client.getContext(target.id)
const contextMessages = (Array.isArray(ctx.messages) ? ctx.messages : []) as ModelMessage[]
const existingUsage = toSubagentUsage(ctx.usage)
// Create a scoped agent instance for the subagent
const { askAsSubagent } = createAgent({
model,
allowedActions: [
AgentAction.Web,
],
allowedActions: [AgentAction.Web],
identity,
auth,
}, fetch)
const result = await askAsSubagent({
messages: contextMessages,
input: query,
name: target.name,
description: target.description,
})
// Accumulate usage
const newUsage = addUsage(existingUsage, result.usage)
// Persist updated messages + usage
const updatedMessages = [...contextMessages, ...result.messages]
await fetch(`${base}/${target.id}/context`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ messages: updatedMessages }),
})
await client.updateContext(
target.id,
updatedMessages as Record<string, unknown>[],
newUsage,
)
return {
success: true,
result: result.messages[result.messages.length - 1].content,
@@ -110,8 +99,7 @@ export const getSubagentTools = ({ fetch, model, identity, auth }: SubagentToolP
return {
'list_subagents': listSubagents,
'create_subagent': createSubagent,
'delete_subagent': deleteSubagent,
'query_subagent': querySubagent,
}
}
}
+207
View File
@@ -0,0 +1,207 @@
import type { AuthFetcher } from '../types'
// ---------- types ----------
export interface FSFileInfo {
name: string
path: string
size: number
mode: string
modTime: string
isDir: boolean
}
export interface FSListResponse {
path: string
entries: FSFileInfo[]
}
export interface FSReadResponse {
path: string
content: string
size: number
}
export interface FSWriteParams {
path: string
content: string
}
export interface FSUploadResponse {
path: string
size: number
}
export interface FSMkdirParams {
path: string
}
export interface FSDeleteParams {
path: string
recursive?: boolean
}
export interface FSRenameParams {
oldPath: string
newPath: string
}
export interface FSOkResponse {
ok: boolean
}
export interface FSClientOptions {
fetch: AuthFetcher
botId: string
}
// ---------- helpers ----------
const encodeQuery = (path: string) => encodeURIComponent(path)
const ensureOk = async (response: Response, action: string): Promise<void> => {
if (!response.ok) {
const text = await response.text().catch(() => '')
throw new Error(`fs ${action} failed (${response.status}): ${text}`)
}
}
// ---------- public API ----------
/**
* Creates a set of filesystem utility functions that operate on a bot's
* container via the REST file-manager API.
*
* All functions use `AuthFetcher` so auth headers are injected automatically.
*/
export const createFS = ({ fetch, botId }: FSClientOptions) => {
const base = `/bots/${botId}/container/fs`
/** Get file or directory metadata. */
const stat = async (path: string): Promise<FSFileInfo> => {
const response = await fetch(`${base}?path=${encodeQuery(path)}`)
await ensureOk(response, 'stat')
return response.json() as Promise<FSFileInfo>
}
/** List directory contents. */
const list = async (path: string): Promise<FSListResponse> => {
const response = await fetch(`${base}/list?path=${encodeQuery(path)}`)
await ensureOk(response, 'list')
return response.json() as Promise<FSListResponse>
}
/** Read a file as text. */
const read = async (path: string): Promise<FSReadResponse> => {
const response = await fetch(`${base}/read?path=${encodeQuery(path)}`)
await ensureOk(response, 'read')
return response.json() as Promise<FSReadResponse>
}
/** Download a file as a binary `Response` (stream-ready). */
const download = async (path: string): Promise<Response> => {
const response = await fetch(`${base}/download?path=${encodeQuery(path)}`)
await ensureOk(response, 'download')
return response
}
/** Write text content to a file (creates parent dirs automatically). */
const write = async (params: FSWriteParams): Promise<FSOkResponse> => {
const response = await fetch(`${base}/write`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params),
})
await ensureOk(response, 'write')
return response.json() as Promise<FSOkResponse>
}
/** Upload a binary file via multipart/form-data. */
const upload = async (
path: string,
file: Blob | File,
fileName?: string,
): Promise<FSUploadResponse> => {
const form = new FormData()
form.append('path', path)
form.append('file', file, fileName ?? (file instanceof File ? file.name : 'upload'))
const response = await fetch(`${base}/upload`, {
method: 'POST',
body: form,
})
await ensureOk(response, 'upload')
return response.json() as Promise<FSUploadResponse>
}
/** Create a directory (and parents). */
const mkdir = async (params: FSMkdirParams): Promise<FSOkResponse> => {
const response = await fetch(`${base}/mkdir`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params),
})
await ensureOk(response, 'mkdir')
return response.json() as Promise<FSOkResponse>
}
/** Delete a file or directory. */
const remove = async (params: FSDeleteParams): Promise<FSOkResponse> => {
const response = await fetch(`${base}/delete`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params),
})
await ensureOk(response, 'delete')
return response.json() as Promise<FSOkResponse>
}
/** Rename or move a file / directory. */
const rename = async (params: FSRenameParams): Promise<FSOkResponse> => {
const response = await fetch(`${base}/rename`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params),
})
await ensureOk(response, 'rename')
return response.json() as Promise<FSOkResponse>
}
/** Check whether a path exists. */
const exists = async (path: string): Promise<boolean> => {
try {
await stat(path)
return true
} catch {
return false
}
}
/** Read a file and return only the text content string. */
const readText = async (path: string): Promise<string> => {
const result = await read(path)
return result.content
}
/** Shorthand: write text content to a path. */
const writeText = async (path: string, content: string): Promise<FSOkResponse> => {
return write({ path, content })
}
return {
stat,
list,
read,
readText,
download,
write,
writeText,
upload,
mkdir,
remove,
rename,
exists,
}
}
export type FSClient = ReturnType<typeof createFS>
+3 -1
View File
@@ -1,2 +1,4 @@
export * from './attachments'
export * from './headers'
export * from './fs'
export * from './headers'
export * from './subagent'
+131
View File
@@ -0,0 +1,131 @@
import type { AuthFetcher } from '../types'
import type { LanguageModelUsage } from 'ai'
// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
export interface SubagentItem {
id: string
name: string
description: string
bot_id: string
messages: Record<string, unknown>[]
metadata: Record<string, unknown>
skills: string[]
usage: SubagentUsage
created_at: string
updated_at: string
deleted: boolean
deleted_at?: string
}
export interface SubagentUsage {
inputTokens: number
outputTokens: number
totalTokens: number
}
export interface SubagentListResponse {
items: SubagentItem[]
}
export interface SubagentContextResponse {
messages: Record<string, unknown>[]
usage: SubagentUsage
}
// ---------------------------------------------------------------------------
// Usage helpers
// ---------------------------------------------------------------------------
const emptyUsage: SubagentUsage = {
inputTokens: 0,
outputTokens: 0,
totalTokens: 0,
}
export const toSubagentUsage = (raw: unknown): SubagentUsage => {
if (!raw || typeof raw !== 'object') return { ...emptyUsage }
const obj = raw as Record<string, unknown>
return {
inputTokens: typeof obj.inputTokens === 'number' ? obj.inputTokens : 0,
outputTokens: typeof obj.outputTokens === 'number' ? obj.outputTokens : 0,
totalTokens: typeof obj.totalTokens === 'number' ? obj.totalTokens : 0,
}
}
export const addUsage = (
existing: SubagentUsage,
delta: LanguageModelUsage,
): SubagentUsage => ({
inputTokens: existing.inputTokens + (delta.inputTokens ?? 0),
outputTokens: existing.outputTokens + (delta.outputTokens ?? 0),
totalTokens: existing.totalTokens + (delta.totalTokens ?? 0),
})
// ---------------------------------------------------------------------------
// Client factory
// ---------------------------------------------------------------------------
export const createSubagentClient = (fetch: AuthFetcher, botId: string) => {
const base = `/bots/${botId}/subagents`
const list = async (): Promise<SubagentListResponse> => {
const res = await fetch(base, { method: 'GET' })
return res.json() as Promise<SubagentListResponse>
}
const create = async (params: {
name: string
description: string
}): Promise<SubagentItem> => {
const res = await fetch(base, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(params),
})
return res.json() as Promise<SubagentItem>
}
const get = async (id: string): Promise<SubagentItem> => {
const res = await fetch(`${base}/${id}`, { method: 'GET' })
return res.json() as Promise<SubagentItem>
}
const getContext = async (id: string): Promise<SubagentContextResponse> => {
const res = await fetch(`${base}/${id}/context`, { method: 'GET' })
return res.json() as Promise<SubagentContextResponse>
}
const updateContext = async (
id: string,
messages: Record<string, unknown>[],
usage: SubagentUsage,
): Promise<SubagentContextResponse> => {
const res = await fetch(`${base}/${id}/context`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ messages, usage }),
})
return res.json() as Promise<SubagentContextResponse>
}
const getOrCreate = async (params: {
name: string
description: string
}): Promise<SubagentItem> => {
const { items } = await list()
const existing = items.find((item) => item.name === params.name)
if (existing) return existing
return create(params)
}
const remove = async (id: string): Promise<{ success: boolean }> => {
const res = await fetch(`${base}/${id}`, { method: 'DELETE' })
return res.status === 204 ? { success: true } : (res.json() as Promise<{ success: boolean }>)
}
return { list, create, get, getContext, updateContext, getOrCreate, remove }
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+450
View File
@@ -397,6 +397,50 @@ export type HandlersErrorResponse = {
message?: string;
};
export type HandlersFsDeleteRequest = {
path?: string;
recursive?: boolean;
};
export type HandlersFsFileInfo = {
isDir?: boolean;
modTime?: string;
mode?: string;
name?: string;
path?: string;
size?: number;
};
export type HandlersFsListResponse = {
entries?: Array<HandlersFsFileInfo>;
path?: string;
};
export type HandlersFsMkdirRequest = {
path?: string;
};
export type HandlersFsReadResponse = {
content?: string;
path?: string;
size?: number;
};
export type HandlersFsRenameRequest = {
newPath?: string;
oldPath?: string;
};
export type HandlersFsUploadResponse = {
path?: string;
size?: number;
};
export type HandlersFsWriteRequest = {
content?: string;
path?: string;
};
export type HandlersGetContainerResponse = {
container_id?: string;
container_path?: string;
@@ -485,6 +529,10 @@ export type HandlersSnapshotInfo = {
version?: number;
};
export type HandlersFsOpResponse = {
ok?: boolean;
};
export type HandlersListMyIdentitiesResponse = {
items?: Array<IdentitiesChannelIdentity>;
user_id?: string;
@@ -945,6 +993,9 @@ export type SubagentContextResponse = {
messages?: Array<{
[key: string]: unknown;
}>;
usage?: {
[key: string]: unknown;
};
};
export type SubagentCreateRequest = {
@@ -983,12 +1034,18 @@ export type SubagentSubagent = {
name?: string;
skills?: Array<string>;
updated_at?: string;
usage?: {
[key: string]: unknown;
};
};
export type SubagentUpdateContextRequest = {
messages?: Array<{
[key: string]: unknown;
}>;
usage?: {
[key: string]: unknown;
};
};
export type SubagentUpdateRequest = {
@@ -1297,6 +1354,399 @@ export type PostBotsByBotIdContainerResponses = {
export type PostBotsByBotIdContainerResponse = PostBotsByBotIdContainerResponses[keyof PostBotsByBotIdContainerResponses];
export type GetBotsByBotIdContainerFsData = {
body?: never;
path: {
/**
* Bot ID
*/
bot_id: string;
};
query: {
/**
* Container path
*/
path: string;
};
url: '/bots/{bot_id}/container/fs';
};
export type GetBotsByBotIdContainerFsErrors = {
/**
* Bad Request
*/
400: HandlersErrorResponse;
/**
* Forbidden
*/
403: HandlersErrorResponse;
/**
* Not Found
*/
404: HandlersErrorResponse;
/**
* Internal Server Error
*/
500: HandlersErrorResponse;
};
export type GetBotsByBotIdContainerFsError = GetBotsByBotIdContainerFsErrors[keyof GetBotsByBotIdContainerFsErrors];
export type GetBotsByBotIdContainerFsResponses = {
/**
* OK
*/
200: HandlersFsFileInfo;
};
export type GetBotsByBotIdContainerFsResponse = GetBotsByBotIdContainerFsResponses[keyof GetBotsByBotIdContainerFsResponses];
export type PostBotsByBotIdContainerFsDeleteData = {
/**
* Delete request
*/
body: HandlersFsDeleteRequest;
path: {
/**
* Bot ID
*/
bot_id: string;
};
query?: never;
url: '/bots/{bot_id}/container/fs/delete';
};
export type PostBotsByBotIdContainerFsDeleteErrors = {
/**
* Bad Request
*/
400: HandlersErrorResponse;
/**
* Forbidden
*/
403: HandlersErrorResponse;
/**
* Not Found
*/
404: HandlersErrorResponse;
/**
* Internal Server Error
*/
500: HandlersErrorResponse;
};
export type PostBotsByBotIdContainerFsDeleteError = PostBotsByBotIdContainerFsDeleteErrors[keyof PostBotsByBotIdContainerFsDeleteErrors];
export type PostBotsByBotIdContainerFsDeleteResponses = {
/**
* OK
*/
200: HandlersFsOpResponse;
};
export type PostBotsByBotIdContainerFsDeleteResponse = PostBotsByBotIdContainerFsDeleteResponses[keyof PostBotsByBotIdContainerFsDeleteResponses];
export type GetBotsByBotIdContainerFsDownloadData = {
body?: never;
path: {
/**
* Bot ID
*/
bot_id: string;
};
query: {
/**
* Container file path
*/
path: string;
};
url: '/bots/{bot_id}/container/fs/download';
};
export type GetBotsByBotIdContainerFsDownloadErrors = {
/**
* Bad Request
*/
400: HandlersErrorResponse;
/**
* Not Found
*/
404: HandlersErrorResponse;
/**
* Internal Server Error
*/
500: HandlersErrorResponse;
};
export type GetBotsByBotIdContainerFsDownloadError = GetBotsByBotIdContainerFsDownloadErrors[keyof GetBotsByBotIdContainerFsDownloadErrors];
export type GetBotsByBotIdContainerFsDownloadResponses = {
/**
* OK
*/
200: unknown;
};
export type GetBotsByBotIdContainerFsListData = {
body?: never;
path: {
/**
* Bot ID
*/
bot_id: string;
};
query: {
/**
* Container directory path
*/
path: string;
};
url: '/bots/{bot_id}/container/fs/list';
};
export type GetBotsByBotIdContainerFsListErrors = {
/**
* Bad Request
*/
400: HandlersErrorResponse;
/**
* Not Found
*/
404: HandlersErrorResponse;
/**
* Internal Server Error
*/
500: HandlersErrorResponse;
};
export type GetBotsByBotIdContainerFsListError = GetBotsByBotIdContainerFsListErrors[keyof GetBotsByBotIdContainerFsListErrors];
export type GetBotsByBotIdContainerFsListResponses = {
/**
* OK
*/
200: HandlersFsListResponse;
};
export type GetBotsByBotIdContainerFsListResponse = GetBotsByBotIdContainerFsListResponses[keyof GetBotsByBotIdContainerFsListResponses];
export type PostBotsByBotIdContainerFsMkdirData = {
/**
* Mkdir request
*/
body: HandlersFsMkdirRequest;
path: {
/**
* Bot ID
*/
bot_id: string;
};
query?: never;
url: '/bots/{bot_id}/container/fs/mkdir';
};
export type PostBotsByBotIdContainerFsMkdirErrors = {
/**
* Bad Request
*/
400: HandlersErrorResponse;
/**
* Forbidden
*/
403: HandlersErrorResponse;
/**
* Internal Server Error
*/
500: HandlersErrorResponse;
};
export type PostBotsByBotIdContainerFsMkdirError = PostBotsByBotIdContainerFsMkdirErrors[keyof PostBotsByBotIdContainerFsMkdirErrors];
export type PostBotsByBotIdContainerFsMkdirResponses = {
/**
* OK
*/
200: HandlersFsOpResponse;
};
export type PostBotsByBotIdContainerFsMkdirResponse = PostBotsByBotIdContainerFsMkdirResponses[keyof PostBotsByBotIdContainerFsMkdirResponses];
export type GetBotsByBotIdContainerFsReadData = {
body?: never;
path: {
/**
* Bot ID
*/
bot_id: string;
};
query: {
/**
* Container file path
*/
path: string;
};
url: '/bots/{bot_id}/container/fs/read';
};
export type GetBotsByBotIdContainerFsReadErrors = {
/**
* Bad Request
*/
400: HandlersErrorResponse;
/**
* Not Found
*/
404: HandlersErrorResponse;
/**
* Internal Server Error
*/
500: HandlersErrorResponse;
};
export type GetBotsByBotIdContainerFsReadError = GetBotsByBotIdContainerFsReadErrors[keyof GetBotsByBotIdContainerFsReadErrors];
export type GetBotsByBotIdContainerFsReadResponses = {
/**
* OK
*/
200: HandlersFsReadResponse;
};
export type GetBotsByBotIdContainerFsReadResponse = GetBotsByBotIdContainerFsReadResponses[keyof GetBotsByBotIdContainerFsReadResponses];
export type PostBotsByBotIdContainerFsRenameData = {
/**
* Rename request
*/
body: HandlersFsRenameRequest;
path: {
/**
* Bot ID
*/
bot_id: string;
};
query?: never;
url: '/bots/{bot_id}/container/fs/rename';
};
export type PostBotsByBotIdContainerFsRenameErrors = {
/**
* Bad Request
*/
400: HandlersErrorResponse;
/**
* Forbidden
*/
403: HandlersErrorResponse;
/**
* Not Found
*/
404: HandlersErrorResponse;
/**
* Internal Server Error
*/
500: HandlersErrorResponse;
};
export type PostBotsByBotIdContainerFsRenameError = PostBotsByBotIdContainerFsRenameErrors[keyof PostBotsByBotIdContainerFsRenameErrors];
export type PostBotsByBotIdContainerFsRenameResponses = {
/**
* OK
*/
200: HandlersFsOpResponse;
};
export type PostBotsByBotIdContainerFsRenameResponse = PostBotsByBotIdContainerFsRenameResponses[keyof PostBotsByBotIdContainerFsRenameResponses];
export type PostBotsByBotIdContainerFsUploadData = {
body: {
/**
* Destination container path
*/
path: string;
/**
* File to upload
*/
file: Blob | File;
};
path: {
/**
* Bot ID
*/
bot_id: string;
};
query?: never;
url: '/bots/{bot_id}/container/fs/upload';
};
export type PostBotsByBotIdContainerFsUploadErrors = {
/**
* Bad Request
*/
400: HandlersErrorResponse;
/**
* Forbidden
*/
403: HandlersErrorResponse;
/**
* Internal Server Error
*/
500: HandlersErrorResponse;
};
export type PostBotsByBotIdContainerFsUploadError = PostBotsByBotIdContainerFsUploadErrors[keyof PostBotsByBotIdContainerFsUploadErrors];
export type PostBotsByBotIdContainerFsUploadResponses = {
/**
* OK
*/
200: HandlersFsUploadResponse;
};
export type PostBotsByBotIdContainerFsUploadResponse = PostBotsByBotIdContainerFsUploadResponses[keyof PostBotsByBotIdContainerFsUploadResponses];
export type PostBotsByBotIdContainerFsWriteData = {
/**
* Write request
*/
body: HandlersFsWriteRequest;
path: {
/**
* Bot ID
*/
bot_id: string;
};
query?: never;
url: '/bots/{bot_id}/container/fs/write';
};
export type PostBotsByBotIdContainerFsWriteErrors = {
/**
* Bad Request
*/
400: HandlersErrorResponse;
/**
* Forbidden
*/
403: HandlersErrorResponse;
/**
* Internal Server Error
*/
500: HandlersErrorResponse;
};
export type PostBotsByBotIdContainerFsWriteError = PostBotsByBotIdContainerFsWriteErrors[keyof PostBotsByBotIdContainerFsWriteErrors];
export type PostBotsByBotIdContainerFsWriteResponses = {
/**
* OK
*/
200: HandlersFsOpResponse;
};
export type PostBotsByBotIdContainerFsWriteResponse = PostBotsByBotIdContainerFsWriteResponses[keyof PostBotsByBotIdContainerFsWriteResponses];
export type DeleteBotsByBotIdContainerSkillsData = {
/**
* Delete skills payload