Skip to content

Conversation

@JayaSurya-27
Copy link
Collaborator

@JayaSurya-27 JayaSurya-27 commented Jun 11, 2025

Pull Request

Description

Describe the changes in this pull request:

  • What feature/bug does this PR address?
  • Provide any relevant links or screenshots.

Checklist

  • Code compiles correctly.
  • Created/updated tests.
  • Linting and formatting applied.
  • Documentation updated.

Related Issues

Closes #<issue_number>

Summary by CodeRabbit

  • New Features

    • Introduced OpenTelemetry instrumentation for Google ADK, enabling tracing and observability for AI workflows.
    • Added detailed tracing wrappers for Google ADK agents, runners, LLM calls, and tool executions.
    • Provided example scripts demonstrating integration and usage of tracing with Google ADK.
    • Added new documentation and quickstart guides for TraceAI packages, including Google ADK, core, and semantic conventions.
  • Documentation

    • Added comprehensive READMEs and changelogs for multiple packages, outlining features, setup, and usage instructions.
  • Chores

    • Updated and streamlined TypeScript and Python project configurations, including new base and environment-specific TypeScript config files.
    • Updated package versions and dependency specifications across several packages.

@coderabbitai
Copy link

coderabbitai bot commented Jun 11, 2025

Walkthrough

This update introduces new Python and TypeScript instrumentation packages and configuration files targeting AI observability and tracing. It adds OpenTelemetry-based tracing for Google ADK in Python, including instrumentor classes, wrappers, documentation, and example scripts. In TypeScript, the update refines project structure, adds changelogs, documentation, and modular TypeScript configuration files, and updates dependencies and supported versions across core, semantic conventions, OpenAI, Anthropic, and LangChain instrumentation packages.

Changes

Files/Paths Change Summary
python/frameworks/google-adk/.venv/pyvenv.cfg Added Python virtual environment configuration for Python 3.12.9.
python/frameworks/google-adk/README.md Added README with overview, installation, and usage instructions for TraceAI Google ADK instrumentation.
python/frameworks/google-adk/examples/testing_google_adk.py Added example script demonstrating Google ADK agent tracing and instrumentation.
python/frameworks/google-adk/pyproject.toml Added project configuration specifying metadata and dependencies.
python/frameworks/google-adk/traceai_google_adk/init.py Introduced OpenTelemetry instrumentor for Google ADK; manages async method wrapping and tracer patching.
python/frameworks/google-adk/traceai_google_adk/_wrappers.py Added wrappers and helpers for tracing Google ADK Runner, Agent, LLM, and tool calls with span attribute capture.
python/frameworks/google-adk/traceai_google_adk/version.py Added version file defining __version__ = "0.1.0".
typescript/packages/fi-core/CHANGELOG.md Added changelog documenting release history and updates for fi-core.
typescript/packages/fi-core/README.md Added README with features, usage, and development instructions for fi-core.
typescript/packages/fi-core/package.json Updated version to 0.1.11; reorganized and updated dependencies.
typescript/packages/fi-core/tsconfig.esm.json Added ESM-specific TypeScript config.
typescript/packages/fi-core/tsconfig.esnext.json Added ESNext-specific TypeScript config.
typescript/packages/fi-core/tsconfig.json Updated to extend new base config, simplified paths, expanded includes, removed excludes.
typescript/packages/fi-semantic-conventions/CHANGELOG.md Added changelog for fi-semantic-conventions.
typescript/packages/fi-semantic-conventions/README.md Added README with package overview and installation instructions.
typescript/packages/fi-semantic-conventions/package.json Updated version to 0.1.8.
typescript/packages/fi-semantic-conventions/tsconfig.esm.json Added ESM-specific TypeScript config.
typescript/packages/fi-semantic-conventions/tsconfig.esnext.json Added ESNext-specific TypeScript config.
typescript/packages/fi-semantic-conventions/tsconfig.json Updated to extend new base config, simplified paths, expanded includes, removed excludes.
typescript/packages/traceai_anthropic/CHANGELOG.md Added changelog for traceai_anthropic.
typescript/packages/traceai_anthropic/package.json Updated version to 0.1.1; updated dependency versions.
typescript/packages/traceai_anthropic/tsconfig.esm.json Added ESM-specific TypeScript config.
typescript/packages/traceai_anthropic/tsconfig.esnext.json Added ESNext-specific TypeScript config.
typescript/packages/traceai_anthropic/tsconfig.json Updated to extend new base config, simplified paths, expanded includes, removed references.
typescript/packages/traceai_langchain/tsconfig.esm.json Added ESM-specific TypeScript config.
typescript/packages/traceai_langchain/tsconfig.esnext.json Added ESNext-specific TypeScript config.
typescript/packages/traceai_langchain/tsconfig.json Updated to extend new base config, simplified paths, expanded includes, removed references and paths.
typescript/packages/traceai_openai/CHANGELOG.md Added changelog for traceai_openai.
typescript/packages/traceai_openai/examples/manual.ts Added example demonstrating manual and auto tracing with OpenAI.
typescript/packages/traceai_openai/package.json Updated version to 0.1.12; updated dependency versions and peer dependency range.
typescript/packages/traceai_openai/src/instrumentation.ts Expanded supported OpenAI versions for instrumentation.
typescript/packages/traceai_openai/tsconfig.esm.json Added ESM-specific TypeScript config.
typescript/packages/traceai_openai/tsconfig.esnext.json Added ESNext-specific TypeScript config.
typescript/packages/traceai_openai/tsconfig.json Updated to extend new base config, simplified paths, expanded includes, removed references.
typescript/tsconfig.base.es5.json Added ES5-specific TypeScript base config.
typescript/tsconfig.base.esm.json Added ESM-specific TypeScript base config with ES2020 target and module settings.
typescript/tsconfig.base.esnext.json Added ESNext-specific TypeScript base config.
typescript/tsconfig.base.json Added new comprehensive TypeScript base config for all packages.
typescript/tsconfig.json Deleted old root TypeScript config file.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ExampleScript
    participant TraceAIInstrumentor
    participant GoogleADKAgent
    participant GoogleADKRunner
    participant OpenTelemetryTracer
    participant ObservePlatform

    User->>ExampleScript: Run instrumented example
    ExampleScript->>TraceAIInstrumentor: Register and apply instrumentation
    TraceAIInstrumentor->>GoogleADKAgent: Patch async methods for tracing
    ExampleScript->>GoogleADKRunner: Create and run agent session
    GoogleADKRunner->>OpenTelemetryTracer: Start span for run_async
    GoogleADKAgent->>OpenTelemetryTracer: Start span for agent actions
    OpenTelemetryTracer->>ObservePlatform: Export trace data
    GoogleADKRunner-->>ExampleScript: Emit events and final response
    ExampleScript->>User: Print response
Loading

Poem

🐇
A flurry of configs, new code in the den,
Tracing for agents, with spans to pen.
TypeScript and Python, both join the show,
Observability rising, as metrics now flow.
With docs and examples, our garden is bright—
Hooray for new features, and tracing done right!
🌱✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@NVJKKartik NVJKKartik merged commit e30e671 into main Jun 11, 2025
1 check was pending
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 17

🧹 Nitpick comments (22)
python/frameworks/google-adk/traceai_google_adk/version.py (1)

1-1: Single-source the version to avoid drift

Hard-coding the version string here duplicates the value already declared in pyproject.toml. In practice one of the two places is forgotten during the next bump and the values diverge.

Consider generating __version__ from importlib.metadata.version(__package__), or import the value from this file inside pyproject.toml via poetry-dynamic-versioning/setuptools-scm to keep a single source of truth.

python/frameworks/google-adk/pyproject.toml (2)

1-6: Package metadata is inconsistent (name ↔︎ description)

The package is named traceAI-google-adk but the description still says “Instrumentation for Anthropic”. Copy/paste artefact? Update the description so users browsing PyPI immediately know it targets Google-ADK.

-description = "OpenTelemetry instrumentation for Anthropic"
+description = "OpenTelemetry instrumentation for Google ADK"

12-17: Tight-pinning third-party libs hampers downstream users

google-adk = ">= 1.2.1" is flexible, but
fi-instrumentation-otel = "0.1.7" is hard-pinned. Unless you rely on an exact bug-fix release, prefer a compatible range (^0.1.7) so you automatically receive backward-compatible patches.

