@iinm/plain-agent 1.14.3 → 1.14.4
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 +30 -32
- package/config/config.predefined.json +138 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Plain Agent
|
|
2
2
|
|
|
3
3
|
[](https://github.com/iinm/plain-agent/actions/workflows/github-code-scanning/codeql)
|
|
4
|
-
[](https://socket.dev/npm/package/@iinm/plain-agent)
|
|
5
5
|
[](https://packagephobia.com/result?p=@iinm/plain-agent)
|
|
6
6
|
|
|
7
7
|
A lightweight terminal-based coding agent focused on safety and low token cost
|
|
@@ -34,15 +34,15 @@ Supports Claude, OpenAI, Gemini, and any OpenAI-compatible provider. Bedrock, Ve
|
|
|
34
34
|
|
|
35
35
|
Each model definition has two independent parts:
|
|
36
36
|
|
|
37
|
-
- **`platform
|
|
38
|
-
- **`model.format
|
|
37
|
+
- **`platform`**: where to send the request and how to authenticate (Anthropic, Bedrock, Vertex AI, Azure, etc.)
|
|
38
|
+
- **`model.format`**: which API format to use (`anthropic`, `gemini`, `openai-responses`, `openai-messages`, `bedrock-converse`)
|
|
39
39
|
|
|
40
40
|
Because these are separate, the same API format works across different platforms. For example, Claude models use the `anthropic` format whether you call Anthropic directly or through Bedrock.
|
|
41
41
|
|
|
42
42
|
```js
|
|
43
43
|
// Anthropic direct
|
|
44
44
|
{
|
|
45
|
-
"name": "claude-sonnet-
|
|
45
|
+
"name": "claude-sonnet-5",
|
|
46
46
|
"variant": "thinking-high",
|
|
47
47
|
"platform": {
|
|
48
48
|
"name": "anthropic",
|
|
@@ -51,7 +51,7 @@ Because these are separate, the same API format works across different platforms
|
|
|
51
51
|
"model": {
|
|
52
52
|
"format": "anthropic",
|
|
53
53
|
"config": {
|
|
54
|
-
"model": "claude-sonnet-
|
|
54
|
+
"model": "claude-sonnet-5",
|
|
55
55
|
"max_tokens": 32768,
|
|
56
56
|
"thinking": { "type": "adaptive" },
|
|
57
57
|
"output_config": { "effort": "high" }
|
|
@@ -59,9 +59,9 @@ Because these are separate, the same API format works across different platforms
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
// Bedrock
|
|
62
|
+
// Bedrock: same format, different platform
|
|
63
63
|
{
|
|
64
|
-
"name": "claude-sonnet-
|
|
64
|
+
"name": "claude-sonnet-5",
|
|
65
65
|
"variant": "thinking-high-bedrock-jp",
|
|
66
66
|
"platform": {
|
|
67
67
|
"name": "bedrock",
|
|
@@ -70,7 +70,7 @@ Because these are separate, the same API format works across different platforms
|
|
|
70
70
|
"model": {
|
|
71
71
|
"format": "anthropic",
|
|
72
72
|
"config": {
|
|
73
|
-
"model": "jp.anthropic.claude-sonnet-
|
|
73
|
+
"model": "jp.anthropic.claude-sonnet-5",
|
|
74
74
|
"max_tokens": 32768,
|
|
75
75
|
"thinking": { "type": "adaptive" },
|
|
76
76
|
"output_config": { "effort": "high" }
|
|
@@ -79,7 +79,7 @@ Because these are separate, the same API format works across different platforms
|
|
|
79
79
|
}
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
Models are identified by `name+variant` (e.g., `claude-sonnet-
|
|
82
|
+
Models are identified by `name+variant` (e.g., `claude-sonnet-5+thinking-high`). You can define multiple variants of the same model with different settings, such as thinking budget or region.
|
|
83
83
|
|
|
84
84
|
You can also add entries to `platforms` and `models` to use any OpenAI-compatible endpoint, such as Ollama or Fireworks. See the Quick Start section for examples.
|
|
85
85
|
|
|
@@ -87,7 +87,7 @@ You can also add entries to `platforms` and `models` to use any OpenAI-compatibl
|
|
|
87
87
|
|
|
88
88
|
Configure what the agent can do automatically using a small DSL with regex matching. Below is an excerpt from the [default config](https://github.com/iinm/plain-agent/blob/main/config/config.predefined.json).
|
|
89
89
|
|
|
90
|
-
**Note**: Commands are executed without a shell
|
|
90
|
+
**Note**: Commands are executed without a shell. Shell operators like `|`, `>`, `;`, and `&&` are not interpreted unless the agent explicitly uses `bash -c`. This makes each argument a discrete token that can be validated individually.
|
|
91
91
|
|
|
92
92
|
```js
|
|
93
93
|
{
|
|
@@ -98,7 +98,7 @@ Configure what the agent can do automatically using a small DSL with regex match
|
|
|
98
98
|
// Patterns are evaluated top-to-bottom; first match wins
|
|
99
99
|
"patterns": [
|
|
100
100
|
// fd example:
|
|
101
|
-
// Ask for approval when risky
|
|
101
|
+
// Ask for approval when risky flag like --exec is present
|
|
102
102
|
{
|
|
103
103
|
"toolName": "exec_command",
|
|
104
104
|
"input": {
|
|
@@ -157,14 +157,14 @@ Configure what the agent can do automatically using a small DSL with regex match
|
|
|
157
157
|
|
|
158
158
|
### Path Validation
|
|
159
159
|
|
|
160
|
-
String values in tool inputs are treated as file paths and validated against these rules. This takes precedence over `autoApproval
|
|
160
|
+
String values in tool inputs are treated as file paths and validated against these rules. This takes precedence over `autoApproval`: even if a pattern marks an action as `allow`, a validation failure falls back to `defaultAction`.
|
|
161
161
|
|
|
162
162
|
- The path must be under the working directory or a path listed in `autoApproval.allowedPaths`
|
|
163
163
|
- No directory traversal (`..` is not allowed)
|
|
164
|
-
- Symlinks are resolved to their real path before validation
|
|
164
|
+
- Symlinks are resolved to their real path before validation: a symlink inside the working directory that points outside is rejected. Broken and circular symlinks are also rejected.
|
|
165
165
|
- The file must be tracked by Git (not ignored)
|
|
166
166
|
|
|
167
|
-
Compound arguments are decomposed before validation
|
|
167
|
+
Compound arguments are decomposed before validation; embedded paths are extracted and checked individually:
|
|
168
168
|
|
|
169
169
|
| Pattern | Example | Extracted |
|
|
170
170
|
|---|---|---|
|
|
@@ -174,9 +174,7 @@ Compound arguments are decomposed before validation — embedded paths are extra
|
|
|
174
174
|
| `VAR=<val>` | `OUTPUT=/etc/passwd` | `/etc/passwd` |
|
|
175
175
|
| `proto://…` | `file:///etc/passwd` | `/etc/passwd` (only `file:` is treated as a local path; `http(s)://` URLs are always allowed) |
|
|
176
176
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
**Note**: Validation only applies when the agent explicitly passes file paths to tools. It cannot catch file access inside scripts the agent writes — something like `bash -c "rm -rf /"` is beyond its reach. Always use a sandbox when auto-approving script execution.
|
|
177
|
+
**Note**: Validation only applies when the agent explicitly passes file paths to tools. It cannot catch file access inside scripts the agent writes: something like `bash -c "rm -rf /"` is beyond its reach. Always use a sandbox when auto-approving script execution.
|
|
180
178
|
|
|
181
179
|
### Sandbox
|
|
182
180
|
|
|
@@ -219,24 +217,24 @@ A Docker-based wrapper called `plain-sandbox` is included, but the interface is
|
|
|
219
217
|
|
|
220
218
|
The agent maintains a memory file (`.plain-agent/memory/`) for each session to:
|
|
221
219
|
|
|
222
|
-
- Keep task state human-readable
|
|
223
|
-
- Resume cleanly
|
|
224
|
-
- Pass information between dependent tasks
|
|
220
|
+
- Keep task state human-readable: you can open the file to see exactly where things stand.
|
|
221
|
+
- Resume cleanly: the agent can restart a task from the memory file with a clean context.
|
|
222
|
+
- Pass information between dependent tasks: subagents write their results to the memory file, which the main agent or a follow-up session reads to continue.
|
|
225
223
|
|
|
226
224
|
### Token Efficiency
|
|
227
225
|
|
|
228
226
|
A few design choices keep token usage low:
|
|
229
227
|
|
|
230
|
-
- Minimal system prompt
|
|
231
|
-
- Output truncation
|
|
232
|
-
- Context compaction
|
|
233
|
-
- MCP tool filtering
|
|
228
|
+
- Minimal system prompt: the [system prompt](https://github.com/iinm/plain-agent/blob/main/src/prompt.mjs) contains only what the agent needs to function.
|
|
229
|
+
- Output truncation: when a command or MCP tool produces large output, it is truncated and saved to a file. The agent can then read only the relevant parts.
|
|
230
|
+
- Context compaction: run `/compact` to discard old messages and reload task state from a memory file. This also happens automatically when input tokens exceed a configurable soft limit.
|
|
231
|
+
- MCP tool filtering: MCP servers often expose many tools. Use `enabledTools` in the server config to enable only the ones you need, which reduces the number of tool definitions sent to the model.
|
|
234
232
|
|
|
235
233
|
### Claude Code Compatibility
|
|
236
234
|
|
|
237
235
|
Claude Code has a plugin ecosystem and is widely used across teams. plain-agent supports `.claude/` commands, subagents, and skills so you can share project skills with Claude Code users. Plugins can also be installed.
|
|
238
236
|
|
|
239
|
-
**Limitation:** Subagents run sequentially, not in parallel. The upside is that their activity is fully observable and they don't spike token usage. They also inherit the main context rather than starting fresh
|
|
237
|
+
**Limitation:** Subagents run sequentially, not in parallel. The upside is that their activity is fully observable and they don't spike token usage. They also inherit the main context rather than starting fresh, a simplification chosen for ease of implementation, which also avoids redundant file reads and reduces the chance of losing context between handoffs.
|
|
240
238
|
|
|
241
239
|
## Requirements
|
|
242
240
|
|
|
@@ -263,7 +261,7 @@ Create a configuration file.
|
|
|
263
261
|
// ~/.config/plain-agent/config.local.json
|
|
264
262
|
{
|
|
265
263
|
// Set default model
|
|
266
|
-
"model": "claude-sonnet-
|
|
264
|
+
"model": "claude-sonnet-5+thinking-high",
|
|
267
265
|
|
|
268
266
|
// Configure the providers you want to use
|
|
269
267
|
"platforms": [
|
|
@@ -466,7 +464,7 @@ Create a configuration file.
|
|
|
466
464
|
}
|
|
467
465
|
},
|
|
468
466
|
{
|
|
469
|
-
"name": "claude-sonnet-
|
|
467
|
+
"name": "claude-sonnet-5",
|
|
470
468
|
"variant": "thinking-high-bedrock-jp",
|
|
471
469
|
"platform": {
|
|
472
470
|
"name": "bedrock",
|
|
@@ -475,7 +473,7 @@ Create a configuration file.
|
|
|
475
473
|
"model": {
|
|
476
474
|
"format": "anthropic",
|
|
477
475
|
"config": {
|
|
478
|
-
"model": "jp.anthropic.claude-sonnet-
|
|
476
|
+
"model": "jp.anthropic.claude-sonnet-5",
|
|
479
477
|
"max_tokens": 32768,
|
|
480
478
|
"thinking": { "type": "adaptive" },
|
|
481
479
|
"output_config": { "effort": "high" }
|
|
@@ -562,10 +560,10 @@ Arguments before `--` are flags for the `plain` CLI itself (e.g. `-c` to load a
|
|
|
562
560
|
config file). Arguments after `--` are passed through to the sandbox command as-is.
|
|
563
561
|
|
|
564
562
|
```sh
|
|
565
|
-
plain sandbox -- --tty zsh
|
|
563
|
+
plain sandbox -- --allow-net 0.0.0.0/0 --tty --verbose zsh
|
|
566
564
|
|
|
567
565
|
# Or specify a config file explicitly
|
|
568
|
-
plain sandbox -c .plain-agent/config.sandbox.json -- --tty zsh
|
|
566
|
+
plain sandbox -c .plain-agent/config.sandbox.json -- --allow-net 0.0.0.0/0 --tty --verbose zsh
|
|
569
567
|
```
|
|
570
568
|
|
|
571
569
|
## Configuration
|
|
@@ -589,7 +587,7 @@ Files are loaded in the following order. Settings in later files override earlie
|
|
|
589
587
|
|
|
590
588
|
|
|
591
589
|
<details>
|
|
592
|
-
<summary><b>Minimal example (file editing and web search only
|
|
590
|
+
<summary><b>Minimal example (file editing and web search only, no script execution, no sandbox required)</b></summary>
|
|
593
591
|
|
|
594
592
|
```js
|
|
595
593
|
{
|
|
@@ -768,7 +766,7 @@ Files are loaded in the following order. Settings in later files override earlie
|
|
|
768
766
|
"softLimit": 120000,
|
|
769
767
|
// Optional: override per model (prefix match on name+variant)
|
|
770
768
|
"softLimitPerModelPrefix": {
|
|
771
|
-
"
|
|
769
|
+
"claude-sonnet-5": 120000
|
|
772
770
|
}
|
|
773
771
|
},
|
|
774
772
|
|
|
@@ -607,6 +607,76 @@
|
|
|
607
607
|
]
|
|
608
608
|
}
|
|
609
609
|
},
|
|
610
|
+
{
|
|
611
|
+
"name": "claude-sonnet-5",
|
|
612
|
+
"variant": "thinking-high",
|
|
613
|
+
"platform": {
|
|
614
|
+
"name": "anthropic",
|
|
615
|
+
"variant": "default",
|
|
616
|
+
"baseURL": "https://api.anthropic.com"
|
|
617
|
+
},
|
|
618
|
+
"model": {
|
|
619
|
+
"format": "anthropic",
|
|
620
|
+
"config": {
|
|
621
|
+
"model": "claude-sonnet-5",
|
|
622
|
+
"max_tokens": 32768,
|
|
623
|
+
"thinking": { "type": "adaptive" },
|
|
624
|
+
"output_config": { "effort": "high" }
|
|
625
|
+
}
|
|
626
|
+
},
|
|
627
|
+
"cost": {
|
|
628
|
+
"currency": "USD",
|
|
629
|
+
"unit": "1M",
|
|
630
|
+
"prices": {
|
|
631
|
+
"input_tokens": 3,
|
|
632
|
+
"output_tokens": 15,
|
|
633
|
+
"cache_read_input_tokens": 0.3,
|
|
634
|
+
"cache_creation_input_tokens": 3.75
|
|
635
|
+
}
|
|
636
|
+
},
|
|
637
|
+
"autoCompact": {
|
|
638
|
+
"inputTokensKeys": [
|
|
639
|
+
"input_tokens",
|
|
640
|
+
"cache_read_input_tokens",
|
|
641
|
+
"cache_creation_input_tokens"
|
|
642
|
+
]
|
|
643
|
+
}
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
"name": "claude-sonnet-5",
|
|
647
|
+
"variant": "thinking-max",
|
|
648
|
+
"platform": {
|
|
649
|
+
"name": "anthropic",
|
|
650
|
+
"variant": "default",
|
|
651
|
+
"baseURL": "https://api.anthropic.com"
|
|
652
|
+
},
|
|
653
|
+
"model": {
|
|
654
|
+
"format": "anthropic",
|
|
655
|
+
"config": {
|
|
656
|
+
"model": "claude-sonnet-5",
|
|
657
|
+
"max_tokens": 64000,
|
|
658
|
+
"thinking": { "type": "adaptive" },
|
|
659
|
+
"output_config": { "effort": "max" }
|
|
660
|
+
}
|
|
661
|
+
},
|
|
662
|
+
"cost": {
|
|
663
|
+
"currency": "USD",
|
|
664
|
+
"unit": "1M",
|
|
665
|
+
"prices": {
|
|
666
|
+
"input_tokens": 3,
|
|
667
|
+
"output_tokens": 15,
|
|
668
|
+
"cache_read_input_tokens": 0.3,
|
|
669
|
+
"cache_creation_input_tokens": 3.75
|
|
670
|
+
}
|
|
671
|
+
},
|
|
672
|
+
"autoCompact": {
|
|
673
|
+
"inputTokensKeys": [
|
|
674
|
+
"input_tokens",
|
|
675
|
+
"cache_read_input_tokens",
|
|
676
|
+
"cache_creation_input_tokens"
|
|
677
|
+
]
|
|
678
|
+
}
|
|
679
|
+
},
|
|
610
680
|
{
|
|
611
681
|
"name": "claude-opus-4-8",
|
|
612
682
|
"variant": "thinking-high",
|
|
@@ -882,6 +952,74 @@
|
|
|
882
952
|
]
|
|
883
953
|
}
|
|
884
954
|
},
|
|
955
|
+
{
|
|
956
|
+
"name": "claude-sonnet-5",
|
|
957
|
+
"variant": "thinking-high-bedrock",
|
|
958
|
+
"platform": {
|
|
959
|
+
"name": "bedrock",
|
|
960
|
+
"variant": "default"
|
|
961
|
+
},
|
|
962
|
+
"model": {
|
|
963
|
+
"format": "anthropic",
|
|
964
|
+
"config": {
|
|
965
|
+
"model": "global.anthropic.claude-sonnet-5",
|
|
966
|
+
"max_tokens": 32768,
|
|
967
|
+
"thinking": { "type": "adaptive" },
|
|
968
|
+
"output_config": { "effort": "high" }
|
|
969
|
+
}
|
|
970
|
+
},
|
|
971
|
+
"cost": {
|
|
972
|
+
"currency": "USD",
|
|
973
|
+
"unit": "1M",
|
|
974
|
+
"prices": {
|
|
975
|
+
"input_tokens": 3,
|
|
976
|
+
"output_tokens": 15,
|
|
977
|
+
"cache_read_input_tokens": 0.3,
|
|
978
|
+
"cache_creation_input_tokens": 3.75
|
|
979
|
+
}
|
|
980
|
+
},
|
|
981
|
+
"autoCompact": {
|
|
982
|
+
"inputTokensKeys": [
|
|
983
|
+
"input_tokens",
|
|
984
|
+
"cache_read_input_tokens",
|
|
985
|
+
"cache_creation_input_tokens"
|
|
986
|
+
]
|
|
987
|
+
}
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
"name": "claude-sonnet-5",
|
|
991
|
+
"variant": "thinking-max-bedrock",
|
|
992
|
+
"platform": {
|
|
993
|
+
"name": "bedrock",
|
|
994
|
+
"variant": "default"
|
|
995
|
+
},
|
|
996
|
+
"model": {
|
|
997
|
+
"format": "anthropic",
|
|
998
|
+
"config": {
|
|
999
|
+
"model": "global.anthropic.claude-sonnet-5",
|
|
1000
|
+
"max_tokens": 64000,
|
|
1001
|
+
"thinking": { "type": "adaptive" },
|
|
1002
|
+
"output_config": { "effort": "max" }
|
|
1003
|
+
}
|
|
1004
|
+
},
|
|
1005
|
+
"cost": {
|
|
1006
|
+
"currency": "USD",
|
|
1007
|
+
"unit": "1M",
|
|
1008
|
+
"prices": {
|
|
1009
|
+
"input_tokens": 3,
|
|
1010
|
+
"output_tokens": 15,
|
|
1011
|
+
"cache_read_input_tokens": 0.3,
|
|
1012
|
+
"cache_creation_input_tokens": 3.75
|
|
1013
|
+
}
|
|
1014
|
+
},
|
|
1015
|
+
"autoCompact": {
|
|
1016
|
+
"inputTokensKeys": [
|
|
1017
|
+
"input_tokens",
|
|
1018
|
+
"cache_read_input_tokens",
|
|
1019
|
+
"cache_creation_input_tokens"
|
|
1020
|
+
]
|
|
1021
|
+
}
|
|
1022
|
+
},
|
|
885
1023
|
{
|
|
886
1024
|
"name": "claude-opus-4-8",
|
|
887
1025
|
"variant": "thinking-high-bedrock",
|