completion-kit 0.5.29 → 0.5.30

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1c4a2e5c9305e6f54a09266a8e7896231c6518dbe576a76c1f0d3db6511f18f
4
- data.tar.gz: 1127b9f555ef7ef483302522cfb9039ec9d274cfa32aff2789301562ea0d1043
3
+ metadata.gz: 1bc6277357aee1869602b6c290d958c794788d14efc01d0c4caf1529d3567d69
4
+ data.tar.gz: a1e60f9278e2bc42c4e1bb487e850f7568a3b134b46e8dbc6b6b3d0bea79c469
5
5
  SHA512:
6
- metadata.gz: 3e6018c3d6d44ae68d64646f4d7272013f065203c765c68444800fd9b528b137582a4b4c6872a1b3e33325ab66a1dc5f67dd59536185320f602bc9875be8c101
7
- data.tar.gz: 856868da4c6d9aa78fbf3b0a0d7ead23065c3f4b50970aed1056849650f9cffe1e62e01ddaeca2e595e2cc2837c67f077f5e3fd1820f74348cc4fd23d3dffaa1
6
+ metadata.gz: fb4ffbbdb89589e0eca37f995ebc342bd6a6063160ca00cffa25abc956532a2b34aa7e6ce7b7c852802bcf5ed74cc4c49cb7f817ab36dbe07608bf18dd52dc1d
7
+ data.tar.gz: 61ef079b27c73bb749778e182052ac9c1e6824f1d432635210b647f716f10c5364f6ff8ec9b45cbc274d00b3d93d58b37613c61953596fd7ccf6fe89df1b88f0
data/README.md CHANGED
@@ -18,19 +18,19 @@ It's the difference between "this prompt seems to work" and "this prompt scores
18
18
 
