chore: retire zen-backed summarization
Disable the active Zen summarization flow because the unauthenticated/free Zen provider is no longer available and now returns usage-limit errors for this feature.
Keep /api/text/summarize as an API-compatible stub that returns local sanitized or distilled fallback text with summarized=false, rather than attempting external model calls.
Remove notification and voice playback summary behavior from runtime paths. Notification {last_message} now always uses normalized truncated text, and TTS playback ignores historical summarize request fields.
Hide the notification summary settings and voice summarize-before-playback controls while preserving legacy persisted settings for compatibility. Also disable Zen model startup validation and make Zen model list routes return empty results.
Update module documentation and tests to describe the retired provider behavior and the remaining compatibility stubs.
This commit is contained in:
@@ -22,19 +22,6 @@ type SystemRuntimeDeps = {
|
||||
clientReloadDelayMs: number;
|
||||
};
|
||||
|
||||
type NotificationBridgePayload = {
|
||||
title?: string;
|
||||
body?: string;
|
||||
tag?: string;
|
||||
};
|
||||
|
||||
type NotificationsNotifyRequestPayload = {
|
||||
payload?: NotificationBridgePayload;
|
||||
};
|
||||
|
||||
const ZEN_MODELS_URL = 'https://opencode.ai/zen/v1/models';
|
||||
const ZEN_MODELS_CACHE_TTL_MS = 5 * 60 * 1000;
|
||||
let cachedZenModels: { models: Array<{ id: string; owned_by?: string }>; at: number } | null = null;
|
||||
|
||||
const getOpenChamberConfigDir = (): string => {
|
||||
if (process.platform === 'win32') {
|
||||
@@ -91,11 +78,6 @@ const virtualDiffContents = new Map<string, string>();
|
||||
let virtualDiffCounter = 0;
|
||||
let virtualDiffProviderDisposable: vscode.Disposable | null = null;
|
||||
|
||||
const asObject = (value: unknown): Record<string, unknown> | null =>
|
||||
value && typeof value === 'object' && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
: null;
|
||||
|
||||
const ensureVirtualDiffProviderRegistered = (ctx?: BridgeContext): void => {
|
||||
if (virtualDiffProviderDisposable) {
|
||||
return;
|
||||
@@ -204,56 +186,7 @@ const reconstructOriginalContentFromPatch = (modifiedContent: string, patch: str
|
||||
return lines.join('\n');
|
||||
};
|
||||
|
||||
const fetchFreeZenModels = async (): Promise<Array<{ id: string; owned_by?: string }>> => {
|
||||
const now = Date.now();
|
||||
if (cachedZenModels && now - cachedZenModels.at < ZEN_MODELS_CACHE_TTL_MS) {
|
||||
return cachedZenModels.models;
|
||||
}
|
||||
|
||||
const signal = AbortSignal.timeout(8_000);
|
||||
const [response, metadataResponse] = await Promise.all([
|
||||
fetch(ZEN_MODELS_URL, {
|
||||
headers: { Accept: 'application/json' },
|
||||
signal,
|
||||
}),
|
||||
fetch('https://models.dev/api.json', {
|
||||
headers: { Accept: 'application/json' },
|
||||
signal,
|
||||
}),
|
||||
]);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`zen models request failed (${response.status})`);
|
||||
}
|
||||
if (!metadataResponse.ok) {
|
||||
throw new Error(`models.dev request failed (${metadataResponse.status})`);
|
||||
}
|
||||
|
||||
const rawPayload = await response.json().catch(() => null);
|
||||
const rawMetadata = await metadataResponse.json().catch(() => null);
|
||||
const payload = asObject(rawPayload);
|
||||
const metadata = asObject(rawMetadata);
|
||||
const metadataProvider = asObject(metadata?.opencode);
|
||||
const metadataModels = asObject(metadataProvider?.models);
|
||||
const rows = Array.isArray(payload?.data) ? payload.data : [];
|
||||
const models = rows
|
||||
.map((entry) => {
|
||||
const id = typeof (entry as { id?: unknown })?.id === 'string'
|
||||
? (entry as { id: string }).id.trim()
|
||||
: '';
|
||||
const ownedBy = typeof (entry as { owned_by?: unknown })?.owned_by === 'string'
|
||||
? (entry as { owned_by: string }).owned_by
|
||||
: undefined;
|
||||
const metadataModel = asObject(metadataModels?.[id]);
|
||||
const cost = asObject(metadataModel?.cost);
|
||||
if (!id || cost?.input !== 0 || cost?.output !== 0) return null;
|
||||
return ownedBy ? { id, owned_by: ownedBy } : { id };
|
||||
})
|
||||
.filter((entry): entry is { id: string; owned_by?: string } => entry !== null);
|
||||
|
||||
cachedZenModels = { models, at: Date.now() };
|
||||
return models;
|
||||
};
|
||||
const fetchFreeZenModels = async (): Promise<Array<{ id: string; owned_by?: string }>> => [];
|
||||
|
||||
export async function handleSystemBridgeMessage(
|
||||
message: BridgeMessageInput,
|
||||
@@ -293,16 +226,8 @@ export async function handleSystemBridgeMessage(
|
||||
}
|
||||
|
||||
case 'api:zen:models': {
|
||||
try {
|
||||
const models = await fetchFreeZenModels();
|
||||
return { id, type, success: true, data: { models } };
|
||||
} catch (error) {
|
||||
if (cachedZenModels) {
|
||||
return { id, type, success: true, data: { models: cachedZenModels.models } };
|
||||
}
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
return { id, type, success: false, error: errorMessage };
|
||||
}
|
||||
const models = await fetchFreeZenModels();
|
||||
return { id, type, success: true, data: { models } };
|
||||
}
|
||||
|
||||
case 'api:openchamber:update-check': {
|
||||
@@ -546,26 +471,13 @@ export async function handleSystemBridgeMessage(
|
||||
}
|
||||
}
|
||||
|
||||
case 'notifications:can-notify': {
|
||||
return { id, type, success: true, data: true };
|
||||
}
|
||||
|
||||
case 'notifications:notify': {
|
||||
const request = (payload || {}) as NotificationsNotifyRequestPayload;
|
||||
const notification = request.payload || {};
|
||||
const title = typeof notification.title === 'string' ? notification.title.trim() : '';
|
||||
const body = typeof notification.body === 'string' ? notification.body.trim() : '';
|
||||
|
||||
const message = title && body
|
||||
? `${title}: ${body}`
|
||||
: title || body;
|
||||
|
||||
if (!message) {
|
||||
return { id, type, success: true, data: { shown: false } };
|
||||
case 'api:notifications/auto-accept': {
|
||||
const request = (payload || {}) as { sessionId?: unknown; enabled?: unknown };
|
||||
const sessionId = typeof request.sessionId === 'string' ? request.sessionId.trim() : '';
|
||||
if (!sessionId) {
|
||||
return { id, type, success: false, error: 'sessionId is required' };
|
||||
}
|
||||
|
||||
void vscode.window.showInformationMessage(message);
|
||||
return { id, type, success: true, data: { shown: true } };
|
||||
return { id, type, success: true, data: { success: true } };
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user