Skip to content

Code Indexing Support for WSO2 Integrator Copilot#2263

Draft
yasithrashan wants to merge 76 commits into
wso2:feature/wso2-integrator-copilot-code-indexingfrom
yasithrashan:feature/code-indexing-bi-copilot
Draft

Code Indexing Support for WSO2 Integrator Copilot#2263
yasithrashan wants to merge 76 commits into
wso2:feature/wso2-integrator-copilot-code-indexingfrom
yasithrashan:feature/code-indexing-bi-copilot

Conversation

@yasithrashan

@yasithrashan yasithrashan commented May 19, 2026

Copy link
Copy Markdown
Contributor

Purpose

$title

Resolves: https://github.com/wso2-enterprise/integration-engineering/issues/893

key Changes

  • Introduced CodeMap, a Markdown-based file that provides a high-level summary of artifacts in a Ballerina codebase
  • Added grep and glob tools for code exploration
  • Added context retrieval evaluation to the AI test pipeline

Summary by CodeRabbit

  • New Features

    • Code Map endpoints with optional Code Map markdown injected into AI agents.
    • New grep and glob search tools for AI-assisted code exploration.
    • Text-editor read API now uses line-based ranges (startLine/endLine).
    • AI panel displays dependency-pull progress banner.
    • Added multiple example/test projects and generated sample services.
  • AI / Evaluation

    • Prompts accept precomputed code-map summaries.
    • New context-retrieval LLM evaluation and reporting.
  • Tests

    • Many new unit and integration test suites for tools and evals.

Review Change Stack

@yasithrashan

Copy link
Copy Markdown
Contributor Author

