rubyllm-observ 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +778 -0
- data/Rakefile +49 -0
- data/app/assets/javascripts/observ/application.js +12 -0
- data/app/assets/javascripts/observ/controllers/autoscroll_controller.js +33 -0
- data/app/assets/javascripts/observ/controllers/chat_form_controller.js +93 -0
- data/app/assets/javascripts/observ/controllers/copy_controller.js +43 -0
- data/app/assets/javascripts/observ/controllers/dashboard_controller.js +58 -0
- data/app/assets/javascripts/observ/controllers/drawer_controller.js +58 -0
- data/app/assets/javascripts/observ/controllers/expandable_controller.js +33 -0
- data/app/assets/javascripts/observ/controllers/filter_controller.js +36 -0
- data/app/assets/javascripts/observ/controllers/index.js +52 -0
- data/app/assets/javascripts/observ/controllers/json_viewer_controller.js +260 -0
- data/app/assets/javascripts/observ/controllers/message_form_controller.js +58 -0
- data/app/assets/javascripts/observ/controllers/prompt_variables_controller.js +64 -0
- data/app/assets/javascripts/observ/controllers/text_select_controller.js +14 -0
- data/app/assets/stylesheets/observ/_annotations.scss +127 -0
- data/app/assets/stylesheets/observ/_card.scss +52 -0
- data/app/assets/stylesheets/observ/_chat.scss +156 -0
- data/app/assets/stylesheets/observ/_components.scss +460 -0
- data/app/assets/stylesheets/observ/_dashboard.scss +40 -0
- data/app/assets/stylesheets/observ/_datasets.scss +697 -0
- data/app/assets/stylesheets/observ/_drawer.scss +273 -0
- data/app/assets/stylesheets/observ/_json_viewer.scss +120 -0
- data/app/assets/stylesheets/observ/_layout.scss +256 -0
- data/app/assets/stylesheets/observ/_metrics.scss +99 -0
- data/app/assets/stylesheets/observ/_observations.scss +160 -0
- data/app/assets/stylesheets/observ/_pagination.scss +143 -0
- data/app/assets/stylesheets/observ/_prompts.scss +365 -0
- data/app/assets/stylesheets/observ/_table.scss +53 -0
- data/app/assets/stylesheets/observ/_variables.scss +53 -0
- data/app/assets/stylesheets/observ/application.scss +15 -0
- data/app/controllers/observ/annotations_controller.rb +144 -0
- data/app/controllers/observ/application_controller.rb +8 -0
- data/app/controllers/observ/chats_controller.rb +58 -0
- data/app/controllers/observ/dashboard_controller.rb +159 -0
- data/app/controllers/observ/dataset_items_controller.rb +85 -0
- data/app/controllers/observ/dataset_run_items_controller.rb +84 -0
- data/app/controllers/observ/dataset_runs_controller.rb +110 -0
- data/app/controllers/observ/datasets_controller.rb +74 -0
- data/app/controllers/observ/messages_controller.rb +26 -0
- data/app/controllers/observ/observations_controller.rb +59 -0
- data/app/controllers/observ/prompt_versions_controller.rb +148 -0
- data/app/controllers/observ/prompts_controller.rb +205 -0
- data/app/controllers/observ/sessions_controller.rb +45 -0
- data/app/controllers/observ/traces_controller.rb +86 -0
- data/app/forms/observ/prompt_form.rb +96 -0
- data/app/helpers/observ/application_helper.rb +9 -0
- data/app/helpers/observ/chats_helper.rb +47 -0
- data/app/helpers/observ/dashboard_helper.rb +154 -0
- data/app/helpers/observ/datasets_helper.rb +62 -0
- data/app/helpers/observ/pagination_helper.rb +38 -0
- data/app/jobs/observ/application_job.rb +4 -0
- data/app/jobs/observ/dataset_runner_job.rb +49 -0
- data/app/mailers/observ/application_mailer.rb +6 -0
- data/app/models/concerns/observ/agent_phaseable.rb +124 -0
- data/app/models/concerns/observ/agent_selectable.rb +50 -0
- data/app/models/concerns/observ/chat_enhancements.rb +109 -0
- data/app/models/concerns/observ/message_enhancements.rb +31 -0
- data/app/models/concerns/observ/observability_instrumentation.rb +124 -0
- data/app/models/concerns/observ/prompt_management.rb +320 -0
- data/app/models/concerns/observ/trace_association.rb +9 -0
- data/app/models/observ/annotation.rb +23 -0
- data/app/models/observ/application_record.rb +5 -0
- data/app/models/observ/dataset.rb +51 -0
- data/app/models/observ/dataset_item.rb +41 -0
- data/app/models/observ/dataset_run.rb +104 -0
- data/app/models/observ/dataset_run_item.rb +111 -0
- data/app/models/observ/generation.rb +56 -0
- data/app/models/observ/null_prompt.rb +59 -0
- data/app/models/observ/observation.rb +38 -0
- data/app/models/observ/prompt.rb +315 -0
- data/app/models/observ/score.rb +51 -0
- data/app/models/observ/session.rb +131 -0
- data/app/models/observ/span.rb +13 -0
- data/app/models/observ/trace.rb +135 -0
- data/app/presenters/observ/agent_select_presenter.rb +59 -0
- data/app/services/observ/agent_executor_service.rb +174 -0
- data/app/services/observ/agent_provider.rb +60 -0
- data/app/services/observ/agent_selection_service.rb +53 -0
- data/app/services/observ/chat_instrumenter.rb +523 -0
- data/app/services/observ/dataset_runner_service.rb +153 -0
- data/app/services/observ/evaluator_runner_service.rb +58 -0
- data/app/services/observ/evaluators/base_evaluator.rb +51 -0
- data/app/services/observ/evaluators/contains_evaluator.rb +53 -0
- data/app/services/observ/evaluators/exact_match_evaluator.rb +23 -0
- data/app/services/observ/evaluators/json_structure_evaluator.rb +44 -0
- data/app/services/observ/prompt_manager/cache_statistics.rb +82 -0
- data/app/services/observ/prompt_manager/caching.rb +167 -0
- data/app/services/observ/prompt_manager/comparison.rb +49 -0
- data/app/services/observ/prompt_manager/version_management.rb +96 -0
- data/app/services/observ/prompt_manager.rb +40 -0
- data/app/services/observ/trace_text_formatter.rb +349 -0
- data/app/validators/observ/prompt_config_validator.rb +187 -0
- data/app/views/kaminari/_first_page.html.erb +11 -0
- data/app/views/kaminari/_gap.html.erb +8 -0
- data/app/views/kaminari/_last_page.html.erb +11 -0
- data/app/views/kaminari/_next_page.html.erb +11 -0
- data/app/views/kaminari/_page.html.erb +12 -0
- data/app/views/kaminari/_paginator.html.erb +25 -0
- data/app/views/kaminari/_prev_page.html.erb +11 -0
- data/app/views/kaminari/observ/_first_page.html.erb +11 -0
- data/app/views/kaminari/observ/_gap.html.erb +8 -0
- data/app/views/kaminari/observ/_last_page.html.erb +11 -0
- data/app/views/kaminari/observ/_next_page.html.erb +11 -0
- data/app/views/kaminari/observ/_page.html.erb +12 -0
- data/app/views/kaminari/observ/_paginator.html.erb +25 -0
- data/app/views/kaminari/observ/_prev_page.html.erb +11 -0
- data/app/views/layouts/observ/application.html.erb +88 -0
- data/app/views/observ/annotations/_annotation.html.erb +13 -0
- data/app/views/observ/annotations/_form.html.erb +28 -0
- data/app/views/observ/annotations/index.html.erb +28 -0
- data/app/views/observ/annotations/sessions_index.html.erb +48 -0
- data/app/views/observ/annotations/traces_index.html.erb +48 -0
- data/app/views/observ/chats/_form.html.erb +45 -0
- data/app/views/observ/chats/index.html.erb +67 -0
- data/app/views/observ/chats/new.html.erb +17 -0
- data/app/views/observ/chats/show.html.erb +34 -0
- data/app/views/observ/dashboard/index.html.erb +236 -0
- data/app/views/observ/dataset_items/_form.html.erb +49 -0
- data/app/views/observ/dataset_items/edit.html.erb +18 -0
- data/app/views/observ/dataset_items/index.html.erb +95 -0
- data/app/views/observ/dataset_items/new.html.erb +18 -0
- data/app/views/observ/dataset_run_items/_score_close_drawer.html.erb +4 -0
- data/app/views/observ/dataset_run_items/_score_drawer.html.erb +75 -0
- data/app/views/observ/dataset_run_items/_score_success.html.erb +29 -0
- data/app/views/observ/dataset_run_items/_scores_cell.html.erb +19 -0
- data/app/views/observ/dataset_run_items/details_drawer.turbo_stream.erb +80 -0
- data/app/views/observ/dataset_run_items/score_drawer.turbo_stream.erb +7 -0
- data/app/views/observ/dataset_runs/index.html.erb +108 -0
- data/app/views/observ/dataset_runs/new.html.erb +57 -0
- data/app/views/observ/dataset_runs/review.html.erb +155 -0
- data/app/views/observ/dataset_runs/show.html.erb +166 -0
- data/app/views/observ/datasets/_form.html.erb +62 -0
- data/app/views/observ/datasets/_items_tab.html.erb +66 -0
- data/app/views/observ/datasets/_runs_tab.html.erb +82 -0
- data/app/views/observ/datasets/edit.html.erb +32 -0
- data/app/views/observ/datasets/index.html.erb +105 -0
- data/app/views/observ/datasets/new.html.erb +18 -0
- data/app/views/observ/datasets/show.html.erb +67 -0
- data/app/views/observ/messages/_content.html.erb +1 -0
- data/app/views/observ/messages/_form.html.erb +33 -0
- data/app/views/observ/messages/_message.html.erb +14 -0
- data/app/views/observ/messages/_tool_calls.html.erb +10 -0
- data/app/views/observ/messages/create.turbo_stream.erb +9 -0
- data/app/views/observ/observations/index.html.erb +97 -0
- data/app/views/observ/observations/show_generation.html.erb +195 -0
- data/app/views/observ/observations/show_span.html.erb +93 -0
- data/app/views/observ/prompts/_diff_content.html.erb +16 -0
- data/app/views/observ/prompts/_form.html.erb +111 -0
- data/app/views/observ/prompts/_new_form.html.erb +102 -0
- data/app/views/observ/prompts/_prompt_actions.html.erb +4 -0
- data/app/views/observ/prompts/_prompt_content_highlighted.html.erb +4 -0
- data/app/views/observ/prompts/_version_actions.html.erb +40 -0
- data/app/views/observ/prompts/compare.html.erb +155 -0
- data/app/views/observ/prompts/edit.html.erb +17 -0
- data/app/views/observ/prompts/index.html.erb +108 -0
- data/app/views/observ/prompts/new.html.erb +17 -0
- data/app/views/observ/prompts/show.html.erb +138 -0
- data/app/views/observ/prompts/versions.html.erb +87 -0
- data/app/views/observ/sessions/annotations_drawer.turbo_stream.erb +25 -0
- data/app/views/observ/sessions/drawer_test.turbo_stream.erb +49 -0
- data/app/views/observ/sessions/index.html.erb +91 -0
- data/app/views/observ/sessions/show.html.erb +251 -0
- data/app/views/observ/traces/add_to_dataset_drawer.turbo_stream.erb +48 -0
- data/app/views/observ/traces/annotations_drawer.turbo_stream.erb +25 -0
- data/app/views/observ/traces/index.html.erb +87 -0
- data/app/views/observ/traces/show.html.erb +285 -0
- data/app/views/observ/traces/text_output_drawer.turbo_stream.erb +48 -0
- data/app/views/shared/_drawer.html.erb +26 -0
- data/config/routes.rb +80 -0
- data/db/migrate/001_create_observ_sessions.rb +21 -0
- data/db/migrate/002_create_observ_traces.rb +25 -0
- data/db/migrate/003_create_observ_observations.rb +42 -0
- data/db/migrate/004_add_message_id_to_observ_traces.rb +7 -0
- data/db/migrate/005_create_observ_prompts.rb +21 -0
- data/db/migrate/006_fix_prompt_config_strings.rb +23 -0
- data/db/migrate/007_create_observ_annotations.rb +12 -0
- data/db/migrate/009_add_prompt_fields_to_observ_chats.rb +11 -0
- data/db/migrate/010_create_observ_datasets.rb +15 -0
- data/db/migrate/011_create_observ_dataset_items.rb +17 -0
- data/db/migrate/012_create_observ_dataset_runs.rb +22 -0
- data/db/migrate/013_create_observ_dataset_run_items.rb +16 -0
- data/db/migrate/014_create_observ_scores.rb +26 -0
- data/lib/generators/observ/add_phase_tracking/add_phase_tracking_generator.rb +150 -0
- data/lib/generators/observ/add_phase_tracking/templates/migration.rb.tt +6 -0
- data/lib/generators/observ/install/USAGE +27 -0
- data/lib/generators/observ/install/install_generator.rb +270 -0
- data/lib/generators/observ/install_chat/install_chat_generator.rb +313 -0
- data/lib/generators/observ/install_chat/templates/agents/base_agent.rb.tt +147 -0
- data/lib/generators/observ/install_chat/templates/agents/simple_agent.rb.tt +55 -0
- data/lib/generators/observ/install_chat/templates/concerns/observ_chat_enhancements.rb.tt +34 -0
- data/lib/generators/observ/install_chat/templates/concerns/observ_message_enhancements.rb.tt +18 -0
- data/lib/generators/observ/install_chat/templates/initializers/observability.rb.tt +20 -0
- data/lib/generators/observ/install_chat/templates/jobs/chat_response_job.rb.tt +56 -0
- data/lib/generators/observ/install_chat/templates/migrations/add_agent_class_name.rb.tt +6 -0
- data/lib/generators/observ/install_chat/templates/migrations/add_observability_session_id.rb.tt +6 -0
- data/lib/generators/observ/install_chat/templates/tools/think_tool.rb.tt +29 -0
- data/lib/generators/observ/install_chat/templates/views/messages/_content.html.erb.tt +1 -0
- data/lib/observ/asset_installer.rb +130 -0
- data/lib/observ/asset_syncer.rb +104 -0
- data/lib/observ/configuration.rb +108 -0
- data/lib/observ/engine.rb +50 -0
- data/lib/observ/index_file_generator.rb +142 -0
- data/lib/observ/instrumenter/ruby_llm.rb +6 -0
- data/lib/observ/version.rb +3 -0
- data/lib/observ.rb +29 -0
- data/lib/tasks/observ_tasks.rake +75 -0
- metadata +453 -0
data/README.md
ADDED
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
# Observ
|
|
2
|
+
|
|
3
|
+
A Rails engine providing comprehensive observability for LLM-powered applications, including session tracking, trace analysis, prompt management, and cost monitoring.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
### Core Observability Features
|
|
8
|
+
- **Session Tracking**: Automatically track user sessions across LLM interactions
|
|
9
|
+
- **Trace Analysis**: Detailed execution traces with token usage and cost metrics
|
|
10
|
+
- **Prompt Management**: Version-controlled prompts with state machine (draft/production/archived)
|
|
11
|
+
- **Cost Monitoring**: Real-time tracking of API costs across models and providers
|
|
12
|
+
- **Annotation Tools**: Add notes and export data for analysis
|
|
13
|
+
- **Advanced Caching**: Sophisticated caching system with Redis support and monitoring
|
|
14
|
+
|
|
15
|
+
### Optional Chat/Agent Testing Feature
|
|
16
|
+
- **Agent Testing UI**: Interactive chat interface for testing LLM agents at `/observ/chats`
|
|
17
|
+
- **Agent Management**: Create, select, and configure different agents
|
|
18
|
+
- **Message Streaming**: Real-time response streaming with Turbo
|
|
19
|
+
- **Tool Visualization**: See tool calls in action
|
|
20
|
+
- **RubyLLM Integration**: Full integration with RubyLLM gem for agent development
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
Observ offers **two installation modes**: Core (observability only) or Core + Chat (with agent testing).
|
|
25
|
+
|
|
26
|
+
### Core Installation (Recommended for Most Users)
|
|
27
|
+
|
|
28
|
+
For LLM observability without the chat UI:
|
|
29
|
+
|
|
30
|
+
**1. Add to Gemfile:**
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
gem "observ"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**2. Install:**
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
bundle install
|
|
40
|
+
rails observ:install:migrations
|
|
41
|
+
rails db:migrate
|
|
42
|
+
rails generate observ:install
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**What you get:**
|
|
46
|
+
- Dashboard at `/observ`
|
|
47
|
+
- Session tracking and analysis
|
|
48
|
+
- Trace visualization
|
|
49
|
+
- Prompt management
|
|
50
|
+
- Cost monitoring
|
|
51
|
+
- Annotation tools
|
|
52
|
+
|
|
53
|
+
**No chat UI** - Perfect if you're instrumenting an existing application and just want observability.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### Core + Chat Installation (For Agent Testing)
|
|
58
|
+
|
|
59
|
+
For full observability + interactive agent testing UI:
|
|
60
|
+
|
|
61
|
+
**1. Add to Gemfile:**
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
gem "observ"
|
|
65
|
+
gem "ruby_llm" # Required for chat feature
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**2. Install core + chat:**
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
bundle install
|
|
72
|
+
|
|
73
|
+
# Install RubyLLM infrastructure first
|
|
74
|
+
rails generate ruby_llm:install
|
|
75
|
+
rails db:migrate
|
|
76
|
+
rails ruby_llm:load_models
|
|
77
|
+
|
|
78
|
+
# Then install Observ
|
|
79
|
+
rails observ:install:migrations
|
|
80
|
+
rails generate observ:install # Core features
|
|
81
|
+
rails generate observ:install:chat # Chat feature
|
|
82
|
+
rails db:migrate
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**What you get:**
|
|
86
|
+
- Everything from Core installation
|
|
87
|
+
- Chat UI at `/observ/chats`
|
|
88
|
+
- Agent testing interface
|
|
89
|
+
- Observ enhancements on RubyLLM infrastructure
|
|
90
|
+
- Example agents and tools
|
|
91
|
+
|
|
92
|
+
See **[Chat Installation Guide](docs/CHAT_INSTALLATION.md)** for detailed setup.
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### Asset Installation
|
|
97
|
+
|
|
98
|
+
After running either installation mode:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# For first-time installation (recommended)
|
|
102
|
+
rails generate observ:install
|
|
103
|
+
|
|
104
|
+
# Or use the rake task
|
|
105
|
+
rails observ:install_assets
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This will:
|
|
109
|
+
- Show you the destination paths where assets will be copied
|
|
110
|
+
- Ask for confirmation before proceeding
|
|
111
|
+
- Automatically mount the engine in `config/routes.rb` (if not already present)
|
|
112
|
+
- Copy Observ stylesheets to `app/javascript/stylesheets/observ`
|
|
113
|
+
- Copy Observ JavaScript Stimulus controllers to `app/javascript/controllers/observ`
|
|
114
|
+
- Generate index files for easy importing
|
|
115
|
+
- Check if controllers are properly registered in your application
|
|
116
|
+
|
|
117
|
+
**Custom asset destinations:**
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Install to custom locations
|
|
121
|
+
rails generate observ:install --styles-dest=app/assets/stylesheets/observ --js-dest=app/javascript/controllers/custom
|
|
122
|
+
|
|
123
|
+
# Or with rake task
|
|
124
|
+
rails observ:install_assets[app/assets/stylesheets/observ,app/javascript/controllers/custom]
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Skip confirmation (useful for CI/CD or automated scripts):**
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Skip confirmation prompt
|
|
131
|
+
rails generate observ:install --force
|
|
132
|
+
|
|
133
|
+
# With custom destinations
|
|
134
|
+
rails generate observ:install --force --styles-dest=custom/path --js-dest=custom/path
|
|
135
|
+
|
|
136
|
+
# Skip automatic route mounting (if you want to mount manually)
|
|
137
|
+
rails generate observ:install --skip-routes
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**Updating assets:**
|
|
141
|
+
|
|
142
|
+
When you update the Observ gem, sync the latest assets:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
rails observ:sync_assets
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
This will update only changed files without regenerating index files.
|
|
149
|
+
|
|
150
|
+
## Configuration
|
|
151
|
+
|
|
152
|
+
### 1. Mount the Engine (Automatic)
|
|
153
|
+
|
|
154
|
+
The install generator automatically adds the engine mount to `config/routes.rb`:
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
mount Observ::Engine, at: "/observ"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
This makes Observ available at `/observ` in your application.
|
|
161
|
+
|
|
162
|
+
If you used `--skip-routes` during installation, manually add the route to `config/routes.rb`:
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
Rails.application.routes.draw do
|
|
166
|
+
mount Observ::Engine, at: "/observ"
|
|
167
|
+
|
|
168
|
+
# Your other routes...
|
|
169
|
+
end
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 2. Configure the Engine
|
|
173
|
+
|
|
174
|
+
Create `config/initializers/observ.rb`:
|
|
175
|
+
|
|
176
|
+
```ruby
|
|
177
|
+
Observ.configure do |config|
|
|
178
|
+
# Prompt management
|
|
179
|
+
config.prompt_management_enabled = true
|
|
180
|
+
config.prompt_max_versions = 100
|
|
181
|
+
config.prompt_default_state = :production
|
|
182
|
+
config.prompt_allow_production_deletion = false
|
|
183
|
+
config.prompt_fallback_behavior = :raise # or :return_nil, :use_fallback
|
|
184
|
+
|
|
185
|
+
# Caching configuration
|
|
186
|
+
config.prompt_cache_ttl = 300 # 5 minutes (0 to disable)
|
|
187
|
+
config.prompt_cache_store = :redis_cache_store # or :memory_store
|
|
188
|
+
config.prompt_cache_namespace = "observ:prompt"
|
|
189
|
+
|
|
190
|
+
# Cache warming (load critical prompts on boot)
|
|
191
|
+
config.prompt_cache_warming_enabled = true
|
|
192
|
+
config.prompt_cache_critical_prompts = ["research_agent", "rpg_agent"]
|
|
193
|
+
|
|
194
|
+
# Cache monitoring (track hit rates)
|
|
195
|
+
config.prompt_cache_monitoring_enabled = true
|
|
196
|
+
|
|
197
|
+
# UI configuration
|
|
198
|
+
config.back_to_app_path = -> { Rails.application.routes.url_helpers.root_path }
|
|
199
|
+
config.back_to_app_label = "← Back to App"
|
|
200
|
+
|
|
201
|
+
# Chat UI (auto-detects if Chat model exists with acts_as_chat)
|
|
202
|
+
# Manually override if needed:
|
|
203
|
+
# config.chat_ui_enabled = true
|
|
204
|
+
end
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### 3. Configure Observability Features
|
|
208
|
+
|
|
209
|
+
The `observ:install:chat` generator automatically creates `config/initializers/observability.rb`:
|
|
210
|
+
|
|
211
|
+
```ruby
|
|
212
|
+
Rails.application.configure do
|
|
213
|
+
config.observability = ActiveSupport::OrderedOptions.new
|
|
214
|
+
|
|
215
|
+
# Enable observability instrumentation
|
|
216
|
+
# When enabled, sessions, traces, and observations are automatically tracked
|
|
217
|
+
config.observability.enabled = true
|
|
218
|
+
|
|
219
|
+
# Automatically instrument RubyLLM chats with observability
|
|
220
|
+
# When enabled, LLM calls, tool usage, and metrics are tracked
|
|
221
|
+
config.observability.auto_instrument_chats = true
|
|
222
|
+
|
|
223
|
+
# Enable debug logging for observability metrics
|
|
224
|
+
# When enabled, job completion metrics (tokens, cost) will be logged
|
|
225
|
+
config.observability.debug = Rails.env.development?
|
|
226
|
+
end
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Environment-based configuration:**
|
|
230
|
+
|
|
231
|
+
```ruby
|
|
232
|
+
# Use environment variables for production
|
|
233
|
+
config.observability.enabled = ENV.fetch("OBSERVABILITY_ENABLED", "true") == "true"
|
|
234
|
+
config.observability.auto_instrument_chats = ENV.fetch("AUTO_INSTRUMENT", "true") == "true"
|
|
235
|
+
config.observability.debug = ENV.fetch("OBSERVABILITY_DEBUG", "false") == "true"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Important:**
|
|
239
|
+
- `enabled` must be `true` for observability sessions to be created
|
|
240
|
+
- `auto_instrument_chats` must be `true` for automatic LLM call tracking
|
|
241
|
+
- Without these settings, observability features will be disabled
|
|
242
|
+
|
|
243
|
+
### 4. Configure RubyLLM (Chat Feature Only)
|
|
244
|
+
|
|
245
|
+
**Skip this if you're using Core installation only.**
|
|
246
|
+
|
|
247
|
+
If you installed the chat feature, create `config/initializers/ruby_llm.rb`:
|
|
248
|
+
|
|
249
|
+
```ruby
|
|
250
|
+
RubyLLM.configure do |config|
|
|
251
|
+
config.openai_api_key = ENV['OPENAI_API_KEY']
|
|
252
|
+
config.default_model = "gpt-4o-mini"
|
|
253
|
+
|
|
254
|
+
# Use the new association-based acts_as API (recommended)
|
|
255
|
+
config.use_new_acts_as = true
|
|
256
|
+
|
|
257
|
+
# Optional: Other providers
|
|
258
|
+
# config.anthropic_api_key = ENV['ANTHROPIC_API_KEY']
|
|
259
|
+
# config.google_api_key = ENV['GOOGLE_API_KEY']
|
|
260
|
+
end
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### 5. Add Concerns to Your Models (Chat Feature Only)
|
|
264
|
+
|
|
265
|
+
**Skip this if you're using Core installation only.**
|
|
266
|
+
|
|
267
|
+
The `observ:install:chat` generator creates these models automatically. If you're manually setting up:
|
|
268
|
+
|
|
269
|
+
```ruby
|
|
270
|
+
class Chat < ApplicationRecord
|
|
271
|
+
include Observ::ObservabilityInstrumentation
|
|
272
|
+
|
|
273
|
+
# Your existing code...
|
|
274
|
+
end
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
This adds:
|
|
278
|
+
- `observ_session` association
|
|
279
|
+
- Automatic session creation on model creation
|
|
280
|
+
- `ask_with_observability` method for tracked LLM calls
|
|
281
|
+
|
|
282
|
+
For message models (optional, for trace linking):
|
|
283
|
+
|
|
284
|
+
```ruby
|
|
285
|
+
class Message < ApplicationRecord
|
|
286
|
+
include Observ::TraceAssociation
|
|
287
|
+
|
|
288
|
+
# Your existing code...
|
|
289
|
+
end
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
This adds `has_many :traces` relationship.
|
|
293
|
+
|
|
294
|
+
**Note:** The `observ:install:chat` generator handles all of this automatically, including migrations!
|
|
295
|
+
|
|
296
|
+
## Usage
|
|
297
|
+
|
|
298
|
+
### Basic Usage (Core Features)
|
|
299
|
+
|
|
300
|
+
Once installed, Observ automatically tracks:
|
|
301
|
+
|
|
302
|
+
1. **Sessions**: Created when your instrumented models are created
|
|
303
|
+
2. **Traces**: Captured when you call LLM methods (if using RubyLLM)
|
|
304
|
+
3. **Observations**: Generations and spans are recorded with metadata
|
|
305
|
+
|
|
306
|
+
Visit `/observ` in your browser to see:
|
|
307
|
+
- Dashboard with metrics and cost analysis
|
|
308
|
+
- Session history
|
|
309
|
+
- Trace details
|
|
310
|
+
- Prompt management UI
|
|
311
|
+
|
|
312
|
+
### Chat Feature Usage (If Installed)
|
|
313
|
+
|
|
314
|
+
If you installed the chat feature with `rails generate observ:install:chat`:
|
|
315
|
+
|
|
316
|
+
**1. Visit `/observ/chats`**
|
|
317
|
+
|
|
318
|
+
**2. Create a new chat:**
|
|
319
|
+
- Click "New Chat"
|
|
320
|
+
- Select an agent (e.g., SimpleAgent)
|
|
321
|
+
- Start chatting!
|
|
322
|
+
|
|
323
|
+
**3. Create custom agents:**
|
|
324
|
+
|
|
325
|
+
```ruby
|
|
326
|
+
# app/agents/my_agent.rb
|
|
327
|
+
class MyAgent < BaseAgent
|
|
328
|
+
include AgentSelectable
|
|
329
|
+
|
|
330
|
+
def self.display_name
|
|
331
|
+
"My Custom Agent"
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
def self.system_prompt
|
|
335
|
+
"You are a helpful assistant that..."
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def self.default_model
|
|
339
|
+
"gpt-4o-mini"
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**4. View session data:**
|
|
345
|
+
- All chat interactions appear in `/observ/sessions`
|
|
346
|
+
- Full observability of tokens, costs, and tool calls
|
|
347
|
+
|
|
348
|
+
See **[Chat Installation Guide](docs/CHAT_INSTALLATION.md)** for complete documentation.
|
|
349
|
+
|
|
350
|
+
### Phase Tracking (Optional Chat Feature)
|
|
351
|
+
|
|
352
|
+
For multi-phase agent workflows (e.g., scoping → research → writing), add phase tracking:
|
|
353
|
+
|
|
354
|
+
**1. Add phase tracking to your installation:**
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
# During initial installation
|
|
358
|
+
rails generate observ:install:chat --with-phase-tracking
|
|
359
|
+
|
|
360
|
+
# Or add to existing installation
|
|
361
|
+
rails generate observ:add_phase_tracking
|
|
362
|
+
rails db:migrate
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
**2. Use phase transitions in your agents:**
|
|
366
|
+
|
|
367
|
+
```ruby
|
|
368
|
+
# app/agents/research_agent.rb
|
|
369
|
+
class ResearchAgent < BaseAgent
|
|
370
|
+
def perform_research(chat, query)
|
|
371
|
+
# Transition to research phase
|
|
372
|
+
chat.transition_to_phase('research')
|
|
373
|
+
|
|
374
|
+
# Do research work...
|
|
375
|
+
results = research(query)
|
|
376
|
+
|
|
377
|
+
# Transition to writing phase
|
|
378
|
+
chat.transition_to_phase('writing', depth: 'comprehensive')
|
|
379
|
+
|
|
380
|
+
# Generate report...
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**3. Check current phase:**
|
|
386
|
+
|
|
387
|
+
```ruby
|
|
388
|
+
chat.current_phase # => 'research'
|
|
389
|
+
chat.in_phase?('research') # => true
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**4. (Optional) Define allowed phases:**
|
|
393
|
+
|
|
394
|
+
```ruby
|
|
395
|
+
# app/models/chat.rb
|
|
396
|
+
class Chat < ApplicationRecord
|
|
397
|
+
include Observ::ObservabilityInstrumentation
|
|
398
|
+
include Observ::AgentPhaseable
|
|
399
|
+
|
|
400
|
+
def allowed_phases
|
|
401
|
+
%w[scoping research writing review]
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
**Benefits:**
|
|
407
|
+
- Phase transitions are automatically tracked in observability metadata
|
|
408
|
+
- View phase progression in `/observ/sessions`
|
|
409
|
+
- Analyze time and cost per phase
|
|
410
|
+
- Debug which phase causes issues
|
|
411
|
+
|
|
412
|
+
**Phase data in observability:**
|
|
413
|
+
|
|
414
|
+
All phase transitions are captured in session metadata:
|
|
415
|
+
```ruby
|
|
416
|
+
session.metadata
|
|
417
|
+
# => {
|
|
418
|
+
# "agent_type" => "ResearchAgent",
|
|
419
|
+
# "chat_id" => 42,
|
|
420
|
+
# "agent_phase" => "writing",
|
|
421
|
+
# "phase_transition" => "research -> writing",
|
|
422
|
+
# "depth" => "comprehensive"
|
|
423
|
+
# }
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Extending Observability Metadata (Advanced)
|
|
427
|
+
|
|
428
|
+
You can extend observability metadata by overriding hook methods in your Chat model:
|
|
429
|
+
|
|
430
|
+
```ruby
|
|
431
|
+
# app/models/chat.rb
|
|
432
|
+
class Chat < ApplicationRecord
|
|
433
|
+
include Observ::ObservabilityInstrumentation
|
|
434
|
+
|
|
435
|
+
# Override to add custom metadata to session
|
|
436
|
+
def observability_metadata
|
|
437
|
+
super.merge(
|
|
438
|
+
user_id: user_id,
|
|
439
|
+
subscription_tier: user.subscription_tier,
|
|
440
|
+
feature_flags: enabled_features
|
|
441
|
+
)
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
# Override to add custom context to instrumenter
|
|
445
|
+
def observability_context
|
|
446
|
+
super.merge(
|
|
447
|
+
locale: I18n.locale,
|
|
448
|
+
timezone: Time.zone.name
|
|
449
|
+
)
|
|
450
|
+
end
|
|
451
|
+
end
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
This allows you to:
|
|
455
|
+
- Track user-specific information
|
|
456
|
+
- Add business logic metadata
|
|
457
|
+
- Include feature flags for A/B testing analysis
|
|
458
|
+
- Track localization and timezone data
|
|
459
|
+
|
|
460
|
+
**Note:** The `AgentPhaseable` concern uses these same hooks to inject phase data.
|
|
461
|
+
|
|
462
|
+
### Manual Instrumentation
|
|
463
|
+
|
|
464
|
+
If not using RubyLLM, you can manually create traces:
|
|
465
|
+
|
|
466
|
+
```ruby
|
|
467
|
+
session = Observ::Session.create(
|
|
468
|
+
session_id: SecureRandom.uuid,
|
|
469
|
+
user_id: current_user.id,
|
|
470
|
+
metadata: { agent_type: "custom" }
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
trace = session.traces.create(
|
|
474
|
+
name: "Custom Operation",
|
|
475
|
+
start_time: Time.current
|
|
476
|
+
)
|
|
477
|
+
|
|
478
|
+
# ... do work ...
|
|
479
|
+
|
|
480
|
+
trace.update(
|
|
481
|
+
end_time: Time.current,
|
|
482
|
+
metadata: { result: "success" }
|
|
483
|
+
)
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### Prompt Management
|
|
487
|
+
|
|
488
|
+
Fetch prompts in your code:
|
|
489
|
+
|
|
490
|
+
```ruby
|
|
491
|
+
# Fetch production version
|
|
492
|
+
prompt = Observ::PromptManager.fetch(name: "research_agent", state: :production)
|
|
493
|
+
content = prompt.content
|
|
494
|
+
|
|
495
|
+
# Fetch specific version
|
|
496
|
+
prompt = Observ::PromptManager.fetch(name: "research_agent", version: 5)
|
|
497
|
+
|
|
498
|
+
# With caching (automatic)
|
|
499
|
+
prompt = Observ::PromptManager.fetch(name: "research_agent") # Cached for 5 min
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Cache management:
|
|
503
|
+
|
|
504
|
+
```ruby
|
|
505
|
+
# Check cache stats
|
|
506
|
+
Observ::PromptManager.cache_stats("research_agent")
|
|
507
|
+
# => { hits: 145, misses: 12, total: 157, hit_rate: 92.36 }
|
|
508
|
+
|
|
509
|
+
# Invalidate cache
|
|
510
|
+
Observ::PromptManager.invalidate_cache(name: "research_agent")
|
|
511
|
+
|
|
512
|
+
# Warm cache (done automatically on boot if configured)
|
|
513
|
+
Observ::PromptManager.warm_cache(["agent1", "agent2"])
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### Annotations
|
|
517
|
+
|
|
518
|
+
Add annotations to sessions or traces:
|
|
519
|
+
|
|
520
|
+
```ruby
|
|
521
|
+
session.annotations.create(
|
|
522
|
+
content: "Important insight",
|
|
523
|
+
annotator: "user@example.com",
|
|
524
|
+
tags: ["bug", "performance"]
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
# Export annotations
|
|
528
|
+
# Visit /observ/annotations/export in browser
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
## Asset Management
|
|
532
|
+
|
|
533
|
+
Observ provides several tools for managing assets in your Rails application:
|
|
534
|
+
|
|
535
|
+
### Generators
|
|
536
|
+
|
|
537
|
+
```bash
|
|
538
|
+
# Install assets for the first time (recommended)
|
|
539
|
+
rails generate observ:install
|
|
540
|
+
|
|
541
|
+
# Install to custom locations
|
|
542
|
+
rails generate observ:install --styles-dest=custom/path --js-dest=custom/controllers
|
|
543
|
+
|
|
544
|
+
# Skip index file generation
|
|
545
|
+
rails generate observ:install --skip-index
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Rake Tasks
|
|
549
|
+
|
|
550
|
+
```bash
|
|
551
|
+
# Install assets (with index file generation)
|
|
552
|
+
rails observ:install_assets
|
|
553
|
+
rails observ:install # shorthand
|
|
554
|
+
|
|
555
|
+
# Sync assets (update only, no index generation)
|
|
556
|
+
rails observ:sync_assets
|
|
557
|
+
rails observ:sync # shorthand
|
|
558
|
+
|
|
559
|
+
# Custom destinations
|
|
560
|
+
rails observ:install_assets[app/assets/stylesheets/observ,app/javascript/controllers/custom]
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Programmatic API
|
|
564
|
+
|
|
565
|
+
You can also use the Ruby API directly:
|
|
566
|
+
|
|
567
|
+
```ruby
|
|
568
|
+
require 'observ/asset_installer'
|
|
569
|
+
|
|
570
|
+
installer = Observ::AssetInstaller.new(
|
|
571
|
+
gem_root: Observ::Engine.root,
|
|
572
|
+
app_root: Rails.root
|
|
573
|
+
)
|
|
574
|
+
|
|
575
|
+
# Full installation with index generation
|
|
576
|
+
result = installer.install(
|
|
577
|
+
styles_dest: 'app/javascript/stylesheets/observ',
|
|
578
|
+
js_dest: 'app/javascript/controllers/observ',
|
|
579
|
+
generate_index: true
|
|
580
|
+
)
|
|
581
|
+
|
|
582
|
+
# Just sync existing files
|
|
583
|
+
result = installer.sync(
|
|
584
|
+
styles_dest: 'app/javascript/stylesheets/observ',
|
|
585
|
+
js_dest: 'app/javascript/controllers/observ'
|
|
586
|
+
)
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
## Development
|
|
590
|
+
|
|
591
|
+
After checking out the repo, run:
|
|
592
|
+
|
|
593
|
+
```bash
|
|
594
|
+
cd observ
|
|
595
|
+
bundle install
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
Run tests:
|
|
599
|
+
|
|
600
|
+
```bash
|
|
601
|
+
bundle exec rspec
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
## Architecture
|
|
605
|
+
|
|
606
|
+
Observ uses:
|
|
607
|
+
- **Isolated namespace**: All classes under `Observ::` module
|
|
608
|
+
- **Engine pattern**: Mountable Rails engine for easy integration
|
|
609
|
+
- **STI for observations**: `Observ::Generation` and `Observ::Span` inherit from `Observ::Observation`
|
|
610
|
+
- **AASM for state machine**: Prompt lifecycle management
|
|
611
|
+
- **Kaminari for pagination**: Session and trace listings
|
|
612
|
+
- **Stimulus controllers**: Interactive UI components
|
|
613
|
+
- **Rails.cache**: Pluggable caching backend (Redis, Memory, etc.)
|
|
614
|
+
- **Conditional routes**: Chat routes only mount if Chat model exists (Phase 1)
|
|
615
|
+
- **Global namespace**: Controllers use `::Chat` and `::Message` for host app models
|
|
616
|
+
|
|
617
|
+
## Optional Dependencies
|
|
618
|
+
|
|
619
|
+
### Core Features
|
|
620
|
+
- **Redis**: For production caching (optional, can use memory cache)
|
|
621
|
+
|
|
622
|
+
### Chat Feature (Optional Add-on)
|
|
623
|
+
- **RubyLLM**: Required for chat/agent testing feature
|
|
624
|
+
- Installed with `rails generate observ:install:chat`
|
|
625
|
+
- See [Chat Installation Guide](docs/CHAT_INSTALLATION.md)
|
|
626
|
+
|
|
627
|
+
## Testing
|
|
628
|
+
|
|
629
|
+
Disable observability in tests by default:
|
|
630
|
+
|
|
631
|
+
```ruby
|
|
632
|
+
# spec/rails_helper.rb
|
|
633
|
+
RSpec.configure do |config|
|
|
634
|
+
config.before(:each) do
|
|
635
|
+
allow(Rails.configuration.observability).to receive(:enabled).and_return(false)
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
# Enable for specific tests
|
|
639
|
+
config.before(:each, observability: true) do
|
|
640
|
+
allow(Rails.configuration.observability).to receive(:enabled).and_return(true)
|
|
641
|
+
end
|
|
642
|
+
end
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
## Troubleshooting
|
|
646
|
+
|
|
647
|
+
### Routes not found
|
|
648
|
+
|
|
649
|
+
Make sure you've mounted the engine in `config/routes.rb` and restarted your server.
|
|
650
|
+
|
|
651
|
+
### Assets not loading
|
|
652
|
+
|
|
653
|
+
First, make sure you've installed the assets:
|
|
654
|
+
|
|
655
|
+
```bash
|
|
656
|
+
rails generate observ:install
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
Then ensure you've imported them in your application:
|
|
660
|
+
|
|
661
|
+
**For JavaScript/Vite/esbuild setups:**
|
|
662
|
+
|
|
663
|
+
Add to `app/javascript/application.js`:
|
|
664
|
+
```javascript
|
|
665
|
+
import 'observ'
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
And ensure `app/javascript/controllers/index.js` includes:
|
|
669
|
+
```javascript
|
|
670
|
+
import './observ'
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
**For Sprockets (traditional asset pipeline):**
|
|
674
|
+
|
|
675
|
+
Add to `app/assets/stylesheets/application.scss`:
|
|
676
|
+
```scss
|
|
677
|
+
@use 'observ';
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
Or for older Sass versions:
|
|
681
|
+
```scss
|
|
682
|
+
@import 'observ';
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
**Verifying Stimulus controllers:**
|
|
686
|
+
|
|
687
|
+
Check your browser console for any Stimulus connection errors. Observ controllers should register with the `observ--` prefix (e.g., `observ--drawer`, `observ--copy`).
|
|
688
|
+
|
|
689
|
+
**Syncing after gem updates:**
|
|
690
|
+
|
|
691
|
+
If you've updated the Observ gem, run:
|
|
692
|
+
```bash
|
|
693
|
+
rails observ:sync_assets
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
### Concerns not found
|
|
697
|
+
|
|
698
|
+
The engine loads concerns via initializer. Make sure the gem is properly bundled and the app has restarted.
|
|
699
|
+
|
|
700
|
+
### Cache not working
|
|
701
|
+
|
|
702
|
+
Check that:
|
|
703
|
+
- `prompt_cache_ttl > 0`
|
|
704
|
+
- Rails cache store is configured (Redis recommended for production)
|
|
705
|
+
- Rails.cache is working: `Rails.cache.write("test", "value")` / `Rails.cache.read("test")`
|
|
706
|
+
|
|
707
|
+
### Observability sessions not being created
|
|
708
|
+
|
|
709
|
+
If chats are created but observability sessions are not:
|
|
710
|
+
|
|
711
|
+
**1. Check observability is enabled:**
|
|
712
|
+
|
|
713
|
+
```ruby
|
|
714
|
+
rails runner "puts Rails.configuration.observability.enabled.inspect"
|
|
715
|
+
# Should output: true
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
If it outputs `nil` or `false`, check `config/initializers/observability.rb` exists and sets:
|
|
719
|
+
```ruby
|
|
720
|
+
config.observability.enabled = true
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
**2. Check the observability_session_id column exists:**
|
|
724
|
+
|
|
725
|
+
```ruby
|
|
726
|
+
rails runner "puts Chat.column_names.include?('observability_session_id')"
|
|
727
|
+
# Should output: true
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
If it outputs `false`, you're missing the migration. Run:
|
|
731
|
+
```bash
|
|
732
|
+
rails generate migration AddObservabilitySessionIdToChats observability_session_id:string:index
|
|
733
|
+
rails db:migrate
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
**3. Check for errors in logs:**
|
|
737
|
+
|
|
738
|
+
```bash
|
|
739
|
+
tail -f log/development.log | grep Observability
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
Look for `[Observability] Failed to initialize session:` messages.
|
|
743
|
+
|
|
744
|
+
**4. Verify the concern is included:**
|
|
745
|
+
|
|
746
|
+
```ruby
|
|
747
|
+
rails runner "puts Chat.included_modules.include?(Observ::ObservabilityInstrumentation)"
|
|
748
|
+
# Should output: true
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
### Phase tracking errors
|
|
752
|
+
|
|
753
|
+
If you see `AgentPhaseable requires a 'current_phase' column`:
|
|
754
|
+
|
|
755
|
+
You're trying to use phase tracking without the database column. Run:
|
|
756
|
+
|
|
757
|
+
```bash
|
|
758
|
+
rails generate observ:add_phase_tracking
|
|
759
|
+
rails db:migrate
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
Or remove `include Observ::AgentPhaseable` from your Chat model if you don't need phase tracking.
|
|
763
|
+
|
|
764
|
+
## Contributing
|
|
765
|
+
|
|
766
|
+
1. Fork it
|
|
767
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
768
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
769
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
770
|
+
5. Create new Pull Request
|
|
771
|
+
|
|
772
|
+
## License
|
|
773
|
+
|
|
774
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
775
|
+
|
|
776
|
+
## Version
|
|
777
|
+
|
|
778
|
+
Current version: 0.1.0
|