Skip to content

Commit 61f341c

Browse files
committed
feat(usage): update Usage module
1 parent 4b26c02 commit 61f341c

File tree

9 files changed

+305
-33
lines changed

9 files changed

+305
-33
lines changed

src/actor/src/_index.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ entries:
88
meta:
99
description: "Testing component"
1010
component: "wippy/test"
11-
version: ">=v0.0.1"
11+
version: ">=v0.2.0"
1212

1313
# wippy.actor:actor
1414
- name: actor

src/llm/src/_index.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ entries:
88
meta:
99
description: "Testing component"
1010
component: "wippy/test"
11-
version: ">=v0.0.1"
11+
version: ">=v0.2.0"
1212

1313
# wippy.llm:embedder
1414
- name: embedder
Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,19 @@ entries:
88
meta:
99
description: "Application database ID for usage tracking"
1010
targets:
11-
- entry: env-target_db
11+
- entry: wippy.usage.env:target_db
1212
path: ".default"
1313
- entry: wippy.usage.migrations:01_create_token_usage_table
1414
path: ".meta.env-target_db"
15+
default: "app:db"
1516

1617
# Dependencies
1718
- name: __dependency.wippy.test
1819
kind: "ns.dependency"
1920
meta:
2021
description: "Testing component"
2122
component: "wippy/test"
22-
version: ">=v0.0.1"
23+
version: ">=v0.2.0"
2324

2425
- name: __dependency.wippy.migration
2526
kind: "ns.dependency"
@@ -28,21 +29,6 @@ entries:
2829
component: "wippy/migration"
2930
version: ">=v0.0.7"
3031

31-
# wippy.usage:envs
32-
- name: envs
33-
kind: env.storage.os
34-
meta:
35-
type: envstorage
36-
comment: OS storage for environment variables
37-
38-
# wippy.usage:env-target_db
39-
- name: env-target_db
40-
kind: env.variable
41-
meta:
42-
type: config_key
43-
comment: Database resource identifier
44-
storage: wippy.usage:envs
45-
4632
# wippy.usage:token_usage_repo
4733
- name: token_usage_repo
4834
kind: library.lua
@@ -58,7 +44,6 @@ entries:
5844
- json
5945
- uuid
6046
- time
61-
- env
6247

6348
# wippy.usage:token_usage_repo_test
6449
- name: token_usage_repo_test
@@ -67,7 +52,7 @@ entries:
6752
name: Token Usage Repository Test
6853
type: test
6954
comment: Tests for the token usage repository functionality
70-
group: Usage Tests
55+
group: LLM / Usage Tests
7156
tags:
7257
- usage
7358
- tokens
@@ -85,3 +70,36 @@ entries:
8570
test: wippy.test:test
8671
token_usage_repo: wippy.usage:token_usage_repo
8772
method: run_tests
73+
74+
# wippy.usage:usage_tracker
75+
- name: usage_tracker
76+
kind: function.lua
77+
meta:
78+
comment: Usage tracker contract handler for recording LLM token usage
79+
tags:
80+
- usage
81+
- tokens
82+
- tracking
83+
source: file://usage_tracker.lua
84+
modules:
85+
- security
86+
imports:
87+
token_usage_repo: wippy.usage:token_usage_repo
88+
method: track_usage
89+
pool:
90+
max_size: 25
91+
92+
# wippy.usage:usage_tracker_binding
93+
- name: usage_tracker_binding
94+
kind: contract.binding
95+
meta:
96+
comment: Usage tracker contract binding to token usage repository
97+
tags:
98+
- usage
99+
- binding
100+
- contract
101+
contracts:
102+
- contract: wippy.llm:usage_tracker
103+
default: true
104+
methods:
105+
track_usage: wippy.usage:usage_tracker

