completion-kit 0.5.2 → 0.5.4
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 +8 -7
- data/app/assets/stylesheets/completion_kit/application.css +318 -0
- data/app/controllers/completion_kit/onboarding_controller.rb +18 -0
- data/app/services/completion_kit/onboarding/checklist.rb +59 -0
- data/app/views/completion_kit/onboarding/show.html.erb +80 -0
- data/app/views/completion_kit/prompts/show.html.erb +4 -1
- data/app/views/completion_kit/runs/show.html.erb +4 -1
- data/app/views/layouts/completion_kit/application.html.erb +2 -1
- data/config/routes.rb +4 -1
- data/lib/completion_kit/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb708ad1732ab18fac5f415ad90f53374832bd8e629ab2f1530e860a2eca6c03
|
|
4
|
+
data.tar.gz: 3e159d8c80601f791a8b5e9fcabea66c1755dfb1635d268efa104a0a17bd9eb1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2d6bb436f79222b66d6f12bb0cb82642eb9e50c48704bbea76fb6b47c3c3b65f665363a905b4d8e57062445ad31bee44ba65c901de2a07d716d231fdef59e7df
|
|
7
|
+
data.tar.gz: ba8c62309efc2f19d343c6744b47e1db25c2a64e3597f19f957bdfd971dac6ee5118fd7f2017c573799f04a5423ac030627ff91ec9785d77822bc22a9ba7d27b
|
data/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
+
<a href="https://badge.fury.io/rb/completion-kit"><img src="https://badge.fury.io/rb/completion-kit.svg" alt="Gem Version" /></a>
|
|
6
7
|
<a href="https://github.com/homemade-software-inc/completion-kit/actions/workflows/ci.yml"><img src="https://github.com/homemade-software-inc/completion-kit/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
|
|
7
8
|
<img src="https://img.shields.io/badge/coverage-100%25-brightgreen" alt="coverage" />
|
|
8
9
|
</p>
|
|
@@ -15,19 +16,19 @@ It's the difference between "this prompt seems to work" and "this prompt scores
|
|
|
15
16
|
|
|
16
17
|
**[completionkit.com](https://completionkit.com)** | **[RubyGems](https://rubygems.org/gems/completion-kit)**
|
|
17
18
|
|
|
18
|
-
> **CompletionKit Cloud**
|
|
19
|
-
|
|
20
|
-

|
|
21
|
-
|
|
22
|
-

|
|
19
|
+
> **CompletionKit Cloud** — hosted, managed CompletionKit with zero setup. Same engine, run for you. See plans at [completionkit.com/pricing](https://completionkit.com/pricing).
|
|
23
20
|
|
|
24
21
|

|
|
25
22
|
|
|
26
23
|
## Quick Start
|
|
27
24
|
|
|
28
|
-
###
|
|
25
|
+
### Use CompletionKit Cloud
|
|
26
|
+
|
|
27
|
+
The fastest way to start — no install, no servers to run. Sign up at [completionkit.com](https://completionkit.com) and you get the same engine you'd self-host, hosted for you. Best fit if you want to skip the Rails ops.
|
|
28
|
+
|
|
29
|
+
### Or run the standalone app
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
Self-host the same engine. No existing Rails app needed.
|
|
31
32
|
|
|
32
33
|
```bash
|
|
33
34
|
git clone https://github.com/homemade-software-inc/completion-kit.git
|
|
@@ -482,6 +482,7 @@ tr:hover .ck-chip--publish {
|
|
|
482
482
|
display: inline-flex;
|
|
483
483
|
align-items: center;
|
|
484
484
|
justify-content: center;
|
|
485
|
+
gap: 0.4rem;
|
|
485
486
|
min-height: 2rem;
|
|
486
487
|
padding: 0.4rem 0.75rem;
|
|
487
488
|
border: 1px solid transparent;
|
|
@@ -493,10 +494,18 @@ tr:hover .ck-chip--publish {
|
|
|
493
494
|
letter-spacing: 0.04em;
|
|
494
495
|
text-transform: uppercase;
|
|
495
496
|
line-height: 1;
|
|
497
|
+
white-space: nowrap;
|
|
496
498
|
cursor: pointer;
|
|
497
499
|
transition: all 0.15s ease;
|
|
498
500
|
}
|
|
499
501
|
|
|
502
|
+
.ck-magic-icon {
|
|
503
|
+
width: 1.1em;
|
|
504
|
+
height: 1.1em;
|
|
505
|
+
flex-shrink: 0;
|
|
506
|
+
color: var(--ck-warning);
|
|
507
|
+
}
|
|
508
|
+
|
|
500
509
|
.ck-button:hover {
|
|
501
510
|
transform: translateY(-1px);
|
|
502
511
|
}
|
|
@@ -3778,3 +3787,312 @@ a.tag-mark {
|
|
|
3778
3787
|
.ck-tag-filter__clear:hover { color: var(--ck-accent); }
|
|
3779
3788
|
|
|
3780
3789
|
|
|
3790
|
+
/* --- Onboarding / launch checklist --- */
|
|
3791
|
+
@keyframes ck-launch-rise {
|
|
3792
|
+
from { opacity: 0; transform: translateY(14px); }
|
|
3793
|
+
to { opacity: 1; transform: translateY(0); }
|
|
3794
|
+
}
|
|
3795
|
+
|
|
3796
|
+
.ck-launch {
|
|
3797
|
+
position: relative;
|
|
3798
|
+
max-width: 720px;
|
|
3799
|
+
margin: 1rem auto 4rem;
|
|
3800
|
+
padding-top: 1rem;
|
|
3801
|
+
}
|
|
3802
|
+
|
|
3803
|
+
.ck-launch__field {
|
|
3804
|
+
position: absolute;
|
|
3805
|
+
inset: -2rem -3rem auto -3rem;
|
|
3806
|
+
height: 300px;
|
|
3807
|
+
pointer-events: none;
|
|
3808
|
+
z-index: 0;
|
|
3809
|
+
background:
|
|
3810
|
+
radial-gradient(ellipse 70% 80% at 50% 0%, var(--ck-accent-soft) 0%, transparent 65%),
|
|
3811
|
+
repeating-linear-gradient(90deg, transparent 0 23px, rgba(148, 163, 184, 0.035) 23px 24px),
|
|
3812
|
+
repeating-linear-gradient(0deg, transparent 0 23px, rgba(148, 163, 184, 0.035) 23px 24px);
|
|
3813
|
+
-webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
|
|
3814
|
+
mask-image: linear-gradient(to bottom, #000 0%, transparent 100%);
|
|
3815
|
+
}
|
|
3816
|
+
|
|
3817
|
+
.ck-launch__header {
|
|
3818
|
+
position: relative;
|
|
3819
|
+
z-index: 1;
|
|
3820
|
+
text-align: center;
|
|
3821
|
+
margin-bottom: 2.25rem;
|
|
3822
|
+
animation: ck-launch-rise 0.5s ease both;
|
|
3823
|
+
}
|
|
3824
|
+
|
|
3825
|
+
.ck-launch__overline {
|
|
3826
|
+
margin: 0 0 0.6rem;
|
|
3827
|
+
font-family: var(--ck-mono);
|
|
3828
|
+
font-size: 0.72rem;
|
|
3829
|
+
letter-spacing: 0.32em;
|
|
3830
|
+
text-transform: uppercase;
|
|
3831
|
+
color: var(--ck-accent);
|
|
3832
|
+
}
|
|
3833
|
+
|
|
3834
|
+
.ck-launch__org {
|
|
3835
|
+
margin: 0;
|
|
3836
|
+
font-family: var(--ck-mono);
|
|
3837
|
+
font-size: clamp(1.8rem, 4vw, 2.6rem);
|
|
3838
|
+
font-weight: 600;
|
|
3839
|
+
letter-spacing: -0.02em;
|
|
3840
|
+
color: var(--ck-text);
|
|
3841
|
+
}
|
|
3842
|
+
|
|
3843
|
+
.ck-launch__handle {
|
|
3844
|
+
margin: 0.5rem 0 0;
|
|
3845
|
+
font-family: var(--ck-mono);
|
|
3846
|
+
font-size: 0.8rem;
|
|
3847
|
+
letter-spacing: 0.04em;
|
|
3848
|
+
color: var(--ck-muted);
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3851
|
+
.ck-launch__panel {
|
|
3852
|
+
position: relative;
|
|
3853
|
+
z-index: 1;
|
|
3854
|
+
background: var(--ck-surface);
|
|
3855
|
+
border: 1px solid var(--ck-line);
|
|
3856
|
+
border-radius: var(--ck-radius-lg);
|
|
3857
|
+
padding: 1.75rem 2rem 2rem;
|
|
3858
|
+
box-shadow: 0 24px 64px -28px rgba(0, 0, 0, 0.5);
|
|
3859
|
+
animation: ck-launch-rise 0.5s ease both;
|
|
3860
|
+
animation-delay: 0.08s;
|
|
3861
|
+
}
|
|
3862
|
+
|
|
3863
|
+
.ck-launch__progress {
|
|
3864
|
+
padding-bottom: 1.5rem;
|
|
3865
|
+
margin-bottom: 0.5rem;
|
|
3866
|
+
border-bottom: 1px solid var(--ck-line);
|
|
3867
|
+
}
|
|
3868
|
+
.ck-launch__progress-head {
|
|
3869
|
+
display: flex;
|
|
3870
|
+
align-items: baseline;
|
|
3871
|
+
justify-content: space-between;
|
|
3872
|
+
gap: 1rem;
|
|
3873
|
+
margin-bottom: 0.85rem;
|
|
3874
|
+
}
|
|
3875
|
+
.ck-launch__progress-title {
|
|
3876
|
+
margin: 0;
|
|
3877
|
+
font-family: var(--ck-mono);
|
|
3878
|
+
font-size: 1.05rem;
|
|
3879
|
+
font-weight: 600;
|
|
3880
|
+
letter-spacing: -0.02em;
|
|
3881
|
+
color: var(--ck-text);
|
|
3882
|
+
}
|
|
3883
|
+
.ck-launch__progress-count {
|
|
3884
|
+
margin: 0;
|
|
3885
|
+
font-family: var(--ck-mono);
|
|
3886
|
+
font-size: 0.78rem;
|
|
3887
|
+
letter-spacing: 0.02em;
|
|
3888
|
+
color: var(--ck-muted);
|
|
3889
|
+
white-space: nowrap;
|
|
3890
|
+
}
|
|
3891
|
+
.ck-launch__progress-bar {
|
|
3892
|
+
height: 5px;
|
|
3893
|
+
border-radius: 999px;
|
|
3894
|
+
background: var(--ck-line);
|
|
3895
|
+
overflow: hidden;
|
|
3896
|
+
}
|
|
3897
|
+
.ck-launch__progress-fill {
|
|
3898
|
+
display: block;
|
|
3899
|
+
height: 100%;
|
|
3900
|
+
border-radius: 999px;
|
|
3901
|
+
background: var(--ck-accent);
|
|
3902
|
+
box-shadow: 0 0 10px var(--ck-accent-soft);
|
|
3903
|
+
transition: width 0.4s ease;
|
|
3904
|
+
}
|
|
3905
|
+
|
|
3906
|
+
.ck-launch__steps {
|
|
3907
|
+
list-style: none;
|
|
3908
|
+
margin: 0;
|
|
3909
|
+
padding: 0;
|
|
3910
|
+
display: flex;
|
|
3911
|
+
flex-direction: column;
|
|
3912
|
+
}
|
|
3913
|
+
|
|
3914
|
+
.ck-launch__step {
|
|
3915
|
+
display: grid;
|
|
3916
|
+
grid-template-columns: 2.4rem 1fr;
|
|
3917
|
+
gap: 1rem;
|
|
3918
|
+
align-items: baseline;
|
|
3919
|
+
padding: 1.25rem 0 1.25rem 1rem;
|
|
3920
|
+
border-top: 1px solid var(--ck-line);
|
|
3921
|
+
border-left: 2px solid transparent;
|
|
3922
|
+
animation: ck-launch-rise 0.45s ease both;
|
|
3923
|
+
animation-delay: calc(0.24s + var(--i) * 0.07s);
|
|
3924
|
+
}
|
|
3925
|
+
|
|
3926
|
+
.ck-launch__step-num {
|
|
3927
|
+
font-family: var(--ck-mono);
|
|
3928
|
+
font-size: 0.8rem;
|
|
3929
|
+
font-weight: 600;
|
|
3930
|
+
letter-spacing: 0.04em;
|
|
3931
|
+
color: var(--ck-dim);
|
|
3932
|
+
user-select: none;
|
|
3933
|
+
white-space: nowrap;
|
|
3934
|
+
}
|
|
3935
|
+
.ck-launch__step--done .ck-launch__step-num { color: var(--ck-success); }
|
|
3936
|
+
.ck-launch__step--next .ck-launch__step-num { color: var(--ck-accent); }
|
|
3937
|
+
.ck-launch__step-tick { margin-left: 0.3em; font-size: 0.78em; }
|
|
3938
|
+
|
|
3939
|
+
.ck-launch__step--done { border-left-color: rgba(45, 212, 168, 0.4); }
|
|
3940
|
+
|
|
3941
|
+
.ck-launch__step-body { min-width: 0; }
|
|
3942
|
+
|
|
3943
|
+
.ck-launch__step-head {
|
|
3944
|
+
display: flex;
|
|
3945
|
+
align-items: baseline;
|
|
3946
|
+
gap: 0.7rem;
|
|
3947
|
+
flex-wrap: wrap;
|
|
3948
|
+
margin-bottom: 0.3rem;
|
|
3949
|
+
}
|
|
3950
|
+
|
|
3951
|
+
.ck-launch__step-title {
|
|
3952
|
+
margin: 0;
|
|
3953
|
+
font-size: 1rem;
|
|
3954
|
+
font-weight: 500;
|
|
3955
|
+
letter-spacing: -0.005em;
|
|
3956
|
+
}
|
|
3957
|
+
.ck-launch__step-title a { color: var(--ck-text); text-decoration: none; }
|
|
3958
|
+
.ck-launch__step-title a:hover { color: var(--ck-accent); }
|
|
3959
|
+
.ck-launch__step--done .ck-launch__step-title { color: var(--ck-muted); }
|
|
3960
|
+
|
|
3961
|
+
.ck-launch__step-tag {
|
|
3962
|
+
font-family: var(--ck-mono);
|
|
3963
|
+
font-size: 0.6rem;
|
|
3964
|
+
letter-spacing: 0.18em;
|
|
3965
|
+
text-transform: uppercase;
|
|
3966
|
+
color: var(--ck-accent);
|
|
3967
|
+
padding: 0.12rem 0.45rem;
|
|
3968
|
+
border: 1px solid var(--ck-accent);
|
|
3969
|
+
border-radius: 999px;
|
|
3970
|
+
line-height: 1.4;
|
|
3971
|
+
}
|
|
3972
|
+
|
|
3973
|
+
.ck-launch__step-desc {
|
|
3974
|
+
margin: 0;
|
|
3975
|
+
font-size: 0.9rem;
|
|
3976
|
+
line-height: 1.55;
|
|
3977
|
+
color: var(--ck-muted);
|
|
3978
|
+
}
|
|
3979
|
+
|
|
3980
|
+
.ck-launch__step--pending .ck-launch__step-title,
|
|
3981
|
+
.ck-launch__step--pending .ck-launch__step-desc { opacity: 0.65; }
|
|
3982
|
+
|
|
3983
|
+
.ck-launch__step--next {
|
|
3984
|
+
border-left-color: var(--ck-accent);
|
|
3985
|
+
background: linear-gradient(90deg, var(--ck-accent-soft) 0%, transparent 30%);
|
|
3986
|
+
margin-left: -1rem;
|
|
3987
|
+
padding-left: 2rem;
|
|
3988
|
+
padding-right: 1rem;
|
|
3989
|
+
border-radius: 0 var(--ck-radius) var(--ck-radius) 0;
|
|
3990
|
+
}
|
|
3991
|
+
|
|
3992
|
+
.ck-launch__step-cta {
|
|
3993
|
+
display: inline-flex;
|
|
3994
|
+
align-items: center;
|
|
3995
|
+
gap: 0.4rem;
|
|
3996
|
+
margin-top: 0.85rem;
|
|
3997
|
+
padding: 0.5rem 0.95rem;
|
|
3998
|
+
background: var(--ck-accent);
|
|
3999
|
+
color: #06121a;
|
|
4000
|
+
border-radius: var(--ck-radius);
|
|
4001
|
+
font-family: var(--ck-mono);
|
|
4002
|
+
font-size: 0.75rem;
|
|
4003
|
+
letter-spacing: 0.06em;
|
|
4004
|
+
text-transform: uppercase;
|
|
4005
|
+
font-weight: 600;
|
|
4006
|
+
text-decoration: none;
|
|
4007
|
+
transition: filter 0.15s, transform 0.15s;
|
|
4008
|
+
}
|
|
4009
|
+
.ck-launch__step-cta:hover { filter: brightness(1.1); transform: translateY(-1px); }
|
|
4010
|
+
|
|
4011
|
+
.ck-launch__panel-footer {
|
|
4012
|
+
margin-top: 1.75rem;
|
|
4013
|
+
padding-top: 1.25rem;
|
|
4014
|
+
border-top: 1px solid var(--ck-line);
|
|
4015
|
+
}
|
|
4016
|
+
.ck-launch__dismiss {
|
|
4017
|
+
margin: 0;
|
|
4018
|
+
padding: 0;
|
|
4019
|
+
background: transparent;
|
|
4020
|
+
border: none;
|
|
4021
|
+
color: var(--ck-muted);
|
|
4022
|
+
font-family: var(--ck-mono);
|
|
4023
|
+
font-size: 0.78rem;
|
|
4024
|
+
letter-spacing: 0.04em;
|
|
4025
|
+
cursor: pointer;
|
|
4026
|
+
text-decoration: underline;
|
|
4027
|
+
text-underline-offset: 3px;
|
|
4028
|
+
transition: color 0.15s;
|
|
4029
|
+
}
|
|
4030
|
+
.ck-launch__dismiss:hover { color: var(--ck-accent); }
|
|
4031
|
+
.ck-launch__dismiss-hint {
|
|
4032
|
+
margin: 0.5rem 0 0;
|
|
4033
|
+
font-size: 0.78rem;
|
|
4034
|
+
color: var(--ck-dim);
|
|
4035
|
+
}
|
|
4036
|
+
|
|
4037
|
+
.ck-launch__ready-panel {
|
|
4038
|
+
position: relative;
|
|
4039
|
+
z-index: 1;
|
|
4040
|
+
background: var(--ck-surface);
|
|
4041
|
+
border: 1px solid var(--ck-line);
|
|
4042
|
+
border-radius: var(--ck-radius-lg);
|
|
4043
|
+
padding: 2rem;
|
|
4044
|
+
text-align: center;
|
|
4045
|
+
animation: ck-launch-rise 0.5s ease both;
|
|
4046
|
+
animation-delay: 0.08s;
|
|
4047
|
+
}
|
|
4048
|
+
|
|
4049
|
+
.ck-launch__ready-flag {
|
|
4050
|
+
margin: 0;
|
|
4051
|
+
font-family: var(--ck-mono);
|
|
4052
|
+
font-size: 0.85rem;
|
|
4053
|
+
letter-spacing: 0.14em;
|
|
4054
|
+
text-transform: uppercase;
|
|
4055
|
+
color: var(--ck-success);
|
|
4056
|
+
display: inline-flex;
|
|
4057
|
+
align-items: center;
|
|
4058
|
+
gap: 0.6rem;
|
|
4059
|
+
}
|
|
4060
|
+
.ck-launch__ready-dot {
|
|
4061
|
+
width: 8px;
|
|
4062
|
+
height: 8px;
|
|
4063
|
+
border-radius: 50%;
|
|
4064
|
+
background: var(--ck-success);
|
|
4065
|
+
box-shadow: 0 0 12px var(--ck-success);
|
|
4066
|
+
}
|
|
4067
|
+
.ck-launch__ready-copy { margin: 0.6rem 0 1.5rem; color: var(--ck-muted); }
|
|
4068
|
+
|
|
4069
|
+
.ck-launch__quicklinks {
|
|
4070
|
+
display: flex;
|
|
4071
|
+
gap: 0.6rem;
|
|
4072
|
+
justify-content: center;
|
|
4073
|
+
flex-wrap: wrap;
|
|
4074
|
+
}
|
|
4075
|
+
.ck-launch__quicklink {
|
|
4076
|
+
padding: 0.5rem 0.95rem;
|
|
4077
|
+
border: 1px solid var(--ck-line-strong);
|
|
4078
|
+
border-radius: var(--ck-radius);
|
|
4079
|
+
font-family: var(--ck-mono);
|
|
4080
|
+
font-size: 0.75rem;
|
|
4081
|
+
letter-spacing: 0.06em;
|
|
4082
|
+
text-transform: uppercase;
|
|
4083
|
+
color: var(--ck-text);
|
|
4084
|
+
text-decoration: none;
|
|
4085
|
+
transition: border-color 0.15s, background 0.15s;
|
|
4086
|
+
}
|
|
4087
|
+
.ck-launch__quicklink:hover { border-color: var(--ck-accent); background: var(--ck-surface-hover); }
|
|
4088
|
+
|
|
4089
|
+
@media (max-width: 560px) {
|
|
4090
|
+
.ck-launch__panel { padding: 1.5rem 1.25rem; }
|
|
4091
|
+
}
|
|
4092
|
+
|
|
4093
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4094
|
+
.ck-launch__header,
|
|
4095
|
+
.ck-launch__panel,
|
|
4096
|
+
.ck-launch__ready-panel,
|
|
4097
|
+
.ck-launch__step { animation: none; }
|
|
4098
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module CompletionKit
|
|
2
|
+
class OnboardingController < ApplicationController
|
|
3
|
+
DISMISS_COOKIE = :ck_onboarding_dismissed
|
|
4
|
+
|
|
5
|
+
def show
|
|
6
|
+
cookies.delete(DISMISS_COOKIE) if params[:reset]
|
|
7
|
+
@checklist = Onboarding::Checklist.new
|
|
8
|
+
return if params[:reset]
|
|
9
|
+
|
|
10
|
+
redirect_to prompts_path if @checklist.complete? || cookies[DISMISS_COOKIE]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def dismiss
|
|
14
|
+
cookies[DISMISS_COOKIE] = { value: "1", expires: 1.year.from_now, httponly: true }
|
|
15
|
+
redirect_to prompts_path, notice: "Setup skipped. Pick it back up from Settings → Getting started any time."
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module CompletionKit
|
|
2
|
+
module Onboarding
|
|
3
|
+
Step = Data.define(:key, :title, :description, :path_name, :done?)
|
|
4
|
+
|
|
5
|
+
class Checklist
|
|
6
|
+
STEP_DEFS = [
|
|
7
|
+
{
|
|
8
|
+
key: :credential,
|
|
9
|
+
title: "Connect a provider",
|
|
10
|
+
description: "Add an API key for OpenAI, Anthropic, or another model provider so you can run prompts and score outputs.",
|
|
11
|
+
path_name: :new_provider_credential_path,
|
|
12
|
+
done: -> { CompletionKit::ProviderCredential.exists? }
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
key: :dataset,
|
|
16
|
+
title: "Upload a dataset",
|
|
17
|
+
description: "Drop in a CSV of test inputs. Column headers become the {{variables}} your prompts get evaluated against.",
|
|
18
|
+
path_name: :new_dataset_path,
|
|
19
|
+
done: -> { CompletionKit::Dataset.exists? }
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
key: :prompt,
|
|
23
|
+
title: "Write your first prompt",
|
|
24
|
+
description: "Create a versioned prompt template with {{variable}} placeholders. Publishing freezes it; editing makes a new version.",
|
|
25
|
+
path_name: :new_prompt_path,
|
|
26
|
+
done: -> { CompletionKit::Prompt.exists? }
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
key: :run,
|
|
30
|
+
title: "Run it",
|
|
31
|
+
description: "Kick off a run against the dataset and watch the responses come in, each scored by the LLM judge against your metrics.",
|
|
32
|
+
path_name: :runs_path,
|
|
33
|
+
done: -> { CompletionKit::Run.exists? }
|
|
34
|
+
}
|
|
35
|
+
].freeze
|
|
36
|
+
|
|
37
|
+
def steps
|
|
38
|
+
@steps ||= STEP_DEFS.map do |d|
|
|
39
|
+
Step.new(
|
|
40
|
+
key: d[:key],
|
|
41
|
+
title: d[:title],
|
|
42
|
+
description: d[:description],
|
|
43
|
+
path_name: d[:path_name],
|
|
44
|
+
done?: d[:done].call
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def complete?
|
|
50
|
+
steps.all?(&:done?)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def progress
|
|
54
|
+
done = steps.count(&:done?)
|
|
55
|
+
{ done: done, total: steps.size, percent: ((done.to_f / steps.size) * 100).round }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<div class="ck-launch <%= "ck-launch--ready" if @checklist.complete? %>">
|
|
2
|
+
<div class="ck-launch__field" aria-hidden="true"></div>
|
|
3
|
+
|
|
4
|
+
<header class="ck-launch__header">
|
|
5
|
+
<p class="ck-launch__overline">Welcome to CompletionKit</p>
|
|
6
|
+
<h1 class="ck-launch__org">Your prompts need tests too</h1>
|
|
7
|
+
<p class="ck-launch__handle">Four steps from a fresh install to a scored test run.</p>
|
|
8
|
+
</header>
|
|
9
|
+
|
|
10
|
+
<% if @checklist.complete? %>
|
|
11
|
+
<section class="ck-launch__ready-panel">
|
|
12
|
+
<p class="ck-launch__ready-flag">
|
|
13
|
+
<span class="ck-launch__ready-dot" aria-hidden="true"></span>
|
|
14
|
+
You're all set up
|
|
15
|
+
</p>
|
|
16
|
+
<p class="ck-launch__ready-copy">Jump in wherever you like.</p>
|
|
17
|
+
<div class="ck-launch__quicklinks">
|
|
18
|
+
<%= link_to "Prompts", prompts_path, class: "ck-launch__quicklink" %>
|
|
19
|
+
<%= link_to "Datasets", datasets_path, class: "ck-launch__quicklink" %>
|
|
20
|
+
<%= link_to "Metrics", metrics_path, class: "ck-launch__quicklink" %>
|
|
21
|
+
<%= link_to "Runs", runs_path, class: "ck-launch__quicklink" %>
|
|
22
|
+
</div>
|
|
23
|
+
</section>
|
|
24
|
+
<% else %>
|
|
25
|
+
<% next_index = @checklist.steps.index { |s| !s.done? } %>
|
|
26
|
+
<% progress = @checklist.progress %>
|
|
27
|
+
<section class="ck-launch__panel">
|
|
28
|
+
<div class="ck-launch__progress">
|
|
29
|
+
<div class="ck-launch__progress-head">
|
|
30
|
+
<h2 class="ck-launch__progress-title">Finish setting up</h2>
|
|
31
|
+
<p class="ck-launch__progress-count"><%= progress[:done] %> of <%= progress[:total] %> done</p>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="ck-launch__progress-bar" role="img" aria-label="<%= progress[:done] %> of <%= progress[:total] %> setup steps complete">
|
|
34
|
+
<span class="ck-launch__progress-fill" style="width: <%= progress[:percent] %>%"></span>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<ol class="ck-launch__steps">
|
|
39
|
+
<% @checklist.steps.each_with_index do |step, i| %>
|
|
40
|
+
<%
|
|
41
|
+
state = if step.done?
|
|
42
|
+
"done"
|
|
43
|
+
elsif i == next_index
|
|
44
|
+
"next"
|
|
45
|
+
else
|
|
46
|
+
"pending"
|
|
47
|
+
end
|
|
48
|
+
step_path = public_send(step.path_name)
|
|
49
|
+
%>
|
|
50
|
+
<li class="ck-launch__step ck-launch__step--<%= state %>" style="--i: <%= i %>">
|
|
51
|
+
<span class="ck-launch__step-num" aria-hidden="true"><%= format("%02d", i + 1) %><% if step.done? %><span class="ck-launch__step-tick">✓</span><% end %></span>
|
|
52
|
+
<div class="ck-launch__step-body">
|
|
53
|
+
<div class="ck-launch__step-head">
|
|
54
|
+
<h3 class="ck-launch__step-title">
|
|
55
|
+
<% if step.done? %>
|
|
56
|
+
<%= step.title %>
|
|
57
|
+
<% else %>
|
|
58
|
+
<%= link_to step.title, step_path %>
|
|
59
|
+
<% end %>
|
|
60
|
+
</h3>
|
|
61
|
+
<% if state == "next" %><span class="ck-launch__step-tag">Next up</span><% end %>
|
|
62
|
+
</div>
|
|
63
|
+
<p class="ck-launch__step-desc"><%= step.description %></p>
|
|
64
|
+
<% if state == "next" %>
|
|
65
|
+
<%= link_to step_path, class: "ck-launch__step-cta" do %>Start <span aria-hidden="true">→</span><% end %>
|
|
66
|
+
<% end %>
|
|
67
|
+
</div>
|
|
68
|
+
</li>
|
|
69
|
+
<% end %>
|
|
70
|
+
</ol>
|
|
71
|
+
|
|
72
|
+
<div class="ck-launch__panel-footer">
|
|
73
|
+
<%= button_to dismiss_onboarding_path, method: :post, class: "ck-launch__dismiss", form: { style: "display:inline" } do %>
|
|
74
|
+
Skip setup — go to the app <span aria-hidden="true">→</span>
|
|
75
|
+
<% end %>
|
|
76
|
+
<p class="ck-launch__dismiss-hint">You can come back to this from <strong>Settings → Getting started</strong> any time.</p>
|
|
77
|
+
</div>
|
|
78
|
+
</section>
|
|
79
|
+
<% end %>
|
|
80
|
+
</div>
|
|
@@ -36,7 +36,10 @@
|
|
|
36
36
|
<p class="ck-kicker">Prompt</p>
|
|
37
37
|
<% judged_run = @runs.select { |r| r.prompt_id == @prompt.id && r.status == "completed" }.find { |r| r.responses.joins(:reviews).exists? } %>
|
|
38
38
|
<% if judged_run %>
|
|
39
|
-
<%= button_to
|
|
39
|
+
<%= button_to suggest_run_path(judged_run), method: :post, class: ck_button_classes(:light, variant: :outline) + " ck-button--sm", form_class: "inline-block" do %>
|
|
40
|
+
<%= heroicon_tag "sparkles", variant: :outline, class: "ck-magic-icon", "aria-hidden": "true" %>
|
|
41
|
+
Suggest improvements
|
|
42
|
+
<% end %>
|
|
40
43
|
<% else %>
|
|
41
44
|
<p class="ck-hint"><%= link_to "Run a test with judging configured", new_run_path(prompt_id: @prompt.id), class: "ck-link" %> to get AI-suggested improvements.</p>
|
|
42
45
|
<% end %>
|
|
@@ -66,7 +66,10 @@
|
|
|
66
66
|
<% if latest_suggestion %>
|
|
67
67
|
<%= link_to "View suggestion", suggestion_path(latest_suggestion, from: "run"), class: ck_button_classes(:light, variant: :outline) + " ck-button--sm" %>
|
|
68
68
|
<% elsif @run.status == "completed" && @run.responses.joins(:reviews).exists? %>
|
|
69
|
-
<%= button_to
|
|
69
|
+
<%= button_to suggest_run_path(@run), method: :post, class: ck_button_classes(:light, variant: :outline) + " ck-button--sm", form_class: "inline-block" do %>
|
|
70
|
+
<%= heroicon_tag "sparkles", variant: :outline, class: "ck-magic-icon", "aria-hidden": "true" %>
|
|
71
|
+
Suggest improvements
|
|
72
|
+
<% end %>
|
|
70
73
|
<% end %>
|
|
71
74
|
</div>
|
|
72
75
|
<p class="ck-prompt-preview__text" id="prompt_text"><%= @run.prompt.template %></p>
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
<%= link_to "Metrics", metrics_path, class: request.path.start_with?(metrics_path) || request.path.start_with?(metric_groups_path) ? ck_button_classes(:dark) : ck_button_classes(:light, variant: :outline) %>
|
|
24
24
|
<%= link_to "Datasets", datasets_path, class: active.(datasets_path) %>
|
|
25
25
|
<%= link_to "Runs", runs_path, class: active.(runs_path) %>
|
|
26
|
-
<% settings_active = request.path.start_with?(provider_credentials_path) || request.path.start_with?(tags_path) %>
|
|
26
|
+
<% settings_active = request.path.start_with?(provider_credentials_path) || request.path.start_with?(tags_path) || request.path.start_with?(onboarding_path) %>
|
|
27
27
|
<details class="ck-settings-menu">
|
|
28
28
|
<summary class="<%= settings_active ? ck_button_classes(:dark) : ck_button_classes(:light, variant: :outline) %> ck-settings-menu__trigger" aria-label="Settings">
|
|
29
29
|
Settings
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
<div class="ck-settings-menu__panel" role="menu">
|
|
32
32
|
<%= link_to "Providers", provider_credentials_path, class: "ck-settings-menu__item" %>
|
|
33
33
|
<%= link_to "Tags", tags_path, class: "ck-settings-menu__item" %>
|
|
34
|
+
<%= link_to "Getting started", onboarding_path(reset: 1), class: "ck-settings-menu__item" %>
|
|
34
35
|
</div>
|
|
35
36
|
</details>
|
|
36
37
|
<%= link_to "API", api_reference_path, class: active.(api_reference_path) %>
|
data/config/routes.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
CompletionKit::Engine.routes.draw do
|
|
2
|
-
root to: "
|
|
2
|
+
root to: "onboarding#show"
|
|
3
|
+
|
|
4
|
+
get "onboarding", to: "onboarding#show", as: :onboarding
|
|
5
|
+
post "onboarding/dismiss", to: "onboarding#dismiss", as: :dismiss_onboarding
|
|
3
6
|
|
|
4
7
|
resources :prompts do
|
|
5
8
|
member do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: completion-kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Damien Bastin
|
|
@@ -245,6 +245,7 @@ files:
|
|
|
245
245
|
- app/controllers/completion_kit/mcp_controller.rb
|
|
246
246
|
- app/controllers/completion_kit/metric_groups_controller.rb
|
|
247
247
|
- app/controllers/completion_kit/metrics_controller.rb
|
|
248
|
+
- app/controllers/completion_kit/onboarding_controller.rb
|
|
248
249
|
- app/controllers/completion_kit/prompts_controller.rb
|
|
249
250
|
- app/controllers/completion_kit/provider_credentials_controller.rb
|
|
250
251
|
- app/controllers/completion_kit/responses_controller.rb
|
|
@@ -292,6 +293,7 @@ files:
|
|
|
292
293
|
- app/services/completion_kit/mcp_tools/tags.rb
|
|
293
294
|
- app/services/completion_kit/model_discovery_service.rb
|
|
294
295
|
- app/services/completion_kit/ollama_client.rb
|
|
296
|
+
- app/services/completion_kit/onboarding/checklist.rb
|
|
295
297
|
- app/services/completion_kit/open_ai_client.rb
|
|
296
298
|
- app/services/completion_kit/open_router_client.rb
|
|
297
299
|
- app/services/completion_kit/prompt_improvement_service.rb
|
|
@@ -314,6 +316,7 @@ files:
|
|
|
314
316
|
- app/views/completion_kit/metrics/index.html.erb
|
|
315
317
|
- app/views/completion_kit/metrics/new.html.erb
|
|
316
318
|
- app/views/completion_kit/metrics/show.html.erb
|
|
319
|
+
- app/views/completion_kit/onboarding/show.html.erb
|
|
317
320
|
- app/views/completion_kit/prompts/_form.html.erb
|
|
318
321
|
- app/views/completion_kit/prompts/edit.html.erb
|
|
319
322
|
- app/views/completion_kit/prompts/index.html.erb
|