@aliou/pi-ts-aperture 0.0.1 → 0.2.0
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/.github/workflows/publish.yml +4 -8
- package/CHANGELOG.md +28 -0
- package/README.md +1 -1
- package/package.json +19 -18
- package/src/commands/settings.ts +7 -4
- package/src/commands/setup.ts +134 -13
- package/src/index.ts +56 -18
- package/src/lib/health.ts +30 -0
- package/.envrc +0 -21
- package/.osgrep/cache/meta.lmdb +0 -0
- package/.osgrep/cache/meta.lmdb-lock +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/b9016ebf-b6e6-4c43-be9f-7413728f6389/metadata.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/b9016ebf-b6e6-4c43-be9f-7413728f6389/part_11_docs.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/b9016ebf-b6e6-4c43-be9f-7413728f6389/part_11_invert.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/b9016ebf-b6e6-4c43-be9f-7413728f6389/part_11_tokens.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/cc7bd185-bc88-4dbd-af7f-6aac2f6b29d3/metadata.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/cc7bd185-bc88-4dbd-af7f-6aac2f6b29d3/part_0_docs.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/cc7bd185-bc88-4dbd-af7f-6aac2f6b29d3/part_0_invert.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/cc7bd185-bc88-4dbd-af7f-6aac2f6b29d3/part_0_tokens.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/cd01c8d9-fae8-4482-b01f-59f06abe1b48/metadata.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/cd01c8d9-fae8-4482-b01f-59f06abe1b48/part_0_docs.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/cd01c8d9-fae8-4482-b01f-59f06abe1b48/part_0_invert.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/cd01c8d9-fae8-4482-b01f-59f06abe1b48/part_0_tokens.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/dedba042-4a7b-44d7-ac2f-258233b62681/metadata.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/dedba042-4a7b-44d7-ac2f-258233b62681/part_0_docs.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/dedba042-4a7b-44d7-ac2f-258233b62681/part_0_invert.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_indices/dedba042-4a7b-44d7-ac2f-258233b62681/part_0_tokens.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/_transactions/0-fd59fbcc-e229-4069-b8b0-764b34f2d645.txn +0 -0
- package/.osgrep/lancedb/chunks.lance/_transactions/1-f130f13d-123c-4e71-b806-b6b4f6cdd6d8.txn +0 -0
- package/.osgrep/lancedb/chunks.lance/_transactions/2-5f641c2a-07a9-45a1-b450-72c7d4d38754.txn +0 -1
- package/.osgrep/lancedb/chunks.lance/_transactions/3-83167775-6ec4-4cb6-9388-6549f583087a.txn +0 -0
- package/.osgrep/lancedb/chunks.lance/_transactions/4-feb1627d-f860-4c02-b8a6-6b93cf42ec22.txn +0 -0
- package/.osgrep/lancedb/chunks.lance/_transactions/5-e00ef82b-90b4-4c91-a7ec-d7b4903e1c61.txn +0 -0
- package/.osgrep/lancedb/chunks.lance/_transactions/6-ccc1d487-f511-4e48-afa0-2edf42f8effd.txn +0 -0
- package/.osgrep/lancedb/chunks.lance/_transactions/7-b26d7d18-4411-44cd-b559-54bfa2999b70.txn +0 -0
- package/.osgrep/lancedb/chunks.lance/_versions/1.manifest +0 -0
- package/.osgrep/lancedb/chunks.lance/_versions/2.manifest +0 -0
- package/.osgrep/lancedb/chunks.lance/_versions/3.manifest +0 -0
- package/.osgrep/lancedb/chunks.lance/_versions/4.manifest +0 -0
- package/.osgrep/lancedb/chunks.lance/_versions/5.manifest +0 -0
- package/.osgrep/lancedb/chunks.lance/_versions/6.manifest +0 -0
- package/.osgrep/lancedb/chunks.lance/_versions/7.manifest +0 -0
- package/.osgrep/lancedb/chunks.lance/_versions/8.manifest +0 -0
- package/.osgrep/lancedb/chunks.lance/data/0110110100011111000100108ca476475fac277950ba4295de.lance +0 -0
- package/.osgrep/lancedb/chunks.lance/data/111110011111110001101001d059cb4ceab8147482b4391458.lance +0 -0
|
@@ -57,14 +57,10 @@ jobs:
|
|
|
57
57
|
|
|
58
58
|
let title = 'Version Packages';
|
|
59
59
|
let commit = 'Version Packages';
|
|
60
|
-
if (releases.length
|
|
61
|
-
const
|
|
62
|
-
title =
|
|
63
|
-
commit =
|
|
64
|
-
} else if (releases.length > 1) {
|
|
65
|
-
const summary = releases.map(r => r.name + '@' + r.newVersion).join(', ');
|
|
66
|
-
title = 'Updating ' + summary;
|
|
67
|
-
commit = summary;
|
|
60
|
+
if (releases.length >= 1) {
|
|
61
|
+
const version = releases[0].newVersion;
|
|
62
|
+
title = version;
|
|
63
|
+
commit = version;
|
|
68
64
|
}
|
|
69
65
|
|
|
70
66
|
fs.appendFileSync(process.env.GITHUB_OUTPUT, 'title=' + title + '\n');
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# @aliou/pi-ts-aperture
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 926f0a9: Improve `/aperture:setup` provider and connectivity flow.
|
|
8
|
+
|
|
9
|
+
- Add URL health check during setup (`/v1/models`) before provider selection, with retry/cancel UX.
|
|
10
|
+
- Build provider choices from Pi's runtime model registry so extension-registered providers (for example `pi-synthetic`) appear in the setup list.
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 2263fc2: mark pi SDK peer deps as optional to prevent koffi OOM in Gondolin VMs
|
|
15
|
+
|
|
16
|
+
## 0.1.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- ebb9556: Initial release. Route Pi LLM providers through Tailscale Aperture.
|
|
21
|
+
|
|
22
|
+
- `/aperture:setup` interactive wizard (base URL + provider multi-select)
|
|
23
|
+
- `/aperture:settings` settings UI for updating configuration
|
|
24
|
+
- Auto-registers selected providers with Aperture base URL on load
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- 7388139: Fix providers not taking effect immediately after setup/settings save. Register directly on modelRegistry and re-resolve the active model when it belongs to a reconfigured provider.
|
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aliou/pi-ts-aperture",
|
|
3
3
|
"description": "Route Pi LLM providers through Tailscale Aperture",
|
|
4
|
-
"version": "0.0
|
|
5
|
-
"packageManager": "pnpm@10.26.1",
|
|
4
|
+
"version": "0.2.0",
|
|
6
5
|
"repository": {
|
|
7
6
|
"type": "git",
|
|
8
7
|
"url": "https://github.com/aliou/pi-ts-aperture"
|
|
@@ -11,7 +10,8 @@
|
|
|
11
10
|
"pi-package"
|
|
12
11
|
],
|
|
13
12
|
"publishConfig": {
|
|
14
|
-
"access": "public"
|
|
13
|
+
"access": "public",
|
|
14
|
+
"provenance": true
|
|
15
15
|
},
|
|
16
16
|
"pi": {
|
|
17
17
|
"extensions": [
|
|
@@ -20,21 +20,12 @@
|
|
|
20
20
|
"video": "https://assets.aliou.me/pi-extensions/demos/pi-ts-aperture.mp4"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@aliou/pi-utils-settings": "^0.
|
|
23
|
+
"@aliou/pi-utils-settings": "^0.4.0"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"@mariozechner/pi-ai": ">=0.52.12",
|
|
27
27
|
"@mariozechner/pi-coding-agent": ">=0.52.12"
|
|
28
28
|
},
|
|
29
|
-
"scripts": {
|
|
30
|
-
"typecheck": "tsc --noEmit",
|
|
31
|
-
"lint": "biome check",
|
|
32
|
-
"format": "biome check --write",
|
|
33
|
-
"prepare": "husky",
|
|
34
|
-
"changeset": "changeset",
|
|
35
|
-
"version": "changeset version",
|
|
36
|
-
"release": "pnpm changeset publish"
|
|
37
|
-
},
|
|
38
29
|
"devDependencies": {
|
|
39
30
|
"@biomejs/biome": "^2.3.13",
|
|
40
31
|
"@changesets/cli": "^2.27.11",
|
|
@@ -45,10 +36,20 @@
|
|
|
45
36
|
"husky": "^9.1.7",
|
|
46
37
|
"typescript": "^5.9.3"
|
|
47
38
|
},
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
39
|
+
"peerDependenciesMeta": {
|
|
40
|
+
"@mariozechner/pi-coding-agent": {
|
|
41
|
+
"optional": true
|
|
42
|
+
},
|
|
43
|
+
"@mariozechner/pi-ai": {
|
|
44
|
+
"optional": true
|
|
52
45
|
}
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"lint": "biome check",
|
|
50
|
+
"format": "biome check --write",
|
|
51
|
+
"changeset": "changeset",
|
|
52
|
+
"version": "changeset version",
|
|
53
|
+
"release": "pnpm changeset publish"
|
|
53
54
|
}
|
|
54
|
-
}
|
|
55
|
+
}
|
package/src/commands/settings.ts
CHANGED
|
@@ -12,14 +12,17 @@ import {
|
|
|
12
12
|
type SettingsSection,
|
|
13
13
|
setNestedValue,
|
|
14
14
|
} from "@aliou/pi-utils-settings";
|
|
15
|
-
import type {
|
|
15
|
+
import type {
|
|
16
|
+
ExtensionAPI,
|
|
17
|
+
ExtensionContext,
|
|
18
|
+
} from "@mariozechner/pi-coding-agent";
|
|
16
19
|
import { getSettingsListTheme } from "@mariozechner/pi-coding-agent";
|
|
17
20
|
import type { ApertureConfig, ResolvedConfig } from "../config";
|
|
18
21
|
import { configLoader } from "../config";
|
|
19
22
|
|
|
20
23
|
export function registerApertureSettings(
|
|
21
24
|
pi: ExtensionAPI,
|
|
22
|
-
onConfigChange: () => void,
|
|
25
|
+
onConfigChange: (ctx: ExtensionContext) => void,
|
|
23
26
|
): void {
|
|
24
27
|
registerSettingsCommand<ApertureConfig, ResolvedConfig>(pi, {
|
|
25
28
|
commandName: "aperture:settings",
|
|
@@ -89,8 +92,8 @@ export function registerApertureSettings(
|
|
|
89
92
|
}
|
|
90
93
|
return updated;
|
|
91
94
|
},
|
|
92
|
-
onSave: () => {
|
|
93
|
-
onConfigChange();
|
|
95
|
+
onSave: (ctx) => {
|
|
96
|
+
onConfigChange(ctx);
|
|
94
97
|
},
|
|
95
98
|
});
|
|
96
99
|
}
|
package/src/commands/setup.ts
CHANGED
|
@@ -8,12 +8,15 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { FuzzySelector } from "@aliou/pi-utils-settings";
|
|
11
|
-
import {
|
|
12
|
-
|
|
11
|
+
import type {
|
|
12
|
+
ExtensionAPI,
|
|
13
|
+
ExtensionContext,
|
|
14
|
+
} from "@mariozechner/pi-coding-agent";
|
|
13
15
|
import { getSettingsListTheme } from "@mariozechner/pi-coding-agent";
|
|
14
|
-
import type { Component } from "@mariozechner/pi-tui";
|
|
16
|
+
import type { Component, TUI } from "@mariozechner/pi-tui";
|
|
15
17
|
import { Input, Key, matchesKey } from "@mariozechner/pi-tui";
|
|
16
18
|
import { configLoader } from "../config";
|
|
19
|
+
import { checkApertureHealth } from "../lib/health";
|
|
17
20
|
|
|
18
21
|
function normalizeUrl(url: string): string {
|
|
19
22
|
let result = url.trim();
|
|
@@ -24,6 +27,102 @@ function normalizeUrl(url: string): string {
|
|
|
24
27
|
return result.replace(/\/v1\/?$/, "").replace(/\/+$/, "");
|
|
25
28
|
}
|
|
26
29
|
|
|
30
|
+
const SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Shows a spinner while verifying the Aperture URL is reachable.
|
|
34
|
+
* Kicks off the health check on construction and resolves done(boolean)
|
|
35
|
+
* when the check completes.
|
|
36
|
+
*/
|
|
37
|
+
class HealthCheckSpinner implements Component {
|
|
38
|
+
private theme: ReturnType<typeof getSettingsListTheme>;
|
|
39
|
+
private url: string;
|
|
40
|
+
private tui: TUI;
|
|
41
|
+
// true = healthy, false = failed (retry), undefined = cancelled
|
|
42
|
+
private done: (result: boolean | undefined) => void;
|
|
43
|
+
private frame = 0;
|
|
44
|
+
private timer: ReturnType<typeof setInterval>;
|
|
45
|
+
private result: { ok: boolean; error?: string } | null = null;
|
|
46
|
+
|
|
47
|
+
constructor(
|
|
48
|
+
theme: ReturnType<typeof getSettingsListTheme>,
|
|
49
|
+
url: string,
|
|
50
|
+
tui: TUI,
|
|
51
|
+
done: (result: boolean | undefined) => void,
|
|
52
|
+
) {
|
|
53
|
+
this.theme = theme;
|
|
54
|
+
this.url = url;
|
|
55
|
+
this.tui = tui;
|
|
56
|
+
this.done = done;
|
|
57
|
+
|
|
58
|
+
// Animate spinner at ~80ms per frame.
|
|
59
|
+
this.timer = setInterval(() => {
|
|
60
|
+
this.frame = (this.frame + 1) % SPINNER_FRAMES.length;
|
|
61
|
+
this.tui.requestRender();
|
|
62
|
+
}, 80);
|
|
63
|
+
|
|
64
|
+
// Fire the check.
|
|
65
|
+
checkApertureHealth(url).then((res) => {
|
|
66
|
+
clearInterval(this.timer);
|
|
67
|
+
this.result = res;
|
|
68
|
+
this.tui.requestRender();
|
|
69
|
+
|
|
70
|
+
// On success, auto-advance after a brief pause.
|
|
71
|
+
// On failure, wait for user input (see handleInput).
|
|
72
|
+
if (res.ok) {
|
|
73
|
+
setTimeout(() => this.done(true), 600);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
render(_width: number): string[] {
|
|
79
|
+
const lines: string[] = [];
|
|
80
|
+
lines.push(this.theme.label(" Aperture Setup", true));
|
|
81
|
+
lines.push("");
|
|
82
|
+
|
|
83
|
+
if (!this.result) {
|
|
84
|
+
const spinner = SPINNER_FRAMES[this.frame];
|
|
85
|
+
lines.push(
|
|
86
|
+
this.theme.hint(` ${spinner} Checking connection to ${this.url}...`),
|
|
87
|
+
);
|
|
88
|
+
} else if (this.result.ok) {
|
|
89
|
+
lines.push(this.theme.hint(` Connected to ${this.url}`));
|
|
90
|
+
} else {
|
|
91
|
+
lines.push(
|
|
92
|
+
this.theme.hint(` Could not reach ${this.url}: ${this.result.error}`),
|
|
93
|
+
);
|
|
94
|
+
lines.push("");
|
|
95
|
+
lines.push(
|
|
96
|
+
this.theme.hint(
|
|
97
|
+
" Make sure the URL is correct and you are connected to the tailnet.",
|
|
98
|
+
),
|
|
99
|
+
);
|
|
100
|
+
lines.push("");
|
|
101
|
+
lines.push(this.theme.hint(" Enter: try another URL · Esc: cancel"));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
lines.push("");
|
|
105
|
+
return lines;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
invalidate() {}
|
|
109
|
+
|
|
110
|
+
handleInput(data: string) {
|
|
111
|
+
// Only handle input after a failed check.
|
|
112
|
+
if (!this.result || this.result.ok) return;
|
|
113
|
+
|
|
114
|
+
if (matchesKey(data, Key.enter)) {
|
|
115
|
+
this.done(false); // retry
|
|
116
|
+
} else if (matchesKey(data, Key.escape)) {
|
|
117
|
+
this.done(undefined); // cancel wizard
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
dispose() {
|
|
122
|
+
clearInterval(this.timer);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
27
126
|
/**
|
|
28
127
|
* Simple input prompt component for the base URL step.
|
|
29
128
|
*/
|
|
@@ -152,7 +251,7 @@ class ProviderMultiSelect implements Component {
|
|
|
152
251
|
|
|
153
252
|
export function registerSetupCommand(
|
|
154
253
|
pi: ExtensionAPI,
|
|
155
|
-
onConfigChange: () => void,
|
|
254
|
+
onConfigChange: (ctx: ExtensionContext) => void,
|
|
156
255
|
): void {
|
|
157
256
|
pi.registerCommand("aperture:setup", {
|
|
158
257
|
description: "Configure Tailscale Aperture integration",
|
|
@@ -168,17 +267,39 @@ export function registerSetupCommand(
|
|
|
168
267
|
const config = configLoader.getConfig();
|
|
169
268
|
const settingsTheme = getSettingsListTheme();
|
|
170
269
|
|
|
171
|
-
// Step 1: base URL
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
270
|
+
// Step 1: base URL + health check loop.
|
|
271
|
+
// On failure, loop back to the URL prompt so the user can retry.
|
|
272
|
+
let baseUrl: string | undefined;
|
|
273
|
+
while (true) {
|
|
274
|
+
baseUrl = await ctx.ui.custom<string | undefined>(
|
|
275
|
+
(_tui, _theme, _kb, done) => {
|
|
276
|
+
return new UrlPrompt(
|
|
277
|
+
settingsTheme,
|
|
278
|
+
baseUrl ?? config.baseUrl,
|
|
279
|
+
done,
|
|
280
|
+
);
|
|
281
|
+
},
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
if (!baseUrl) return;
|
|
285
|
+
const urlToCheck = baseUrl;
|
|
286
|
+
|
|
287
|
+
const result = await ctx.ui.custom<boolean | undefined>(
|
|
288
|
+
(tui, _theme, _kb, done) => {
|
|
289
|
+
return new HealthCheckSpinner(settingsTheme, urlToCheck, tui, done);
|
|
290
|
+
},
|
|
291
|
+
);
|
|
177
292
|
|
|
178
|
-
|
|
293
|
+
if (result === true) break; // healthy, proceed
|
|
294
|
+
if (result === undefined) return; // cancelled
|
|
295
|
+
}
|
|
179
296
|
|
|
180
297
|
// Step 2: select providers
|
|
181
|
-
|
|
298
|
+
// Use model registry so custom/extension providers are included.
|
|
299
|
+
const knownProviders = Array.from(
|
|
300
|
+
new Set(ctx.modelRegistry.getAll().map((model) => model.provider)),
|
|
301
|
+
).sort((a, b) => a.localeCompare(b));
|
|
302
|
+
|
|
182
303
|
const providers = await ctx.ui.custom<string[] | undefined>(
|
|
183
304
|
(_tui, _theme, _kb, done) => {
|
|
184
305
|
return new ProviderMultiSelect(
|
|
@@ -194,7 +315,7 @@ export function registerSetupCommand(
|
|
|
194
315
|
|
|
195
316
|
// Step 3: save and register
|
|
196
317
|
await configLoader.save("global", { baseUrl, providers });
|
|
197
|
-
onConfigChange();
|
|
318
|
+
onConfigChange(ctx);
|
|
198
319
|
ctx.ui.notify(
|
|
199
320
|
`Aperture configured: ${providers.length} provider(s) via ${baseUrl}`,
|
|
200
321
|
"info",
|
package/src/index.ts
CHANGED
|
@@ -6,34 +6,72 @@
|
|
|
6
6
|
* overrides each provider's baseUrl and sets a dummy apiKey.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
ExtensionAPI,
|
|
11
|
+
ExtensionContext,
|
|
12
|
+
} from "@mariozechner/pi-coding-agent";
|
|
10
13
|
import { registerApertureSettings } from "./commands/settings";
|
|
11
14
|
import { registerSetupCommand } from "./commands/setup";
|
|
12
15
|
import { configLoader } from "./config";
|
|
13
16
|
|
|
14
|
-
function
|
|
17
|
+
function getApertureBaseUrl(): string | null {
|
|
15
18
|
const config = configLoader.getConfig();
|
|
16
|
-
if (!config.baseUrl || config.providers.length === 0) return;
|
|
17
|
-
|
|
18
|
-
const baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
19
|
-
|
|
20
|
-
for (const provider of config.providers) {
|
|
21
|
-
pi.registerProvider(provider, {
|
|
22
|
-
baseUrl: `${baseUrl}/v1`,
|
|
23
|
-
apiKey: "-",
|
|
24
|
-
});
|
|
25
|
-
}
|
|
19
|
+
if (!config.baseUrl || config.providers.length === 0) return null;
|
|
20
|
+
return `${config.baseUrl.replace(/\/+$/, "")}/v1`;
|
|
26
21
|
}
|
|
27
22
|
|
|
28
23
|
export default async function (pi: ExtensionAPI): Promise<void> {
|
|
29
24
|
await configLoader.load();
|
|
30
25
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
const config = configLoader.getConfig();
|
|
27
|
+
let lastRegisteredProviders = [...config.providers];
|
|
28
|
+
|
|
29
|
+
// At load time, pi.registerProvider() queue is flushed by the runner.
|
|
30
|
+
const baseUrl = getApertureBaseUrl();
|
|
31
|
+
if (baseUrl) {
|
|
32
|
+
for (const provider of config.providers) {
|
|
33
|
+
pi.registerProvider(provider, { baseUrl, apiKey: "-" });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const onSetupComplete = (ctx: ExtensionContext) => {
|
|
38
|
+
const cfg = configLoader.getConfig();
|
|
39
|
+
const removedProviders = lastRegisteredProviders.filter(
|
|
40
|
+
(p) => !cfg.providers.includes(p),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const url = getApertureBaseUrl();
|
|
44
|
+
if (url) {
|
|
45
|
+
for (const provider of cfg.providers) {
|
|
46
|
+
ctx.modelRegistry.registerProvider(provider, {
|
|
47
|
+
baseUrl: url,
|
|
48
|
+
apiKey: "-",
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
lastRegisteredProviders = [...cfg.providers];
|
|
53
|
+
|
|
54
|
+
// The active model is a snapshot. If it belongs to a provider we just
|
|
55
|
+
// reconfigured, re-resolve it so the new baseUrl takes effect.
|
|
56
|
+
if (ctx.model && cfg.providers.includes(ctx.model.provider)) {
|
|
57
|
+
const updated = ctx.modelRegistry.find(ctx.model.provider, ctx.model.id);
|
|
58
|
+
if (updated) {
|
|
59
|
+
ctx.ui.notify(
|
|
60
|
+
`[aperture] re-routing ${ctx.model.id} through ${updated.baseUrl}`,
|
|
61
|
+
"info",
|
|
62
|
+
);
|
|
63
|
+
pi.setModel(updated);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (removedProviders.length > 0) {
|
|
68
|
+
ctx.ui.notify(
|
|
69
|
+
`Removed providers (${removedProviders.join(", ")}) will revert after /reload`,
|
|
70
|
+
"warning",
|
|
71
|
+
);
|
|
72
|
+
}
|
|
34
73
|
};
|
|
35
74
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
registerApertureSettings(pi, onConfigChange);
|
|
75
|
+
registerSetupCommand(pi, onSetupComplete);
|
|
76
|
+
registerApertureSettings(pi, onSetupComplete);
|
|
39
77
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Health check for the Aperture gateway.
|
|
3
|
+
*
|
|
4
|
+
* Hits GET <baseUrl>/v1/models to verify the gateway is reachable.
|
|
5
|
+
* Uses native fetch (no extra dependencies).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface HealthCheckResult {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function checkApertureHealth(
|
|
14
|
+
baseUrl: string,
|
|
15
|
+
): Promise<HealthCheckResult> {
|
|
16
|
+
const url = `${baseUrl.replace(/\/+$/, "")}/v1/models`;
|
|
17
|
+
try {
|
|
18
|
+
const res = await fetch(url, {
|
|
19
|
+
method: "GET",
|
|
20
|
+
signal: AbortSignal.timeout(5000),
|
|
21
|
+
});
|
|
22
|
+
if (!res.ok) {
|
|
23
|
+
return { ok: false, error: `HTTP ${res.status} ${res.statusText}` };
|
|
24
|
+
}
|
|
25
|
+
return { ok: true };
|
|
26
|
+
} catch (e: unknown) {
|
|
27
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
28
|
+
return { ok: false, error: msg };
|
|
29
|
+
}
|
|
30
|
+
}
|
package/.envrc
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# shellcheck disable=2148,2086
|
|
2
|
-
|
|
3
|
-
# Use `source_up` if part of a monorepo.
|
|
4
|
-
|
|
5
|
-
use nix
|
|
6
|
-
|
|
7
|
-
# Load layouts. This basically just sets up PATH and other env vars.
|
|
8
|
-
# Possible values are "node", "bun", and "uv".
|
|
9
|
-
#
|
|
10
|
-
# Options:
|
|
11
|
-
# --deny bin1,bin2,... Exclude binaries from local PATH, falling back to system.
|
|
12
|
-
# Useful when a local binary shadows a system one you need.
|
|
13
|
-
#
|
|
14
|
-
# Examples:
|
|
15
|
-
# layout node
|
|
16
|
-
# layout node --deny pi,prettier
|
|
17
|
-
# layout uv --deny python
|
|
18
|
-
|
|
19
|
-
if has node; then
|
|
20
|
-
layout node --deny pi
|
|
21
|
-
fi
|
package/.osgrep/cache/meta.lmdb
DELETED
|
Binary file
|
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_indices/b9016ebf-b6e6-4c43-be9f-7413728f6389/metadata.lance
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_indices/cc7bd185-bc88-4dbd-af7f-6aac2f6b29d3/metadata.lance
DELETED
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_indices/cc7bd185-bc88-4dbd-af7f-6aac2f6b29d3/part_0_docs.lance
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_indices/cd01c8d9-fae8-4482-b01f-59f06abe1b48/metadata.lance
DELETED
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_indices/cd01c8d9-fae8-4482-b01f-59f06abe1b48/part_0_docs.lance
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_indices/dedba042-4a7b-44d7-ac2f-258233b62681/metadata.lance
DELETED
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_indices/dedba042-4a7b-44d7-ac2f-258233b62681/part_0_docs.lance
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_transactions/0-fd59fbcc-e229-4069-b8b0-764b34f2d645.txn
DELETED
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_transactions/1-f130f13d-123c-4e71-b806-b6b4f6cdd6d8.txn
DELETED
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_transactions/2-5f641c2a-07a9-45a1-b450-72c7d4d38754.txn
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
$5f641c2a-07a9-45a1-b450-72c7d4d38754�(&path IN ('tsconfig.json','biome.json')
|
package/.osgrep/lancedb/chunks.lance/_transactions/3-83167775-6ec4-4cb6-9388-6549f583087a.txn
DELETED
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_transactions/4-feb1627d-f860-4c02-b8a6-6b93cf42ec22.txn
DELETED
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_transactions/5-e00ef82b-90b4-4c91-a7ec-d7b4903e1c61.txn
DELETED
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_transactions/6-ccc1d487-f511-4e48-afa0-2edf42f8effd.txn
DELETED
|
Binary file
|
package/.osgrep/lancedb/chunks.lance/_transactions/7-b26d7d18-4411-44cd-b559-54bfa2999b70.txn
DELETED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|