src/usage/src/env/_index.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
version: "1.0"
2+
namespace: wippy.usage.env
3+
4+
entries:
5+
# wippy.usage.env:target_db
6+
- name: target_db
7+
kind: env.variable
8+
meta:
9+
type: config_key
10+
comment: Database resource identifier
11+
storage: wippy.usage:envs
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
-- 01_create_token_usage_table.lua (updated)
2+
return require("migration").define(function()
3+
migration("Create token_usage table", function()
4+
database("postgres", function()
5+
up(function(db)
6+
-- Create token_usage table
7+
local success, err = db:execute([[
8+
CREATE TABLE token_usage (
9+
usage_id TEXT PRIMARY KEY,
10+
user_id TEXT NOT NULL,
11+
context_id TEXT,
12+
model_id TEXT NOT NULL,
13+
prompt_tokens INTEGER NOT NULL,
14+
completion_tokens INTEGER NOT NULL,
15+
thinking_tokens INTEGER NOT NULL DEFAULT 0,
16+
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
17+
cache_write_tokens INTEGER NOT NULL DEFAULT 0,
18+
timestamp timestamp NOT NULL DEFAULT now(),
19+
meta TEXT
20+
)
21+
]])
22+
23+
if err then
24+
error(err)
25+
end
26+
27+
-- Create indexes
28+
success, err = db:execute("CREATE INDEX idx_token_usage_user ON token_usage(user_id)")
29+
if err then
30+
error(err)
31+
end
32+
33+
success, err = db:execute("CREATE INDEX idx_token_usage_context ON token_usage(context_id)")
34+
if err then
35+
error(err)
36+
end
37+
38+
success, err = db:execute("CREATE INDEX idx_token_usage_model ON token_usage(model_id)")
39+
if err then
40+
error(err)
41+
end
42+
43+
success, err = db:execute("CREATE INDEX idx_token_usage_timestamp ON token_usage(timestamp)")
44+
if err then
45+
error(err)
46+
end
47+
end)
48+
49+
down(function(db)
50+
-- Drop indexes first
51+
local success, err = db:execute("DROP INDEX IF EXISTS idx_token_usage_user")
52+
if err then
53+
error(err)
54+
end
55+
56+
success, err = db:execute("DROP INDEX IF EXISTS idx_token_usage_context")
57+
if err then
58+
error(err)
59+
end
60+
61+
success, err = db:execute("DROP INDEX IF EXISTS idx_token_usage_model")
62+
if err then
63+
error(err)
64+
end
65+
66+
success, err = db:execute("DROP INDEX IF EXISTS idx_token_usage_timestamp")
67+
if err then
68+
error(err)
69+
end
70+
71+
-- Drop table
72+
success, err = db:execute("DROP TABLE IF EXISTS token_usage")
73+
if err then
74+
error(err)
75+
end
76+
end)
77+
end)
78+
79+
database("sqlite", function()
80+
up(function(db)
81+
-- Create token_usage table
82+
local success, err = db:execute([[
83+
CREATE TABLE token_usage (
84+
usage_id TEXT PRIMARY KEY,
85+
user_id TEXT NOT NULL,
86+
context_id TEXT,
87+
model_id TEXT NOT NULL,
88+
prompt_tokens INTEGER NOT NULL,
89+
completion_tokens INTEGER NOT NULL,
90+
thinking_tokens INTEGER NOT NULL DEFAULT 0,
91+
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
92+
cache_write_tokens INTEGER NOT NULL DEFAULT 0,
93+
timestamp INTEGER NOT NULL,
94+
meta TEXT
95+
)
96+
]])
97+
98+
if err then
99+
error(err)
100+
end
101+
102+
-- Create indexes
103+
success, err = db:execute("CREATE INDEX idx_token_usage_user ON token_usage(user_id)")
104+
if err then
105+
error(err)
106+
end
107+
108+
success, err = db:execute("CREATE INDEX idx_token_usage_context ON token_usage(context_id)")
109+
if err then
110+
error(err)
111+
end
112+
113+
success, err = db:execute("CREATE INDEX idx_token_usage_model ON token_usage(model_id)")
114+
if err then
115+
error(err)
116+
end
117+
118+
success, err = db:execute("CREATE INDEX idx_token_usage_timestamp ON token_usage(timestamp)")
119+
if err then
120+
error(err)
121+
end
122+
end)
123+
124+
down(function(db)
125+
-- Drop indexes first
126+
local success, err = db:execute("DROP INDEX IF EXISTS idx_token_usage_user")
127+
if err then
128+
error(err)
129+
end
130+
131+
success, err = db:execute("DROP INDEX IF EXISTS idx_token_usage_context")
132+
if err then
133+
error(err)
134+
end
135+
136+
success, err = db:execute("DROP INDEX IF EXISTS idx_token_usage_model")
137+
if err then
138+
error(err)
139+
end
140+
141+
success, err = db:execute("DROP INDEX IF EXISTS idx_token_usage_timestamp")
142+
if err then
143+
error(err)
144+
end
145+
146+
-- Drop table
147+
success, err = db:execute("DROP TABLE IF EXISTS token_usage")
148+
if err then
149+
error(err)
150+
end
151+
end)
152+
end)
153+
end)
154+
end)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
version: "1.0"
2+
namespace: wippy.usage.migrations
3+
4+
entries:
5+
# wippy.usage.migrations:01_create_token_usage_table
6+
- name: 01_create_token_usage_table
7+
kind: function.lua
8+
meta:
9+
type: migration
10+
tags:
11+
- usage
12+
- tokens
13+
- database
14+
description: Create token_usage table for tracking LLM token consumption
15+
target_db: app:db
16+
timestamp: "2025-04-08T10:00:00Z"
17+
source: file://01_create_token_usage_table.lua
18+
imports:
19+
migration: wippy.migration:migration
20+
method: migrate
21+
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ local sql = require("sql")
22
local json = require("json")
33
local uuid = require("uuid")
44
local time = require("time")
5-
local env = require("env")
5+
6+
-- Hardcoded database resource name
7+
local DB_RESOURCE = "app:db"
68

79
local token_usage_repo = {}
810

@@ -16,9 +18,6 @@ token_usage_repo.INTERVAL = {
1618

1719
-- Get a database connection
1820
local function get_db()
19-
-- Get database resource from environment
20-
local DB_RESOURCE, _ = env.get("wippy.usage:env-target_db")
21-
2221
local db, err = sql.get(DB_RESOURCE)
2322
if err then
2423
return nil, "Failed to connect to database: " .. err
@@ -49,9 +48,9 @@ function token_usage_repo.create(user_id, model_id, prompt_tokens, completion_to
4948

5049
-- Convert meta to JSON if it's a table
5150
local meta_json = nil
52-
if options.meta then
53-
if type(options.meta) == "table" then
54-
local encoded, err = json.encode(options.meta)
51+
if options.metadata then
52+
if type(options.metadata) == "table" then
53+
local encoded, err = json.encode(options.metadata)
5554
if err then
5655
return nil, "Failed to encode meta: " .. err
5756
end
@@ -276,7 +275,7 @@ FROM
276275
-- SQLite implementation using recursive CTE
277276
local interval_seconds
278277
local date_format
279-
278+
280279
if interval == token_usage_repo.INTERVAL.HOUR then
281280
interval_seconds = 3600
282281
date_format = "%Y-%m-%d %H:00:00"
@@ -293,7 +292,7 @@ FROM
293292
db:release()
294293
return nil, "Invalid interval: must be hour, day, week, or month"
295294
end
296-
295+
297296
query_sql = [[
298297
WITH RECURSIVE
299298
time_buckets(bucket_start, bucket_end) AS (
@@ -435,4 +434,4 @@ function token_usage_repo.get_usage_by_model(start_time, end_time)
435434
return results
436435
end
437436

438-
return token_usage_repo
437+
return token_usage_repo
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ local function define_tests()
7171
-- Clean up test data after all tests
7272
after_all(function()
7373
-- Get a database connection for cleanup
74-
local db_resource, _ = env.get("wippy.usage:env-target_db")
74+
local db_resource, _ = env.get("wippy.usage.env:target_db")
7575
local db, err = sql.get(db_resource)
7676
if err then
7777
error("Failed to connect to database: " .. err)
@@ -120,7 +120,7 @@ local function define_tests()
120120
local end_time = test_data.base_time + 3600 -- 1 hour from now
121121

122122
-- Query only for our test users to isolate the data
123-
local db_resource, _ = env.get("wippy.usage:env-target_db")
123+
local db_resource, _ = env.get("wippy.usage.env:target_db")
124124
local db, db_err = sql.get(db_resource)
125125
if db_err then error(db_err) end
126126

0 commit comments

Comments
 (0)