@oh-my-pi/pi-coding-agent 17.3.1 → 17.3.2

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.
@@ -112,6 +112,8 @@ interface UpdateMethodResolutionOptions {
112
112
  miseBinDirs?: readonly string[];
113
113
  miseDataDir?: string;
114
114
  npmBinDir?: string;
115
+ /** Bun's configured global package directory, independent of its bin directory. */
116
+ bunGlobalDir?: string;
115
117
  /**
116
118
  * Whether the resolved omp path is a plain file (the standalone binary)
117
119
  * rather than a package-manager symlink. Stops a binary install from being
@@ -119,8 +121,34 @@ interface UpdateMethodResolutionOptions {
119
121
  * target directory.
120
122
  */
121
123
  ompIsRegularFile?: boolean;
124
+ /**
125
+ * Absolute path named by the bin entry's first symlink hop. This deliberately
126
+ * preserves a global package symlink instead of resolving into its checkout.
127
+ */
128
+ ompLinkTarget?: string;
122
129
  }
130
+ type UpdateTarget = {
131
+ method: "brew";
132
+ } | {
133
+ method: "mise";
134
+ } | {
135
+ method: "nix";
136
+ } | {
137
+ method: "bun";
138
+ path?: string;
139
+ } | {
140
+ method: "npm";
141
+ path?: string;
142
+ } | {
143
+ method: "binary";
144
+ path: string;
145
+ replacesSymlink: boolean;
146
+ };
123
147
  export declare function resolveUpdateMethodForTest(ompPath: string, bunBinDir: string | undefined, options?: UpdateMethodResolutionOptions): UpdateMethod;
148
+ /** Resolve an update target from the concrete PATH entry selected by the shell. */
149
+ export declare function resolveUpdateTargetFromPath(ompPath: string, bunBinDir: string | undefined, options: UpdateMethodResolutionOptions & {
150
+ allowPackageManagers: boolean;
151
+ }): UpdateTarget;
124
152
  /**
125
153
  * Get the latest release info from the npm registry, following `omp.rename`
126
154
  * pointers ({@link resolveReleaseRename}) when the package has moved to a new
@@ -145,7 +173,13 @@ interface BunInstallCachePruneResult {
145
173
  * cache stays internally consistent.
146
174
  */
147
175
  export declare function pruneBunInstallCache(cacheDir: string, packageNames?: Set<string>): Promise<BunInstallCachePruneResult>;