Also double-check whether google-genai already depends on a narrower version of google-adk to avoid resolver conflicts.

python/frameworks/google-adk/README.md (3)

10-16: Missing comma after “example” – minor readability nit

“In this example we will instrument …”

Add a comma after example:

-In this example we will instrument
+In this example, we will instrument
🧰 Tools
🪛 LanguageTool

[typographical] ~10-~10: It appears that a comma is missing.
Context: ...or Google ADK. ## Quickstart In this example we will instrument a small program that...

(DURING_THAT_TIME_COMMA)


20-33: Sample imports include unused exporters/processors

OTLPSpanExporter, ConsoleSpanExporter, and SimpleSpanProcessor are imported in the snippet but never used, which may confuse readers and encourages copy-pasting unused code.

Either wire them into the example or drop the imports to keep the quick-start minimal.


105-109: Article missing before “Future AGI Platform”

“send the traces to Future AGI Platform”

Kings-English: “to the Future AGI Platform”

🧰 Tools
🪛 LanguageTool

[uncategorized] ~105-~105: You might be missing the article “the” here.
Context: ...n the python file to send the traces to Future AGI Platform. ```shell python your_fil...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

python/frameworks/google-adk/examples/testing_google_adk.py (1)

32-44: Eliminate the unnecessary else after return

After the early return the else block is redundant. Micro-refactor for clarity:

-    else:
-        return {
-            "status": "error",
-            "error_message": f"Weather information for '{city}' is not available.",
-        }
+    return {
+        "status": "error",
+        "error_message": f"Weather information for '{city}' is not available.",
+    }
🧰 Tools
🪛 Pylint (3.3.7)

[refactor] 32-44: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

python/frameworks/google-adk/traceai_google_adk/__init__.py (1)

89-101: Remove duplicate imports.

The base_llm_flow module is imported twice in this method.

 def _unpatch_trace_call_llm(self) -> None:
     """Restore the original LLM call tracing functionality."""
     from google.adk.flows.llm_flows import base_llm_flow
 
     if callable(
         original := getattr(base_llm_flow.trace_call_llm, "__wrapped__"),  # type: ignore[attr-defined]
     ):
-        from google.adk.flows.llm_flows import (
-            base_llm_flow,
-        )
-
         setattr(base_llm_flow, "trace_call_llm", original)
🧰 Tools
🪛 Ruff (0.11.9)

94-94: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)


100-100: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)

🪛 Pylint (3.3.7)

[error] 91-91: No name 'adk' in module 'google'

(E0611)


[error] 96-98: No name 'adk' in module 'google'

(E0611)

python/frameworks/google-adk/traceai_google_adk/_wrappers.py (3)

147-163: Consider capturing input values for agent runs.

Unlike _RunnerRunAsync, this wrapper doesn't capture input arguments. Consider adding input value capture for better observability.

Add input value capture after line 163:

arguments = bind_args_kwargs(wrapped, *args, **kwargs)
try:
    attributes[SpanAttributes.INPUT_VALUE] = json.dumps(
        arguments,
        default=_default,
        ensure_ascii=False,
    )
    attributes[SpanAttributes.INPUT_MIME_TYPE] = FiMimeTypeValues.JSON.value
except Exception:
    logger.exception(f"Failed to get attribute: {SpanAttributes.INPUT_VALUE}.")
🧰 Tools
🪛 Pylint (3.3.7)

[refactor] 147-147: Too few public methods (1/2)

(R0903)


268-271: Address TODO for list type system instructions.

The TODO comment indicates missing implementation for handling list-type system instructions.

Would you like me to implement the handling for list-type system instructions or create an issue to track this?


328-341: Simplify nested conditional.

The nested if statements can be combined for better readability.

-        if event := next((arg for arg in arguments.values() if isinstance(arg, Event)), None):
-            if responses := event.get_function_responses():
+        if (event := next((arg for arg in arguments.values() if isinstance(arg, Event)), None)) and (responses := event.get_function_responses()):
                 try:
                     span.set_attribute(
                         SpanAttributes.OUTPUT_VALUE,
                         responses[0].model_dump_json(exclude_none=True),
                     )
                     span.set_attribute(
                         SpanAttributes.OUTPUT_MIME_TYPE,
                         FiMimeTypeValues.JSON.value,
                     )
                 except Exception:
                     logger.exception(f"Failed to get attribute in {wrapped.__name__}.")
🧰 Tools
🪛 Ruff (0.11.9)

328-329: Use a single if statement instead of nested if statements

(SIM102)

typescript/packages/fi-semantic-conventions/README.md (1)

1-17: Installation instructions are clear.
The README provides concise npm/yarn/pnpm commands.
Consider adding a basic usage example (e.g., code snippet demonstrating attribute import and application) and repository badges (npm version, build status) to improve discoverability and developer experience.

typescript/packages/traceai_anthropic/package.json (1)

29-30: Dependency ranges should target the latest release.
You’ve pinned @traceai/fi-core to ^0.1.10, but the core package is now at 0.1.11. While ^0.1.10 will pull in 0.1.11, consider updating it to ^0.1.11 for clarity, or confirm that your CI matrix tests against the latest core.

typescript/packages/fi-semantic-conventions/tsconfig.json (2)

7-7: Consider removing the empty files array
An empty "files": [] can be omitted since "include" covers file matching. Removing it reduces clutter.


9-9: Review references usage
An empty "references": [] is a no-op; if project references aren't needed, you can remove this field. Otherwise, populate it for composite projects.

typescript/packages/traceai_openai/tsconfig.json (1)

7-10: Optional: Clean up empty fields
Since "files" and "references" are empty and you’re using "include", you may remove them to reduce noise.

typescript/packages/traceai_langchain/tsconfig.json (1)

7-10: Optional cleanup
Empty "files" and "references" entries can be removed for clarity when not used.

typescript/packages/fi-core/package.json (1)

2-27: Optional: Add license field
It’s good practice to include a "license" property in package.json to explicitly declare the package license.

typescript/packages/traceai_openai/examples/manual.ts (4)

3-4: Combine imports from the same module.

Multiple imports from @traceai/fi-core can be combined into a single import statement for better readability.

-import { register } from "@traceai/fi-core";
-import { ProjectType } from "@traceai/fi-core";
+import { register, ProjectType } from "@traceai/fi-core";

10-10: Consider making the diagnostic log level configurable.

The DEBUG log level is hardcoded, which might be too verbose for some use cases. Consider making it configurable via environment variables to demonstrate best practices.

-diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
+const logLevel = process.env.OTEL_LOG_LEVEL || 'INFO';
+const diagLogLevel = DiagLogLevel[logLevel as keyof typeof DiagLogLevel] || DiagLogLevel.INFO;
+diag.setLogger(new DiagConsoleLogger(), diagLogLevel);

45-45: Add type annotations for function parameters.

The function parameter prompt lacks explicit type annotation. While TypeScript can infer it, explicit types improve code clarity and maintainability.

-async function enhancedTextGeneration(prompt: string) {
+async function enhancedTextGeneration(prompt: string): Promise<OpenAI.Chat.Completions.ChatCompletion> {

244-244: Add return type annotation for consistency.

-async function testInstrumentation() {
+async function testInstrumentation(): Promise<void> {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 197ddfa and 006e8d9.

⛔ Files ignored due to path filters (2)
  • python/frameworks/google-adk/poetry.lock is excluded by !**/*.lock
  • typescript/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (39)
  • python/frameworks/google-adk/.venv/pyvenv.cfg (1 hunks)
  • python/frameworks/google-adk/README.md (1 hunks)
  • python/frameworks/google-adk/examples/testing_google_adk.py (1 hunks)
  • python/frameworks/google-adk/pyproject.toml (1 hunks)
  • python/frameworks/google-adk/traceai_google_adk/__init__.py (1 hunks)
  • python/frameworks/google-adk/traceai_google_adk/_wrappers.py (1 hunks)
  • python/frameworks/google-adk/traceai_google_adk/version.py (1 hunks)
  • typescript/packages/fi-core/CHANGELOG.md (1 hunks)
  • typescript/packages/fi-core/README.md (1 hunks)
  • typescript/packages/fi-core/package.json (2 hunks)
  • typescript/packages/fi-core/tsconfig.esm.json (1 hunks)
  • typescript/packages/fi-core/tsconfig.esnext.json (1 hunks)
  • typescript/packages/fi-core/tsconfig.json (1 hunks)
  • typescript/packages/fi-semantic-conventions/CHANGELOG.md (1 hunks)
  • typescript/packages/fi-semantic-conventions/README.md (1 hunks)
  • typescript/packages/fi-semantic-conventions/package.json (1 hunks)
  • typescript/packages/fi-semantic-conventions/tsconfig.esm.json (1 hunks)
  • typescript/packages/fi-semantic-conventions/tsconfig.esnext.json (1 hunks)
  • typescript/packages/fi-semantic-conventions/tsconfig.json (1 hunks)
  • typescript/packages/traceai_anthropic/CHANGELOG.md (1 hunks)
  • typescript/packages/traceai_anthropic/package.json (2 hunks)
  • typescript/packages/traceai_anthropic/tsconfig.esm.json (1 hunks)
  • typescript/packages/traceai_anthropic/tsconfig.esnext.json (1 hunks)
  • typescript/packages/traceai_anthropic/tsconfig.json (1 hunks)
  • typescript/packages/traceai_langchain/tsconfig.esm.json (1 hunks)
  • typescript/packages/traceai_langchain/tsconfig.esnext.json (1 hunks)
  • typescript/packages/traceai_langchain/tsconfig.json (1 hunks)
  • typescript/packages/traceai_openai/CHANGELOG.md (1 hunks)
  • typescript/packages/traceai_openai/examples/manual.ts (1 hunks)
  • typescript/packages/traceai_openai/package.json (3 hunks)
  • typescript/packages/traceai_openai/src/instrumentation.ts (1 hunks)
  • typescript/packages/traceai_openai/tsconfig.esm.json (1 hunks)
  • typescript/packages/traceai_openai/tsconfig.esnext.json (1 hunks)
  • typescript/packages/traceai_openai/tsconfig.json (1 hunks)
  • typescript/tsconfig.base.es5.json (1 hunks)
  • typescript/tsconfig.base.esm.json (1 hunks)
  • typescript/tsconfig.base.esnext.json (1 hunks)
  • typescript/tsconfig.base.json (1 hunks)
  • typescript/tsconfig.json (0 hunks)
💤 Files with no reviewable changes (1)
  • typescript/tsconfig.json
🧰 Additional context used
🧬 Code Graph Analysis (2)
python/frameworks/google-adk/examples/testing_google_adk.py (1)
python/frameworks/google-adk/traceai_google_adk/__init__.py (1)
  • GoogleADKInstrumentor (22-174)
python/frameworks/google-adk/traceai_google_adk/__init__.py (1)
python/frameworks/google-adk/traceai_google_adk/_wrappers.py (5)
  • _BaseAgentRunAsync (147-190)
  • _RunnerRunAsync (78-144)
  • wrapper (347-351)
  • _TraceCallLlm (193-283)
  • _TraceToolCall (286-341)
🪛 Biome (1.9.4)
typescript/tsconfig.base.json

[error] 3-3: JSON standard does not allow comments.

(parse)


[error] 5-5: JSON standard does not allow comments.

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: JSON standard does not allow comments.

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: JSON standard does not allow comments.

(parse)


[error] 13-13: JSON standard does not allow comments.

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: JSON standard does not allow comments.

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-17: JSON standard does not allow comments.

(parse)


[error] 29-29: JSON standard does not allow comments.

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: JSON standard does not allow comments.

(parse)


[error] 48-48: JSON standard does not allow comments.

(parse)


[error] 53-53: JSON standard does not allow comments.

(parse)


[error] 54-54: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 54-54: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 54-54: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 54-54: JSON standard does not allow comments.

(parse)


[error] 55-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-55: JSON standard does not allow comments.

(parse)


[error] 57-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-57: JSON standard does not allow comments.

(parse)


[error] 78-78: JSON standard does not allow comments.

(parse)


[error] 82-82: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 82-82: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 82-82: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 82-82: JSON standard does not allow comments.

(parse)


[error] 84-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-84: JSON standard does not allow comments.

(parse)


[error] 86-86: JSON standard does not allow comments.

(parse)


[error] 87-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-87: JSON standard does not allow comments.

(parse)


[error] 107-107: JSON standard does not allow comments.

(parse)


[error] 109-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-109: JSON standard does not allow comments.

(parse)


[error] 111-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-112: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

typescript/tsconfig.base.esnext.json

[error] 5-5: Expected a property but instead found '// target should be aligned with tsconfig.base.json'.

Expected a property here.

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 8-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

🪛 LanguageTool
python/frameworks/google-adk/README.md

[typographical] ~10-~10: It appears that a comma is missing.
Context: ...or Google ADK. ## Quickstart In this example we will instrument a small program that...

(DURING_THAT_TIME_COMMA)


[uncategorized] ~105-~105: You might be missing the article “the” here.
Context: ...n the python file to send the traces to Future AGI Platform. ```shell python your_fil...

