Compare commits

...

2 Commits

Author SHA1 Message Date
thomas 39e7bddb35 update pi 2026-03-27 14:22:06 +00:00
thomas d5b4042b06 add gsf 2026-03-25 19:12:49 +00:00
14 changed files with 117 additions and 65 deletions
+18
View File
@@ -0,0 +1,18 @@
---@class SigilConfig
---@field target table<string, string|boolean>
---@field ignore? string[]
---@type SigilConfig
local config = {
target = {
linux = "~/.config/gsf",
default = "~/.config/gsf",
},
ignore = {
-- "**/.DS_Store",
-- "**/*.tmp",
-- "cache/**",
},
}
return config
+17
View File
@@ -0,0 +1,17 @@
{
"mode": 0,
"sens_mult": 1.5,
"yx_ratio": 1.0,
"input_dpi": 400.0,
"angle_rotation": 0.0,
"accel": 2.0,
"offset_linear": 3.5,
"output_cap": 30.0,
"decay_rate": 0.1,
"offset_natural": 0.0,
"limit": 2.0,
"gamma": 1.0,
"smooth": 0.5,
"motivity": 1.5,
"sync_speed": 5.0
}
+1 -1
View File
@@ -1,5 +1,5 @@
{ {
"lastChangelogVersion": "0.60.0", "lastChangelogVersion": "0.63.1",
"defaultProvider": "openai-codex", "defaultProvider": "openai-codex",
"defaultModel": "gpt-5.3-codex", "defaultModel": "gpt-5.3-codex",
"defaultThinkingLevel": "high", "defaultThinkingLevel": "high",
+1
View File
@@ -0,0 +1 @@
{}
+4 -4
View File
@@ -9,8 +9,8 @@
* The editor is determined by $VISUAL, then $EDITOR, then falls back to 'vi'. * The editor is determined by $VISUAL, then $EDITOR, then falls back to 'vi'.
*/ */
import type { ExtensionAPI, ExtensionCommandContext } from "@mariozechner/pi-coding-agent"; import type { ExtensionAPI, ExtensionCommandContext, Theme } from "@mariozechner/pi-coding-agent";
import type { TUI, Theme, KeybindingsManager, Component } from "@mariozechner/pi-tui"; import type { TUI, KeybindingsManager, Component } from "@mariozechner/pi-tui";
import { spawnSync } from "node:child_process"; import { spawnSync } from "node:child_process";
export default function editSessionExtension(pi: ExtensionAPI) { export default function editSessionExtension(pi: ExtensionAPI) {
@@ -59,7 +59,7 @@ export default function editSessionExtension(pi: ExtensionAPI) {
ctx.ui.notify(`Editor exited with code ${result.status}`, "warning"); ctx.ui.notify(`Editor exited with code ${result.status}`, "warning");
} }
done(); done(undefined);
// Return dummy component // Return dummy component
return createDummyComponent(); return createDummyComponent();
@@ -69,7 +69,7 @@ export default function editSessionExtension(pi: ExtensionAPI) {
await ctx.ui.custom<void>(factory); await ctx.ui.custom<void>(factory);
// Signal that we're about to reload the session (so confirm-destructive skips) // Signal that we're about to reload the session (so confirm-destructive skips)
pi.events.emit("edit-session:reload"); pi.events.emit("edit-session:reload", undefined);
// Reload the session by switching to the same file (forces re-read from disk) // Reload the session by switching to the same file (forces re-read from disk)
ctx.ui.notify("Reloading session...", "info"); ctx.ui.notify("Reloading session...", "info");
+3 -2
View File
@@ -80,7 +80,8 @@ export default function (pi: ExtensionAPI) {
loader.onAbort = () => done(null); loader.onAbort = () => done(null);
const doGenerate = async () => { const doGenerate = async () => {
const apiKey = await ctx.modelRegistry.getApiKey(ctx.model!); const auth = await ctx.modelRegistry.getApiKeyAndHeaders(ctx.model!);
if (!auth.ok) throw new Error(auth.error);
const userMessage: Message = { const userMessage: Message = {
role: "user", role: "user",
@@ -96,7 +97,7 @@ export default function (pi: ExtensionAPI) {
const response = await complete( const response = await complete(
ctx.model!, ctx.model!,
{ systemPrompt: SYSTEM_PROMPT, messages: [userMessage] }, { systemPrompt: SYSTEM_PROMPT, messages: [userMessage] },
{ apiKey, signal: loader.signal }, { apiKey: auth.apiKey, headers: auth.headers, signal: loader.signal },
); );
if (response.stopReason === "aborted") { if (response.stopReason === "aborted") {
+4 -3
View File
@@ -13,10 +13,11 @@
"vscode-languageserver-protocol": "^3.17.5" "vscode-languageserver-protocol": "^3.17.5"
}, },
"devDependencies": { "devDependencies": {
"@mariozechner/pi-ai": "^0.56.3", "@mariozechner/pi-ai": "^0.63.1",
"@mariozechner/pi-coding-agent": "^0.56.3", "@mariozechner/pi-coding-agent": "^0.63.1",
"@mariozechner/pi-tui": "^0.56.3", "@mariozechner/pi-tui": "^0.63.1",
"@types/node": "^25.3.3", "@types/node": "^25.3.3",
"@types/turndown": "^5.0.6",
"typescript": "^5.7.0" "typescript": "^5.7.0"
}, },
"pi": {}, "pi": {},
@@ -211,12 +211,12 @@ function updateWidget(ctx: ExtensionContext): void {
(resetMs > 0 ? theme.fg("dim", ` (resets in ${resetSec}s)`) : ""), (resetMs > 0 ? theme.fg("dim", ` (resets in ${resetSec}s)`) : ""),
); );
ctx.ui.setWidget("web-activity", new Text(lines.join("\n"), 0, 0)); ctx.ui.setWidget("web-activity", lines);
} }
function formatEntryLine( function formatEntryLine(
entry: ActivityEntry, entry: ActivityEntry,
theme: { fg: (color: string, text: string) => string }, theme: ExtensionContext["ui"]["theme"],
): string { ): string {
const typeStr = entry.type === "api" ? "API" : "GET"; const typeStr = entry.type === "api" ? "API" : "GET";
const target = const target =
@@ -550,7 +550,7 @@ export default function (pi: ExtensionAPI) {
} else { } else {
widgetUnsubscribe?.(); widgetUnsubscribe?.();
widgetUnsubscribe = null; widgetUnsubscribe = null;
ctx.ui.setWidget("web-activity", null); ctx.ui.setWidget("web-activity", undefined);
} }
}, },
}); });
@@ -598,7 +598,7 @@ export default function (pi: ExtensionAPI) {
})), })),
}), }),
async execute(_toolCallId, params, signal, onUpdate, ctx) { async execute(_toolCallId, params, signal, onUpdate, ctx): Promise<any> {
const queryList = params.queries ?? (params.query ? [params.query] : []); const queryList = params.queries ?? (params.query ? [params.query] : []);
const isMultiQuery = queryList.length > 1; const isMultiQuery = queryList.length > 1;
const shouldCurate = params.curate !== false && ctx?.hasUI !== false; const shouldCurate = params.curate !== false && ctx?.hasUI !== false;
@@ -613,7 +613,10 @@ export default function (pi: ExtensionAPI) {
if (shouldCurate) { if (shouldCurate) {
closeCurator(); closeCurator();
const { promise, resolve: resolvePromise } = Promise.withResolvers<unknown>(); let resolvePromise!: (value: unknown) => void;
const promise = new Promise<unknown>((resolve) => {
resolvePromise = resolve;
});
const includeContent = params.includeContent ?? false; const includeContent = params.includeContent ?? false;
const searchResults = new Map<number, QueryResultData>(); const searchResults = new Map<number, QueryResultData>();
const allUrls: string[] = []; const allUrls: string[] = [];
@@ -637,7 +640,7 @@ export default function (pi: ExtensionAPI) {
queryList, queryList,
includeContent, includeContent,
numResults: params.numResults, numResults: params.numResults,
recencyFilter: params.recencyFilter, recencyFilter: params.recencyFilter as "day" | "week" | "month" | "year" | undefined,
domainFilter: params.domainFilter, domainFilter: params.domainFilter,
availableProviders, availableProviders,
defaultProvider, defaultProvider,
@@ -684,7 +687,7 @@ export default function (pi: ExtensionAPI) {
const { answer, results } = await search(queryList[qi], { const { answer, results } = await search(queryList[qi], {
provider: defaultProvider as SearchProvider | undefined, provider: defaultProvider as SearchProvider | undefined,
numResults: params.numResults, numResults: params.numResults,
recencyFilter: params.recencyFilter, recencyFilter: params.recencyFilter as "day" | "week" | "month" | "year" | undefined,
domainFilter: params.domainFilter, domainFilter: params.domainFilter,
signal, signal,
}); });
@@ -754,7 +757,7 @@ export default function (pi: ExtensionAPI) {
text = `${searchResults.size} searches (${totalSources} sources) · ${curateLabel} to review · sending in ${remaining}s`; text = `${searchResults.size} searches (${totalSources} sources) · ${curateLabel} to review · sending in ${remaining}s`;
} }
return { return {
content: [{ type: "text", text }], content: [{ type: "text" as const, text }],
details: { details: {
phase: "curate-window", phase: "curate-window",
searchCount: searchResults.size, searchCount: searchResults.size,
@@ -824,7 +827,7 @@ export default function (pi: ExtensionAPI) {
const { answer, results } = await search(query, { const { answer, results } = await search(query, {
provider: resolvedProvider as SearchProvider | undefined, provider: resolvedProvider as SearchProvider | undefined,
numResults: params.numResults, numResults: params.numResults,
recencyFilter: params.recencyFilter, recencyFilter: params.recencyFilter as "day" | "week" | "month" | "year" | undefined,
domainFilter: params.domainFilter, domainFilter: params.domainFilter,
signal, signal,
}); });
@@ -1117,7 +1120,10 @@ export default function (pi: ExtensionAPI) {
`Use get_search_content({ responseId: "${responseId}", urlIndex: 0 }) for full content.`; `Use get_search_content({ responseId: "${responseId}", urlIndex: 0 }) for full content.`;
} }
const content: Array<{ type: string; text?: string; data?: string; mimeType?: string }> = []; const content: Array<
| { type: "image"; data: string; mimeType: string }
| { type: "text"; text: string }
> = [];
if (result.frames?.length) { if (result.frames?.length) {
for (const frame of result.frames) { for (const frame of result.frames) {
content.push({ type: "image", data: frame.data, mimeType: frame.mimeType }); content.push({ type: "image", data: frame.data, mimeType: frame.mimeType });
@@ -1290,7 +1296,7 @@ export default function (pi: ExtensionAPI) {
urlIndex: Type.Optional(Type.Number({ description: "Get content for URL at index" })), urlIndex: Type.Optional(Type.Number({ description: "Get content for URL at index" })),
}), }),
async execute(_toolCallId, params) { async execute(_toolCallId, params, _signal, _onUpdate, _ctx): Promise<any> {
const data = getResult(params.responseId); const data = getResult(params.responseId);
if (!data) { if (!data) {
return { return {
@@ -1477,7 +1483,7 @@ export default function (pi: ExtensionAPI) {
pi.sendMessage({ pi.sendMessage({
customType: "web-search-results", customType: "web-search-results",
content: [{ type: "text", text }], content: [{ type: "text", text }],
display: "tool", display: true,
details: { queryCount: results.length, totalResults: urls.length }, details: { queryCount: results.length, totalResults: urls.length },
}, { triggerTurn: true, deliverAs: "followUp" }); }, { triggerTurn: true, deliverAs: "followUp" });
} }
@@ -42,9 +42,10 @@ export async function extractPDFToMarkdown(
const pdf = await getDocumentProxy(new Uint8Array(buffer)); const pdf = await getDocumentProxy(new Uint8Array(buffer));
const metadata = await pdf.getMetadata(); const metadata = await pdf.getMetadata();
const info = (metadata.info ?? {}) as Record<string, unknown>;
// Extract title from metadata or URL // Extract title from metadata or URL
const metaTitle = metadata.info?.Title as string | undefined; const metaTitle = typeof info.Title === "string" ? info.Title : undefined;
const urlTitle = extractTitleFromURL(url); const urlTitle = extractTitleFromURL(url);
const title = metaTitle?.trim() || urlTitle; const title = metaTitle?.trim() || urlTitle;
@@ -79,8 +80,9 @@ export async function extractPDFToMarkdown(
lines.push(""); lines.push("");
lines.push(`> Source: ${url}`); lines.push(`> Source: ${url}`);
lines.push(`> Pages: ${pdf.numPages}${truncated ? ` (extracted first ${pagesToExtract})` : ""}`); lines.push(`> Pages: ${pdf.numPages}${truncated ? ` (extracted first ${pagesToExtract})` : ""}`);
if (metadata.info?.Author) { const author = typeof info.Author === "string" ? info.Author : undefined;
lines.push(`> Author: ${metadata.info.Author}`); if (author) {
lines.push(`> Author: ${author}`);
} }
lines.push(""); lines.push("");
lines.push("---"); lines.push("---");
@@ -245,8 +245,8 @@ export async function condenseSearchResults(
const model = ctx.modelRegistry.find(provider, modelId); const model = ctx.modelRegistry.find(provider, modelId);
if (!model) return null; if (!model) return null;
const apiKey = await ctx.modelRegistry.getApiKey(model); const auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);
if (!apiKey) return null; if (!auth.ok) return null;
const queryData = [...results.entries()] const queryData = [...results.entries()]
.sort((a, b) => a[0] - b[0]) .sort((a, b) => a[0] - b[0])
@@ -281,7 +281,8 @@ export async function condenseSearchResults(
: timeoutSignal; : timeoutSignal;
const response = await complete(model, aiContext, { const response = await complete(model, aiContext, {
apiKey, apiKey: auth.apiKey,
headers: auth.headers,
signal: combinedSignal, signal: combinedSignal,
max_tokens: MAX_TOKENS, max_tokens: MAX_TOKENS,
} as any); } as any);
+31 -22
View File
@@ -34,17 +34,20 @@ importers:
version: 3.17.5 version: 3.17.5
devDependencies: devDependencies:
'@mariozechner/pi-ai': '@mariozechner/pi-ai':
specifier: ^0.56.3 specifier: ^0.63.1
version: 0.56.3(ws@8.19.0)(zod@4.3.6) version: 0.63.1(ws@8.19.0)(zod@4.3.6)
'@mariozechner/pi-coding-agent': '@mariozechner/pi-coding-agent':
specifier: ^0.56.3 specifier: ^0.63.1
version: 0.56.3(ws@8.19.0)(zod@4.3.6) version: 0.63.1(ws@8.19.0)(zod@4.3.6)
'@mariozechner/pi-tui': '@mariozechner/pi-tui':
specifier: ^0.56.3 specifier: ^0.63.1
version: 0.56.3 version: 0.63.1
'@types/node': '@types/node':
specifier: ^25.3.3 specifier: ^25.3.3
version: 25.3.3 version: 25.3.3
'@types/turndown':
specifier: ^5.0.6
version: 5.0.6
typescript: typescript:
specifier: ^5.7.0 specifier: ^5.7.0
version: 5.9.3 version: 5.9.3
@@ -289,22 +292,22 @@ packages:
resolution: {integrity: sha512-faGUlTcXka5l7rv0lP3K3vGW/ejRuOS24RR2aSFWREUQqzjgdsuWNo/IiPqL3kWRGt6Ahl2+qcDAwtdeWeuGUw==} resolution: {integrity: sha512-faGUlTcXka5l7rv0lP3K3vGW/ejRuOS24RR2aSFWREUQqzjgdsuWNo/IiPqL3kWRGt6Ahl2+qcDAwtdeWeuGUw==}
hasBin: true hasBin: true
'@mariozechner/pi-agent-core@0.56.3': '@mariozechner/pi-agent-core@0.63.1':
resolution: {integrity: sha512-TsI1zENf3wqqKPaERnj486Q4i6Y/y6lAZipLNcfDYUDxDrLwNfQ9EW9xukkbJfTZ8zjG3VZ2pBZe3C7wM51dVQ==} resolution: {integrity: sha512-h0B20xfs/iEVR2EC4gwiE8hKI1TPeB8REdRJMgV+uXKH7gpeIZ9+s8Dp9nX35ZR0QUjkNey2+ULk2DxQtdg14Q==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@mariozechner/pi-ai@0.56.3': '@mariozechner/pi-ai@0.63.1':
resolution: {integrity: sha512-l4J+cVyVeBLAlGOY/osGDvsbTz0DySCQmR171G6SdbPvIeLGhIi6siZ+zHwq91GJYjv/wtu/08M08ag2mGZKeA==} resolution: {integrity: sha512-wjgwY+yfrFO6a9QdAfjWpH7iSrDean6GsKDDMohNcLCy6PreMxHOZvNM0NwJARL1tZoZovr7ikAQfLGFZbnjsw==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
hasBin: true hasBin: true
'@mariozechner/pi-coding-agent@0.56.3': '@mariozechner/pi-coding-agent@0.63.1':
resolution: {integrity: sha512-yHgnadye+TT/4NWKBirZUjw/LWdNWTa7M4HJdX2RxRbwuj4q7RZ0Aqy+lQbOHEPDQYhxK3kZb9hjiAbbGficZQ==} resolution: {integrity: sha512-XSoMyLtuMA7ePK1UBWqSJ/BBdtBdJUHY9nbtnNyG6GeW7Gbgd+iqljIuwmAUf8wlYL981UIfYM/WIPQ6t/dIxw==}
engines: {node: '>=20.6.0'} engines: {node: '>=20.6.0'}
hasBin: true hasBin: true
'@mariozechner/pi-tui@0.56.3': '@mariozechner/pi-tui@0.63.1':
resolution: {integrity: sha512-eZ1P9QRKHp78hwx+lITr/mujZqe+eCwL/bOS9vXXkFP070RW4VYum0j7TJ4BrFEH/nNkXRS1tYCXYU05une1bA==} resolution: {integrity: sha512-G5p+eh1EPkFCNaaggX6vRrqttnDscK6npgmEOknoCQXZtch8XNgh9Lf3VJ0A2lZXSgR7IntG5dfXHPH/Ki64wA==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
'@mistralai/mistralai@1.14.1': '@mistralai/mistralai@1.14.1':
@@ -568,6 +571,9 @@ packages:
'@types/retry@0.12.0': '@types/retry@0.12.0':
resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==}
'@types/turndown@5.0.6':
resolution: {integrity: sha512-ru00MoyeeouE5BX4gRL+6m/BsDfbRayOskWqUvh7CLGW+UXxHQItqALa38kKnOiZPqJrtzJUgAC2+F0rL1S4Pg==}
'@types/yauzl@2.10.3': '@types/yauzl@2.10.3':
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
@@ -1722,9 +1728,9 @@ snapshots:
std-env: 3.10.0 std-env: 3.10.0
yoctocolors: 2.1.2 yoctocolors: 2.1.2
'@mariozechner/pi-agent-core@0.56.3(ws@8.19.0)(zod@4.3.6)': '@mariozechner/pi-agent-core@0.63.1(ws@8.19.0)(zod@4.3.6)':
dependencies: dependencies:
'@mariozechner/pi-ai': 0.56.3(ws@8.19.0)(zod@4.3.6) '@mariozechner/pi-ai': 0.63.1(ws@8.19.0)(zod@4.3.6)
transitivePeerDependencies: transitivePeerDependencies:
- '@modelcontextprotocol/sdk' - '@modelcontextprotocol/sdk'
- aws-crt - aws-crt
@@ -1734,7 +1740,7 @@ snapshots:
- ws - ws
- zod - zod
'@mariozechner/pi-ai@0.56.3(ws@8.19.0)(zod@4.3.6)': '@mariozechner/pi-ai@0.63.1(ws@8.19.0)(zod@4.3.6)':
dependencies: dependencies:
'@anthropic-ai/sdk': 0.73.0(zod@4.3.6) '@anthropic-ai/sdk': 0.73.0(zod@4.3.6)
'@aws-sdk/client-bedrock-runtime': 3.1002.0 '@aws-sdk/client-bedrock-runtime': 3.1002.0
@@ -1758,13 +1764,14 @@ snapshots:
- ws - ws
- zod - zod
'@mariozechner/pi-coding-agent@0.56.3(ws@8.19.0)(zod@4.3.6)': '@mariozechner/pi-coding-agent@0.63.1(ws@8.19.0)(zod@4.3.6)':
dependencies: dependencies:
'@mariozechner/jiti': 2.6.5 '@mariozechner/jiti': 2.6.5
'@mariozechner/pi-agent-core': 0.56.3(ws@8.19.0)(zod@4.3.6) '@mariozechner/pi-agent-core': 0.63.1(ws@8.19.0)(zod@4.3.6)
'@mariozechner/pi-ai': 0.56.3(ws@8.19.0)(zod@4.3.6) '@mariozechner/pi-ai': 0.63.1(ws@8.19.0)(zod@4.3.6)
'@mariozechner/pi-tui': 0.56.3 '@mariozechner/pi-tui': 0.63.1
'@silvia-odwyer/photon-node': 0.3.4 '@silvia-odwyer/photon-node': 0.3.4
ajv: 8.18.0
chalk: 5.6.2 chalk: 5.6.2
cli-highlight: 2.1.11 cli-highlight: 2.1.11
diff: 8.0.3 diff: 8.0.3
@@ -1790,7 +1797,7 @@ snapshots:
- ws - ws
- zod - zod
'@mariozechner/pi-tui@0.56.3': '@mariozechner/pi-tui@0.63.1':
dependencies: dependencies:
'@types/mime-types': 2.1.4 '@types/mime-types': 2.1.4
chalk: 5.6.2 chalk: 5.6.2
@@ -2166,6 +2173,8 @@ snapshots:
'@types/retry@0.12.0': {} '@types/retry@0.12.0': {}
'@types/turndown@5.0.6': {}
'@types/yauzl@2.10.3': '@types/yauzl@2.10.3':
dependencies: dependencies:
'@types/node': 25.3.3 '@types/node': 25.3.3
+8 -7
View File
@@ -135,11 +135,11 @@ export default function(pi: ExtensionAPI) {
// Fire-and-forget: run auto-naming in background without blocking // Fire-and-forget: run auto-naming in background without blocking
const doAutoName = async () => { const doAutoName = async () => {
const apiKey = await ctx.modelRegistry.getApiKey(AUTO_NAME_MODEL); const auth = await ctx.modelRegistry.getApiKeyAndHeaders(AUTO_NAME_MODEL);
log(`Got API key: ${apiKey ? "yes" : "no"}`); log(`Got API key: ${auth.ok ? "yes" : "no"}`);
if (!apiKey) { if (!auth.ok) {
log("No API key available, aborting"); log(`No API key available, aborting: ${auth.error}`);
return; return;
} }
@@ -157,7 +157,7 @@ export default function(pi: ExtensionAPI) {
const response = await complete( const response = await complete(
AUTO_NAME_MODEL, AUTO_NAME_MODEL,
{ systemPrompt: SYSTEM_PROMPT, messages: [userMessage] }, { systemPrompt: SYSTEM_PROMPT, messages: [userMessage] },
{ apiKey }, { apiKey: auth.apiKey, headers: auth.headers },
); );
log(`Response received, stopReason: ${response.stopReason}`); log(`Response received, stopReason: ${response.stopReason}`);
@@ -273,7 +273,8 @@ export default function(pi: ExtensionAPI) {
loader.onAbort = () => done(null); loader.onAbort = () => done(null);
const doGenerate = async () => { const doGenerate = async () => {
const apiKey = await ctx.modelRegistry.getApiKey(AUTO_NAME_MODEL); const auth = await ctx.modelRegistry.getApiKeyAndHeaders(AUTO_NAME_MODEL);
if (!auth.ok) throw new Error(auth.error);
const userMessage: Message = { const userMessage: Message = {
role: "user", role: "user",
@@ -289,7 +290,7 @@ export default function(pi: ExtensionAPI) {
const response = await complete( const response = await complete(
AUTO_NAME_MODEL, AUTO_NAME_MODEL,
{ systemPrompt: SYSTEM_PROMPT, messages: [userMessage] }, { systemPrompt: SYSTEM_PROMPT, messages: [userMessage] },
{ apiKey, signal: loader.signal }, { apiKey: auth.apiKey, headers: auth.headers, signal: loader.signal },
); );
if (response.stopReason === "aborted") { if (response.stopReason === "aborted") {
+2 -7
View File
@@ -6,7 +6,7 @@
* - Injects timestamp markers without triggering extra turns * - Injects timestamp markers without triggering extra turns
*/ */
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"; import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
import { Box, Text } from "@mariozechner/pi-tui"; import { Box, Text } from "@mariozechner/pi-tui";
// Track session time // Track session time
@@ -41,12 +41,7 @@ function formatDuration(ms: number): string {
} }
export default function (pi: ExtensionAPI) { export default function (pi: ExtensionAPI) {
const updateStatus = (ctx: { const updateStatus = (ctx: ExtensionContext) => {
ui: {
setStatus: (id: string, text: string | undefined) => void;
theme: { fg: (color: string, text: string) => string };
};
}) => {
const elapsed = Date.now() - sessionStart; const elapsed = Date.now() - sessionStart;
let status = ctx.ui.theme.fg("dim", `${formatElapsed(elapsed)}`); let status = ctx.ui.theme.fg("dim", `${formatElapsed(elapsed)}`);
if (lastTurnDuration !== null) { if (lastTurnDuration !== null) {
+1 -1
View File
@@ -1,3 +1,3 @@
{ {
"selectModel": "ctrl+space" "app.model.select": "ctrl+space"
} }