opencode and native tasks
This commit is contained in:
@@ -2,7 +2,8 @@ import type { ServerWebSocket } from 'bun';
|
||||
import { mkdir, rename } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import type { ClientMessage, ServerMessage, ImageData, TaskInfo } from '@@/api/chat-types';
|
||||
import { getTmpAttachmentsDir, getAttachmentsDir } from '@@/data-path';
|
||||
import { getTmpAttachmentsDir, getAttachmentsDir, getNativeSkillsDir, getGlobalSkillsDir, getUserSkillsDir } from '@@/data-path';
|
||||
import { readSkillDirs, parseFrontmatter } from '@@/api/skills/skills';
|
||||
import { createTaskLog, appendToLog, finalizeLog } from '@@/api/task-logger';
|
||||
|
||||
const OPENCODE_PORT = process.env.OPENCODE_PORT ?? '10006';
|
||||
@@ -303,6 +304,29 @@ function handleSSEEvent(ws: ServerWebSocket<WSData>, event: string, data: any) {
|
||||
}
|
||||
}
|
||||
|
||||
async function buildSkillsPrompt(email: string): Promise<string> {
|
||||
const nativeSkills = await readSkillDirs(getNativeSkillsDir());
|
||||
const globalSkills = await readSkillDirs(getGlobalSkillsDir());
|
||||
const userSkills = await readSkillDirs(getUserSkillsDir(email));
|
||||
|
||||
const merged = new Map(nativeSkills);
|
||||
for (const [name, path] of globalSkills) merged.set(name, path);
|
||||
for (const [name, path] of userSkills) merged.set(name, path);
|
||||
|
||||
if (merged.size === 0) return '';
|
||||
|
||||
const lines = await Promise.all(
|
||||
Array.from(merged.entries()).map(async ([dirName, filePath]) => {
|
||||
const raw = await Bun.file(filePath).text();
|
||||
const { frontmatter } = parseFrontmatter(raw);
|
||||
const name = frontmatter.name || dirName;
|
||||
return `- ${name}: ${frontmatter.description} (read ${filePath} for full instructions)`;
|
||||
}),
|
||||
);
|
||||
|
||||
return `\n\nYou have access to the following skills. When a user's request matches a skill, read its SKILL.md file for detailed instructions before proceeding.\n\nAvailable skills:\n${lines.join('\n')}`;
|
||||
}
|
||||
|
||||
type HandleChatParams = {
|
||||
ws: ServerWebSocket<WSData>;
|
||||
prompt: string;
|
||||
@@ -368,6 +392,9 @@ async function handleChat({ ws, prompt, sessionId, model, attachmentIds, images,
|
||||
}
|
||||
}
|
||||
|
||||
const skillsAppend = await buildSkillsPrompt(ws.data.email);
|
||||
const fullPrompt = skillsAppend ? `${skillsAppend}\n\n${prompt}` : prompt;
|
||||
|
||||
const parts: Record<string, unknown>[] = [];
|
||||
if (images?.length) {
|
||||
for (const img of images) {
|
||||
@@ -378,7 +405,7 @@ async function handleChat({ ws, prompt, sessionId, model, attachmentIds, images,
|
||||
});
|
||||
}
|
||||
}
|
||||
parts.push({ type: 'text', text: prompt });
|
||||
parts.push({ type: 'text', text: fullPrompt });
|
||||
|
||||
const promptBody: Record<string, unknown> = { parts };
|
||||
if (modelSelection.modelId) {
|
||||
|
||||
Reference in New Issue
Block a user