148
- export declare function resolveBunGlobalNodeModulesDirFromLocations(globalBinDir: string | undefined, cacheDir: string | undefined): string | undefined;
176
+ interface BunGlobalInstallLocations {
177
+ globalDir?: string;
178
+ globalBinDir?: string;
179
+ cacheDir?: string;
180
+ }
181
+ /** Resolve Bun's global node_modules root from explicit, default, or cache locations. */
182
+ export declare function resolveBunGlobalNodeModulesDirFromLocations({ globalDir, globalBinDir, cacheDir, }: BunGlobalInstallLocations): string | undefined;
149
183
  /**
150
184
  * Detect a musl-libc Linux host (Alpine, Void-musl) so self-update replaces a
151
185
  * musl binary with the musl release asset instead of the glibc build, which
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-coding-agent",
4
- "version": "17.3.1",
4
+ "version": "17.3.2",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -50,18 +50,18 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@babel/parser": "^7.29.7",
53
- "@oh-my-pi/hashline": "17.3.1",
54
- "@oh-my-pi/omp-stats": "17.3.1",
55
- "@oh-my-pi/omptype": "17.3.1",
56
- "@oh-my-pi/pi-agent-core": "17.3.1",
57
- "@oh-my-pi/pi-ai": "17.3.1",
58
- "@oh-my-pi/pi-catalog": "17.3.1",
59
- "@oh-my-pi/pi-mnemopi": "17.3.1",
60
- "@oh-my-pi/pi-natives": "17.3.1",
61
- "@oh-my-pi/pi-tui": "17.3.1",
62
- "@oh-my-pi/pi-utils": "17.3.1",
63
- "@oh-my-pi/pi-wire": "17.3.1",
64
- "@oh-my-pi/snapcompact": "17.3.1",
53
+ "@oh-my-pi/hashline": "17.3.2",
54
+ "@oh-my-pi/omp-stats": "17.3.2",
55
+ "@oh-my-pi/omptype": "17.3.2",
56
+ "@oh-my-pi/pi-agent-core": "17.3.2",
57
+ "@oh-my-pi/pi-ai": "17.3.2",
58
+ "@oh-my-pi/pi-catalog": "17.3.2",
59
+ "@oh-my-pi/pi-mnemopi": "17.3.2",
60
+ "@oh-my-pi/pi-natives": "17.3.2",
61
+ "@oh-my-pi/pi-tui": "17.3.2",
62
+ "@oh-my-pi/pi-utils": "17.3.2",
63
+ "@oh-my-pi/pi-wire": "17.3.2",
64
+ "@oh-my-pi/snapcompact": "17.3.2",
65
65
  "@opentelemetry/api": "^1.9.1",
66
66
  "@opentelemetry/api-logs": "^0.220.0",
67
67
  "@opentelemetry/context-async-hooks": "^2.9.0",
@@ -467,6 +467,27 @@ function isPathInDirectory(filePath: string, directoryPath: string): boolean {
467
467
  return isPathInDirectoryLexical(resolvedFile, dirReal);
468
468
  }
469
469
 
470
+ function isPathInManagerRoot(linkTarget: string, nodeModulesDir: string): boolean {
471
+ if (isPathInDirectoryLexical(linkTarget, nodeModulesDir)) return true;
472
+ // Resolve only the manager root. Resolving the link target itself would
473
+ // follow globally linked packages into their checkout and lose ownership.
474
+ const nodeModulesReal = tryRealpath(path.resolve(nodeModulesDir));
475
+ return nodeModulesReal !== undefined && isPathInDirectoryLexical(linkTarget, nodeModulesReal);
476
+ }
477
+
478
+ function resolveNpmGlobalNodeModulesDir(globalBinDir: string | undefined): string | undefined {
479
+ if (!globalBinDir) return undefined;
480
+ if (process.platform === "win32") return path.join(globalBinDir, "node_modules");
481
+ return path.join(path.dirname(globalBinDir), "lib", "node_modules");
482
+ }
483
+
484
+ function isManagerOwnedBinEntry(linkTarget: string | undefined, nodeModulesDir: string | undefined): boolean {
485
+ // Non-symlink launchers and unreadable links retain the existing bin-dir
486
+ // classification. A readable link must point through the manager's exact
487
+ // global node_modules tree.
488
+ return linkTarget === undefined || (nodeModulesDir !== undefined && isPathInManagerRoot(linkTarget, nodeModulesDir));
489
+ }
490
+
470
491
  type UpdateMethod = "brew" | "mise" | "nix" | "bun" | "npm" | "binary";
471
492
 
472
493
  interface UpdateMethodResolutionOptions {
@@ -474,6 +495,8 @@ interface UpdateMethodResolutionOptions {
474
495
  miseBinDirs?: readonly string[];
475
496
  miseDataDir?: string;
476
497
  npmBinDir?: string;
498
+ /** Bun's configured global package directory, independent of its bin directory. */
499
+ bunGlobalDir?: string;
477
500
  /**
478
501
  * Whether the resolved omp path is a plain file (the standalone binary)
479
502
  * rather than a package-manager symlink. Stops a binary install from being
@@ -481,6 +504,11 @@ interface UpdateMethodResolutionOptions {
481
504
  * target directory.
482
505
  */
483
506
  ompIsRegularFile?: boolean;
507
+ /**
508
+ * Absolute path named by the bin entry's first symlink hop. This deliberately
509
+ * preserves a global package symlink instead of resolving into its checkout.
510
+ */
511
+ ompLinkTarget?: string;
484
512
  }
485
513
 
486
514
  type UpdateTarget =
