@2kw/ai 7.4.0-dev.13 → 7.4.0-dev.15
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.
|
@@ -571,7 +571,7 @@ export declare const agentSchema: {
|
|
|
571
571
|
};
|
|
572
572
|
readonly additionalProperties: {
|
|
573
573
|
readonly type: "string";
|
|
574
|
-
readonly enum: readonly ["read", "write", "destructive", "approve", "
|
|
574
|
+
readonly enum: readonly ["read", "write", "destructive", "approve", "deny"];
|
|
575
575
|
};
|
|
576
576
|
};
|
|
577
577
|
};
|
|
@@ -105,8 +105,8 @@ export const agentSchema = {
|
|
|
105
105
|
properties: {
|
|
106
106
|
readOnlyHint: { type: "boolean" },
|
|
107
107
|
destructiveHint: { type: "boolean" },
|
|
108
|
-
// Optional. With destructiveHint: false it declares the tool harmless, so a write
|
|
109
|
-
//
|
|
108
|
+
// Optional. With destructiveHint: false it declares the tool harmless, so a write that needs
|
|
109
|
+
// approval may be decided by the automatic approver in the Auto mode (#938, #1645).
|
|
110
110
|
openWorldHint: { type: "boolean" },
|
|
111
111
|
},
|
|
112
112
|
},
|
|
@@ -290,17 +290,17 @@ export const agentSchema = {
|
|
|
290
290
|
type: "object",
|
|
291
291
|
additionalProperties: false,
|
|
292
292
|
properties: {
|
|
293
|
-
read: oneOfLowercase("allow", "
|
|
294
|
-
write: oneOfLowercase("
|
|
295
|
-
destructive: oneOfLowercase("block", "deny"),
|
|
293
|
+
read: oneOfLowercase("allow", "approve", "block", "deny"),
|
|
294
|
+
write: oneOfLowercase("approve", "block", "deny"),
|
|
295
|
+
destructive: oneOfLowercase("approve", "block", "deny"),
|
|
296
296
|
},
|
|
297
297
|
},
|
|
298
298
|
tools: {
|
|
299
|
-
// Value is a policy class or an action. Actions (approve,
|
|
299
|
+
// Value is a policy class or an action. Actions (approve, deny) are exact lowercase;
|
|
300
300
|
// classes (read, write, destructive) are case-insensitive and lowercased by the validator.
|
|
301
301
|
type: "object",
|
|
302
302
|
propertyNames: { pattern: "\\S" },
|
|
303
|
-
additionalProperties: { type: "string", enum: ["read", "write", "destructive", "approve", "
|
|
303
|
+
additionalProperties: { type: "string", enum: ["read", "write", "destructive", "approve", "deny"] },
|
|
304
304
|
},
|
|
305
305
|
},
|
|
306
306
|
},
|
|
@@ -24,7 +24,8 @@ export function makeAgentPolicyCommand() {
|
|
|
24
24
|
.option("--tool <name>", "Answer for one tool instead of every configured tool")
|
|
25
25
|
.option("--installation <id>", "Resolve the module tool catalog of this installation")
|
|
26
26
|
.option("--mode <mode>", "Answer as a conversation in this mode would be gated: plan (every call that is not read-only is refused), " +
|
|
27
|
-
"ask (a person decides
|
|
27
|
+
"ask (a person decides every call that needs approval), auto (the automatic approver decides reads and " +
|
|
28
|
+
"writes the server marks safe). Without it, the agent's default mode")
|
|
28
29
|
.action(async (agentRef, opts, command) => {
|
|
29
30
|
await runAction(command, async () => {
|
|
30
31
|
const mode = parseModeOption(opts.mode);
|
|
@@ -49,14 +50,14 @@ export function makeAgentPolicyCommand() {
|
|
|
49
50
|
// model, so they belong above the table rather than in a footnote.
|
|
50
51
|
const auto = data?.autoApproval;
|
|
51
52
|
const parts = [
|
|
52
|
-
`auto-approval ${auto?.enabled ? "on" : "off (every
|
|
53
|
-
`
|
|
53
|
+
`auto-approval ${auto?.enabled ? "on" : "off (every call the approver would decide pauses for a human)"}`,
|
|
54
|
+
`approver ${auto?.judgeConfigured ? "configured" : "not configured (every candidate escalates)"}`,
|
|
54
55
|
];
|
|
55
56
|
if (auto?.instructionsExceedJudgeBound) {
|
|
56
|
-
parts.push("instructions longer than the
|
|
57
|
+
parts.push("instructions longer than the approver reads (every candidate escalates)");
|
|
57
58
|
}
|
|
58
|
-
if (
|
|
59
|
-
parts.push(`mode ${
|
|
59
|
+
if (data?.effectiveMode)
|
|
60
|
+
parts.push(`mode ${data.effectiveMode} (${data.effectiveModeSource})`);
|
|
60
61
|
if (data?.catalogResolvedAt)
|
|
61
62
|
parts.push(`catalog resolved ${data.catalogResolvedAt}`);
|
|
62
63
|
console.log(chalk.dim(parts.join(", ")));
|
package/dist/lib/agent-run.js
CHANGED
|
@@ -5,8 +5,9 @@ import { CliUsageError } from "./errors.js";
|
|
|
5
5
|
import { previewIsIncomplete, previewLines } from "./skills-apply-preview.js";
|
|
6
6
|
export const CONVERSATION_MODES = ["plan", "ask", "auto"];
|
|
7
7
|
/** `--mode` help text, in the words of the embedded chat's mode chip (#655). */
|
|
8
|
-
export const MODE_OPTION_HELP = "Conversation mode: plan (read-only), ask (
|
|
9
|
-
"auto (the
|
|
8
|
+
export const MODE_OPTION_HELP = "Conversation mode: plan (read-only), ask (calls that need approval wait for you), " +
|
|
9
|
+
"auto (the automatic approver decides reads and writes the server marks safe; the rest wait for you). " +
|
|
10
|
+
"Without it, the conversation keeps its mode, else the agent's default; a mode the agent does not offer is refused";
|
|
10
11
|
function isConversationMode(value) {
|
|
11
12
|
return typeof value === "string" && CONVERSATION_MODES.includes(value);
|
|
12
13
|
}
|
package/dist/lib/errors.js
CHANGED
|
@@ -102,6 +102,7 @@ const CODE_HINTS = {
|
|
|
102
102
|
"Check pendingToolCalls and pendingApprovals in the run envelope.",
|
|
103
103
|
unknown_tool_output: "That call id was not released by this response. Use the responseId of the latest envelope.",
|
|
104
104
|
conversation_agent_mismatch: "This conversation belongs to another agent. Start a new conversation or run the agent that owns it.",
|
|
105
|
+
conversation_mode_not_offered: "The agent does not offer that mode. Use one of the modes the message lists (plan is always offered), or leave --mode out for the agent's default.",
|
|
105
106
|
provider_quota_exhausted: "The model provider account is out of credits or at its spend limit. Add credits or raise the limit with the provider; retrying will not help.",
|
|
106
107
|
};
|
|
107
108
|
/** The most specific hint for an API error: gateway code, then known messages, then the status table. */
|
|
@@ -117,6 +118,9 @@ export function hintFor(err) {
|
|
|
117
118
|
}
|
|
118
119
|
if (err.code && Object.hasOwn(CODE_HINTS, err.code))
|
|
119
120
|
return CODE_HINTS[err.code];
|
|
121
|
+
// The REST layer (the explain view) spells the same refusal as an errorCode.
|
|
122
|
+
if (err.errorCode === "CONVERSATION_MODE_NOT_OFFERED")
|
|
123
|
+
return CODE_HINTS.conversation_mode_not_offered;
|
|
120
124
|
// The gateway answers `agent_not_published` (code), the REST layer AGENT_NOT_PUBLISHED (errorCode).
|
|
121
125
|
if (err.code === "agent_not_published" || err.errorCode === "AGENT_NOT_PUBLISHED") {
|
|
122
126
|
return NOT_PUBLISHED_HINT;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@2kw/ai",
|
|
3
|
-
"version": "7.4.0-dev.
|
|
3
|
+
"version": "7.4.0-dev.15",
|
|
4
4
|
"description": "CLI for 2kw.ai — schema-driven document extraction, an OpenAI-compatible EU LLM gateway, transcription, prompts, datasets, and experiments from your terminal or agentic workflows. Ships as 2kw, backbone, and bb.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|