Commit fdd01e8
authored
feat: read and write llm providers through the server (#2537)
* feat(app): read and write llm providers through the server
useLlmProviders keeps its exact interface so both consumers, AI settings
and chat target selection, are untouched. Underneath it is now a
react-query-kit query over Hono RPC instead of extension storage.
It gains an unavailable state. Previously an empty list meant the user
had no providers, and the hook seeded the built-in one in response. Over
HTTP a failed load looks the same as an empty one, so seeding moved into
the fetcher where it can only run on a confirmed empty response, and AI
settings now says the list could not be loaded rather than showing none.
Saving a single-instance provider used to collapse earlier copies as a
side effect of writing the whole list. That is now an explicit plan of
one PUT and the deletes it displaces.
The default provider id stays in extension storage. It is a per-profile
preference and every profile shares one database, so a column would make
them share a default too. A stale id costs nothing because it is
resolved on read.
Logout no longer deletes providers or scheduled jobs. That was right
while they were account data synced to the cloud; they are now local
data the account does not back.
* fix(app): do not substitute a provider the caller did not choose
An unreachable provider list returned an empty array, so a scheduled job
that named a provider found no match and fell through to the built-in
one. It ran on a different model with different credentials and was
recorded as completed. The list being unreachable says nothing about
whether that provider exists, so the two cases are now distinguished and
naming a provider that cannot be loaded fails the run instead. A
provider that was genuinely deleted still falls back, as before.
Deleting a provider also persisted the replacement default before
attempting the delete, so a failed delete left the provider configured
but no longer default with nothing to show for it. The delete goes
first; a default id left pointing at a deleted provider is repaired on
read.
* fix(app): never resolve a provider from a list that failed to load
The previous guard only covered a job that named a provider, which left
the same hole one step over. A job that names none still has a choice
behind it: the configured default, whose id lives in extension storage
but whose model and credentials live in the list. So an unreachable list
sent those runs to the built-in provider and recorded them completed,
which is the case this guard existed to prevent.
The condition drops to the list itself, which also states the invariant
plainly. An empty list keeps the fallback, because that is the server
answering that it genuinely has no providers rather than not answering.
* feat: move scheduled jobs and run history to the server (#2538)
* feat(server): add local storage for scheduled job runs
Job definitions had a table; their run history did not, so it was the
one part of the domain with nowhere to live on this side.
Runs cascade on job delete, unlike the job to provider reference which
is set null. A job whose provider was removed is a job needing
attention, whereas a run whose job was removed means nothing, and
deleting a job already removed its runs before this table existed.
The tool call log is a json column. Its input field is optional here
where the extension has it required: an unknown already admits
undefined, so the two describe the same values, and matching the
validator avoids asserting the difference away at the route boundary.
* feat(server): carry the per-job run cap across with the runs
The extension kept fifteen runs per job, trimming as it created each
one. Now that it no longer owns the history that policy has to live
here, or the table grows without bound.
It applies on every write rather than only on creation, which is bounded
and idempotent, so it holds however the run was written. The import path
does not prune, staying purely additive; the next real run trims.
* feat(app): read and write scheduled jobs and runs through the server
The hooks keep their shape, so the tasks page, the results view, the
card and the new tab panel are unchanged apart from where they import
from. Both gain an unavailable state, since an empty list and an
unreachable server are now the same shape without one.
The alarm runner distinguishes them everywhere it reads. Treating a
failed load as an empty list would read as nothing being scheduled:
alarms would not be rebuilt on startup and schedules would quietly stop
firing, with no failed run to show for it. It skips the pass instead and
retries on the next startup.
Extension storage no longer carries the data, but it still carries the
change signal. Runs are written by the background while the side panel
and new tab display them, and storage watch is what kept those in step.
A revision item is bumped after a write so every mounted view refetches.
Run history is imported once, under its own marker. It cannot share the
provider and job marker because that import must never run twice:
extension storage is frozen now, so a second pass would insert back
whatever the user has since deleted.
Also removes the scheduled job deletion queue, whose only reader went
when sync did, and the mount-time storage read that chose the opening
tab, which is now derived so it settles when the history arrives.
* fix(app): record a finished run against the current job
Recording that a run finished wrote back the job as it was read before
the run started. A run can take minutes and the job stays editable
throughout, so a rename, a schedule change, a disable or a different
provider chosen while it was going would be silently reverted.
The old code merged into a freshly read list; passing the job object
instead was an attempt to save a read and is what lost the update. It
takes an id again, so a stale snapshot cannot be handed to it, and it
skips the write when the job was deleted mid-run rather than
resurrecting it.1 parent bfa7e8b commit fdd01e8
38 files changed
Lines changed: 2935 additions & 490 deletions
File tree
- packages/browseros-agent/apps
- app
- entrypoints/background
- lib
- llm-providers
- schedules
- modules
- llm-providers
- local-first-migration
- schedules
- screens
- ai-settings
- auth
- newtab/index
- scheduled-tasks
- server
- src
- api/routes
- lib
- db
- migrations
- meta
- schema
- schedules
- tests
- api/routes
- lib/schedules
Lines changed: 57 additions & 59 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | 4 | | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
9 | 12 | | |
10 | | - | |
11 | 13 | | |
12 | 14 | | |
13 | 15 | | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
17 | 24 | | |
18 | | - | |
| 25 | + | |
| 26 | + | |
19 | 27 | | |
20 | 28 | | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
35 | 34 | | |
36 | | - | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
37 | 43 | | |
38 | 44 | | |
39 | 45 | | |
40 | | - | |
41 | | - | |
42 | | - | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
43 | 49 | | |
44 | 50 | | |
45 | 51 | | |
| |||
56 | 62 | | |
57 | 63 | | |
58 | 64 | | |
| 65 | + | |
| 66 | + | |
59 | 67 | | |
60 | 68 | | |
61 | 69 | | |
62 | 70 | | |
63 | 71 | | |
64 | 72 | | |
65 | 73 | | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
| 74 | + | |
81 | 75 | | |
82 | 76 | | |
83 | 77 | | |
| 78 | + | |
| 79 | + | |
84 | 80 | | |
85 | | - | |
| 81 | + | |
86 | 82 | | |
87 | 83 | | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
| 84 | + | |
92 | 85 | | |
93 | 86 | | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
94 | 90 | | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
101 | 96 | | |
102 | 97 | | |
103 | 98 | | |
104 | | - | |
105 | | - | |
106 | | - | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
107 | 103 | | |
| 104 | + | |
108 | 105 | | |
109 | 106 | | |
110 | 107 | | |
| |||
120 | 117 | | |
121 | 118 | | |
122 | 119 | | |
123 | | - | |
| 120 | + | |
124 | 121 | | |
125 | 122 | | |
126 | 123 | | |
| |||
135 | 132 | | |
136 | 133 | | |
137 | 134 | | |
138 | | - | |
| 135 | + | |
139 | 136 | | |
140 | 137 | | |
141 | 138 | | |
| |||
155 | 152 | | |
156 | 153 | | |
157 | 154 | | |
158 | | - | |
159 | | - | |
160 | | - | |
161 | | - | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
162 | 160 | | |
163 | 161 | | |
164 | 162 | | |
| |||
Lines changed: 13 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
202 | 215 | | |
203 | 216 | | |
204 | 217 | | |
Lines changed: 31 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
8 | 7 | | |
9 | 8 | | |
10 | 9 | | |
11 | 10 | | |
12 | 11 | | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | 76 | | |
85 | 77 | | |
86 | 78 | | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
87 | 100 | | |
88 | | - | |
89 | | - | |
| 101 | + | |
90 | 102 | | |
91 | 103 | | |
92 | | - | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
93 | 112 | | |
94 | 113 | | |
95 | 114 | | |
| |||
Lines changed: 79 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
49 | 58 | | |
50 | 59 | | |
51 | 60 | | |
| |||
160 | 169 | | |
161 | 170 | | |
162 | 171 | | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
Lines changed: 13 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
5 | | - | |
6 | 5 | | |
7 | 6 | | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
17 | | - | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
18 | 28 | | |
19 | 29 | | |
20 | 30 | | |
| |||
0 commit comments