pi-ast-sgrep 2.2.1 → 2.5.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.
@@ -13,7 +13,7 @@ export declare const DEFAULT_LIMIT = 8;
13
13
  * session, or a host that drops the built-ins still gets them — but they are
14
14
  * left out of the active set when the host already provides read+edit. Pi only
15
15
  * sends ACTIVE tools (schema, snippet, guidelines) to the model, so this is the
16
- * difference between ~296 tokens per request and nothing.
16
+ * difference between ~271 tokens per request and nothing.
17
17
  *
18
18
  * ASGREP_KEEP_FILE_TOOLS=1 pins them active regardless.
19
19
  */
@@ -4,22 +4,21 @@ import { Type } from "typebox";
4
4
  import { createAsgrepConnector, runCodemode, runNativeBatch, runBatchViaStdin, CODEMODE_TYPES_FOR_MODEL, NativeSessionPool, argvFor, asEnvelope, applyQueryScope, warmCodemodeSandbox, resetCodemodeSandboxForTests, isClosedWorkerError, } from "../codemode/index.js";
5
5
  import { AstSgrepRuntime, FreshnessCoordinator, RuntimeError } from "../runtime/runtime.js";
6
6
  import { RESOLVED_ROOT } from "../runtime/types.js";
7
- import { ASGREP_PROMPT_GUIDELINES, ASGREP_PROMPT_SNIPPET, formatCodemodeResult, } from "../ui/present.js";
7
+ import { ASGREP_PROMPT_GUIDELINES, ASGREP_PROMPT_GUIDELINES_HOST_FILES, ASGREP_PROMPT_SNIPPET, formatCodemodeResult, } from "../ui/present.js";
8
8
  import { EMPTY_CALL, renderAsgrepResult } from "../ui/card.js";
9
9
  import { bounded, errorDetails, failure, isFreshnessTimeout, extractInPath, report, success, } from "./results.js";
10
10
  export const DEFAULT_LIMIT = 8;
11
11
  const MAX_LIMIT = 100;
12
12
  const MAX_EXCERPT_LINES = 100;
13
13
  const searchParameters = Type.Object({
14
- query: Type.String({ maxLength: 4_096, description: "Query, symbol, or pattern" }),
14
+ query: Type.String({ maxLength: 4_096 }),
15
15
  mode: Type.Optional(Type.Unsafe({
16
16
  type: "string",
17
17
  enum: ["natural", "pattern", "defs", "callers", "chain", "semantic", "word", "literal", "regex", "imports"],
18
18
  default: "natural",
19
- description: "Search strategy",
20
19
  })),
21
20
  limit: Type.Optional(Type.Integer({ default: DEFAULT_LIMIT })),
22
- excerptLines: Type.Optional(Type.Integer({ default: 0, description: "Inline N excerpt lines per hit" })),
21
+ excerptLines: Type.Optional(Type.Integer({ default: 0 })),
23
22
  in: Type.Optional(Type.String({ maxLength: 512, description: "Bound to a directory or glob" })),
24
23
  lang: Type.Optional(Type.String({ maxLength: 32, description: "Language filter (rs, ts, py)" })),
25
24
  }, { additionalProperties: false });
@@ -27,9 +26,9 @@ const indexParameters = Type.Object({
27
26
  force: Type.Optional(Type.Boolean({ default: false, description: "Rebuild the index from scratch" })),
28
27
  }, { additionalProperties: false });
