Skip to content

Split/1 cli prompt store constants#503

Merged
VaibhavUpreti merged 9 commits intomainfrom
split/1-cli-prompt-store-constants
Apr 8, 2026
Merged

Split/1 cli prompt store constants#503
VaibhavUpreti merged 9 commits intomainfrom
split/1-cli-prompt-store-constants

Conversation

@davincios
Copy link
Copy Markdown
Contributor

Fixes #

Describe the changes you have made in this PR -

Screenshots of the UI changes (If any) -


Code Understanding and AI Usage

Did you use AI assistance (ChatGPT, Claude, Copilot, etc.) to write any part of this code?

  • No, I wrote all the code myself
  • Yes, I used AI assistance (continue below)

If you used AI assistance:

  • I have reviewed every single line of the AI-generated code
  • I can explain the purpose and logic of each function/component I added
  • I have tested edge cases and understand how the code handles them
  • I have modified the AI output to follow this project's coding standards and conventions

Explain your implementation approach:


Checklist before requesting a review

  • I have added proper PR title and linked to the issue
  • I have performed a self-review of my code
  • I can explain the purpose of every function, class, and logic block I added
  • I understand why my changes work and have tested them thoroughly
  • I have considered potential edge cases and how my code handles them
  • If it is a core feature, I have added thorough tests
  • My code follows the project's style guidelines and conventions

Note: Please check Allow edits from maintainers if you would like us to assist in the PR.

…pport

- Switch LangGraph stream_mode from ["updates"] to ["events"] for fine-grained
  tool calls, LLM reasoning, and chain transitions in real-time
- Add reasoning mapper (app/remote/reasoning.py) to translate events into
  human-readable spinner subtext (replaces fake cycling verbs)
- Enhance StreamRenderer and _LiveSpinner to show live tool calls and LLM
  reasoning instead of cosmetic placeholders
- Add astream_investigation() async runner and CLI bridge for local streaming
  with the same UX as remote
- Add POST /investigate/stream SSE endpoint to the lightweight FastAPI server
- Make opensre deploy fully interactive: context-aware menu, health check,
  confirmation prompts, branch selection
- Add named remotes to the wizard store so multiple remote endpoints (ec2,
  staging, local) can coexist with an active selection
- Deploy always saves the EC2 URL as a named remote and sets it active
- opensre remote shows a remote picker when multiple remotes are configured

Made-with: Cursor
…ions

Empty investigation reports were caused by two bugs:

1. _save_investigation used result.get('key', 'N/A') which returns ""
   when the key exists but is empty, instead of the 'N/A' fallback.
   Fixed with `or 'N/A'` to treat empty strings as missing.

2. Noise-classified alerts routed to END before diagnose/publish ran,
   leaving root_cause, report, and problem_md as "". Now propagates
   is_noise through the result dict and writes an explanatory message.

Also adds interactive investigation browser (select + view + save)
and persists streamed investigation results as .md files.

Made-with: Cursor
Keep managed EC2 deployment state in app-owned local storage, preserve streamed investigations on disconnect, and surface local streaming failures promptly so the remote CLI can stay stream-first and merge-ready.

Made-with: Cursor
Redact api_token values in integration show output and allow vercel records to be shown through the managed integrations CLI so credentials are not exposed during inspection.

Made-with: Cursor
Support Vercel incident discovery and RCA from the CLI and remote server so deployment failures can be selected, investigated, and correlated with GitHub code context.

Made-with: Cursor
Use the project-scoped Vercel runtime log API and structured error fields so the CLI finds the same incidents users see in the dashboard. Add loading feedback after project selection and keep the Vercel RCA tests aligned with the updated behavior.

Made-with: Cursor
Resolve the PR conflicts by keeping the Vercel RCA flows, setup verification behavior, and remote server integrations while bringing in the latest main-branch updates.

Made-with: Cursor
- Add INTEGRATIONS_STORE_PATH and shared home constants; wire integrations store.

- Add prompt_support (questionary escape/cancel) for opensre and wizard entrypoints.

- Wizard prompt/store tweaks and tests; daily-update workflow and Makefile.

