Add skills catalog and sidebar tooling

This commit is contained in:
Gemini AI
2025-12-24 14:23:51 +04:00
Unverified
parent d153892bdf
commit f9748391a9
13 changed files with 1178 additions and 106 deletions

View File

@@ -14,6 +14,7 @@ import { createSession, loadMessages } from "./session-api"
import { showToastNotification } from "../lib/notifications"
import { showConfirmDialog } from "./alerts"
import { QwenOAuthManager } from "../lib/integrations/qwen-oauth"
import { loadSkillDetails } from "./skills"
const log = getLogger("actions")
@@ -255,6 +256,46 @@ function buildLanguageSystemInstruction(prompt: string): string | undefined {
return "Respond in English unless the user explicitly requests another language."
}
function clampText(value: string, maxChars: number): string {
if (value.length <= maxChars) return value
return `${value.slice(0, Math.max(0, maxChars - 3))}...`
}
async function buildSkillsSystemInstruction(instanceId: string, sessionId: string): Promise<string | undefined> {
const session = sessions().get(instanceId)?.get(sessionId)
const selected = session?.skills ?? []
if (selected.length === 0) return undefined
const details = await loadSkillDetails(selected.map((skill) => skill.id))
if (details.length === 0) return undefined
const sections: string[] = []
for (const detail of details) {
const header = detail.name ? `# Skill: ${detail.name}` : `# Skill: ${detail.id}`
const content = detail.content ? clampText(detail.content.trim(), 4000) : ""
sections.push(`${header}\n${content}`.trim())
}
const payload = sections.join("\n\n")
if (!payload) return undefined
return `You have access to the following skills. Follow their instructions when relevant.\n\n${payload}`
}
async function mergeSystemInstructions(
instanceId: string,
sessionId: string,
prompt: string,
): Promise<string | undefined> {
const [languageSystem, skillsSystem] = await Promise.all([
Promise.resolve(buildLanguageSystemInstruction(prompt)),
buildSkillsSystemInstruction(instanceId, sessionId),
])
if (languageSystem && skillsSystem) {
return `${languageSystem}\n\n${skillsSystem}`
}
return languageSystem || skillsSystem
}
function extractPlainTextFromParts(parts: Array<{ type?: string; text?: unknown; filename?: string }>): string {
const segments: string[] = []
for (const part of parts) {
@@ -821,7 +862,7 @@ async function sendMessage(
})
const providerId = effectiveModel.providerId
const languageSystem = buildLanguageSystemInstruction(prompt)
const systemMessage = await mergeSystemInstructions(instanceId, sessionId, prompt)
if (providerId === "ollama-cloud" || providerId === "qwen-oauth" || providerId === "opencode-zen" || providerId === "zai") {
const store = messageStoreBus.getOrCreate(instanceId)
const now = Date.now()
@@ -861,7 +902,7 @@ async function sendMessage(
sessionId,
providerId,
effectiveModel.modelId,
languageSystem,
systemMessage,
messageId,
assistantMessageId,
assistantPartId,
@@ -872,7 +913,7 @@ async function sendMessage(
sessionId,
providerId,
effectiveModel.modelId,
languageSystem,
systemMessage,
messageId,
assistantMessageId,
assistantPartId,
@@ -883,7 +924,7 @@ async function sendMessage(
sessionId,
providerId,
effectiveModel.modelId,
languageSystem,
systemMessage,
messageId,
assistantMessageId,
assistantPartId,
@@ -921,7 +962,7 @@ async function sendMessage(
sessionId,
providerId,
effectiveModel.modelId,
languageSystem,
systemMessage,
token.access_token,
token.resource_url,
messageId,
@@ -989,7 +1030,7 @@ async function sendMessage(
modelID: effectiveModel.modelId,
},
}),
...(languageSystem && { system: languageSystem }),
...(systemMessage && { system: systemMessage }),
}
log.info("sendMessage", {