(AI_EN_LECTOR_MISSING_DETERMINER_THE)

typescript/packages/fi-core/README.md

[uncategorized] ~98-~98: Loose punctuation mark.
Context: ...agent-as-judge #### Span Types - LLM: Large Language Model operations - `AGEN...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~107-~107: Loose punctuation mark.
Context: ...tions ### Project Types - EXPERIMENT: For experimental AI development and tes...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~115-~115: Loose punctuation mark.
Context: ...# Environment Variables - FI_BASE_URL: Base URL for the TraceAI collector - `F...

(UNLIKELY_OPENING_PUNCTUATION)

🪛 Ruff (0.11.9)
python/frameworks/google-adk/examples/testing_google_adk.py

8-8: opentelemetry.exporter.otlp.proto.http.trace_exporter.OTLPSpanExporter imported but unused

Remove unused import: opentelemetry.exporter.otlp.proto.http.trace_exporter.OTLPSpanExporter

(F401)


9-9: opentelemetry.sdk.trace imported but unused

Remove unused import: opentelemetry.sdk.trace

(F401)


10-10: opentelemetry.sdk.trace.export.ConsoleSpanExporter imported but unused

Remove unused import

(F401)


10-10: opentelemetry.sdk.trace.export.SimpleSpanProcessor imported but unused

Remove unused import

(F401)

python/frameworks/google-adk/traceai_google_adk/__init__.py

82-82: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


83-87: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


94-94: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)


100-100: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


104-104: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


112-112: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


113-117: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


124-124: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)


130-130: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


134-134: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


145-145: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


154-154: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


162-162: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)


165-165: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


171-171: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)


174-174: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)

python/frameworks/google-adk/traceai_google_adk/_wrappers.py

60-60: _WithTracer is an abstract base class, but it has no abstract methods or properties

(B024)


328-329: Use a single if statement instead of nested if statements

(SIM102)

🪛 Pylint (3.3.7)
python/frameworks/google-adk/examples/testing_google_adk.py

[error] 3-3: No name 'adk' in module 'google'

(E0611)


[error] 4-4: No name 'adk' in module 'google'

(E0611)


[error] 5-5: No name 'genai' in module 'google'

(E0611)


[refactor] 32-44: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

python/frameworks/google-adk/traceai_google_adk/__init__.py

[error] 42-42: No name 'adk' in module 'google'

(E0611)


[error] 43-43: No name 'adk' in module 'google'

(E0611)


[error] 78-78: No name 'adk' in module 'google'

(E0611)


[error] 91-91: No name 'adk' in module 'google'

(E0611)


[error] 96-98: No name 'adk' in module 'google'

(E0611)


[error] 102-102: No name 'adk' in module 'google'

(E0611)


[error] 108-108: No name 'adk' in module 'google'

(E0611)


[error] 121-121: No name 'adk' in module 'google'

(E0611)


[error] 126-128: No name 'adk' in module 'google'

(E0611)


[error] 132-132: No name 'adk' in module 'google'

(E0611)


[error] 138-140: No name 'adk' in module 'google'

(E0611)


[error] 143-143: No name 'adk' in module 'google'

(E0611)


[error] 147-149: No name 'adk' in module 'google'

(E0611)