@@ -496,7 +524,15 @@ function resolveUpdateMethod(
496
524
  bunBinDir: string | undefined,
497
525
  options: UpdateMethodResolutionOptions = {},
498
526
  ): UpdateMethod {
499
- const { homebrewPrefix, miseBinDirs = [], miseDataDir, npmBinDir, ompIsRegularFile = false } = options;
527
+ const {
528
+ bunGlobalDir,
529
+ homebrewPrefix,
530
+ miseBinDirs = [],
531
+ miseDataDir,
532
+ npmBinDir,
533
+ ompIsRegularFile = false,
534
+ ompLinkTarget,
535
+ } = options;
500
536
  const launcherExtension = path.extname(ompPath).toLowerCase();
501
537
  const isWindowsScriptLauncher =
502
538
  launcherExtension === ".cmd" || launcherExtension === ".ps1" || launcherExtension === ".bat";
@@ -514,9 +550,28 @@ function resolveUpdateMethod(
514
550
  // (bun's .exe launcher, npm's .cmd/.ps1), so a regular file is NOT evidence
515
551
  // of a standalone install and the override would hijack managed installs.
516
552
  const isStandaloneRegularFile = ompIsRegularFile && process.platform !== "win32";
517
- if (bunBinDir && isPathInDirectory(ompPath, bunBinDir) && !isStandaloneRegularFile) return "bun";
518
- if ((npmBinDir && isPathInDirectory(ompPath, npmBinDir) && !isStandaloneRegularFile) || isWindowsScriptLauncher)
553
+ const bunNodeModulesDir = resolveBunGlobalNodeModulesDirFromLocations({
554
+ globalDir: bunGlobalDir,
555
+ globalBinDir: bunBinDir,
556
+ });
557
+ if (
558
+ bunBinDir &&
559
+ isPathInDirectory(ompPath, bunBinDir) &&
560
+ !isStandaloneRegularFile &&
561
+ isManagerOwnedBinEntry(ompLinkTarget, bunNodeModulesDir)
562
+ ) {
563
+ return "bun";
564
+ }
565
+ const npmNodeModulesDir = resolveNpmGlobalNodeModulesDir(npmBinDir);
566
+ if (
567
+ npmBinDir &&
568
+ isPathInDirectory(ompPath, npmBinDir) &&
569
+ !isStandaloneRegularFile &&
570
+ isManagerOwnedBinEntry(ompLinkTarget, npmNodeModulesDir)
571
+ ) {
519
572
  return "npm";
573
+ }
574
+ if (isWindowsScriptLauncher) return "npm";
520
575
  return "binary";
521
576
  }
522
577
 
@@ -527,6 +582,44 @@ export function resolveUpdateMethodForTest(
527
582
  ): UpdateMethod {
528
583
  return resolveUpdateMethod(ompPath, bunBinDir, options);
529
584
  }
585
+
586
+ /** Resolve an update target from the concrete PATH entry selected by the shell. */
587
+ export function resolveUpdateTargetFromPath(
588
+ ompPath: string,
589
+ bunBinDir: string | undefined,
590
+ options: UpdateMethodResolutionOptions & { allowPackageManagers: boolean },
591
+ ): UpdateTarget {
592
+ let ompIsRegularFile = false;
593
+ let ompIsSymlink = false;
594
+ let ompLinkTarget: string | undefined;
595
+ let ompRealpath: string | undefined;
596
+ try {
597
+ const stat = fs.lstatSync(ompPath);
598
+ ompIsRegularFile = stat.isFile() && !stat.isSymbolicLink();
599
+ ompIsSymlink = stat.isSymbolicLink();
600
+ if (ompIsSymlink) {
601
+ const rawTarget = fs.readlinkSync(ompPath);
602
+ const linkDir = path.dirname(ompPath);
603
+ ompLinkTarget = path.resolve(tryRealpath(linkDir) ?? linkDir, rawTarget);
604
+ ompRealpath = tryRealpath(ompPath);
605
+ }
606
+ } catch {}
607
+
608
+ const method = resolveUpdateMethod(ompPath, bunBinDir, {
609
+ ...options,
610
+ ompIsRegularFile,
611
+ ompLinkTarget,
612
+ });
613
+ if (method === "binary") {
614
+ // A package-manager-enabled update follows a foreign alias to replace
615
+ // its standalone binary. Binary-only releases intentionally replace the
616
+ // selected manager launcher in place.
617
+ const binaryPath = options.allowPackageManagers && ompIsSymlink ? (ompRealpath ?? ompPath) : ompPath;
618
+ return { method, path: binaryPath, replacesSymlink: ompIsSymlink && binaryPath === ompPath };
619
+ }
620
+ if (method === "bun" || method === "npm") return { method, path: ompPath };
621
+ return { method };
622
+ }
530
623
  /**
531
624
  * Resolve how the running install should be updated.
532
625
  *
@@ -546,27 +639,14 @@ async function resolveUpdateTarget(options: { allowPackageManagers: boolean }):
546
639
  const ompPath = resolveOmpPath();
547
640
 
548
641
  if (ompPath) {
549
- // Package-manager installs symlink the bin entry into node_modules; the
550
- // standalone installer writes a plain executable. When the global bin dir
551
- // overlaps the installer's default (~/.local/bin), that file type — not
552
- // directory containment — distinguishes a binary install from npm/bun.
553
- let ompIsRegularFile = false;
554
- let ompIsSymlink = false;
555
- try {
556
- const stat = fs.lstatSync(ompPath);
557
- ompIsRegularFile = stat.isFile() && !stat.isSymbolicLink();
558
- ompIsSymlink = stat.isSymbolicLink();
559
- } catch {}
560
- const method = resolveUpdateMethod(ompPath, bunBinDir, {
642
+ return resolveUpdateTargetFromPath(ompPath, bunBinDir, {
643
+ allowPackageManagers: options.allowPackageManagers,
644
+ bunGlobalDir: options.allowPackageManagers ? process.env.BUN_INSTALL_GLOBAL_DIR : undefined,
561
645
  homebrewPrefix,
562
646
  miseBinDirs,
563
647
  miseDataDir,
564
648
  npmBinDir,
565
- ompIsRegularFile,
566
649
  });
567
- if (method === "binary") return { method, path: ompPath, replacesSymlink: ompIsSymlink };
568
- if (method === "bun" || method === "npm") return { method, path: ompPath };
569
- return { method };
570
650
  }
571
651
 
572
652
  if (bunBinDir) return { method: "bun" };
@@ -795,10 +875,19 @@ async function resolveBunInstallCacheDir(): Promise<string | undefined> {
795
875
  }
796
876
  }
797
877
 
798
- export function resolveBunGlobalNodeModulesDirFromLocations(
799
- globalBinDir: string | undefined,
800
- cacheDir: string | undefined,
801
- ): string | undefined {
878
+ interface BunGlobalInstallLocations {
879
+ globalDir?: string;
880
+ globalBinDir?: string;
881
+ cacheDir?: string;
882
+ }
883
+
884
+ /** Resolve Bun's global node_modules root from explicit, default, or cache locations. */
885
+ export function resolveBunGlobalNodeModulesDirFromLocations({
886
+ globalDir,
887
+ globalBinDir,
888
+ cacheDir,
889
+ }: BunGlobalInstallLocations): string | undefined {
890
+ if (globalDir && globalDir.length > 0) return path.join(globalDir, "node_modules");
802
891
  if (globalBinDir && globalBinDir.length > 0) {
803
892
  return path.join(path.dirname(globalBinDir), "install", "global", "node_modules");
804
893
  }
@@ -812,9 +901,16 @@ async function resolveBunGlobalNodeModulesDir(cacheDir: string): Promise<string
812
901
  try {
813
902
  const result = await $`bun pm bin -g`.quiet().nothrow();
814
903
  const globalBinDir = result.exitCode === 0 ? result.text().trim() : undefined;
815
- return resolveBunGlobalNodeModulesDirFromLocations(globalBinDir, cacheDir);
904
+ return resolveBunGlobalNodeModulesDirFromLocations({
905
+ globalDir: process.env.BUN_INSTALL_GLOBAL_DIR,
906
+ globalBinDir,
907
+ cacheDir,
908
+ });
816
909
  } catch {
817
- return resolveBunGlobalNodeModulesDirFromLocations(undefined, cacheDir);
910
+ return resolveBunGlobalNodeModulesDirFromLocations({
911
+ globalDir: process.env.BUN_INSTALL_GLOBAL_DIR,
912
+ cacheDir,
913
+ });
818
914
  }
819
915
  }
820
916
 
@@ -37,6 +37,7 @@ import {
37
37
  type AsideMessage,
38
38
  type BeforeToolCallContext,
39
39
  type BeforeToolCallResult,
40
+ EventLoopKeepalive,
40
41
  resolveTelemetry,
41
42
  type StreamFn,
42
43
  TERMINAL_TOOL_RESULT_ABORT_REASON,
@@ -1213,15 +1214,28 @@ export class AgentSession {
1213
1214
  }
1214
1215
  },
1215
1216
  scheduleIdleFlush: run => {
1216
- this.#schedulePostPromptTask(
1217
- async () => {
1218
- await run();
1219
- },
1220
- {
1221
- delayMs: 1,
1222
- onSkip: () => this.yieldQueue.cancelIdleFlushScheduling(),
1223
- },
1224
- );
1217
+ const keepalive = new EventLoopKeepalive();
1218
+ try {
1219
+ this.#schedulePostPromptTask(
1220
+ async () => {
1221
+ try {
1222
+ await run();
1223
+ } finally {
1224
+ keepalive[Symbol.dispose]();
1225
+ }
1226
+ },
1227
+ {
1228
+ delayMs: 1,
1229
+ onSkip: () => {
1230
+ keepalive[Symbol.dispose]();
1231
+ this.yieldQueue.cancelIdleFlushScheduling();
1232
+ },
1233
+ },
1234
+ );
1235
+ } catch (error) {
1236
+ keepalive[Symbol.dispose]();
1237
+ throw error;
1238
+ }
1225
1239
  },