Made-with: Cursor
Comment thread app/services/vercel/client.py Fixed
Comment thread app/cli/prompt_support.py Fixed
Comment thread app/integrations/cli.py Fixed
Comment thread app/integrations/cli.py Fixed
Comment thread app/remote/server.py Fixed
Comment thread app/cli/prompt_support.py Fixed
Comment thread app/integrations/cli.py Fixed
Comment thread app/integrations/cli.py Fixed
Comment thread app/remote/server.py Fixed
Resolve conflicts by aligning integrations CLI, Vercel client (streaming runtime logs), poller, VercelLogsTool, and tests with main; remove the obsolete vercel incident subcommand from the branch side.

Made-with: Cursor
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 8, 2026

Greptile Summary

This PR introduces app/integrations/vercel_incidents.py, a new interactive CLI module for browsing Vercel incidents and running or viewing RCA reports, backed by a ~/.tracer/investigations/vercel/ cache directory. A companion test file covers the JSON output path, error handling, project scoping, timestamp formatting, and the view/run/back action loop.

Confidence Score: 5/5

Safe to merge; all findings are minor style suggestions with no correctness or reliability impact.

The new module is logically correct: error paths are caught and surfaced via _die, cache reads/writes are consistent, and the interactive loop handles every action branch. The three P2 findings (dead return after _die, implicit fall-through after run, and a spurious monkeypatch in one test) are cosmetic and do not affect runtime behaviour.

No files require special attention.

Vulnerabilities

No security concerns identified. The module reads and writes files under a well-defined user-home subdirectory, does not execute shell commands, and delegates network calls to the existing make_vercel_client and collect_vercel_candidates abstractions.

Important Files Changed

Filename Overview
app/integrations/vercel_incidents.py New module providing interactive CLI helpers for Vercel incidents and RCA reports; logic is sound, but _die() should be typed -> Never and the unreachable return statements after each _die() call should be removed.
tests/integrations/test_vercel_incidents.py Good test coverage for the happy path, error handling, and cache round-trip; one unnecessary monkeypatch (resolve_vercel_config) in the JSON-output test adds noise without providing signal.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[cmd_vercel_incidents] --> B{is_json_output?}
    B -- Yes --> C[_load_incidents]
    C --> D[collect_vercel_candidates]
    D --> E[_json_echo payloads]
    B -- No --> F[_load_projects]
    F --> G[_select_project]
    G -- None/exit --> Z[return]
    G -- project selected --> H[_load_incidents_with_status]
    H --> I{any candidates?}
    I -- No --> Z
    I -- Yes --> J[_select_incident]
    J -- None/exit --> Z
    J -- _refresh --> H
    J -- candidate --> K[_incident_actions]
    K --> L{action}
    L -- view --> M[_load_cached_report / _render_report]
    L -- run --> N[_execute_rca]
    N --> O[run_investigation_cli_streaming]
    O --> P[_save_report]
    L -- back --> Z
    L -- exit --> Z
    M --> L
    P --> L
Loading
Prompt To Fix All With AI
This is a comment left during a code review.
Path: app/integrations/vercel_incidents.py
Line: 348-349

Comment:
**Unreachable `return` after `_die()`**

`_die()` unconditionally raises `SystemExit`, so the `return` on the next line (and the two similar ones at lines 369–370 and 388–389) can never be reached. Consider annotating `_die` with `-> Never` (from `typing`) so type-checkers confirm this, and drop the dead `return` statements.

```suggestion
        _die(f"{exc} {_repair_hint()}")
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: app/integrations/vercel_incidents.py
Line: 226-228

Comment:
**Implicit fall-through after `run` action**

After `_execute_rca(candidate)` the loop continues implicitly because there is no `continue`. This works correctly today, but an explicit `continue` would make the intent unambiguous and prevent a future `else`/`return` from being accidentally inserted between the two clauses.

```suggestion
        if action == "run":
            _execute_rca(candidate)
            continue
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: tests/integrations/test_vercel_incidents.py
Line: 59-62

Comment:
**Unnecessary `resolve_vercel_config` patch in JSON test**

When `is_json_output()` returns `True`, `cmd_vercel_incidents` calls `_load_incidents → collect_vercel_candidates` directly and never reaches `_load_projects`, which is the only call site for `resolve_vercel_config`. The patch here is dead weight and may mislead future readers into thinking the JSON path depends on that config resolver.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Merge branch 'main' into split/1-cli-pro..." | Re-trigger Greptile

