@iinm/plain-agent 1.10.14 → 1.10.16
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 +20 -10
- package/config/config.predefined.json +198 -3
- package/package.json +1 -1
- package/src/cli/args.mjs +2 -2
- package/src/cli/streamFormatter.mjs +3 -3
- package/src/main.mjs +4 -5
- package/src/providers/openaiCompatible.mjs +17 -1
package/README.md
CHANGED
|
@@ -103,28 +103,38 @@ Create the configuration.
|
|
|
103
103
|
```js
|
|
104
104
|
{
|
|
105
105
|
"platforms": [
|
|
106
|
+
// Bedrock: Requires AWS CLI to get credentials
|
|
106
107
|
{
|
|
107
|
-
// Requires Azure CLI to get access token
|
|
108
|
-
"name": "azure",
|
|
109
|
-
"variant": "openai",
|
|
110
|
-
"baseURL": "https://<resource>.openai.azure.com/openai",
|
|
111
|
-
// Optional
|
|
112
|
-
"azureConfigDir": "/home/xxx/.azure-for-agent"
|
|
113
|
-
},
|
|
114
|
-
{
|
|
115
|
-
// Requires AWS CLI to get credentials
|
|
116
108
|
"name": "bedrock",
|
|
117
109
|
"variant": "default",
|
|
118
110
|
"baseURL": "https://bedrock-runtime.<region>.amazonaws.com",
|
|
119
111
|
"awsProfile": "<AWS_PROFILE>"
|
|
120
112
|
},
|
|
113
|
+
|
|
114
|
+
// Vertex AI: Requires gcloud CLI to get authentication token
|
|
121
115
|
{
|
|
122
|
-
// Requires gcloud CLI to get authentication token
|
|
123
116
|
"name": "vertex-ai",
|
|
124
117
|
"variant": "default",
|
|
125
118
|
"baseURL": "https://aiplatform.googleapis.com/v1beta1/projects/<project>/locations/<location>",
|
|
126
119
|
// (Optional) Impersonate this service account to obtain an auth token
|
|
127
120
|
"account": "<SERVICE_ACCOUNT_EMAIL>"
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
// Azure: Requires Azure CLI to get access token
|
|
124
|
+
{
|
|
125
|
+
"name": "azure",
|
|
126
|
+
"variant": "default",
|
|
127
|
+
"baseURL": "https://<resource>.services.ai.azure.com",
|
|
128
|
+
// Optional
|
|
129
|
+
"azureConfigDir": "/home/xxx/.azure-for-agent"
|
|
130
|
+
},
|
|
131
|
+
// Azure OpenAI
|
|
132
|
+
{
|
|
133
|
+
"name": "azure",
|
|
134
|
+
"variant": "openai",
|
|
135
|
+
"baseURL": "https://<resource>.openai.azure.com/openai",
|
|
136
|
+
// Optional
|
|
137
|
+
"azureConfigDir": "/home/xxx/.azure-for-agent"
|
|
128
138
|
}
|
|
129
139
|
]
|
|
130
140
|
}
|
|
@@ -916,7 +916,7 @@
|
|
|
916
916
|
},
|
|
917
917
|
|
|
918
918
|
{
|
|
919
|
-
"name": "gpt-5.
|
|
919
|
+
"name": "gpt-5.4-mini",
|
|
920
920
|
"variant": "thinking-medium-azure",
|
|
921
921
|
"platform": {
|
|
922
922
|
"name": "azure",
|
|
@@ -925,8 +925,149 @@
|
|
|
925
925
|
"model": {
|
|
926
926
|
"format": "openai-responses",
|
|
927
927
|
"config": {
|
|
928
|
-
"model": "gpt-5.
|
|
929
|
-
"reasoning": { "effort": "medium", "summary": "auto" }
|
|
928
|
+
"model": "gpt-5.4-mini",
|
|
929
|
+
"reasoning": { "effort": "medium", "summary": "auto" },
|
|
930
|
+
"store": false,
|
|
931
|
+
"include": ["reasoning.encrypted_content"]
|
|
932
|
+
}
|
|
933
|
+
},
|
|
934
|
+
"cost": {
|
|
935
|
+
"currency": "USD",
|
|
936
|
+
"unit": "1M",
|
|
937
|
+
"costs": {
|
|
938
|
+
"input_tokens": 0.75,
|
|
939
|
+
"input_tokens_details.cached_tokens": -0.675,
|
|
940
|
+
"output_tokens": 4.5
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
},
|
|
944
|
+
{
|
|
945
|
+
"name": "gpt-5.4-mini",
|
|
946
|
+
"variant": "thinking-high-azure",
|
|
947
|
+
"platform": {
|
|
948
|
+
"name": "azure",
|
|
949
|
+
"variant": "openai"
|
|
950
|
+
},
|
|
951
|
+
"model": {
|
|
952
|
+
"format": "openai-responses",
|
|
953
|
+
"config": {
|
|
954
|
+
"model": "gpt-5.4-mini",
|
|
955
|
+
"reasoning": { "effort": "high", "summary": "auto" },
|
|
956
|
+
"store": false,
|
|
957
|
+
"include": ["reasoning.encrypted_content"]
|
|
958
|
+
}
|
|
959
|
+
},
|
|
960
|
+
"cost": {
|
|
961
|
+
"currency": "USD",
|
|
962
|
+
"unit": "1M",
|
|
963
|
+
"costs": {
|
|
964
|
+
"input_tokens": 0.75,
|
|
965
|
+
"input_tokens_details.cached_tokens": -0.675,
|
|
966
|
+
"output_tokens": 4.5
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
},
|
|
970
|
+
{
|
|
971
|
+
"name": "gpt-5.4-mini",
|
|
972
|
+
"variant": "thinking-xhigh-azure",
|
|
973
|
+
"platform": {
|
|
974
|
+
"name": "azure",
|
|
975
|
+
"variant": "openai"
|
|
976
|
+
},
|
|
977
|
+
"model": {
|
|
978
|
+
"format": "openai-responses",
|
|
979
|
+
"config": {
|
|
980
|
+
"model": "gpt-5.4-mini",
|
|
981
|
+
"reasoning": { "effort": "xhigh", "summary": "auto" },
|
|
982
|
+
"store": false,
|
|
983
|
+
"include": ["reasoning.encrypted_content"]
|
|
984
|
+
}
|
|
985
|
+
},
|
|
986
|
+
"cost": {
|
|
987
|
+
"currency": "USD",
|
|
988
|
+
"unit": "1M",
|
|
989
|
+
"costs": {
|
|
990
|
+
"input_tokens": 0.75,
|
|
991
|
+
"input_tokens_details.cached_tokens": -0.675,
|
|
992
|
+
"output_tokens": 4.5
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
"name": "gpt-5.5",
|
|
998
|
+
"variant": "thinking-medium-azure",
|
|
999
|
+
"platform": {
|
|
1000
|
+
"name": "azure",
|
|
1001
|
+
"variant": "openai"
|
|
1002
|
+
},
|
|
1003
|
+
"model": {
|
|
1004
|
+
"format": "openai-responses",
|
|
1005
|
+
"config": {
|
|
1006
|
+
"model": "gpt-5.5",
|
|
1007
|
+
"reasoning": { "effort": "medium", "summary": "auto" },
|
|
1008
|
+
"store": false,
|
|
1009
|
+
"include": ["reasoning.encrypted_content"]
|
|
1010
|
+
}
|
|
1011
|
+
},
|
|
1012
|
+
"cost": {
|
|
1013
|
+
"currency": "USD",
|
|
1014
|
+
"unit": "1M",
|
|
1015
|
+
"costs": {
|
|
1016
|
+
"input_tokens": 5,
|
|
1017
|
+
"input_tokens_details.cached_tokens": -4.5,
|
|
1018
|
+
"output_tokens": 30
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
"name": "gpt-5.5",
|
|
1024
|
+
"variant": "thinking-high-azure",
|
|
1025
|
+
"platform": {
|
|
1026
|
+
"name": "azure",
|
|
1027
|
+
"variant": "openai"
|
|
1028
|
+
},
|
|
1029
|
+
"model": {
|
|
1030
|
+
"format": "openai-responses",
|
|
1031
|
+
"config": {
|
|
1032
|
+
"model": "gpt-5.5",
|
|
1033
|
+
"reasoning": { "effort": "high", "summary": "auto" },
|
|
1034
|
+
"store": false,
|
|
1035
|
+
"include": ["reasoning.encrypted_content"]
|
|
1036
|
+
}
|
|
1037
|
+
},
|
|
1038
|
+
"cost": {
|
|
1039
|
+
"currency": "USD",
|
|
1040
|
+
"unit": "1M",
|
|
1041
|
+
"costs": {
|
|
1042
|
+
"input_tokens": 5,
|
|
1043
|
+
"input_tokens_details.cached_tokens": -4.5,
|
|
1044
|
+
"output_tokens": 30
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
"name": "gpt-5.5",
|
|
1050
|
+
"variant": "thinking-xhigh-azure",
|
|
1051
|
+
"platform": {
|
|
1052
|
+
"name": "azure",
|
|
1053
|
+
"variant": "openai"
|
|
1054
|
+
},
|
|
1055
|
+
"model": {
|
|
1056
|
+
"format": "openai-responses",
|
|
1057
|
+
"config": {
|
|
1058
|
+
"model": "gpt-5.5",
|
|
1059
|
+
"reasoning": { "effort": "xhigh", "summary": "auto" },
|
|
1060
|
+
"store": false,
|
|
1061
|
+
"include": ["reasoning.encrypted_content"]
|
|
1062
|
+
}
|
|
1063
|
+
},
|
|
1064
|
+
"cost": {
|
|
1065
|
+
"currency": "USD",
|
|
1066
|
+
"unit": "1M",
|
|
1067
|
+
"costs": {
|
|
1068
|
+
"input_tokens": 5,
|
|
1069
|
+
"input_tokens_details.cached_tokens": -4.5,
|
|
1070
|
+
"output_tokens": 30
|
|
930
1071
|
}
|
|
931
1072
|
}
|
|
932
1073
|
},
|
|
@@ -978,6 +1119,30 @@
|
|
|
978
1119
|
}
|
|
979
1120
|
}
|
|
980
1121
|
},
|
|
1122
|
+
{
|
|
1123
|
+
"name": "glm-5",
|
|
1124
|
+
"variant": "bedrock",
|
|
1125
|
+
"platform": {
|
|
1126
|
+
"name": "bedrock",
|
|
1127
|
+
"variant": "default"
|
|
1128
|
+
},
|
|
1129
|
+
"model": {
|
|
1130
|
+
"format": "openai-messages",
|
|
1131
|
+
"config": {
|
|
1132
|
+
"model": "zai.glm-5",
|
|
1133
|
+
"reasoning_effort": "high"
|
|
1134
|
+
}
|
|
1135
|
+
},
|
|
1136
|
+
"cost": {
|
|
1137
|
+
"currency": "USD",
|
|
1138
|
+
"unit": "1M",
|
|
1139
|
+
"costs": {
|
|
1140
|
+
"prompt_tokens": 1,
|
|
1141
|
+
"completion_tokens": 3.2
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
},
|
|
1145
|
+
|
|
981
1146
|
{
|
|
982
1147
|
"name": "glm-5.1",
|
|
983
1148
|
"variant": "fireworks",
|
|
@@ -1071,6 +1236,21 @@
|
|
|
1071
1236
|
}
|
|
1072
1237
|
}
|
|
1073
1238
|
},
|
|
1239
|
+
{
|
|
1240
|
+
"name": "kimi-k2.6",
|
|
1241
|
+
"variant": "azure",
|
|
1242
|
+
"platform": {
|
|
1243
|
+
"name": "azure",
|
|
1244
|
+
"variant": "default"
|
|
1245
|
+
},
|
|
1246
|
+
"model": {
|
|
1247
|
+
"format": "openai-messages",
|
|
1248
|
+
"config": {
|
|
1249
|
+
"model": "Kimi-K2.6",
|
|
1250
|
+
"reasoning_effort": "high"
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
},
|
|
1074
1254
|
|
|
1075
1255
|
{
|
|
1076
1256
|
"name": "deepseek-v4-pro",
|
|
@@ -1118,6 +1298,21 @@
|
|
|
1118
1298
|
}
|
|
1119
1299
|
}
|
|
1120
1300
|
},
|
|
1301
|
+
{
|
|
1302
|
+
"name": "deepseek-v4-pro",
|
|
1303
|
+
"variant": "azure",
|
|
1304
|
+
"platform": {
|
|
1305
|
+
"name": "azure",
|
|
1306
|
+
"variant": "default"
|
|
1307
|
+
},
|
|
1308
|
+
"model": {
|
|
1309
|
+
"format": "openai-messages",
|
|
1310
|
+
"config": {
|
|
1311
|
+
"model": "DeepSeek-V4-Pro",
|
|
1312
|
+
"reasoning_effort": "high"
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
},
|
|
1121
1316
|
|
|
1122
1317
|
{
|
|
1123
1318
|
"name": "minimax-m2.7",
|
package/package.json
CHANGED
package/src/cli/args.mjs
CHANGED
|
@@ -184,7 +184,7 @@ export function printHelp(exitCode = 0) {
|
|
|
184
184
|
console.log(`
|
|
185
185
|
Usage: plain [options]
|
|
186
186
|
plain batch [options] <task>
|
|
187
|
-
plain resume [<sessionId>] [--list]
|
|
187
|
+
plain resume [<sessionId>] [--list]
|
|
188
188
|
plain cost [--from YYYY-MM-DD] [--to YYYY-MM-DD]
|
|
189
189
|
plain list-models
|
|
190
190
|
plain install-claude-code-plugins
|
|
@@ -210,7 +210,7 @@ Subcommands:
|
|
|
210
210
|
install-claude-code-plugins Install Claude Code plugins
|
|
211
211
|
|
|
212
212
|
Examples:
|
|
213
|
-
plain -m
|
|
213
|
+
plain -m claude-sonnet-4-6+thinking-high
|
|
214
214
|
plain batch \\
|
|
215
215
|
-c ~/.config/plain-agent/config.local.json \\
|
|
216
216
|
-c .plain-agent/config.json \\
|
|
@@ -15,12 +15,12 @@ import { applyInlineMarkdown, formatMarkdownTable } from "./formatter.mjs";
|
|
|
15
15
|
* correctly without special boundary-detection logic.
|
|
16
16
|
*
|
|
17
17
|
* @param {(lines: string[], maxWidth?: number) => string} [formatTable=formatMarkdownTable] - Table formatting function (injectable for testing)
|
|
18
|
-
* @param {number} [maxWidth] - Maximum terminal display width (defaults to process.stdout.columns - 4 or
|
|
18
|
+
* @param {() => number} [maxWidth] - Maximum terminal display width (defaults to process.stdout.columns - 4 or 100)
|
|
19
19
|
* @returns {{ feed: (chunk: string) => StreamFormatterResult, forceFlush: () => StreamFormatterResult }}
|
|
20
20
|
*/
|
|
21
21
|
export function createStreamFormatter(
|
|
22
22
|
formatTable = formatMarkdownTable,
|
|
23
|
-
maxWidth = process.stdout.columns ? process.stdout.columns - 4 :
|
|
23
|
+
maxWidth = () => (process.stdout.columns ? process.stdout.columns - 4 : 100),
|
|
24
24
|
) {
|
|
25
25
|
/** @type {string} - Accumulated incomplete line */
|
|
26
26
|
let pendingLine = "";
|
|
@@ -168,7 +168,7 @@ export function createStreamFormatter(
|
|
|
168
168
|
l.endsWith("\n") ? l.slice(0, -1) : l,
|
|
169
169
|
);
|
|
170
170
|
try {
|
|
171
|
-
const formatted = formatTable(rawLines, maxWidth);
|
|
171
|
+
const formatted = formatTable(rawLines, maxWidth());
|
|
172
172
|
output.push(`${formatted}\n`);
|
|
173
173
|
} catch (err) {
|
|
174
174
|
// Fallback: output raw lines if formatting fails
|
package/src/main.mjs
CHANGED
|
@@ -241,23 +241,22 @@ export async function main(argv = process.argv) {
|
|
|
241
241
|
|
|
242
242
|
if (resumedState) {
|
|
243
243
|
// Switching models on resume is not supported. The model from the saved
|
|
244
|
-
// session always wins. If config disagrees,
|
|
244
|
+
// session always wins. If config disagrees, warn and continue.
|
|
245
245
|
if (
|
|
246
246
|
modelNameWithVariant &&
|
|
247
247
|
modelNameWithVariant !== resumedState.modelName
|
|
248
248
|
) {
|
|
249
249
|
console.error(
|
|
250
250
|
styleText(
|
|
251
|
-
"
|
|
251
|
+
"yellow",
|
|
252
252
|
[
|
|
253
|
-
|
|
253
|
+
`⚠️ Model mismatch for session ${resumedState.sessionId}.`,
|
|
254
254
|
` saved model: ${resumedState.modelName}`,
|
|
255
255
|
` current model: ${modelNameWithVariant}`,
|
|
256
|
-
"
|
|
256
|
+
"Resuming with the saved model.",
|
|
257
257
|
].join("\n"),
|
|
258
258
|
),
|
|
259
259
|
);
|
|
260
|
-
process.exit(1);
|
|
261
260
|
}
|
|
262
261
|
modelNameWithVariant = resumedState.modelName;
|
|
263
262
|
}
|
|
@@ -8,6 +8,7 @@ import { styleText } from "node:util";
|
|
|
8
8
|
import { noThrow } from "../utils/noThrow.mjs";
|
|
9
9
|
import { retryOnError } from "../utils/retryOnError.mjs";
|
|
10
10
|
import { loadAwsCredentials, signAwsRequest } from "./platform/awsSigV4.mjs";
|
|
11
|
+
import { getAzureAccessToken } from "./platform/azure.mjs";
|
|
11
12
|
import { readBedrockStreamEvents } from "./platform/bedrock.mjs";
|
|
12
13
|
import { getGoogleCloudAccessToken } from "./platform/googleCloud.mjs";
|
|
13
14
|
|
|
@@ -43,6 +44,8 @@ export async function callOpenAICompatibleModel(
|
|
|
43
44
|
return `${baseURL}/model/${modelConfig.model}/invoke-with-response-stream`;
|
|
44
45
|
case "vertex-ai":
|
|
45
46
|
return `${baseURL}/endpoints/openapi/chat/completions`;
|
|
47
|
+
case "azure":
|
|
48
|
+
return `${baseURL}/models/chat/completions?api-version=2024-05-01-preview`;
|
|
46
49
|
default:
|
|
47
50
|
throw new Error(`Unsupported platform: ${platformConfig.name}`);
|
|
48
51
|
}
|
|
@@ -64,6 +67,15 @@ export async function callOpenAICompatibleModel(
|
|
|
64
67
|
...platformConfig.customHeaders,
|
|
65
68
|
Authorization: `Bearer ${await getGoogleCloudAccessToken()}`,
|
|
66
69
|
};
|
|
70
|
+
case "azure":
|
|
71
|
+
return {
|
|
72
|
+
...platformConfig.customHeaders,
|
|
73
|
+
Authorization: `Bearer ${await getAzureAccessToken(
|
|
74
|
+
platformConfig.azureConfigDir
|
|
75
|
+
? { azureConfigDir: platformConfig.azureConfigDir }
|
|
76
|
+
: undefined,
|
|
77
|
+
)}`,
|
|
78
|
+
};
|
|
67
79
|
}
|
|
68
80
|
})();
|
|
69
81
|
|
|
@@ -83,7 +95,11 @@ export async function callOpenAICompatibleModel(
|
|
|
83
95
|
case "vertex-ai":
|
|
84
96
|
return {
|
|
85
97
|
...modelConfig,
|
|
86
|
-
|
|
98
|
+
stream: true,
|
|
99
|
+
};
|
|
100
|
+
case "azure":
|
|
101
|
+
return {
|
|
102
|
+
...modelConfig,
|
|
87
103
|
stream: true,
|
|
88
104
|
};
|
|
89
105
|
}
|