[error] 152-152: No name 'adk' in module 'google'

(E0611)


[error] 158-160: No name 'adk' in module 'google'

(E0611)


[error] 163-163: No name 'adk' in module 'google'

(E0611)


[error] 167-169: No name 'adk' in module 'google'

(E0611)


[error] 172-172: No name 'adk' in module 'google'

(E0611)


[refactor] 177-177: Too few public methods (1/2)

(R0903)

python/frameworks/google-adk/traceai_google_adk/_wrappers.py

[error] 19-19: No name 'adk' in module 'google'

(E0611)


[error] 20-20: No name 'adk' in module 'google'

(E0611)


[error] 21-21: No name 'adk' in module 'google'

(E0611)


[error] 22-22: No name 'adk' in module 'google'

(E0611)


[error] 23-23: No name 'adk' in module 'google'

(E0611)


[error] 24-24: No name 'adk' in module 'google'

(E0611)


[error] 25-25: No name 'adk' in module 'google'

(E0611)


[error] 26-26: No name 'adk' in module 'google'

(E0611)


[error] 27-27: No name 'genai' in module 'google'

(E0611)


[error] 28-28: No name 'genai' in module 'google'

(E0611)


[refactor] 60-60: Too few public methods (0/2)

(R0903)


[refactor] 111-111: Too few public methods (1/2)

(R0903)


[refactor] 78-78: Too few public methods (1/2)

(R0903)


[refactor] 164-164: Too few public methods (1/2)

(R0903)


[refactor] 147-147: Too few public methods (1/2)

(R0903)


[refactor] 195-195: Too many local variables (17/15)

(R0914)


[refactor] 217-279: Too many nested blocks (6/5)

(R1702)


[refactor] 195-195: Too many branches (20/12)

(R0912)


[refactor] 193-193: Too few public methods (1/2)

(R0903)


[refactor] 286-286: Too few public methods (1/2)

(R0903)


[refactor] 515-522: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

🔇 Additional comments (34)
python/frameworks/google-adk/examples/testing_google_adk.py (1)

54-64: Awaiting create_session() without a try/except hides failures

create_session makes a network call; in an example it’s fine, but in production you should wrap it so errors don’t bubble unhandled:

try:
    await session_service.create_session(...)
except Exception as exc:
    logger.exception("Failed to create session: %s", exc)
    return
python/frameworks/google-adk/traceai_google_adk/__init__.py (4)

26-41: Well-structured instrumentation setup.

The method properly handles tracer provider and config initialization with appropriate type checking.


50-62: Excellent method wrapping implementation.

The approach of storing original methods for cleanup and using wrapt for method wrapping follows best practices.


136-175: Clean tracer management implementation.

The approach of disabling existing tracers with a passthrough proxy and restoring them later is well-implemented with proper type checking.

🧰 Tools
🪛 Ruff (0.11.9)

145-145: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


154-154: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


162-162: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)


165-165: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)


171-171: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)


174-174: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)

🪛 Pylint (3.3.7)

[error] 138-140: No name 'adk' in module 'google'

(E0611)


[error] 143-143: No name 'adk' in module 'google'

(E0611)


[error] 147-149: No name 'adk' in module 'google'

(E0611)


[error] 152-152: No name 'adk' in module 'google'

(E0611)


[error] 158-160: No name 'adk' in module 'google'

(E0611)


[error] 163-163: No name 'adk' in module 'google'

(E0611)


[error] 167-169: No name 'adk' in module 'google'

(E0611)


[error] 172-172: No name 'adk' in module 'google'

(E0611)


177-187: Elegant passthrough tracer implementation.

The use of wrapt.ObjectProxy to create a no-op tracer that preserves context is a clean solution for preventing double instrumentation.

🧰 Tools
🪛 Pylint (3.3.7)

[refactor] 177-177: Too few public methods (1/2)

(R0903)

python/frameworks/google-adk/traceai_google_adk/_wrappers.py (2)

78-145: Robust async generator wrapper implementation.

Excellent use of ExitStack for managing multiple contexts and comprehensive error handling for attribute serialization. The wrapper properly captures both input and output values.

🧰 Tools
🪛 Pylint (3.3.7)

[refactor] 111-111: Too few public methods (1/2)

(R0903)


[refactor] 78-78: Too few public methods (1/2)

(R0903)


344-522: Well-structured attribute extraction helpers.

Excellent use of the stop_on_exception decorator pattern for consistent error handling across all attribute extraction functions. The comprehensive coverage of Google ADK types ensures rich telemetry data.

🧰 Tools
🪛 Pylint (3.3.7)

[refactor] 515-522: Unnecessary "else" after "return", remove the "else" and de-indent the code inside it

(R1705)

typescript/tsconfig.base.esnext.json (1)

1-9: Comments in TSConfig are supported despite strict JSON lint warnings.
TypeScript parses tsconfig files as JSONC, so inline comments (e.g., on line 5) are valid here. You can safely ignore the parse errors from strict JSON tools.

🧰 Tools
🪛 Biome (1.9.4)

[error] 5-5: Expected a property but instead found '// target should be aligned with tsconfig.base.json'.

Expected a property here.

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 8-9: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

typescript/packages/fi-semantic-conventions/package.json (1)

3-3: Version bump aligned with ecosystem updates.
The package version has been updated from 0.1.1 to 0.1.8 to stay in sync with related TraceAI packages.

typescript/packages/traceai_anthropic/CHANGELOG.md (1)

1-4: CHANGELOG entries follow Keep a Changelog format.
Versions 0.1.1 and 0.1.0 are correctly ordered with feature notes. No issues detected.

typescript/packages/traceai_anthropic/package.json (1)

3-3: Package version increment is correct.
Bumped from 0.1.0 to 0.1.1, matching the changelog.

typescript/tsconfig.base.es5.json (1)

1-7: ES5 Base Config Looks Good
The new ES5-targeted base config correctly extends tsconfig.base.json, sets target: "es5", and enables downlevelIteration for proper iterator support.

typescript/packages/traceai_openai/src/instrumentation.ts (1)

129-137: OpenAI v5 Support Added
Including ^5.0.0 alongside ^4.0.0 in the init() module definition aligns with the updated peer dependency ranges. Ensure that package.json and any documentation examples are updated to reflect support for both major versions.

typescript/packages/fi-core/tsconfig.json (2)

2-6: Base Config Extension and Path Simplification
Switching to extend ../../tsconfig.base.json and removing leading ./ from outDir/rootDir simplifies the config and aligns with other packages.


7-9: Explicit Include of Source and Test Files
Narrowing include to src/**/*.ts and test/**/*.ts ensures only relevant files are compiled. The empty files and references arrays are appropriate for standalone builds.

typescript/packages/fi-core/tsconfig.esm.json (1)

1-10: ESM Config Correctly Extends Base ESM
The ESM-specific config properly extends tsconfig.base.esm.json, directs output to dist/esm, and sets tsBuildInfoFile. Including only src/**/*.ts is appropriate for the ESM build.

typescript/packages/traceai_openai/tsconfig.esnext.json (1)

1-10: ESNext Config Aligns with Base
Extending tsconfig.base.esnext.json with correct outDir, rootDir, and tsBuildInfoFile for the ESNext build ensures consistency across packages. Including only source files is appropriate.

typescript/packages/traceai_openai/tsconfig.esm.json (1)

1-10: Consistent ESM build configuration applied
Extends the shared base ESM config and correctly sets outDir, rootDir, and incremental tsBuildInfoFile. Including only src/**/*.ts is appropriate for package builds.

typescript/packages/fi-semantic-conventions/tsconfig.esm.json (1)

1-10: Standardized ESM config matches project conventions
This file properly extends the base ESM config, directs output to dist/esm, and scopes sources to src. The setup is consistent with other packages.

typescript/packages/traceai_anthropic/tsconfig.esnext.json (1)

1-10: ESNext configuration aligns with monorepo standards
Extends the base ESNext config and sets outDir, rootDir, and incremental build info correctly. Inclusion of src/**/*.ts is correct.

typescript/packages/fi-core/tsconfig.esnext.json (1)

1-10: Consistent ESNext build settings
Follows the same pattern as other packages: extends base ESNext config, outputs to dist/esnext, and uses src as the root.

