completion-kit 0.4.8 → 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 +4 -4
- data/README.md +1 -0
- data/app/assets/stylesheets/completion_kit/application.css +375 -0
- data/app/controllers/completion_kit/api/v1/datasets_controller.rb +2 -2
- data/app/controllers/completion_kit/api/v1/metric_groups_controller.rb +2 -2
- data/app/controllers/completion_kit/api/v1/metrics_controller.rb +3 -2
- data/app/controllers/completion_kit/api/v1/prompts_controller.rb +5 -4
- data/app/controllers/completion_kit/api/v1/runs_controller.rb +3 -2
- data/app/controllers/completion_kit/api/v1/tags_controller.rb +51 -0
- data/app/controllers/completion_kit/datasets_controller.rb +3 -2
- data/app/controllers/completion_kit/metric_groups_controller.rb +7 -6
- data/app/controllers/completion_kit/metrics_controller.rb +4 -2
- data/app/controllers/completion_kit/prompts_controller.rb +7 -4
- data/app/controllers/completion_kit/runs_controller.rb +4 -3
- data/app/controllers/completion_kit/tags_controller.rb +50 -0
- data/app/controllers/concerns/completion_kit/tag_filtering.rb +22 -0
- data/app/helpers/completion_kit/application_helper.rb +11 -0
- data/app/models/completion_kit/dataset.rb +5 -2
- data/app/models/completion_kit/metric.rb +4 -1
- data/app/models/completion_kit/metric_group.rb +4 -1
- data/app/models/completion_kit/prompt.rb +4 -1
- data/app/models/completion_kit/run.rb +3 -1
- data/app/models/completion_kit/tag.rb +39 -0
- data/app/models/completion_kit/tagging.rb +12 -0
- data/app/models/concerns/completion_kit/taggable.rb +24 -0
- data/app/services/completion_kit/mcp_dispatcher.rb +3 -1
- data/app/services/completion_kit/mcp_tools/datasets.rb +6 -4
- data/app/services/completion_kit/mcp_tools/metric_groups.rb +6 -2
- data/app/services/completion_kit/mcp_tools/metrics.rb +8 -4
- data/app/services/completion_kit/mcp_tools/prompts.rb +10 -5
- data/app/services/completion_kit/mcp_tools/runs.rb +7 -3
- data/app/services/completion_kit/mcp_tools/tags.rb +74 -0
- data/app/views/completion_kit/api_reference/index.html.erb +38 -0
- data/app/views/completion_kit/datasets/_form.html.erb +20 -1
- data/app/views/completion_kit/datasets/index.html.erb +17 -1
- data/app/views/completion_kit/datasets/show.html.erb +6 -0
- data/app/views/completion_kit/metric_groups/_form.html.erb +74 -19
- data/app/views/completion_kit/metric_groups/index.html.erb +30 -4
- data/app/views/completion_kit/metrics/_form.html.erb +19 -1
- data/app/views/completion_kit/metrics/index.html.erb +18 -2
- data/app/views/completion_kit/metrics/show.html.erb +6 -0
- data/app/views/completion_kit/prompts/_form.html.erb +20 -1
- data/app/views/completion_kit/prompts/index.html.erb +17 -1
- data/app/views/completion_kit/prompts/show.html.erb +6 -0
- data/app/views/completion_kit/provider_credentials/_form.html.erb +1 -1
- data/app/views/completion_kit/provider_credentials/index.html.erb +3 -1
- data/app/views/completion_kit/runs/_form.html.erb +25 -3
- data/app/views/completion_kit/runs/_row.html.erb +5 -0
- data/app/views/completion_kit/runs/index.html.erb +9 -0
- data/app/views/completion_kit/runs/show.html.erb +6 -0
- data/app/views/completion_kit/shared/_settings_nav.html.erb +9 -0
- data/app/views/completion_kit/tags/_filter_bar.html.erb +15 -0
- data/app/views/completion_kit/tags/_form.html.erb +39 -0
- data/app/views/completion_kit/tags/_marks.html.erb +3 -0
- data/app/views/completion_kit/tags/_picker.html.erb +20 -0
- data/app/views/completion_kit/tags/edit.html.erb +20 -0
- data/app/views/completion_kit/tags/index.html.erb +45 -0
- data/app/views/completion_kit/tags/new.html.erb +20 -0
- data/app/views/layouts/completion_kit/application.html.erb +38 -1
- data/config/routes.rb +2 -0
- data/db/migrate/20260509000001_create_completion_kit_tags.rb +10 -0
- data/db/migrate/20260509000002_create_completion_kit_taggings.rb +16 -0
- data/lib/completion_kit/version.rb +1 -1
- metadata +18 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e4a1592e3ab99397804845b4b200ec44ec78ba2575426aa34525ce1137b932fc
|
|
4
|
+
data.tar.gz: baaed961b26171e4fac1410b587de872f5e0c28606d3b591232218406cca79d3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a0709c0819790bcb7246920fbaa6440debbafaa5872fa968f3d91acc1c3011c60c1682187d4a64102a81ead142ce2b0aa123503b13f9730967e20d3e1b156a94
|
|
7
|
+
data.tar.gz: 6ea65ed6fec559e8b92c5f3cc46812425120a5a20681d527d7cb05c32dd39e22a6705b95df21f51657a0bf4e255cbc0e876df49e181578714218aaf921234754
|
data/README.md
CHANGED
|
@@ -136,6 +136,7 @@ Only one mode can be active.
|
|
|
136
136
|
- **Response.** The model's output for one dataset row, with reviews attached.
|
|
137
137
|
- **Metric.** An evaluation dimension with a name, instruction, evaluation steps, and a 1-5 star scoring scale. The LLM judge uses this to score each response.
|
|
138
138
|
- **Metric Group.** A reusable group of metrics you can apply to a run as a set.
|
|
139
|
+
- **Tag.** A domain label you can attach to prompts, runs, metrics, and datasets. Auto-assigned from a 10-color palette. Filter any index page by tag (`?tag[]=...`).
|
|
139
140
|
- **Provider Credential.** An API key for a model provider. Encrypted at rest, never returned through the API.
|
|
140
141
|
|
|
141
142
|
## REST API
|
|
@@ -501,6 +501,11 @@ tr:hover .ck-chip--publish {
|
|
|
501
501
|
transform: translateY(-1px);
|
|
502
502
|
}
|
|
503
503
|
|
|
504
|
+
.ck-button:focus-visible {
|
|
505
|
+
outline: 2px solid var(--ck-accent);
|
|
506
|
+
outline-offset: 2px;
|
|
507
|
+
}
|
|
508
|
+
|
|
504
509
|
.ck-button--primary {
|
|
505
510
|
background: var(--ck-accent);
|
|
506
511
|
color: #080b14;
|
|
@@ -1531,6 +1536,11 @@ tr:hover .ck-chip--publish {
|
|
|
1531
1536
|
color: var(--ck-danger);
|
|
1532
1537
|
}
|
|
1533
1538
|
|
|
1539
|
+
.ck-icon-btn:focus-visible {
|
|
1540
|
+
outline: 2px solid var(--ck-accent);
|
|
1541
|
+
outline-offset: 2px;
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1534
1544
|
.ck-icon-btn--spinning svg {
|
|
1535
1545
|
animation: ck-spin 0.8s linear infinite;
|
|
1536
1546
|
}
|
|
@@ -2594,6 +2604,7 @@ select.ck-input {
|
|
|
2594
2604
|
align-items: center;
|
|
2595
2605
|
gap: 0.4rem;
|
|
2596
2606
|
padding: 0.32rem 0.7rem;
|
|
2607
|
+
white-space: nowrap;
|
|
2597
2608
|
background: transparent;
|
|
2598
2609
|
border: 1px solid var(--ck-line);
|
|
2599
2610
|
border-radius: 999px;
|
|
@@ -2842,6 +2853,72 @@ select.ck-input {
|
|
|
2842
2853
|
color: var(--ck-dim);
|
|
2843
2854
|
}
|
|
2844
2855
|
|
|
2856
|
+
.ck-clamp-2 {
|
|
2857
|
+
display: -webkit-box;
|
|
2858
|
+
-webkit-line-clamp: 2;
|
|
2859
|
+
-webkit-box-orient: vertical;
|
|
2860
|
+
overflow: hidden;
|
|
2861
|
+
}
|
|
2862
|
+
|
|
2863
|
+
.ck-tags-table th:first-child,
|
|
2864
|
+
.ck-tags-table td:first-child {
|
|
2865
|
+
width: 35%;
|
|
2866
|
+
}
|
|
2867
|
+
.ck-tags-table th:nth-child(2),
|
|
2868
|
+
.ck-tags-table td:nth-child(2) {
|
|
2869
|
+
width: 60%;
|
|
2870
|
+
}
|
|
2871
|
+
.tag-mark.tag-mark--lg {
|
|
2872
|
+
padding: 4px 10px;
|
|
2873
|
+
font-size: 0.8rem;
|
|
2874
|
+
letter-spacing: 0.02em;
|
|
2875
|
+
border-radius: 5px;
|
|
2876
|
+
}
|
|
2877
|
+
.ck-tags-table__unused {
|
|
2878
|
+
color: var(--ck-dim);
|
|
2879
|
+
font-style: italic;
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
.ck-mg-members {
|
|
2883
|
+
display: flex;
|
|
2884
|
+
flex-wrap: wrap;
|
|
2885
|
+
gap: 0.3rem;
|
|
2886
|
+
}
|
|
2887
|
+
.ck-mg-member {
|
|
2888
|
+
display: inline-flex;
|
|
2889
|
+
align-items: center;
|
|
2890
|
+
padding: 2px 8px;
|
|
2891
|
+
background: var(--ck-surface-soft);
|
|
2892
|
+
border: 1px solid var(--ck-line);
|
|
2893
|
+
border-radius: 4px;
|
|
2894
|
+
font-family: var(--ck-mono);
|
|
2895
|
+
font-size: 11px;
|
|
2896
|
+
letter-spacing: 0.02em;
|
|
2897
|
+
color: var(--ck-muted);
|
|
2898
|
+
white-space: nowrap;
|
|
2899
|
+
}
|
|
2900
|
+
|
|
2901
|
+
.ck-metric-tag-filter {
|
|
2902
|
+
display: flex;
|
|
2903
|
+
flex-wrap: wrap;
|
|
2904
|
+
align-items: center;
|
|
2905
|
+
gap: 8px;
|
|
2906
|
+
margin: 0.5rem 0 0.85rem;
|
|
2907
|
+
}
|
|
2908
|
+
.ck-metric-tag-filter__label {
|
|
2909
|
+
font-family: var(--ck-mono);
|
|
2910
|
+
font-size: 11px;
|
|
2911
|
+
letter-spacing: 0.14em;
|
|
2912
|
+
text-transform: uppercase;
|
|
2913
|
+
color: var(--ck-dim);
|
|
2914
|
+
margin-right: 0.3rem;
|
|
2915
|
+
}
|
|
2916
|
+
.ck-metric-tag-filter__chip {
|
|
2917
|
+
border-radius: 5px;
|
|
2918
|
+
font: inherit;
|
|
2919
|
+
cursor: pointer;
|
|
2920
|
+
}
|
|
2921
|
+
|
|
2845
2922
|
.ck-metrics-table__groups {
|
|
2846
2923
|
display: flex;
|
|
2847
2924
|
flex-wrap: wrap;
|
|
@@ -3396,3 +3473,301 @@ a.ck-metric-group-pill {
|
|
|
3396
3473
|
text-overflow: ellipsis;
|
|
3397
3474
|
}
|
|
3398
3475
|
|
|
3476
|
+
:root {
|
|
3477
|
+
--tag-crimson: #F24E1E;
|
|
3478
|
+
--tag-burnt-orange: #FF8A00;
|
|
3479
|
+
--tag-amber: #FFC700;
|
|
3480
|
+
--tag-mint: #14AE5C;
|
|
3481
|
+
--tag-deep-emerald: #00623F;
|
|
3482
|
+
--tag-electric-cyan: #00D1FF;
|
|
3483
|
+
--tag-cobalt-blue: #0D99FF;
|
|
3484
|
+
--tag-deep-indigo: #5551FF;
|
|
3485
|
+
--tag-amethyst: #9747FF;
|
|
3486
|
+
--tag-rose: #FF5CBE;
|
|
3487
|
+
}
|
|
3488
|
+
|
|
3489
|
+
.tag {
|
|
3490
|
+
display: inline-flex;
|
|
3491
|
+
align-items: center;
|
|
3492
|
+
gap: 6px;
|
|
3493
|
+
padding: 4px 9px;
|
|
3494
|
+
min-height: calc(1.4em + 8px);
|
|
3495
|
+
border-radius: 5px;
|
|
3496
|
+
font-family: var(--ck-mono);
|
|
3497
|
+
font-size: 12.5px;
|
|
3498
|
+
font-weight: 500;
|
|
3499
|
+
letter-spacing: 0.01em;
|
|
3500
|
+
text-transform: lowercase;
|
|
3501
|
+
color: white;
|
|
3502
|
+
line-height: 1.4;
|
|
3503
|
+
white-space: nowrap;
|
|
3504
|
+
transition: filter 120ms ease;
|
|
3505
|
+
text-decoration: none;
|
|
3506
|
+
user-select: none;
|
|
3507
|
+
}
|
|
3508
|
+
|
|
3509
|
+
.tag::before {
|
|
3510
|
+
content: "";
|
|
3511
|
+
width: 6px;
|
|
3512
|
+
height: 6px;
|
|
3513
|
+
border-radius: 50%;
|
|
3514
|
+
background: rgba(255, 255, 255, 0.85);
|
|
3515
|
+
flex-shrink: 0;
|
|
3516
|
+
}
|
|
3517
|
+
|
|
3518
|
+
.tag > span:empty { display: none; }
|
|
3519
|
+
|
|
3520
|
+
a.tag, label.tag { cursor: pointer; }
|
|
3521
|
+
a.tag:hover, label.tag:hover { filter: brightness(1.12); }
|
|
3522
|
+
|
|
3523
|
+
|
|
3524
|
+
.tag-crimson { background-color: var(--tag-crimson); --current-tag-color: var(--tag-crimson); }
|
|
3525
|
+
.tag-burnt-orange { background-color: var(--tag-burnt-orange); --current-tag-color: var(--tag-burnt-orange); color: #2a1300; }
|
|
3526
|
+
.tag-burnt-orange::before { background: rgba(0, 0, 0, 0.55); }
|
|
3527
|
+
.tag-amber { background-color: var(--tag-amber); --current-tag-color: var(--tag-amber); color: #1a0f00; }
|
|
3528
|
+
.tag-amber::before { background: rgba(0, 0, 0, 0.55); }
|
|
3529
|
+
.tag-mint { background-color: var(--tag-mint); --current-tag-color: var(--tag-mint); }
|
|
3530
|
+
.tag-deep-emerald { background-color: var(--tag-deep-emerald); --current-tag-color: var(--tag-deep-emerald); }
|
|
3531
|
+
.tag-electric-cyan { background-color: var(--tag-electric-cyan); --current-tag-color: var(--tag-electric-cyan); color: #001620; }
|
|
3532
|
+
.tag-electric-cyan::before { background: rgba(0, 0, 0, 0.55); }
|
|
3533
|
+
.tag-cobalt-blue { background-color: var(--tag-cobalt-blue); --current-tag-color: var(--tag-cobalt-blue); }
|
|
3534
|
+
.tag-deep-indigo { background-color: var(--tag-deep-indigo); --current-tag-color: var(--tag-deep-indigo); }
|
|
3535
|
+
.tag-amethyst { background-color: var(--tag-amethyst); --current-tag-color: var(--tag-amethyst); }
|
|
3536
|
+
.tag-rose { background-color: var(--tag-rose); --current-tag-color: var(--tag-rose); color: #2a0017; }
|
|
3537
|
+
.tag-rose::before { background: rgba(0, 0, 0, 0.6); }
|
|
3538
|
+
|
|
3539
|
+
.tag-outline {
|
|
3540
|
+
background-color: transparent !important;
|
|
3541
|
+
border: 1px solid currentColor;
|
|
3542
|
+
box-shadow: none;
|
|
3543
|
+
}
|
|
3544
|
+
.tag-outline::before { background: currentColor; }
|
|
3545
|
+
.tag-outline.tag-crimson { color: var(--tag-crimson); }
|
|
3546
|
+
.tag-outline.tag-burnt-orange { color: var(--tag-burnt-orange); }
|
|
3547
|
+
.tag-outline.tag-amber { color: var(--tag-amber); }
|
|
3548
|
+
.tag-outline.tag-mint { color: var(--tag-mint); }
|
|
3549
|
+
.tag-outline.tag-deep-emerald { color: var(--tag-deep-emerald); }
|
|
3550
|
+
.tag-outline.tag-electric-cyan { color: var(--tag-electric-cyan); }
|
|
3551
|
+
.tag-outline.tag-cobalt-blue { color: var(--tag-cobalt-blue); }
|
|
3552
|
+
.tag-outline.tag-deep-indigo { color: var(--tag-deep-indigo); }
|
|
3553
|
+
.tag-outline.tag-amethyst { color: var(--tag-amethyst); }
|
|
3554
|
+
.tag-outline.tag-rose { color: var(--tag-rose); }
|
|
3555
|
+
|
|
3556
|
+
/* Inline mark — quiet "color dot + name" used on row metadata */
|
|
3557
|
+
.tag-mark {
|
|
3558
|
+
display: inline-flex;
|
|
3559
|
+
align-items: center;
|
|
3560
|
+
gap: 5px;
|
|
3561
|
+
padding: 2px 8px;
|
|
3562
|
+
border: 1px solid transparent;
|
|
3563
|
+
border-radius: 4px;
|
|
3564
|
+
font-family: var(--ck-mono);
|
|
3565
|
+
font-size: 11px;
|
|
3566
|
+
letter-spacing: 0.02em;
|
|
3567
|
+
text-transform: lowercase;
|
|
3568
|
+
white-space: nowrap;
|
|
3569
|
+
background: color-mix(in srgb, var(--mark-color) 24%, transparent);
|
|
3570
|
+
color: color-mix(in srgb, var(--mark-color) 88%, var(--ck-text));
|
|
3571
|
+
}
|
|
3572
|
+
|
|
3573
|
+
.tag-mark::before {
|
|
3574
|
+
content: "";
|
|
3575
|
+
display: inline-block;
|
|
3576
|
+
width: 0.95em;
|
|
3577
|
+
height: 0.95em;
|
|
3578
|
+
flex-shrink: 0;
|
|
3579
|
+
background-color: currentColor;
|
|
3580
|
+
-webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path fill-rule='evenodd' clip-rule='evenodd' d='M3 4.5C3 3.67 3.67 3 4.5 3h5.379c.398 0 .779.158 1.06.44L18.06 10.56c.585.586.585 1.535 0 2.121l-5.379 5.379a1.5 1.5 0 0 1-2.121 0L3.44 10.94A1.5 1.5 0 0 1 3 9.879V4.5Zm3.5 1.75a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5Z' fill='black'/></svg>") no-repeat center / contain;
|
|
3581
|
+
mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path fill-rule='evenodd' clip-rule='evenodd' d='M3 4.5C3 3.67 3.67 3 4.5 3h5.379c.398 0 .779.158 1.06.44L18.06 10.56c.585.586.585 1.535 0 2.121l-5.379 5.379a1.5 1.5 0 0 1-2.121 0L3.44 10.94A1.5 1.5 0 0 1 3 9.879V4.5Zm3.5 1.75a1.25 1.25 0 1 1 0 2.5 1.25 1.25 0 0 1 0-2.5Z' fill='black'/></svg>") no-repeat center / contain;
|
|
3582
|
+
}
|
|
3583
|
+
.tag-mark + .tag-mark { margin-left: 0.4rem; }
|
|
3584
|
+
.tag-marks-row {
|
|
3585
|
+
display: flex;
|
|
3586
|
+
flex-wrap: wrap;
|
|
3587
|
+
align-items: center;
|
|
3588
|
+
margin-top: 0.35rem;
|
|
3589
|
+
}
|
|
3590
|
+
|
|
3591
|
+
/* Picker — flat row of chips + inline input, no enclosing field */
|
|
3592
|
+
.ck-tag-picker {
|
|
3593
|
+
display: flex;
|
|
3594
|
+
flex-wrap: wrap;
|
|
3595
|
+
align-items: center;
|
|
3596
|
+
gap: 7px;
|
|
3597
|
+
}
|
|
3598
|
+
.ck-tag-picker__input {
|
|
3599
|
+
flex: 1;
|
|
3600
|
+
min-width: 160px;
|
|
3601
|
+
background: transparent;
|
|
3602
|
+
border: 0;
|
|
3603
|
+
padding: 2px 0;
|
|
3604
|
+
color: var(--ck-text);
|
|
3605
|
+
font-family: var(--ck-mono);
|
|
3606
|
+
font-size: 12.5px;
|
|
3607
|
+
letter-spacing: 0.01em;
|
|
3608
|
+
outline: none;
|
|
3609
|
+
}
|
|
3610
|
+
.ck-tag-picker__input::placeholder { color: var(--ck-dim); }
|
|
3611
|
+
|
|
3612
|
+
/* Picker chips: unchecked = neutral pill with a small tag-colored dot.
|
|
3613
|
+
Avoids looking "applied" simply because the tag color is on screen. */
|
|
3614
|
+
.ck-tag-picker label.tag-mark,
|
|
3615
|
+
.ck-tag-filter .tag-mark,
|
|
3616
|
+
.ck-metric-tag-filter .tag-mark {
|
|
3617
|
+
cursor: pointer;
|
|
3618
|
+
user-select: none;
|
|
3619
|
+
padding: 4px 10px;
|
|
3620
|
+
font-size: 0.8rem;
|
|
3621
|
+
transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
|
|
3622
|
+
}
|
|
3623
|
+
|
|
3624
|
+
/* Selected state — picker, filter bars, metric-tag-filter share one look */
|
|
3625
|
+
.ck-tag-picker label.tag-mark:has(input:checked),
|
|
3626
|
+
.ck-tag-filter .tag-mark:not(.tag-mark--off),
|
|
3627
|
+
.ck-metric-tag-filter .tag-mark:not(.tag-mark--off) {
|
|
3628
|
+
background: color-mix(in srgb, var(--mark-color) 38%, transparent);
|
|
3629
|
+
color: color-mix(in srgb, var(--mark-color) 95%, var(--ck-text));
|
|
3630
|
+
border-color: color-mix(in srgb, var(--mark-color) 50%, transparent);
|
|
3631
|
+
}
|
|
3632
|
+
|
|
3633
|
+
/* Unselected state — same shape, neutral outline + muted text */
|
|
3634
|
+
.ck-tag-picker label.tag-mark:has(input:not(:checked)),
|
|
3635
|
+
.ck-tag-filter .tag-mark.tag-mark--off,
|
|
3636
|
+
.ck-metric-tag-filter .tag-mark.tag-mark--off {
|
|
3637
|
+
background: transparent;
|
|
3638
|
+
border-color: var(--ck-line);
|
|
3639
|
+
color: var(--ck-muted);
|
|
3640
|
+
}
|
|
3641
|
+
.ck-tag-picker label.tag-mark:has(input:not(:checked)):hover,
|
|
3642
|
+
.ck-tag-filter .tag-mark.tag-mark--off:hover,
|
|
3643
|
+
.ck-metric-tag-filter .tag-mark.tag-mark--off:hover {
|
|
3644
|
+
border-color: var(--ck-line-strong);
|
|
3645
|
+
color: color-mix(in srgb, var(--mark-color) 80%, var(--ck-text));
|
|
3646
|
+
}
|
|
3647
|
+
button.tag-mark, a.tag-mark {
|
|
3648
|
+
border: 0;
|
|
3649
|
+
background: color-mix(in srgb, var(--mark-color) 24%, transparent);
|
|
3650
|
+
cursor: pointer;
|
|
3651
|
+
text-decoration: none;
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3654
|
+
/* Top-nav settings menu (ported from completion-kit-cloud) */
|
|
3655
|
+
.ck-settings-menu {
|
|
3656
|
+
position: relative;
|
|
3657
|
+
}
|
|
3658
|
+
.ck-settings-menu__trigger {
|
|
3659
|
+
cursor: pointer;
|
|
3660
|
+
list-style: none;
|
|
3661
|
+
user-select: none;
|
|
3662
|
+
}
|
|
3663
|
+
.ck-settings-menu__trigger::-webkit-details-marker {
|
|
3664
|
+
display: none;
|
|
3665
|
+
}
|
|
3666
|
+
.ck-settings-menu__panel {
|
|
3667
|
+
position: absolute;
|
|
3668
|
+
right: 0;
|
|
3669
|
+
top: calc(100% + 0.5rem);
|
|
3670
|
+
padding: 0.5rem;
|
|
3671
|
+
background: var(--ck-surface);
|
|
3672
|
+
border: 1px solid var(--ck-line);
|
|
3673
|
+
border-radius: var(--ck-radius);
|
|
3674
|
+
z-index: 50;
|
|
3675
|
+
display: flex;
|
|
3676
|
+
flex-direction: column;
|
|
3677
|
+
gap: 0.1rem;
|
|
3678
|
+
white-space: nowrap;
|
|
3679
|
+
}
|
|
3680
|
+
.ck-settings-menu__item {
|
|
3681
|
+
display: block;
|
|
3682
|
+
padding: 0.5rem 0.65rem;
|
|
3683
|
+
border-radius: calc(var(--ck-radius) - 2px);
|
|
3684
|
+
font-family: var(--ck-mono);
|
|
3685
|
+
font-size: 0.78rem;
|
|
3686
|
+
letter-spacing: 0.04em;
|
|
3687
|
+
text-transform: uppercase;
|
|
3688
|
+
text-decoration: none;
|
|
3689
|
+
color: var(--ck-text);
|
|
3690
|
+
transition: background 0.15s, color 0.15s;
|
|
3691
|
+
}
|
|
3692
|
+
.ck-settings-menu__item:hover {
|
|
3693
|
+
background: var(--ck-surface-hover);
|
|
3694
|
+
}
|
|
3695
|
+
|
|
3696
|
+
/* Settings page kicker — small label above the page title on settings pages */
|
|
3697
|
+
.ck-settings-kicker {
|
|
3698
|
+
display: flex;
|
|
3699
|
+
align-items: center;
|
|
3700
|
+
gap: 0.45rem;
|
|
3701
|
+
flex-wrap: wrap;
|
|
3702
|
+
font-family: var(--ck-mono);
|
|
3703
|
+
font-size: 11px;
|
|
3704
|
+
letter-spacing: 0.2em;
|
|
3705
|
+
text-transform: uppercase;
|
|
3706
|
+
color: var(--ck-dim);
|
|
3707
|
+
margin: 0 0 0.85rem;
|
|
3708
|
+
}
|
|
3709
|
+
.ck-settings-kicker__sep {
|
|
3710
|
+
opacity: 0.55;
|
|
3711
|
+
}
|
|
3712
|
+
.ck-settings-kicker__link {
|
|
3713
|
+
color: var(--ck-muted);
|
|
3714
|
+
text-decoration: none;
|
|
3715
|
+
transition: color 120ms ease;
|
|
3716
|
+
}
|
|
3717
|
+
.ck-settings-kicker__link:hover { color: var(--ck-text); }
|
|
3718
|
+
|
|
3719
|
+
.tag-marks-row--header {
|
|
3720
|
+
margin-top: -0.5rem;
|
|
3721
|
+
margin-bottom: 1.25rem;
|
|
3722
|
+
}
|
|
3723
|
+
|
|
3724
|
+
|
|
3725
|
+
.ck-input--error {
|
|
3726
|
+
border-color: var(--ck-danger);
|
|
3727
|
+
background: rgba(248, 113, 113, 0.05);
|
|
3728
|
+
}
|
|
3729
|
+
.ck-input--error:focus {
|
|
3730
|
+
box-shadow: 0 0 0 3px rgba(248, 113, 113, 0.15);
|
|
3731
|
+
border-color: var(--ck-danger);
|
|
3732
|
+
}
|
|
3733
|
+
|
|
3734
|
+
.ck-field-error {
|
|
3735
|
+
margin: 0.35rem 0 0;
|
|
3736
|
+
color: var(--ck-danger);
|
|
3737
|
+
font-family: var(--ck-sans);
|
|
3738
|
+
font-size: 0.95rem;
|
|
3739
|
+
}
|
|
3740
|
+
|
|
3741
|
+
/* Filter bar — its own visual moment */
|
|
3742
|
+
.ck-tag-filter {
|
|
3743
|
+
display: flex;
|
|
3744
|
+
flex-wrap: wrap;
|
|
3745
|
+
align-items: center;
|
|
3746
|
+
gap: 8px;
|
|
3747
|
+
margin: 1.1rem 0 1.6rem;
|
|
3748
|
+
padding: 0.65rem 0.85rem;
|
|
3749
|
+
background: var(--ck-surface-soft);
|
|
3750
|
+
border: 1px solid var(--ck-line);
|
|
3751
|
+
border-radius: 6px;
|
|
3752
|
+
}
|
|
3753
|
+
.ck-tag-filter__label {
|
|
3754
|
+
font-family: var(--ck-mono);
|
|
3755
|
+
font-size: 12px;
|
|
3756
|
+
letter-spacing: 0.12em;
|
|
3757
|
+
text-transform: uppercase;
|
|
3758
|
+
color: var(--ck-dim);
|
|
3759
|
+
margin-right: 0.4rem;
|
|
3760
|
+
}
|
|
3761
|
+
.ck-tag-filter__clear {
|
|
3762
|
+
margin-left: auto;
|
|
3763
|
+
font-family: var(--ck-mono);
|
|
3764
|
+
font-size: 11.5px;
|
|
3765
|
+
letter-spacing: 0.08em;
|
|
3766
|
+
text-transform: uppercase;
|
|
3767
|
+
color: var(--ck-muted);
|
|
3768
|
+
text-decoration: none;
|
|
3769
|
+
transition: color 120ms ease;
|
|
3770
|
+
}
|
|
3771
|
+
.ck-tag-filter__clear:hover { color: var(--ck-accent); }
|
|
3772
|
+
|
|
3773
|
+
|
|
@@ -5,7 +5,7 @@ module CompletionKit
|
|
|
5
5
|
before_action :set_dataset, only: [:show, :update, :destroy]
|
|
6
6
|
|
|
7
7
|
def index
|
|
8
|
-
render json: Dataset.order(created_at: :desc)
|
|
8
|
+
render json: Dataset.includes(:tags).order(created_at: :desc)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def show
|
|
@@ -43,7 +43,7 @@ module CompletionKit
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def dataset_params
|
|
46
|
-
params.permit(:name, :csv_data)
|
|
46
|
+
params.permit(:name, :csv_data, tag_names: [])
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
end
|
|
@@ -5,7 +5,7 @@ module CompletionKit
|
|
|
5
5
|
before_action :set_metric_group, only: [:show, :update, :destroy]
|
|
6
6
|
|
|
7
7
|
def index
|
|
8
|
-
render json: MetricGroup.order(created_at: :desc)
|
|
8
|
+
render json: MetricGroup.includes(:tags).order(created_at: :desc)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def show
|
|
@@ -45,7 +45,7 @@ module CompletionKit
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def metric_group_params
|
|
48
|
-
params.permit(:name, :description, metric_ids: [])
|
|
48
|
+
params.permit(:name, :description, metric_ids: [], tag_names: [])
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
end
|
|
@@ -5,7 +5,7 @@ module CompletionKit
|
|
|
5
5
|
before_action :set_metric, only: [:show, :update, :destroy]
|
|
6
6
|
|
|
7
7
|
def index
|
|
8
|
-
render json: Metric.order(created_at: :desc)
|
|
8
|
+
render json: Metric.includes(:tags).order(created_at: :desc)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def show
|
|
@@ -43,7 +43,8 @@ module CompletionKit
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def metric_params
|
|
46
|
-
params.permit(:name, :instruction,
|
|
46
|
+
params.permit(:name, :instruction,
|
|
47
|
+
rubric_bands: [:stars, :description], tag_names: [])
|
|
47
48
|
end
|
|
48
49
|
end
|
|
49
50
|
end
|
|
@@ -5,7 +5,7 @@ module CompletionKit
|
|
|
5
5
|
before_action :set_prompt, only: [:show, :update, :destroy, :publish]
|
|
6
6
|
|
|
7
7
|
def index
|
|
8
|
-
render json: Prompt.order(created_at: :desc)
|
|
8
|
+
render json: Prompt.includes(:tags).order(created_at: :desc)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def show
|
|
@@ -23,9 +23,10 @@ module CompletionKit
|
|
|
23
23
|
|
|
24
24
|
def update
|
|
25
25
|
if @prompt.runs.exists?
|
|
26
|
-
new_prompt = @prompt.clone_as_new_version(prompt_params.to_h)
|
|
26
|
+
new_prompt = @prompt.clone_as_new_version(prompt_params.except(:tag_names).to_h)
|
|
27
27
|
new_prompt.publish!
|
|
28
|
-
|
|
28
|
+
new_prompt.update!(tag_names: prompt_params[:tag_names]) if prompt_params.key?(:tag_names)
|
|
29
|
+
render json: new_prompt.reload
|
|
29
30
|
elsif @prompt.update(prompt_params)
|
|
30
31
|
render json: @prompt
|
|
31
32
|
else
|
|
@@ -56,7 +57,7 @@ module CompletionKit
|
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
def prompt_params
|
|
59
|
-
params.permit(:name, :description, :template, :llm_model)
|
|
60
|
+
params.permit(:name, :description, :template, :llm_model, tag_names: [])
|
|
60
61
|
end
|
|
61
62
|
end
|
|
62
63
|
end
|
|
@@ -5,7 +5,7 @@ module CompletionKit
|
|
|
5
5
|
before_action :set_run, only: [:show, :update, :destroy, :generate, :retry_failures]
|
|
6
6
|
|
|
7
7
|
def index
|
|
8
|
-
render json: Run.order(created_at: :desc)
|
|
8
|
+
render json: Run.includes(:tags).order(created_at: :desc)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def show
|
|
@@ -76,7 +76,8 @@ module CompletionKit
|
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
def run_params
|
|
79
|
-
params.permit(:name, :prompt_id, :dataset_id, :judge_model, :temperature,
|
|
79
|
+
params.permit(:name, :prompt_id, :dataset_id, :judge_model, :temperature,
|
|
80
|
+
metric_ids: [], tag_names: [])
|
|
80
81
|
end
|
|
81
82
|
end
|
|
82
83
|
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module CompletionKit
|
|
2
|
+
module Api
|
|
3
|
+
module V1
|
|
4
|
+
class TagsController < BaseController
|
|
5
|
+
before_action :set_tag, only: [:show, :update, :destroy]
|
|
6
|
+
|
|
7
|
+
def index
|
|
8
|
+
render json: Tag.order(:name)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def show
|
|
12
|
+
render json: @tag
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def create
|
|
16
|
+
tag = Tag.new(tag_params)
|
|
17
|
+
if tag.save
|
|
18
|
+
render json: tag, status: :created
|
|
19
|
+
else
|
|
20
|
+
render json: {errors: tag.errors}, status: :unprocessable_entity
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def update
|
|
25
|
+
if @tag.update(tag_params)
|
|
26
|
+
render json: @tag
|
|
27
|
+
else
|
|
28
|
+
render json: {errors: @tag.errors}, status: :unprocessable_entity
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def destroy
|
|
33
|
+
@tag.destroy!
|
|
34
|
+
head :no_content
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def set_tag
|
|
40
|
+
@tag = Tag.find(params[:id])
|
|
41
|
+
rescue ActiveRecord::RecordNotFound
|
|
42
|
+
not_found
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def tag_params
|
|
46
|
+
params.permit(:name)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
module CompletionKit
|
|
2
2
|
class DatasetsController < ApplicationController
|
|
3
|
+
include CompletionKit::TagFiltering
|
|
3
4
|
before_action :set_dataset, only: [:show, :edit, :update, :destroy]
|
|
4
5
|
|
|
5
6
|
def index
|
|
6
|
-
@datasets = Dataset.includes(:runs).order(created_at: :desc)
|
|
7
|
+
@datasets = apply_tag_filter(Dataset.includes(:runs, :tags).order(created_at: :desc))
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def show
|
|
@@ -47,7 +48,7 @@ module CompletionKit
|
|
|
47
48
|
end
|
|
48
49
|
|
|
49
50
|
def dataset_params
|
|
50
|
-
params.require(:dataset).permit(:name, :csv_data)
|
|
51
|
+
params.require(:dataset).permit(:name, :csv_data, tag_names: [])
|
|
51
52
|
end
|
|
52
53
|
end
|
|
53
54
|
end
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
module CompletionKit
|
|
2
2
|
class MetricGroupsController < ApplicationController
|
|
3
|
+
include CompletionKit::TagFiltering
|
|
3
4
|
before_action :set_metric_group, only: [:show, :edit, :update, :destroy]
|
|
4
5
|
|
|
5
6
|
def index
|
|
6
|
-
@metric_groups = MetricGroup.includes(:metrics).order(:name)
|
|
7
|
+
@metric_groups = apply_tag_filter(MetricGroup.includes(:metrics, :tags).order(:name))
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def show
|
|
@@ -11,16 +12,16 @@ module CompletionKit
|
|
|
11
12
|
|
|
12
13
|
def new
|
|
13
14
|
@metric_group = MetricGroup.new
|
|
14
|
-
@metrics = Metric.order(:name)
|
|
15
|
+
@metrics = Metric.includes(:tags).order(:name)
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def edit
|
|
18
|
-
@metrics = Metric.order(:name)
|
|
19
|
+
@metrics = Metric.includes(:tags).order(:name)
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def create
|
|
22
23
|
@metric_group = MetricGroup.new(metric_group_params.except(:metric_ids))
|
|
23
|
-
@metrics = Metric.order(:name)
|
|
24
|
+
@metrics = Metric.includes(:tags).order(:name)
|
|
24
25
|
|
|
25
26
|
if @metric_group.save
|
|
26
27
|
@metric_group.replace_metrics!(metric_group_params[:metric_ids])
|
|
@@ -31,7 +32,7 @@ module CompletionKit
|
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def update
|
|
34
|
-
@metrics = Metric.order(:name)
|
|
35
|
+
@metrics = Metric.includes(:tags).order(:name)
|
|
35
36
|
|
|
36
37
|
if @metric_group.update(metric_group_params.except(:metric_ids))
|
|
37
38
|
@metric_group.replace_metrics!(metric_group_params[:metric_ids])
|
|
@@ -53,7 +54,7 @@ module CompletionKit
|
|
|
53
54
|
end
|
|
54
55
|
|
|
55
56
|
def metric_group_params
|
|
56
|
-
params.require(:metric_group).permit(:name, :description, metric_ids: [])
|
|
57
|
+
params.require(:metric_group).permit(:name, :description, metric_ids: [], tag_names: [])
|
|
57
58
|
end
|
|
58
59
|
end
|
|
59
60
|
end
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
module CompletionKit
|
|
2
2
|
class MetricsController < ApplicationController
|
|
3
|
+
include CompletionKit::TagFiltering
|
|
3
4
|
before_action :set_metric, only: [:show, :edit, :update, :destroy]
|
|
4
5
|
|
|
5
6
|
def index
|
|
6
|
-
@metrics = Metric.includes(:metric_groups).order(:name)
|
|
7
|
+
@metrics = apply_tag_filter(Metric.includes(:metric_groups, :tags).order(:name))
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def show
|
|
@@ -46,7 +47,8 @@ module CompletionKit
|
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
def metric_params
|
|
49
|
-
params.require(:metric).permit(:name, :instruction,
|
|
50
|
+
params.require(:metric).permit(:name, :instruction,
|
|
51
|
+
rubric_bands: [:stars, :description], tag_names: [])
|
|
50
52
|
end
|
|
51
53
|
end
|
|
52
54
|
end
|