rubyllm-observ 0.5.0 → 0.6.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.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +54 -6
  3. data/app/assets/stylesheets/observ/_annotations.scss +114 -103
  4. data/app/assets/stylesheets/observ/_card.scss +58 -49
  5. data/app/assets/stylesheets/observ/_chat.scss +247 -155
  6. data/app/assets/stylesheets/observ/_components.scss +622 -340
  7. data/app/assets/stylesheets/observ/_dashboard.scss +31 -28
  8. data/app/assets/stylesheets/observ/_datasets.scss +494 -547
  9. data/app/assets/stylesheets/observ/_drawer.scss +250 -228
  10. data/app/assets/stylesheets/observ/_filters.scss +139 -0
  11. data/app/assets/stylesheets/observ/_json_viewer.scss +103 -97
  12. data/app/assets/stylesheets/observ/_layout.scss +443 -178
  13. data/app/assets/stylesheets/observ/_metrics.scss +79 -76
  14. data/app/assets/stylesheets/observ/_namespace.scss +18 -0
  15. data/app/assets/stylesheets/observ/_observations.scss +122 -119
  16. data/app/assets/stylesheets/observ/_pagination.scss +129 -112
  17. data/app/assets/stylesheets/observ/_prompts.scss +485 -269
  18. data/app/assets/stylesheets/observ/_reset.scss +249 -0
  19. data/app/assets/stylesheets/observ/_table.scss +46 -38
  20. data/app/assets/stylesheets/observ/_variables.scss +54 -0
  21. data/app/assets/stylesheets/observ/application.scss +3 -0
  22. data/app/controllers/observ/dataset_run_items_controller.rb +0 -1
  23. data/app/controllers/observ/review_queue_controller.rb +154 -0
  24. data/app/controllers/observ/scores_controller.rb +64 -0
  25. data/app/controllers/observ/sessions_controller.rb +23 -0
  26. data/app/helpers/observ/application_helper.rb +1 -0
  27. data/app/helpers/observ/reviews_helper.rb +33 -0
  28. data/app/models/concerns/observ/json_queryable.rb +138 -0
  29. data/app/models/concerns/observ/reviewable.rb +41 -0
  30. data/app/models/concerns/observ/scoreable.rb +34 -0
  31. data/app/models/observ/dataset_run_item.rb +3 -13
  32. data/app/models/observ/review_item.rb +48 -0
  33. data/app/models/observ/score.rb +38 -6
  34. data/app/models/observ/session.rb +5 -1
  35. data/app/models/observ/trace.rb +3 -0
  36. data/app/services/observ/evaluators/base_evaluator.rb +0 -1
  37. data/app/services/observ/guardrail_service.rb +128 -0
  38. data/app/views/kaminari/_first_page.html.erb +1 -1
  39. data/app/views/kaminari/_gap.html.erb +1 -1
  40. data/app/views/kaminari/_last_page.html.erb +1 -1
  41. data/app/views/kaminari/_next_page.html.erb +1 -1
  42. data/app/views/kaminari/_page.html.erb +1 -1
  43. data/app/views/kaminari/_paginator.html.erb +1 -1
  44. data/app/views/kaminari/_prev_page.html.erb +1 -1
  45. data/app/views/kaminari/observ/_first_page.html.erb +1 -1
  46. data/app/views/kaminari/observ/_gap.html.erb +1 -1
  47. data/app/views/kaminari/observ/_last_page.html.erb +1 -1
  48. data/app/views/kaminari/observ/_next_page.html.erb +1 -1
  49. data/app/views/kaminari/observ/_page.html.erb +1 -1
  50. data/app/views/kaminari/observ/_paginator.html.erb +1 -1
  51. data/app/views/kaminari/observ/_prev_page.html.erb +1 -1
  52. data/app/views/layouts/observ/application.html.erb +96 -58
  53. data/app/views/observ/annotations/_form.html.erb +5 -5
  54. data/app/views/observ/annotations/index.html.erb +4 -4
  55. data/app/views/observ/annotations/sessions_index.html.erb +9 -9
  56. data/app/views/observ/annotations/traces_index.html.erb +9 -9
  57. data/app/views/observ/chats/_form.html.erb +7 -7
  58. data/app/views/observ/datasets/index.html.erb +6 -6
  59. data/app/views/observ/messages/_form.html.erb +11 -12
  60. data/app/views/observ/observations/index.html.erb +3 -4
  61. data/app/views/observ/prompts/_form.html.erb +37 -38
  62. data/app/views/observ/prompts/_new_form.html.erb +37 -38
  63. data/app/views/observ/prompts/compare.html.erb +59 -55
  64. data/app/views/observ/prompts/edit.html.erb +3 -3
  65. data/app/views/observ/prompts/index.html.erb +9 -9
  66. data/app/views/observ/prompts/new.html.erb +3 -3
  67. data/app/views/observ/prompts/show.html.erb +2 -2
  68. data/app/views/observ/prompts/versions.html.erb +22 -22
  69. data/app/views/observ/review_queue/_item.html.erb +39 -0
  70. data/app/views/observ/review_queue/_stats.html.erb +18 -0
  71. data/app/views/observ/review_queue/index.html.erb +49 -0
  72. data/app/views/observ/review_queue/show.html.erb +76 -0
  73. data/app/views/observ/review_queue/stats.html.erb +100 -0
  74. data/app/views/observ/scores/_form.html.erb +39 -0
  75. data/app/views/observ/scores/create.turbo_stream.erb +10 -0
  76. data/app/views/observ/sessions/_chat.html.erb +59 -0
  77. data/app/views/observ/sessions/_metadata.html.erb +17 -0
  78. data/app/views/observ/sessions/_metrics.html.erb +81 -0
  79. data/app/views/observ/sessions/_traces.html.erb +92 -0
  80. data/app/views/observ/sessions/annotations_drawer.turbo_stream.erb +8 -1
  81. data/app/views/observ/sessions/index.html.erb +60 -4
  82. data/app/views/observ/sessions/show.html.erb +4 -217
  83. data/app/views/observ/traces/_details.html.erb +47 -0
  84. data/app/views/observ/traces/_input.html.erb +10 -0
  85. data/app/views/observ/traces/_metadata.html.erb +10 -0
  86. data/app/views/observ/traces/_observations.html.erb +172 -0
  87. data/app/views/observ/traces/_output.html.erb +10 -0
  88. data/app/views/observ/traces/annotations_drawer.turbo_stream.erb +8 -1
  89. data/app/views/observ/traces/index.html.erb +3 -4
  90. data/app/views/observ/traces/show.html.erb +5 -232
  91. data/config/routes.rb +14 -0
  92. data/db/migrate/015_refactor_scores_to_polymorphic.rb +27 -0
  93. data/db/migrate/016_create_observ_review_items.rb +25 -0
  94. data/lib/observ/version.rb +1 -1
  95. data/lib/rubyllm-observ.rb +1 -0
  96. metadata +31 -1