typescript/packages/traceai_anthropic/tsconfig.esm.json (1)

1-10: ESM build config is correctly defined
Extends the shared base ESM config, targets dist/esm, and scopes source files under src. No project references needed here.

typescript/packages/traceai_anthropic/tsconfig.json (1)

2-9: Confirm Anthropic config simplification
The TS config now extends the centralized base and removes composite and project references. Verify that traceai_anthropic no longer relies on project references and builds correctly in isolation or via the root-level build.

typescript/packages/traceai_openai/package.json (1)

3-3: Approve version bump
Bumping from 0.1.2 to 0.1.12 follows semver and aligns with the release cadence.

typescript/packages/fi-semantic-conventions/tsconfig.json (3)

2-2: Verify the base config extension path
Using "../../tsconfig.base.json" aligns with the new base config structure; confirm the path resolves correctly in the package context.


4-5: Simplified compiler paths look correct
Dropping the leading "./" in outDir and rootDir simplifies the paths without altering behavior.


8-8: Explicitly include tests in the build
Adding "test/**/*.ts" ensures test files are compiled and type-checked; this matches the standardized setup.

typescript/tsconfig.base.esm.json (1)

2-6: Validate extension and module resolution settings
Ensure that extending ./tsconfig.base.esnext.json is intentional for ESM targets and that moduleResolution: "node10" aligns with your Node.js support policy (Node.js 10 is EOL). Consider upgrading to a more recent resolution strategy (e.g., node16 or nodeNext) if applicable.

typescript/packages/traceai_openai/tsconfig.json (1)

2-6: Consistent base configuration inheritance
Extending from tsconfig.base.json and simplifying compiler options (outDir, rootDir) aligns this package with other monorepo packages.

typescript/packages/traceai_langchain/tsconfig.json (1)

2-6: Standardized compiler options
Updating to extend tsconfig.base.json and normalizing outDir/rootDir simplifies and unifies the build across packages.

typescript/packages/fi-core/package.json (3)

3-3: Version bump
Updated version to 0.1.11 to align with dependent packages across the monorepo.


34-37: Dependencies version pinning
Pinned @traceai/fi-semantic-conventions to ^0.1.8 and uuid to ^11.1.0, matching the ecosystem’s coordinated versioning strategy.


38-41: DevDependencies cleanup
Limiting devDependencies to TypeScript and Node types streamlines setup and avoids unnecessary packages.

typescript/tsconfig.base.json (1)

1-112: Comprehensive base configuration
The new tsconfig.base.json provides a solid foundation (incremental builds, strict checks, source maps). TS’s JSONC format supports comments—these static-analysis JSON errors can be safely ignored.

🧰 Tools
🪛 Biome (1.9.4)

[error] 3-3: JSON standard does not allow comments.

(parse)


[error] 5-5: JSON standard does not allow comments.

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 6-6: JSON standard does not allow comments.

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 7-7: JSON standard does not allow comments.

(parse)


[error] 13-13: JSON standard does not allow comments.

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 14-14: JSON standard does not allow comments.

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-15: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 15-17: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 17-17: JSON standard does not allow comments.

(parse)


[error] 29-29: JSON standard does not allow comments.

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 30-30: JSON standard does not allow comments.

(parse)


[error] 48-48: JSON standard does not allow comments.

(parse)


[error] 53-53: JSON standard does not allow comments.

(parse)


[error] 54-54: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 54-54: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 54-54: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 54-54: JSON standard does not allow comments.

(parse)


[error] 55-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-55: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 55-55: JSON standard does not allow comments.

(parse)


[error] 57-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-57: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 57-57: JSON standard does not allow comments.

(parse)


[error] 78-78: JSON standard does not allow comments.

(parse)


[error] 82-82: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 82-82: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 82-82: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 82-82: JSON standard does not allow comments.

(parse)


[error] 84-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-84: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 84-84: JSON standard does not allow comments.

(parse)


[error] 86-86: JSON standard does not allow comments.

(parse)


[error] 87-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-87: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 87-87: JSON standard does not allow comments.

(parse)


[error] 107-107: JSON standard does not allow comments.

(parse)


[error] 109-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-109: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 109-109: JSON standard does not allow comments.

(parse)


[error] 111-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-111: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 111-112: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

Comment on lines +1 to +5
home = /opt/homebrew/opt/python@3.12/bin
include-system-site-packages = false
version = 3.12.9
executable = /opt/homebrew/Cellar/python@3.12/3.12.9/Frameworks/Python.framework/Versions/3.12/bin/python3.12
command = /opt/homebrew/opt/python@3.12/bin/python3.12 -m venv /Users/n.v.j.kkartik/traceAI/python/frameworks/google-adk/.venv
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Don’t commit virtual-environment artefacts

python/frameworks/google-adk/.venv/pyvenv.cfg is machine-specific (absolute paths, Python installation prefix) and will quickly become stale or break CI. Virtual-envs should be excluded via .gitignore and re-created locally (python -m venv .venv or poetry env use …).

Please delete the directory from the repository and add a deny-listing rule such as:

+# Development artefacts
+python/**/.venv/

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In python/frameworks/google-adk/.venv/pyvenv.cfg lines 1 to 5, the virtual
environment configuration file contains machine-specific absolute paths that
should not be committed to the repository. Remove the entire .venv directory
from the repository and add an entry to the .gitignore file to exclude the .venv
directory from future commits. This ensures that each developer or CI
environment creates their own local virtual environment without conflicts.

Comment on lines +8 to +11
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk import trace as trace_sdk
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from fi_instrumentation import register
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Clean up unused imports to satisfy Ruff / pylint

OTLPSpanExporter, trace_sdk, ConsoleSpanExporter, and SimpleSpanProcessor are imported but not referenced, triggering F401/E0611. Remove them (or use them) to keep the example lint-clean:

-from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
-from opentelemetry.sdk import trace as trace_sdk
-from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk import trace as trace_sdk
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from fi_instrumentation import register
from fi_instrumentation import register
🧰 Tools
🪛 Ruff (0.11.9)

8-8: opentelemetry.exporter.otlp.proto.http.trace_exporter.OTLPSpanExporter imported but unused

Remove unused import: opentelemetry.exporter.otlp.proto.http.trace_exporter.OTLPSpanExporter

(F401)


9-9: opentelemetry.sdk.trace imported but unused

Remove unused import: opentelemetry.sdk.trace

(F401)


10-10: opentelemetry.sdk.trace.export.ConsoleSpanExporter imported but unused

Remove unused import

(F401)


10-10: opentelemetry.sdk.trace.export.SimpleSpanProcessor imported but unused

Remove unused import

(F401)

🤖 Prompt for AI Agents
In python/frameworks/google-adk/examples/testing_google_adk.py around lines 8 to
11, the imports OTLPSpanExporter, trace_sdk, ConsoleSpanExporter, and
SimpleSpanProcessor are unused and cause lint errors. Remove these unused
imports to clean up the code and satisfy Ruff/pylint checks.

Comment on lines +65 to +73
async for event in runner.run_async(
user_id=user_id,
session_id=session_id,
new_message=types.Content(role="user", parts=[
types.Part(text="What is the weather in New York?")]
)
):
if event.is_final_response():
print(event.content.parts[0].text.strip())
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Loop keeps iterating after final response

Once event.is_final_response() is True the loop can break; otherwise the run_async generator will continue yielding heartbeat events and the script hangs.

-        if event.is_final_response():
-            print(event.content.parts[0].text.strip())
+        if event.is_final_response():
+            print(event.content.parts[0].text.strip())
+            break
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async for event in runner.run_async(
user_id=user_id,
session_id=session_id,
new_message=types.Content(role="user", parts=[
types.Part(text="What is the weather in New York?")]
)
):
if event.is_final_response():
print(event.content.parts[0].text.strip())
async for event in runner.run_async(
user_id=user_id,
session_id=session_id,
new_message=types.Content(role="user", parts=[
types.Part(text="What is the weather in New York?")]
)
):
if event.is_final_response():
print(event.content.parts[0].text.strip())
break
🤖 Prompt for AI Agents
In python/frameworks/google-adk/examples/testing_google_adk.py around lines 65
to 73, the async for loop continues iterating even after receiving the final
response, causing the script to hang due to ongoing heartbeat events. To fix
this, add a break statement immediately after the print statement inside the if
event.is_final_response() block to exit the loop once the final response is
received.