19
19
  > **Just want to use it?** [CompletionKit Cloud](https://completionkit.com) is the same engine, fully hosted — zero install, no Rails ops, plans at [completionkit.com/pricing](https://completionkit.com/pricing).
20
20
 
21
- ![Test run with scored results](https://raw.githubusercontent.com/homemade-software-inc/completion-kit/main/docs/screenshots/test-run.png)
21
+ ![The CompletionKit dashboard — workspace totals, run activity over the last 14 days, the worst-scoring metric, version-over-version score changes, and recent runs](https://raw.githubusercontent.com/homemade-software-inc/completion-kit/main/docs/screenshots/dashboard.png)
22
22
 
23
23
  ## Three ways to run it
24
24
 
25
- Same engine, same UI, same REST API and MCP server — pick the deployment that fits.
25
+ Same engine, same UI, same REST API and MCP server — pick the deployment that fits. The first two are stack-agnostic: you run CompletionKit as a product and talk to it over HTTP and MCP, whatever language your own app is written in. The third is for teams already building on Rails.
26
26
 
27
27
  ### 1. Hosted — [completionkit.com](https://completionkit.com) (recommended)
28
28
 
29
29
  The fastest path. Sign up and you're running on the same engine you'd self-host, without touching a Rails app. No `db:migrate`, no Puma, no Solid Queue, no provider key management — multi-tenant workspaces, your team logs in, you go. Plans at [completionkit.com/pricing](https://completionkit.com/pricing).
30
30
 
31
- ### 2. Self-hosted — the bundled standalone Rails app
31
+ ### 2. Self-hosted — the bundled standalone app
32
32
 
33
- Run it on your own infra. No existing Rails app required; Postgres + any Rails-friendly host (Fly, Render, Heroku, Docker, …).
33
+ Run it on your own infra as a self-contained product. There's nothing to integrate and no Ruby to write — once it's up, you drive everything through the web UI, the REST API, and the MCP server, from whatever stack your own app is built in. It needs Postgres and a host that can run the app (Fly, Render, Heroku, Docker, …).
34
34
 
35
35
  ```bash
36
36
  git clone https://github.com/homemade-software-inc/completion-kit.git
@@ -147,6 +147,12 @@ Limiting uses `Rails.cache`. A shared cache store (Solid Cache, Redis) throttles
147
147
 
148
148
  ## How it works
149
149
 
150
+ <p align="center">
151
+ <img src="https://raw.githubusercontent.com/homemade-software-inc/completion-kit/main/docs/diagrams/workflow.png" alt="CompletionKit workflow: a prompt and a dataset feed a run against a model, an LLM judge scores each output on your rubric, low scores drive an AI-suggested rewrite, and the new prompt version re-runs so you can compare" width="820" />
152
+ </p>
153
+
154
+ It's a loop. Each pass leaves you with a score you can compare against the last one.
155
+
150
156
  1. **Create a prompt** with `{{variable}}` placeholders
151
157
  2. **Upload a dataset.** A CSV where column headers match the variable names.
152
158
  3. **Run it** against a model and score outputs with an LLM judge against criteria you define.
@@ -217,6 +223,37 @@ bin/rails db:migrate
217
223
  git add db/migrate/ && git commit -m "install new engine migration"
218
224
  ```
219
225
 
226
+ ### Docker
227
+
228
+ The standalone app ships a `Dockerfile`, so you can self-host it without a Ruby toolchain on the host. Build with the **repository root** as the context — the app depends on the engine source alongside it:
229
+
230
+ ```bash
231
+ docker build -f standalone/Dockerfile -t completion-kit .
232
+ ```
233
+
234
+ CompletionKit needs a Rails secret (`SECRET_KEY_BASE`) and three Active Record encryption keys. With Docker there's no Rails toolchain on the host to run `bin/rails db:encryption:init`, so generate them with `openssl`. Generate them **once** and keep them stable — if the encryption keys change, provider credentials already stored in the database can no longer be decrypted. Write everything to an env file:
235
+
236
+ ```bash
237
+ cat > completion-kit.env <<EOF
238
+ DATABASE_URL=postgres://user:pass@host/completionkit
239
+ SECRET_KEY_BASE=$(openssl rand -hex 64)
240
+ COMPLETION_KIT_ENCRYPTION_PRIMARY_KEY=$(openssl rand -hex 32)
241
+ COMPLETION_KIT_ENCRYPTION_DETERMINISTIC_KEY=$(openssl rand -hex 32)
242
+ COMPLETION_KIT_ENCRYPTION_KEY_DERIVATION_SALT=$(openssl rand -hex 32)
243
+ EOF
244
+ ```
245
+
246
+ `openssl rand` runs as the file is written, so each line gets a real random value. Keep `completion-kit.env` out of version control and back it up somewhere safe.
247
+
248
+ Run the web process and a job worker from the same image, both pointed at that file:
249
+
250
+ ```bash
251
+ docker run -d -p 3000:3000 --env-file completion-kit.env completion-kit
252
+ docker run -d --env-file completion-kit.env completion-kit ./bin/jobs
253
+ ```
254
+
255
+ Both processes must share the same `SECRET_KEY_BASE` and encryption keys — the single env file guarantees that. The web container runs `db:prepare` on boot, so migrations apply on first start and on every deploy.
256
+
220
257
  ## Multi-tenant host apps (advanced)
221
258
 
222
259
  For hosts that mount CompletionKit in a multi-tenant app, two optional hooks scope engine records per tenant without forking the engine:
@@ -158,3 +158,9 @@ document.addEventListener("turbo:before-stream-render", function(event) {
158
158
  if (status) { status.textContent = 'Models updated.'; setTimeout(function() { status.textContent = ' '; }, 3000); }
159
159
  }
160
160
  });
161
+
162
+ document.addEventListener("click", function(e) {
163
+ document.querySelectorAll("details.ck-nav-menu[open], details.ck-settings-menu[open], details.ck-flyout[open]").forEach(function(menu) {
164
+ if (!menu.contains(e.target)) menu.removeAttribute("open");
165
+ });
166
+ });
@@ -4345,6 +4345,16 @@ a.tag-mark {
4345
4345
  .ck-settings-menu__trigger::-webkit-details-marker {
4346
4346
  display: none;
4347
4347
  }
4348
+ .ck-settings-menu__trigger svg {
4349
+ display: block;
4350
+ width: 18px;
4351
+ height: 18px;
4352
+ }
4353
+ .ck-settings-menu__trigger:focus-visible {
4354
+ outline: none;
4355
+ border-color: var(--ck-accent);
4356
+ color: var(--ck-accent);
4357
+ }
4348
4358
  .ck-settings-menu__panel {
4349
4359
  position: absolute;
4350
4360
  right: 0;
@@ -4374,6 +4384,16 @@ a.tag-mark {
4374
4384
  .ck-settings-menu__item:hover {
4375
4385
  background: var(--ck-surface-hover);
4376
4386
  }
4387
+ .ck-settings-menu__panel form {
4388
+ margin: 0;
4389
+ }
4390
+ .ck-settings-menu__panel button.ck-settings-menu__item {
4391
+ width: 100%;
4392
+ text-align: left;
4393
+ background: none;
4394
+ border: 0;
4395
+ cursor: pointer;
4396
+ }
4377
4397
 
4378
4398
  /* Settings page kicker — small label above the page title on settings pages */
4379
4399
  .ck-settings-kicker {
@@ -4961,3 +4981,71 @@ a.tag-mark {
4961
4981
  max-height: 60vh;
4962
4982
  }
4963
4983
  }
4984
+
4985
+ .ck-concept {
4986
+ position: relative;
4987
+ display: inline;
4988
+ }
4989
+ .ck-concept__toggle {
4990
+ margin: 0 0 0 0.15rem;
4991
+ padding: 0;
4992
+ border: 0;
4993
+ background: none;
4994
+ font: inherit;
4995
+ line-height: 0;
4996
+ color: var(--ck-dim);
4997
+ cursor: pointer;
4998
+ }
4999
+ .ck-concept__toggle:hover,
5000
+ .ck-concept__toggle:focus {
5001
+ color: var(--ck-accent);
5002
+ }
5003
+ .ck-concept__icon {
5004
+ width: 0.92em;
5005
+ height: 0.92em;
5006
+ vertical-align: -0.12em;
5007
+ }
5008
+ .ck-concept__pop {
5009
+ display: none;
5010
+ position: absolute;
5011
+ top: calc(100% + 0.4rem);
5012
+ left: 0;
5013
+ z-index: 40;
5014
+ width: 19rem;
5015
+ max-width: calc(100vw - 1.5rem);
5016
+ padding: 0.7rem 0.8rem;
5017
+ background: var(--ck-bg-strong);
5018
+ border: 1px solid var(--ck-line-strong);
5019
+ border-radius: var(--ck-radius);
5020
+ box-shadow: 0 16px 34px rgba(0, 0, 0, 0.5);
5021
+ white-space: normal;
5022
+ }
5023
+ .ck-concept__toggle:hover + .ck-concept__pop,
5024
+ .ck-concept__toggle:focus + .ck-concept__pop,
5025
+ .ck-concept__pop:hover {
5026
+ display: block;
5027
+ }
5028
+ .ck-concept__name {
5029
+ display: block;
5030
+ margin-bottom: 0.3rem;
5031
+ font-family: var(--ck-mono);
5032
+ font-size: 0.72rem;
5033
+ font-weight: 700;
5034
+ letter-spacing: 0.06em;
5035
+ text-transform: uppercase;
5036
+ color: var(--ck-text);
5037
+ }
5038
+ .ck-concept__body {
5039
+ display: block;
5040
+ font-size: 0.8rem;
5041
+ line-height: 1.5;
5042
+ color: var(--ck-muted);
5043
+ }
5044
+ @media (max-width: 640px) {
5045
+ .ck-concept__pop {
5046
+ position: fixed;
5047
+ inset: auto 0.75rem 0.75rem 0.75rem;
5048
+ width: auto;
5049
+ max-width: none;
5050
+ }
5051
+ }
@@ -27,21 +27,21 @@
27
27
  <%= 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) %>
28
28
  <%= link_to "Datasets", datasets_path, class: active.(datasets_path) %>
29
29
  <%= link_to "Runs", runs_path, class: active.(runs_path) %>
30
- <% settings_active = request.path.start_with?(provider_credentials_path) || request.path.start_with?(tags_path) || request.path.start_with?(onboarding_path) %>
30
+ <% settings_active = request.path.start_with?(provider_credentials_path) || request.path.start_with?(tags_path) || request.path.start_with?(onboarding_path) || request.path.start_with?(api_reference_path) %>
31
31
  <details class="ck-settings-menu">
32
32
  <summary class="<%= settings_active ? ck_button_classes(:dark) : ck_button_classes(:light, variant: :outline) %> ck-settings-menu__trigger" aria-label="Settings">
33
- Settings
33
+ <%= heroicon_tag "cog-6-tooth", variant: :outline, size: 18, "aria-hidden": "true" %>
34
34
  </summary>
35
35
  <div class="ck-settings-menu__panel" role="menu">
36
+ <%= link_to "Getting started", onboarding_path(reset: 1), class: "ck-settings-menu__item" %>
37
+ <%= link_to "API", api_reference_path, class: "ck-settings-menu__item" %>
36
38
  <%= link_to "Providers", provider_credentials_path, class: "ck-settings-menu__item" %>
37
39
  <%= link_to "Tags", tags_path, class: "ck-settings-menu__item" %>
38
- <%= link_to "Getting started", onboarding_path(reset: 1), class: "ck-settings-menu__item" %>
40
+ <% if main_app.respond_to?(:logout_path) %>
41
+ <%= button_to "Sign out", main_app.logout_path, method: :delete, class: "ck-settings-menu__item" %>
42
+ <% end %>
39
43
  </div>
40
44
  </details>
41
- <%= link_to "API", api_reference_path, class: active.(api_reference_path) %>
42
- <% if main_app.respond_to?(:logout_path) %>
43
- <%= button_to "Log out", main_app.logout_path, method: :delete, class: ck_button_classes(:light, variant: :outline) %>
44
- <% end %>
45
45
  </nav>
46
46
  </details>
47
47
  </div>
@@ -1,3 +1,3 @@
1
1
  module CompletionKit
2
- VERSION = "0.5.29"
2
+ VERSION = "0.5.30"
3
3
  end
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.29
4
+ version: 0.5.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - Damien Bastin