@coderabbitai can you review grep.ts file

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@workspaces/ballerina/ballerina-extension/src/features/ai/agent/tools/grep.ts`:
- Around line 212-214: The args.push call in grep.ts currently contains a stray
'--glob' token (args.push('--glob', '!.git/**', '--glob', '--glob',
'!target/**')) which causes the second '--glob' to be used as a glob value and
pushes '!target/**' into ripgrep’s positional PATTERN; remove the extra '--glob'
so each '--glob' is followed by its pattern (i.e., ensure the call passes
'--glob', '!.git/**', '--glob', '!target/**'), then run the grep-related tests
or a quick ripgrep invocation to confirm the target exclusion works as expected.
- Around line 29-39: The grep tool currently treats ripgrep launch failures as
“No matches found”; update the code that calls spawnSync(getRgExecutable(), ...)
to explicitly check for process launch errors (proc.error !== undefined) and
null/undefined proc.status and treat them as failures: when proc.error is set or
proc.status is null/undefined return success: false with an error message
including proc.error or a descriptive message, otherwise keep the existing
checks for status === 1 or empty stdout; reference the spawnSync call and
variables named proc, proc.status and proc.error and the getRgExecutable helper
to locate where to add these additional error branches.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 37af476d-279c-4879-b8df-1f24d4a0fcbb

📥 Commits

Reviewing files that changed from the base of the PR and between d33596d and e07777c.

📒 Files selected for processing (3)
  • workspaces/ballerina/ballerina-extension/package.json
  • workspaces/ballerina/ballerina-extension/src/features/ai/agent/tools/glob.ts
  • workspaces/ballerina/ballerina-extension/src/features/ai/agent/tools/grep.ts

Comment thread workspaces/ballerina/ballerina-extension/src/features/ai/agent/tools/grep.ts Outdated
Comment thread workspaces/ballerina/ballerina-extension/src/features/ai/agent/tools/grep.ts Outdated
@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
cat workspaces/ballerina/ballerina-extension/src/features/ai/agent/tools/grep.ts

Length of output: 13941


@yasithrashan Here's a detailed review of grep.ts:


Review of grep.ts

The implementation is solid overall — ripgrep integration is clean, output modes are well-designed, and the symlink/path-traversal protection is actually better than in glob.ts. A few issues to address:


🐛 Critical Bug: Malformed glob exclusion args

// Line ~228 — there's an extra dangling `'--glob'` token:
args.push('--glob', '!.git/**', '--glob', '--glob', '!target/**');
//                              ^^^^^^^^^^^^^^^^^^^^
//                              This passes `--glob` as the VALUE of the preceding --glob flag,
//                              meaning ripgrep tries to include files named literally "--glob"

As a result, ripgrep receives:

  • --glob !.git/**
  • --glob --glob ❌ (matches files literally named --glob)
  • !target/** is then treated as a standalone pattern/argument

Fix:

args.push('--glob', '!.git/**', '--glob', '!target/**');

⚠️ spawnSync blocks the VS Code event loop

const proc = spawnSync(getRgExecutable(), args, { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 });

spawnSync is fully synchronous. On a large workspace, this can freeze the extension host thread. Since createGrepExecute returns an async function, consider using execFilePromise or a promisified spawn:

import { execFile } from 'child_process';
import { promisify } from 'util';
const execFileAsync = promisify(execFile);

// Then in the execute function:
const { stdout, stderr } = await execFileAsync(
    getRgExecutable(), args,
    { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 }
).catch(err => {
    if (err.code === 1) return { stdout: err.stdout ?? '', stderr: '' }; // no matches
    throw err; // code 2 = rg error
});

⚠️ No regex pre-validation

An invalid regex (e.g., pattern: "[") causes ripgrep to exit with code 2, surfacing a raw rg error string. A pre-check gives a cleaner, user-facing message:

try {
    new RegExp(pattern);
} catch (e) {
    const result: GrepResult = { success: false, message: `Invalid regex pattern: ${(e as Error).message}`, error: 'Error: Invalid regex' };
    eventHandler({ type: "tool_result", toolName: GREP_TOOL_NAME, toolOutput: result });
    return result;
}

🔧 Truncation log count is off-by-one

if (truncated) {
    lines = lines.slice(0, effectiveLimit);
    lines.push(`... (results truncated at ${effectiveLimit} lines; ...)`);
}
// ...
console.log(`[GrepTool] ripgrep returned ${lines.length} lines.`);
// ↑ lines.length is now effectiveLimit + 1 (includes the truncation note)

Consider logging before the push, or logging the pre-truncation count separately:

const originalCount = lines.length;
if (truncated) {
    lines = lines.slice(0, effectiveLimit);
    lines.push(`... (results truncated at ${effectiveLimit} of ${originalCount} lines; ...)`);
}
console.log(`[GrepTool] ripgrep returned ${originalCount} lines (shown: ${Math.min(originalCount, effectiveLimit || originalCount)}).`);

🔧 Minor: node_modules not excluded

While Ballerina projects don't typically have node_modules, the extension itself runs in a Node.js environment and workspace paths can contain mixed projects. Consider adding it alongside .git and target:

args.push('--glob', '!.git/**', '--glob', '!target/**', '--glob', '!node_modules/**');

✅ What's working well

  • Path traversal guard: Using path.relative() instead of string prefix matching is much cleaner than glob.ts's approach and correctly handles symlinked tempProjectPath roots — no false-positive risk.
  • Two-stage symlink detection: path.relative() fast check + realpathSync re-validation is solid defence-in-depth.
  • Consistent event emission: Every exit path (validation failures, no matches, errors, success) emits tool_result — no leaking branches.
  • Sensible defaults: DEFAULT_HEAD_LIMIT = 200 and MAX_CONTEXT_LINES = 10 are pragmatic choices.
  • Ripgrep exit code handling: Correctly distinguishes code 0 (matches), 1 (no matches), 2 (error).
  • getRgExecutable() fallback: Falling back to system rg in test environments is a nice touch.
  • Path relativization: Stripping from tempProjectPath (not resolvedPath) so scoped searches still return full relative paths like order_service/file.bal is well thought-out.
  • Context line capping: Math.min(..., MAX_CONTEXT_LINES) prevents runaway output for heavily matched files.

@yasithrashan

Copy link
Copy Markdown
Contributor Author

@coderabbitai can you review grep.ts, glob.ts and rg-utils.ts

@coderabbitai

coderabbitai Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@yasithrashan Here's a consolidated review of all three files. The codebase has improved significantly since the earlier pass — most of the previously flagged issues are resolved. Remaining findings below:


rg-utils.ts — New shared utility (overall: ✅ solid)

⚠️ getRgExecutable() is not memoized

getRgExecutable() is called inside the execute closure on every tool invocation. When the bundled binary is absent, this runs spawnSync('which', ['rg']) on every grep/glob call:

// rg-utils.ts — current
export function getRgExecutable(): string {
    if (fs.existsSync(builtinRgPath)) { return builtinRgPath; }
    const result = spawnSync('which', ['rg'], { encoding: 'utf-8' });
    ...
    return builtinRgPath; // fallback even if 'which' failed
}

Consider memoizing the result at module level:

let _rgExecutable: string | undefined;

export function getRgExecutable(): string {
    if (_rgExecutable) return _rgExecutable;
    if (fs.existsSync(builtinRgPath)) {
        return (_rgExecutable = builtinRgPath);
    }
    const result = spawnSync('which', ['rg'], { encoding: 'utf-8' });
    _rgExecutable = (result.status === 0 && result.stdout?.trim())
        ? result.stdout.trim()
        : builtinRgPath;
    return _rgExecutable;
}

🔧 Minor: which is Unix-only

which is not available on Windows; the equivalent is where. Since VS Code extensions can run on Windows:

const whichCmd = process.platform === 'win32' ? 'where' : 'which';
const result = spawnSync(whichCmd, ['rg'], { encoding: 'utf-8' });

✅ What's working well in rg-utils.ts

  • resolveProjectRoots() called once at executor-creation time — symlink resolution is never repeated per request.
  • validateSearchPath() — the two-root check (normalizedRoot + normalizedRawRoot) correctly handles the case where tempProjectPath itself is a symlink without a false-positive, which was the bug in the original glob.ts. Clean fix.
  • stripRootPrefix() — the edge case for root-level files (bare tempProjectPath + ':') is well handled.

grep.ts — Updated (previous critical bug fixed ✅)

🐛 Log count off-by-one after truncation

if (truncated) {
    lines = lines.slice(0, effectiveLimit);
    lines.push(`... (results truncated at ${effectiveLimit} lines; ...)`);
}
// ↓ lines.length is now effectiveLimit + 1 — the truncation note is counted
console.log(`[GrepTool] ripgrep returned ${lines.length} lines.`);

Fix: Log the count before pushing the note, or use a separate variable:

const originalCount = lines.length;
if (truncated) {
    lines = lines.slice(0, effectiveLimit);
    lines.push(`... (results truncated at ${effectiveLimit} of ${originalCount} lines; narrow your search or increase head_limit)`);
}
console.log(`[GrepTool] ripgrep returned ${originalCount} lines (displayed: ${Math.min(originalCount, effectiveLimit || originalCount)}).`);

⚠️ No regex pre-validation

An invalid pattern (e.g., "[") causes ripgrep to exit with code 2 and surfaces a raw rg error string. A pre-check gives a cleaner user-facing message:

try {
    new RegExp(pattern);
} catch (e) {
    return fail(`Invalid regex pattern: ${(e as Error).message}`, 'Error: Invalid regex');
}

🔧 Minor: node_modules not excluded

Not common in Ballerina workspaces, but for mixed-project safety:

args.push('--glob', '!.git/**', '--glob', '!target/**', '--glob', '!node_modules/**');

✅ What's fixed since the prior review

  • Duplicate --glob bugargs.push('--glob', '!.git/**', '--glob', '!target/**') is now correct.
  • Path traversal — delegated to validateSearchPath() in rg-utils.ts which uses path.relative() + realpathSync, avoiding the false-positive risk.
  • stripRootPrefix — extracted cleanly into rg-utils.ts.

glob.ts — Updated (custom walkDir + regex entirely removed ✅)

🔧 Nit: Grammar in tool description

description: `
Fast file pattern matching tool that work inside the Ballerina projects.
//                                         ^^^^
//                                         should be "works"