Comment on lines +119 to +131
def _unpatch_trace_tool_call(self) -> None:
"""Restore the original tool call tracing functionality."""
from google.adk.flows.llm_flows.base_llm_flow import functions # type: ignore[attr-defined]

if callable(
original := getattr(functions.trace_tool_call, "__wrapped__"), # type: ignore[attr-defined]
):
from google.adk.flows.llm_flows.base_llm_flow import ( # type: ignore[attr-defined]
functions,
)

setattr(functions, "trace_tool_call", original)

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix import path inconsistency.

The import path in _unpatch_trace_tool_call differs from the one used in _patch_trace_tool_call. This inconsistency could cause the unpatch operation to fail.

 def _unpatch_trace_tool_call(self) -> None:
     """Restore the original tool call tracing functionality."""
-    from google.adk.flows.llm_flows.base_llm_flow import functions  # type: ignore[attr-defined]
+    from google.adk.flows.llm_flows import functions
 
     if callable(
         original := getattr(functions.trace_tool_call, "__wrapped__"),  # type: ignore[attr-defined]
     ):
-        from google.adk.flows.llm_flows.base_llm_flow import (  # type: ignore[attr-defined]
-            functions,
-        )
-
         setattr(functions, "trace_tool_call", original)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def _unpatch_trace_tool_call(self) -> None:
"""Restore the original tool call tracing functionality."""
from google.adk.flows.llm_flows.base_llm_flow import functions # type: ignore[attr-defined]
if callable(
original := getattr(functions.trace_tool_call, "__wrapped__"), # type: ignore[attr-defined]
):
from google.adk.flows.llm_flows.base_llm_flow import ( # type: ignore[attr-defined]
functions,
)
setattr(functions, "trace_tool_call", original)
def _unpatch_trace_tool_call(self) -> None:
"""Restore the original tool call tracing functionality."""
from google.adk.flows.llm_flows import functions # type: ignore[attr-defined]
if callable(
original := getattr(functions.trace_tool_call, "__wrapped__"), # type: ignore[attr-defined]
):
setattr(functions, "trace_tool_call", original)
🧰 Tools
🪛 Ruff (0.11.9)

124-124: Do not call getattr with a constant attribute value. It is not any safer than normal property access.

Replace getattr with attribute access

(B009)


130-130: Do not call setattr with a constant attribute value. It is not any safer than normal property access.

Replace setattr with assignment

(B010)

🪛 Pylint (3.3.7)

[error] 121-121: No name 'adk' in module 'google'

(E0611)


[error] 126-128: No name 'adk' in module 'google'

(E0611)

🤖 Prompt for AI Agents
In python/frameworks/google-adk/traceai_google_adk/__init__.py around lines 119
to 131, the import path used in the _unpatch_trace_tool_call method is
inconsistent with the one in _patch_trace_tool_call, which may cause the unpatch
operation to fail. To fix this, update the import statement in
_unpatch_trace_tool_call to use the exact same module path as in
_patch_trace_tool_call, ensuring both methods import from the same location to
maintain consistency and correctness.

Comment on lines +2 to +9
"extends": "../../tsconfig.base.esm.json",
"compilerOptions": {
"outDir": "dist/esm",
"rootDir": "src",
"tsBuildInfoFile": "dist/esm/tsconfig.esm.tsbuildinfo"
},
"include": ["src/**/*.ts"],
"references": []
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify ESM base config inheritance
The extends path and outDir, rootDir, and tsBuildInfoFile align with other packages. Confirm that tsconfig.base.esm.json includes incremental or composite flags so that the tsBuildInfoFile is utilized correctly.


🏁 Script executed:

#!/bin/bash
# Verify incremental/composite flags in the base ESM config
rg -A2 '"incremental"' typescript/tsconfig.base.esm.json
rg -A2 '"composite"' typescript/tsconfig.base.esm.json

Length of output: 115


I’ll locate the ESM base config file and check for those flags directly.


🏁 Script executed:

#!/bin/bash
# Find the tsconfig.base.esm.json file
file_path=$(find . -type f -name 'tsconfig.base.esm.json' | head -n1)
echo "Config file found at: $file_path"

# Check for incremental and composite settings
if [[ -n "$file_path" ]]; then
  echo "Searching for \"incremental\" in $file_path"
  grep -n '"incremental"' "$file_path" || echo "❌ no incremental flag found"
  echo
  echo "Searching for \"composite\" in $file_path"
  grep -n '"composite"' "$file_path" || echo "❌ no composite flag found"
else
  echo "⚠️ tsconfig.base.esm.json not found"
fi

Length of output: 816


Add composite and incremental flags to the ESM base config

The base ESM tsconfig (typescript/tsconfig.base.esm.json) is missing both "composite": true and "incremental": true, so the per-package tsBuildInfoFile settings won’t take effect. Please add these flags under compilerOptions.

• File needing update:

  • typescript/tsconfig.base.esm.json

Suggested diff:

 {
   "compilerOptions": {
+    "composite": true,
+    "incremental": true,
     // …existing options…
   }
 }
🤖 Prompt for AI Agents
In typescript/tsconfig.base.esm.json, add the compilerOptions flags "composite":
true and "incremental": true to enable proper use of the tsBuildInfoFile in
extending configs like typescript/packages/traceai_langchain/tsconfig.esm.json.
Locate the "compilerOptions" section and insert these two flags to ensure
incremental builds and composite project support are enabled.

Comment on lines +45 to +46
import { register, ProjectType, EvalTag, EvalName, EvalSpanKind } from '@traceai/fi-core';

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix missing imports in documentation
Examples use EvalTagType and ModelChoices but don’t import them.

Apply:

-import { register, ProjectType, EvalTag, EvalName, EvalSpanKind } from '@traceai/fi-core';
+import { register, ProjectType, EvalTag, EvalTagType, EvalName, EvalSpanKind, ModelChoices } from '@traceai/fi-core';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { register, ProjectType, EvalTag, EvalName, EvalSpanKind } from '@traceai/fi-core';
import { register, ProjectType, EvalTag, EvalTagType, EvalName, EvalSpanKind, ModelChoices } from '@traceai/fi-core';
🤖 Prompt for AI Agents
In typescript/packages/fi-core/README.md around lines 45 to 46, the import
statement is missing EvalTagType and ModelChoices which are used in the
examples. Update the import line to include EvalTagType and ModelChoices from
'@traceai/fi-core' to ensure all referenced types are properly imported in the
documentation.

apiKey: process.env.OPENAI_API_KEY,
});

console.log("OpenAI client initialized. Instrumentation patched:", (openaiInstrumentation as any).isPatched?.());
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid accessing private properties.

The code accesses the private property isPatched using type assertion (openaiInstrumentation as any). This relies on internal implementation details that may change.

-console.log("OpenAI client initialized. Instrumentation patched:", (openaiInstrumentation as any).isPatched?.());
+console.log("OpenAI client initialized. Instrumentation registered.");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log("OpenAI client initialized. Instrumentation patched:", (openaiInstrumentation as any).isPatched?.());
console.log("OpenAI client initialized. Instrumentation registered.");
🤖 Prompt for AI Agents
In typescript/packages/traceai_openai/examples/manual.ts at line 42, avoid
accessing the private property isPatched on openaiInstrumentation using type
assertion. Instead, refactor the code to use a public method or property
provided by the openaiInstrumentation object to check if it is patched, or add a
proper accessor if needed, to prevent reliance on internal implementation
details.

Comment on lines +310 to +319
// Give time for spans to be exported
setTimeout(async () => {
try {
await tracerProvider.shutdown();
console.log("Tracer provider shut down successfully.");
} catch (error) {
console.error("Error shutting down tracer provider:", error);
}
}, 2000);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve shutdown mechanism for reliable span export.

