mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-05 08:33:10 +00:00
feat: mcp resources (#6542)
This commit is contained in:
@@ -117,7 +117,15 @@ export namespace MessageV2 {
|
||||
ref: "SymbolSource",
|
||||
})
|
||||
|
||||
export const FilePartSource = z.discriminatedUnion("type", [FileSource, SymbolSource]).meta({
|
||||
export const ResourceSource = FilePartSourceBase.extend({
|
||||
type: z.literal("resource"),
|
||||
clientName: z.string(),
|
||||
uri: z.string(),
|
||||
}).meta({
|
||||
ref: "ResourceSource",
|
||||
})
|
||||
|
||||
export const FilePartSource = z.discriminatedUnion("type", [FileSource, SymbolSource, ResourceSource]).meta({
|
||||
ref: "FilePartSource",
|
||||
})
|
||||
|
||||
|
||||
@@ -811,6 +811,78 @@ export namespace SessionPrompt {
|
||||
const parts = await Promise.all(
|
||||
input.parts.map(async (part): Promise<MessageV2.Part[]> => {
|
||||
if (part.type === "file") {
|
||||
// before checking the protocol we check if this is an mcp resource because it needs special handling
|
||||
if (part.source?.type === "resource") {
|
||||
const { clientName, uri } = part.source
|
||||
log.info("mcp resource", { clientName, uri, mime: part.mime })
|
||||
|
||||
const pieces: MessageV2.Part[] = [
|
||||
{
|
||||
id: Identifier.ascending("part"),
|
||||
messageID: info.id,
|
||||
sessionID: input.sessionID,
|
||||
type: "text",
|
||||
synthetic: true,
|
||||
text: `Reading MCP resource: ${part.filename} (${uri})`,
|
||||
},
|
||||
]
|
||||
|
||||
try {
|
||||
const resourceContent = await MCP.readResource(clientName, uri)
|
||||
if (!resourceContent) {
|
||||
throw new Error(`Resource not found: ${clientName}/${uri}`)
|
||||
}
|
||||
|
||||
// Handle different content types
|
||||
const contents = Array.isArray(resourceContent.contents)
|
||||
? resourceContent.contents
|
||||
: [resourceContent.contents]
|
||||
|
||||
for (const content of contents) {
|
||||
if ("text" in content && content.text) {
|
||||
pieces.push({
|
||||
id: Identifier.ascending("part"),
|
||||
messageID: info.id,
|
||||
sessionID: input.sessionID,
|
||||
type: "text",
|
||||
synthetic: true,
|
||||
text: content.text as string,
|
||||
})
|
||||
} else if ("blob" in content && content.blob) {
|
||||
// Handle binary content if needed
|
||||
const mimeType = "mimeType" in content ? content.mimeType : part.mime
|
||||
pieces.push({
|
||||
id: Identifier.ascending("part"),
|
||||
messageID: info.id,
|
||||
sessionID: input.sessionID,
|
||||
type: "text",
|
||||
synthetic: true,
|
||||
text: `[Binary content: ${mimeType}]`,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pieces.push({
|
||||
...part,
|
||||
id: part.id ?? Identifier.ascending("part"),
|
||||
messageID: info.id,
|
||||
sessionID: input.sessionID,
|
||||
})
|
||||
} catch (error: unknown) {
|
||||
log.error("failed to read MCP resource", { error, clientName, uri })
|
||||
const message = error instanceof Error ? error.message : String(error)
|
||||
pieces.push({
|
||||
id: Identifier.ascending("part"),
|
||||
messageID: info.id,
|
||||
sessionID: input.sessionID,
|
||||
type: "text",
|
||||
synthetic: true,
|
||||
text: `Failed to read MCP resource ${part.filename}: ${message}`,
|
||||
})
|
||||
}
|
||||
|
||||
return pieces
|
||||
}
|
||||
const url = new URL(part.url)
|
||||
switch (url.protocol) {
|
||||
case "data:":
|
||||
|
||||
Reference in New Issue
Block a user