@iinm/plain-agent 1.7.17 → 1.7.19
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.
- package/README.md +53 -26
- package/config/config.predefined.json +8 -170
- package/package.json +1 -1
- package/src/cliArgs.mjs +31 -1
- package/src/cliBatch.mjs +22 -0
- package/src/cliCost.mjs +274 -0
- package/src/cliInteractive.mjs +28 -0
- package/src/env.mjs +9 -0
- package/src/main.mjs +15 -0
- package/src/usageStore.mjs +167 -0
- package/src/voiceInput.mjs +24 -634
- package/src/voiceInputGemini.mjs +257 -0
- package/src/voiceInputOpenAI.mjs +261 -0
- package/src/voiceInputSession.mjs +250 -0
- package/src/voiceToggleKey.mjs +62 -0
package/README.md
CHANGED
|
@@ -152,6 +152,19 @@ Create the configuration.
|
|
|
152
152
|
<details>
|
|
153
153
|
<summary><b>OpenAI compatible provider examples</b></summary>
|
|
154
154
|
|
|
155
|
+
```js
|
|
156
|
+
{
|
|
157
|
+
"platforms": [
|
|
158
|
+
{
|
|
159
|
+
"name": "openai-compatible",
|
|
160
|
+
"variant": "fireworks",
|
|
161
|
+
"baseURL": "https://api.fireworks.ai/inference",
|
|
162
|
+
"apiKey": "<FIREWORKS_API_KEY>"
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
155
168
|
```js
|
|
156
169
|
{
|
|
157
170
|
"platforms": [
|
|
@@ -160,21 +173,26 @@ Create the configuration.
|
|
|
160
173
|
"variant": "ollama",
|
|
161
174
|
"baseURL": "https://ollama.com",
|
|
162
175
|
"apiKey": "<API_KEY>"
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
"variant": "huggingface",
|
|
167
|
-
"baseURL": "https://router.huggingface.co",
|
|
168
|
-
"apiKey": "<HUGGINGFACE_API_KEY>"
|
|
169
|
-
},
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
"models": [
|
|
170
179
|
{
|
|
171
|
-
"name": "
|
|
172
|
-
"variant": "
|
|
173
|
-
"
|
|
174
|
-
|
|
180
|
+
"name": "gpt-oss",
|
|
181
|
+
"variant": "ollama",
|
|
182
|
+
"platform": {
|
|
183
|
+
"name": "openai-compatible",
|
|
184
|
+
"variant": "ollama"
|
|
185
|
+
},
|
|
186
|
+
"model": {
|
|
187
|
+
"format": "openai-responses",
|
|
188
|
+
"config": {
|
|
189
|
+
"model": "gpt-oss:120b-cloud"
|
|
190
|
+
}
|
|
191
|
+
}
|
|
175
192
|
}
|
|
176
193
|
]
|
|
177
194
|
}
|
|
195
|
+
|
|
178
196
|
```
|
|
179
197
|
</details>
|
|
180
198
|
|
|
@@ -183,6 +201,14 @@ Create the configuration.
|
|
|
183
201
|
|
|
184
202
|
```js
|
|
185
203
|
{
|
|
204
|
+
"platforms": [
|
|
205
|
+
{
|
|
206
|
+
"name": "bedrock",
|
|
207
|
+
"variant": "jp",
|
|
208
|
+
"baseURL": "https://bedrock-runtime.ap-northeast-1.amazonaws.com",
|
|
209
|
+
"awsProfile": "<AWS_PROFILE>"
|
|
210
|
+
}
|
|
211
|
+
],
|
|
186
212
|
"models": [
|
|
187
213
|
{
|
|
188
214
|
"name": "claude-haiku-4-5",
|
|
@@ -237,14 +263,6 @@ Create the configuration.
|
|
|
237
263
|
}
|
|
238
264
|
}
|
|
239
265
|
}
|
|
240
|
-
],
|
|
241
|
-
"platforms": [
|
|
242
|
-
{
|
|
243
|
-
"name": "bedrock",
|
|
244
|
-
"variant": "jp",
|
|
245
|
-
"baseURL": "https://bedrock-runtime.ap-northeast-1.amazonaws.com",
|
|
246
|
-
"awsProfile": "<AWS_PROFILE>"
|
|
247
|
-
}
|
|
248
266
|
]
|
|
249
267
|
}
|
|
250
268
|
```
|
|
@@ -289,6 +307,17 @@ Display the help message.
|
|
|
289
307
|
/help
|
|
290
308
|
```
|
|
291
309
|
|
|
310
|
+
Show aggregated token cost per day across sessions.
|
|
311
|
+
Each finished session appends a record to `~/.local/share/plain-agent/usage.jsonl`,
|
|
312
|
+
and `plain cost` reads that log. The period defaults to the first day of the
|
|
313
|
+
current month through today; override it with `--from` / `--to`. Multiple
|
|
314
|
+
currencies (e.g., USD and JPY) are aggregated separately.
|
|
315
|
+
|
|
316
|
+
```sh
|
|
317
|
+
plain cost
|
|
318
|
+
plain cost --from 2026-04-01 --to 2026-04-30
|
|
319
|
+
```
|
|
320
|
+
|
|
292
321
|
Interrupt the agent while it's running:
|
|
293
322
|
|
|
294
323
|
Press **Ctrl-C** to pause auto-approve. The agent will finish the current tool call, then return to the prompt.
|
|
@@ -307,7 +336,7 @@ The agent can use the following tools to assist with tasks:
|
|
|
307
336
|
- **report_as_subagent**: Report completion and return to the main agent. Used by subagents to communicate results and restore the main agent role. After reporting, the subagent's conversation history is removed from the context.
|
|
308
337
|
- **compact_context**: Compact the conversation context by discarding prior messages and reloading task state from a memory file. Use when the context has grown large but the task is not yet complete. Can also be invoked via the `/compact` slash command.
|
|
309
338
|
|
|
310
|
-
##
|
|
339
|
+
## Configuration
|
|
311
340
|
|
|
312
341
|
```
|
|
313
342
|
~/.config/plain-agent/
|
|
@@ -325,14 +354,12 @@ The agent can use the following tools to assist with tasks:
|
|
|
325
354
|
\__ agents/ # Project-specific agent roles
|
|
326
355
|
```
|
|
327
356
|
|
|
328
|
-
## Configuration
|
|
329
|
-
|
|
330
357
|
The agent loads configuration files in the following order. Settings in later files will override those in earlier files.
|
|
331
358
|
|
|
332
|
-
- `~/.config/plain-agent/config.json
|
|
333
|
-
- `~/.config/plain-agent/config.local.json
|
|
334
|
-
- `.plain-agent/config.json
|
|
335
|
-
- `.plain-agent/config.local.json
|
|
359
|
+
- `~/.config/plain-agent/config.json`
|
|
360
|
+
- `~/.config/plain-agent/config.local.json`
|
|
361
|
+
- `.plain-agent/config.json`
|
|
362
|
+
- `.plain-agent/config.local.json`
|
|
336
363
|
|
|
337
364
|
### Example
|
|
338
365
|
|
|
@@ -910,37 +910,6 @@
|
|
|
910
910
|
}
|
|
911
911
|
},
|
|
912
912
|
|
|
913
|
-
{
|
|
914
|
-
"name": "grok-4-1-fast-reasoning",
|
|
915
|
-
"variant": "default",
|
|
916
|
-
"platform": {
|
|
917
|
-
"name": "openai",
|
|
918
|
-
"variant": "xai",
|
|
919
|
-
"baseURL": "https://api.x.ai"
|
|
920
|
-
},
|
|
921
|
-
"model": {
|
|
922
|
-
"format": "openai-messages",
|
|
923
|
-
"config": {
|
|
924
|
-
"model": "grok-4-1-fast-reasoning"
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
},
|
|
928
|
-
{
|
|
929
|
-
"name": "grok-4.20-0309-reasoning",
|
|
930
|
-
"variant": "default",
|
|
931
|
-
"platform": {
|
|
932
|
-
"name": "openai",
|
|
933
|
-
"variant": "xai",
|
|
934
|
-
"baseURL": "https://api.x.ai"
|
|
935
|
-
},
|
|
936
|
-
"model": {
|
|
937
|
-
"format": "openai-messages",
|
|
938
|
-
"config": {
|
|
939
|
-
"model": "grok-4.20-0309-reasoning"
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
},
|
|
943
|
-
|
|
944
913
|
{
|
|
945
914
|
"name": "glm-5",
|
|
946
915
|
"variant": "vertex-ai",
|
|
@@ -964,21 +933,6 @@
|
|
|
964
933
|
}
|
|
965
934
|
}
|
|
966
935
|
},
|
|
967
|
-
{
|
|
968
|
-
"name": "glm-5",
|
|
969
|
-
"variant": "bedrock",
|
|
970
|
-
"platform": {
|
|
971
|
-
"name": "bedrock",
|
|
972
|
-
"variant": "default"
|
|
973
|
-
},
|
|
974
|
-
"model": {
|
|
975
|
-
"format": "openai-messages",
|
|
976
|
-
"config": {
|
|
977
|
-
"model": "zai.glm-5",
|
|
978
|
-
"reasoning_effort": "high"
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
},
|
|
982
936
|
{
|
|
983
937
|
"name": "glm-5.1",
|
|
984
938
|
"variant": "fireworks",
|
|
@@ -1002,52 +956,9 @@
|
|
|
1002
956
|
}
|
|
1003
957
|
}
|
|
1004
958
|
},
|
|
1005
|
-
{
|
|
1006
|
-
"name": "glm-5.1",
|
|
1007
|
-
"variant": "ollama",
|
|
1008
|
-
"platform": {
|
|
1009
|
-
"name": "openai-compatible",
|
|
1010
|
-
"variant": "ollama"
|
|
1011
|
-
},
|
|
1012
|
-
"model": {
|
|
1013
|
-
"format": "openai-responses",
|
|
1014
|
-
"config": {
|
|
1015
|
-
"model": "glm-5:cloud"
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
},
|
|
1019
|
-
{
|
|
1020
|
-
"name": "glm-5.1",
|
|
1021
|
-
"variant": "huggingface",
|
|
1022
|
-
"platform": {
|
|
1023
|
-
"name": "openai-compatible",
|
|
1024
|
-
"variant": "huggingface"
|
|
1025
|
-
},
|
|
1026
|
-
"model": {
|
|
1027
|
-
"format": "openai-messages",
|
|
1028
|
-
"config": {
|
|
1029
|
-
"model": "zai-org/GLM-5.1:together"
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
},
|
|
1033
959
|
|
|
1034
960
|
{
|
|
1035
|
-
"name": "kimi-k2.
|
|
1036
|
-
"variant": "bedrock",
|
|
1037
|
-
"platform": {
|
|
1038
|
-
"name": "bedrock",
|
|
1039
|
-
"variant": "default"
|
|
1040
|
-
},
|
|
1041
|
-
"model": {
|
|
1042
|
-
"format": "openai-messages",
|
|
1043
|
-
"config": {
|
|
1044
|
-
"model": "moonshotai.kimi-k2.5",
|
|
1045
|
-
"reasoning_effort": "high"
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
},
|
|
1049
|
-
{
|
|
1050
|
-
"name": "kimi-k2.5",
|
|
961
|
+
"name": "kimi-k2.6",
|
|
1051
962
|
"variant": "fireworks",
|
|
1052
963
|
"platform": {
|
|
1053
964
|
"name": "openai-compatible",
|
|
@@ -1056,16 +967,16 @@
|
|
|
1056
967
|
"model": {
|
|
1057
968
|
"format": "openai-messages",
|
|
1058
969
|
"config": {
|
|
1059
|
-
"model": "accounts/fireworks/models/kimi-
|
|
970
|
+
"model": "accounts/fireworks/models/kimi-k2p6"
|
|
1060
971
|
}
|
|
1061
972
|
},
|
|
1062
973
|
"cost": {
|
|
1063
974
|
"currency": "USD",
|
|
1064
975
|
"unit": "1M",
|
|
1065
976
|
"costs": {
|
|
1066
|
-
"prompt_tokens": 0.
|
|
1067
|
-
"prompt_tokens_details.cached_tokens": -0.
|
|
1068
|
-
"completion_tokens":
|
|
977
|
+
"prompt_tokens": 0.95,
|
|
978
|
+
"prompt_tokens_details.cached_tokens": -0.79,
|
|
979
|
+
"completion_tokens": 4
|
|
1069
980
|
}
|
|
1070
981
|
}
|
|
1071
982
|
},
|
|
@@ -1085,21 +996,6 @@
|
|
|
1085
996
|
}
|
|
1086
997
|
}
|
|
1087
998
|
},
|
|
1088
|
-
{
|
|
1089
|
-
"name": "deepseek-v3.2",
|
|
1090
|
-
"variant": "bedrock",
|
|
1091
|
-
"platform": {
|
|
1092
|
-
"name": "bedrock",
|
|
1093
|
-
"variant": "default"
|
|
1094
|
-
},
|
|
1095
|
-
"model": {
|
|
1096
|
-
"format": "openai-messages",
|
|
1097
|
-
"config": {
|
|
1098
|
-
"model": "deepseek.v3.2",
|
|
1099
|
-
"reasoning_effort": "high"
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
},
|
|
1103
999
|
{
|
|
1104
1000
|
"name": "deepseek-v3.2",
|
|
1105
1001
|
"variant": "fireworks",
|
|
@@ -1123,23 +1019,9 @@
|
|
|
1123
1019
|
}
|
|
1124
1020
|
}
|
|
1125
1021
|
},
|
|
1022
|
+
|
|
1126
1023
|
{
|
|
1127
|
-
"name": "minimax-m2.
|
|
1128
|
-
"variant": "bedrock",
|
|
1129
|
-
"platform": {
|
|
1130
|
-
"name": "bedrock",
|
|
1131
|
-
"variant": "default"
|
|
1132
|
-
},
|
|
1133
|
-
"model": {
|
|
1134
|
-
"format": "openai-messages",
|
|
1135
|
-
"config": {
|
|
1136
|
-
"model": "minimax.minimax-m2.1",
|
|
1137
|
-
"reasoning_effort": "high"
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
},
|
|
1141
|
-
{
|
|
1142
|
-
"name": "minimax-m2.5",
|
|
1024
|
+
"name": "minimax-m2.7",
|
|
1143
1025
|
"variant": "fireworks",
|
|
1144
1026
|
"platform": {
|
|
1145
1027
|
"name": "openai-compatible",
|
|
@@ -1148,7 +1030,7 @@
|
|
|
1148
1030
|
"model": {
|
|
1149
1031
|
"format": "openai-messages",
|
|
1150
1032
|
"config": {
|
|
1151
|
-
"model": "accounts/fireworks/models/minimax-
|
|
1033
|
+
"model": "accounts/fireworks/models/minimax-m2p7"
|
|
1152
1034
|
}
|
|
1153
1035
|
},
|
|
1154
1036
|
"cost": {
|
|
@@ -1162,21 +1044,6 @@
|
|
|
1162
1044
|
}
|
|
1163
1045
|
},
|
|
1164
1046
|
|
|
1165
|
-
{
|
|
1166
|
-
"name": "minimax-m2.7",
|
|
1167
|
-
"variant": "ollama",
|
|
1168
|
-
"platform": {
|
|
1169
|
-
"name": "openai-compatible",
|
|
1170
|
-
"variant": "ollama"
|
|
1171
|
-
},
|
|
1172
|
-
"model": {
|
|
1173
|
-
"format": "openai-responses",
|
|
1174
|
-
"config": {
|
|
1175
|
-
"model": "minimax-m2.7:cloud"
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
},
|
|
1179
|
-
|
|
1180
1047
|
{
|
|
1181
1048
|
"name": "qwen3-next",
|
|
1182
1049
|
"variant": "vertex-ai",
|
|
@@ -1215,35 +1082,6 @@
|
|
|
1215
1082
|
}
|
|
1216
1083
|
},
|
|
1217
1084
|
|
|
1218
|
-
{
|
|
1219
|
-
"name": "gemma4",
|
|
1220
|
-
"variant": "ollama",
|
|
1221
|
-
"platform": {
|
|
1222
|
-
"name": "openai-compatible",
|
|
1223
|
-
"variant": "ollama"
|
|
1224
|
-
},
|
|
1225
|
-
"model": {
|
|
1226
|
-
"format": "openai-responses",
|
|
1227
|
-
"config": {
|
|
1228
|
-
"model": "gemma4:31b-cloud"
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
},
|
|
1232
|
-
{
|
|
1233
|
-
"name": "gemma4",
|
|
1234
|
-
"variant": "huggingface",
|
|
1235
|
-
"platform": {
|
|
1236
|
-
"name": "openai-compatible",
|
|
1237
|
-
"variant": "huggingface"
|
|
1238
|
-
},
|
|
1239
|
-
"model": {
|
|
1240
|
-
"format": "openai-messages",
|
|
1241
|
-
"config": {
|
|
1242
|
-
"model": "google/gemma-4-31B-it:together"
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
},
|
|
1246
|
-
|
|
1247
1085
|
{
|
|
1248
1086
|
"name": "nova-2-lite",
|
|
1249
1087
|
"variant": "bedrock",
|
package/package.json
CHANGED
package/src/cliArgs.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @typedef {HelpSubcommand | InteractiveSubcommand | BatchSubcommand | ListModelsSubcommand | InstallClaudeCodePluginsSubcommand} Subcommand
|
|
2
|
+
* @typedef {HelpSubcommand | InteractiveSubcommand | BatchSubcommand | ListModelsSubcommand | InstallClaudeCodePluginsSubcommand | CostSubcommand} Subcommand
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
* @typedef {{ type: 'install-claude-code-plugins' }} InstallClaudeCodePluginsSubcommand
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {{ type: 'cost', from: string | null, to: string | null }} CostSubcommand
|
|
27
|
+
*/
|
|
28
|
+
|
|
25
29
|
/**
|
|
26
30
|
* @typedef {Object} CliArgs
|
|
27
31
|
* @property {Subcommand} subcommand - The subcommand to execute
|
|
@@ -106,6 +110,28 @@ export function parseCliArgs(argv) {
|
|
|
106
110
|
};
|
|
107
111
|
}
|
|
108
112
|
|
|
113
|
+
if (subcommandName === "cost") {
|
|
114
|
+
const costArgs = args.slice(1);
|
|
115
|
+
let from = null;
|
|
116
|
+
let to = null;
|
|
117
|
+
for (let i = 0; i < costArgs.length; i++) {
|
|
118
|
+
if (costArgs[i] === "--from") {
|
|
119
|
+
if (costArgs[i + 1]) {
|
|
120
|
+
from = costArgs[i + 1];
|
|
121
|
+
i++;
|
|
122
|
+
}
|
|
123
|
+
} else if (costArgs[i] === "--to") {
|
|
124
|
+
if (costArgs[i + 1]) {
|
|
125
|
+
to = costArgs[i + 1];
|
|
126
|
+
i++;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
subcommand: { type: "cost", from, to },
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
109
135
|
return {
|
|
110
136
|
subcommand: { type: "help" },
|
|
111
137
|
};
|
|
@@ -119,6 +145,7 @@ export function printHelp(exitCode = 0) {
|
|
|
119
145
|
console.log(`
|
|
120
146
|
Usage: plain [options]
|
|
121
147
|
plain batch [options] <task>
|
|
148
|
+
plain cost [--from YYYY-MM-DD] [--to YYYY-MM-DD]
|
|
122
149
|
plain list-models
|
|
123
150
|
plain install-claude-code-plugins
|
|
124
151
|
|
|
@@ -131,6 +158,9 @@ Subcommands:
|
|
|
131
158
|
batch <task> Run in batch mode with the given task instruction.
|
|
132
159
|
Config files are NOT auto-loaded in batch mode;
|
|
133
160
|
use -c to specify config files explicitly.
|
|
161
|
+
cost Show aggregated token cost per day for a period.
|
|
162
|
+
Defaults to the first day of the current month
|
|
163
|
+
through today.
|
|
134
164
|
list-models List available models
|
|
135
165
|
install-claude-code-plugins Install Claude Code plugins
|
|
136
166
|
|
package/src/cliBatch.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { formatCostForBatch } from "./cliFormatter.mjs";
|
|
6
|
+
import { appendUsageRecord, buildUsageRecord } from "./usageStore.mjs";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* @typedef {object} BatchSessionOptions
|
|
@@ -46,6 +47,27 @@ export async function startBatchSession({
|
|
|
46
47
|
timestamp: new Date().toISOString(),
|
|
47
48
|
cost: formatCostForBatch(costSummary),
|
|
48
49
|
});
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const record = buildUsageRecord({
|
|
53
|
+
sessionId,
|
|
54
|
+
mode: "batch",
|
|
55
|
+
modelName,
|
|
56
|
+
workingDir: process.cwd(),
|
|
57
|
+
costSummary,
|
|
58
|
+
});
|
|
59
|
+
if (record) {
|
|
60
|
+
await appendUsageRecord(record);
|
|
61
|
+
}
|
|
62
|
+
} catch (err) {
|
|
63
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
64
|
+
outputEvent({
|
|
65
|
+
type: "error",
|
|
66
|
+
error: { message: `failed to record usage: ${message}` },
|
|
67
|
+
timestamp: new Date().toISOString(),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
49
71
|
await onStop();
|
|
50
72
|
resolve();
|
|
51
73
|
});
|