@adaptiqai/opencode 0.1.5 → 0.1.6

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.
Files changed (4) hide show
  1. package/README.md +161 -43
  2. package/lib/index.js +4696 -669
  3. package/lib/tui.js +396 -0
  4. package/package.json +5 -3
package/README.md CHANGED
@@ -6,7 +6,13 @@ AdaptiqAI remembers, and your saved knowledge, in one plugin.
6
6
 
7
7
  ## Install
8
8
 
9
- Add the plugin to the harness's config:
9
+ Set up from the AdaptiqAI console's **Connect to app**, the harness gets this
10
+ plugin by itself, from the configuration that sign-in gives it. It runs on
11
+ the console's own AdaptiqAI provider (`adaptiq/<model>`), and the plugin works
12
+ on that provider's requests the same way it works on its own (see below). It
13
+ adds its tools and `/adaptiq` beside it, but no second provider.
14
+
15
+ To set it up by hand, add the plugin to the harness's config:
10
16
 
11
17
  | Harness | Config | Entry |
12
18
  |---|---|---|
@@ -23,44 +29,71 @@ in the app) and choose **AdaptiqAI**:
23
29
  `ADAPTIQAI_API_KEY` in the environment works too.
24
30
 
25
31
  Choose a model from the **AdaptiqAI** provider (`adaptiqai/<model>`). The list
