Commit graph

6103 commits

Author SHA1 Message Date
ali
ec97ebd4e7
more cleanup 2026-01-28 22:23:54 +02:00
ali
31091350c9
cleanup 2026-01-28 22:19:40 +02:00
ali
dcac02b3f2
abstraction 2026-01-28 21:53:51 +02:00
ali
373d4c6574
Merge branch 'main' of github.com:codeflash-ai/codeflash-internal into multi-language 2026-01-28 20:47:57 +02:00
mashraf-222
d9a8aa8811
enhance LLM response view & adding ranker details in observability (#2326)
<img width="1755" height="1017" alt="image"
src="https://github.com/user-attachments/assets/9d398362-48b0-45b3-82a7-acf1174f1684"
/>
<img width="1901" height="1043" alt="image"
src="https://github.com/user-attachments/assets/a3ea7ef4-4b62-4f72-874e-80b28d513b8d"
/>

---------

Co-authored-by: Codeflash Bot <bot@codeflash.ai>
Co-authored-by: Kevin Turcios <106575910+KRRT7@users.noreply.github.com>
2026-01-28 13:20:00 -05:00
HeshamHM28
f909642ce1
feat: Add Line Profiler visualization to webapp (#2268)
## Summary
Adds a line-by-line performance profiler visualization to the webapp,
allowing users to compare execution times between original and optimized
code.

  ## Changes

  ### New Line Profiler View
- **`LineProfilerView.tsx`**: Side-by-side comparison component showing:
    - Line-by-line execution times with heat map visualization
    - Syntax highlighting using `prism-react-renderer`
    - Collapsible function blocks
    - Light/dark mode support
    - Heat legend (cold → hot based on % time)

- **`lineProfilerParser.ts`**: Parser utilities for line profiler data:
- `parseLineProfilerResults()` - parses markdown table output from
Python's line_profiler
- `formatTime()` - converts timer units to human-readable format (ns,
µs, ms, s)
    - `getHeatLevel()` - determines heat coloring based on % time

- **`/review-optimizations/[traceId]/profiler/page.tsx`**: New route for
the profiler view

  ### API Changes
- **`create-pr.ts`**: Adds "📊 Performance Profile" link to PR
description when profiler data exists
- **`github-app.ts`**: Removes line profiler data from metadata when PR
is closed/merged
- **`create-staging.ts`**, **`suggest-pr-changes.ts`**: Handle line
profiler data in staging
- **`staging-storage-strategy.ts`**: Interface updates for line profiler
fields

  ### Webapp Integration
- **`page.tsx`**: Added "Performance Profile" button (only visible when
profiler data exists)
- **`action.ts`**: Sends line profiler data when creating PR from webapp
  Fixes CF-1018
  


https://codeflash-ai.slack.com/files/U08MSR1UN6L/F0A9YVDJY75/screen_recording_2026-01-21_at_10.03.18___pm.mov
https://github.com/HeshamHM28/my-best-repo/pull/21

linked to https://github.com/codeflash-ai/codeflash/pull/1139

---------

Co-authored-by: Aseem Saxena <aseem.bits@gmail.com>
2026-01-28 08:36:54 -08:00
Kevin Turcios
5ab169076c
Merge branch 'main' into multi-language 2026-01-28 08:19:52 -05:00
Kevin Turcios
8a66c78220
refactor: consolidate CST utilities and simplify add_missing_imports (#2324)
## Summary
- Consolidate shared CST utilities into `aiservice/common/cst_utils.py`
- Simplify `add_missing_imports` by removing redundant abstractions
- Require CST modules instead of strings in postprocessing pipeline
2026-01-28 08:05:45 -05:00
ali
d7e7125220
Merge branch 'multi-language' of github.com:codeflash-ai/codeflash-internal into multi-language 2026-01-28 13:41:55 +02:00
ali
557fb11939
remove jest globals check (client handles it now) 2026-01-28 13:41:06 +02:00
misrasaurabh1
b0a1d6c09f Remove instrumentation of js tests from aiservice and into client 2026-01-27 16:10:35 -08:00
ali
39de6a3bce
Merge branch 'multi-language' of github.com:codeflash-ai/codeflash-internal into multi-language 2026-01-27 23:30:11 +02:00
ali
72cb589948
some instrumentation fixes 2026-01-27 23:30:03 +02:00
mohammed ahmed
0c9cc6afe4
Merge branch 'main' into multi-language 2026-01-27 19:44:57 +02:00
snyk-io[bot]
f7f3e7f0bd
[Snyk] Security upgrade diff from 8.0.2 to 8.0.3 (#2305)
![snyk-top-banner](https://res.cloudinary.com/snyk/image/upload/r-d/scm-platform/snyk-pull-requests/pr-banner-default.svg)

### Snyk has created this PR to fix 1 vulnerabilities in the npm
dependencies of this project.

#### Snyk changed the following file(s):

- `js/VSC-Extension/package.json`




#### Vulnerabilities that will be fixed with an upgrade:

|  | Issue | Score | 

:-------------------------:|:-------------------------|:-------------------------
![medium
severity](https://res.cloudinary.com/snyk/image/upload/w_20,h_20/v1561977819/icon/m.png
'medium severity') | Regular Expression Denial of Service (ReDoS)
<br/>[SNYK-JS-DIFF-14917201](https://snyk.io/vuln/SNYK-JS-DIFF-14917201)
| &nbsp;&nbsp;**708**&nbsp;&nbsp;




---

> [!IMPORTANT]
>
> - Check the changes in this PR to ensure they won't cause issues with
your project.
> - Max score is 1000. Note that the real score may have changed since
the PR was raised.
> - This PR was automatically created by Snyk using the credentials of a
real user.

---

**Note:** _You are seeing this because you or someone else with access
to this repository has authorized Snyk to open fix PRs._

For more information: <img
src="https://api.segment.io/v1/pixel/track?data=eyJ3cml0ZUtleSI6InJyWmxZcEdHY2RyTHZsb0lYd0dUcVg4WkFRTnNCOUEwIiwiYW5vbnltb3VzSWQiOiI1YmZkM2I3OC1iNmQ1LTRmNTYtODBhNC1iZDg4YmMzMTA4NDAiLCJldmVudCI6IlBSIHZpZXdlZCIsInByb3BlcnRpZXMiOnsicHJJZCI6IjViZmQzYjc4LWI2ZDUtNGY1Ni04MGE0LWJkODhiYzMxMDg0MCJ9fQ=="
width="0" height="0"/>
🧐 [View latest project
report](https://app.snyk.io/org/sarthak-aNe3RTvxtiDtBRn3AkWpLk/project/9d3b7f4a-fb81-42ff-ac9e-3cf1a6bff233?utm_source&#x3D;github-cloud-app&amp;utm_medium&#x3D;referral&amp;page&#x3D;fix-pr)
📜 [Customise PR
templates](https://docs.snyk.io/scan-using-snyk/pull-requests/snyk-fix-pull-or-merge-requests/customize-pr-templates?utm_source=github-cloud-app&utm_content=fix-pr-template)
🛠 [Adjust project
settings](https://app.snyk.io/org/sarthak-aNe3RTvxtiDtBRn3AkWpLk/project/9d3b7f4a-fb81-42ff-ac9e-3cf1a6bff233?utm_source&#x3D;github-cloud-app&amp;utm_medium&#x3D;referral&amp;page&#x3D;fix-pr/settings)
📚 [Read about Snyk's upgrade
logic](https://docs.snyk.io/scan-with-snyk/snyk-open-source/manage-vulnerabilities/upgrade-package-versions-to-fix-vulnerabilities?utm_source=github-cloud-app&utm_content=fix-pr-template)

---

**Learn how to fix vulnerabilities with free interactive lessons:**

🦉 [Regular Expression Denial of Service
(ReDoS)](https://learn.snyk.io/lesson/redos/?loc&#x3D;fix-pr)

[//]: #
'snyk:metadata:{"breakingChangeRiskLevel":null,"FF_showPullRequestBreakingChanges":false,"FF_showPullRequestBreakingChangesWebSearch":false,"customTemplate":{"variablesUsed":[],"fieldsUsed":[]},"dependencies":[{"name":"diff","from":"8.0.2","to":"8.0.3"}],"env":"prod","issuesToFix":["SNYK-JS-DIFF-14917201"],"prId":"5bfd3b78-b6d5-4f56-80a4-bd88bc310840","prPublicId":"5bfd3b78-b6d5-4f56-80a4-bd88bc310840","packageManager":"npm","priorityScoreList":[708],"projectPublicId":"9d3b7f4a-fb81-42ff-ac9e-3cf1a6bff233","projectUrl":"https://app.snyk.io/org/sarthak-aNe3RTvxtiDtBRn3AkWpLk/project/9d3b7f4a-fb81-42ff-ac9e-3cf1a6bff233?utm_source=github-cloud-app&utm_medium=referral&page=fix-pr","prType":"fix","templateFieldSources":{"branchName":"default","commitMessage":"default","description":"default","title":"default"},"templateVariants":["updated-fix-title","priorityScore"],"type":"auto","upgrade":["SNYK-JS-DIFF-14917201"],"vulns":["SNYK-JS-DIFF-14917201"],"patch":[],"isBreakingChange":false,"remediationStrategy":"vuln"}'

Co-authored-by: snyk-io[bot] <141718529+snyk-io[bot]@users.noreply.github.com>
2026-01-27 17:37:39 +05:30
Sarthak Agarwal
ccdebe5782
fix for cf-api route issue and process exit (#2315) 2026-01-27 17:35:48 +05:30
Kevin Turcios
1b2105e6d3
Merge branch 'main' into multi-language 2026-01-27 01:25:52 -05:00
Kevin Turcios
3fabea495f fix: install uv in fix-formatting workflow
The ty-check hook requires uv to be available. Add astral-sh/setup-uv
step before running prek.
2026-01-27 01:25:19 -05:00
Kevin Turcios
bf3890fdbf fix: use interactive mode for Claude @mentions
Remove prompt parameter from claude-mention job so Claude runs in
interactive mode and naturally receives @mention context. Move prek
formatting instructions to CLAUDE.md where Claude reads them for any
request.
2026-01-27 01:24:07 -05:00
Kevin Turcios
d26871b355
Merge branch 'main' into multi-language 2026-01-27 01:18:25 -05:00
Kevin Turcios
d80321da9f one more cc debug 2026-01-27 01:17:48 -05:00
Kevin Turcios
35e5e37f7e
Merge branch 'main' into multi-language 2026-01-27 01:08:17 -05:00
Kevin Turcios
a741523b1f debug
- Add standalone fix-formatting.yml workflow for `/fix-formatting` command
- Uses prek's native --from-ref to only format changed files
- Properly handles prek exit codes and reports errors
- Enable show_full_output in claude-mention job for debugging
2026-01-27 01:07:55 -05:00
Kevin Turcios
646a480769
Merge branch 'main' into multi-language 2026-01-27 00:57:23 -05:00
Kevin Turcios
f558f882bb Create fix-formatting.yml 2026-01-27 00:55:25 -05:00
Kevin Turcios
a22672d504 fix: improve Claude Code prompt for prek formatting fixes
Update the prompt to explicitly mention "pre-k" and "prek" triggers
and provide step-by-step instructions for running the formatter,
committing, and pushing changes.
2026-01-27 00:51:59 -05:00
Kevin Turcios
e464bcaae2
Merge branch 'main' into multi-language 2026-01-27 00:44:56 -05:00
Kevin Turcios
98b6577bc8 one more fix for CC 2026-01-27 00:43:52 -05:00
Kevin Turcios
e141c7e4fd
Merge branch 'main' into multi-language 2026-01-27 00:32:09 -05:00
codeflash-ai[bot]
238de2b9c0
️ Speed up function _safe_replace_function_calls by 101% in PR #2247 (multi-language) (#2306)
## ️ This pull request contains optimizations for PR #2247
If you approve this dependent PR, these changes will be merged into the
original PR branch `multi-language`.
>This PR will be automatically closed if the original PR is merged.
----
#### 📄 101% (1.01x) speedup for ***`_safe_replace_function_calls` in
`django/aiservice/testgen/instrumentation/javascript/instrument_javascript.py`***

⏱️ Runtime : **`4.63 milliseconds`** **→** **`2.30 milliseconds`** (best
of `5` runs)

#### 📝 Explanation and details


This optimization achieves a **101% speedup** (reducing runtime from
4.63ms to 2.30ms) through three key performance improvements:

**1. Pre-compiled regex pattern (primary speedup driver)**
The original code calls `re.match(pattern, remaining)` inside the main
loop, which recompiles the pattern on every iteration. The line profiler
shows this operation took 3.92 seconds (33.1% of total time). The
optimized version compiles the pattern once upfront (`pattern_re =
re.compile(pattern)`) and reuses it via `pattern_re.match(source, i)`,
reducing this to 1.10 seconds (10% of total time) - a **72% reduction**
in pattern matching overhead.

**2. Eliminated substring creation for pattern matching**
The original creates a new substring `remaining = source[i:]` on every
loop iteration (5.68e8 ns, 4.8% of time). The optimized version uses
`pattern_re.match(source, i)` which matches directly from position `i`
without creating intermediate strings. This saves both allocation and
copying costs, particularly impactful given the loop runs 1.3-1.8
million times per execution.

**3. Fast-forward through comments using `str.find()`**
- **Single-line comments**: Changed from character-by-character loop
(`while i < length and source[i] != "\n"`) to `source.find("\n", i)`,
eliminating repeated indexing operations
- **Multi-line comments**: Changed from character-by-character scanning
to `source.find("*/", i)`, directly jumping to comment end

**Test case analysis:**
The optimization particularly excels on:
- **Large-scale scenarios**: The 500-iteration test shows 125% speedup
(1.24ms → 549μs), demonstrating excellent scalability
- **Comment-heavy code**: Tests with comments show 17-65% speedups as
`str.find()` efficiently skips entire comment blocks
- **Method call filtering**: Tests with `.foo()` patterns show 53-75%
speedups from reduced pattern matching overhead

All 45 test cases pass with improved or comparable performance,
validating that the optimization preserves correctness while delivering
consistent runtime improvements across diverse JavaScript code patterns.



 **Correctness verification report:**

| Test                        | Status            |
| --------------------------- | ----------------- |
| ⚙️ Existing Unit Tests | 🔘 **None Found** |
| 🌀 Generated Regression Tests |  **59 Passed** |
|  Replay Tests | 🔘 **None Found** |
| 🔎 Concolic Coverage Tests | 🔘 **None Found** |
|📊 Tests Coverage       | 100.0% |
<details>
<summary>🌀 Click to see Generated Regression Tests</summary>

```python
from __future__ import annotations

# imports
import re
from collections.abc import Callable

import pytest  # used for our unit tests

from testgen.instrumentation.javascript.instrument_javascript import (
    _safe_replace_function_calls,
)

# unit tests


# Helper replacement function used in many tests: wraps the matched call
def _wrap_with_capture(match: re.Match[str]) -> str:
    # return a wrapper that includes the exact matched text
    return f"codeflash.capture({match.group(0)})"


def test_basic_single_replacement():
    # Basic scenario: a single top-level function call should be replaced.
    src = "var x = foo(1);"
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 12.5μs -> 9.73μs (28.9% faster)


def test_string_literals_not_replaced():
    # Strings containing the function call should be left alone.
    src = "var s = 'foo(1)'; foo(2);"
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 14.5μs -> 10.5μs (38.5% faster)


def test_double_quoted_and_escaped_strings():
    # Double-quoted strings with escaped quotes should be preserved.
    src = 'var s = "he said \\"foo(3)\\""; foo(4);'
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 15.7μs -> 11.5μs (36.0% faster)


def test_template_literals_with_expressions_skipped():
    # Template literals should preserve content and skip replacement inside ${...}.
    src = "`start ${ { nested: foo(5) } } end` foo(6);"
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 12.8μs -> 12.0μs (6.23% faster)


def test_single_line_comment_skipped():
    # Calls inside single-line comments should not be replaced.
    src = " // foo(7)\nfoo(8);"
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 9.40μs -> 8.02μs (17.1% faster)


def test_multi_line_comment_skipped_and_unclosed_comment_handled():
    # Multi-line comments containing calls should be preserved.
    src = "/* comment foo(9) */ foo(10);"
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 9.87μs -> 8.17μs (20.9% faster)

    # Unclosed multi-line comment at EOF should not hang or replace inside it
    src_unclosed = "/* unclosed foo(11)"
    codeflash_output = _safe_replace_function_calls(
        src_unclosed, "foo", _wrap_with_capture, pattern
    )
    res_unclosed = codeflash_output  # 3.26μs -> 1.97μs (65.2% faster)


def test_method_call_dot_not_replaced():
    # Calls that are methods (preceded by a dot) should not be replaced.
    src = "obj.foo(12); foo(13);"
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 14.8μs -> 9.49μs (55.6% faster)


def test_already_wrapped_skipped():
    # If 'codeflash.capture' immediately precedes the call start index, replacement should be skipped.
    # This tests the specific check in the function that avoids double-wrapping.
    src = "codeflash.capturefoo(14);"
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 19.9μs -> 11.3μs (75.4% faster)


def test_template_literal_with_escaped_backticks_and_expressions():
    # Template literal containing escaped backticks and ${...} should be handled correctly.
    src = r"`backtick \` and ${ { foo: foo(15) } } end` foo(16);"
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 14.2μs -> 12.8μs (11.1% faster)


def test_overlapping_names_handling():
    # When function name appears adjacent to other letters like 'foofoo(17)',
    # ensure inner call is still found at the correct position.
    src = "foofoo(17); foo(18);"
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 11.3μs -> 7.92μs (43.2% faster)


def test_escaped_characters_in_regular_strings_do_not_break_scanning():
    # Strings that include escaped backslashes and escaped quotes should not break the scanner.
    src = '"line1\\nfoo(19)\\nline2" foo(20);'
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 10.9μs -> 9.15μs (19.1% faster)


def test_large_scale_multiple_replacements():
    # Large-scale test: many occurrences (but below 1000) to assess scalability.
    count = 500  # keep below 1000 as per instructions
    src_parts = [f"foo({i});" for i in range(count)]
    src = " ".join(src_parts)
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 1.24ms -> 549μs (125% faster)
    # Ensure that every occurrence was wrapped exactly once.
    wrapped_count = res.count("codeflash.capture(")


def test_no_false_positive_when_preceded_by_other_chars():
    # If the character before the function is not a dot but some other char, replacement should proceed.
    src = "afoo(21); .foo(22);"
    pattern = r"foo\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 13.3μs -> 8.96μs (48.5% faster)


def test_pattern_that_matches_functions_with_spaces():
    # Pattern that allows spaces before the opening parenthesis.
    src = "foo (23); foo(24);"
    pattern = r"foo\s*\([^\)]*\)"
    codeflash_output = _safe_replace_function_calls(
        src, "foo", _wrap_with_capture, pattern
    )
    res = codeflash_output  # 10.1μs -> 7.71μs (30.6% faster)


# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

```

```python
import re
from collections.abc import Callable

# imports
import pytest

from testgen.instrumentation.javascript.instrument_javascript import (
    _safe_replace_function_calls,
)


class TestBasicFunctionality:
    """Test cases for basic functionality of _safe_replace_function_calls."""

    def test_simple_function_call_replacement(self):
        """Test replacing a simple function call with a basic pattern."""
        source = "foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "bar()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 5.38μs -> 5.00μs (7.58% faster)

    def test_function_call_with_arguments(self):
        """Test replacing function calls that have arguments."""
        source = "foo(x, y)"
        pattern = r"foo\([^)]*\)"
        replace_func = lambda m: "bar(x, y)"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 5.25μs -> 4.74μs (10.7% faster)

    def test_multiple_function_calls(self):
        """Test replacing multiple occurrences of the same function."""
        source = "foo(); foo(); foo();"
        pattern = r"foo\(\)"
        call_count = [0]

        def replace_func(m):
            call_count[0] += 1
            return f"replaced_{call_count[0]}()"

        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 12.2μs -> 8.70μs (40.3% faster)

    def test_empty_source(self):
        """Test with an empty source string."""
        source = ""
        pattern = r"foo\(\)"
        replace_func = lambda m: "bar()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 853ns -> 2.04μs (58.1% slower)

    def test_no_matches(self):
        """Test when no function calls match the pattern."""
        source = "let x = 5; y = 10;"
        pattern = r"foo\(\)"
        replace_func = lambda m: "bar()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 14.3μs -> 7.73μs (84.8% faster)

    def test_function_call_in_middle_of_code(self):
        """Test replacing function call in the middle of other code."""
        source = "let result = foo(); console.log(result);"
        pattern = r"foo\(\)"
        replace_func = lambda m: "bar()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 24.9μs -> 12.9μs (92.5% faster)

    def test_preserve_whitespace(self):
        """Test that whitespace around function calls is preserved."""
        source = "foo(  )  "
        pattern = r"foo\(\s*\)"
        replace_func = lambda m: "bar()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 6.61μs -> 5.85μs (12.8% faster)

    def test_function_call_in_single_quoted_string(self):
        """Test that function calls inside single-quoted strings are NOT replaced."""
        source = "'foo()' bar()"
        pattern = r"foo\(\)|bar\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 7.49μs -> 7.27μs (3.07% faster)

    def test_function_call_in_double_quoted_string(self):
        """Test that function calls inside double-quoted strings are NOT replaced."""
        source = '"foo()" bar()'
        pattern = r"foo\(\)|bar\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 7.22μs -> 6.47μs (11.5% faster)

    def test_function_call_in_single_line_comment(self):
        """Test that function calls in single-line comments are NOT replaced."""
        source = "// foo() should not be replaced\nbar()"
        pattern = r"foo\(\)|bar\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 9.27μs -> 6.86μs (35.0% faster)

    def test_function_call_in_multiline_comment(self):
        """Test that function calls in multi-line comments are NOT replaced."""
        source = "/* foo() should not be replaced */ bar()"
        pattern = r"foo\(\)|bar\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 10.00μs -> 7.47μs (33.7% faster)


class TestEdgeCases:
    """Test cases for edge cases and unusual conditions."""

    def test_escaped_quote_in_string(self):
        """Test handling of escaped quotes inside strings."""
        source = r"'foo\'s bar' foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 7.99μs -> 7.41μs (7.81% faster)

    def test_escaped_backslash_in_string(self):
        """Test handling of escaped backslashes in strings."""
        source = r"'path\\to\\file' foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 8.41μs -> 7.76μs (8.36% faster)

    def test_method_call_not_replaced(self):
        """Test that method calls (preceded by dot) are NOT replaced."""
        source = "obj.foo() + foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "bar()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 12.9μs -> 8.37μs (53.6% faster)

    def test_template_literal_simple(self):
        """Test handling of simple template literals."""
        source = "`foo()` bar()"
        pattern = r"foo\(\)|bar\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 7.53μs -> 6.86μs (9.73% faster)

    def test_template_literal_with_expression(self):
        """Test handling of template literals with embedded expressions."""
        source = "`Value: ${foo()}` bar()"
        pattern = r"foo\(\)|bar\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 9.50μs -> 9.01μs (5.51% faster)

    def test_template_literal_with_nested_braces(self):
        """Test handling of template literals with nested braces in expressions."""
        source = "`${obj.map(x => ({value: x}))}` foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 10.5μs -> 10.2μs (2.83% faster)

    def test_codeflash_capture_already_wrapped(self):
        """Test that already wrapped codeflash.capture calls are not double-wrapped."""
        source = "codeflash.capture(foo())"
        pattern = r"foo\(\)"
        replace_func = lambda m: "bar()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 16.9μs -> 10.5μs (60.3% faster)

    def test_nested_quotes_in_string(self):
        """Test handling of different quote types inside strings."""
        source = """'string with "quotes"' foo()"""
        pattern = r"foo\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 8.46μs -> 8.08μs (4.66% faster)

    def test_multiline_comment_not_closed(self):
        """Test handling of multi-line comment that extends to end of source."""
        source = "foo() /* comment starts here"
        pattern = r"foo\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 9.20μs -> 6.59μs (39.5% faster)

    def test_function_call_at_end_of_source(self):
        """Test function call replacement at the very end of source."""
        source = "foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "bar()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 4.28μs -> 4.24μs (0.730% faster)

    def test_adjacent_strings(self):
        """Test handling of adjacent string literals."""
        source = "'foo()' \"foo()\" foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 9.13μs -> 8.05μs (13.4% faster)

    def test_comment_after_function_call(self):
        """Test function call followed by a comment."""
        source = "foo() // this is foo\nbar()"
        pattern = r"foo\(\)|bar\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 10.5μs -> 8.23μs (27.1% faster)

    def test_escaped_character_in_comment(self):
        """Test comment handling with special characters."""
        source = "foo() // comment with \\ backslash\nbar()"
        pattern = r"foo\(\)|bar\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 11.4μs -> 8.42μs (35.6% faster)

    def test_regex_special_chars_in_string(self):
        """Test strings containing regex special characters."""
        source = r"'[a-z].*+?' foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 7.29μs -> 6.70μs (8.80% faster)

    def test_single_char_string(self):
        """Test handling of single character strings."""
        source = "'' 'a' foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 7.62μs -> 6.79μs (12.2% faster)

    def test_consecutive_escaped_quotes(self):
        """Test multiple consecutive escaped quotes."""
        source = r"'\"\"' foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 6.92μs -> 6.09μs (13.5% faster)

    def test_template_literal_escaped_backtick(self):
        """Test template literal with escaped backtick."""
        source = r"`escaped \` backtick` foo()"
        pattern = r"foo\(\)"
        replace_func = lambda m: "replaced()"
        codeflash_output = _safe_replace_function_calls(
            source, "foo", replace_func, pattern
        )
        result = codeflash_output  # 9.10μs -> 8.80μs (3.43% faster)

```

</details>


To edit these changes `git checkout
codeflash/optimize-pr2247-2026-01-25T08.38.25` and push.


[![Codeflash](https://img.shields.io/badge/Optimized%20with-Codeflash-yellow?style=flat&color=%23ffc428&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgwIiBoZWlnaHQ9ImF1dG8iIHZpZXdCb3g9IjAgMCA0ODAgMjgwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTI4Ni43IDAuMzc4NDE4SDIwMS43NTFMNTAuOTAxIDE0OC45MTFIMTM1Ljg1MUwwLjk2MDkzOCAyODEuOTk5SDk1LjQzNTJMMjgyLjMyNCA4OS45NjE2SDE5Ni4zNDVMMjg2LjcgMC4zNzg0MThaIiBmaWxsPSIjRkZDMDQzIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzExLjYwNyAwLjM3ODkwNkwyNTguNTc4IDU0Ljk1MjZIMzc5LjU2N0w0MzIuMzM5IDAuMzc4OTA2SDMxMS42MDdaIiBmaWxsPSIjMEIwQTBBIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzA5LjU0NyA4OS45NjAxTDI1Ni41MTggMTQ0LjI3NkgzNzcuNTA2TDQzMC4wMjEgODkuNzAyNkgzMDkuNTQ3Vjg5Ljk2MDFaIiBmaWxsPSIjMEIwQTBBIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMjQyLjg3MyAxNjQuNjZMMTg5Ljg0NCAyMTkuMjM0SDMxMC44MzNMMzYzLjM0NyAxNjQuNjZIMjQyLjg3M1oiIGZpbGw9IiMwQjBBMEEiLz4KPC9zdmc+Cg==)](https://codeflash.ai)
![Static
Badge](https://img.shields.io/badge/🎯_Optimization_Quality-high-green)

Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com>
Co-authored-by: Kevin Turcios <106575910+KRRT7@users.noreply.github.com>
2026-01-27 00:28:03 -05:00
Kevin Turcios
596c07709c add prompt for pre-commit related and perms changes 2026-01-27 00:25:12 -05:00
codeflash-ai[bot]
64b0bb74e0
️ Speed up function _has_test_functions by 18% in PR #2247 (multi-language) (#2308)
## ️ This pull request contains optimizations for PR #2247
If you approve this dependent PR, these changes will be merged into the
original PR branch `multi-language`.
>This PR will be automatically closed if the original PR is merged.
----
#### 📄 18% (0.18x) speedup for ***`_has_test_functions` in
`django/aiservice/testgen/testgen_javascript.py`***

⏱️ Runtime : **`740 microseconds`** **→** **`627 microseconds`** (best
of `76` runs)

#### 📝 Explanation and details


The optimized code achieves an **18% runtime improvement** by
eliminating repeated regex compilation overhead.

**Key optimization:**
- **Precompiled regex pattern**: The pattern
`r"(?:test|it)\s*\(\s*['\"]"` is compiled once at module load time into
`_TEST_FUNC_RE`, rather than being recompiled on every function call. In
Python, `re.search()` with a raw string pattern incurs compilation cost
each time it's invoked.

**Performance breakdown from line profiler:**
- Original: 2.70ms spent in `re.search(test_pattern, code)` (96.5% of
total time)
- Optimized: 862μs for the direct pattern search (100% of total time,
but 3.1x faster overall)
- The pattern string assignment overhead (97μs in original) is
eliminated entirely

**Why this matters for the workload:**
Based on `function_references`, this function is called from
`parse_and_validate_js_output()` during LLM response validation. This is
a **hot path** operation that executes on every test generation request.
The validation flow checks multiple conditions including syntax
validation before checking for test functions, meaning this function
runs repeatedly during normal operations.

**Test case performance:**
- **Small inputs** (single test functions): 50-80% faster (e.g., 2.80μs
→ 1.83μs)
- **Empty/minimal strings**: 130-140% faster (e.g., 1.80μs → 750ns) 
- **Large inputs** (500-1000 lines): 1-8% faster depending on match
location
- **Early matches** benefit most since regex short-circuits on first
match

The optimization is most effective when processing typical-sized
JavaScript test code (dozens to hundreds of lines), which aligns with
the common use case of validating LLM-generated test functions.



 **Correctness verification report:**

| Test                        | Status            |
| --------------------------- | ----------------- |
| ⚙️ Existing Unit Tests | 🔘 **None Found** |
| 🌀 Generated Regression Tests |  **102 Passed** |
|  Replay Tests | 🔘 **None Found** |
| 🔎 Concolic Coverage Tests | 🔘 **None Found** |
|📊 Tests Coverage       | 100.0% |
<details>
<summary>🌀 Click to see Generated Regression Tests</summary>

```python
from __future__ import annotations

import re

# imports
import pytest  # used for our unit tests

from testgen.testgen_javascript import _has_test_functions


def test_basic_test_call_double_quotes():
    # Basic: a standard Jest test call using double quotes should be detected.
    code = 'test("my test name", () => { expect(true).toBe(true); });'
    codeflash_output = _has_test_functions(code)  # 2.83μs -> 1.78μs (59.3% faster)


def test_basic_it_call_single_quotes():
    # Basic: a standard it() call using single quotes should be detected.
    code = "it('does something', function() { /* ... */ });"
    codeflash_output = _has_test_functions(code)  # 2.80μs -> 1.83μs (53.0% faster)


def test_whitespace_and_newlines_between_name_and_paren():
    # Edge: whitespace/newlines between the function name and '(' and between '(' and the quote
    # The regex allows arbitrary whitespace, so this should still match.
    code = "it   \n (\n  'handles newlines'\n )"
    codeflash_output = _has_test_functions(code)  # 2.90μs -> 1.89μs (53.2% faster)


def test_empty_string_returns_false():
    # Edge: empty input must return False (no tests found).
    code = ""
    codeflash_output = _has_test_functions(code)  # 1.80μs -> 750ns (139% faster)


def test_uppercase_function_name_not_matched():
    # Edge: the regex is case-sensitive; 'Test' should NOT match.
    code = "Test('capitalized should not match', () => {});"
    codeflash_output = _has_test_functions(code)  # 3.20μs -> 2.23μs (43.7% faster)


def test_backtick_template_not_matched():
    # Edge: template literals use backticks; pattern looks only for single/double quotes.
    code = "test(`template literal name`, () => {});"
    codeflash_output = _has_test_functions(code)  # 3.34μs -> 2.27μs (47.0% faster)


def test_numeric_first_arg_not_matched():
    # Edge: if the first argument is not a quoted string (e.g., a number), pattern should not match.
    code = "test(123, () => {});"
    codeflash_output = _has_test_functions(code)  # 3.01μs -> 1.86μs (61.7% faster)


def test_test_call_inside_comment_still_matches():
    # Important behavioral note: the function does not ignore comments.
    # A 'test(' occurrence inside a JS comment still matches because the function only does regex search.
    code = "// test('in a single-line comment')\n/* test(\"in block comment\") */"
    # Both comment forms contain test('...') / test("...") which the regex will find.
    codeflash_output = _has_test_functions(code)  # 2.96μs -> 1.84μs (61.1% faster)


def test_substring_in_identifier_matches():
    # The regex is permissive and will match occurrences where 'test' or 'it' appear as suffixes
    # of other identifiers (e.g., 'latesttest(' or 'split('). This test documents that behavior.
    code_latest = "function latesttest(){}\nlatesttest('x')"
    code_split = "const arr = ['a']; arr.split('a');"
    # Both contain the substring "test('..." or "it('...", so they should be considered matches by the implementation.
    codeflash_output = _has_test_functions(
        code_latest
    )  # 3.77μs -> 2.59μs (45.5% faster)
    codeflash_output = _has_test_functions(code_split)  # 1.16μs -> 793ns (46.7% faster)


def test_comment_between_paren_blocks_prevents_match():
    # If there is a non-whitespace token (like a block comment) between '(' and the starting quote,
    # the current regex will not match because it expects only whitespace between '(' and the quote.
    code = "test(/* important note */ 'name in comment')"
    codeflash_output = _has_test_functions(code)  # 3.31μs -> 2.30μs (43.5% faster)


def test_multiple_test_and_it_occurrences():
    # A file with multiple matches should still return True (boolean).
    code = """
    describe('suite', () => {
      it('first case', () => {});
      // some other code
      test("second case", () => {});
    });
    """
    codeflash_output = _has_test_functions(code)  # 3.34μs -> 2.16μs (54.9% faster)


def test_large_scale_no_match_performance():
    # Large-scale: many lines without any test/it(...) occurrences should return False.
    # Keep size under 1000 to respect constraints. We use 900 repeated lines.
    repeated = "const filler = 0;\n" * 900  # 900 lines of filler
    codeflash_output = _has_test_functions(repeated)  # 76.6μs -> 75.5μs (1.47% faster)


def test_large_scale_match_near_end():
    # Large-scale: many lines of filler followed by a single test at the end should return True.
    # This ensures the search scans through large input and finds a late occurrence.
    repeated = "const filler = 0;\n" * 900  # 900 lines of filler
    code = repeated + "  // real test follows\n  test('final case', () => {});"
    codeflash_output = _has_test_functions(code)  # 77.5μs -> 76.3μs (1.59% faster)


def test_it_with_newline_between_name_and_paren():
    # Verify that a newline immediately after 'it' and before '(' is allowed by the regex (\s* covers newline).
    code = "it\n('newline-allowed')"
    codeflash_output = _has_test_functions(code)  # 3.22μs -> 1.94μs (66.0% faster)


def test_quoted_string_with_escaped_quotes_still_matches():
    # Even if the string contains escaped quotes, the regex only checks the opening quote, so it should match.
    code = r'test("contains an escaped quote: \" here", () => {});'
    codeflash_output = _has_test_functions(code)  # 2.90μs -> 1.83μs (58.2% faster)


# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

```

```python
import re

import pytest

from testgen.testgen_javascript import _has_test_functions


def test_simple_test_function_with_single_quotes():
    """Test detection of test() function with single quotes."""
    code = "test('should work', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.78μs -> 2.29μs (65.1% faster)


def test_simple_it_function_with_single_quotes():
    """Test detection of it() function with single quotes."""
    code = "it('should work', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.10μs -> 1.99μs (56.0% faster)


def test_simple_test_function_with_double_quotes():
    """Test detection of test() function with double quotes."""
    code = 'test("should work", () => {})'
    codeflash_output = _has_test_functions(code)  # 3.07μs -> 1.89μs (62.8% faster)


def test_simple_it_function_with_double_quotes():
    """Test detection of it() function with double quotes."""
    code = 'it("should work", () => {})'
    codeflash_output = _has_test_functions(code)  # 3.13μs -> 1.86μs (68.2% faster)


def test_no_test_functions():
    """Test code without any test functions returns False."""
    code = "function myFunction() { return 42; }"
    codeflash_output = _has_test_functions(code)  # 3.08μs -> 1.85μs (66.5% faster)


def test_test_function_with_single_whitespace():
    """Test detection with single space between function name and parenthesis."""
    code = "test ('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.20μs -> 1.96μs (63.0% faster)


def test_it_function_with_single_whitespace():
    """Test detection with single space between function name and parenthesis."""
    code = "it ('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.98μs -> 1.88μs (58.5% faster)


def test_test_function_with_multiple_whitespaces():
    """Test detection with multiple spaces between function name and parenthesis."""
    code = "test   ('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.04μs -> 1.95μs (55.5% faster)


def test_it_function_with_multiple_whitespaces():
    """Test detection with multiple spaces between function name and parenthesis."""
    code = "it   ('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.06μs -> 1.89μs (62.1% faster)


def test_test_function_with_tab_character():
    """Test detection with tab character between function name and parenthesis."""
    code = "test\t('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.05μs -> 1.93μs (57.8% faster)


def test_it_function_with_tab_character():
    """Test detection with tab character between function name and parenthesis."""
    code = "it\t('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.99μs -> 1.85μs (61.6% faster)


def test_test_function_with_newline():
    """Test detection with newline between function name and parenthesis."""
    code = "test\n('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.02μs -> 1.93μs (56.5% faster)


def test_it_function_with_newline():
    """Test detection with newline between function name and parenthesis."""
    code = "it\n('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.95μs -> 1.90μs (55.4% faster)


def test_multiple_test_functions():
    """Test detection with multiple test functions in the same code."""
    code = """
    test('first test', () => {});
    it('second test', () => {});
    """
    codeflash_output = _has_test_functions(code)  # 3.12μs -> 1.92μs (62.3% faster)


def test_test_function_in_multiline_code():
    """Test detection of test function within multiline code."""
    code = """
    const helper = () => {};
    test('actual test', () => {});
    const another = () => {};
    """
    codeflash_output = _has_test_functions(code)  # 3.19μs -> 2.12μs (50.1% faster)


def test_it_function_in_multiline_code():
    """Test detection of it function within multiline code."""
    code = """
    const helper = () => {};
    it('actual test', () => {});
    const another = () => {};
    """
    codeflash_output = _has_test_functions(code)  # 3.46μs -> 2.23μs (55.1% faster)


def test_test_word_in_comment_not_matched():
    """Test that test() in comments is still detected by regex (no comment parsing)."""
    code = "// test('in comment', () => {})"
    # Note: The function uses regex without comment awareness, so it will match
    codeflash_output = _has_test_functions(code)  # 3.10μs -> 1.94μs (60.2% faster)


def test_test_word_in_string_variable():
    """Test that test word in string variable doesn't match pattern."""
    code = 'const description = "this is a test of something";'
    codeflash_output = _has_test_functions(code)  # 3.56μs -> 2.29μs (55.3% faster)


def test_test_as_variable_name_not_matched():
    """Test that 'test' as variable name doesn't match without parenthesis."""
    code = "const test = 5;"
    codeflash_output = _has_test_functions(code)  # 3.11μs -> 2.03μs (53.1% faster)


def test_testing_as_word_not_matched():
    """Test that 'testing' word doesn't match."""
    code = "const testing = 'some value';"
    codeflash_output = _has_test_functions(code)  # 3.17μs -> 2.04μs (55.4% faster)


def test_it_as_pronoun_not_matched():
    """Test that 'it' as pronoun doesn't match without proper pattern."""
    code = "// it is a good day"
    codeflash_output = _has_test_functions(code)  # 3.15μs -> 1.98μs (59.1% faster)


def test_it_as_variable_not_matched():
    """Test that 'it' as variable name doesn't match without parenthesis."""
    code = "const it = 5;"
    codeflash_output = _has_test_functions(code)  # 3.13μs -> 1.92μs (63.7% faster)


def test_empty_string():
    """Test with empty string input."""
    codeflash_output = _has_test_functions("")  # 1.74μs -> 757ns (129% faster)


def test_only_whitespace():
    """Test with only whitespace."""
    codeflash_output = _has_test_functions("   \n\t  ")  # 2.05μs -> 890ns (131% faster)


def test_test_function_with_special_test_name():
    """Test detection with special characters in test name."""
    code = "test('test-name_123!@#', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.95μs -> 1.90μs (55.1% faster)


def test_it_function_with_special_test_name():
    """Test detection with special characters in test name."""
    code = "it('it-name_123!@#', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.04μs -> 1.88μs (62.0% faster)


def test_test_function_with_empty_string_name():
    """Test detection with empty string as test name."""
    code = "test('', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.90μs -> 1.84μs (58.0% faster)


def test_it_function_with_empty_string_name():
    """Test detection with empty string as test name."""
    code = "it('', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.97μs -> 1.86μs (59.7% faster)


def test_test_with_carriage_return():
    """Test detection with carriage return character."""
    code = "test\r('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.02μs -> 1.89μs (60.2% faster)


def test_it_with_carriage_return():
    """Test detection with carriage return character."""
    code = "it\r('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.12μs -> 1.91μs (63.8% faster)


def test_test_with_form_feed():
    """Test detection with form feed character."""
    code = "test\f('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.98μs -> 1.85μs (60.7% faster)


def test_it_with_form_feed():
    """Test detection with form feed character."""
    code = "it\f('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.13μs -> 1.91μs (64.4% faster)


def test_test_with_vertical_tab():
    """Test detection with vertical tab character."""
    code = "test\v('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.08μs -> 1.87μs (65.0% faster)


def test_it_with_vertical_tab():
    """Test detection with vertical tab character."""
    code = "it\v('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.13μs -> 1.83μs (71.4% faster)


def test_test_with_non_breaking_space():
    """Test that non-breaking space might not work depending on whitespace regex."""
    code = "test\u00a0('my test', () => {})"
    # Non-breaking space might not be treated as \s in regex
    codeflash_output = _has_test_functions(code)
    result = codeflash_output  # 3.25μs -> 2.07μs (56.6% faster)


def test_test_with_zero_width_space():
    """Test with zero-width space."""
    code = "test\u200b('my test', () => {})"
    codeflash_output = _has_test_functions(code)
    result = codeflash_output  # 3.82μs -> 2.74μs (39.4% faster)


def test_only_test_keyword():
    """Test with only the word 'test' without parenthesis."""
    code = "test"
    codeflash_output = _has_test_functions(code)  # 2.85μs -> 1.83μs (55.3% faster)


def test_only_it_keyword():
    """Test with only the word 'it' without parenthesis."""
    code = "it"
    codeflash_output = _has_test_functions(code)  # 1.89μs -> 793ns (138% faster)


def test_test_with_parenthesis_but_no_quote():
    """Test function call without string argument."""
    code = "test(variable)"
    codeflash_output = _has_test_functions(code)  # 3.39μs -> 2.12μs (59.8% faster)


def test_it_with_parenthesis_but_no_quote():
    """Test it function call without string argument."""
    code = "it(variable)"
    codeflash_output = _has_test_functions(code)  # 3.24μs -> 2.07μs (56.5% faster)


def test_test_followed_by_string_literal_without_parenthesis():
    """Test with string literal but missing parenthesis."""
    code = "test 'string'"
    codeflash_output = _has_test_functions(code)  # 3.17μs -> 1.93μs (64.5% faster)


def test_it_followed_by_string_literal_without_parenthesis():
    """Test with string literal but missing parenthesis."""
    code = "it 'string'"
    codeflash_output = _has_test_functions(code)  # 3.24μs -> 2.02μs (59.9% faster)


def test_test_with_backtick_quotes():
    """Test with backtick quotes (template literals)."""
    code = "test(`my test`, () => {})"
    codeflash_output = _has_test_functions(code)  # 3.49μs -> 2.34μs (49.5% faster)


def test_it_with_backtick_quotes():
    """Test it with backtick quotes (template literals)."""
    code = "it(`my test`, () => {})"
    codeflash_output = _has_test_functions(code)  # 3.38μs -> 2.23μs (51.4% faster)


def test_describe_function_not_matched():
    """Test that describe() function is not matched."""
    code = "describe('suite', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.13μs -> 1.94μs (61.2% faster)


def test_beforeEach_function_not_matched():
    """Test that beforeEach() function is not matched."""
    code = "beforeEach(() => {})"
    codeflash_output = _has_test_functions(code)  # 1.98μs -> 901ns (119% faster)


def test_afterEach_function_not_matched():
    """Test that afterEach() function is not matched."""
    code = "afterEach(() => {})"
    codeflash_output = _has_test_functions(code)  # 2.68μs -> 1.50μs (78.6% faster)


def test_test_method_on_object():
    """Test with test as method call on object."""
    code = "obj.test('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.12μs -> 1.94μs (61.4% faster)


def test_it_method_on_object():
    """Test with it as method call on object."""
    code = "obj.it('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.10μs -> 2.00μs (55.0% faster)


def test_test_substring_in_longer_identifier():
    """Test when test is part of longer identifier."""
    code = "mytest('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.00μs -> 1.90μs (58.0% faster)


def test_it_substring_in_longer_identifier():
    """Test when it is part of longer identifier."""
    code = "unit('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.07μs -> 1.94μs (58.2% faster)


def test_test_with_unicode_test_name():
    """Test detection with unicode characters in test name."""
    code = "test('\u4e2d\u6587\u6d4b\u8bd5', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.57μs -> 2.31μs (54.4% faster)


def test_it_with_unicode_test_name():
    """Test detection with unicode characters in test name."""
    code = "it('\u4e2d\u6587\u6d4b\u8bd5', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.09μs -> 2.08μs (48.8% faster)


def test_test_with_emoji():
    """Test detection with emoji in test name."""
    code = "test('\u263a emoji test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.14μs -> 2.02μs (55.2% faster)


def test_it_with_emoji():
    """Test detection with emoji in test name."""
    code = "it('\u263a emoji test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.09μs -> 2.00μs (54.0% faster)


def test_very_long_test_name():
    """Test detection with very long test name."""
    long_name = "a" * 5000
    code = f"test('{long_name}', () => {{}})"
    codeflash_output = _has_test_functions(code)  # 3.00μs -> 1.77μs (69.5% faster)


def test_very_long_code_without_tests():
    """Test with very long code but no test functions."""
    code = "const x = 1;\n" * 500
    codeflash_output = _has_test_functions(code)  # 29.7μs -> 28.5μs (4.29% faster)


def test_test_with_escaped_quote():
    """Test with escaped quote in test name."""
    code = "test('test\\'s name', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.15μs -> 2.03μs (55.2% faster)


def test_it_with_escaped_quote():
    """Test with escaped quote in test name."""
    code = "it('it\\'s name', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.97μs -> 1.87μs (59.0% faster)


def test_test_with_double_quote_in_single_quote():
    """Test with double quote inside single quoted test name."""
    code = "test('has \"double\" quotes', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.93μs -> 1.82μs (60.7% faster)


def test_it_with_double_quote_in_single_quote():
    """Test with double quote inside single quoted test name."""
    code = "it('has \"double\" quotes', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.97μs -> 1.83μs (62.6% faster)


def test_test_with_single_quote_in_double_quote():
    """Test with single quote inside double quoted test name."""
    code = "test(\"has 'single' quotes\", () => {})"
    codeflash_output = _has_test_functions(code)  # 3.00μs -> 1.90μs (57.8% faster)


def test_it_with_single_quote_in_double_quote():
    """Test with single quote inside double quoted test name."""
    code = "it(\"has 'single' quotes\", () => {})"
    codeflash_output = _has_test_functions(code)  # 2.97μs -> 1.78μs (66.7% faster)


def test_test_case_sensitive():
    """Test that TEST (uppercase) is not matched."""
    code = "TEST('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.03μs -> 1.81μs (67.1% faster)


def test_it_case_sensitive():
    """Test that IT (uppercase) is not matched."""
    code = "IT('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.81μs -> 1.84μs (52.8% faster)


def test_test_with_mixed_case():
    """Test that TeSt (mixed case) is not matched."""
    code = "TeSt('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 3.05μs -> 1.85μs (65.2% faster)


def test_it_with_mixed_case():
    """Test that It (mixed case) is not matched."""
    code = "It('my test', () => {})"
    codeflash_output = _has_test_functions(code)  # 2.94μs -> 1.91μs (54.3% faster)


def test_code_with_many_non_test_functions():
    """Test performance with many non-test functions."""
    # Build code with 500 non-test function definitions
    code_lines = [f"function func{i}() {{ return {i}; }}" for i in range(500)]
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 77.0μs -> 75.9μs (1.52% faster)


def test_code_with_many_functions_and_one_test():
    """Test detection of single test among many non-test functions."""
    # Build code with 500 non-test functions and 1 test function
    code_lines = [f"function func{i}() {{ return {i}; }}" for i in range(250)]
    code_lines.append("test('the actual test', () => {})")
    code_lines.extend(
        [f"function func{i}() {{ return {i}; }}" for i in range(250, 500)]
    )
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 40.3μs -> 38.9μs (3.41% faster)


def test_code_with_many_test_functions():
    """Test detection with many test functions."""
    # Build code with 100 test functions
    code_lines = [f"test('test {i}', () => {{}})" for i in range(100)]
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 2.94μs -> 1.74μs (69.4% faster)


def test_code_with_many_it_functions():
    """Test detection with many it functions."""
    # Build code with 100 it functions
    code_lines = [f"it('test {i}', () => {{}})" for i in range(100)]
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 2.91μs -> 1.61μs (80.4% faster)


def test_code_with_alternating_test_and_it_functions():
    """Test detection with alternating test and it functions."""
    # Build code with 100 alternating test and it functions
    code_lines = []
    for i in range(50):
        code_lines.append(f"test('test {i}', () => {{}})")
        code_lines.append(f"it('it {i}', () => {{}})")
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 2.93μs -> 1.64μs (78.7% faster)


def test_code_with_many_non_matching_similar_patterns():
    """Test performance with many similar but non-matching patterns."""
    # Build code with 500 similar patterns that don't match
    code_lines = [f"test{i}('name', () => {{}})" for i in range(500)]
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 64.3μs -> 62.9μs (2.27% faster)


def test_large_code_with_test_at_end():
    """Test detection when test function is at end of large code."""
    # Build code with 500 lines and test at the end
    code_lines = [f"const var{i} = {i};" for i in range(500)]
    code_lines.append("test('test at end', () => {})")
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 41.4μs -> 40.3μs (2.65% faster)


def test_large_code_with_it_at_end():
    """Test detection when it function is at end of large code."""
    # Build code with 500 lines and it at the end
    code_lines = [f"const var{i} = {i};" for i in range(500)]
    code_lines.append("it('it at end', () => {})")
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 41.5μs -> 40.3μs (3.00% faster)


def test_large_code_with_test_at_beginning():
    """Test detection when test function is at beginning of large code."""
    # Build code with test at beginning and 500 lines after
    code_lines = ["test('test at beginning', () => {})"]
    code_lines.extend([f"const var{i} = {i};" for i in range(500)])
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 3.09μs -> 1.90μs (62.2% faster)


def test_large_code_with_it_at_beginning():
    """Test detection when it function is at beginning of large code."""
    # Build code with it at beginning and 500 lines after
    code_lines = ["it('it at beginning', () => {})"]
    code_lines.extend([f"const var{i} = {i};" for i in range(500)])
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 3.02μs -> 1.81μs (67.1% faster)


def test_code_with_multiple_tests_scattered():
    """Test detection with multiple test functions scattered throughout large code."""
    # Build code with 20 test functions scattered among 480 non-test lines
    code_lines = []
    for i in range(500):
        if i % 25 == 0:
            code_lines.append(f"test('scattered test {i}', () => {{}})")
        else:
            code_lines.append(f"const var{i} = {i};")
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 2.86μs -> 1.79μs (59.8% faster)


def test_code_with_very_large_test_name():
    """Test performance with very long test name."""
    # Create a test with name of 10000 characters
    long_name = "x" * 10000
    code = f"test('{long_name}', () => {{}})"
    codeflash_output = _has_test_functions(code)  # 2.99μs -> 1.84μs (62.1% faster)


def test_code_with_deeply_nested_structures():
    """Test detection in deeply nested code structures."""
    # Build nested structure with test at bottom
    code = "const nested = { level1: { level2: { level3: { level4: { " * 50
    code += "test('nested test', () => {})"
    code += " } } } } };" * 50
    codeflash_output = _has_test_functions(code)  # 14.6μs -> 13.5μs (8.56% faster)


def test_code_with_many_whitespace_variations():
    """Test detection with many different whitespace patterns."""
    code_lines = []
    for i in range(100):
        if i % 4 == 0:
            code_lines.append(f"test('test {i}', () => {{}})")
        elif i % 4 == 1:
            code_lines.append(f"test ('test {i}', () => {{}})")
        elif i % 4 == 2:
            code_lines.append(f"test  ('test {i}', () => {{}})")
        else:
            code_lines.append(f"test\t('test {i}', () => {{}})")
    code = "\n".join(code_lines)
    codeflash_output = _has_test_functions(code)  # 2.92μs -> 1.71μs (70.7% faster)


def test_code_return_type_is_boolean():
    """Test that return value is always boolean regardless of input size."""
    # Various test inputs
    test_inputs = [
        "",
        "test",
        "test('name', () => {})",
        "const x = 1;" * 100,
        "test('name', () => {})" + "const x = 1;" * 100,
    ]
    for test_input in test_inputs:
        codeflash_output = _has_test_functions(test_input)
        result = codeflash_output  # 11.9μs -> 9.34μs (27.0% faster)


# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

```

</details>


To edit these changes `git checkout
codeflash/optimize-pr2247-2026-01-25T08.57.25` and push.


[![Codeflash](https://img.shields.io/badge/Optimized%20with-Codeflash-yellow?style=flat&color=%23ffc428&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDgwIiBoZWlnaHQ9ImF1dG8iIHZpZXdCb3g9IjAgMCA0ODAgMjgwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTI4Ni43IDAuMzc4NDE4SDIwMS43NTFMNTAuOTAxIDE0OC45MTFIMTM1Ljg1MUwwLjk2MDkzOCAyODEuOTk5SDk1LjQzNTJMMjgyLjMyNCA4OS45NjE2SDE5Ni4zNDVMMjg2LjcgMC4zNzg0MThaIiBmaWxsPSIjRkZDMDQzIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzExLjYwNyAwLjM3ODkwNkwyNTguNTc4IDU0Ljk1MjZIMzc5LjU2N0w0MzIuMzM5IDAuMzc4OTA2SDMxMS42MDdaIiBmaWxsPSIjMEIwQTBBIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMzA5LjU0NyA4OS45NjAxTDI1Ni41MTggMTQ0LjI3NkgzNzcuNTA2TDQzMC4wMjEgODkuNzAyNkgzMDkuNTQ3Vjg5Ljk2MDFaIiBmaWxsPSIjMEIwQTBBIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMjQyLjg3MyAxNjQuNjZMMTg5Ljg0NCAyMTkuMjM0SDMxMC44MzNMMzYzLjM0NyAxNjQuNjZIMjQyLjg3M1oiIGZpbGw9IiMwQjBBMEEiLz4KPC9zdmc+Cg==)](https://codeflash.ai)
![Static
Badge](https://img.shields.io/badge/🎯_Optimization_Quality-high-green)

Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com>
Co-authored-by: Kevin Turcios <106575910+KRRT7@users.noreply.github.com>
2026-01-27 00:14:02 -05:00
Kevin Turcios
6e530ce081
allow claude to run pre-k (#2314)
# Pull Request Checklist

## Description
- [ ] **Description of PR**: Clear and concise description of what this
PR accomplishes
- [ ] **Breaking Changes**: Document any breaking changes (if
applicable)
- [ ] **Related Issues**: Link to any related issues or tickets

## Testing
- [ ] **Test cases Attached**: All relevant test cases have been
added/updated
- [ ] **Manual Testing**: Manual testing completed for the changes

## Monitoring & Debugging
- [ ] **Logging in place**: Appropriate logging has been added for
debugging user issues
- [ ] **Sentry will be able to catch errors**: Error handling ensures
Sentry can capture and report errors
- [ ] **Avoid Dev based/Prisma logging**: No development-only or
Prisma-specific logging in production code

## Configuration
- [ ] **Env variables newly added**: Any new environment variables are
documented in .env.example file or mentioned in description
---

## Additional Notes
<!-- Add any additional context, screenshots, or notes for reviewers
here -->
2026-01-27 00:10:58 -05:00
Kevin Turcios
bf1d214ece format 2026-01-27 00:00:49 -05:00
Kevin Turcios
764a3f8899
Merge branch 'main' into multi-language 2026-01-26 23:59:03 -05:00
Kevin Turcios
0444e32f77
fix: CST tree handling and testgen pipeline improvements (#2310)
## Summary
- Fix CST tree corruption issues that caused 'NoneType' object has no
attribute 'visit' errors
- Consolidate testgen postprocessing into a single pipeline with
tuple-based pattern
- Improve markdown code extraction to prefer filepath-annotated blocks
- Add diagnostic context to optimization failure logs

## Changes
- Handle empty `SimpleStatementLine` and `StatementHandler` body to
prevent malformed CST
- Add trace_id logging to optimization and import failure paths
- Refactor testgen postprocessing into consolidated pipeline
- Fix code extraction for LLM responses with multiple code blocks

## Test plan
- [x] Added integration tests for full testgen pipeline
- [x] Added tests for markdown extraction with filepath preference
- [x] Existing tests pass

---------

Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com>
2026-01-26 23:57:55 -05:00
HeshamHM28
548fcacff7
refactor: remove roboflow repository check from suggestPrChanges and … (#2311)
## Summary
- Remove the hardcoded check that blocked PR suggestions for roboflow
repositories
- Remove the corresponding unit test that validated the roboflow
restriction
2026-01-26 17:15:45 -08:00
ali
2d7a8ad89a
Merge branch 'main' of github.com:codeflash-ai/codeflash-internal into multi-language 2026-01-26 19:57:53 +02:00
ali
580da4cc8e
fix unit tests 2026-01-26 19:57:38 +02:00
HeshamHM28
11532147ea
fix: improve review comment handling for single and multi-line changes in suggestPrChanges (#2309)
Fixes CF-967
samples https://github.com/codeflash-ai/my-best-repo/pull/461 
  ## Summary
- Fix review comment creation to properly handle single-line changes by
only
  using `line` parameter (without `start_line`)
  - Fix condition to allow single-line hunks where `oldStart === oldEnd`
  (changed from `<` to `<=`)
2026-01-26 21:20:16 +05:30
mashraf-222
80c2945d9a
Observability updates & enhancements (#2269)
# Observability Platform: UI Enhancements & Bug Fixes

## Overview
Enhances the observability UI, fixes data accuracy issues, and adds
organization filtering. Includes reusable components, performance
optimizations, and improved error handling.

---

## Fixed Issues & Enhancements

### 1. Total Traces Count Incorrect
**Problem**: Total traces count was inaccurate, especially with filters.

**Fix**: Added `getTotalTracesCount()` using `groupBy` for accurate
distinct trace counting.

**Code Changes**:
- `traces/page.tsx`: Added cached `getTotalTracesCount()` function
- Uses `groupBy` with proper filtering before counting

**How to Test**:
1. Go to `/observability/traces`
2. Check "Total Traces" stat card — should match the number of unique
traces
3. Apply organization filter — count should reflect filtered results
4. Compare with table rows — count should be accurate

---

### 2. Organization Filtering
**Problem**: No way to filter traces/LLM calls by organization.

**Fix**: Added organization filter dropdown and database-level filtering
using `IN` clause.

**Code Changes**:
- `traces/page.tsx`: Added organization filter in search form
- `llm-calls/page.tsx`: Added organization filter in filters section
- Both pages: Fetch trace IDs from `optimization_features` and use `IN`
clause for filtering
- Added `getUniqueOrganizations()` cached function

**How to Test**:
1. Go to `/observability/traces` or `/observability/llm-calls`
2. Select an organization from the dropdown
3. Verify only traces/calls for that organization are shown
4. Check that pagination works correctly with filter applied
5. Verify "Total Traces" updates when filter is applied

---

### 3. Cost Column Showing Incorrect Values
**Problem**: Cost aggregation was incorrect on traces page.

**Fix**: Use `safeCostTokens()` utility and proper aggregation logic.

**Code Changes**:
- `traces/page.tsx`: Use `safeCostTokens()` for null-safe cost/token
handling
- Proper aggregation in trace grouping logic

**How to Test**:
1. Go to `/observability/traces`
2. Check "Total Cost" stat card — should sum all trace costs correctly
3. Compare individual trace costs in table with sum
4. Verify cost displays correctly for traces with null values

---

### 4. Negative Duration Values
**Problem**: Some traces showed negative duration (e.g., "-41.81s").

**Fix**: Use `Math.min`/`Math.max` to handle out-of-order timestamps.

**Code Changes**:
- `trace/[trace_id]/page.tsx`: Calculate duration using
`Math.min`/`Math.max` on timestamps
- `traces/page.tsx`: Use `Math.max(0, ...)` to prevent negative
durations

**How to Test**:
1. Go to `/observability/trace/[any-trace-id]`
2. Check "Duration" in summary — should never be negative
3. Go to `/observability/traces`
4. Check "Duration" column — all values should be positive or zero

---

### 5. Missing Source Information
**Problem**: No indication of where LLM calls originated (GitHub Action,
CLI, etc.).

**Fix**: Added source detection and display using `getCallSource()`
utility.

**Code Changes**:
- `lib/observability-utils.ts`: Added `getCallSource()` function
- `llm-calls/page.tsx`: Added "Source" column with icons
- `trace/[trace_id]/page.tsx`: Added source in summary section
- Fetches `optimization_events` to get `event_type`

**How to Test**:
1. Go to `/observability/llm-calls`
2. Check "Source" column — should show "GitHub Action" or "CLI/VSCode"
with icons
3. Go to `/observability/trace/[trace-id]`
4. Check "Source" in summary — should display correctly

---

### 6. Partial Success Status Missing
**Problem**: No distinction between complete success and partial
success.

**Fix**: Added "Partial" status detection and display.

**Code Changes**:
- `trace/[trace_id]/page.tsx`: Check for `partial_success` status in
calls
- `llm-calls/page.tsx`: Added "Partial" option in status filter
- Both pages: Display "Partial" status with yellow/warning styling

**How to Test**:
1. Go to `/observability/traces`
2. Find traces with partial success — should show "Partial" status
(yellow)
3. Go to `/observability/llm-calls`
4. Filter by "Partial" status — should show only partial success calls
5. Check trace detail page — status should reflect partial success
correctly

---

### 7. Missing LLM Call Details Link for Candidates
**Problem**: Generated candidates didn't have links to their LLM call
details.

**Fix**: Added "View LLM Call Details" link for each candidate.

**Code Changes**:
- `trace/[trace_id]/page.tsx`: Map candidates to their LLM calls and add
link

**How to Test**:
1. Go to `/observability/trace/[trace-id]`
2. Expand "Generated Candidates" section
3. Expand any candidate
4. Verify "View LLM Call Details →" link appears at bottom
5. Click link — should navigate to LLM call detail page

---

### 8. Test Failure Details Not Shown
**Problem**: Test failures only showed error message, not detailed
failure info.

**Fix**: Added detailed test failure display with expected/actual
values.

**Code Changes**:
- `trace/[trace_id]/page.tsx`: Parse error context for test failures
- Display test name, failure reason, expected/actual values, test output

**How to Test**:
1. Go to `/observability/trace/[trace-id-with-test-failure]`
2. Scroll to "Errors" section
3. Find a test failure error
4. Verify "Test Failure Details" section shows:
   - Test name
   - Failure reason
   - Expected value
   - Actual value
   - Test output

---

### 9. UI/UX Improvements
**Problem**: Basic UI without helpful tooltips, copy functionality, or
visual enhancements.

**Fix**: Added reusable components and improved visual design.

**Code Changes**:
- New components: `StatCard`, `CopyButton`, `InfoIcon`, `HelpButton`,
`ColumnHeader`
- All pages: Enhanced with tooltips, copy buttons, better spacing
- `llm-call/[id]/page.tsx`: Complete UI overhaul with visual token
breakdown

**How to Test**:
1. Go to any observability page
2. Hover over info icons (?) — tooltips should appear
3. Click copy buttons — text should copy to clipboard
4. Check stat cards — should have hover effects and icons
5. Go to `/observability/llm-call/[id]`
6. Check token distribution bar — visual breakdown of prompt vs
completion tokens
7. Verify all sections have proper spacing and visual hierarchy

---

### 10. Performance Optimizations
**Problem**: Unconditional fetching of organizations, call types, and
models on every page load.

**Fix**: Added caching for frequently accessed dropdown data.

**Code Changes**:
- `traces/page.tsx`: `getUniqueOrganizations()` with 5-minute cache
- `llm-calls/page.tsx`: `getUniqueOrganizations()`, `getCallTypes()`,
`getModels()` with caching
- All use `unstable_cache` with 300-second revalidation

**How to Test**:
1. Load `/observability/traces` — note load time
2. Reload page — should be faster (cached data)
3. Check browser network tab — fewer database queries on subsequent
loads
4. Wait 5+ minutes and reload — cache should refresh

---

### 11. Database Query Optimization
**Problem**: Organization filtering used inefficient `OR` with
`startsWith` conditions.

**Fix**: Switched to `IN` clause for exact trace ID matches.

**Code Changes**:
- Both pages: Changed from `OR` array to `where.trace_id = { in:
filteredTraceIds }`
- Added comments explaining why Prisma relations can't be used

**How to Test**:
1. Apply organization filter with many traces
2. Check page load time — should be faster
3. Verify results are still accurate
4. Test with organizations having 100+ traces — should handle
efficiently

---

## New Components

### StatCard
Reusable stat display with icons, tooltips, and variants.

**Usage**: Used in all observability pages for summary statistics.

### CopyButton
One-click copy to clipboard with visual feedback.

**Usage**: Used for IDs, prompts, responses, error messages.

### InfoIcon
Tooltip helper for inline explanations.

**Usage**: Used throughout tables and forms for field explanations.

### HelpButton
Modal dialog for detailed help content.

**Usage**: Used in page headers for comprehensive guides.

### ColumnHeader
Table header with integrated tooltips.

**Usage**: Used in all data tables for column explanations.

---

## Code Quality Improvements

1. Shared utilities: `lib/observability-utils.ts` with `getCallSource()`
and `safeCostTokens()`
2. Type safety: Proper TypeScript types, nullish coalescing (`??`)
instead of `||`
3. Comments: Added inline comments explaining architectural decisions
4. Error handling: Better error states and empty state messages

---

## Testing Checklist

- [ ] Total traces count is accurate with/without filters
- [ ] Organization filter works on traces and LLM calls pages
- [ ] Cost values are correctly aggregated
- [ ] No negative duration values appear
- [ ] Source column shows correct values with icons
- [ ] Partial success status displays correctly
- [ ] LLM call details links work from candidates
- [ ] Test failure details show complete information
- [ ] Copy buttons work for all copyable content
- [ ] Tooltips appear on hover for info icons
- [ ] Token distribution bar displays correctly
- [ ] Pagination works with all filters
- [ ] Performance is acceptable with large datasets

---------

Co-authored-by: Codeflash Bot <bot@codeflash.ai>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
2026-01-26 21:14:36 +05:30
ali
e559b6b9b4
handle repair multi-language 2026-01-26 16:41:58 +02:00
ali
7a8661ae31
fix line profiler optimizations 2026-01-26 15:19:24 +02:00
Kevin Turcios
80be7d2dae fix: resolve type errors and linting issues
- Add language parameter to split_markdown_code and group_code for JS/TS support
- Fix callable type annotation in instrument_javascript.py
- Update testgen_javascript.py to use ChatCompletionMessageParam types
- Add None checks before parse_python_version calls
- Add missing None assertions in test files
- Apply ruff auto-fixes for formatting and unused imports
2026-01-25 01:17:44 -05:00
Kevin Turcios
549f99eb97 formatting 2026-01-25 01:04:50 -05:00
Kevin Turcios
f04ac67728 merge: resolve conflicts with main
- Accept consolidated markdown utilities from common module
- Use wrap_code_in_markdown with language parameter for language support
- Remove duplicate split_markdown_code implementation
- Add validation for python_version before parsing
2026-01-25 01:00:56 -05:00
Kevin Turcios
d091cd17fe
refactor: consolidate shared utilities (#2289)
- Consolidate shared utilities into `aiservice/common/`
- Remove profanity filtering from optimization pipeline
- Add unit tests for common module
2026-01-25 00:49:48 -05:00
Kevin Turcios
df9bef20c4
refactor: remove profanity filtering from optimization pipeline (#2288)
## Summary
- Removes `profanity_regex` and `profanity_words` from
`postprocess_constants.py`
- Removes `remove_profanity_from_explanation` from the optimization
pipeline
- Removes associated test
2026-01-24 23:46:03 -05:00
Kevin Turcios
3a304aa00f
Merge branch 'main' into multi-language 2026-01-24 17:42:16 -05:00
Kevin Turcios
7aa4da74f8
feat: improve testgen import resolution and forward reference handling (#2276)
## Summary
- Add forward reference detection and automatic fix with `from
__future__ import annotations`
- Handle aliased imports and chained calls in test instrumentation
- Fix import resolution from correct module in multi-context testgen
- Allow ellipsis in Protocol/abstract method bodies
- Add dataclass constructor notes for LLM about required/positional
arguments
- Add logging to silent exception handlers

## Test plan
- [x] Unit tests added for forward reference detection
- [x] Unit tests added for dataclass constructor notes
- [x] Unit tests added for ellipsis handling in AST
- [x] Unit tests added for chained call instrumentation
- [x] Unit tests extended for add_missing_imports

---------

Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com>
2026-01-24 17:39:38 -05:00