completion-kit 0.5.11 → 0.5.12
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c45ef9dab51631cbc2bfc606b6c98c038d967edeea8903efa634571d012e0b0
|
|
4
|
+
data.tar.gz: 549981db86a07f2d48cafb2b2413f6e1850997087ef553418c3ec9d7d07e0a0a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ddf258f7c59bc3a92113bcb95211f0314ea6cebe624d163478833f1515f0baafab0c630b9dd8983b7e2bde7ea5b641cb45b2249cd48c08a853422633e93409d9
|
|
7
|
+
data.tar.gz: 5001137b6be3a376f665cff46480e51b6994774f7e9146b5e464053bedcd5d989e2171b4ea8d792c9312b8c03b2e46e9d6b7515d8037e1c5510bde14caf11b1f
|
|
@@ -1874,17 +1874,21 @@ tr:hover .ck-chip--publish {
|
|
|
1874
1874
|
overflow: auto;
|
|
1875
1875
|
max-height: 60vh;
|
|
1876
1876
|
scrollbar-width: thin;
|
|
1877
|
-
scrollbar-color: var(--ck-line-strong)
|
|
1877
|
+
scrollbar-color: var(--ck-line-strong) var(--ck-bg);
|
|
1878
|
+
}
|
|
1879
|
+
.ck-csv-table-wrap::-webkit-scrollbar { width: 12px; height: 12px; background: var(--ck-bg); }
|
|
1880
|
+
.ck-csv-table-wrap::-webkit-scrollbar-track {
|
|
1881
|
+
background: var(--ck-bg);
|
|
1882
|
+
border-left: 1px solid var(--ck-line);
|
|
1883
|
+
border-top: 1px solid var(--ck-line);
|
|
1878
1884
|
}
|
|
1879
|
-
.ck-csv-table-wrap::-webkit-scrollbar { width: 10px; height: 10px; }
|
|
1880
|
-
.ck-csv-table-wrap::-webkit-scrollbar-track { background: transparent; }
|
|
1881
1885
|
.ck-csv-table-wrap::-webkit-scrollbar-thumb {
|
|
1882
1886
|
background: var(--ck-line-strong);
|
|
1883
|
-
border-radius:
|
|
1884
|
-
border:
|
|
1887
|
+
border-radius: 6px;
|
|
1888
|
+
border: 3px solid var(--ck-bg);
|
|
1885
1889
|
}
|
|
1886
1890
|
.ck-csv-table-wrap::-webkit-scrollbar-thumb:hover { background: var(--ck-muted); }
|
|
1887
|
-
.ck-csv-table-wrap::-webkit-scrollbar-corner { background:
|
|
1891
|
+
.ck-csv-table-wrap::-webkit-scrollbar-corner { background: var(--ck-bg); }
|
|
1888
1892
|
|
|
1889
1893
|
.ck-modal__body .ck-csv-table-wrap {
|
|
1890
1894
|
margin-top: 0;
|
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
module CompletionKit
|
|
2
2
|
# MCP session marker — one row per active client session, kept in the
|
|
3
3
|
# database so sessions survive Puma restarts, deploys, and Rails.cache
|
|
4
|
-
# eviction.
|
|
5
|
-
#
|
|
4
|
+
# eviction.
|
|
5
|
+
#
|
|
6
|
+
# Two things to know about why every query goes through `unscoped`:
|
|
7
|
+
#
|
|
8
|
+
# 1. CompletionKit::ApplicationRecord applies the host app's tenant_scope as
|
|
9
|
+
# a default_scope. MCP sessions are per-CONNECTION, not per-tenant — the
|
|
10
|
+
# table has no organization_id column. Letting the tenant_scope into a
|
|
11
|
+
# session lookup turns "is this session live?" into either a SQL error
|
|
12
|
+
# (no such column) or a false negative (`WHERE 1=0`), which surfaces to
|
|
13
|
+
# the client as a spurious "Session not initialized" right after init.
|
|
14
|
+
# 2. `active?` slides expires_at forward when a session is more than halfway
|
|
15
|
+
# through its TTL, so an MCP connection that keeps making calls stays
|
|
16
|
+
# alive instead of expiring on the original 1-hour wall clock.
|
|
17
|
+
#
|
|
18
|
+
# Expired rows are opportunistically pruned on every new session start, so
|
|
19
|
+
# the table stays bounded by recent activity.
|
|
6
20
|
class McpSession < ApplicationRecord
|
|
7
21
|
self.table_name = "completion_kit_mcp_sessions"
|
|
8
22
|
|
|
@@ -10,20 +24,31 @@ module CompletionKit
|
|
|
10
24
|
|
|
11
25
|
def self.start!
|
|
12
26
|
prune_expired!
|
|
13
|
-
create!(session_id: SecureRandom.uuid, expires_at: SESSION_TTL.from_now).session_id
|
|
27
|
+
unscoped.create!(session_id: SecureRandom.uuid, expires_at: SESSION_TTL.from_now).session_id
|
|
14
28
|
end
|
|
15
29
|
|
|
16
30
|
def self.active?(session_id)
|
|
17
31
|
return false if session_id.blank?
|
|
18
|
-
|
|
32
|
+
|
|
33
|
+
row = unscoped.where(session_id: session_id).where("expires_at > ?", Time.current).first
|
|
34
|
+
return false unless row
|
|
35
|
+
|
|
36
|
+
slide_expiry(row)
|
|
37
|
+
true
|
|
19
38
|
end
|
|
20
39
|
|
|
21
40
|
def self.destroy_session(session_id)
|
|
22
|
-
where(session_id: session_id).delete_all
|
|
41
|
+
unscoped.where(session_id: session_id).delete_all
|
|
23
42
|
end
|
|
24
43
|
|
|
25
44
|
def self.prune_expired!
|
|
26
|
-
where("expires_at < ?", Time.current).delete_all
|
|
45
|
+
unscoped.where("expires_at < ?", Time.current).delete_all
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.slide_expiry(row)
|
|
49
|
+
half_ttl_from_now = (SESSION_TTL / 2).from_now
|
|
50
|
+
return if row.expires_at > half_ttl_from_now
|
|
51
|
+
row.update_column(:expires_at, SESSION_TTL.from_now)
|
|
27
52
|
end
|
|
28
53
|
end
|
|
29
54
|
end
|