The current setTimeout approach doesn't guarantee all spans are exported before the process exits. Consider using a more reliable shutdown pattern.

     } finally {
-        // Give time for spans to be exported
-        setTimeout(async () => {
-            try {
-                await tracerProvider.shutdown();
-                console.log("Tracer provider shut down successfully.");
-            } catch (error) {
-                console.error("Error shutting down tracer provider:", error);
-            }
-        }, 2000);
+        // Ensure all spans are exported before exit
+        console.log("Shutting down tracer provider...");
+        try {
+            // Give a reasonable timeout for span export
+            await Promise.race([
+                tracerProvider.shutdown(),
+                new Promise((_, reject) => 
+                    setTimeout(() => reject(new Error("Shutdown timeout")), 5000)
+                )
+            ]);
+            console.log("Tracer provider shut down successfully.");
+        } catch (error) {
+            console.error("Error shutting down tracer provider:", error);
+        }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Give time for spans to be exported
setTimeout(async () => {
try {
await tracerProvider.shutdown();
console.log("Tracer provider shut down successfully.");
} catch (error) {
console.error("Error shutting down tracer provider:", error);
}
}, 2000);
}
} finally {
// Ensure all spans are exported before exit
console.log("Shutting down tracer provider...");
try {
// Give a reasonable timeout for span export
await Promise.race([
tracerProvider.shutdown(),
new Promise((_, reject) =>
setTimeout(() => reject(new Error("Shutdown timeout")), 5000)
)
]);
console.log("Tracer provider shut down successfully.");
} catch (error) {
console.error("Error shutting down tracer provider:", error);
}
}
🤖 Prompt for AI Agents
In typescript/packages/traceai_openai/examples/manual.ts around lines 310 to
319, the current use of setTimeout to delay shutdown does not reliably ensure
all spans are exported before the process exits. Replace the setTimeout with a
proper asynchronous shutdown sequence that awaits the tracerProvider.shutdown()
call directly and only exits the process after confirming shutdown completion,
avoiding arbitrary delays and improving reliability.