29
28
  const editParameters = Type.Object({
30
- path: Type.Optional(Type.String({ maxLength: 512, description: "File to edit" })),
29
+ path: Type.Optional(Type.String({ maxLength: 512 })),
31
30
  oldText: Type.Optional(Type.String({ description: "Exact text to replace (must match once)" })),
32
- newText: Type.Optional(Type.String({ description: "Replacement" })),
31
+ newText: Type.Optional(Type.String()),
33
32
  edits: Type.Optional(Type.Array(Type.Object({
34
33
  path: Type.Optional(Type.String({ minLength: 1, maxLength: 512 })),
35
34
  oldText: Type.String({ minLength: 1 }),
@@ -37,7 +36,7 @@ const editParameters = Type.Object({
37
36
  }), { maxItems: 64, description: "Multi-edit entries; top-level path is the default" })),
38
37
  }, { additionalProperties: false });
39
38
  const readParameters = Type.Object({
40
- path: Type.Optional(Type.String({ maxLength: 512, description: "File to read" })),
39
+ path: Type.Optional(Type.String({ maxLength: 512 })),
41
40
  ref: Type.Optional(Type.String({ description: "Hit ref path#L12-L40" })),
42
41
  refs: Type.Optional(Type.Array(Type.String(), { maxItems: 24, description: "Several refs in one call" })),
43
42
  start: Type.Optional(Type.Integer()),
@@ -49,7 +48,7 @@ const codemodeParameters = Type.Object({
49
48
  code: Type.String({
50
49
  minLength: 1,
51
50
  maxLength: 32_000,
52
- description: "JavaScript: async () => { ... } or a bare body with return. The returned value is the tool result.",
51
+ description: "JavaScript: async () => { ... } or a bare body with return.",
53
52
  }),
54
53
  timeoutMs: Type.Optional(Type.Integer({ description: "Timeout ms (default 30000)" })),
55
54
  }, { additionalProperties: false });
@@ -84,7 +83,7 @@ function withSearchLang(argv, lang) {
84
83
  * session, or a host that drops the built-ins still gets them — but they are
85
84
  * left out of the active set when the host already provides read+edit. Pi only
86
85
  * sends ACTIVE tools (schema, snippet, guidelines) to the model, so this is the
87
- * difference between ~296 tokens per request and nothing.
86
+ * difference between ~271 tokens per request and nothing.
88
87
  *
89
88
  * ASGREP_KEEP_FILE_TOOLS=1 pins them active regardless.
90
89
  */
@@ -518,10 +517,10 @@ export function registerAstSgrepTools(pi, runtime = new AstSgrepRuntime(pi), fre
518
517
  name: "asgrep",
519
518
  label: "asgrep",
520
519
  promptSnippet: ASGREP_PROMPT_SNIPPET,
521
- promptGuidelines: [...ASGREP_PROMPT_GUIDELINES],
520
+ promptGuidelines: [...(hostProvidesFileTools(pi) ? ASGREP_PROMPT_GUIDELINES_HOST_FILES : ASGREP_PROMPT_GUIDELINES)],
522
521
  description: [
523
- "Code search (in-process, warm Searcher): use it for any code lookup instead of grep.",
524
- "Write JavaScript; the returned value is your result.",
522
+ "Code search: use it for any code lookup instead of grep.",
523
+ "The returned value is your result.",
525
524
  CODEMODE_TYPES_FOR_MODEL,
526
525
  "Example: async () => (await asgrep.search(\"auth\", { limit: 5 })).hits",
527
526
  ].join("\n"),
@@ -608,7 +607,7 @@ export function registerAstSgrepTools(pi, runtime = new AstSgrepRuntime(pi), fre
608
607
  pi.registerTool({
609
608
  name: "asgrep_search",
610
609
  label: "asgrep search",
611
- promptSnippet: "One-shot asgrep search",
610
+ promptSnippet: "One-shot search",
612
611
  description: "One-shot search. Use asgrep (Code Mode) for anything multi-step, parallel, or filtered.",
613
612
  parameters: searchParameters,
614
613
  renderShell: "self",
@@ -675,7 +674,7 @@ export function registerAstSgrepTools(pi, runtime = new AstSgrepRuntime(pi), fre
675
674
  name: "asgrep_edit",
676
675
  label: "asgrep edit",
677
676
  promptSnippet: "Exact-string edit",
678
- description: "Edit by exact-string replace; oldText must match once. edits[] applies many atomically.",
677
+ description: "Edit by exact-string replace. edits[] applies many atomically.",
679
678
  parameters: editParameters,
680
679
  renderShell: "self",
681
680
  renderCall() {
@@ -735,7 +734,7 @@ export function registerAstSgrepTools(pi, runtime = new AstSgrepRuntime(pi), fre
735
734
  name: "asgrep_index",
736
735
  label: "asgrep index",
737
736
  promptSnippet: "Build or rebuild the index",
738
- description: "Build or rebuild the index (embeddings included).",
737
+ description: "Build or rebuild the index.",
739
738
  parameters: indexParameters,
740
739
  renderShell: "self",
741
740
  renderCall() {
@@ -27,8 +27,16 @@ export type EnvelopeLike = {
27
27
  backend?: unknown;
28
28
  [key: string]: unknown;
29
29
  };
30
- export declare const ASGREP_PROMPT_SNIPPET = "Code search by intent, symbol, defs, callers, pattern (asgrep; use without being asked)";
30
+ export declare const ASGREP_PROMPT_SNIPPET = "Code search by intent, symbol, defs, callers, pattern (use without being asked)";
31
31
  export declare const ASGREP_PROMPT_GUIDELINES: readonly ["Any code lookup: call asgrep first; read code with asgrep_read, change it with asgrep_edit.", "Compose in Code Mode (search/defs/read, Promise.all, small shaped value); grep only exact strings/filenames. Bound with in:\"path\"; on 0 hits use suggested_next."];
32
+ /**
33
+ * Guideline variant for hosts that already ship read/edit built in: our
34
+ * one-shot file tools are inactive there, so naming them would point the
35
+ * model at tools it cannot see. The host's own builtins describe
36
+ * themselves; this keeps only the asgrep-first routing plus the shared
37
+ * composition guideline.
38
+ */
39
+ export declare const ASGREP_PROMPT_GUIDELINES_HOST_FILES: readonly ["Any code lookup: call asgrep first.", "Compose in Code Mode (search/defs/read, Promise.all, small shaped value); grep only exact strings/filenames. Bound with in:\"path\"; on 0 hits use suggested_next."];
32
40
  export declare function paint(theme: PresentTheme | undefined, role: string, text: string, bold?: boolean): string;
33
41
  export declare function hitLocation(hit: HitLike): string;
34
42
  export declare function hitLabel(hit: HitLike): string;
@@ -1,9 +1,20 @@
1
1
  /** Neat asgrep tool chrome for the Pi TUI and the model-visible content. */
2
- export const ASGREP_PROMPT_SNIPPET = "Code search by intent, symbol, defs, callers, pattern (asgrep; use without being asked)";
2
+ export const ASGREP_PROMPT_SNIPPET = "Code search by intent, symbol, defs, callers, pattern (use without being asked)";
3
3
  export const ASGREP_PROMPT_GUIDELINES = [
4
4
  "Any code lookup: call asgrep first; read code with asgrep_read, change it with asgrep_edit.",
5
5
  "Compose in Code Mode (search/defs/read, Promise.all, small shaped value); grep only exact strings/filenames. Bound with in:\"path\"; on 0 hits use suggested_next.",
6
6
  ];
7
+ /**
8
+ * Guideline variant for hosts that already ship read/edit built in: our
9
+ * one-shot file tools are inactive there, so naming them would point the
10
+ * model at tools it cannot see. The host's own builtins describe
11
+ * themselves; this keeps only the asgrep-first routing plus the shared
12
+ * composition guideline.
13
+ */
14
+ export const ASGREP_PROMPT_GUIDELINES_HOST_FILES = [
15
+ "Any code lookup: call asgrep first.",
16
+ ASGREP_PROMPT_GUIDELINES[1],
17
+ ];
7
18
  export function paint(theme, role, text, bold = false) {
8
19
  const body = bold && theme ? theme.bold(text) : text;
9
20
  return theme ? theme.fg(role, body) : body;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-ast-sgrep",
3
- "version": "2.2.1",
3
+ "version": "2.5.2",
4
4
  "description": "Native Code Mode, structural, graph, and semantic code search for Pi",
5
5
  "type": "module",
6
6
  "license": "MIT",