@@ -1,99 +1,102 @@
1
1
  @import 'variables';
2
+ @import 'namespace';
2
3
 
3
- .observ-metrics-grid {
4
- display: grid;
5
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
6
- gap: $observ-spacing-lg;
4
+ @include observ-scoped {
5
+ .observ-metrics-grid {
6
+ display: grid;
7
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
8
+ gap: $observ-spacing-lg;
7
9
 
8
- &--4col {
9
- grid-template-columns: repeat(4, 1fr);
10
+ &--4col {
11
+ grid-template-columns: repeat(4, 1fr);
10
12
 
11
- @media (max-width: $observ-breakpoint-lg) {
12
- grid-template-columns: repeat(2, 1fr);
13
- }
13
+ @media (max-width: $observ-breakpoint-lg) {
14
+ grid-template-columns: repeat(2, 1fr);
15
+ }
14
16
 
15
- @media (max-width: $observ-breakpoint-sm) {
16
- grid-template-columns: 1fr;
17
+ @media (max-width: $observ-breakpoint-sm) {
18
+ grid-template-columns: 1fr;
19
+ }
17
20
  }
18
21
  }
19
- }
20
22
 
21
- .observ-metric-card {
22
- background-color: $observ-white;
23
- border-radius: $observ-border-radius;
24
- box-shadow: $observ-shadow;
25
- padding: $observ-spacing-lg;
26
- transition: $observ-transition;
23
+ .observ-metric-card {
24
+ background-color: $observ-bg-surface;
25
+ border: 1px solid $observ-border-color;
26
+ border-radius: $observ-border-radius;
27
+ padding: $observ-spacing-lg;
28
+ transition: all 0.2s ease-in-out;
27
29
 
28
- &:hover {
29
- box-shadow: $observ-shadow-md;
30
- }
31
-
32
- &__header {
33
- display: flex;
34
- align-items: center;
35
- justify-content: space-between;
36
- margin-bottom: $observ-spacing-md;
37
- }
30
+ &:hover {
31
+ background-color: $observ-bg-hover;
32
+ }
38
33
 
39
- &__label {
40
- font-size: $observ-font-size-sm;
41
- font-weight: 500;
42
- color: $observ-gray-600;
43
- margin: 0;
44
- text-transform: uppercase;
45
- letter-spacing: 0.05em;
46
- }
34
+ &__header {
35
+ display: flex;
36
+ align-items: center;
37
+ justify-content: space-between;
38
+ margin-bottom: $observ-spacing-md;
39
+ }
47
40
 
48
- &__body {
49
- display: flex;
50
- align-items: baseline;
51
- gap: $observ-spacing-sm;
52
- }
41
+ &__label {
42
+ font-size: $observ-font-size-sm;
43
+ font-weight: 600;
44
+ color: $observ-text-muted;
45
+ margin: 0;
46
+ }
53
47
 
54
- &__value {
55
- font-size: $observ-font-size-3xl;
56
- font-weight: 700;
57
- color: $observ-gray-900;
58
- margin: 0;
59
- line-height: 1;
48
+ &__body {
49
+ display: flex;
50
+ align-items: baseline;
51
+ gap: $observ-spacing-sm;
52
+ }
60
53
 
61
- &--small {
62
- font-size: $observ-font-size-xl;
54
+ &__value {
55
+ font-size: $observ-font-size-3xl;
56
+ font-weight: 700;
57
+ color: $observ-text-primary;
58
+ margin: 0;
59
+ line-height: 1.1;
60
+ letter-spacing: -0.02em;
61
+ font-variant-numeric: tabular-nums;
62
+
63
+ &--small {
64
+ font-size: $observ-font-size-xl;
65
+ }
63
66
  }
64
- }
65
67
 
66
- &--highlighted {
67
- background: linear-gradient(135deg, lighten($observ-primary, 45%) 0%, lighten($observ-info, 45%) 100%);
68
- border: 1px solid $observ-primary;
68
+ &--highlighted {
69
+ background: linear-gradient(135deg, rgba($observ-primary, 0.15) 0%, rgba($observ-info, 0.15) 100%);
70
+ border: 1px solid $observ-primary;
69
71
 
70
- .observ-metric-card__value {
71
- color: $observ-primary;
72
+ .observ-metric-card__value {
73
+ color: $observ-primary;
74
+ }
72
75
  }
73
76
  }
74
- }
75
77
 
76
- .observ-trend {
77
- display: inline-flex;
78
- align-items: center;
79
- gap: 0.25rem;
80
- padding: 0.25rem 0.5rem;
81
- border-radius: $observ-border-radius-sm;
82
- font-size: $observ-font-size-xs;
83
- font-weight: 600;
84
-
85
- &--positive {
86
- background-color: lighten($observ-success, 45%);
87
- color: darken($observ-success, 10%);
88
- }
78
+ .observ-trend {
79
+ display: inline-flex;
80
+ align-items: center;
81
+ gap: 0.25rem;
82
+ padding: 0.25rem 0.5rem;
83
+ border-radius: $observ-border-radius-sm;
84
+ font-size: $observ-font-size-xs;
85
+ font-weight: 600;
86
+
87
+ &--positive {
88
+ background-color: rgba($observ-success, 0.15);
89
+ color: lighten($observ-success, 15%);
90
+ }
89
91
 
90
- &--negative {
91
- background-color: lighten($observ-danger, 45%);
92
- color: darken($observ-danger, 10%);
93
- }
92
+ &--negative {
93
+ background-color: rgba($observ-danger, 0.15);
94
+ color: lighten($observ-danger, 15%);
95
+ }
94
96
 
95
- &--neutral {
96
- background-color: $observ-gray-100;
97
- color: $observ-gray-600;
97
+ &--neutral {
98
+ background-color: $observ-bg-elevated;
99
+ color: $observ-text-secondary;
100
+ }
98
101
  }
99
102
  }
@@ -0,0 +1,18 @@
1
+ // Observ Namespace Mixin
2
+ // ======================
3
+ // Use this mixin to scope all Observ styles under .observ-layout
4
+ // This ensures isolation from host application styles.
5
+ //
6
+ // Usage:
7
+ // @include observ-scoped {
8
+ // .observ-button { ... }
9
+ // }
10
+ //
11
+ // Outputs:
12
+ // .observ-layout .observ-button { ... }
13
+
14
+ @mixin observ-scoped {
15
+ .observ-layout {
16
+ @content;
17
+ }
18
+ }
@@ -1,160 +1,163 @@
1
1
  @import 'variables';
2
+ @import 'namespace';
2
3
 
3
- .observ-observations-list {
4
- display: flex;
5
- flex-direction: column;
6
- gap: $observ-spacing-lg;
4
+ @include observ-scoped {
5
+ .observ-observations-list {
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: $observ-spacing-lg;
7
9
 
8
- &--compact {
9
- gap: $observ-spacing-sm;
10
+ &--compact {
11
+ gap: $observ-spacing-sm;
12
+ }
10
13
  }
11
- }
12
-
13
- .observ-observation-card {
14
- border: 1px solid $observ-gray-200;
15
- border-radius: $observ-border-radius;
16
- background-color: $observ-white;
17
- overflow: hidden;
18
14
 
19
- &--generation {
20
- border-left: 4px solid $observ-primary;
21
- }
15
+ .observ-observation-card {
16
+ border: 1px solid $observ-border-color;
17
+ border-radius: $observ-border-radius;
18
+ background-color: $observ-bg-surface;
19
+ overflow: hidden;
22
20
 
23
- &--span {
24
- border-left: 4px solid $observ-info;
25
- }
21
+ &--generation {
22
+ border-left: 4px solid $observ-primary;
23
+ }
26
24
 
27
- &--compact {
28
- font-size: 0.875rem;
29
- }
25
+ &--span {
26
+ border-left: 4px solid $observ-info;
27
+ }
30
28
 
31
- &__header {
32
- padding: $observ-spacing-md;
33
- background-color: $observ-gray-50;
34
- display: flex;
35
- align-items: center;
36
- gap: $observ-spacing-md;
29
+ &--compact {
30
+ font-size: 0.875rem;
31
+ }
37
32
 
38
- .observ-observation-card--compact & {
39
- padding: 0.375rem 0.75rem;
40
- gap: 0.5rem;
33
+ &__header {
34
+ padding: $observ-spacing-md;
35
+ background-color: $observ-bg-elevated;
36
+ display: flex;
37
+ align-items: center;
38
+ gap: $observ-spacing-md;
39
+
40
+ .observ-observation-card--compact & {
41
+ padding: 0.375rem 0.75rem;
42
+ gap: 0.5rem;
43
+ }
41
44
  }
42
- }
43
45
 
44
- &__type-badge {
45
- display: inline-flex;
46
- padding: 0.25rem 0.5rem;
47
- background-color: $observ-gray-200;
48
- color: $observ-gray-700;
49
- border-radius: $observ-border-radius-sm;
50
- font-size: $observ-font-size-xs;
51
- font-weight: 600;
52
- text-transform: uppercase;
53
- letter-spacing: 0.05em;
54
-
55
- .observ-observation-card--compact & {
56
- padding: 0.125rem 0.375rem;
57
- font-size: 0.625rem;
46
+ &__type-badge {
47
+ display: inline-flex;
48
+ padding: 0.25rem 0.5rem;
49
+ background-color: $observ-bg-hover;
50
+ color: $observ-text-secondary;
51
+ border-radius: $observ-border-radius-sm;
52
+ font-size: $observ-font-size-xs;
53
+ font-weight: 600;
54
+ text-transform: uppercase;
55
+ letter-spacing: 0.05em;
56
+
57
+ .observ-observation-card--compact & {
58
+ padding: 0.125rem 0.375rem;
59
+ font-size: 0.625rem;
60
+ }
58
61
  }
59
- }
60
62
 
61
- &__name {
62
- font-size: $observ-font-size-lg;
63
- font-weight: 600;
64
- margin: 0;
65
- color: $observ-gray-900;
66
- flex: 1;
63
+ &__name {
64
+ font-size: $observ-font-size-lg;
65
+ font-weight: 600;
66
+ margin: 0;
67
+ color: $observ-text-primary;
68
+ flex: 1;
67
69
 
68
- .observ-observation-card--compact & {
69
- font-size: 0.875rem;
70
+ .observ-observation-card--compact & {
71
+ font-size: 0.875rem;
72
+ }
70
73
  }
71
- }
72
74
 
73
- &__meta {
74
- display: flex;
75
- align-items: center;
76
- gap: $observ-spacing-sm;
77
- }
75
+ &__meta {
76
+ display: flex;
77
+ align-items: center;
78
+ gap: $observ-spacing-sm;
79
+ }
78
80
 
79
- &__id {
80
- font-size: $observ-font-size-sm;
81
- color: $observ-gray-500;
81
+ &__id {
82
+ font-size: $observ-font-size-sm;
83
+ color: $observ-text-muted;
82
84
 
83
- .observ-observation-card--compact & {
84
- font-size: 0.75rem;
85
+ .observ-observation-card--compact & {
86
+ font-size: 0.75rem;
87
+ }
85
88
  }
86
- }
87
89
 
88
- &__body {
89
- padding: $observ-spacing-md;
90
+ &__body {
91
+ padding: $observ-spacing-md;
90
92
 
91
- .observ-observation-card--compact & {
92
- padding: 0.5rem 0.75rem;
93
+ .observ-observation-card--compact & {
94
+ padding: 0.5rem 0.75rem;
95
+ }
93
96
  }
94
- }
95
97
 
96
- &__section {
97
- padding: $observ-spacing-md;
98
- border-top: 1px solid $observ-gray-100;
98
+ &__section {
99
+ padding: $observ-spacing-md;
100
+ border-top: 1px solid $observ-border-subtle;
99
101
 
100
- &--compact {
101
- padding: 0.5rem 0.75rem;
102
+ &--compact {
103
+ padding: 0.5rem 0.75rem;
104
+ }
102
105
  }
103
- }
104
-
105
- &__section-title {
106
- font-size: $observ-font-size-sm;
107
- font-weight: 600;
108
- color: $observ-gray-700;
109
- margin: 0 0 $observ-spacing-sm 0;
110
- text-transform: uppercase;
111
- letter-spacing: 0.05em;
112
106
 
113
- .observ-observation-card--compact & {
114
- font-size: 0.688rem;
115
- margin: 0 0 0.25rem 0;
107
+ &__section-title {
108
+ font-size: $observ-font-size-sm;
109
+ font-weight: 600;
110
+ color: $observ-text-secondary;
111
+ margin: 0 0 $observ-spacing-sm 0;
112
+ text-transform: uppercase;
113
+ letter-spacing: 0.05em;
114
+
115
+ .observ-observation-card--compact & {
116
+ font-size: 0.688rem;
117
+ margin: 0 0 0.25rem 0;
118
+ }
116
119
  }
117
- }
118
120
 
119
- &__footer {
120
- padding: $observ-spacing-md;
121
- border-top: 1px solid $observ-gray-200;
122
- background-color: $observ-gray-50;
121
+ &__footer {
122
+ padding: $observ-spacing-md;
123
+ border-top: 1px solid $observ-border-subtle;
124
+ background-color: $observ-bg-elevated;
123
125
 
124
- .observ-observation-card--compact & {
125
- padding: 0.375rem 0.75rem;
126
+ .observ-observation-card--compact & {
127
+ padding: 0.375rem 0.75rem;
128
+ }
126
129
  }
127
130
  }
128
- }
129
-
130
- .observ-code-block--compact {
131
- font-size: 0.75rem;
132
- line-height: 1.4;
133
- padding: 1rem;
134
- }
135
131
 
136
- .observ-card--compact {
137
- .observ-card__header {
138
- padding: 0.5rem 0.75rem;
132
+ .observ-code-block--compact {
133
+ font-size: 0.75rem;
134
+ line-height: 1.4;
135
+ padding: 1rem;
139
136
  }
140
137
 
141
- .observ-card__body {
142
- padding: 0.75rem;
143
- }
138
+ .observ-card--compact {
139
+ .observ-card__header {
140
+ padding: 0.5rem 0.75rem;
141
+ }
142
+
143
+ .observ-card__body {
144
+ padding: 0.75rem;
145
+ }
144
146
 
145
- .observ-card__title {
146
- font-size: 0.875rem;
147
+ .observ-card__title {
148
+ font-size: 0.875rem;
149
+ }
147
150
  }
148
- }
149
151
 
150
- .observ-definition-list--compact {
151
- gap: 0.5rem;
152
+ .observ-definition-list--compact {
153
+ gap: 0.5rem;
152
154
 
153
- .observ-definition-list__term {
154
- font-size: 0.75rem;
155
- }
155
+ .observ-definition-list__term {
156
+ font-size: 0.75rem;
157
+ }
156
158
 
157
- .observ-definition-list__definition {
158
- font-size: 0.813rem;
159
+ .observ-definition-list__definition {
160
+ font-size: 0.813rem;
161
+ }
159
162
  }
160
163
  }