26
- is the models in your workspace, each with its own output limit and
27
- thinking levels (OpenCode's variants).
28
-
29
- Set up from the AdaptiqAI console's **Connect to app** instead, the harness
30
- gets this plugin by itself, from the configuration that sign-in gives it, and
31
- the plugin takes that sign-in's key. The harness then runs on the console's
32
- own AdaptiqAI provider (`adaptiq/<model>`), and the plugin adds its tools and
33
- `/adaptiq` beside it, but no second provider.
32
+ is the models in your workspace, each with its own output limit, thinking
33
+ levels (OpenCode's variants) and price.
34
34
 
35
35
  ## What it does
36
36
 
37
+ These hold on the plugin's own provider and on Connect to app's alike.
38
+
37
39
  - **A conversation is one AdaptiqAI session.** Every turn carries the
38
40
  harness's session id as `x-adaptiq-session-id`. AdaptiqAI keeps the
39
41
  conversation's memory, and the collections and conversations you attach to
40
- it in the console reach the model.
42
+ it reach the model.
41
43
  - **The harness's own session headers are replaced.** OpenCode and Kilo put
42
44
  session headers of their own on every request, title calls too. OpenCode 2
43
45
  even puts the root conversation's id in a subagent's `X-Session-Id`. A turn
44
46
  goes out with only the plugin's header, a helper call with none.
45
- - **Helper calls leave nothing.** Titles, compaction and summaries run once,
46
- marked ephemeral, and never become a conversation. So do Kilo's commit
47
- messages and branch names, and any request the plugin cannot tell is a turn.
47
+ - **Helper calls leave nothing.** Titles and summaries run once, marked
48
+ ephemeral, and never become a conversation. So do Kilo's commit messages
49
+ and branch names, and any request the plugin cannot tell is a turn.
50
+ - **Private conversations stay private.** `/adaptiq private` (or the agent's
51
+ "continue without saving", on your word) stops saving the conversation's new
52
+ messages: its turns are read back and save nothing. `/adaptiq remember`
53
+ turns saving back on.
54
+ - **A subagent names the conversation that started it**
55
+ (`X-Adaptiq-Parent-Session-Id`). One the conversation waits for is a
56
+ `helper`, folded under it in the console. In OpenCode 1.x and Kilo, one the
57
+ task tool starts in the background (an experimental option in both) is a
58
+ `track`, a line of work of its own, listed on its own. A fork you make is a
59
+ conversation of its own.
60
+ - **Another model says where the memory is.** AdaptiqAI keeps a
61
+ conversation's memory on the model it ran on. Send a message on another
62
+ model and you are told once, per conversation and model: "This
63
+ conversation's memory is on Model A. Switch back: pick Model A in /models ·
64
+ Start fresh on Model B: /new". OpenCode 1.x and Kilo show it as a toast in
65
+ the terminal app, for any other model. OpenCode 2 has no notice a plugin can
66
+ give without a model turn, so there the model is told to say it, on
67
+ AdaptiqAI's models only.
48
68
  - **The harness never compacts an AdaptiqAI conversation by itself.**
49
69
  AdaptiqAI holds the conversation whole. The harness's own compaction would
50
70
  rewrite that history and make the engine compile the conversation again.
51
- - The plugin leaves its models' context window unknown, which all three
52
- harnesses read as "never compact automatically". Every other model keeps
53
- the harness's compaction.
54
- - Compacting on purpose (`/compact`) still works, once and ephemeral, but
55
- an unknown window sizes it less well. OpenCode 1.x and Kilo keep no
56
- recent messages word for word beside the summary, and Kilo 7.8.15 sums
57
- up one message per request. OpenCode 2 sums up only as much as fits a
58
- 200k window, and its model list shows the window as 0.
59
- - A request the gateway refuses as too large (HTTP 413) still makes the
60
- harness compact.
61
- - **A subagent names the conversation that started it**
62
- (`X-Adaptiq-Parent-Session-Id`, role `helper`), so the console folds it
63
- under that conversation.
71
+ - In OpenCode 1.x and Kilo the plugin's models carry the card's window, so
72
+ the context meter shows the real share, and an input limit no
73
+ conversation reaches: their automatic compaction goes by that limit, not
74
+ by the window. OpenCode 2 compacts at 85% of the smaller of the two, so
75
+ its models keep the window unknown, which it reads as "never compact
76
+ automatically". Connect to app turns automatic compaction off in its
77
+ configuration.
78
+ - In OpenCode 1.x and Kilo, `/compact` is declined, and nothing is sent: the
79
+ harness shows "AdaptiqAI keeps the whole conversation in native memory, so
80
+ it never needs compacting. Nothing was removed." The history stays whole.
81
+ - OpenCode 2 lets no plugin decline a compaction, so `/compact` still runs
82
+ there, once and ephemeral.
83
+ - **What AdaptiqAI answers is said in plain words.** A refusal shows the same
84
+ sentence as in every AdaptiqAI plugin: a busy model ("retries
85
+ automatically"), a conversation being prepared, an empty balance (with the
86
+ page to add funds), a full memory (with what to do), a sign-in to renew. The
87
+ harness retries exactly what that sentence says it retries, after the wait
88
+ AdaptiqAI asks for (Retry-After), and nothing else: a full memory is not
89
+ retried five times. `/adaptiq diagnostics` lists the latest ones.
90
+ - **Notices the harness shows nowhere else** show as a toast in OpenCode 1.x
91
+ and Kilo's terminal app: a newer plugin is out, with the step that installs
92
+ it, and idle conversations were put to sleep to make room (nothing is
93
+ deleted).
94
+ - **Prices.** The harness counts what a conversation costs from each model's
95
+ price per million tokens (read from memory and saved to memory as cache
96
+ reads and writes), on Connect's models too.
64
97
  - **Tools for the agent:**
65
98
  - `adaptiq_knowledge`: what this conversation uses; find words, ids or names
66
99
  in the text of its collections, with the exact lines as document:line;
@@ -68,48 +101,133 @@ own AdaptiqAI provider (`adaptiq/<model>`), and the plugin adds its tools and
68
101
  - `adaptiq_memory`: how full the memory is; the saved collections; keep a
69
102
  conversation private.
70
103
  - `adaptiq_create_knowledge`: save material as a collection, only when you
71
- ask.
104
+ ask, or when you say yes to the agent's offer, typed or through the
105
+ harness's question tool.
72
106
 
73
107
  In OpenCode 2 they are on the model's own tool list, not behind Code Mode.
74
108
  - **A turn is told which ready collections its conversation reads**, so the
75
109
  agent looks things up there with find. OpenCode 1.x and Kilo save the note
76
110
  with your message, as a part you don't see, once and again when the
77
- collections change; OpenCode 2 keeps nothing a plugin adds, so each request
78
- carries it in its system prompt. Conversations on the console's own
79
- provider (Connect to app) get it too.
80
- - **`/adaptiq`** asks the agent where this conversation's memory and
81
- knowledge stand. OpenCode and Kilo give a plugin's command no way to answer
82
- by itself, so it is a turn of the model and costs like one. That turn reads
83
- the conversation and saves nothing: the question and its answer stay out of
84
- the conversation's memory. Only what you type after `/adaptiq` counts as
85
- your own words.
86
-
87
- Signing out in the harness (`opencode auth logout`, or removing the
88
- credential in OpenCode 2) signs the plugin out too, and the plugin removes
89
- its own copy of the sign-in, refresh token and all:
111
+ collections change (a conversation from before the harness started keeps
112
+ the note it has). OpenCode 2 keeps nothing a plugin adds, so each request
113
+ carries it in its system prompt.
114
+
115
+ ## The memory pill and the AdaptiqAI menu
116
+
117
+ In the terminal app of OpenCode 1.x (from 1.18.29), Kilo and OpenCode 2, the
118
+ plugin shows what DeepSeek Harness shows beside its message field:
119
+
120
+ - **The memory pill** by the prompt: "Memory · 26.2k / 5M", "Preparing
121
+ memory" and "Waiting in line" while a request waits, a collection being
122
+ prepared, "Private", "+24.6k from memory" for a moment after a reply, and
123
+ a notice's button when one needs you ("Add funds to continue ›", "Sign in
124
+ to AdaptiqAI").
125
+ - **A click on it**, `/adaptiq` or the command palette opens the AdaptiqAI
126
+ menu, with no model turn: Remember or Private, the knowledge used here
127
+ (one pick uses or stops a collection, or makes one available for this
128
+ model), an earlier conversation to read here, files added as a collection
129
+ (drag a file into the terminal, or type its path), Processed, Status,
130
+ Settings (workspace, models with their queues, memory, saving, links,
131
+ plugin, account) and an update with one pick.
132
+ - **OpenCode 2** also shows, above the message field, where the
133
+ conversation's memory is while another model is picked, and the notices
134
+ it has no toast for.
135
+
136
+ OpenCode 1.x and Kilo load this part from `tui.json` only, never from the
137
+ config that names the plugin. The plugin creates the global `tui.json`
138
+ (`~/.config/opencode/tui.json`, or `kilo`) naming itself, once, when there is
139
+ none; it never changes one you have, and says once how to add the line
140
+ instead: `"plugin": ["@adaptiqai/opencode"]`. OpenCode 2 loads it by itself.
141
+ Kilo's VS Code panel has no place for it.
142
+
143
+ ## `/adaptiq`
144
+
145
+ The same actions and words as in every AdaptiqAI plugin:
146
+
147
+ ```
148
+ /adaptiq workspace, models and memory
149
+ /adaptiq private stop saving new messages of this conversation
150
+ /adaptiq remember save this conversation to memory again
151
+ /adaptiq knowledge knowledge used here, and what else you can use
152
+ /adaptiq use <name> use a collection or an earlier conversation here
153
+ /adaptiq stop <name> stop using it here (nothing is deleted)
154
+ /adaptiq open open this conversation in AdaptiqAI Knowledge
155
+ /adaptiq diagnostics a report you can send to support (no secrets)
156
+ /adaptiq signout forget the connection on this computer
157
+ /adaptiq signin how to sign in
158
+ ```
159
+
160
+ The plugin answers it itself; the model takes no action.
161
+
162
+ - **In the terminal app** (OpenCode 1.x, Kilo, OpenCode 2) the answer shows
163
+ in a dialog, with no model turn. In OpenCode 1.x and Kilo, typed with words
164
+ after it, `/adaptiq` is the harness's command, which always starts a turn:
165
+ the plugin shows the answer in the panel and stops the command, and the
166
+ harness logs one error line saying why.
167
+ - **Without the panel**, OpenCode 2 shows the answer as a notice in the
168
+ conversation (the model reads it with your next message), and OpenCode 1.x
169
+ and Kilo (`run`, Kilo's VS Code panel) run a turn in which the model
170
+ repeats the plugin's answer. That turn reads the conversation and saves
171
+ nothing.
172
+
173
+ **Signing in** happens in the harness: `opencode auth login` (or `kilo auth
174
+ login`, `/connect` in the app, or Connect to app). The browser sign-in counts
175
+ while the harness keeps its AdaptiqAI sign-in.
176
+
177
+ **Signing out:** `/adaptiq signout` forgets the plugin's sign-in on this
178
+ computer, refresh token and all, and says when the harness still has an
179
+ AdaptiqAI key (its own, `ADAPTIQAI_API_KEY`, or Connect's); `opencode auth
180
+ logout` (or `kilo auth logout`) removes that. Signing out in the harness signs
181
+ the plugin out too:
90
182
 
91
183
  - OpenCode 2 tells the plugin at once.
92
184
  - `opencode auth logout` and `kilo auth logout` change only the harness's
93
185
  own file. The plugin removes its copy at the next request, or within five
94
186
  minutes while the harness runs, or when the harness next starts.
95
187
 
96
- The copy is removed from this computer, not revoked at AdaptiqAI: to
188
+ The sign-in is removed from this computer, not revoked at AdaptiqAI: to
97
189
  disconnect this computer altogether, use Connected apps in the AdaptiqAI
98
190
  console.
99
191
 
192
+ **Keys.** A harness can hold several AdaptiqAI keys: its own sign-in's key,
193
+ the one Connect to app gave it, `ADAPTIQAI_API_KEY`. The tools try them in
194
+ that order, `ADAPTIQAI_API_KEY` first, and a key AdaptiqAI refuses gives way to
195
+ the next, so an old key never hides a working one.
196
+
100
197
  OpenCode 1.x and 2.x keep separate AdaptiqAI sign-ins, and so does the
101
198
  plugin: signing out of one leaves the other signed in.
102
199
 
200
+ ## Updates
201
+
202
+ `/adaptiq` says when a newer plugin is out (the plugin reads the newest
203
+ published version once a day), with the one step that installs it:
204
+
205
+ - **In the terminal app**, "Update to …" in the AdaptiqAI menu installs it;
206
+ it runs from the next start. In OpenCode 1.x and Kilo that names the new
207
+ version in your global `opencode.json` and `tui.json`.
208
+ - **OpenCode 1.x and Kilo** otherwise install the plugin once, into a folder
209
+ of their cache named by the plugin entry (Connect to app's is
210
+ `~/.cache/opencode/packages/@adaptiqai/opencode@>=0.1.3`, or `kilo`), and
211
+ never look for a newer version. Quit the harness, delete that folder and
212
+ start it again: it installs the newest version.
213
+ - **OpenCode 2**: `opencode plugin update`, then restart OpenCode.
214
+
103
215
  ## How it fits each harness
104
216
 
105
217
  | | OpenCode 1.x and Kilo (`server()`) | OpenCode 2.x (`setup()`) |
106
218
  |---|---|---|
107
- | Provider and models | added to the config by the `config` hook | `provider.transform`, reloaded when the list changes |
219
+ | Provider and models | added to the config by the `config` hook | `provider.transform`, reloaded when the list or the sign-in changes |
220
+ | Connect to app's provider | its `fetch` set in the `config` hook; prices added to its models | the hooks act on it too; prices through `model.transform` |
108
221
  | Sign-in | `auth` methods; the plugin's own fetch signs each request | integration methods; OAuth `refresh` renews OpenCode's copy |
109
222
  | Turn or helper call | `chat.headers` marks it by agent (and Kilo's session ids) | `model.request` by request kind |
110
223
  | Session headers | replaced in the plugin's fetch | replaced in `model.request` |
111
224
  | Memory field | added in the plugin's fetch | added in `http.request` |
112
- | No automatic compaction | window left unknown (`limit.context: 0`) | the same |
225
+ | What AdaptiqAI answers | read in the plugin's fetch | read in `http.response` |
226
+ | Your words and the agent's offer | `chat.message`, and the message events | the history each request carries (`context`) |
227
+ | `/adaptiq` | the panel's slash command; typed with words, `command.execute.before` answers in the panel and stops it; without a panel, a turn that repeats the answer | the panel's slash command with its words; without a panel, the command and a notice (`session.synthetic`) |
228
+ | No automatic compaction | the card's window, `limit.input` of 9 billion; `/compact` declined | window left unknown |
229
+ | Another model than the memory's | a toast, from `chat.message` | the panel's line above the message field; without one, the turn's first request tells the model (`context`) |
230
+ | Memory pill and menu | `./tui` from `tui.json`: slot `session_prompt_right`, a keymap command, dialogs; talks over `tui.command.execute` events | `./tui` loaded with the plugin: slot `prompt.footer.status`, a keymap command, dialogs; talks over an RPC |
113
231
  | Tools | zod arguments, rebuilt from the core's JSON Schema | the core's JSON Schema, `codemode: false` |
114
232
 
115
233
  A provider that only the config knows never gets a plugin's model list in