Skip to content

Commit d439ab1

Browse files
committed
fix: address provider release readiness feedback
1 parent aee7d81 commit d439ab1

6 files changed

Lines changed: 63 additions & 14 deletions

File tree

apps/server/src/provider/Layers/HermesProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export function parseHermesConfigModelDefaults(raw: string): HermesConfigModelDe
7676
let sawModelBlock = false;
7777

7878
for (const line of lines) {
79-
const withoutComment = line.replace(/\s+#.*$/, "");
79+
const withoutComment = line.replace(/\s*#.*$/, "");
8080
if (withoutComment.trim().length === 0) continue;
8181

8282
const indent = withoutComment.length - withoutComment.trimStart().length;

apps/server/src/provider/Layers/PiProvider.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const PROVIDER = ProviderDriverKind.make("pi");
3636
const PI_PRESENTATION = {
3737
displayName: "Pi",
3838
badgeLabel: "Early Access",
39-
showInteractionModeToggle: true,
39+
showInteractionModeToggle: false,
4040
} as const;
4141
const EMPTY_CAPABILITIES = createModelCapabilities({ optionDescriptors: [] });
4242
const PI_FALLBACK_MODEL: ServerProviderModel = {
@@ -176,8 +176,9 @@ function readPiConfigModelDefaults(
176176
return Effect.gen(function* () {
177177
const fs = yield* FileSystem.FileSystem;
178178
const path = yield* Path.Path;
179-
const home = environment.PI_CODING_AGENT_DIR?.trim()
180-
? environment.PI_CODING_AGENT_DIR
179+
const configuredHome = environment.PI_CODING_AGENT_DIR?.trim();
180+
const home = configuredHome
181+
? configuredHome
181182
: path.join(environment.HOME || NodeOS.homedir(), ".pi", "agent");
182183
const raw = yield* fs
183184
.readFileString(path.join(home, "settings.json"))
@@ -231,8 +232,9 @@ function readPiAuthState(
231232
): Effect.Effect<PiAuthState, never, FileSystem.FileSystem | Path.Path> {
232233
return Effect.gen(function* () {
233234
const path = yield* Path.Path;
234-
const home = environment.PI_CODING_AGENT_DIR?.trim()
235-
? environment.PI_CODING_AGENT_DIR
235+
const configuredHome = environment.PI_CODING_AGENT_DIR?.trim();
236+
const home = configuredHome
237+
? configuredHome
236238
: path.join(environment.HOME || NodeOS.homedir(), ".pi", "agent");
237239
const settings = yield* readOptionalFile(path.join(home, "settings.json"));
238240
const defaultProvider = settings

apps/server/src/provider/acp/PiAcpSupport.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,32 @@ describe("buildPiAcpSpawnInput", () => {
7474
},
7575
});
7676
});
77+
78+
it("preserves Windows root executable directories", () => {
79+
expect(
80+
buildPiAcpSpawnInput(
81+
{
82+
binaryPath: "C:\\pi-acp.cmd",
83+
piBinaryPath: "C:\\pi.cmd",
84+
},
85+
"C:\\work\\project",
86+
{},
87+
).env?.PATH,
88+
).toBe("C:\\");
89+
});
90+
91+
it("does not add an empty PATH for relative commands without an existing path", () => {
92+
expect(
93+
buildPiAcpSpawnInput(
94+
{
95+
binaryPath: "pi-acp",
96+
piBinaryPath: "pi",
97+
},
98+
"/tmp/project",
99+
{},
100+
).env,
101+
).toEqual({
102+
PI_ACP_PI_COMMAND: "pi",
103+
});
104+
});
77105
});

apps/server/src/provider/acp/PiAcpSupport.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,14 @@ function dirnameForExecutablePath(value: string | undefined): string | null {
3434
return null;
3535
}
3636
const normalized = value.replaceAll("\\", "/");
37-
if (!normalized.startsWith("/") && !WINDOWS_ABSOLUTE_PATH_PATTERN.test(normalized)) {
37+
const isWindowsAbsolute = WINDOWS_ABSOLUTE_PATH_PATTERN.test(normalized);
38+
if (!normalized.startsWith("/") && !isWindowsAbsolute) {
3839
return null;
3940
}
4041
const separatorIndex = normalized.lastIndexOf("/");
42+
if (isWindowsAbsolute && separatorIndex === 2) {
43+
return value.slice(0, 3);
44+
}
4145
return separatorIndex > 0 ? value.slice(0, separatorIndex) : "/";
4246
}
4347

@@ -72,14 +76,17 @@ function buildPiAcpEnvironment(
7276
if (piSettings?.piBinaryPath) {
7377
env.PI_ACP_PI_COMMAND = piSettings.piBinaryPath;
7478
}
75-
env[pathKey] = prependUniquePathEntries(
79+
const nextPath = prependUniquePathEntries(
7680
env[pathKey],
7781
[
7882
dirnameForExecutablePath(piSettings?.binaryPath),
7983
dirnameForExecutablePath(piSettings?.piBinaryPath),
8084
],
8185
pathDelimiter,
8286
);
87+
if (nextPath) {
88+
env[pathKey] = nextPath;
89+
}
8390
return env;
8491
}
8592

apps/web/src/components/settings/SettingsPanels.browser.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,9 +1261,15 @@ describe("GeneralSettingsPanel observability", () => {
12611261
});
12621262

12631263
it("offers provider updates in expanded settings even without an outdated advisory", async () => {
1264-
const updateProvider = vi.fn<LocalApi["server"]["updateProvider"]>().mockResolvedValue({
1265-
providers: [createCurrentUpdatableProvider("pi", "pi update")],
1266-
});
1264+
let resolveUpdateProvider:
1265+
| ((value: Awaited<ReturnType<LocalApi["server"]["updateProvider"]>>) => void)
1266+
| undefined;
1267+
const updateProvider = vi.fn<LocalApi["server"]["updateProvider"]>().mockImplementation(
1268+
() =>
1269+
new Promise((resolve) => {
1270+
resolveUpdateProvider = resolve;
1271+
}),
1272+
);
12671273
window.nativeApi = {
12681274
persistence: {
12691275
getClientSettings: vi.fn().mockResolvedValue(null),
@@ -1289,11 +1295,15 @@ describe("GeneralSettingsPanel observability", () => {
12891295
await expect.element(page.getByText("Provider update")).toBeInTheDocument();
12901296
await expect.element(page.getByText("pi update")).toBeInTheDocument();
12911297
await page.getByRole("button", { name: "Update provider" }).click();
1298+
await expect.element(page.getByRole("button", { name: "Updating" })).toBeDisabled();
12921299

12931300
expect(updateProvider).toHaveBeenCalledWith({
12941301
provider: ProviderDriverKind.make("pi"),
12951302
instanceId: ProviderInstanceId.make("pi"),
12961303
});
1304+
resolveUpdateProvider?.({
1305+
providers: [createCurrentUpdatableProvider("pi", "pi update")],
1306+
});
12971307
});
12981308

12991309
it("keeps long provider update commands inside the fixed-width popover", async () => {

apps/web/src/components/settings/SettingsPanels.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,11 +1233,13 @@ export function ProviderSettingsPanel() {
12331233
? providerUpdateCandidateByInstanceId.get(liveProvider.instanceId)
12341234
: undefined;
12351235
const isDriverUpdateRunning =
1236-
updateCandidate !== undefined &&
1237-
(updatingProviderDrivers.has(updateCandidate.driver) ||
1236+
liveProvider !== undefined &&
1237+
(updatingProviderDrivers.has(liveProvider.driver) ||
1238+
(updateCandidate !== undefined &&
1239+
updatingProviderDrivers.has(updateCandidate.driver)) ||
12381240
serverProviders.some(
12391241
(provider) =>
1240-
provider.driver === updateCandidate.driver && isProviderUpdateActive(provider),
1242+
provider.driver === liveProvider.driver && isProviderUpdateActive(provider),
12411243
));
12421244
const showInlineUpdateButton =
12431245
liveProvider !== undefined &&

0 commit comments

Comments
 (0)