⚠️ spawnSync still blocks the event loop (both grep.ts and glob.ts)

Both tools still use spawnSync. For large workspaces this blocks the VS Code extension host thread. Since both execute functions are already async, consider using spawnAsync (or a promisified wrapper):

import { spawn } from 'child_process';

function spawnAsync(cmd: string, args: string[], opts: { maxBuffer: number }): Promise<{ status: number | null; stdout: string; stderr: string }> {
    return new Promise((resolve) => {
        const chunks: Buffer[] = [], errChunks: Buffer[] = [];
        const proc = spawn(cmd, args, { ...opts });
        proc.stdout.on('data', d => chunks.push(d));
        proc.stderr.on('data', d => errChunks.push(d));
        proc.on('close', status => resolve({
            status,
            stdout: Buffer.concat(chunks).toString('utf-8'),
            stderr: Buffer.concat(errChunks).toString('utf-8'),
        }));
    });
}

✅ What's fixed since the prior review

  • Custom walkDir removed — ripgrep's native glob engine handles matching, eliminating the brace-expansion empty-alternation and ** mid-pattern issues.
  • MAX_RESULTS = 500 — already added ✅
  • False-positive path traversal — fixed via rg-utils.ts validateSearchPath()
  • Result truncation note — properly appended with files.length captured before slicing ✅

Summary Table