Comment on lines +116 to +177
async function processWithAnalysis(prompt: string) {
return tracer.startActiveSpan("ai-processing-pipeline", async (pipelineSpan) => {
pipelineSpan.setAttribute("fi.span.kind", "chain");

console.log("Starting auto-instrumented OpenAI call in processing pipeline");

// Auto-instrumented OpenAI call
const response = await openai.chat.completions.create({
messages: [{ role: "user", content: prompt }],
model: "gpt-4o-mini",
});

// Get the currently active span (could be the auto-created OpenAI span)
const currentSpan = trace.getActiveSpan();
if (currentSpan) {
console.log("Found active span, adding analysis flag");
currentSpan.setAttribute("custom.analysis.enabled", true);
} else {
console.log("No active span found in processing pipeline");
}

// Create manual analysis spans as children
const content = response.choices[0]?.message?.content || "";

await tracer.startActiveSpan("content-analysis", async (analysisSpan) => {
analysisSpan.setAttribute("fi.span.kind", "tool");
analysisSpan.setAttribute("analysis.content.length", content.length);
analysisSpan.setAttribute("analysis.word.count", content.split(' ').length);

// Simulate analysis work
await new Promise(resolve => setTimeout(resolve, 100));

analysisSpan.addEvent("Content analysis completed", {
"sentiment": "positive",
"complexity": "medium"
});

analysisSpan.end();
});

await tracer.startActiveSpan("content-validation", async (validationSpan) => {
validationSpan.setAttribute("fi.span.kind", "tool");

// Simulate validation
const isValid = content.length > 10;
validationSpan.setAttribute("validation.result", isValid);
validationSpan.setAttribute("validation.criteria", "min_length_check");

if (!isValid) {
validationSpan.setStatus({
code: 2,
message: "Content validation failed"
});
}

validationSpan.end();
});

pipelineSpan.end();
return response;
});
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling to ensure spans are properly closed.

The function lacks try-catch-finally blocks to ensure spans are properly closed in case of errors, which could lead to memory leaks or incomplete traces.

 async function processWithAnalysis(prompt: string) {
     return tracer.startActiveSpan("ai-processing-pipeline", async (pipelineSpan) => {
         pipelineSpan.setAttribute("fi.span.kind", "chain");
         
         console.log("Starting auto-instrumented OpenAI call in processing pipeline");
         
+        try {
             // Auto-instrumented OpenAI call
             const response = await openai.chat.completions.create({
                 messages: [{ role: "user", content: prompt }],
                 model: "gpt-4o-mini",
             });
             
             // ... rest of the function logic ...
             
-            pipelineSpan.end();
             return response;
+        } catch (error) {
+            pipelineSpan.recordException(error as Error);
+            pipelineSpan.setStatus({ 
+                code: 2, 
+                message: `Processing pipeline failed: ${(error as Error).message}` 
+            });
+            throw error;
+        } finally {
+            pipelineSpan.end();
+        }
     });
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function processWithAnalysis(prompt: string) {
return tracer.startActiveSpan("ai-processing-pipeline", async (pipelineSpan) => {
pipelineSpan.setAttribute("fi.span.kind", "chain");
console.log("Starting auto-instrumented OpenAI call in processing pipeline");
// Auto-instrumented OpenAI call
const response = await openai.chat.completions.create({
messages: [{ role: "user", content: prompt }],
model: "gpt-4o-mini",
});
// Get the currently active span (could be the auto-created OpenAI span)
const currentSpan = trace.getActiveSpan();
if (currentSpan) {
console.log("Found active span, adding analysis flag");
currentSpan.setAttribute("custom.analysis.enabled", true);
} else {
console.log("No active span found in processing pipeline");
}
// Create manual analysis spans as children
const content = response.choices[0]?.message?.content || "";
await tracer.startActiveSpan("content-analysis", async (analysisSpan) => {
analysisSpan.setAttribute("fi.span.kind", "tool");
analysisSpan.setAttribute("analysis.content.length", content.length);
analysisSpan.setAttribute("analysis.word.count", content.split(' ').length);
// Simulate analysis work
await new Promise(resolve => setTimeout(resolve, 100));
analysisSpan.addEvent("Content analysis completed", {
"sentiment": "positive",
"complexity": "medium"
});
analysisSpan.end();
});
await tracer.startActiveSpan("content-validation", async (validationSpan) => {
validationSpan.setAttribute("fi.span.kind", "tool");
// Simulate validation
const isValid = content.length > 10;
validationSpan.setAttribute("validation.result", isValid);
validationSpan.setAttribute("validation.criteria", "min_length_check");
if (!isValid) {
validationSpan.setStatus({
code: 2,
message: "Content validation failed"
});
}
validationSpan.end();
});
pipelineSpan.end();
return response;
});
}
async function processWithAnalysis(prompt: string) {
return tracer.startActiveSpan("ai-processing-pipeline", async (pipelineSpan) => {
pipelineSpan.setAttribute("fi.span.kind", "chain");
console.log("Starting auto-instrumented OpenAI call in processing pipeline");
try {
// Auto-instrumented OpenAI call
const response = await openai.chat.completions.create({
messages: [{ role: "user", content: prompt }],
model: "gpt-4o-mini",
});
// Get the currently active span (could be the auto-created OpenAI span)
const currentSpan = trace.getActiveSpan();
if (currentSpan) {
console.log("Found active span, adding analysis flag");
currentSpan.setAttribute("custom.analysis.enabled", true);
} else {
console.log("No active span found in processing pipeline");
}
// Create manual analysis spans as children
const content = response.choices[0]?.message?.content || "";
await tracer.startActiveSpan("content-analysis", async (analysisSpan) => {
analysisSpan.setAttribute("fi.span.kind", "tool");
analysisSpan.setAttribute("analysis.content.length", content.length);
analysisSpan.setAttribute("analysis.word.count", content.split(' ').length);
// Simulate analysis work
await new Promise(resolve => setTimeout(resolve, 100));
analysisSpan.addEvent("Content analysis completed", {
"sentiment": "positive",
"complexity": "medium"
});
analysisSpan.end();
});
await tracer.startActiveSpan("content-validation", async (validationSpan) => {
validationSpan.setAttribute("fi.span.kind", "tool");
// Simulate validation
const isValid = content.length > 10;
validationSpan.setAttribute("validation.result", isValid);
validationSpan.setAttribute("validation.criteria", "min_length_check");
if (!isValid) {
validationSpan.setStatus({
code: 2,
message: "Content validation failed"
});
}
validationSpan.end();
});
return response;
} catch (error) {
pipelineSpan.recordException(error as Error);
pipelineSpan.setStatus({
code: 2,
message: `Processing pipeline failed: ${(error as Error).message}`
});
throw error;
} finally {
pipelineSpan.end();
}
});
}
🤖 Prompt for AI Agents
In typescript/packages/traceai_openai/examples/manual.ts between lines 116 and
177, the processWithAnalysis function lacks error handling around the span
usage, risking spans not being closed on exceptions. Wrap the main logic inside
the tracer.startActiveSpan callback in a try block, use catch to handle errors
appropriately, and ensure each span (pipelineSpan, analysisSpan, validationSpan)
is ended in a finally block to guarantee proper closure regardless of errors.

Comment on lines +180 to +241
async function chainedOperations() {
return tracer.startActiveSpan("chained-ai-operations", async (rootSpan) => {
rootSpan.setAttribute("fi.span.kind", "chain");

console.log("Starting first auto-instrumented operation");

// First operation - auto-instrumented
const firstResponse = await openai.chat.completions.create({
messages: [{ role: "user", content: "Generate a creative story title" }],
model: "gpt-4o-mini",
});

// Extract the title and use it in manual processing
const title = firstResponse.choices[0]?.message?.content || "";

// Manual span that uses context from the auto-instrumented span
await tracer.startActiveSpan("title-processing", async (processingSpan) => {
processingSpan.setAttribute("fi.span.kind", "tool");
processingSpan.setAttribute("processing.input", title);

// Get active span context for correlation
const activeSpan = trace.getActiveSpan();
if (activeSpan) {
const spanContext = activeSpan.spanContext();
processingSpan.setAttribute("correlation.parent.trace_id", spanContext.traceId);
processingSpan.setAttribute("correlation.parent.span_id", spanContext.spanId);
}

// Process the title
const processedTitle = title.toUpperCase().trim();
processingSpan.setAttribute("processing.output", processedTitle);

processingSpan.end();

console.log("Starting second auto-instrumented operation with processed title");

// Second auto-instrumented operation using processed result
const storyResponse = await openai.chat.completions.create({
messages: [{
role: "user",
content: `Write a short story with the title: "${processedTitle}"`
}],
model: "gpt-4o-mini",
});

// Enhance the auto-created span for the second call
const currentSpan = trace.getActiveSpan();
if (currentSpan) {
console.log("Enhancing second auto-created span with story metadata");
currentSpan.setAttribute("custom.story.title", processedTitle);
currentSpan.setAttribute("custom.story.word_count",
storyResponse.choices[0]?.message?.content?.split(' ').length || 0);
} else {
console.log("No active span found for second OpenAI call");
}

return storyResponse;
});

rootSpan.end();
});
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix missing return statement and add error handling.

The function doesn't return the result from the inner async operation and lacks error handling.

 async function chainedOperations() {
     return tracer.startActiveSpan("chained-ai-operations", async (rootSpan) => {
         rootSpan.setAttribute("fi.span.kind", "chain");
         
+        try {
             console.log("Starting first auto-instrumented operation");
             
             // ... existing code ...
             
             // Manual span that uses context from the auto-instrumented span
-            await tracer.startActiveSpan("title-processing", async (processingSpan) => {
+            const result = await tracer.startActiveSpan("title-processing", async (processingSpan) => {
                 // ... existing code ...
                 
                 return storyResponse;
             });
             
-            rootSpan.end();
+            return result;
+        } catch (error) {
+            rootSpan.recordException(error as Error);
+            rootSpan.setStatus({ 
+                code: 2, 
+                message: `Chained operations failed: ${(error as Error).message}` 
+            });
+            throw error;
+        } finally {
+            rootSpan.end();
+        }
     });
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async function chainedOperations() {
return tracer.startActiveSpan("chained-ai-operations", async (rootSpan) => {
rootSpan.setAttribute("fi.span.kind", "chain");
console.log("Starting first auto-instrumented operation");
// First operation - auto-instrumented
const firstResponse = await openai.chat.completions.create({
messages: [{ role: "user", content: "Generate a creative story title" }],
model: "gpt-4o-mini",
});
// Extract the title and use it in manual processing
const title = firstResponse.choices[0]?.message?.content || "";
// Manual span that uses context from the auto-instrumented span
await tracer.startActiveSpan("title-processing", async (processingSpan) => {
processingSpan.setAttribute("fi.span.kind", "tool");
processingSpan.setAttribute("processing.input", title);
// Get active span context for correlation
const activeSpan = trace.getActiveSpan();
if (activeSpan) {
const spanContext = activeSpan.spanContext();
processingSpan.setAttribute("correlation.parent.trace_id", spanContext.traceId);
processingSpan.setAttribute("correlation.parent.span_id", spanContext.spanId);
}
// Process the title
const processedTitle = title.toUpperCase().trim();
processingSpan.setAttribute("processing.output", processedTitle);
processingSpan.end();
console.log("Starting second auto-instrumented operation with processed title");
// Second auto-instrumented operation using processed result
const storyResponse = await openai.chat.completions.create({
messages: [{
role: "user",
content: `Write a short story with the title: "${processedTitle}"`
}],
model: "gpt-4o-mini",
});
// Enhance the auto-created span for the second call
const currentSpan = trace.getActiveSpan();
if (currentSpan) {
console.log("Enhancing second auto-created span with story metadata");
currentSpan.setAttribute("custom.story.title", processedTitle);
currentSpan.setAttribute("custom.story.word_count",
storyResponse.choices[0]?.message?.content?.split(' ').length || 0);
} else {
console.log("No active span found for second OpenAI call");
}
return storyResponse;
});
rootSpan.end();
});
}
async function chainedOperations() {
return tracer.startActiveSpan("chained-ai-operations", async (rootSpan) => {
rootSpan.setAttribute("fi.span.kind", "chain");
try {
console.log("Starting first auto-instrumented operation");
// First operation - auto-instrumented
const firstResponse = await openai.chat.completions.create({
messages: [{ role: "user", content: "Generate a creative story title" }],
model: "gpt-4o-mini",
});
// Extract the title and use it in manual processing
const title = firstResponse.choices[0]?.message?.content || "";
// Manual span that uses context from the auto-instrumented span
const result = await tracer.startActiveSpan("title-processing", async (processingSpan) => {
processingSpan.setAttribute("fi.span.kind", "tool");
processingSpan.setAttribute("processing.input", title);
// Get active span context for correlation
const activeSpan = trace.getActiveSpan();
if (activeSpan) {
const spanContext = activeSpan.spanContext();
processingSpan.setAttribute("correlation.parent.trace_id", spanContext.traceId);
processingSpan.setAttribute("correlation.parent.span_id", spanContext.spanId);
}
// Process the title
const processedTitle = title.toUpperCase().trim();
processingSpan.setAttribute("processing.output", processedTitle);
processingSpan.end();
console.log("Starting second auto-instrumented operation with processed title");
// Second auto-instrumented operation using processed result
const storyResponse = await openai.chat.completions.create({
messages: [
{
role: "user",
content: `Write a short story with the title: "${processedTitle}"`,
},
],
model: "gpt-4o-mini",
});
// Enhance the auto-created span for the second call
const currentSpan = trace.getActiveSpan();
if (currentSpan) {
console.log("Enhancing second auto-created span with story metadata");
currentSpan.setAttribute("custom.story.title", processedTitle);
currentSpan.setAttribute(
"custom.story.word_count",
storyResponse.choices[0]?.message?.content?.split(" ").length || 0
);
} else {
console.log("No active span found for second OpenAI call");
}
return storyResponse;
});
return result;
} catch (error) {
rootSpan.recordException(error as Error);
rootSpan.setStatus({
code: 2,
message: `Chained operations failed: ${(error as Error).message}`,
});
throw error;
} finally {
rootSpan.end();
}
});
}
🤖 Prompt for AI Agents
In typescript/packages/traceai_openai/examples/manual.ts around lines 180 to
241, the chainedOperations function is missing a return statement for the result
of the inner async operation inside the manual span, causing it not to return
the final storyResponse. Additionally, it lacks error handling. Fix this by
adding a return statement before the inner tracer.startActiveSpan call to return
the storyResponse, and wrap the entire function body in a try-catch block to
catch and handle errors appropriately, such as logging the error and rethrowing
or returning a fallback value.

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