fix(deploy): trigger EC2 deploy on push to main instead of tags - #1
Open
Lokesh7025 wants to merge 1069 commits into
Open
fix(deploy): trigger EC2 deploy on push to main instead of tags#1Lokesh7025 wants to merge 1069 commits into
Lokesh7025 wants to merge 1069 commits into
Conversation
Screenshots captured via Playwright showing the edit form after all bugfixes (no IDE section, version bump dialog with server suggestions, dirty-gated actions). Refs: Observal#630 Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
) Full-viewport dialog for reviewing agent versions: - Two-pane layout: left (details) + right (diff or first-release JSON) - YamlDiffView with GitHub dark-mode colors (rgba tints, normal text) - Admin-gated delete button on review queue cards/rows - Nested reject-reason dialog with textarea - Playwright E2E screenshot spec for all three dialog states Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
- Query AgentVersion for pending status instead of joining on Agent.latest_version_id (which only updates on approval) - Use pending version's components for component_count and readiness check instead of the agent's current approved state - Fix all _check_agent_components_ready call sites to pass components list (fixes test_returns_422_when_components_not_ready) Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Cleaned up: - CL-06: extracted 5 repeated localStorage key strings to named constants in api.ts - CL-01: removed unreachable nullish coalescing in badge renders (ReviewCard, ReviewRow) Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
…bserval#636) - Add agent_version Nullable(String) column to traces, spans, scores - Add bloom_filter indexes for efficient point lookups - Extract observal.agent.version from OTLP resource attributes at ingest - Propagate agent_version to both trace and span rows - Add agent_version filter to query_traces() Clean break migration — alpha product, ADD COLUMN IF NOT EXISTS is safe. Refs: Observal#636 Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Three issues caused DELETE /api/v1/agents/{id} to fail:
1. Scorecard.penalties (lazy='raise') prevented cascade-delete — fixed
by eagerly loading penalties via selectinload before db.delete()
2. EvalRun.scorecards (lazy='raise') same issue — fixed with chained
selectinload(EvalRun.scorecards).selectinload(Scorecard.penalties)
3. Circular FK dependency (Agent.latest_version_id ↔ AgentVersion.agent_id)
caused CircularDependencyError — fixed by nulling latest_version_id,
then deleting versions and agent via SQL DELETE statements
Also fixes download_tracker setting Agent.download_count (now a read-only
compat property) — updated to set latest_version.download_count instead.
Closes Observal#666
Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
…bserval#667) Three issues prevented `observal agent pull` from working: 1. AgentResponse schema missing `latest_approved_version` and `latest_version` fields — CLI couldn't resolve which version to pull. Fixed by adding fields to schema and populating in _agent_to_response. 2. POST /api/v1/agents/{id}/install returned 500 when agent had no published version (download_tracker tried to set read-only property). Fixed by adding guard: returns 400 with clear message. 3. `observal agent pull` failed with 404 when version had no cached ide_configs. Fixed by adding fallback to install endpoint in CLI. Closes Observal#667 Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
…val#673) The full-featured pull command (with --scope, --model, --tools, --dry-run, --no-prompt, MCP env var prompting, setup commands, etc.) now lives under `observal agent pull` instead of the top-level `observal pull`. The old root command is removed. Fixes Observal#673 Signed-off-by: Hari Srinivasan <hari@blazeup.ai> Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
When both the legacy `observal` package and `observal-cli` are installed in the same environment, the CLI now detects the conflict at startup and exits with a clear message telling the user to uninstall the old package. Fixes Observal#671 Signed-off-by: Hari Srinivasan <hari@blazeup.ai> Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
- Fix version_callback to query "observal-cli" instead of "observal" (the old name would resolve to the conflicting legacy package) - Sync uv.lock with pyproject.toml (0.3.4 → 0.4.0) - Add `uv lock` step to release.sh so the lockfile stays in sync on future version bumps Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Add /api/v1/config/version endpoint returning server_version and min_cli_version. CLI checks this on `auth login` and `auth status`, printing upgrade instructions when the local CLI is outdated. Server operators can control the minimum via MIN_CLI_VERSION env var. Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Deploy was firing on every push to main, which pulled unreleased code onto the production server. Internal broke when main had migrations (0019-0022) that the v0.4.0 database didn't have. Now deploys only on v* tags and checks out the tagged ref instead of hard-resetting to origin/main. Signed-off-by: Lokesh Selvam <lokeshselvam7025@gmail.com>
…#678) Clear latest_version_id before deleting listings to avoid circular foreign key constraint violation. The cascade tries to delete versions while the listing still references one of them via latest_version_id. Affected: MCP, Sandbox, Skill, Hook, Prompt delete endpoints. Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
- Add missing model_name field to test agent creation (required field) - Fix "Save & Release" test to dirty the form before clicking (button is disabled when form is clean) Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Comprehensive serial e2e test covering: - Save Draft updates agent without version bump - Save & Release opens dialog and creates version 1.0.1 - New version appears as pending in versions list - Admin can approve version via review endpoint Refs: Observal#677, Observal#678 Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Adds a separate deployment workflow that triggers on every push to main, targeting the dev EC2 instance. Keeps Docker volumes intact across deploys so data is preserved. Signed-off-by: Lokesh Selvam <lokeshselvam7025@gmail.com>
Adds a separate deployment workflow that triggers on every push to main, targeting the dev EC2 instance at dev.observal.io. Includes: - deploy-dev.yml workflow using EC2_HOST_DEV / EC2_SSH_KEY_DEV secrets - docker-compose.dev.yml override (port 80, dev API URL) - nginx.dev.conf (HTTP-only reverse proxy) Keeps Docker volumes intact across deploys so data is preserved. Signed-off-by: Lokesh Selvam <lokeshselvam7025@gmail.com>
Signed-off-by: VishnuM449 <vishnu.muthiah04@gmail.com>
Replace Approve/Reject buttons on review queue cards with a single Review button that opens the detail sheet. Approve/Reject actions remain on the detail page. Closes Observal#688 Signed-off-by: Naraen Rammoorthi <naraen13@gmail.com>
…erval#684) Signed-off-by: Naraen Rammoorthi <naraen13@gmail.com>
…bserval#668) Previously, logging out from the UI or CLI only cleared local state. The hooks token (30-day JWT) and baked-in user_id in IDE hook configs meant traces kept flowing after logout. Changes: - Add POST /api/v1/auth/logout endpoint that blacklists the access token JTI and marks the user_id as revoked in Redis - Check revoked JTIs in get_current_user auth dependency (fail open) - Drop hook events silently for revoked user_ids in /telemetry/hooks - Check revoked JTIs in OTLP _resolve_project_id - UI calls logout endpoint before clearing localStorage - CLI calls logout endpoint before clearing config, shows unpatch hint - Clear user revocation on re-login so hooks resume after re-auth Fixes Observal#668 Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
…tables in deep copy (Observal#681) - Filter archive columns to target schema (extra columns skipped) - Schema version mismatch is a warning, not a hard exit - Validate stale .import_state.json against actual ClickHouse data - Backfill NULL owner_org_id from creator's user record - Add --project-id flag to rewrite project_id in Parquet files - Add otel_logs, security_events, webhook_deliveries to deep copy - Use all target schema columns for insertion (not just first row) - Use pa.nulls().fill_null() to avoid large list materialization Signed-off-by: Lokesh Selvam <lokeshselvam7025@gmail.com>
…rator When no --model flag is passed during pull, the config generator now falls back to the agent's model_name from the database instead of emitting no model line (which causes the IDE to use its default model). Signed-off-by: Lokesh Selvam <lokeshselvam7025@gmail.com>
Short names like "sonnet" resolve to the IDE's default version (4.5), not the specific version stored on the agent. Now passes through the full model ID (e.g. claude-sonnet-4-6) with only the date suffix stripped. Signed-off-by: Lokesh Selvam <lokeshselvam7025@gmail.com>
update_draft still referenced non-existent AgentComponent.agent_id and version_ref columns after the version-scoping migration. This caused 500 errors on any draft component update. Signed-off-by: Lokesh <lokeshselvam7025@gmail.com>
The legacy approve_agent/reject_agent routes checked agent.status which delegates to latest_version. After a new version is published (pending), latest_version still points to the old approved version, so approval always failed with "Agent is 'approved', not pending". Now both routes query for the newest pending AgentVersion directly. Approval also promotes latest_version_id using semver comparison (matching the version-router behavior). Signed-off-by: Lokesh <lokeshselvam7025@gmail.com>
… IDs claude-sonnet-4-6 (date-stripped) is not a valid model identifier for the IDE. The API rejects it with "The provided model identifier is invalid". Frontmatter needs either short names (sonnet, opus, haiku) or full API model IDs with date suffix. Now maps stored model_name to short names via keyword matching. Signed-off-by: Lokesh <lokeshselvam7025@gmail.com>
get_session route: after fetching parent events, also queries
WHERE parent_session_id = X, groups by session_id, and returns
subagent_sessions: [{session_id, spawned_by, events}].
spawned_by = parent_uuid of the subagent's first row — points at
the exact Agent tool_call in the parent that spawned it.
Frontend (traces/[id]/page.tsx):
- SubagentSession type added to types.ts
- InlineSubagentBlock: collapsible indigo block showing the
subagent's turns nested below the Agent tool_call that spawned it
- TurnNode: builds spawned_by uuid → subagent map, renders
InlineSubagentBlock inline after each Agent tool_call event
- subagentSessions prop threaded from page root down to TurnNode
- Legacy hook-based AgentNode kept for shim IDEs
insights (session_cache.py):
- fetch_session_metas_from_events wraps the direct agent_id query
in a UNION ALL with a subagent fallback: sessions whose
parent_session_id is in the agent's session set are included
even if their own agent_id is NULL (pre-attribution push).
Outer SELECT deduplicates by session_id.
Co-authored-by: Hari Srinivasan <harisrini21@gmail.com>
Signed-off-by: Shaan Narendran <shaannaren06@gmail.com>
Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
- facets.py: datetime.UTC alias, sort imports - metrics.py: datetime.UTC alias, collapse nested if (SIM102) - sections.py: sort imports Co-authored-by: Hari Srinivasan <harisrini21@gmail.com> Signed-off-by: Shaan Narendran <shaannaren06@gmail.com> Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Rename inner subquery aliases from start_time/end_time to s_start/s_end so the outer query's min()/max() aggregates don't resolve back to nested aggregate expressions. ClickHouse treats alias references as expression expansion, causing ILLEGAL_AGGREGATION when wrapping in another aggregate. Signed-off-by: Shaan Narendran <shaannaren06@gmail.com>
The hook was silently failing when the 1-hour access_token expired, causing total trace data loss until the user manually re-logged in. Changes: - load_config now prefers api_key (30-day) over access_token (1-hour) - post_to_server retries once on 401 using refresh_token rotation - Refreshed tokens are persisted to config.json for subsequent hooks - Timeout bumped to 10s for large backlog payloads Benchmarks (per-prompt hook): 241ms total, ~14KB payload. Auto-refresh adds ~226ms one-time when token is expired. Signed-off-by: Shaan Narendran <shaannaren06@gmail.com>
Subagent sessions (those with parent_session_id set) were appearing as independent entries in the trace list. They should only appear nested inside their parent session's detail view. Signed-off-by: Shaan Narendran <shaannaren06@gmail.com>
…n usage - Add registry catalog loading (`_load_registry_catalog`) to batch.py which queries public MCPs/skills with descriptions for LLM context - Add `_filter_catalog` in generator.py to exclude already-configured components before passing to the suggestions prompt - Wire `registry_catalog` through generate_report_content → _run_pipeline → generate_sections (injected only into suggestions prompt) - Expand suggestions prompt with REGISTRY and EXTERNAL MCP recommendation instructions including CLI commands and YAML snippets - Add per-section `_SECTION_MAX_TOKENS` to avoid wasting output capacity on smaller sections (512 for fun_ending vs 4096 for suggestions) - Fix tools_effective dict-key crash in aggregate_facets when LLM returns dicts instead of strings Signed-off-by: Shaan Narendran <shaannaren06@gmail.com>
The Stop hook fires before Claude Code finishes writing — ~5 lines (final assistant response with token usage, turn_duration, etc.) are written after the hook runs. Previously these were permanently lost because the cursor was marked finalized immediately. Now on Stop: push current lines without finalizing, then spawn a background subprocess (cmd_tail_flush) that sleeps 3s, reads any new tail bytes, pushes them, and marks finalized. Crash recovery remains as a safety net for network failures. Signed-off-by: Shaan Narendran <shaannaren06@gmail.com> Co-authored-by: Hari Srinivasan <harisrini21@gmail.com> Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
AggregatingMergeTree table (session_stats_agg) + materialized view (session_stats_mv) that fires on every INSERT block into session_events and maintains running sums/min/max per (project_id, session_id). The session list query (_list_sessions_query) now reads from session_stats_agg instead of scanning session_events FINAL with JSONExtract on every row. At ~1 tiny row per session, the aggregate table is orders of magnitude cheaper — ClickHouse's Bluesky benchmark shows pre-aggregated MVs reduce 44-second full-table scans to 6 ms (7,000x at 4B rows). Changes: - clickhouse.py: add session_stats_agg DDL and session_stats_mv to INIT_SQL - sessions.py: rewrite _list_sessions_query to query session_stats_agg; HAVING clause handles parent_session_id, time, and platform filters; no FINAL, no JSONExtract, no session_events scan Correctness note: the MV sees raw INSERT blocks not the deduplicated ReplacingMergeTree view. Dedup correctness relies on session_ingest.py's offset + hash pre-check preventing duplicate (session_id, line_offset) rows. Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
All token aggregation queries in the insights primary path (session_events) now read from the input_tokens / output_tokens / cache_read_tokens / cache_write_tokens columns extracted at ingest time instead of calling JSONExtractInt(raw_line, 'message', 'usage', ...) on every row. PostHog engineering (posthog.com handbook) identifies the same pattern: JSONExtract requires CPU to parse JSON on every row and stores data non-optimally; materialized columns are stored the same way as normal columns and require less resources to read and parse. Files changed: - metrics.py: _ev_token_aggregates, _ev_per_session_tokens, _ev_session_details, _ev_subagent_stats — all drop JSONExtract on token fields; Kiro model field retains a narrow JSONExtract fallback only for kiro_credits rows not covered by the materialized column - session_cache.py: fetch_session_metas_from_events UNION ALL — both primary and subagent branches replace sumIf(JSONExtract...) with sum(input_tokens) / sum(output_tokens) etc. Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Add a column-level TTL expression on session_events.raw_line so that
large tool_result blobs (file reads, test output, grep results) are
nulled out after 30 days while keeping all metadata rows intact.
What survives:
input_tokens, output_tokens, cache_*_tokens, model — materialized at ingest
content_preview (500 char), tool_name, event_type — always small
timestamp, session_id, user_id, agent_id, line_offset — indexing columns
What gets nulled:
raw_line — the full raw JSONL line, which can be up to 256 KB per row
(capped by RAW_LINE_MAX_BYTES; uncapped historical rows may be larger)
ClickHouse TTL source:
clickhouse.com/docs/guides/developer/ttl — column TTL expression pattern:
ALTER TABLE t MODIFY COLUMN col String TTL ts + INTERVAL N DAY
Design notes:
- Column TTL (nulls field) and row TTL (set via admin retention_days,
deletes entire row) are independent and can coexist.
- TTL fires on background merge; no immediate backfill on existing rows.
- The 30-day window is idempotent to re-apply on each server restart.
- raw_line_truncated flag remains set so the UI can show a truncation
notice even after the TTL fires and the column is empty.
Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
…L scan
fetch_session_metas_from_events previously ran two FINAL scans of
session_events with a correlated subquery for subagent attribution — the
most expensive query in the insights pipeline, called once per report.
New: both the primary and subagent branches query session_stats_agg, the
AggregatingMergeTree table maintained by session_stats_mv.
Why this is faster:
- session_stats_agg has ~1 row per session vs N rows per session in
session_events (where N = number of events, often 500-3000)
- No FINAL: AggregatingMergeTree reads the GROUP BY aggregate over parts
at read time, which is correct without a synchronous merge
- No JSONExtract: token columns are pre-summed as SimpleAggregateFunction
- The correlated parent_session_id subquery now runs over session_stats_agg
(~365K rows/year at 200 devs) not session_events FINAL (~100M rows/year)
The returned column names are now direct (ide, user_id, parent_session_id)
— the post-query alias remapping loop is removed since session_stats_agg
already uses the canonical column names expected by enrich_all_metas and
the generator ranking step.
Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Add observal support CLI command group with �undle and inspect subcommands for generating and reviewing portable diagnostic archives. Bundle collects version info, sanitized config, health probes, aggregate table counts, error fingerprints, redacted logs, and system metrics via a new server-side POST /api/v1/support/collect endpoint. All values pass through a single Redaction Layer (JWT, AWS keys, URL credentials, high-entropy tokens, sensitive JSON keys). Config uses an explicit allowlist — unlisted keys are omitted entirely. Inspect opens bundles read-only with path traversal protection, displays manifest JSON and Rich file tree, supports --show for individual files. Includes 305 tests across 8 test files covering redaction, manifest, collectors, endpoint, wiring, inspect, integration, and property-based tests (Hypothesis). Updates README, CHANGELOG, and GitHub issue template. Signed-off-by: Naraen Rammoorthi <naraen13@gmail.com>
- Add CLA.md based on Apache ICLA v2.2 and HashiCorp CLA - Includes dual-license sublicensing grant for commercial licensing - CLA-assistant.io will handle electronic signatures on PRs - Update CONTRIBUTING.md: fix license references (Apache -> AGPL-3.0) - Update CONTRIBUTING.md: add CLA section explaining CLA + DCO relationship - Add Corporate CLA contact info Closes Observal#803 Signed-off-by: Haz3-jolt <haz3@blazeup.ai> Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
- Delete .github/workflows/dco.yml (CI check) - Delete scripts/check_dco.sh (pre-push hook script) - Remove check-dco hook from .pre-commit-config.yaml - Remove signed-off-by checkbox from PR template - Remove DCO Sign-off section from CONTRIBUTING.md - Remove 'CLA and DCO work together' paragraph from CLA section - Fix em dash to colon in CLA section while here CLA via cla-assistant.io replaces DCO. Contributors sign once via the bot rather than on every commit.
- pyproject.toml (CLI): license field + OSI classifier - observal-server/pyproject.toml: license field - README.md: license badge + footer license line - CODE_OF_CONDUCT.md: open-source core license mention - docs/README.md: FAQ license mention - .github/pull_request_template.md: example row in Licenses table Structural scorer 'apache' string and CHANGELOG historical entry are intentionally untouched.
Signed-off-by: Lokesh Selvam <lokeshselvam7025@gmail.com>
Postgres 18 requires the volume at /var/lib/postgresql (not /data subdirectory) to use version-specific directory names. Signed-off-by: Lokesh Selvam <lokeshselvam7025@gmail.com>
|
This PR has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Add the keep open label to prevent this. |
Lokesh7025
pushed a commit
that referenced
this pull request
Jul 16, 2026
Bug #1: Add global IDE-format hooks (~/.kiro/hooks/) for agentless chat - Writes promptSubmit, preToolUse, postToolUse, agentStop hooks - Fires for ALL Kiro sessions including plain kiro-cli chat Bug Observal#2: Fix pre-existing agent hook injection - Merge hooks instead of replacing them - Preserves existing user hooks in agent JSON files Bug Observal#3: Fix null model_name crash in observal scan --ide kiro --home - data.get('model', '') returns None when JSON has null value - Changed to data.get('model') or '' pattern Bug Observal#4: Fix missing session metadata in traces - Hook scripts now inject user_id from ~/.observal/config.json - Applied to both kiro_hook.py and kiro_stop_hook.py Bug Observal#5: Add Kiro auto-detection during observal auth login - Added _configure_kiro() alongside _configure_claude_code() - Auto-prompts on login when ~/.kiro or kiro-cli detected - Injects both per-agent hooks and global IDE hooks Signed-off-by: shreem <shreemseth26@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose / Description
Remove the dead deploy-dev workflow that was failing on every PR and update the production deploy to trigger on push to main instead of release tags.
Fixes
Approach
How Has This Been Tested?
SSH connection to the EC2 instance verified manually. Instance pulled latest main successfully.
Checklist