Issue File Severity Status
getRgExecutable() not memoized rg-utils.ts ⚠️ Perf New
which Unix-only rg-utils.ts 🔧 Minor New
Log count off-by-one grep.ts 🐛 Minor New
No regex pre-validation grep.ts ⚠️ UX Carry-over
node_modules not excluded grep.ts 🔧 Minor Carry-over
spawnSync blocks event loop grep.ts, glob.ts ⚠️ Perf Carry-over
Grammar nit in description glob.ts 🔧 Nit New
Duplicate --glob bug grep.ts 🐛 Fixed
False-positive path traversal glob.ts 🐛 Fixed
Custom walkDir / glob regex glob.ts ⚠️ Fixed
MAX_RESULTS cap glob.ts ⚠️ Fixed
Two-root symlink protection rg-utils.ts

@coderabbitai

coderabbitai Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@yasithrashan Here's a consolidated review of all three files. The refactor into rg-utils.ts is excellent — great shared-utility extraction. glob.ts in particular has been substantially improved.


rg-utils.ts — New shared utility module

🐛 getRgExecutable(): Windows incompatibility

which is a Unix-only command and will fail silently on Windows:

const result = spawnSync('which', ['rg'], { encoding: 'utf-8' });

On Windows the equivalent is where. Consider a cross-platform approach:

const whichCmd = process.platform === 'win32' ? 'where' : 'which';
const result = spawnSync(whichCmd, ['rg'], { encoding: 'utf-8' });

🐛 getRgExecutable(): Silent fallback to non-existent path

If the bundled binary is missing and system rg lookup fails, the function returns builtinRgPath anyway — which doesn't exist. The downstream spawnSync will then fail with an obscure ENOENT:

// Current:
return builtinRgPath; // ← returned even when fs.existsSync(builtinRgPath) was false!

// Safer:
console.error('[rg-utils] ripgrep binary not found. Install `@vscode/ripgrep` or ensure rg is on PATH.');
throw new Error('ripgrep binary not found');
// or return a sentinel so callers can handle gracefully

validateSearchPath() — Symlink false-positive fixed

The path traversal check now correctly tests against both normalizedRoot (real path) and normalizedRawRoot (raw path), which directly addresses the false-positive I flagged in the original glob.ts. Well done.

resolveProjectRoots() — Efficient, called once at setup time

Resolving realpathSync at executor creation time rather than per-request is a clear win.

stripRootPrefix() — Edge case handling

Correctly handles both the normal (/project/pkg/file.bal:42:...) and root-level file (/project/file.bal:42:...) forms.


glob.ts — Major rewrite, previous issues resolved

The complete rewrite to use ripgrep's --files mode instead of a custom walkDir is a significant improvement. Ripgrep's built-in glob engine is battle-tested and eliminates all the edge cases I flagged before (empty brace alternation, foo**bar cross-separator matching, synchronous readdirSync/statSync walk). The MAX_RESULTS = 500 cap is also now in place.

⚠️ mtime-based sorting lost

The original implementation sorted results by descending mtimeMs, which was a useful UX feature for surfacing recently-modified files first. The ripgrep --files output ordering is filesystem-dependent. Ripgrep natively supports modification-time sorting:

const args = [
    '--files',
    '--sortr', 'modified',   // ← most recently modified first
    '--glob', pattern,
    ...
];

⚠️ spawnSync still blocks the event loop

createGlobExecute returns an async function but uses spawnSync internally, which blocks the extension host thread. This was flagged before and remains. Since spawnSync is now also used in grep.ts, it may be worth tracking as a follow-up issue to migrate both tools to an async spawn/execFile approach.


grep.ts — Key bug fixed, two remaining issues

✅ Double --glob bug fixed

The malformed '--glob', '--glob', '!target/**' from the earlier version is now correctly:

args.push('--glob', '!.git/**', '--glob', '!target/**');

⚠️ No regex pre-validation (still)

