dist / generator.js
dist / generator.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.completionUrl = completionUrl;
exports.generate = generate;
const config_1 = require("./config");
const messages_1 = require("./messages");
const stream_1 = require("./stream");
const toolBridge_1 = require("./toolBridge");
const analysisHandoff_1 = require("./analysisHandoff");
const titleGeneration_1 = require("./titleGeneration");
function completionUrl(input) {
const url = new URL(input.trim());
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.search || url.hash) {
throw new Error("Base URL must be an HTTP(S) address without credentials, query or fragment.");
}
const path = url.pathname.replace(/\/+$/, "");
url.pathname = path.endsWith("/chat/completions") ? path : `${path.endsWith("/v1") ? path : `${path}/v1`}/chat/completions`;
return url.toString();
}
async function generate(ctl, history) {
const config = ctl.getPluginConfig(config_1.configSchematics);
const global = ctl.getGlobalPluginConfig(config_1.globalConfigSchematics);
const model = config.get("model").trim();
if (!model)
throw new Error("Set the Strata model ID.");
const endpoint = completionUrl(global.get("baseUrl"));
const key = global.get("apiKey").trim();
const headers = { "Content-Type": "application/json", ...(key ? { Authorization: `Bearer ${key}` } : {}) };
if ((0, titleGeneration_1.isTitleRequest)(history)) {
await (0, titleGeneration_1.generateTitle)(ctl, history, endpoint, model, headers);
return;
}
const bridge = new toolBridge_1.ToolBridge(ctl.getToolDefinitions());
const tools = bridge.tools;
const messages = await (0, analysisHandoff_1.completeDeferredAnalyses)(history, await (0, messages_1.toMessages)(history, ctl.client, ctl.abortSignal, {
getSnapshotRoot: () => ctl.getWorkingDirectory(), warn: message => console.warn("[Strata]", message),
}), () => ctl.getWorkingDirectory(), ctl.abortSignal, async (imageUrl, prompt) => {
const response = await fetch(endpoint, {
method: "POST", headers, signal: ctl.abortSignal, redirect: "error",
body: JSON.stringify({ model, stream: false, reasoning_effort: "none", max_tokens: 2048,
messages: [{ role: "user", content: [
{ type: "text", text: prompt }, { type: "image_url", image_url: { url: imageUrl } },
] }],
}),
});
if (!response.ok) {
await response.body?.cancel();
throw new Error(`Strata image-analysis subrequest failed: HTTP ${response.status}.`);
}
const result = await response.json();
if (result.error)
throw new Error(`Strata image-analysis subrequest failed: ${result.error.message ?? "unknown error"}`);
const content = result.choices?.[0]?.message?.content;
if (typeof content !== "string" || !content.trim())
throw new Error("Strata image-analysis subrequest returned no answer.");
return content;
});
const payload = {
model,
messages: bridge.mapHistory(messages),
stream: true,
...(tools.length ? { tools, parallel_tool_calls: false } : {}),
...(config.get("thinking") !== "default" ? { reasoning_effort: config.get("thinking") } : {}),
...(config.get("maxTokens") > 0 ? { max_tokens: config.get("maxTokens") } : {}),
...(config.get("thinkingBudget") > 0 ? { reasoning_budget_tokens: config.get("thinkingBudget") } : {}),
};
const response = await fetch(endpoint, {
method: "POST",
headers,
body: JSON.stringify(payload),
signal: ctl.abortSignal,
redirect: "error",
});
if (!response.ok) {
await response.body?.cancel();
throw new Error(`Strata HTTP ${response.status}. Check Base URL, API key, model and vision setup in Strata.`);
}
if (!response.body || !response.headers.get("content-type")?.includes("text/event-stream")) {
await response.body?.cancel();
throw new Error("Strata did not return an SSE stream (text/event-stream). Check the endpoint.");
}
await (0, stream_1.consumeStream)(response.body, ctl, bridge);
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.completionUrl = completionUrl;
exports.generate = generate;
const config_1 = require("./config");
const messages_1 = require("./messages");
const stream_1 = require("./stream");
const toolBridge_1 = require("./toolBridge");
const analysisHandoff_1 = require("./analysisHandoff");
const titleGeneration_1 = require("./titleGeneration");
function completionUrl(input) {
const url = new URL(input.trim());
if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.search || url.hash) {
throw new Error("Base URL must be an HTTP(S) address without credentials, query or fragment.");
}
const path = url.pathname.replace(/\/+$/, "");
url.pathname = path.endsWith("/chat/completions") ? path : `${path.endsWith("/v1") ? path : `${path}/v1`}/chat/completions`;
return url.toString();
}
async function generate(ctl, history) {
const config = ctl.getPluginConfig(config_1.configSchematics);
const global = ctl.getGlobalPluginConfig(config_1.globalConfigSchematics);
const model = config.get("model").trim();
if (!model)
throw new Error("Set the Strata model ID.");
const endpoint = completionUrl(global.get("baseUrl"));
const key = global.get("apiKey").trim();
const headers = { "Content-Type": "application/json", ...(key ? { Authorization: `Bearer ${key}` } : {}) };
if ((0, titleGeneration_1.isTitleRequest)(history)) {
await (0, titleGeneration_1.generateTitle)(ctl, history, endpoint, model, headers);
return;
}
const bridge = new toolBridge_1.ToolBridge(ctl.getToolDefinitions());
const tools = bridge.tools;
const messages = await (0, analysisHandoff_1.completeDeferredAnalyses)(history, await (0, messages_1.toMessages)(history, ctl.client, ctl.abortSignal, {
getSnapshotRoot: () => ctl.getWorkingDirectory(), warn: message => console.warn("[Strata]", message),
}), () => ctl.getWorkingDirectory(), ctl.abortSignal, async (imageUrl, prompt) => {
const response = await fetch(endpoint, {
method: "POST", headers, signal: ctl.abortSignal, redirect: "error",
body: JSON.stringify({ model, stream: false, reasoning_effort: "none", max_tokens: 2048,
messages: [{ role: "user", content: [
{ type: "text", text: prompt }, { type: "image_url", image_url: { url: imageUrl } },
] }],
}),
});
if (!response.ok) {
await response.body?.cancel();
throw new Error(`Strata image-analysis subrequest failed: HTTP ${response.status}.`);
}
const result = await response.json();
if (result.error)
throw new Error(`Strata image-analysis subrequest failed: ${result.error.message ?? "unknown error"}`);
const content = result.choices?.[0]?.message?.content;
if (typeof content !== "string" || !content.trim())
throw new Error("Strata image-analysis subrequest returned no answer.");
return content;
});
const payload = {
model,
messages: bridge.mapHistory(messages),
stream: true,
...(tools.length ? { tools, parallel_tool_calls: false } : {}),
...(config.get("thinking") !== "default" ? { reasoning_effort: config.get("thinking") } : {}),
...(config.get("maxTokens") > 0 ? { max_tokens: config.get("maxTokens") } : {}),
...(config.get("thinkingBudget") > 0 ? { reasoning_budget_tokens: config.get("thinkingBudget") } : {}),
};
const response = await fetch(endpoint, {
method: "POST",
headers,
body: JSON.stringify(payload),
signal: ctl.abortSignal,
redirect: "error",
});
if (!response.ok) {
await response.body?.cancel();
throw new Error(`Strata HTTP ${response.status}. Check Base URL, API key, model and vision setup in Strata.`);
}
if (!response.body || !response.headers.get("content-type")?.includes("text/event-stream")) {
await response.body?.cancel();
throw new Error("Strata did not return an SSE stream (text/event-stream). Check the endpoint.");
}
await (0, stream_1.consumeStream)(response.body, ctl, bridge);
}