1226
1240
  });
1227
1241
  this.yieldQueue.register<LaunchCompletionEntry>(LAUNCH_COMPLETION_MESSAGE_TYPE, {
@@ -6,7 +6,7 @@
6
6
 
7
7
  import path from "node:path";
8
8
  import type { AgentEvent, AgentIdentity, AgentMessage, AgentTelemetryConfig } from "@oh-my-pi/pi-agent-core";
9
- import { recordHandoff, resolveTelemetry } from "@oh-my-pi/pi-agent-core";
9
+ import { EventLoopKeepalive, recordHandoff, resolveTelemetry } from "@oh-my-pi/pi-agent-core";
10
10
  import type { Api, Model, ServiceTierByFamily, Usage } from "@oh-my-pi/pi-ai";
11
11
  import { logger, popLoopPhase, prompt, pushLoopPhase, untilAborted } from "@oh-my-pi/pi-utils";
12
12
  import { ASYNC_JOB_MANAGER_SHUTDOWN_REASON, AsyncJobManager } from "../async";
@@ -1868,6 +1868,7 @@ async function driveSessionToYield(
1868
1868
  monitor: SubagentRunMonitor,
1869
1869
  task: string,
1870
1870
  ): Promise<DriveOutcome> {
1871
+ using _keepalive = new EventLoopKeepalive();
1871
1872
  const abortSignal = monitor.abortSignal;
1872
1873
  let exitCode = 0;
1873
1874
  let error: string | undefined;
@@ -37,16 +37,17 @@ export interface HashlineHeaderContext {
37
37
  }
38
38
 
39
39
  export function formatReadHashlineHeader(displayPath: string, tag: string): string {
40
- // In-workspace reads collapse to the bare filename for brevity: the edit
41
- // tool's snapshot-tag recovery rebinds a bare `[name#tag]` onto the in-tree
42
- // file it uniquely names. Out-of-workspace reads can't lean on that
43
- // recovery refuses to redirect a write outside the cwd/sandbox
44
- // (HashlineFilesystem.allowTagPathRecovery) so an absolute displayPath
45
- // must stay directly resolvable, otherwise the basename resolves against
46
- // cwd, misses, and the edit fails with "File not found" (e.g. ~/.claude/*).
47
- // `shortenPath` keeps `~/.claude/...` (round-trips through resolveToCwd's ~
48
- // expansion) instead of leaking the full home path into the read output.
49
- const anchor = path.isAbsolute(displayPath) ? shortenPath(displayPath) : path.basename(displayPath);
40
+ // In-workspace reads keep their workspace-relative path (e.g.
41
+ // `src/settings.json`), not just the basename: collapsing to the bare name
42
+ // made a header ambiguous whenever another same-named file exists at cwd
43
+ // the edit tool would resolve the bare name against cwd, hit the wrong
44
+ // file, and reject the valid edit via the snapshot-tag guard (the authored
45
+ // path exists, so Patcher's tag-path recovery never runs). The relative
46
+ // path stays directly resolvable against cwd and names the file uniquely.
47
+ // Out-of-workspace reads use an absolute displayPath; `shortenPath` keeps
48
+ // `~/.claude/...` (round-trips through resolveToCwd's ~ expansion) instead
49
+ // of leaking the full home path into the read output.
50
+ const anchor = path.isAbsolute(displayPath) ? shortenPath(displayPath) : displayPath;
50
51
  return formatHashlineHeader(anchor, tag);
51
52
  }
52
53
 
@@ -38,7 +38,7 @@ interface ObservedPromiseState {
38
38
  const observedBrowserPromises = new WeakMap<Promise<unknown>, ObservedPromiseState>();
39
39
  const observedPromiseConstructor = { [Symbol.species]: Promise };
40
40
 
41
- type PromiseCombinatorName = "all" | "race";
41
+ type PromiseCombinatorName = "all" | "race" | "allSettled" | "any";
42
42
  type PromiseCombinator = (this: PromiseConstructor, values: Iterable<unknown>) => Promise<unknown>;
43
43
 
44
44
  interface PromiseCombinatorTrackingContext {
@@ -46,11 +46,13 @@ interface PromiseCombinatorTrackingContext {
46
46
  onFloatingRejection: FloatingRejectionHandler;
47
47
  }
48
48
 
49
- const PROMISE_COMBINATORS: readonly PromiseCombinatorName[] = ["all", "race"];
49
+ const PROMISE_COMBINATORS: readonly PromiseCombinatorName[] = ["all", "race", "allSettled", "any"];
50
50
  const NativePromise = Promise;
51
51
  const nativePromiseCombinators: Record<PromiseCombinatorName, PromiseCombinator> = {
52
52
  all: Promise.all,
53
53
  race: Promise.race,
54
+ allSettled: Promise.allSettled,
55
+ any: Promise.any,
54
56
  };
55
57
  const promiseCombinatorTracking = new AsyncLocalStorage<PromiseCombinatorTrackingContext>();
56
58
  let previousPromiseDescriptor: PropertyDescriptor | undefined;
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Utilities for launching an external text editor ($VISUAL / $EDITOR).
3
3
  */
4
- import { spawn } from "node:child_process";
5
4
  import * as fs from "node:fs/promises";
6
5
  import * as os from "node:os";
7
6
  import * as path from "node:path";
@@ -51,17 +50,17 @@ export async function openInEditor(
51
50
  try {
52
51
  await Bun.write(tmpFile, content);
53
52
 
54
- const [editor, ...editorArgs] = editorCmd.split(" ");
55
- const stdio = options?.stdio ?? ["inherit", "inherit", "inherit"];
56
- const child =
53
+ const [stdin, stdout, stderr] = options?.stdio ?? ["inherit", "inherit", "inherit"];
54
+ const cmd =
57
55
  process.platform === "win32"
58
- ? spawn(editor, [...editorArgs, tmpFile], { stdio, shell: true })
59
- : spawn($which("sh") ?? "sh", ["-c", `${editorCmd} "$1"`, "sh", tmpFile], { stdio });
60
- const { promise, reject, resolve } = Promise.withResolvers<number>();
61
- child.once("exit", (code, signal) => resolve(code ?? (signal ? -1 : 0)));
62
- child.once("error", error => reject(error));
63
- const exitCode = await promise;
64
-
56
+ ? ["cmd", "/c", `${editorCmd} "${tmpFile}"`]
57
+ : [$which("sh") ?? "sh", "-c", `${editorCmd} "$1"`, "sh", tmpFile];
58
+ const child = Bun.spawn(cmd, {
59
+ stdin,
60
+ stdout,
61
+ stderr,
62
+ });
63
+ const exitCode = await child.exited;
65
64
  if (exitCode === 0) {
66
65
  const text = await Bun.file(tmpFile).text();
67
66
  if (options?.trimTrailingNewline === false) {
@@ -9,11 +9,7 @@
9
9
  * endpoint.
10
10
  */
11
11
  import { type AuthStorage, type FetchImpl, type OAuthAccess, withOAuthAccess } from "@oh-my-pi/pi-ai";
12
- import {
13
- ANTIGRAVITY_SYSTEM_INSTRUCTION,
14
- getAntigravityUserAgent,
15
- getGeminiCliHeaders,
16
- } from "@oh-my-pi/pi-catalog/wire/gemini-headers";
12
+ import { getAntigravityUserAgent, getGeminiCliHeaders } from "@oh-my-pi/pi-catalog/wire/gemini-headers";
17
13
  import { fetchWithRetry, USER_AGENT } from "@oh-my-pi/pi-utils";
18
14
 
19
15
  import type { SearchCitation, SearchResponse, SearchSource } from "../../../web/search/types";
@@ -441,10 +437,9 @@ async function callGeminiSearch(
441
437
  };
442
438
 
443
439
  const normalizedSystemPrompt = systemPrompt?.toWellFormed();
444
- const systemInstructionParts: Array<{ text: string }> = [
445
- ...(auth.isAntigravity ? [{ text: ANTIGRAVITY_SYSTEM_INSTRUCTION }] : []),
446
- ...(normalizedSystemPrompt ? [{ text: normalizedSystemPrompt }] : []),
447
- ];
440
+ const systemInstructionParts: Array<{ text: string }> = normalizedSystemPrompt
441
+ ? [{ text: normalizedSystemPrompt }]
442
+ : [];
448
443
 
449
444
  const requestBody: Record<string, unknown> = {
450
445
  project: auth.projectId,