An invalid regex (e.g., [) makes ripgrep exit with code 2 and returns a raw rg error string to the LLM. A pre-validation step gives a cleaner user-facing message:

try {
    new RegExp(pattern);
} catch (e) {
    return fail(`Invalid regex pattern: ${(e as Error).message}`, 'Error: Invalid regex');
}

🔧 Truncation log count off-by-one (still)

After lines.push(truncationNote), lines.length is effectiveLimit + 1. The log on the next line overstates the count:

console.log(`[GrepTool] ripgrep returned ${lines.length} lines.`);
// ↑ includes the truncation note line itself

A simple fix:

const rawCount = lines.length;
if (truncated) { lines = lines.slice(0, effectiveLimit); lines.push(`...`); }
console.log(`[GrepTool] ripgrep returned ${rawCount} lines (showing ${Math.min(rawCount, effectiveLimit || rawCount)}).`);

Summary

File Status Key remaining items
rg-utils.ts ✅ Clean extraction getRgExecutable Windows compat + silent fallback
glob.ts ✅ Major improvement mtime sort regression; spawnSync async follow-up
grep.ts ✅ Double-glob bug fixed Regex pre-validation; log count nit; spawnSync async follow-up

@yasithrashan yasithrashan force-pushed the feature/code-indexing-bi-copilot branch from 7dac3ed to c8a63a9 Compare May 28, 2026 02:35

function fail(message: string, error: string): GlobResult {
const result: GlobResult = { success: false, message, error };
eventHandler({ type: "tool_result", toolName: GLOB_TOOL_NAME, toolOutput: result });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have new ui elements to render these events

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

Comment on lines +71 to +72
eventHandler({
type: "tool_call",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

success: true,
message: `No files found matching pattern: "${pattern}"`,
};
eventHandler({ type: "tool_result", toolName: GLOB_TOOL_NAME, toolOutput: result });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

message: `Found ${files.length} file(s) matching "${pattern}":\n${displayed.join("\n")}${truncationNote}`,
};

eventHandler({ type: "tool_result", toolName: GLOB_TOOL_NAME, toolOutput: result });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack


function fail(message: string, error: string): GrepResult {
const result: GrepResult = { success: false, message, error };
eventHandler({ type: "tool_result", toolName: GREP_TOOL_NAME, toolOutput: result });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

Comment on lines +93 to +94
eventHandler({
type: "tool_call",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

if (proc.status === RgExitCode.Error) {
const errMsg = (proc.stderr || "").trim();
const result: GrepResult = { success: false, message: `ripgrep error: ${errMsg}`, error: errMsg };
eventHandler({ type: "tool_result", toolName: GREP_TOOL_NAME, toolOutput: result });

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto, Check other places too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

- When the user submits a query, you will receive either **Codebase High Level Summary** or **Complete Structure of the Codebase**. Identify which one you have received before proceeding.
- If you received Codebase High Level Summary, use it as a navigation map to locate the relevant components for the user query, in the codebase, but the actual source must be read separately when needed.
- Codebase High Level Summary lists, for each Ballerina file, all of its components (imports, configurables, variables, types, functions, services, listeners, classes) with their signatures and line ranges, but excludes implementation bodies, test files, and resource files.
- If you receive complete structure of the codebase, it contains the complete source of all .bal files (test and resource files excluded) provided directly in your context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test files were included i guess.
please verify

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we are not including the test files.

FILE_WRITE_TOOL_NAME,
].join(
", "
)} tools. The complete existing source code will be provided in the <existing_code> section of the user prompt.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have this <existing_code> section?

Comment on lines +199 to +203
if (!this.config.chatStorage) {
console.log('[AICommandExecutor] Chat storage not configured, skipping initialization');
return;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inner if (!this.config.chatStorage) is unreachable right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

);

// ==================================
// bal.md Generation for Agent Context

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we use CodeMap


### Local Connectors
- If the codebase structure shows connector modules in generated/moduleName, import using: import packageName.moduleName
- Generated connector files appear under a \`<generated_files>\` block in the codebase structure as path-only entries (e.g. \`<file path="generated/moduleName/client.bal"/>\`) — no source content is included. Use the \`${FILE_READ_TOOL_NAME}\` tool with the listed path to fetch the content when needed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<generated_files> is invalid for codemap case right?

Comment on lines +32 to +40
const DEFAULT_GLOB_ARGS = [
"--glob", "*.bal",
"--glob", "*.toml",
"--glob", "*.md",
"--glob", "*.json",
"--glob", "*.yaml",
"--glob", "*.yml",
"--glob", "*.sql",
];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it's better to mention the supported types to the agent. instead of silently ignores other type searches.
Maybe we can add a line to the tool description listing the file types we search by default, so the model knows.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

}

/** Paths and files always excluded from search */
const EXCLUDE_GLOB_ARGS = ["--glob", "!.git/**", "--glob", "!target/**"];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing Config.toml

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the glob tool, we do not search within the files, and there is no need to ignore them since the tool returns file paths rather than file content.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we can better to avoid the path too.
optional :)

@yasithrashan yasithrashan marked this pull request as draft May 29, 2026 08:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants