-
Notifications
You must be signed in to change notification settings - Fork 59
Expand file tree
/
Copy pathmodel_state.lua
More file actions
155 lines (129 loc) · 3.79 KB
/
model_state.lua
File metadata and controls
155 lines (129 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
local M = {}
---Get the path to the model state file
---@return string
local function get_model_state_path()
local home = vim.uv.os_homedir()
return home .. '/.local/state/opencode/model.json'
end
---Load model state (favorites, recent, and variants) in OpenCode CLI format
---@return table
function M.load()
local state_path = get_model_state_path()
local file = io.open(state_path, 'r')
if not file then
return { recent = {}, favorite = {}, variant = {} }
end
local content = file:read('*a')
file:close()
local ok, data = pcall(vim.json.decode, content)
if not ok or type(data) ~= 'table' then
return { recent = {}, favorite = {}, variant = {} }
end
data.recent = data.recent or {}
data.favorite = data.favorite or {}
data.variant = data.variant or {}
return data
end
---Save model state (favorites, recent, and variants) in OpenCode CLI format
---@param state table
function M.save(state)
local state_path = get_model_state_path()
local state_dir = vim.fn.fnamemodify(state_path, ':h')
if not vim.fn.isdirectory(state_dir) then
vim.fn.mkdir(state_dir, 'p')
end
local file = io.open(state_path, 'w')
if not file then
vim.notify('Failed to save model state', vim.log.levels.WARN)
return
end
local ok, json = pcall(vim.json.encode, state)
if not ok then
file:close()
vim.notify('Failed to encode model state', vim.log.levels.WARN)
return
end
file:write(json)
file:close()
end
---Get the saved variant for a model
---@param provider_id string
---@param model_id string
---@return string|nil
function M.get_variant(provider_id, model_id)
local state = M.load()
local key = provider_id .. '/' .. model_id
return state.variant[key]
end
---Save the variant for a model
---@param provider_id string
---@param model_id string
---@param variant_name string|nil
function M.set_variant(provider_id, model_id, variant_name)
local state = M.load()
local key = provider_id .. '/' .. model_id
if variant_name then
state.variant[key] = variant_name
else
state.variant[key] = nil
end
M.save(state)
end
---Record that a model was accessed
---@param provider_id string
---@param model_id string
function M.record_model_access(provider_id, model_id)
local state = M.load()
state.recent = vim.tbl_filter(function(item)
return not (item.providerID == provider_id and item.modelID == model_id)
end, state.recent)
table.insert(state.recent, 1, {
providerID = provider_id,
modelID = model_id,
})
if #state.recent > 10 then
for i = #state.recent, 11, -1 do
table.remove(state.recent, i)
end
end
M.save(state)
end
---Toggle a model as favorite
---@param provider_id string
---@param model_id string
function M.toggle_favorite(provider_id, model_id)
local state = M.load()
-- Check if already in favorites
local found_idx = nil
for i, item in ipairs(state.favorite) do
if item.providerID == provider_id and item.modelID == model_id then
found_idx = i
break
end
end
if found_idx then
table.remove(state.favorite, found_idx)
vim.notify('Removed from favorites: ' .. provider_id .. '/' .. model_id, vim.log.levels.INFO)
else
table.insert(state.favorite, {
providerID = provider_id,
modelID = model_id,
})
vim.notify('Added to favorites: ' .. provider_id .. '/' .. model_id, vim.log.levels.INFO)
end
M.save(state)
end
---Get model index in a state list
---@param provider_id string
---@param model_id string
---@param list table Array of model entries with providerID and modelID
---@return number|nil Index in the list (1-based) or nil if not found
function M.get_model_index(provider_id, model_id, list)
for i, item in ipairs(list) do
if item.providerID == provider_id and item.modelID == model_id then
return i
end
end
return nil
end
return M