Comment on lines +348 to +349
_die(f"{exc} {_repair_hint()}")
return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Unreachable return after _die()

_die() unconditionally raises SystemExit, so the return on the next line (and the two similar ones at lines 369–370 and 388–389) can never be reached. Consider annotating _die with -> Never (from typing) so type-checkers confirm this, and drop the dead return statements.

Suggested change
_die(f"{exc} {_repair_hint()}")
return
_die(f"{exc} {_repair_hint()}")
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/integrations/vercel_incidents.py
Line: 348-349

Comment:
**Unreachable `return` after `_die()`**

`_die()` unconditionally raises `SystemExit`, so the `return` on the next line (and the two similar ones at lines 369–370 and 388–389) can never be reached. Consider annotating `_die` with `-> Never` (from `typing`) so type-checkers confirm this, and drop the dead `return` statements.

```suggestion
        _die(f"{exc} {_repair_hint()}")
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +226 to +228
if action == "run":
_execute_rca(candidate)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Implicit fall-through after run action

After _execute_rca(candidate) the loop continues implicitly because there is no continue. This works correctly today, but an explicit continue would make the intent unambiguous and prevent a future else/return from being accidentally inserted between the two clauses.

Suggested change
if action == "run":
_execute_rca(candidate)
if action == "run":
_execute_rca(candidate)
continue
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/integrations/vercel_incidents.py
Line: 226-228

Comment:
**Implicit fall-through after `run` action**

After `_execute_rca(candidate)` the loop continues implicitly because there is no `continue`. This works correctly today, but an explicit `continue` would make the intent unambiguous and prevent a future `else`/`return` from being accidentally inserted between the two clauses.

```suggestion
        if action == "run":
            _execute_rca(candidate)
            continue
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +59 to +62
monkeypatch.setattr(
"app.integrations.vercel_incidents.resolve_vercel_config",
lambda: VercelConfig(api_token="tok_test", team_id=""),
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Unnecessary resolve_vercel_config patch in JSON test

When is_json_output() returns True, cmd_vercel_incidents calls _load_incidents → collect_vercel_candidates directly and never reaches _load_projects, which is the only call site for resolve_vercel_config. The patch here is dead weight and may mislead future readers into thinking the JSON path depends on that config resolver.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/integrations/test_vercel_incidents.py
Line: 59-62

Comment:
**Unnecessary `resolve_vercel_config` patch in JSON test**

When `is_json_output()` returns `True`, `cmd_vercel_incidents` calls `_load_incidents → collect_vercel_candidates` directly and never reaches `_load_projects`, which is the only call site for `resolve_vercel_config`. The patch here is dead weight and may mislead future readers into thinking the JSON path depends on that config resolver.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Member

@VaibhavUpreti VaibhavUpreti left a comment

Choose a reason for hiding this comment

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

Merging this for now; the rest of the changes can be added in a new PR to maintain velocity

@VaibhavUpreti VaibhavUpreti merged commit aa0cb35 into main Apr 8, 2026
9 checks passed
@VaibhavUpreti VaibhavUpreti deleted the split/1-cli-prompt-store-constants branch April 8, 2026 11:15
mayankbharati-ops added a commit to mayankbharati-ops/opensre that referenced this pull request Apr 27, 2026
… drop redundant header, fix CodeQL

- slack_delivery `_post_direct` exception log key reverted to ``type=%s``
  (matching the exact pre-refactor format ``type=%s channel=%s
  thread_ts=%s detail=%s``) so existing log parsers that key off
  ``type=`` keep working. Per @muddlebee's nit on PR Tracer-Cloud#952.
- DeliveryResponse field renamed ``error_type`` → ``exc_type``. Pythonic
  abbreviation for "exception type"; can't be ``type`` because that
  shadows the builtin. Field/log-key are intentionally distinct: the
  field is the Python attribute, the log key matches the legacy format.
- Drop ``Content-Type: application/json; charset=utf-8`` from
  ``_slack_bearer_headers`` and ``_discord_auth_headers``. ``httpx.post``
  already sets ``Content-Type: application/json`` automatically when the
  request uses the ``json=`` kwarg, so the explicit header was
  redundant. No behavioural change for Slack/Discord (UTF-8 is httpx's
  default encoding and neither provider parses the charset suffix).
- Fix CodeQL py/import-and-import-from alerts on tests Tracer-Cloud#503/Tracer-Cloud#504. The
  ``test_module_does_not_import_httpx`` regression test in each
  delivery test file was importing the module under test via both
  ``import X as mod`` and ``from X import Y`` styles. Switched to a
  single ``from app.utils import <module>`` style so the same module
  is no longer dual-imported.

Test count unchanged (3208 pass / 2 skipped / 1 xfail). Lint, format,
and ``mypy app/utils/`` clean.
muddlebee pushed a commit that referenced this pull request Apr 28, 2026
…#952)

* refactor(utils): extract shared HTTP-post helper for delivery modules

Closes #864.

``app/utils/slack_delivery.py``, ``app/utils/discord_delivery.py``, and
``app/utils/telegram_delivery.py`` each issued ``httpx.post`` directly,
applied a per-provider timeout, parsed the response body, and converted
exceptions to ``(False, error, ...)`` tuples. The transport pieces were
identical; only the success criteria, auth scheme, and error-message
extraction differed per provider.

Add ``app/utils/delivery_transport.py`` with ``post_json`` plus a
``DeliveryResponse`` dataclass that captures the shared transport
behavior: HTTP POST, timeout, optional ``follow_redirects``, exception
suppression, and JSON decoding with graceful fallback. The helper
deliberately does not decide provider-level success — callers inspect
``status_code`` / ``data`` per their own semantics.

Refactored callers:

- Slack: ``_call_reactions_api``, ``_post_direct``, ``_post_via_webapp``,
  ``_post_via_incoming_webhook`` — all four code paths now go through
  ``post_json``. ``send_slack_report`` orchestration unchanged.
- Discord: ``post_discord_message``, ``create_discord_thread`` — same
  Bearer/Bot header pattern factored into ``_discord_auth_headers``.
- Telegram: ``post_telegram_message`` — bot-token redaction in error
  messages preserved by re-running ``_redact_token`` over
  ``response.error``.

Provider-specific payload building, success criteria
(``data["ok"]`` for Slack, status codes for Discord/Telegram), and
error extraction all stay in the calling modules. Public function
signatures are unchanged.

Tests:

- ``tests/utils/test_delivery_transport.py`` (new) — 15 tests covering
  happy path, every transport-failure shape (httpx.ConnectError,
  ReadTimeout, RequestError, OSError, RuntimeError), JSON-decode
  fallbacks (non-JSON body, JSON array, empty body), header / timeout /
  follow_redirects pass-through, and DeliveryResponse frozen-dataclass
  invariants.
- ``tests/utils/test_slack_delivery.py`` (new) — 24 tests covering all
  four Slack code paths, ``send_slack_report`` orchestration, and
  fallback chain ``direct → webapp``.
- ``tests/utils/test_discord_delivery.py`` (extended) — 3 new tests
  pinning the helper-delegation contract: module no longer imports
  ``httpx``, ``post_discord_message`` and ``create_discord_thread``
  both go through ``post_json``.
- ``tests/utils/test_telegram_delivery.py`` (extended) — 3 new tests
  pinning the same contract plus a regression test that the bot-token
  is redacted out of error strings even when the failure originates
  from the shared transport.
- All pre-existing tests in ``test_discord_delivery.py`` and
  ``test_telegram_delivery.py`` updated to patch
  ``app.utils.delivery_transport.httpx.post`` (the new transport
  boundary) instead of the per-module ``httpx.post`` import that no
  longer exists.

Verification:

- ``pytest tests/``: 3191 pass, 2 skipped, 1 xfailed, 0 failures.
- ``pytest tests/utils/``: 105 pass, 1 skipped (was 32 + 26 = 58 across
  delivery modules; now 105 with helper + Slack additions).
- ``ruff check app/ tests/`` and ``ruff format --check``: clean.
- ``mypy app/utils/``: clean on touched modules; the 5 reported errors
  are pre-existing missing-stub warnings in
  ``app/integrations/{mariadb,mysql,hf_remote}`` unrelated to this PR.

* ci: retrigger after anyio/mcp circular-import flake

The previous CI run hit a known transient ImportError in
anyio.lowlevel/mcp when opensre integrations list ran on a
pytest-xdist worker. Reproduces zero times locally on origin/main and
on this branch; pushing an empty commit to re-run with a fresh
interpreter pool.

* fix(utils): address greptile review on delivery transport refactor

- Wrap `DeliveryResponse.data` in `MappingProxyType` so the frozen
  dataclass is fully immutable end-to-end. Mutating the parsed body
  now raises `TypeError` instead of silently succeeding, and caller-
  passed dicts can no longer leak mutations into the response.
- Add `error_type` field on `DeliveryResponse` populated with
  `type(exc).__name__` on transport failures. `slack_delivery._post_direct`
  threads it back into the exception log so on-call can distinguish
  `TimeoutError` from `ConnectionError` at a glance — restores the
  pre-refactor log shape that #864 had dropped.
- Add `TestDelegatesToSharedTransport` to `tests/utils/test_slack_delivery.py`,
  mirroring the regression class on the discord/telegram test files.
  Pins that `slack_delivery` does not import `httpx` and that all four
  code paths (`_call_reactions_api`, `_post_direct`, `_post_via_webapp`,
  `_post_via_incoming_webhook`) route through `delivery_transport.post_json`.
- Add focused tests for the immutable-data, error_type, and slack
  exc_type-log behaviours (+17 tests; 3208 pass / 2 skipped / 1 xfail).

Tighten `_discord_error_from_data` signature to `Mapping[str, Any]` so
mypy stays clean against the new read-only `data` type.

* refactor(utils): address review nits — restore log key, rename field, drop redundant header, fix CodeQL

- slack_delivery `_post_direct` exception log key reverted to ``type=%s``
  (matching the exact pre-refactor format ``type=%s channel=%s
  thread_ts=%s detail=%s``) so existing log parsers that key off
  ``type=`` keep working. Per @muddlebee's nit on PR #952.
- DeliveryResponse field renamed ``error_type`` → ``exc_type``. Pythonic
  abbreviation for "exception type"; can't be ``type`` because that
  shadows the builtin. Field/log-key are intentionally distinct: the
  field is the Python attribute, the log key matches the legacy format.
- Drop ``Content-Type: application/json; charset=utf-8`` from
  ``_slack_bearer_headers`` and ``_discord_auth_headers``. ``httpx.post``
  already sets ``Content-Type: application/json`` automatically when the
  request uses the ``json=`` kwarg, so the explicit header was
  redundant. No behavioural change for Slack/Discord (UTF-8 is httpx's
  default encoding and neither provider parses the charset suffix).
- Fix CodeQL py/import-and-import-from alerts on tests #503/#504. The
  ``test_module_does_not_import_httpx`` regression test in each
  delivery test file was importing the module under test via both
  ``import X as mod`` and ``from X import Y`` styles. Switched to a
  single ``from app.utils import <module>`` style so the same module
  is no longer dual-imported.

Test count unchanged (3208 pass / 2 skipped / 1 xfail). Lint, format,
and ``mypy app/utils/`` clean.

* fix(slack): restore charset=utf-8 — Slack emits missing_charset warning without it

Live e2e probe against real ``slack.com/api/chat.postMessage`` revealed
that dropping the explicit ``Content-Type: application/json; charset=utf-8``
header (per the previous nit-fix commit) caused Slack to add a
``missing_charset`` entry to ``response_metadata.warnings`` on every
request. httpx alone sets only the bare ``application/json`` for ``json=``
kwargs, but Slack's docs explicitly recommend the charset suffix
(https://api.slack.com/web#posting_json) and emit the warning otherwise.

Restored the ``charset=utf-8`` header on ``_slack_bearer_headers`` with
an inline comment explaining the reason. ``_discord_auth_headers`` stays
auth-only (Discord does not emit this warning, and its docs do not
require the charset suffix).

Pinned via direct header assertions on the two existing slack tests that
already captured headers (``test_sends_correct_url_and_headers`` for the
reactions API, ``test_sends_thread_reply_payload`` for chat.postMessage),
so a future regression that re-drops the charset will fail loudly.

Verified live:
- direct ``chat.postMessage`` probe now returns ``warnings=[]`` (was
  ``['missing_charset']`` before this commit).
- 38/38 live checks against real Slack / Discord / Telegram pass.
- 3208 unit tests pass; lint / format / mypy clean.
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