tracebook 0.1.1 → 1.0.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 +4 -4
- data/CHANGELOG.md +49 -24
- data/README.md +197 -713
- data/app/assets/javascripts/tracebook/application.js +92 -35
- data/app/assets/stylesheets/tracebook/application.css +1882 -55
- data/app/controllers/tracebook/application_controller.rb +25 -0
- data/app/controllers/tracebook/chats_controller.rb +229 -0
- data/app/controllers/tracebook/comments_controller.rb +25 -0
- data/app/helpers/tracebook/chats_helper.rb +29 -0
- data/app/models/tracebook/chat_review.rb +19 -0
- data/app/models/tracebook/comment.rb +14 -0
- data/app/models/tracebook/message_cost.rb +12 -0
- data/app/models/tracebook/pricing_rule.rb +6 -8
- data/app/views/tracebook/chats/index.html.erb +77 -0
- data/app/views/tracebook/chats/show.html.erb +94 -0
- data/config/routes.rb +6 -6
- data/db/migrate/20260325000100_create_tracebook_message_costs.rb +19 -0
- data/db/migrate/20260325000200_create_tracebook_chat_reviews.rb +19 -0
- data/db/migrate/{20241112000300_create_tracebook_pricing_rules.rb → 20260325000300_create_tracebook_pricing_rules.rb} +3 -3
- data/db/migrate/20260325000500_create_tracebook_comments.rb +15 -0
- data/lib/generators/tracebook/install/install_generator.rb +6 -9
- data/lib/generators/tracebook/install/templates/initializer.rb.tt +11 -5
- data/lib/tasks/tracebook_tasks.rake +14 -4
- data/lib/tracebook/adapters/ruby_llm.rb +19 -81
- data/lib/tracebook/adapters.rb +5 -4
- data/lib/tracebook/config.rb +83 -104
- data/lib/tracebook/engine.rb +6 -0
- data/lib/tracebook/errors.rb +0 -2
- data/lib/tracebook/pricing/calculator.rb +11 -6
- data/lib/tracebook/pricing.rb +0 -2
- data/lib/tracebook/redaction/pattern.rb +124 -0
- data/lib/tracebook/redaction/pipeline.rb +32 -0
- data/lib/tracebook/seeds/pricing_rules.rb +62 -0
- data/lib/tracebook/version.rb +1 -1
- data/lib/tracebook.rb +46 -152
- metadata +23 -51
- data/app/controllers/tracebook/exports_controller.rb +0 -25
- data/app/controllers/tracebook/interactions_controller.rb +0 -71
- data/app/helpers/tracebook/interactions_helper.rb +0 -35
- data/app/jobs/tracebook/daily_rollups_job.rb +0 -100
- data/app/jobs/tracebook/export_job.rb +0 -162
- data/app/jobs/tracebook/persist_interaction_job.rb +0 -160
- data/app/mailers/tracebook/application_mailer.rb +0 -6
- data/app/models/tracebook/interaction.rb +0 -103
- data/app/models/tracebook/redaction_rule.rb +0 -81
- data/app/models/tracebook/rollup_daily.rb +0 -73
- data/app/views/tracebook/interactions/index.html.erb +0 -108
- data/app/views/tracebook/interactions/show.html.erb +0 -44
- data/db/migrate/20241112000100_create_tracebook_interactions.rb +0 -55
- data/db/migrate/20241112000200_create_tracebook_rollups_dailies.rb +0 -24
- data/db/migrate/20241112000400_create_tracebook_redaction_rules.rb +0 -19
- data/lib/tracebook/adapters/active_agent.rb +0 -82
- data/lib/tracebook/mappers/anthropic.rb +0 -59
- data/lib/tracebook/mappers/base.rb +0 -38
- data/lib/tracebook/mappers/ollama.rb +0 -49
- data/lib/tracebook/mappers/openai.rb +0 -75
- data/lib/tracebook/mappers.rb +0 -283
- data/lib/tracebook/normalized_interaction.rb +0 -86
- data/lib/tracebook/redaction_pipeline.rb +0 -88
- data/lib/tracebook/redactors/base.rb +0 -29
- data/lib/tracebook/redactors/card_pan.rb +0 -15
- data/lib/tracebook/redactors/email.rb +0 -15
- data/lib/tracebook/redactors/phone.rb +0 -15
- data/lib/tracebook/redactors.rb +0 -8
- data/lib/tracebook/result.rb +0 -53
|
@@ -4,14 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
function warnStimulusMissing() {
|
|
6
6
|
if (booted) return;
|
|
7
|
-
|
|
8
|
-
console.warn("TraceBook: Stimulus failed to load; keyboard shortcuts disabled.");
|
|
9
|
-
if (document.body) {
|
|
10
|
-
const banner = document.createElement("div");
|
|
11
|
-
banner.className = "tb-alert";
|
|
12
|
-
banner.textContent = "Keyboard navigation is unavailable because Stimulus failed to load.";
|
|
13
|
-
document.body.prepend(banner);
|
|
14
|
-
}
|
|
7
|
+
console.warn("TraceBook: Stimulus failed to load.");
|
|
15
8
|
}
|
|
16
9
|
|
|
17
10
|
function startApplication() {
|
|
@@ -23,56 +16,120 @@
|
|
|
23
16
|
booted = true;
|
|
24
17
|
const application = window.Stimulus.Application.start();
|
|
25
18
|
|
|
26
|
-
class
|
|
19
|
+
class BulkSelectController extends window.Stimulus.Controller {
|
|
20
|
+
static get targets() {
|
|
21
|
+
return ["toggleAll", "checkbox", "submitButton"];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
connect() {
|
|
25
|
+
this.updateButtonState();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
toggleAll() {
|
|
29
|
+
const checked = this.toggleAllTarget.checked;
|
|
30
|
+
this.checkboxTargets.forEach((checkbox) => {
|
|
31
|
+
checkbox.checked = checked;
|
|
32
|
+
});
|
|
33
|
+
this.updateButtonState();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
checkboxChanged() {
|
|
37
|
+
this.updateButtonState();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
updateButtonState() {
|
|
41
|
+
const hasSelectedCheckboxes = this.checkboxTargets.some((checkbox) => checkbox.checked);
|
|
42
|
+
this.submitButtonTarget.disabled = !hasSelectedCheckboxes;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class JsonViewerController extends window.Stimulus.Controller {
|
|
27
47
|
static get targets() {
|
|
28
|
-
return ["
|
|
48
|
+
return ["content", "icon", "copyBtn", "copyText"];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static get values() {
|
|
52
|
+
return { collapsed: Boolean };
|
|
29
53
|
}
|
|
30
54
|
|
|
31
55
|
connect() {
|
|
32
|
-
this.
|
|
33
|
-
|
|
34
|
-
|
|
56
|
+
if (this.collapsedValue) {
|
|
57
|
+
this.collapse();
|
|
58
|
+
} else {
|
|
59
|
+
this.expand();
|
|
60
|
+
}
|
|
35
61
|
}
|
|
36
62
|
|
|
37
|
-
|
|
38
|
-
if
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
63
|
+
toggle(event) {
|
|
64
|
+
// Don't toggle if clicking the copy button
|
|
65
|
+
if (event.target.closest('.tb-copy-btn')) return;
|
|
66
|
+
|
|
67
|
+
if (this.element.classList.contains("tb-collapsed")) {
|
|
68
|
+
this.expand();
|
|
69
|
+
} else {
|
|
70
|
+
this.collapse();
|
|
42
71
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
collapse() {
|
|
75
|
+
this.element.classList.add("tb-collapsed");
|
|
76
|
+
this.element.classList.remove("tb-expanded");
|
|
77
|
+
if (this.hasContentTarget) {
|
|
78
|
+
this.contentTarget.style.display = "none";
|
|
47
79
|
}
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
const checkbox = this.checkboxTargets[this.index];
|
|
51
|
-
if (checkbox) {
|
|
52
|
-
checkbox.checked = !checkbox.checked;
|
|
53
|
-
}
|
|
80
|
+
if (this.hasIconTarget) {
|
|
81
|
+
this.iconTarget.textContent = "▶";
|
|
54
82
|
}
|
|
55
83
|
}
|
|
56
84
|
|
|
57
|
-
|
|
58
|
-
this.
|
|
59
|
-
|
|
85
|
+
expand() {
|
|
86
|
+
this.element.classList.remove("tb-collapsed");
|
|
87
|
+
this.element.classList.add("tb-expanded");
|
|
88
|
+
if (this.hasContentTarget) {
|
|
89
|
+
this.contentTarget.style.display = "block";
|
|
90
|
+
}
|
|
91
|
+
if (this.hasIconTarget) {
|
|
92
|
+
this.iconTarget.textContent = "▼";
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
copy(event) {
|
|
97
|
+
event.stopPropagation();
|
|
98
|
+
const btn = event.currentTarget;
|
|
99
|
+
const payload = btn.dataset.payload;
|
|
100
|
+
|
|
101
|
+
navigator.clipboard.writeText(payload).then(() => {
|
|
102
|
+
if (this.hasCopyTextTarget) {
|
|
103
|
+
const originalText = this.copyTextTarget.textContent;
|
|
104
|
+
this.copyTextTarget.textContent = "Copied!";
|
|
105
|
+
setTimeout(() => { this.copyTextTarget.textContent = originalText; }, 2000);
|
|
106
|
+
}
|
|
107
|
+
}).catch(() => {
|
|
108
|
+
console.error("Failed to copy to clipboard");
|
|
60
109
|
});
|
|
61
110
|
}
|
|
62
111
|
}
|
|
63
112
|
|
|
64
|
-
class
|
|
113
|
+
class MessageToggleController extends window.Stimulus.Controller {
|
|
65
114
|
static get targets() {
|
|
66
|
-
return ["content"];
|
|
115
|
+
return ["content", "icon"];
|
|
67
116
|
}
|
|
68
117
|
|
|
69
118
|
toggle() {
|
|
70
|
-
this.
|
|
119
|
+
const isHidden = this.contentTarget.classList.contains("hidden");
|
|
120
|
+
if (isHidden) {
|
|
121
|
+
this.contentTarget.classList.remove("hidden");
|
|
122
|
+
this.iconTarget.textContent = "▼";
|
|
123
|
+
} else {
|
|
124
|
+
this.contentTarget.classList.add("hidden");
|
|
125
|
+
this.iconTarget.textContent = "▶";
|
|
126
|
+
}
|
|
71
127
|
}
|
|
72
128
|
}
|
|
73
129
|
|
|
74
|
-
application.register("
|
|
130
|
+
application.register("bulk-select", BulkSelectController);
|
|
75
131
|
application.register("json-viewer", JsonViewerController);
|
|
132
|
+
application.register("message-toggle", MessageToggleController);
|
|
76
133
|
}
|
|
77
134
|
|
|
78
135
|
if (window.Stimulus) {
|