refactor(text): extract shared summarization service with tts/note/notification modes
Move server-side summarization out of lib/tts/summarization.js into a shared lib/text module exposing tts, note and notification modes. TTS and notification runtimes now delegate to the shared service, note mode is used to distill a selected excerpt into a short project note. Expose the new endpoint via /api/text/summarize and route it through the common request middleware. Client voice/summarize.ts accepts a mode option and points at the new endpoint with an absolute URL that respects the desktop server origin. VS Code webview swaps the stubbed tts summarize path for /api/text/summarize and hardens URL parsing with window.location.href as the base.
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { summarizeText as summarizeSharedText } from '../text/summarization.js';
|
||||
|
||||
export const createNotificationTemplateRuntime = (deps) => {
|
||||
const {
|
||||
readSettingsFromDisk,
|
||||
@@ -136,39 +138,16 @@ export const createNotificationTemplateRuntime = (deps) => {
|
||||
|
||||
const summarizeText = async (text, targetLength, zenModel) => {
|
||||
if (!text || typeof text !== 'string' || text.trim().length === 0) return text;
|
||||
|
||||
try {
|
||||
const prompt = `Summarize the following text in approximately ${targetLength} characters. Be concise and capture the key point. Output plain text only. Do not use markdown, bullets, headings, code fences, backticks, or quotes. Output only the summary text.\n\nText:\n${text}`;
|
||||
|
||||
const completionTimeout = createTimeoutSignal(15000);
|
||||
let response;
|
||||
try {
|
||||
response = await fetch('https://opencode.ai/zen/v1/responses', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
model: zenModel || ZEN_DEFAULT_MODEL,
|
||||
input: [{ role: 'user', content: prompt }],
|
||||
max_output_tokens: 1000,
|
||||
stream: false,
|
||||
reasoning: { effort: 'low' },
|
||||
}),
|
||||
signal: completionTimeout.signal,
|
||||
});
|
||||
} finally {
|
||||
completionTimeout.cleanup();
|
||||
}
|
||||
|
||||
if (!response.ok) return text;
|
||||
|
||||
const data = await response.json();
|
||||
const summary = data?.output?.find((item) => item?.type === 'message')
|
||||
?.content?.find((item) => item?.type === 'output_text')?.text?.trim();
|
||||
|
||||
return summary || text;
|
||||
} catch {
|
||||
return text;
|
||||
}
|
||||
const result = await summarizeSharedText({
|
||||
text,
|
||||
threshold: 0,
|
||||
maxLength: targetLength,
|
||||
zenModel: zenModel || ZEN_DEFAULT_MODEL,
|
||||
mode: 'notification',
|
||||
});
|
||||
return typeof result?.summary === 'string' && result.summary.trim().length > 0
|
||||
? result.summary
|
||||
: text;
|
||||
};
|
||||
|
||||
const extractTextFromParts = (parts, maxLength = NOTIFICATION_BODY_MAX_CHARS) => {
|
||||
|
||||
Reference in New Issue
Block a user