@senpiper/sp-agent 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL.md +37 -26
- package/README.md +13 -13
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/distribution.d.ts +2 -2
- package/dist/distribution.d.ts.map +1 -1
- package/dist/distribution.js +2 -3
- package/dist/distribution.js.map +1 -1
- package/dist/extension-identity.generated.d.ts +3 -3
- package/dist/extension-identity.generated.d.ts.map +1 -1
- package/dist/extension-identity.generated.js +3 -3
- package/dist/extension-identity.generated.js.map +1 -1
- package/dist/install-sp.sh +9 -9
- package/dist/release-manager.d.ts.map +1 -1
- package/dist/release-manager.js +2 -2
- package/dist/release-manager.js.map +1 -1
- package/dist/runtime-cli.d.ts.map +1 -1
- package/dist/runtime-cli.js +4 -4
- package/dist/runtime-cli.js.map +1 -1
- package/dist/sdk.d.ts +1 -1
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +5 -5
- package/dist/sdk.js.map +1 -1
- package/dist/session-manager.d.ts +1 -1
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +15 -15
- package/dist/session-manager.js.map +1 -1
- package/dist/sp-web.d.ts.map +1 -1
- package/dist/sp-web.js +2 -2
- package/dist/sp-web.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/node_modules/@senpiper/pi-coding-agent/dist/bundle/chunks/{chunk-IK73Y232.js → chunk-VVKE4QZJ.js} +1 -1
- package/node_modules/@senpiper/pi-coding-agent/dist/bundle/cli.js +1 -1
- package/node_modules/@senpiper/pi-coding-agent/dist/bundle/index.js +1 -1
- package/node_modules/@senpiper/pi-coding-agent/dist/bundle/rpc-entry.js +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/kimi-coding.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/qwen-token-plan.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@senpiper/pi-coding-agent/package.json +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/CHANGELOG.md +17 -0
- package/node_modules/@senpiper/sp-agent-extensions/CONCURRENT_SESSIONS.md +9 -9
- package/node_modules/@senpiper/sp-agent-extensions/TERMINAL_WEB_BRIDGE.md +29 -10
- package/node_modules/@senpiper/sp-agent-extensions/dist/cli-commands.d.ts +0 -6
- package/node_modules/@senpiper/sp-agent-extensions/dist/cli-commands.d.ts.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/cli-commands.js +7 -86
- package/node_modules/@senpiper/sp-agent-extensions/dist/cli-commands.js.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/commands.d.ts +2 -2
- package/node_modules/@senpiper/sp-agent-extensions/dist/commands.d.ts.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/commands.js +2 -2
- package/node_modules/@senpiper/sp-agent-extensions/dist/commands.js.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/gateway.d.ts +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/gateway.d.ts.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/gateway.js +28 -17
- package/node_modules/@senpiper/sp-agent-extensions/dist/gateway.js.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/index.d.ts +1 -3
- package/node_modules/@senpiper/sp-agent-extensions/dist/index.d.ts.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/index.js +1 -3
- package/node_modules/@senpiper/sp-agent-extensions/dist/index.js.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/interactions.d.ts +0 -2
- package/node_modules/@senpiper/sp-agent-extensions/dist/interactions.d.ts.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/interactions.js +0 -3
- package/node_modules/@senpiper/sp-agent-extensions/dist/interactions.js.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/login-command.d.ts.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/login-command.js +10 -20
- package/node_modules/@senpiper/sp-agent-extensions/dist/login-command.js.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/sp-web-launcher.d.ts +27 -0
- package/node_modules/@senpiper/sp-agent-extensions/dist/sp-web-launcher.d.ts.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/sp-web-launcher.js +270 -28
- package/node_modules/@senpiper/sp-agent-extensions/dist/sp-web-launcher.js.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/startup-header.d.ts.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/startup-header.js +13 -20
- package/node_modules/@senpiper/sp-agent-extensions/dist/startup-header.js.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/terminal-web-bridge.d.ts +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/terminal-web-bridge.d.ts.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/terminal-web-bridge.js +11 -9
- package/node_modules/@senpiper/sp-agent-extensions/dist/terminal-web-bridge.js.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/web-command.d.ts.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/web-command.js +36 -10
- package/node_modules/@senpiper/sp-agent-extensions/dist/web-command.js.map +1 -1
- package/node_modules/@senpiper/sp-agent-extensions/package.json +3 -5
- package/package.json +7 -6
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding-command.d.ts +0 -4
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding-command.d.ts.map +0 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding-command.js +0 -67
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding-command.js.map +0 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding-installation.d.ts +0 -14
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding-installation.d.ts.map +0 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding-installation.js +0 -32
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding-installation.js.map +0 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding.d.ts +0 -39
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding.d.ts.map +0 -1
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding.js +0 -311
- package/node_modules/@senpiper/sp-agent-extensions/dist/onboarding.js.map +0 -1
|
@@ -3,7 +3,7 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
export const SP_GATEWAY_PROVIDER_ID = "sp-gateway";
|
|
5
5
|
export const LEGACY_SP_GATEWAY_PROVIDER_ID = "sengateway";
|
|
6
|
-
export const SP_GATEWAY_PROVIDER_NAME = "
|
|
6
|
+
export const SP_GATEWAY_PROVIDER_NAME = "Senpiper Gateway";
|
|
7
7
|
export const SP_USER_AGENT = "sp";
|
|
8
8
|
export const SP_CLIENT_NAME = "sp-agent";
|
|
9
9
|
let gatewayWarning;
|
|
@@ -203,13 +203,13 @@ export async function fetchSpGatewayModels(baseUrl, apiKey, signal) {
|
|
|
203
203
|
if (!response.ok) {
|
|
204
204
|
const body = await response.text().catch(() => "");
|
|
205
205
|
const suffix = body.trim() ? `: ${body.trim().slice(0, 300)}` : "";
|
|
206
|
-
throw new Error(`
|
|
206
|
+
throw new Error(`Senpiper Gateway rejected /v1/models (${response.status} ${response.statusText})${suffix}`);
|
|
207
207
|
}
|
|
208
208
|
const payload = (await response.json());
|
|
209
209
|
if (!isRecord(payload) || !Array.isArray(payload.data)) {
|
|
210
|
-
throw new Error("
|
|
210
|
+
throw new Error("Senpiper Gateway returned an invalid /v1/models envelope.");
|
|
211
211
|
}
|
|
212
|
-
return parseModelCatalog(payload.data, "
|
|
212
|
+
return parseModelCatalog(payload.data, "Senpiper Gateway /v1/models response");
|
|
213
213
|
}
|
|
214
214
|
function readLegacySpGatewayState(agentDir) {
|
|
215
215
|
const path = getLegacyModelsPath(agentDir);
|
|
@@ -224,7 +224,7 @@ function readLegacySpGatewayState(agentDir) {
|
|
|
224
224
|
return {
|
|
225
225
|
schemaVersion: 1,
|
|
226
226
|
baseUrl: normalizeSpGatewayBaseUrl(provider.baseUrl),
|
|
227
|
-
models: parseModelCatalog(provider.models, `legacy
|
|
227
|
+
models: parseModelCatalog(provider.models, `legacy Senpiper Gateway cache ${path}`),
|
|
228
228
|
};
|
|
229
229
|
}
|
|
230
230
|
export function readSpGatewayState(agentDir = getSpAgentDir()) {
|
|
@@ -236,23 +236,23 @@ export function readSpGatewayState(agentDir = getSpAgentDir()) {
|
|
|
236
236
|
writeSpGatewayState(legacy.baseUrl, legacy.models, agentDir);
|
|
237
237
|
gatewayWarning = {
|
|
238
238
|
kind: "legacy_cache_imported",
|
|
239
|
-
message: `Imported the legacy
|
|
239
|
+
message: `Imported the legacy Senpiper Gateway model cache from ${getLegacyModelsPath(agentDir)}.`,
|
|
240
240
|
at: new Date().toISOString(),
|
|
241
241
|
};
|
|
242
242
|
return legacy;
|
|
243
243
|
}
|
|
244
244
|
const value = readJsonFile(path);
|
|
245
245
|
if (value.schemaVersion !== 1 || typeof value.baseUrl !== "string" || !Array.isArray(value.models)) {
|
|
246
|
-
throw new Error(`Invalid
|
|
246
|
+
throw new Error(`Invalid Senpiper Gateway configuration: ${path}`);
|
|
247
247
|
}
|
|
248
248
|
return {
|
|
249
249
|
schemaVersion: 1,
|
|
250
250
|
baseUrl: normalizeSpGatewayBaseUrl(value.baseUrl),
|
|
251
|
-
models: parseModelCatalog(value.models, `
|
|
251
|
+
models: parseModelCatalog(value.models, `Senpiper Gateway configuration ${path}`),
|
|
252
252
|
};
|
|
253
253
|
}
|
|
254
254
|
export function writeSpGatewayState(baseUrl, models, agentDir = getSpAgentDir()) {
|
|
255
|
-
const validatedModels = parseModelCatalog(models, "
|
|
255
|
+
const validatedModels = parseModelCatalog(models, "Senpiper Gateway state");
|
|
256
256
|
writePrivateJson(getSpGatewayStatePath(agentDir), {
|
|
257
257
|
schemaVersion: 1,
|
|
258
258
|
baseUrl: normalizeSpGatewayBaseUrl(baseUrl),
|
|
@@ -310,7 +310,7 @@ export function clearSpGatewayWarning() {
|
|
|
310
310
|
gatewayWarning = undefined;
|
|
311
311
|
}
|
|
312
312
|
export function createSpGatewayProviderConfig(baseUrl, models, agentDir = getSpAgentDir()) {
|
|
313
|
-
let currentModels = parseModelCatalog(models, "
|
|
313
|
+
let currentModels = parseModelCatalog(models, "Senpiper Gateway provider configuration");
|
|
314
314
|
return {
|
|
315
315
|
name: SP_GATEWAY_PROVIDER_NAME,
|
|
316
316
|
baseUrl,
|
|
@@ -344,7 +344,7 @@ export function createSpGatewayProviderConfig(baseUrl, models, agentDir = getSpA
|
|
|
344
344
|
catch (error) {
|
|
345
345
|
gatewayWarning = {
|
|
346
346
|
kind: "refresh_failed",
|
|
347
|
-
message: `
|
|
347
|
+
message: `Senpiper Gateway model refresh failed; using ${currentModels.length} cached model${currentModels.length === 1 ? "" : "s"}: ${error instanceof Error ? error.message : String(error)}`,
|
|
348
348
|
at: new Date().toISOString(),
|
|
349
349
|
};
|
|
350
350
|
throw error;
|
|
@@ -358,11 +358,22 @@ export function createSpGatewayExtension() {
|
|
|
358
358
|
if (state) {
|
|
359
359
|
pi.registerProvider(SP_GATEWAY_PROVIDER_ID, createSpGatewayProviderConfig(state.baseUrl, state.models));
|
|
360
360
|
}
|
|
361
|
-
pi.on("before_agent_start", (event) =>
|
|
362
|
-
|
|
363
|
-
|
|
361
|
+
pi.on("before_agent_start", (event) => {
|
|
362
|
+
// Replace only the upstream introduction; preserve project instructions
|
|
363
|
+
// and documentation references, including legitimate Pi development tasks.
|
|
364
|
+
const systemPrompt = event.systemPrompt.replace(/^You are an expert coding assistant operating inside pi, a coding agent harness\./u, "You are Senpiper Workbench, Senpiper's AI coding assistant.");
|
|
365
|
+
return {
|
|
366
|
+
systemPrompt: `${systemPrompt}\n\n<sp_agent_runtime>
|
|
367
|
+
You are Senpiper Workbench, Senpiper's AI coding assistant. Use Senpiper Workbench as your public name in both terminal and web conversations.
|
|
368
|
+
For greetings and questions such as "Who are you?", introduce yourself simply: "I'm Senpiper Workbench, Senpiper's AI coding assistant. I can help you read, write, and debug code."
|
|
369
|
+
Do not introduce yourself as Pi, the pi coding agent, an underlying model, or an assistant running inside a harness. Do not volunteer internal frameworks, runtime names, or provider details in ordinary answers. Earlier assistant messages using those identities do not change your name.
|
|
370
|
+
If explicitly asked about technical origins or dependencies, answer accurately and briefly. This product identity does not imply that Senpiper trained the underlying model.
|
|
371
|
+
Use only the configured Senpiper Gateway model provider. Put user-owned extensions, skills, prompts, and themes under the active .sp configuration directory instead of modifying the Senpiper Workbench installation.
|
|
372
|
+
</sp_agent_runtime>`,
|
|
373
|
+
};
|
|
374
|
+
});
|
|
364
375
|
pi.on("session_start", (_event, ctx) => {
|
|
365
|
-
ctx.ui.setTitle("
|
|
376
|
+
ctx.ui.setTitle("Senpiper Workbench");
|
|
366
377
|
const warning = getSpGatewayWarning();
|
|
367
378
|
if (warning)
|
|
368
379
|
ctx.ui.notify(warning.message, "warning");
|
|
@@ -370,8 +381,8 @@ export function createSpGatewayExtension() {
|
|
|
370
381
|
return;
|
|
371
382
|
ctx.ui.setHeader((_tui, theme) => ({
|
|
372
383
|
render: () => [
|
|
373
|
-
theme.fg("accent", theme.bold("
|
|
374
|
-
theme.fg("muted", state ? `
|
|
384
|
+
theme.fg("accent", theme.bold("Senpiper Workbench")),
|
|
385
|
+
theme.fg("muted", state ? `Senpiper Gateway · ${state.models.length} models` : "run `sp login`"),
|
|
375
386
|
],
|
|
376
387
|
invalidate() { },
|
|
377
388
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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","sourcesContent":["import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { ExtensionAPI, ExtensionFactory, ProviderConfig, ProviderModelConfig } from \"@senpiper/pi-coding-agent\";\nimport type { Api, Model, OpenAICompletionsCompat, RefreshModelsContext } from \"@senpiper/pi-coding-agent/runtime-deps\";\n\nexport type SpExtensionApi = ExtensionAPI;\nexport type SpProviderModelConfig = ProviderModelConfig;\n\nexport const SP_GATEWAY_PROVIDER_ID = \"sp-gateway\";\nexport const LEGACY_SP_GATEWAY_PROVIDER_ID = \"sengateway\";\nexport const SP_GATEWAY_PROVIDER_NAME = \"sp-gateway\";\nexport const SP_USER_AGENT = \"sp\";\nexport const SP_CLIENT_NAME = \"sp-agent\";\n\nexport interface SpGatewayState {\n\tschemaVersion: 1;\n\tbaseUrl: string;\n\tmodels: SpProviderModelConfig[];\n}\n\nexport interface SpGatewayWarning {\n\tkind: \"refresh_failed\" | \"legacy_cache_imported\";\n\tmessage: string;\n\tat: string;\n}\n\ntype JsonRecord = Record<string, unknown>;\n\nlet gatewayWarning: SpGatewayWarning | undefined;\n\nfunction isRecord(value: unknown): value is JsonRecord {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringValue(value: unknown) {\n\treturn typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction finiteNumber(value: unknown) {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction positiveInteger(value: unknown) {\n\tconst number = finiteNumber(value);\n\treturn number !== undefined && number > 0 ? Math.floor(number) : undefined;\n}\n\nfunction nonNegativeNumber(value: unknown) {\n\tconst number = finiteNumber(value);\n\treturn number !== undefined && number >= 0 ? number : undefined;\n}\n\nfunction booleanValue(value: unknown) {\n\treturn typeof value === \"boolean\" ? value : undefined;\n}\n\nexport function getSpAgentDir() {\n\treturn process.env.SP_CODING_AGENT_DIR || join(homedir(), \".sp\", \"agent\");\n}\n\nexport function getSpGatewayStatePath(agentDir = getSpAgentDir()) {\n\treturn join(agentDir, \"sp-gateway.json\");\n}\n\nexport function getLegacyModelsPath(agentDir = getSpAgentDir()) {\n\treturn join(agentDir, \"models.json\");\n}\n\nexport function getSpAuthPath(agentDir = getSpAgentDir()) {\n\treturn join(agentDir, \"auth.json\");\n}\n\nexport function getSpSettingsPath(agentDir = getSpAgentDir()) {\n\treturn join(agentDir, \"settings.json\");\n}\n\nfunction readJsonFile(path: string): JsonRecord {\n\tif (!existsSync(path)) return {};\n\tconst content = readFileSync(path, \"utf8\").trim();\n\tif (!content) return {};\n\tconst parsed = JSON.parse(content) as unknown;\n\tif (!isRecord(parsed)) throw new Error(`Expected an object in ${path}`);\n\treturn parsed;\n}\n\nfunction writePrivateJson(path: string, value: unknown) {\n\tmkdirSync(dirname(path), { recursive: true });\n\tconst temporaryPath = `${path}.${process.pid}.tmp`;\n\twriteFileSync(temporaryPath, `${JSON.stringify(value, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n\tif (process.platform !== \"win32\") chmodSync(temporaryPath, 0o600);\n\trenameSync(temporaryPath, path);\n\tif (process.platform !== \"win32\") chmodSync(path, 0o600);\n}\n\nexport function normalizeSpGatewayBaseUrl(input: string) {\n\tconst trimmed = input.trim();\n\tif (!trimmed) throw new Error(\"Gateway URL cannot be empty.\");\n\tconst withScheme = /^[a-z][a-z0-9+.-]*:\\/\\//iu.test(trimmed) ? trimmed : `https://${trimmed}`;\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(withScheme);\n\t} catch {\n\t\tthrow new Error(`Invalid gateway URL: ${input}`);\n\t}\n\tif (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n\t\tthrow new Error(\"Gateway URL must use HTTPS or HTTP.\");\n\t}\n\turl.hash = \"\";\n\turl.search = \"\";\n\turl.pathname = url.pathname.replace(/\\/+$/u, \"\");\n\tif (!url.pathname.endsWith(\"/v1\")) url.pathname = `${url.pathname}/v1`.replace(/\\/+/gu, \"/\");\n\treturn url.toString().replace(/\\/$/u, \"\");\n}\n\nfunction parseInput(value: unknown): (\"text\" | \"image\")[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst input = value.filter((entry): entry is \"text\" | \"image\" => entry === \"text\" || entry === \"image\");\n\treturn input.length > 0 ? [...new Set(input)] : undefined;\n}\n\nfunction parseCost(value: unknown): SpProviderModelConfig[\"cost\"] | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst input = nonNegativeNumber(value.input);\n\tconst output = nonNegativeNumber(value.output);\n\tconst cacheRead = nonNegativeNumber(value.cacheRead);\n\tconst cacheWrite = nonNegativeNumber(value.cacheWrite);\n\tif (input === undefined && output === undefined && cacheRead === undefined && cacheWrite === undefined)\n\t\treturn undefined;\n\treturn { input: input ?? 0, output: output ?? 0, cacheRead: cacheRead ?? 0, cacheWrite: cacheWrite ?? 0 };\n}\n\nfunction parseThinkingLevelMap(value: unknown): SpProviderModelConfig[\"thinkingLevelMap\"] {\n\tif (!isRecord(value)) return undefined;\n\tconst result: NonNullable<SpProviderModelConfig[\"thinkingLevelMap\"]> = {};\n\tfor (const key of [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const) {\n\t\tconst entry = value[key];\n\t\tif (typeof entry === \"string\" || entry === null) result[key] = entry;\n\t}\n\treturn Object.keys(result).length > 0 ? result : undefined;\n}\n\nfunction thinkingFormat(value: unknown): OpenAICompletionsCompat[\"thinkingFormat\"] {\n\tswitch (value) {\n\t\tcase \"openai\":\n\t\tcase \"openrouter\":\n\t\tcase \"deepseek\":\n\t\tcase \"together\":\n\t\tcase \"zai\":\n\t\tcase \"qwen\":\n\t\tcase \"chat-template\":\n\t\tcase \"qwen-chat-template\":\n\t\tcase \"string-thinking\":\n\t\tcase \"ant-ling\":\n\t\t\treturn value;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nfunction sessionAffinityFormat(value: unknown): OpenAICompletionsCompat[\"sessionAffinityFormat\"] {\n\treturn value === \"openai\" || value === \"openai-nosession\" || value === \"openrouter\" ? value : undefined;\n}\n\nfunction parseCompat(value: unknown): OpenAICompletionsCompat {\n\tconst record = isRecord(value) ? value : {};\n\tconst maxTokensField =\n\t\trecord.maxTokensField === \"max_completion_tokens\" || record.maxTokensField === \"max_tokens\"\n\t\t\t? record.maxTokensField\n\t\t\t: undefined;\n\tconst compat = {\n\t\tsupportsStore: booleanValue(record.supportsStore) ?? false,\n\t\tsupportsDeveloperRole: booleanValue(record.supportsDeveloperRole),\n\t\tsupportsReasoningEffort: booleanValue(record.supportsReasoningEffort),\n\t\tsupportsUsageInStreaming: booleanValue(record.supportsUsageInStreaming),\n\t\tmaxTokensField,\n\t\trequiresToolResultName: booleanValue(record.requiresToolResultName),\n\t\trequiresAssistantAfterToolResult: booleanValue(record.requiresAssistantAfterToolResult),\n\t\trequiresThinkingAsText: booleanValue(record.requiresThinkingAsText),\n\t\trequiresReasoningContentOnAssistantMessages: booleanValue(record.requiresReasoningContentOnAssistantMessages),\n\t\tthinkingFormat: thinkingFormat(record.thinkingFormat),\n\t\tsupportsStrictMode: booleanValue(record.supportsStrictMode),\n\t\tsendSessionAffinityHeaders: booleanValue(record.sendSessionAffinityHeaders),\n\t\tsessionAffinityFormat: sessionAffinityFormat(record.sessionAffinityFormat),\n\t\tsupportsLongCacheRetention: booleanValue(record.supportsLongCacheRetention),\n\t} satisfies OpenAICompletionsCompat;\n\treturn compat;\n}\n\nfunction parseGatewayModel(value: unknown): SpProviderModelConfig | undefined {\n\tconst record = typeof value === \"string\" ? { id: value } : isRecord(value) ? value : undefined;\n\tif (!record) return undefined;\n\tconst id = stringValue(record.id);\n\tif (!id || id.length > 256 || /[\\u0000-\\u001f\\u007f]/u.test(id)) return undefined;\n\tconst metadata = isRecord(record.metadata) ? record.metadata : {};\n\tconst field = (name: string) => metadata[name] ?? record[name];\n\tconst reasoning = field(\"reasoning\");\n\treturn {\n\t\tid,\n\t\tname: stringValue(field(\"name\")) ?? id,\n\t\treasoning: typeof reasoning === \"boolean\" ? reasoning : false,\n\t\tthinkingLevelMap: parseThinkingLevelMap(field(\"thinkingLevelMap\")),\n\t\tinput: parseInput(field(\"input\")) ?? [\"text\"],\n\t\tcost: parseCost(field(\"cost\")) ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: positiveInteger(field(\"contextWindow\")) ?? 128_000,\n\t\tmaxTokens: positiveInteger(field(\"maxTokens\")) ?? 32_000,\n\t\tcompat: parseCompat(field(\"compat\")),\n\t};\n}\n\nfunction parseModelCatalog(values: readonly unknown[], source: string) {\n\tconst models = values.map(parseGatewayModel).filter((model): model is SpProviderModelConfig => model !== undefined);\n\tif (models.length === 0) throw new Error(`${source} contains no valid models.`);\n\tconst ids = new Set<string>();\n\tfor (const model of models) {\n\t\tif (ids.has(model.id)) throw new Error(`${source} contains duplicate model id ${model.id}.`);\n\t\tids.add(model.id);\n\t}\n\treturn models;\n}\n\nexport async function fetchSpGatewayModels(baseUrl: string, apiKey: string, signal?: AbortSignal) {\n\tconst response = await fetch(`${baseUrl.replace(/\\/$/u, \"\")}/models`, {\n\t\tsignal,\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\tAccept: \"application/json\",\n\t\t\t\"User-Agent\": SP_USER_AGENT,\n\t\t\t\"X-Senpiper-Client\": SP_CLIENT_NAME,\n\t\t},\n\t});\n\tif (!response.ok) {\n\t\tconst body = await response.text().catch(() => \"\");\n\t\tconst suffix = body.trim() ? `: ${body.trim().slice(0, 300)}` : \"\";\n\t\tthrow new Error(`sp-gateway rejected /v1/models (${response.status} ${response.statusText})${suffix}`);\n\t}\n\tconst payload = (await response.json()) as unknown;\n\tif (!isRecord(payload) || !Array.isArray(payload.data)) {\n\t\tthrow new Error(\"sp-gateway returned an invalid /v1/models envelope.\");\n\t}\n\treturn parseModelCatalog(payload.data, \"sp-gateway /v1/models response\");\n}\n\nfunction readLegacySpGatewayState(agentDir: string): SpGatewayState | undefined {\n\tconst path = getLegacyModelsPath(agentDir);\n\tif (!existsSync(path)) return undefined;\n\tconst root = readJsonFile(path);\n\tconst providers = isRecord(root.providers) ? root.providers : undefined;\n\tconst providerValue = providers?.[SP_GATEWAY_PROVIDER_ID] ?? providers?.[LEGACY_SP_GATEWAY_PROVIDER_ID];\n\tconst provider = isRecord(providerValue) ? providerValue : undefined;\n\tif (!provider || typeof provider.baseUrl !== \"string\" || !Array.isArray(provider.models)) return undefined;\n\treturn {\n\t\tschemaVersion: 1,\n\t\tbaseUrl: normalizeSpGatewayBaseUrl(provider.baseUrl),\n\t\tmodels: parseModelCatalog(provider.models, `legacy sp-gateway cache ${path}`),\n\t};\n}\n\nexport function readSpGatewayState(agentDir = getSpAgentDir()): SpGatewayState | undefined {\n\tconst path = getSpGatewayStatePath(agentDir);\n\tif (!existsSync(path)) {\n\t\tconst legacy = readLegacySpGatewayState(agentDir);\n\t\tif (!legacy) return undefined;\n\t\twriteSpGatewayState(legacy.baseUrl, legacy.models, agentDir);\n\t\tgatewayWarning = {\n\t\t\tkind: \"legacy_cache_imported\",\n\t\t\tmessage: `Imported the legacy sp-gateway model cache from ${getLegacyModelsPath(agentDir)}.`,\n\t\t\tat: new Date().toISOString(),\n\t\t};\n\t\treturn legacy;\n\t}\n\tconst value = readJsonFile(path);\n\tif (value.schemaVersion !== 1 || typeof value.baseUrl !== \"string\" || !Array.isArray(value.models)) {\n\t\tthrow new Error(`Invalid sp-gateway configuration: ${path}`);\n\t}\n\treturn {\n\t\tschemaVersion: 1,\n\t\tbaseUrl: normalizeSpGatewayBaseUrl(value.baseUrl),\n\t\tmodels: parseModelCatalog(value.models, `sp-gateway configuration ${path}`),\n\t};\n}\n\nexport function writeSpGatewayState(baseUrl: string, models: SpProviderModelConfig[], agentDir = getSpAgentDir()) {\n\tconst validatedModels = parseModelCatalog(models, \"sp-gateway state\");\n\twritePrivateJson(getSpGatewayStatePath(agentDir), {\n\t\tschemaVersion: 1,\n\t\tbaseUrl: normalizeSpGatewayBaseUrl(baseUrl),\n\t\tmodels: validatedModels,\n\t} satisfies SpGatewayState);\n}\n\nexport function readSpGatewayApiKey(agentDir = getSpAgentDir()) {\n\tconst path = getSpAuthPath(agentDir);\n\tconst auth = readJsonFile(path);\n\tlet credential = auth[SP_GATEWAY_PROVIDER_ID];\n\tif (!credential && auth[LEGACY_SP_GATEWAY_PROVIDER_ID]) {\n\t\tcredential = auth[LEGACY_SP_GATEWAY_PROVIDER_ID];\n\t\tauth[SP_GATEWAY_PROVIDER_ID] = credential;\n\t\tdelete auth[LEGACY_SP_GATEWAY_PROVIDER_ID];\n\t\twritePrivateJson(path, auth);\n\t}\n\treturn isRecord(credential) && credential.type === \"api_key\" && typeof credential.key === \"string\"\n\t\t? credential.key\n\t\t: undefined;\n}\n\nexport function writeSpGatewayLogin(apiKey: string, firstModelId: string, agentDir = getSpAgentDir()) {\n\tconst authPath = getSpAuthPath(agentDir);\n\tconst auth = readJsonFile(authPath);\n\tauth[SP_GATEWAY_PROVIDER_ID] = { type: \"api_key\", key: apiKey };\n\tdelete auth[LEGACY_SP_GATEWAY_PROVIDER_ID];\n\twritePrivateJson(authPath, auth);\n\n\tconst settingsPath = getSpSettingsPath(agentDir);\n\tconst settings = readJsonFile(settingsPath);\n\tsettings.defaultProvider = SP_GATEWAY_PROVIDER_ID;\n\tsettings.defaultModel = firstModelId;\n\twritePrivateJson(settingsPath, settings);\n}\n\nexport function removeSpGatewayLogin(agentDir = getSpAgentDir()) {\n\tconst path = getSpAuthPath(agentDir);\n\tconst auth = readJsonFile(path);\n\tdelete auth[SP_GATEWAY_PROVIDER_ID];\n\tdelete auth[LEGACY_SP_GATEWAY_PROVIDER_ID];\n\twritePrivateJson(path, auth);\n}\n\nfunction credentialKey(context: RefreshModelsContext) {\n\treturn context.credential?.type === \"api_key\" ? context.credential.key : undefined;\n}\n\nfunction storedModels(models: readonly SpProviderModelConfig[], baseUrl: string): Model<Api>[] {\n\treturn models.map((model) => ({\n\t\t...model,\n\t\tprovider: SP_GATEWAY_PROVIDER_ID,\n\t\tbaseUrl,\n\t\tapi: \"openai-completions\",\n\t}));\n}\n\nexport function getSpGatewayWarning() {\n\treturn gatewayWarning;\n}\n\nexport function clearSpGatewayWarning() {\n\tgatewayWarning = undefined;\n}\n\nexport function createSpGatewayProviderConfig(\n\tbaseUrl: string,\n\tmodels: SpProviderModelConfig[],\n\tagentDir = getSpAgentDir(),\n): ProviderConfig {\n\tlet currentModels = parseModelCatalog(models, \"sp-gateway provider configuration\");\n\treturn {\n\t\tname: SP_GATEWAY_PROVIDER_NAME,\n\t\tbaseUrl,\n\t\tapi: \"openai-completions\",\n\t\tauthHeader: true,\n\t\theaders: {\n\t\t\t\"User-Agent\": SP_USER_AGENT,\n\t\t\t\"X-Senpiper-Client\": SP_CLIENT_NAME,\n\t\t},\n\t\tmodels: currentModels,\n\t\tasync refreshModels(context) {\n\t\t\tif (!context.allowNetwork) return currentModels;\n\t\t\tconst apiKey = credentialKey(context);\n\t\t\tif (!apiKey) return currentModels;\n\t\t\ttry {\n\t\t\t\tconst refreshed = await fetchSpGatewayModels(baseUrl, apiKey, context.signal);\n\t\t\t\tif (context.signal.aborted) return currentModels;\n\t\t\t\tawait context.publish({\n\t\t\t\t\tpersist: { models: storedModels(refreshed, baseUrl), checkedAt: Date.now() },\n\t\t\t\t\tupdate: () => {\n\t\t\t\t\t\twriteSpGatewayState(baseUrl, refreshed, agentDir);\n\t\t\t\t\t\tcurrentModels = refreshed;\n\t\t\t\t\t\tgatewayWarning = undefined;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn currentModels;\n\t\t\t} catch (error) {\n\t\t\t\tgatewayWarning = {\n\t\t\t\t\tkind: \"refresh_failed\",\n\t\t\t\t\tmessage: `sp-gateway model refresh failed; using ${currentModels.length} cached model${currentModels.length === 1 ? \"\" : \"s\"}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\tat: new Date().toISOString(),\n\t\t\t\t};\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function createSpGatewayExtension(): ExtensionFactory {\n\treturn (pi) => {\n\t\tconst state = readSpGatewayState();\n\t\tif (state) {\n\t\t\tpi.registerProvider(SP_GATEWAY_PROVIDER_ID, createSpGatewayProviderConfig(state.baseUrl, state.models));\n\t\t}\n\n\t\tpi.on(\"before_agent_start\", (event) => ({\n\t\t\tsystemPrompt: `${event.systemPrompt}\\n\\n<sp_agent_runtime>\\nThis is Senpiper's sp-agent distribution. Use only the configured sp-gateway model provider. Put user-owned extensions, skills, prompts, and themes under the active .sp configuration directory instead of modifying the sp-agent installation.\\n</sp_agent_runtime>`,\n\t\t}));\n\n\t\tpi.on(\"session_start\", (_event, ctx) => {\n\t\t\tctx.ui.setTitle(\"sp-agent\");\n\t\t\tconst warning = getSpGatewayWarning();\n\t\t\tif (warning) ctx.ui.notify(warning.message, \"warning\");\n\t\t\tif (ctx.mode !== \"tui\") return;\n\t\t\tctx.ui.setHeader((_tui, theme) => ({\n\t\t\t\trender: () => [\n\t\t\t\t\ttheme.fg(\"accent\", theme.bold(\"sp-agent\")),\n\t\t\t\t\ttheme.fg(\"muted\", state ? `sp-gateway · ${state.models.length} models` : \"run `sp login`\"),\n\t\t\t\t],\n\t\t\t\tinvalidate() {},\n\t\t\t}));\n\t\t});\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpG,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAO1C,MAAM,CAAC,MAAM,sBAAsB,GAAG,YAAY,CAAC;AACnD,MAAM,CAAC,MAAM,6BAA6B,GAAG,YAAY,CAAC;AAC1D,MAAM,CAAC,MAAM,wBAAwB,GAAG,kBAAkB,CAAC;AAC3D,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;AAgBzC,IAAI,cAA4C,CAAC;AAEjD,SAAS,QAAQ,CAAC,KAAc,EAAuB;IACtD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAAA,CAC5E;AAED,SAAS,WAAW,CAAC,KAAc,EAAE;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CAC5E;AAED,SAAS,YAAY,CAAC,KAAc,EAAE;IACrC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CAC/E;AAED,SAAS,eAAe,CAAC,KAAc,EAAE;IACxC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CAC3E;AAED,SAAS,iBAAiB,CAAC,KAAc,EAAE;IAC1C,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,MAAM,KAAK,SAAS,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CAChE;AAED,SAAS,YAAY,CAAC,KAAc,EAAE;IACrC,OAAO,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CACtD;AAED,MAAM,UAAU,aAAa,GAAG;IAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAAA,CAC1E;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAQ,GAAG,aAAa,EAAE,EAAE;IACjE,OAAO,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;AAAA,CACzC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAQ,GAAG,aAAa,EAAE,EAAE;IAC/D,OAAO,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AAAA,CACrC;AAED,MAAM,UAAU,aAAa,CAAC,QAAQ,GAAG,aAAa,EAAE,EAAE;IACzD,OAAO,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAAA,CACnC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAQ,GAAG,aAAa,EAAE,EAAE;IAC7D,OAAO,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;AAAA,CACvC;AAED,SAAS,YAAY,CAAC,IAAY,EAAc;IAC/C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;IAC9C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IACxE,OAAO,MAAM,CAAC;AAAA,CACd;AAED,SAAS,gBAAgB,CAAC,IAAY,EAAE,KAAc,EAAE;IACvD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,MAAM,aAAa,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;IACnD,aAAa,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1G,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,SAAS,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAClE,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAAA,CACzD;AAED,MAAM,UAAU,yBAAyB,CAAC,KAAa,EAAE;IACxD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,OAAO,EAAE,CAAC;IAC9F,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACJ,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACxD,CAAC;IACD,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;IACd,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;IAChB,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,GAAG,CAAC,QAAQ,GAAG,GAAG,GAAG,CAAC,QAAQ,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7F,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAAA,CAC1C;AAED,SAAS,UAAU,CAAC,KAAc,EAAoC;IACrE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAA6B,EAAE,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,CAAC,CAAC;IACxG,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CAC1D;AAED,SAAS,SAAS,CAAC,KAAc,EAA6C;IAC7E,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACvC,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,iBAAiB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACvD,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,IAAI,UAAU,KAAK,SAAS;QACrG,OAAO,SAAS,CAAC;IAClB,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,IAAI,CAAC,EAAE,UAAU,EAAE,UAAU,IAAI,CAAC,EAAE,CAAC;AAAA,CAC1G;AAED,SAAS,qBAAqB,CAAC,KAAc,EAA6C;IACzF,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACvC,MAAM,MAAM,GAA2D,EAAE,CAAC;IAC1E,KAAK,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAU,EAAE,CAAC;QACxF,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtE,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CAC3D;AAED,SAAS,cAAc,CAAC,KAAc,EAA6C;IAClF,QAAQ,KAAK,EAAE,CAAC;QACf,KAAK,QAAQ,CAAC;QACd,KAAK,YAAY,CAAC;QAClB,KAAK,UAAU,CAAC;QAChB,KAAK,UAAU,CAAC;QAChB,KAAK,KAAK,CAAC;QACX,KAAK,MAAM,CAAC;QACZ,KAAK,eAAe,CAAC;QACrB,KAAK,oBAAoB,CAAC;QAC1B,KAAK,iBAAiB,CAAC;QACvB,KAAK,UAAU;YACd,OAAO,KAAK,CAAC;QACd;YACC,OAAO,SAAS,CAAC;IACnB,CAAC;AAAA,CACD;AAED,SAAS,qBAAqB,CAAC,KAAc,EAAoD;IAChG,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,kBAAkB,IAAI,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CACxG;AAED,SAAS,WAAW,CAAC,KAAc,EAA2B;IAC7D,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5C,MAAM,cAAc,GACnB,MAAM,CAAC,cAAc,KAAK,uBAAuB,IAAI,MAAM,CAAC,cAAc,KAAK,YAAY;QAC1F,CAAC,CAAC,MAAM,CAAC,cAAc;QACvB,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,MAAM,GAAG;QACd,aAAa,EAAE,YAAY,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,KAAK;QAC1D,qBAAqB,EAAE,YAAY,CAAC,MAAM,CAAC,qBAAqB,CAAC;QACjE,uBAAuB,EAAE,YAAY,CAAC,MAAM,CAAC,uBAAuB,CAAC;QACrE,wBAAwB,EAAE,YAAY,CAAC,MAAM,CAAC,wBAAwB,CAAC;QACvE,cAAc;QACd,sBAAsB,EAAE,YAAY,CAAC,MAAM,CAAC,sBAAsB,CAAC;QACnE,gCAAgC,EAAE,YAAY,CAAC,MAAM,CAAC,gCAAgC,CAAC;QACvF,sBAAsB,EAAE,YAAY,CAAC,MAAM,CAAC,sBAAsB,CAAC;QACnE,2CAA2C,EAAE,YAAY,CAAC,MAAM,CAAC,2CAA2C,CAAC;QAC7G,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC;QACrD,kBAAkB,EAAE,YAAY,CAAC,MAAM,CAAC,kBAAkB,CAAC;QAC3D,0BAA0B,EAAE,YAAY,CAAC,MAAM,CAAC,0BAA0B,CAAC;QAC3E,qBAAqB,EAAE,qBAAqB,CAAC,MAAM,CAAC,qBAAqB,CAAC;QAC1E,0BAA0B,EAAE,YAAY,CAAC,MAAM,CAAC,0BAA0B,CAAC;KACzC,CAAC;IACpC,OAAO,MAAM,CAAC;AAAA,CACd;AAED,SAAS,iBAAiB,CAAC,KAAc,EAAqC;IAC7E,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/F,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,GAAG,GAAG,IAAI,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IAClF,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;IACrC,OAAO;QACN,EAAE;QACF,IAAI,EAAE,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE;QACtC,SAAS,EAAE,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK;QAC7D,gBAAgB,EAAE,qBAAqB,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAClE,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;QAC7C,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;QACtF,aAAa,EAAE,eAAe,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,OAAO;QACjE,SAAS,EAAE,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,MAAM;QACxD,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;KACpC,CAAC;AAAA,CACF;AAED,SAAS,iBAAiB,CAAC,MAA0B,EAAE,MAAc,EAAE;IACtE,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAkC,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IACpH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,4BAA4B,CAAC,CAAC;IAChF,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,gCAAgC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;QAC7F,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,MAAM,CAAC;AAAA,CACd;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAe,EAAE,MAAc,EAAE,MAAoB,EAAE;IACjG,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,EAAE;QACrE,MAAM;QACN,OAAO,EAAE;YACR,aAAa,EAAE,UAAU,MAAM,EAAE;YACjC,MAAM,EAAE,kBAAkB;YAC1B,YAAY,EAAE,aAAa;YAC3B,mBAAmB,EAAE,cAAc;SACnC;KACD,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,yCAAyC,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,IAAI,MAAM,EAAE,CAAC,CAAC;IAC9G,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAY,CAAC;IACnD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAC;AAAA,CAC/E;AAED,SAAS,wBAAwB,CAAC,QAAgB,EAA8B;IAC/E,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC3C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,MAAM,aAAa,GAAG,SAAS,EAAE,CAAC,sBAAsB,CAAC,IAAI,SAAS,EAAE,CAAC,6BAA6B,CAAC,CAAC;IACxG,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3G,OAAO;QACN,aAAa,EAAE,CAAC;QAChB,OAAO,EAAE,yBAAyB,CAAC,QAAQ,CAAC,OAAO,CAAC;QACpD,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,MAAM,EAAE,iCAAiC,IAAI,EAAE,CAAC;KACnF,CAAC;AAAA,CACF;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAQ,GAAG,aAAa,EAAE,EAA8B;IAC1F,MAAM,IAAI,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC9B,mBAAmB,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC7D,cAAc,GAAG;YAChB,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,yDAAyD,mBAAmB,CAAC,QAAQ,CAAC,GAAG;YAClG,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC5B,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACpG,MAAM,IAAI,KAAK,CAAC,2CAA2C,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,OAAO;QACN,aAAa,EAAE,CAAC;QAChB,OAAO,EAAE,yBAAyB,CAAC,KAAK,CAAC,OAAO,CAAC;QACjD,MAAM,EAAE,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,kCAAkC,IAAI,EAAE,CAAC;KACjF,CAAC;AAAA,CACF;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,MAA+B,EAAE,QAAQ,GAAG,aAAa,EAAE,EAAE;IACjH,MAAM,eAAe,GAAG,iBAAiB,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;IAC5E,gBAAgB,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE;QACjD,aAAa,EAAE,CAAC;QAChB,OAAO,EAAE,yBAAyB,CAAC,OAAO,CAAC;QAC3C,MAAM,EAAE,eAAe;KACE,CAAC,CAAC;AAAA,CAC5B;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAQ,GAAG,aAAa,EAAE,EAAE;IAC/D,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,UAAU,GAAG,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC9C,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,6BAA6B,CAAC,EAAE,CAAC;QACxD,UAAU,GAAG,IAAI,CAAC,6BAA6B,CAAC,CAAC;QACjD,IAAI,CAAC,sBAAsB,CAAC,GAAG,UAAU,CAAC;QAC1C,OAAO,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC3C,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,UAAU,CAAC,GAAG,KAAK,QAAQ;QACjG,CAAC,CAAC,UAAU,CAAC,GAAG;QAChB,CAAC,CAAC,SAAS,CAAC;AAAA,CACb;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,YAAoB,EAAE,QAAQ,GAAG,aAAa,EAAE,EAAE;IACrG,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAChE,OAAO,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC3C,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEjC,MAAM,YAAY,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;IAC5C,QAAQ,CAAC,eAAe,GAAG,sBAAsB,CAAC;IAClD,QAAQ,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,gBAAgB,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;AAAA,CACzC;AAED,MAAM,UAAU,oBAAoB,CAAC,QAAQ,GAAG,aAAa,EAAE,EAAE;IAChE,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC3C,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAAA,CAC7B;AAED,SAAS,aAAa,CAAC,OAA6B,EAAE;IACrD,OAAO,OAAO,CAAC,UAAU,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CACnF;AAED,SAAS,YAAY,CAAC,MAAwC,EAAE,OAAe,EAAgB;IAC9F,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7B,GAAG,KAAK;QACR,QAAQ,EAAE,sBAAsB;QAChC,OAAO;QACP,GAAG,EAAE,oBAAoB;KACzB,CAAC,CAAC,CAAC;AAAA,CACJ;AAED,MAAM,UAAU,mBAAmB,GAAG;IACrC,OAAO,cAAc,CAAC;AAAA,CACtB;AAED,MAAM,UAAU,qBAAqB,GAAG;IACvC,cAAc,GAAG,SAAS,CAAC;AAAA,CAC3B;AAED,MAAM,UAAU,6BAA6B,CAC5C,OAAe,EACf,MAA+B,EAC/B,QAAQ,GAAG,aAAa,EAAE,EACT;IACjB,IAAI,aAAa,GAAG,iBAAiB,CAAC,MAAM,EAAE,yCAAyC,CAAC,CAAC;IACzF,OAAO;QACN,IAAI,EAAE,wBAAwB;QAC9B,OAAO;QACP,GAAG,EAAE,oBAAoB;QACzB,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE;YACR,YAAY,EAAE,aAAa;YAC3B,mBAAmB,EAAE,cAAc;SACnC;QACD,MAAM,EAAE,aAAa;QACrB,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE;YAC5B,IAAI,CAAC,OAAO,CAAC,YAAY;gBAAE,OAAO,aAAa,CAAC;YAChD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;YACtC,IAAI,CAAC,MAAM;gBAAE,OAAO,aAAa,CAAC;YAClC,IAAI,CAAC;gBACJ,MAAM,SAAS,GAAG,MAAM,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC9E,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAO,aAAa,CAAC;gBACjD,MAAM,OAAO,CAAC,OAAO,CAAC;oBACrB,OAAO,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;oBAC5E,MAAM,EAAE,GAAG,EAAE,CAAC;wBACb,mBAAmB,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;wBAClD,aAAa,GAAG,SAAS,CAAC;wBAC1B,cAAc,GAAG,SAAS,CAAC;oBAAA,CAC3B;iBACD,CAAC,CAAC;gBACH,OAAO,aAAa,CAAC;YACtB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,cAAc,GAAG;oBAChB,IAAI,EAAE,gBAAgB;oBACtB,OAAO,EAAE,gDAAgD,aAAa,CAAC,MAAM,gBAAgB,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;oBAC/L,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBAC5B,CAAC;gBACF,MAAM,KAAK,CAAC;YACb,CAAC;QAAA,CACD;KACD,CAAC;AAAA,CACF;AAED,MAAM,UAAU,wBAAwB,GAAqB;IAC5D,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;QACnC,IAAI,KAAK,EAAE,CAAC;YACX,EAAE,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,6BAA6B,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACzG,CAAC;QAED,EAAE,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;YACtC,wEAAwE;YACxE,2EAA2E;YAC3E,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,OAAO,CAC9C,oFAAoF,EACpF,6DAA6D,CAC7D,CAAC;YACF,OAAO;gBACN,YAAY,EAAE,GAAG,YAAY;;;;;;oBAMb;aAChB,CAAC;QAAA,CACF,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;YACvC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;YACtC,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;YACtC,IAAI,OAAO;gBAAE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACvD,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;gBAAE,OAAO;YAC/B,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;gBAClC,MAAM,EAAE,GAAG,EAAE,CAAC;oBACb,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;oBACpD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,uBAAsB,KAAK,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC;iBAChG;gBACD,UAAU,GAAG,EAAC,CAAC;aACf,CAAC,CAAC,CAAC;QAAA,CACJ,CAAC,CAAC;IAAA,CACH,CAAC;AAAA,CACF","sourcesContent":["import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { ExtensionAPI, ExtensionFactory, ProviderConfig, ProviderModelConfig } from \"@senpiper/pi-coding-agent\";\nimport type { Api, Model, OpenAICompletionsCompat, RefreshModelsContext } from \"@senpiper/pi-coding-agent/runtime-deps\";\n\nexport type SpExtensionApi = ExtensionAPI;\nexport type SpProviderModelConfig = ProviderModelConfig;\n\nexport const SP_GATEWAY_PROVIDER_ID = \"sp-gateway\";\nexport const LEGACY_SP_GATEWAY_PROVIDER_ID = \"sengateway\";\nexport const SP_GATEWAY_PROVIDER_NAME = \"Senpiper Gateway\";\nexport const SP_USER_AGENT = \"sp\";\nexport const SP_CLIENT_NAME = \"sp-agent\";\n\nexport interface SpGatewayState {\n\tschemaVersion: 1;\n\tbaseUrl: string;\n\tmodels: SpProviderModelConfig[];\n}\n\nexport interface SpGatewayWarning {\n\tkind: \"refresh_failed\" | \"legacy_cache_imported\";\n\tmessage: string;\n\tat: string;\n}\n\ntype JsonRecord = Record<string, unknown>;\n\nlet gatewayWarning: SpGatewayWarning | undefined;\n\nfunction isRecord(value: unknown): value is JsonRecord {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stringValue(value: unknown) {\n\treturn typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction finiteNumber(value: unknown) {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction positiveInteger(value: unknown) {\n\tconst number = finiteNumber(value);\n\treturn number !== undefined && number > 0 ? Math.floor(number) : undefined;\n}\n\nfunction nonNegativeNumber(value: unknown) {\n\tconst number = finiteNumber(value);\n\treturn number !== undefined && number >= 0 ? number : undefined;\n}\n\nfunction booleanValue(value: unknown) {\n\treturn typeof value === \"boolean\" ? value : undefined;\n}\n\nexport function getSpAgentDir() {\n\treturn process.env.SP_CODING_AGENT_DIR || join(homedir(), \".sp\", \"agent\");\n}\n\nexport function getSpGatewayStatePath(agentDir = getSpAgentDir()) {\n\treturn join(agentDir, \"sp-gateway.json\");\n}\n\nexport function getLegacyModelsPath(agentDir = getSpAgentDir()) {\n\treturn join(agentDir, \"models.json\");\n}\n\nexport function getSpAuthPath(agentDir = getSpAgentDir()) {\n\treturn join(agentDir, \"auth.json\");\n}\n\nexport function getSpSettingsPath(agentDir = getSpAgentDir()) {\n\treturn join(agentDir, \"settings.json\");\n}\n\nfunction readJsonFile(path: string): JsonRecord {\n\tif (!existsSync(path)) return {};\n\tconst content = readFileSync(path, \"utf8\").trim();\n\tif (!content) return {};\n\tconst parsed = JSON.parse(content) as unknown;\n\tif (!isRecord(parsed)) throw new Error(`Expected an object in ${path}`);\n\treturn parsed;\n}\n\nfunction writePrivateJson(path: string, value: unknown) {\n\tmkdirSync(dirname(path), { recursive: true });\n\tconst temporaryPath = `${path}.${process.pid}.tmp`;\n\twriteFileSync(temporaryPath, `${JSON.stringify(value, null, \"\\t\")}\\n`, { encoding: \"utf8\", mode: 0o600 });\n\tif (process.platform !== \"win32\") chmodSync(temporaryPath, 0o600);\n\trenameSync(temporaryPath, path);\n\tif (process.platform !== \"win32\") chmodSync(path, 0o600);\n}\n\nexport function normalizeSpGatewayBaseUrl(input: string) {\n\tconst trimmed = input.trim();\n\tif (!trimmed) throw new Error(\"Gateway URL cannot be empty.\");\n\tconst withScheme = /^[a-z][a-z0-9+.-]*:\\/\\//iu.test(trimmed) ? trimmed : `https://${trimmed}`;\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(withScheme);\n\t} catch {\n\t\tthrow new Error(`Invalid gateway URL: ${input}`);\n\t}\n\tif (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n\t\tthrow new Error(\"Gateway URL must use HTTPS or HTTP.\");\n\t}\n\turl.hash = \"\";\n\turl.search = \"\";\n\turl.pathname = url.pathname.replace(/\\/+$/u, \"\");\n\tif (!url.pathname.endsWith(\"/v1\")) url.pathname = `${url.pathname}/v1`.replace(/\\/+/gu, \"/\");\n\treturn url.toString().replace(/\\/$/u, \"\");\n}\n\nfunction parseInput(value: unknown): (\"text\" | \"image\")[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst input = value.filter((entry): entry is \"text\" | \"image\" => entry === \"text\" || entry === \"image\");\n\treturn input.length > 0 ? [...new Set(input)] : undefined;\n}\n\nfunction parseCost(value: unknown): SpProviderModelConfig[\"cost\"] | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst input = nonNegativeNumber(value.input);\n\tconst output = nonNegativeNumber(value.output);\n\tconst cacheRead = nonNegativeNumber(value.cacheRead);\n\tconst cacheWrite = nonNegativeNumber(value.cacheWrite);\n\tif (input === undefined && output === undefined && cacheRead === undefined && cacheWrite === undefined)\n\t\treturn undefined;\n\treturn { input: input ?? 0, output: output ?? 0, cacheRead: cacheRead ?? 0, cacheWrite: cacheWrite ?? 0 };\n}\n\nfunction parseThinkingLevelMap(value: unknown): SpProviderModelConfig[\"thinkingLevelMap\"] {\n\tif (!isRecord(value)) return undefined;\n\tconst result: NonNullable<SpProviderModelConfig[\"thinkingLevelMap\"]> = {};\n\tfor (const key of [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\"] as const) {\n\t\tconst entry = value[key];\n\t\tif (typeof entry === \"string\" || entry === null) result[key] = entry;\n\t}\n\treturn Object.keys(result).length > 0 ? result : undefined;\n}\n\nfunction thinkingFormat(value: unknown): OpenAICompletionsCompat[\"thinkingFormat\"] {\n\tswitch (value) {\n\t\tcase \"openai\":\n\t\tcase \"openrouter\":\n\t\tcase \"deepseek\":\n\t\tcase \"together\":\n\t\tcase \"zai\":\n\t\tcase \"qwen\":\n\t\tcase \"chat-template\":\n\t\tcase \"qwen-chat-template\":\n\t\tcase \"string-thinking\":\n\t\tcase \"ant-ling\":\n\t\t\treturn value;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nfunction sessionAffinityFormat(value: unknown): OpenAICompletionsCompat[\"sessionAffinityFormat\"] {\n\treturn value === \"openai\" || value === \"openai-nosession\" || value === \"openrouter\" ? value : undefined;\n}\n\nfunction parseCompat(value: unknown): OpenAICompletionsCompat {\n\tconst record = isRecord(value) ? value : {};\n\tconst maxTokensField =\n\t\trecord.maxTokensField === \"max_completion_tokens\" || record.maxTokensField === \"max_tokens\"\n\t\t\t? record.maxTokensField\n\t\t\t: undefined;\n\tconst compat = {\n\t\tsupportsStore: booleanValue(record.supportsStore) ?? false,\n\t\tsupportsDeveloperRole: booleanValue(record.supportsDeveloperRole),\n\t\tsupportsReasoningEffort: booleanValue(record.supportsReasoningEffort),\n\t\tsupportsUsageInStreaming: booleanValue(record.supportsUsageInStreaming),\n\t\tmaxTokensField,\n\t\trequiresToolResultName: booleanValue(record.requiresToolResultName),\n\t\trequiresAssistantAfterToolResult: booleanValue(record.requiresAssistantAfterToolResult),\n\t\trequiresThinkingAsText: booleanValue(record.requiresThinkingAsText),\n\t\trequiresReasoningContentOnAssistantMessages: booleanValue(record.requiresReasoningContentOnAssistantMessages),\n\t\tthinkingFormat: thinkingFormat(record.thinkingFormat),\n\t\tsupportsStrictMode: booleanValue(record.supportsStrictMode),\n\t\tsendSessionAffinityHeaders: booleanValue(record.sendSessionAffinityHeaders),\n\t\tsessionAffinityFormat: sessionAffinityFormat(record.sessionAffinityFormat),\n\t\tsupportsLongCacheRetention: booleanValue(record.supportsLongCacheRetention),\n\t} satisfies OpenAICompletionsCompat;\n\treturn compat;\n}\n\nfunction parseGatewayModel(value: unknown): SpProviderModelConfig | undefined {\n\tconst record = typeof value === \"string\" ? { id: value } : isRecord(value) ? value : undefined;\n\tif (!record) return undefined;\n\tconst id = stringValue(record.id);\n\tif (!id || id.length > 256 || /[\\u0000-\\u001f\\u007f]/u.test(id)) return undefined;\n\tconst metadata = isRecord(record.metadata) ? record.metadata : {};\n\tconst field = (name: string) => metadata[name] ?? record[name];\n\tconst reasoning = field(\"reasoning\");\n\treturn {\n\t\tid,\n\t\tname: stringValue(field(\"name\")) ?? id,\n\t\treasoning: typeof reasoning === \"boolean\" ? reasoning : false,\n\t\tthinkingLevelMap: parseThinkingLevelMap(field(\"thinkingLevelMap\")),\n\t\tinput: parseInput(field(\"input\")) ?? [\"text\"],\n\t\tcost: parseCost(field(\"cost\")) ?? { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: positiveInteger(field(\"contextWindow\")) ?? 128_000,\n\t\tmaxTokens: positiveInteger(field(\"maxTokens\")) ?? 32_000,\n\t\tcompat: parseCompat(field(\"compat\")),\n\t};\n}\n\nfunction parseModelCatalog(values: readonly unknown[], source: string) {\n\tconst models = values.map(parseGatewayModel).filter((model): model is SpProviderModelConfig => model !== undefined);\n\tif (models.length === 0) throw new Error(`${source} contains no valid models.`);\n\tconst ids = new Set<string>();\n\tfor (const model of models) {\n\t\tif (ids.has(model.id)) throw new Error(`${source} contains duplicate model id ${model.id}.`);\n\t\tids.add(model.id);\n\t}\n\treturn models;\n}\n\nexport async function fetchSpGatewayModels(baseUrl: string, apiKey: string, signal?: AbortSignal) {\n\tconst response = await fetch(`${baseUrl.replace(/\\/$/u, \"\")}/models`, {\n\t\tsignal,\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\tAccept: \"application/json\",\n\t\t\t\"User-Agent\": SP_USER_AGENT,\n\t\t\t\"X-Senpiper-Client\": SP_CLIENT_NAME,\n\t\t},\n\t});\n\tif (!response.ok) {\n\t\tconst body = await response.text().catch(() => \"\");\n\t\tconst suffix = body.trim() ? `: ${body.trim().slice(0, 300)}` : \"\";\n\t\tthrow new Error(`Senpiper Gateway rejected /v1/models (${response.status} ${response.statusText})${suffix}`);\n\t}\n\tconst payload = (await response.json()) as unknown;\n\tif (!isRecord(payload) || !Array.isArray(payload.data)) {\n\t\tthrow new Error(\"Senpiper Gateway returned an invalid /v1/models envelope.\");\n\t}\n\treturn parseModelCatalog(payload.data, \"Senpiper Gateway /v1/models response\");\n}\n\nfunction readLegacySpGatewayState(agentDir: string): SpGatewayState | undefined {\n\tconst path = getLegacyModelsPath(agentDir);\n\tif (!existsSync(path)) return undefined;\n\tconst root = readJsonFile(path);\n\tconst providers = isRecord(root.providers) ? root.providers : undefined;\n\tconst providerValue = providers?.[SP_GATEWAY_PROVIDER_ID] ?? providers?.[LEGACY_SP_GATEWAY_PROVIDER_ID];\n\tconst provider = isRecord(providerValue) ? providerValue : undefined;\n\tif (!provider || typeof provider.baseUrl !== \"string\" || !Array.isArray(provider.models)) return undefined;\n\treturn {\n\t\tschemaVersion: 1,\n\t\tbaseUrl: normalizeSpGatewayBaseUrl(provider.baseUrl),\n\t\tmodels: parseModelCatalog(provider.models, `legacy Senpiper Gateway cache ${path}`),\n\t};\n}\n\nexport function readSpGatewayState(agentDir = getSpAgentDir()): SpGatewayState | undefined {\n\tconst path = getSpGatewayStatePath(agentDir);\n\tif (!existsSync(path)) {\n\t\tconst legacy = readLegacySpGatewayState(agentDir);\n\t\tif (!legacy) return undefined;\n\t\twriteSpGatewayState(legacy.baseUrl, legacy.models, agentDir);\n\t\tgatewayWarning = {\n\t\t\tkind: \"legacy_cache_imported\",\n\t\t\tmessage: `Imported the legacy Senpiper Gateway model cache from ${getLegacyModelsPath(agentDir)}.`,\n\t\t\tat: new Date().toISOString(),\n\t\t};\n\t\treturn legacy;\n\t}\n\tconst value = readJsonFile(path);\n\tif (value.schemaVersion !== 1 || typeof value.baseUrl !== \"string\" || !Array.isArray(value.models)) {\n\t\tthrow new Error(`Invalid Senpiper Gateway configuration: ${path}`);\n\t}\n\treturn {\n\t\tschemaVersion: 1,\n\t\tbaseUrl: normalizeSpGatewayBaseUrl(value.baseUrl),\n\t\tmodels: parseModelCatalog(value.models, `Senpiper Gateway configuration ${path}`),\n\t};\n}\n\nexport function writeSpGatewayState(baseUrl: string, models: SpProviderModelConfig[], agentDir = getSpAgentDir()) {\n\tconst validatedModels = parseModelCatalog(models, \"Senpiper Gateway state\");\n\twritePrivateJson(getSpGatewayStatePath(agentDir), {\n\t\tschemaVersion: 1,\n\t\tbaseUrl: normalizeSpGatewayBaseUrl(baseUrl),\n\t\tmodels: validatedModels,\n\t} satisfies SpGatewayState);\n}\n\nexport function readSpGatewayApiKey(agentDir = getSpAgentDir()) {\n\tconst path = getSpAuthPath(agentDir);\n\tconst auth = readJsonFile(path);\n\tlet credential = auth[SP_GATEWAY_PROVIDER_ID];\n\tif (!credential && auth[LEGACY_SP_GATEWAY_PROVIDER_ID]) {\n\t\tcredential = auth[LEGACY_SP_GATEWAY_PROVIDER_ID];\n\t\tauth[SP_GATEWAY_PROVIDER_ID] = credential;\n\t\tdelete auth[LEGACY_SP_GATEWAY_PROVIDER_ID];\n\t\twritePrivateJson(path, auth);\n\t}\n\treturn isRecord(credential) && credential.type === \"api_key\" && typeof credential.key === \"string\"\n\t\t? credential.key\n\t\t: undefined;\n}\n\nexport function writeSpGatewayLogin(apiKey: string, firstModelId: string, agentDir = getSpAgentDir()) {\n\tconst authPath = getSpAuthPath(agentDir);\n\tconst auth = readJsonFile(authPath);\n\tauth[SP_GATEWAY_PROVIDER_ID] = { type: \"api_key\", key: apiKey };\n\tdelete auth[LEGACY_SP_GATEWAY_PROVIDER_ID];\n\twritePrivateJson(authPath, auth);\n\n\tconst settingsPath = getSpSettingsPath(agentDir);\n\tconst settings = readJsonFile(settingsPath);\n\tsettings.defaultProvider = SP_GATEWAY_PROVIDER_ID;\n\tsettings.defaultModel = firstModelId;\n\twritePrivateJson(settingsPath, settings);\n}\n\nexport function removeSpGatewayLogin(agentDir = getSpAgentDir()) {\n\tconst path = getSpAuthPath(agentDir);\n\tconst auth = readJsonFile(path);\n\tdelete auth[SP_GATEWAY_PROVIDER_ID];\n\tdelete auth[LEGACY_SP_GATEWAY_PROVIDER_ID];\n\twritePrivateJson(path, auth);\n}\n\nfunction credentialKey(context: RefreshModelsContext) {\n\treturn context.credential?.type === \"api_key\" ? context.credential.key : undefined;\n}\n\nfunction storedModels(models: readonly SpProviderModelConfig[], baseUrl: string): Model<Api>[] {\n\treturn models.map((model) => ({\n\t\t...model,\n\t\tprovider: SP_GATEWAY_PROVIDER_ID,\n\t\tbaseUrl,\n\t\tapi: \"openai-completions\",\n\t}));\n}\n\nexport function getSpGatewayWarning() {\n\treturn gatewayWarning;\n}\n\nexport function clearSpGatewayWarning() {\n\tgatewayWarning = undefined;\n}\n\nexport function createSpGatewayProviderConfig(\n\tbaseUrl: string,\n\tmodels: SpProviderModelConfig[],\n\tagentDir = getSpAgentDir(),\n): ProviderConfig {\n\tlet currentModels = parseModelCatalog(models, \"Senpiper Gateway provider configuration\");\n\treturn {\n\t\tname: SP_GATEWAY_PROVIDER_NAME,\n\t\tbaseUrl,\n\t\tapi: \"openai-completions\",\n\t\tauthHeader: true,\n\t\theaders: {\n\t\t\t\"User-Agent\": SP_USER_AGENT,\n\t\t\t\"X-Senpiper-Client\": SP_CLIENT_NAME,\n\t\t},\n\t\tmodels: currentModels,\n\t\tasync refreshModels(context) {\n\t\t\tif (!context.allowNetwork) return currentModels;\n\t\t\tconst apiKey = credentialKey(context);\n\t\t\tif (!apiKey) return currentModels;\n\t\t\ttry {\n\t\t\t\tconst refreshed = await fetchSpGatewayModels(baseUrl, apiKey, context.signal);\n\t\t\t\tif (context.signal.aborted) return currentModels;\n\t\t\t\tawait context.publish({\n\t\t\t\t\tpersist: { models: storedModels(refreshed, baseUrl), checkedAt: Date.now() },\n\t\t\t\t\tupdate: () => {\n\t\t\t\t\t\twriteSpGatewayState(baseUrl, refreshed, agentDir);\n\t\t\t\t\t\tcurrentModels = refreshed;\n\t\t\t\t\t\tgatewayWarning = undefined;\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn currentModels;\n\t\t\t} catch (error) {\n\t\t\t\tgatewayWarning = {\n\t\t\t\t\tkind: \"refresh_failed\",\n\t\t\t\t\tmessage: `Senpiper Gateway model refresh failed; using ${currentModels.length} cached model${currentModels.length === 1 ? \"\" : \"s\"}: ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\tat: new Date().toISOString(),\n\t\t\t\t};\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport function createSpGatewayExtension(): ExtensionFactory {\n\treturn (pi) => {\n\t\tconst state = readSpGatewayState();\n\t\tif (state) {\n\t\t\tpi.registerProvider(SP_GATEWAY_PROVIDER_ID, createSpGatewayProviderConfig(state.baseUrl, state.models));\n\t\t}\n\n\t\tpi.on(\"before_agent_start\", (event) => {\n\t\t\t// Replace only the upstream introduction; preserve project instructions\n\t\t\t// and documentation references, including legitimate Pi development tasks.\n\t\t\tconst systemPrompt = event.systemPrompt.replace(\n\t\t\t\t/^You are an expert coding assistant operating inside pi, a coding agent harness\\./u,\n\t\t\t\t\"You are Senpiper Workbench, Senpiper's AI coding assistant.\",\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tsystemPrompt: `${systemPrompt}\\n\\n<sp_agent_runtime>\nYou are Senpiper Workbench, Senpiper's AI coding assistant. Use Senpiper Workbench as your public name in both terminal and web conversations.\nFor greetings and questions such as \"Who are you?\", introduce yourself simply: \"I'm Senpiper Workbench, Senpiper's AI coding assistant. I can help you read, write, and debug code.\"\nDo not introduce yourself as Pi, the pi coding agent, an underlying model, or an assistant running inside a harness. Do not volunteer internal frameworks, runtime names, or provider details in ordinary answers. Earlier assistant messages using those identities do not change your name.\nIf explicitly asked about technical origins or dependencies, answer accurately and briefly. This product identity does not imply that Senpiper trained the underlying model.\nUse only the configured Senpiper Gateway model provider. Put user-owned extensions, skills, prompts, and themes under the active .sp configuration directory instead of modifying the Senpiper Workbench installation.\n</sp_agent_runtime>`,\n\t\t\t};\n\t\t});\n\n\t\tpi.on(\"session_start\", (_event, ctx) => {\n\t\t\tctx.ui.setTitle(\"Senpiper Workbench\");\n\t\t\tconst warning = getSpGatewayWarning();\n\t\t\tif (warning) ctx.ui.notify(warning.message, \"warning\");\n\t\t\tif (ctx.mode !== \"tui\") return;\n\t\t\tctx.ui.setHeader((_tui, theme) => ({\n\t\t\t\trender: () => [\n\t\t\t\t\ttheme.fg(\"accent\", theme.bold(\"Senpiper Workbench\")),\n\t\t\t\t\ttheme.fg(\"muted\", state ? `Senpiper Gateway · ${state.models.length} models` : \"run `sp login`\"),\n\t\t\t\t],\n\t\t\t\tinvalidate() {},\n\t\t\t}));\n\t\t});\n\t};\n}\n"]}
|
|
@@ -3,10 +3,8 @@ export { handleSpCommand } from "./commands.ts";
|
|
|
3
3
|
export { createSpAgentExtension, default } from "./extension.ts";
|
|
4
4
|
export { clearSpGatewayWarning, createSpGatewayExtension, createSpGatewayProviderConfig, fetchSpGatewayModels, getLegacyModelsPath, getSpAgentDir, getSpAuthPath, getSpGatewayStatePath, getSpGatewayWarning, normalizeSpGatewayBaseUrl, readSpGatewayApiKey, readSpGatewayState, removeSpGatewayLogin, SP_CLIENT_NAME, SP_GATEWAY_PROVIDER_ID, SP_GATEWAY_PROVIDER_NAME, SP_USER_AGENT, writeSpGatewayLogin, writeSpGatewayState, } from "./gateway.ts";
|
|
5
5
|
export { registerInteractionExtensions } from "./interactions.ts";
|
|
6
|
-
export { clearOnboardingState, fetchSkillCatalog, getOnboardingStatePath, hasCompletedOnboarding, installCatalogSkills, parseSkillCatalog, selectCatalogSkills, writeOnboardingState, } from "./onboarding.ts";
|
|
7
|
-
export { installOnboardingSelection, type OnboardingInstallationResult } from "./onboarding-installation.ts";
|
|
8
6
|
export type { PendingQuestion, QuestionResponse } from "./question-interaction.ts";
|
|
9
|
-
export { ensureSpWebSidecar, getSpWebSidecarStatePath, resolveSpWebLaunch, type SpWebLauncherOptions, type SpWebLaunchResult, type SpWebSidecarState, } from "./sp-web-launcher.ts";
|
|
7
|
+
export { ensureSpWebSidecar, getSpWebSidecarStatePath, resolveSpWebLaunch, type SpWebLauncherOptions, type SpWebLaunchResult, type SpWebSidecarState, type SpWebStopResult, stopSpWebSidecar, } from "./sp-web-launcher.ts";
|
|
10
8
|
export { filterSpStartupMessage, registerSpStartupHeader, renderSpStartupHeader } from "./startup-header.ts";
|
|
11
9
|
export { DEFAULT_TERMINAL_BRIDGE_MAX_BUFFERED_BYTES, DEFAULT_TERMINAL_BRIDGE_MAX_CLIENTS, DEFAULT_TERMINAL_BRIDGE_MAX_FRAME_BYTES, readTerminalBridgeDescriptor, registerTerminalWebBridge, TERMINAL_BRIDGE_PROTOCOL, TERMINAL_BRIDGE_VERSION, type TerminalBridgeDescriptor, TerminalWebBridge, type TerminalWebBridgeOptions, terminalBridgeDescriptorExists, } from "./terminal-web-bridge.ts";
|
|
12
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,4BAA4B,EAC5B,mCAAmC,EACnC,uBAAuB,EACvB,+BAA+B,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EACN,qBAAqB,EACrB,wBAAwB,EACxB,6BAA6B,EAC7B,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAClE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,4BAA4B,EAC5B,mCAAmC,EACnC,uBAAuB,EACvB,+BAA+B,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EACN,qBAAqB,EACrB,wBAAwB,EACxB,6BAA6B,EAC7B,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAClE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACnF,OAAO,EACN,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,gBAAgB,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC7G,OAAO,EACN,0CAA0C,EAC1C,mCAAmC,EACnC,uCAAuC,EACvC,4BAA4B,EAC5B,yBAAyB,EACzB,wBAAwB,EACxB,uBAAuB,EACvB,KAAK,wBAAwB,EAC7B,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,8BAA8B,GAC9B,MAAM,0BAA0B,CAAC","sourcesContent":["export {\n\tAskUserSchema,\n\tbuildAskUserQuestionResponse,\n\tcreateAskUserQuestionToolDefinition,\n\tregisterAskUserQuestion,\n\tvalidateAskUserQuestionEnvelope,\n} from \"./ask-user.ts\";\nexport { handleSpCommand } from \"./commands.ts\";\nexport { createSpAgentExtension, default } from \"./extension.ts\";\nexport {\n\tclearSpGatewayWarning,\n\tcreateSpGatewayExtension,\n\tcreateSpGatewayProviderConfig,\n\tfetchSpGatewayModels,\n\tgetLegacyModelsPath,\n\tgetSpAgentDir,\n\tgetSpAuthPath,\n\tgetSpGatewayStatePath,\n\tgetSpGatewayWarning,\n\tnormalizeSpGatewayBaseUrl,\n\treadSpGatewayApiKey,\n\treadSpGatewayState,\n\tremoveSpGatewayLogin,\n\tSP_CLIENT_NAME,\n\tSP_GATEWAY_PROVIDER_ID,\n\tSP_GATEWAY_PROVIDER_NAME,\n\tSP_USER_AGENT,\n\twriteSpGatewayLogin,\n\twriteSpGatewayState,\n} from \"./gateway.ts\";\nexport { registerInteractionExtensions } from \"./interactions.ts\";\nexport type { PendingQuestion, QuestionResponse } from \"./question-interaction.ts\";\nexport {\n\tensureSpWebSidecar,\n\tgetSpWebSidecarStatePath,\n\tresolveSpWebLaunch,\n\ttype SpWebLauncherOptions,\n\ttype SpWebLaunchResult,\n\ttype SpWebSidecarState,\n\ttype SpWebStopResult,\n\tstopSpWebSidecar,\n} from \"./sp-web-launcher.ts\";\nexport { filterSpStartupMessage, registerSpStartupHeader, renderSpStartupHeader } from \"./startup-header.ts\";\nexport {\n\tDEFAULT_TERMINAL_BRIDGE_MAX_BUFFERED_BYTES,\n\tDEFAULT_TERMINAL_BRIDGE_MAX_CLIENTS,\n\tDEFAULT_TERMINAL_BRIDGE_MAX_FRAME_BYTES,\n\treadTerminalBridgeDescriptor,\n\tregisterTerminalWebBridge,\n\tTERMINAL_BRIDGE_PROTOCOL,\n\tTERMINAL_BRIDGE_VERSION,\n\ttype TerminalBridgeDescriptor,\n\tTerminalWebBridge,\n\ttype TerminalWebBridgeOptions,\n\tterminalBridgeDescriptorExists,\n} from \"./terminal-web-bridge.ts\";\n"]}
|
|
@@ -3,9 +3,7 @@ export { handleSpCommand } from "./commands.js";
|
|
|
3
3
|
export { createSpAgentExtension, default } from "./extension.js";
|
|
4
4
|
export { clearSpGatewayWarning, createSpGatewayExtension, createSpGatewayProviderConfig, fetchSpGatewayModels, getLegacyModelsPath, getSpAgentDir, getSpAuthPath, getSpGatewayStatePath, getSpGatewayWarning, normalizeSpGatewayBaseUrl, readSpGatewayApiKey, readSpGatewayState, removeSpGatewayLogin, SP_CLIENT_NAME, SP_GATEWAY_PROVIDER_ID, SP_GATEWAY_PROVIDER_NAME, SP_USER_AGENT, writeSpGatewayLogin, writeSpGatewayState, } from "./gateway.js";
|
|
5
5
|
export { registerInteractionExtensions } from "./interactions.js";
|
|
6
|
-
export {
|
|
7
|
-
export { installOnboardingSelection } from "./onboarding-installation.js";
|
|
8
|
-
export { ensureSpWebSidecar, getSpWebSidecarStatePath, resolveSpWebLaunch, } from "./sp-web-launcher.js";
|
|
6
|
+
export { ensureSpWebSidecar, getSpWebSidecarStatePath, resolveSpWebLaunch, stopSpWebSidecar, } from "./sp-web-launcher.js";
|
|
9
7
|
export { filterSpStartupMessage, registerSpStartupHeader, renderSpStartupHeader } from "./startup-header.js";
|
|
10
8
|
export { DEFAULT_TERMINAL_BRIDGE_MAX_BUFFERED_BYTES, DEFAULT_TERMINAL_BRIDGE_MAX_CLIENTS, DEFAULT_TERMINAL_BRIDGE_MAX_FRAME_BYTES, readTerminalBridgeDescriptor, registerTerminalWebBridge, TERMINAL_BRIDGE_PROTOCOL, TERMINAL_BRIDGE_VERSION, TerminalWebBridge, terminalBridgeDescriptorExists, } from "./terminal-web-bridge.js";
|
|
11
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,4BAA4B,EAC5B,mCAAmC,EACnC,uBAAuB,EACvB,+BAA+B,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EACN,qBAAqB,EACrB,wBAAwB,EACxB,6BAA6B,EAC7B,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,4BAA4B,EAC5B,mCAAmC,EACnC,uBAAuB,EACvB,+BAA+B,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EACN,qBAAqB,EACrB,wBAAwB,EACxB,6BAA6B,EAC7B,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,qBAAqB,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,EACb,mBAAmB,EACnB,mBAAmB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAElE,OAAO,EACN,kBAAkB,EAClB,wBAAwB,EACxB,kBAAkB,EAKlB,gBAAgB,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC7G,OAAO,EACN,0CAA0C,EAC1C,mCAAmC,EACnC,uCAAuC,EACvC,4BAA4B,EAC5B,yBAAyB,EACzB,wBAAwB,EACxB,uBAAuB,EAEvB,iBAAiB,EAEjB,8BAA8B,GAC9B,MAAM,0BAA0B,CAAC","sourcesContent":["export {\n\tAskUserSchema,\n\tbuildAskUserQuestionResponse,\n\tcreateAskUserQuestionToolDefinition,\n\tregisterAskUserQuestion,\n\tvalidateAskUserQuestionEnvelope,\n} from \"./ask-user.ts\";\nexport { handleSpCommand } from \"./commands.ts\";\nexport { createSpAgentExtension, default } from \"./extension.ts\";\nexport {\n\tclearSpGatewayWarning,\n\tcreateSpGatewayExtension,\n\tcreateSpGatewayProviderConfig,\n\tfetchSpGatewayModels,\n\tgetLegacyModelsPath,\n\tgetSpAgentDir,\n\tgetSpAuthPath,\n\tgetSpGatewayStatePath,\n\tgetSpGatewayWarning,\n\tnormalizeSpGatewayBaseUrl,\n\treadSpGatewayApiKey,\n\treadSpGatewayState,\n\tremoveSpGatewayLogin,\n\tSP_CLIENT_NAME,\n\tSP_GATEWAY_PROVIDER_ID,\n\tSP_GATEWAY_PROVIDER_NAME,\n\tSP_USER_AGENT,\n\twriteSpGatewayLogin,\n\twriteSpGatewayState,\n} from \"./gateway.ts\";\nexport { registerInteractionExtensions } from \"./interactions.ts\";\nexport type { PendingQuestion, QuestionResponse } from \"./question-interaction.ts\";\nexport {\n\tensureSpWebSidecar,\n\tgetSpWebSidecarStatePath,\n\tresolveSpWebLaunch,\n\ttype SpWebLauncherOptions,\n\ttype SpWebLaunchResult,\n\ttype SpWebSidecarState,\n\ttype SpWebStopResult,\n\tstopSpWebSidecar,\n} from \"./sp-web-launcher.ts\";\nexport { filterSpStartupMessage, registerSpStartupHeader, renderSpStartupHeader } from \"./startup-header.ts\";\nexport {\n\tDEFAULT_TERMINAL_BRIDGE_MAX_BUFFERED_BYTES,\n\tDEFAULT_TERMINAL_BRIDGE_MAX_CLIENTS,\n\tDEFAULT_TERMINAL_BRIDGE_MAX_FRAME_BYTES,\n\treadTerminalBridgeDescriptor,\n\tregisterTerminalWebBridge,\n\tTERMINAL_BRIDGE_PROTOCOL,\n\tTERMINAL_BRIDGE_VERSION,\n\ttype TerminalBridgeDescriptor,\n\tTerminalWebBridge,\n\ttype TerminalWebBridgeOptions,\n\tterminalBridgeDescriptorExists,\n} from \"./terminal-web-bridge.ts\";\n"]}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionCommandContext } from "@senpiper/pi-coding-agent";
|
|
2
|
-
import { runInteractiveOnboarding } from "./onboarding-command.ts";
|
|
3
2
|
export type InteractionContext = ExtensionCommandContext;
|
|
4
3
|
export type InteractionExtensionApi = ExtensionAPI;
|
|
5
|
-
export { runInteractiveOnboarding };
|
|
6
4
|
export declare function registerInteractionExtensions(pi: ExtensionAPI): void;
|
|
7
5
|
//# sourceMappingURL=interactions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactions.d.ts","sourceRoot":"","sources":["../src/interactions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"interactions.d.ts","sourceRoot":"","sources":["../src/interactions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAGvF,MAAM,MAAM,kBAAkB,GAAG,uBAAuB,CAAC;AACzD,MAAM,MAAM,uBAAuB,GAAG,YAAY,CAAC;AAEnD,wBAAgB,6BAA6B,CAAC,EAAE,EAAE,YAAY,QAE7D","sourcesContent":["import type { ExtensionAPI, ExtensionCommandContext } from \"@senpiper/pi-coding-agent\";\nimport { registerAskUserQuestion } from \"./ask-user.ts\";\n\nexport type InteractionContext = ExtensionCommandContext;\nexport type InteractionExtensionApi = ExtensionAPI;\n\nexport function registerInteractionExtensions(pi: ExtensionAPI) {\n\tregisterAskUserQuestion(pi);\n}\n"]}
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { registerAskUserQuestion } from "./ask-user.js";
|
|
2
|
-
import { registerOnboardingCommand, runInteractiveOnboarding } from "./onboarding-command.js";
|
|
3
|
-
export { runInteractiveOnboarding };
|
|
4
2
|
export function registerInteractionExtensions(pi) {
|
|
5
3
|
registerAskUserQuestion(pi);
|
|
6
|
-
registerOnboardingCommand(pi);
|
|
7
4
|
}
|
|
8
5
|
//# sourceMappingURL=interactions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactions.js","sourceRoot":"","sources":["../src/interactions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"interactions.js","sourceRoot":"","sources":["../src/interactions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAKxD,MAAM,UAAU,6BAA6B,CAAC,EAAgB,EAAE;IAC/D,uBAAuB,CAAC,EAAE,CAAC,CAAC;AAAA,CAC5B","sourcesContent":["import type { ExtensionAPI, ExtensionCommandContext } from \"@senpiper/pi-coding-agent\";\nimport { registerAskUserQuestion } from \"./ask-user.ts\";\n\nexport type InteractionContext = ExtensionCommandContext;\nexport type InteractionExtensionApi = ExtensionAPI;\n\nexport function registerInteractionExtensions(pi: ExtensionAPI) {\n\tregisterAskUserQuestion(pi);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login-command.d.ts","sourceRoot":"","sources":["../src/login-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"login-command.d.ts","sourceRoot":"","sources":["../src/login-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAWvF,wBAAsB,aAAa,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,oBAkDnG;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,YAAY,QAYpD","sourcesContent":["import type { ExtensionAPI, ExtensionCommandContext } from \"@senpiper/pi-coding-agent\";\nimport {\n\tcreateSpGatewayProviderConfig,\n\tfetchSpGatewayModels,\n\tnormalizeSpGatewayBaseUrl,\n\treadSpGatewayState,\n\tSP_GATEWAY_PROVIDER_ID,\n\twriteSpGatewayLogin,\n\twriteSpGatewayState,\n} from \"./gateway.ts\";\n\nexport async function runSlashLogin(pi: ExtensionAPI, args: string, context: ExtensionCommandContext) {\n\tconst existingState = readSpGatewayState();\n\tconst argumentUrl = args.trim();\n\tconst enteredUrl = argumentUrl\n\t\t? argumentUrl\n\t\t: await context.ui.input(\"Senpiper Gateway URL\", existingState?.baseUrl ?? \"https://gateway.example.com/v1\");\n\tif (enteredUrl === undefined) {\n\t\tcontext.ui.notify(\"Senpiper Gateway login cancelled.\", \"warning\");\n\t\treturn false;\n\t}\n\tconst gatewayUrl = enteredUrl.trim() || existingState?.baseUrl;\n\tif (!gatewayUrl) {\n\t\tcontext.ui.notify(\"A Senpiper Gateway URL is required.\", \"error\");\n\t\treturn false;\n\t}\n\tconst apiKey = await context.ui.input(\"Senpiper Gateway API key\", \"Paste your API key\", { secret: true });\n\tif (!apiKey?.trim()) {\n\t\tcontext.ui.notify(\n\t\t\tapiKey === undefined ? \"Senpiper Gateway login cancelled.\" : \"An API key is required.\",\n\t\t\t\"warning\",\n\t\t);\n\t\treturn false;\n\t}\n\n\tcontext.ui.setProgress(\"Connecting to Senpiper Gateway and synchronizing models…\");\n\ttry {\n\t\tconst baseUrl = normalizeSpGatewayBaseUrl(gatewayUrl);\n\t\tconst models = await fetchSpGatewayModels(baseUrl, apiKey.trim());\n\t\twriteSpGatewayState(baseUrl, models);\n\t\twriteSpGatewayLogin(apiKey.trim(), models[0]!.id);\n\t\tpi.registerProvider(SP_GATEWAY_PROVIDER_ID, createSpGatewayProviderConfig(baseUrl, models));\n\t\tawait context.modelRegistry.setRuntimeApiKey(SP_GATEWAY_PROVIDER_ID, apiKey.trim());\n\t\tconst firstModel = models[0]!;\n\t\tconst selected = await pi.setModel({\n\t\t\t...firstModel,\n\t\t\tprovider: SP_GATEWAY_PROVIDER_ID,\n\t\t\tbaseUrl,\n\t\t\tapi: \"openai-completions\",\n\t\t});\n\t\tcontext.ui.notify(\n\t\t\tselected\n\t\t\t\t? `Connected to Senpiper Gateway · ${models.length} models · selected ${firstModel.id}.`\n\t\t\t\t: `Connected to Senpiper Gateway · ${models.length} models available. Use /model to select one.`,\n\t\t\t\"info\",\n\t\t);\n\t} finally {\n\t\tcontext.ui.setProgress(undefined);\n\t}\n\n\treturn true;\n}\n\nexport function registerLoginCommand(pi: ExtensionAPI) {\n\tpi.registerCommand(\"login\", {\n\t\tdescription: \"Log in to Senpiper Gateway\",\n\t\thandler: async (args, context) => {\n\t\t\ttry {\n\t\t\t\tawait runSlashLogin(pi, args, context);\n\t\t\t} catch (error) {\n\t\t\t\tcontext.ui.setProgress(undefined);\n\t\t\t\tcontext.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
|
|
@@ -1,27 +1,25 @@
|
|
|
1
|
-
import { createSpGatewayProviderConfig, fetchSpGatewayModels,
|
|
2
|
-
import { hasCompletedOnboarding } from "./onboarding.js";
|
|
3
|
-
import { runInteractiveOnboarding } from "./onboarding-command.js";
|
|
1
|
+
import { createSpGatewayProviderConfig, fetchSpGatewayModels, normalizeSpGatewayBaseUrl, readSpGatewayState, SP_GATEWAY_PROVIDER_ID, writeSpGatewayLogin, writeSpGatewayState, } from "./gateway.js";
|
|
4
2
|
export async function runSlashLogin(pi, args, context) {
|
|
5
3
|
const existingState = readSpGatewayState();
|
|
6
4
|
const argumentUrl = args.trim();
|
|
7
5
|
const enteredUrl = argumentUrl
|
|
8
6
|
? argumentUrl
|
|
9
|
-
: await context.ui.input("
|
|
7
|
+
: await context.ui.input("Senpiper Gateway URL", existingState?.baseUrl ?? "https://gateway.example.com/v1");
|
|
10
8
|
if (enteredUrl === undefined) {
|
|
11
|
-
context.ui.notify("
|
|
9
|
+
context.ui.notify("Senpiper Gateway login cancelled.", "warning");
|
|
12
10
|
return false;
|
|
13
11
|
}
|
|
14
12
|
const gatewayUrl = enteredUrl.trim() || existingState?.baseUrl;
|
|
15
13
|
if (!gatewayUrl) {
|
|
16
|
-
context.ui.notify("A
|
|
14
|
+
context.ui.notify("A Senpiper Gateway URL is required.", "error");
|
|
17
15
|
return false;
|
|
18
16
|
}
|
|
19
|
-
const apiKey = await context.ui.input("
|
|
17
|
+
const apiKey = await context.ui.input("Senpiper Gateway API key", "Paste your API key", { secret: true });
|
|
20
18
|
if (!apiKey?.trim()) {
|
|
21
|
-
context.ui.notify(apiKey === undefined ? "
|
|
19
|
+
context.ui.notify(apiKey === undefined ? "Senpiper Gateway login cancelled." : "An API key is required.", "warning");
|
|
22
20
|
return false;
|
|
23
21
|
}
|
|
24
|
-
context.ui.setProgress("Connecting to
|
|
22
|
+
context.ui.setProgress("Connecting to Senpiper Gateway and synchronizing models…");
|
|
25
23
|
try {
|
|
26
24
|
const baseUrl = normalizeSpGatewayBaseUrl(gatewayUrl);
|
|
27
25
|
const models = await fetchSpGatewayModels(baseUrl, apiKey.trim());
|
|
@@ -37,25 +35,17 @@ export async function runSlashLogin(pi, args, context) {
|
|
|
37
35
|
api: "openai-completions",
|
|
38
36
|
});
|
|
39
37
|
context.ui.notify(selected
|
|
40
|
-
? `Connected to
|
|
41
|
-
: `Connected to
|
|
38
|
+
? `Connected to Senpiper Gateway · ${models.length} models · selected ${firstModel.id}.`
|
|
39
|
+
: `Connected to Senpiper Gateway · ${models.length} models available. Use /model to select one.`, "info");
|
|
42
40
|
}
|
|
43
41
|
finally {
|
|
44
42
|
context.ui.setProgress(undefined);
|
|
45
43
|
}
|
|
46
|
-
if (!hasCompletedOnboarding(getSpAgentDir())) {
|
|
47
|
-
try {
|
|
48
|
-
await runInteractiveOnboarding(context);
|
|
49
|
-
}
|
|
50
|
-
catch (error) {
|
|
51
|
-
context.ui.notify(`Onboarding deferred: ${error instanceof Error ? error.message : String(error)}. Run /onboarding later.`, "warning");
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
44
|
return true;
|
|
55
45
|
}
|
|
56
46
|
export function registerLoginCommand(pi) {
|
|
57
47
|
pi.registerCommand("login", {
|
|
58
|
-
description: "Log in to
|
|
48
|
+
description: "Log in to Senpiper Gateway",
|
|
59
49
|
handler: async (args, context) => {
|
|
60
50
|
try {
|
|
61
51
|
await runSlashLogin(pi, args, context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login-command.js","sourceRoot":"","sources":["../src/login-command.ts"],"names":[],"mappings":"AACA,OAAO,EACN,6BAA6B,EAC7B,oBAAoB,EACpB,
|
|
1
|
+
{"version":3,"file":"login-command.js","sourceRoot":"","sources":["../src/login-command.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionCommandContext } from \"@senpiper/pi-coding-agent\";\nimport {\n\tcreateSpGatewayProviderConfig,\n\tfetchSpGatewayModels,\n\tnormalizeSpGatewayBaseUrl,\n\treadSpGatewayState,\n\tSP_GATEWAY_PROVIDER_ID,\n\twriteSpGatewayLogin,\n\twriteSpGatewayState,\n} from \"./gateway.ts\";\n\nexport async function runSlashLogin(pi: ExtensionAPI, args: string, context: ExtensionCommandContext) {\n\tconst existingState = readSpGatewayState();\n\tconst argumentUrl = args.trim();\n\tconst enteredUrl = argumentUrl\n\t\t? argumentUrl\n\t\t: await context.ui.input(\"Senpiper Gateway URL\", existingState?.baseUrl ?? \"https://gateway.example.com/v1\");\n\tif (enteredUrl === undefined) {\n\t\tcontext.ui.notify(\"Senpiper Gateway login cancelled.\", \"warning\");\n\t\treturn false;\n\t}\n\tconst gatewayUrl = enteredUrl.trim() || existingState?.baseUrl;\n\tif (!gatewayUrl) {\n\t\tcontext.ui.notify(\"A Senpiper Gateway URL is required.\", \"error\");\n\t\treturn false;\n\t}\n\tconst apiKey = await context.ui.input(\"Senpiper Gateway API key\", \"Paste your API key\", { secret: true });\n\tif (!apiKey?.trim()) {\n\t\tcontext.ui.notify(\n\t\t\tapiKey === undefined ? \"Senpiper Gateway login cancelled.\" : \"An API key is required.\",\n\t\t\t\"warning\",\n\t\t);\n\t\treturn false;\n\t}\n\n\tcontext.ui.setProgress(\"Connecting to Senpiper Gateway and synchronizing models…\");\n\ttry {\n\t\tconst baseUrl = normalizeSpGatewayBaseUrl(gatewayUrl);\n\t\tconst models = await fetchSpGatewayModels(baseUrl, apiKey.trim());\n\t\twriteSpGatewayState(baseUrl, models);\n\t\twriteSpGatewayLogin(apiKey.trim(), models[0]!.id);\n\t\tpi.registerProvider(SP_GATEWAY_PROVIDER_ID, createSpGatewayProviderConfig(baseUrl, models));\n\t\tawait context.modelRegistry.setRuntimeApiKey(SP_GATEWAY_PROVIDER_ID, apiKey.trim());\n\t\tconst firstModel = models[0]!;\n\t\tconst selected = await pi.setModel({\n\t\t\t...firstModel,\n\t\t\tprovider: SP_GATEWAY_PROVIDER_ID,\n\t\t\tbaseUrl,\n\t\t\tapi: \"openai-completions\",\n\t\t});\n\t\tcontext.ui.notify(\n\t\t\tselected\n\t\t\t\t? `Connected to Senpiper Gateway · ${models.length} models · selected ${firstModel.id}.`\n\t\t\t\t: `Connected to Senpiper Gateway · ${models.length} models available. Use /model to select one.`,\n\t\t\t\"info\",\n\t\t);\n\t} finally {\n\t\tcontext.ui.setProgress(undefined);\n\t}\n\n\treturn true;\n}\n\nexport function registerLoginCommand(pi: ExtensionAPI) {\n\tpi.registerCommand(\"login\", {\n\t\tdescription: \"Log in to Senpiper Gateway\",\n\t\thandler: async (args, context) => {\n\t\t\ttry {\n\t\t\t\tawait runSlashLogin(pi, args, context);\n\t\t\t} catch (error) {\n\t\t\t\tcontext.ui.setProgress(undefined);\n\t\t\t\tcontext.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n"]}
|
|
@@ -5,16 +5,42 @@ export interface SpWebSidecarState {
|
|
|
5
5
|
executable: string;
|
|
6
6
|
args: string[];
|
|
7
7
|
startedAt: string;
|
|
8
|
+
/** Random identity inherited only by this launched process tree. */
|
|
9
|
+
launchToken?: string;
|
|
8
10
|
}
|
|
9
11
|
export interface SpWebLaunchResult {
|
|
10
12
|
status: "disabled" | "reused" | "launched" | "pending" | "failed";
|
|
11
13
|
pid?: number;
|
|
12
14
|
error?: string;
|
|
13
15
|
}
|
|
16
|
+
export interface SpWebStopResult {
|
|
17
|
+
status: "stopped" | "not-running" | "pending" | "failed";
|
|
18
|
+
pid?: number;
|
|
19
|
+
error?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface SpWebProcessIdentity {
|
|
22
|
+
launchToken?: string;
|
|
23
|
+
/** Full argv of the live process, when the platform exposes argument boundaries. */
|
|
24
|
+
argv?: string[];
|
|
25
|
+
/** Joined command line, used when argv boundaries are unavailable. */
|
|
26
|
+
command?: string;
|
|
27
|
+
/** Live process environment, when readable. */
|
|
28
|
+
env?: NodeJS.ProcessEnv;
|
|
29
|
+
/** Wall-clock start time of the live process, when readable. */
|
|
30
|
+
startedAtMs?: number;
|
|
31
|
+
}
|
|
14
32
|
export interface SpWebLauncherOptions {
|
|
15
33
|
env?: NodeJS.ProcessEnv;
|
|
16
34
|
spawnProcess?: (executable: string, args: readonly string[], options: SpawnOptions) => ChildProcess;
|
|
17
35
|
isProcessRunning?: (pid: number) => boolean;
|
|
36
|
+
/** Verifies that a live PID is still the process recorded at launch. */
|
|
37
|
+
readProcessIdentity?: (pid: number) => SpWebProcessIdentity | undefined;
|
|
38
|
+
/** Sends the graceful stop signal. Defaults to process.kill. */
|
|
39
|
+
signalProcess?: (pid: number, signal: NodeJS.Signals) => void;
|
|
40
|
+
/** Waits for a signaled PID to exit. Defaults to polling isProcessRunning. */
|
|
41
|
+
waitForProcessExit?: (pid: number, timeoutMs: number) => Promise<boolean>;
|
|
42
|
+
/** Grace period for /web off before reporting a timeout. Defaults to 8000 ms. */
|
|
43
|
+
stopTimeoutMs?: number;
|
|
18
44
|
}
|
|
19
45
|
export declare function resolveSpWebLaunch(env: NodeJS.ProcessEnv, runtime?: {
|
|
20
46
|
moduleUrl: string;
|
|
@@ -25,5 +51,6 @@ export declare function resolveSpWebLaunch(env: NodeJS.ProcessEnv, runtime?: {
|
|
|
25
51
|
args: string[];
|
|
26
52
|
};
|
|
27
53
|
export declare function ensureSpWebSidecar(discoveryDir: string, options?: SpWebLauncherOptions): SpWebLaunchResult;
|
|
54
|
+
export declare function stopSpWebSidecar(discoveryDir: string, options?: SpWebLauncherOptions): Promise<SpWebStopResult>;
|
|
28
55
|
export declare function getSpWebSidecarStatePath(discoveryDir: string): string;
|
|
29
56
|
//# sourceMappingURL=sp-web-launcher.d.ts.map
|