feat: expand multimodal and knowledge workflows
This commit is contained in:
@@ -19,8 +19,13 @@ export const builtinMcpServers = [
|
||||
id: 'knowledge-base',
|
||||
name: '知识库 MCP',
|
||||
description:
|
||||
'搜索当前对话明确选择的知识库,并返回可核验的来源与证据引用。',
|
||||
'列出并搜索当前对话明确选择的知识库,返回可核验的来源与证据引用。',
|
||||
tools: [
|
||||
{
|
||||
name: 'knowledge_list',
|
||||
description: '列出当前对话已授权的知识库及其说明。',
|
||||
access: 'read'
|
||||
},
|
||||
{
|
||||
name: 'knowledge_search',
|
||||
description: '搜索当前对话已授权的知识库并返回来源引用。',
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
maximumPastedImageBytes,
|
||||
pastedImageInputSchema
|
||||
} from './contracts'
|
||||
|
||||
describe('context contracts', () => {
|
||||
it('accepts bounded pasted image bytes in supported formats', () => {
|
||||
expect(
|
||||
pastedImageInputSchema.safeParse({
|
||||
data: Uint8Array.from([0x89, 0x50, 0x4e, 0x47]),
|
||||
mimeType: 'image/png'
|
||||
}).success
|
||||
).toBe(true)
|
||||
})
|
||||
|
||||
it('rejects empty, oversized, and unsupported pasted images', () => {
|
||||
expect(
|
||||
pastedImageInputSchema.safeParse({
|
||||
data: new Uint8Array(),
|
||||
mimeType: 'image/png'
|
||||
}).success
|
||||
).toBe(false)
|
||||
expect(
|
||||
pastedImageInputSchema.safeParse({
|
||||
data: new Uint8Array(maximumPastedImageBytes + 1),
|
||||
mimeType: 'image/png'
|
||||
}).success
|
||||
).toBe(false)
|
||||
expect(
|
||||
pastedImageInputSchema.safeParse({
|
||||
data: Uint8Array.from([1]),
|
||||
mimeType: 'image/gif'
|
||||
}).success
|
||||
).toBe(false)
|
||||
})
|
||||
})
|
||||
@@ -231,6 +231,7 @@ export const defaultRuntimeSettings = {
|
||||
modelName: 'sonnet-5',
|
||||
modelProtocol: 'anthropic-messages',
|
||||
modelAuthentication: 'api-key',
|
||||
supportsImageInput: false,
|
||||
imageGenerationQuality: 'auto',
|
||||
opencodeBaseUrl: '',
|
||||
opencodeEmbedded: true,
|
||||
@@ -321,6 +322,7 @@ const modelProfileInputSchema = z
|
||||
.regex(/^[\w./:-]+$/, '模型名称包含不支持的字符'),
|
||||
protocol: modelProtocolSchema,
|
||||
authentication: modelAuthenticationSchema,
|
||||
supportsImageInput: z.boolean().optional(),
|
||||
imageGenerationQuality: imageGenerationQualitySchema,
|
||||
apiKey: modelApiKeyUpdateSchema
|
||||
})
|
||||
@@ -524,6 +526,7 @@ export type ModelConnectionSettings = {
|
||||
modelName: string
|
||||
protocol: ModelProtocol
|
||||
authentication: ModelAuthentication
|
||||
supportsImageInput?: boolean
|
||||
imageGenerationQuality: ImageGenerationQuality
|
||||
apiKeyConfigured: boolean
|
||||
credentialSource: 'none' | 'encrypted' | 'environment'
|
||||
@@ -535,6 +538,7 @@ export type RuntimeSettings = {
|
||||
modelName: string
|
||||
modelProtocol: ModelProtocol
|
||||
modelAuthentication: ModelAuthentication
|
||||
supportsImageInput?: boolean
|
||||
imageGenerationQuality: ImageGenerationQuality
|
||||
opencodeBaseUrl: string
|
||||
opencodeEmbedded: boolean
|
||||
@@ -564,6 +568,23 @@ export type RuntimeSettings = {
|
||||
|
||||
export type ContextAttachment = ConversationAttachment
|
||||
|
||||
export const maximumPastedImageBytes = 12 * 1024 * 1024
|
||||
|
||||
export const pastedImageInputSchema = z
|
||||
.object({
|
||||
data: z
|
||||
.instanceof(Uint8Array)
|
||||
.refine((value) => value.byteLength > 0, '粘贴图片内容为空')
|
||||
.refine(
|
||||
(value) => value.byteLength <= maximumPastedImageBytes,
|
||||
'粘贴图片不能超过 12MB'
|
||||
),
|
||||
mimeType: z.enum(['image/jpeg', 'image/png', 'image/webp'])
|
||||
})
|
||||
.strict()
|
||||
|
||||
export type PastedImageInput = z.infer<typeof pastedImageInputSchema>
|
||||
|
||||
export const windowCaptureSourceIdSchema = z
|
||||
.string()
|
||||
.min(1)
|
||||
@@ -1169,6 +1190,9 @@ export type DesktopApi = {
|
||||
}
|
||||
context: {
|
||||
selectFiles: () => Promise<ContextAttachment[]>
|
||||
addPastedImage: (
|
||||
input: PastedImageInput
|
||||
) => Promise<ContextAttachment>
|
||||
captureScreen: () => Promise<ContextAttachment>
|
||||
listWindows: () => Promise<WindowCaptureOption[]>
|
||||
captureWindow: (sourceId: string) => Promise<ContextAttachment>
|
||||
|
||||
@@ -112,6 +112,7 @@ export const ipcChannels = {
|
||||
capabilitiesDefaultBrowserProfile: 'capabilities:browser-profile:default',
|
||||
capabilitiesRemoveBrowserProfile: 'capabilities:browser-profile:remove',
|
||||
contextSelectFiles: 'context:select-files',
|
||||
contextAddPastedImage: 'context:add-pasted-image',
|
||||
contextCaptureScreen: 'context:capture-screen',
|
||||
contextListWindows: 'context:list-windows',
|
||||
contextCaptureWindow: 'context:capture-window',
|
||||
|
||||
Reference in New Issue
Block a user