@2kw/ai 6.3.0-dev.12 → 6.3.0-dev.14
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/dist/commands/agents.js +15 -1
- package/dist/commands/connectors.js +2 -1
- package/dist/commands/settings.d.ts +13 -0
- package/dist/commands/settings.js +80 -0
- package/dist/index.js +2 -0
- package/dist/lib/client.js +2 -0
- package/dist/lib/errors.d.ts +6 -0
- package/dist/lib/errors.js +5 -2
- package/package.json +1 -1
package/dist/commands/agents.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { getClient, runAction } from "../lib/client.js";
|
|
3
|
-
import { formatPage, formatDetail, formatSuccess } from "../lib/output.js";
|
|
3
|
+
import { formatPage, formatDetail, formatList, formatSuccess } from "../lib/output.js";
|
|
4
4
|
import { addPaginationOptions, paginationParams } from "../lib/pagination.js";
|
|
5
5
|
import { makeAgentVersionsCommand } from "./agent-versions.js";
|
|
6
6
|
import { makeAgentLabelsCommand } from "./agent-labels.js";
|
|
@@ -172,6 +172,20 @@ export function makeAgentsCommand() {
|
|
|
172
172
|
});
|
|
173
173
|
});
|
|
174
174
|
cmd.addCommand(toolCatalogs);
|
|
175
|
+
// The skills the latest published version binds (#827) -- readable by a chat-only USER key,
|
|
176
|
+
// which cannot read the version itself. No published version answers [] rather than 404.
|
|
177
|
+
const skills = new Command("skills").description("List the skills an agent's latest published version binds");
|
|
178
|
+
skills.requiredOption("--agent <id>", "Agent ID");
|
|
179
|
+
skills.action(async (opts, command) => {
|
|
180
|
+
await runAction(command, async () => {
|
|
181
|
+
const client = getClient(command);
|
|
182
|
+
const { data } = await client.GET("/v1/agents/{agentId}/skills", {
|
|
183
|
+
params: { path: { agentId: opts.agent } },
|
|
184
|
+
});
|
|
185
|
+
formatList(data, command, ["name", "description", "versionNumber", "ref", "pluginName"]);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
cmd.addCommand(skills);
|
|
175
189
|
cmd.addCommand(makeAgentRunCommand());
|
|
176
190
|
cmd.addCommand(makeAgentDecideCommand());
|
|
177
191
|
cmd.addCommand(makeAgentApplyCommand());
|
|
@@ -28,7 +28,8 @@ function parsePort(value) {
|
|
|
28
28
|
if (value === undefined) {
|
|
29
29
|
return undefined;
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
// Digits only: `Number` alone accepts " 8443 ", "0x20FB" and "8.443e3".
|
|
32
|
+
const port = /^\d{1,5}$/.test(value) ? Number(value) : NaN;
|
|
32
33
|
if (!Number.isInteger(port) || port < MIN_PORT || port > MAX_PORT) {
|
|
33
34
|
throw new CliUsageError(`--port must be a whole number between ${MIN_PORT} and ${MAX_PORT}, not '${value}'`);
|
|
34
35
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
/**
|
|
3
|
+
* Parses the value a setting takes: a JSON object. The server checks its shape per key
|
|
4
|
+
* (for agents.default: {"agentId": "<id>"}); this only refuses what can never be valid.
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseSettingValue(raw: string): Record<string, unknown>;
|
|
7
|
+
/**
|
|
8
|
+
* Organization and member settings (agent-first chat spec §3.1, §4). Without --org every
|
|
9
|
+
* write targets the caller's own member tier; --org writes the organization's, which needs
|
|
10
|
+
* the key's write role (ADMIN or OWNER for agents.default).
|
|
11
|
+
*/
|
|
12
|
+
export declare function makeSettingsCommand(): Command;
|
|
13
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { getClient, runAction } from "../lib/client.js";
|
|
3
|
+
import { CliUsageError } from "../lib/errors.js";
|
|
4
|
+
import { formatDetail } from "../lib/output.js";
|
|
5
|
+
/**
|
|
6
|
+
* Parses the value a setting takes: a JSON object. The server checks its shape per key
|
|
7
|
+
* (for agents.default: {"agentId": "<id>"}); this only refuses what can never be valid.
|
|
8
|
+
*/
|
|
9
|
+
export function parseSettingValue(raw) {
|
|
10
|
+
let parsed;
|
|
11
|
+
try {
|
|
12
|
+
parsed = JSON.parse(raw);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
throw new CliUsageError(`Setting value is not valid JSON: ${raw}`);
|
|
16
|
+
}
|
|
17
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
18
|
+
throw new CliUsageError('Setting value must be a JSON object, e.g. \'{"agentId":"agt_123"}\'');
|
|
19
|
+
}
|
|
20
|
+
return parsed;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Organization and member settings (agent-first chat spec §3.1, §4). Without --org every
|
|
24
|
+
* write targets the caller's own member tier; --org writes the organization's, which needs
|
|
25
|
+
* the key's write role (ADMIN or OWNER for agents.default).
|
|
26
|
+
*/
|
|
27
|
+
export function makeSettingsCommand() {
|
|
28
|
+
const cmd = new Command("settings").description("Organization and member settings (e.g. agents.default)");
|
|
29
|
+
cmd
|
|
30
|
+
.command("get <key>")
|
|
31
|
+
.description("Show a setting: the effective value, its source and both tiers")
|
|
32
|
+
.action(async (key, _opts, command) => {
|
|
33
|
+
await runAction(command, async () => {
|
|
34
|
+
const client = getClient(command);
|
|
35
|
+
const { data } = await client.GET("/v1/settings/{key}", {
|
|
36
|
+
params: { path: { key } },
|
|
37
|
+
});
|
|
38
|
+
formatDetail(data, command);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
cmd
|
|
42
|
+
.command("set <key> <json>")
|
|
43
|
+
.description("Set your own value, or the organization's with --org (ADMIN+)")
|
|
44
|
+
.option("--org", "Write the organization's value instead of your own")
|
|
45
|
+
.action(async (key, json, opts, command) => {
|
|
46
|
+
await runAction(command, async () => {
|
|
47
|
+
const client = getClient(command);
|
|
48
|
+
const body = { value: parseSettingValue(json) };
|
|
49
|
+
const { data } = opts.org
|
|
50
|
+
? await client.PUT("/v1/settings/{key}/org", {
|
|
51
|
+
params: { path: { key } },
|
|
52
|
+
body,
|
|
53
|
+
})
|
|
54
|
+
: await client.PUT("/v1/settings/{key}/member", {
|
|
55
|
+
params: { path: { key } },
|
|
56
|
+
body,
|
|
57
|
+
});
|
|
58
|
+
formatDetail(data, command);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
cmd
|
|
62
|
+
.command("unset <key>")
|
|
63
|
+
.description("Clear your own value, or the organization's with --org (ADMIN+)")
|
|
64
|
+
.option("--org", "Clear the organization's value instead of your own")
|
|
65
|
+
.action(async (key, opts, command) => {
|
|
66
|
+
await runAction(command, async () => {
|
|
67
|
+
const client = getClient(command);
|
|
68
|
+
const { data } = opts.org
|
|
69
|
+
? await client.DELETE("/v1/settings/{key}/org", {
|
|
70
|
+
params: { path: { key } },
|
|
71
|
+
})
|
|
72
|
+
: await client.DELETE("/v1/settings/{key}/member", {
|
|
73
|
+
params: { path: { key } },
|
|
74
|
+
});
|
|
75
|
+
formatDetail(data, command);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
return cmd;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=settings.js.map
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ import { makeDocsCommand } from "./commands/docs.js";
|
|
|
21
21
|
import { makeContextCommand } from "./commands/context.js";
|
|
22
22
|
import { makeExperimentsCommand } from "./commands/experiments.js";
|
|
23
23
|
import { makeTracingCommand } from "./commands/tracing.js";
|
|
24
|
+
import { makeSettingsCommand } from "./commands/settings.js";
|
|
24
25
|
import { makeEvaluatorsCommand } from "./commands/evaluators.js";
|
|
25
26
|
import { makeScoresCommand } from "./commands/scores.js";
|
|
26
27
|
import { makeQueuesCommand } from "./commands/queues.js";
|
|
@@ -62,6 +63,7 @@ program.addCommand(makeEvaluatorsCommand());
|
|
|
62
63
|
program.addCommand(makeScoresCommand());
|
|
63
64
|
program.addCommand(makeQueuesCommand());
|
|
64
65
|
program.addCommand(makeTracingCommand());
|
|
66
|
+
program.addCommand(makeSettingsCommand());
|
|
65
67
|
program.addCommand(makeAgentsCommand());
|
|
66
68
|
program.addCommand(makeConversationsCommand());
|
|
67
69
|
program.addCommand(makeKnowledgeCommand());
|
package/dist/lib/client.js
CHANGED
|
@@ -37,6 +37,8 @@ export const errorMiddleware = {
|
|
|
37
37
|
`HTTP ${response.status}: ${response.statusText}`,
|
|
38
38
|
timestamp: body.timestamp ?? new Date().toISOString(),
|
|
39
39
|
code: typeof nested?.code === "string" ? nested.code : undefined,
|
|
40
|
+
// A problem detail names its cause in `errorCode` (GlobalExceptionHandler).
|
|
41
|
+
errorCode: typeof body.errorCode === "string" ? body.errorCode : undefined,
|
|
40
42
|
});
|
|
41
43
|
},
|
|
42
44
|
};
|
package/dist/lib/errors.d.ts
CHANGED
|
@@ -10,12 +10,18 @@ export interface ApiErrorBody {
|
|
|
10
10
|
timestamp: string;
|
|
11
11
|
/** Machine-readable code from an OpenAI-style gateway error, e.g. `approval_hmac_mismatch`. */
|
|
12
12
|
code?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Machine-readable code from a problem detail's `errorCode`, e.g. `CONNECTOR_HOST_SIGN_IN_REQUIRED`.
|
|
15
|
+
* Kept apart from {@link code}: that one holds lowercase gateway codes and is printed by `--json`.
|
|
16
|
+
*/
|
|
17
|
+
errorCode?: string;
|
|
13
18
|
}
|
|
14
19
|
export declare class BackboneApiError extends Error {
|
|
15
20
|
readonly status: number;
|
|
16
21
|
readonly errorType: string;
|
|
17
22
|
readonly timestamp: string;
|
|
18
23
|
readonly code?: string;
|
|
24
|
+
readonly errorCode?: string;
|
|
19
25
|
constructor(body: Omit<ApiErrorBody, "error"> & {
|
|
20
26
|
error: string;
|
|
21
27
|
});
|
package/dist/lib/errors.js
CHANGED
|
@@ -7,6 +7,7 @@ export class BackboneApiError extends Error {
|
|
|
7
7
|
errorType;
|
|
8
8
|
timestamp;
|
|
9
9
|
code;
|
|
10
|
+
errorCode;
|
|
10
11
|
constructor(body) {
|
|
11
12
|
super(body.message);
|
|
12
13
|
this.name = "BackboneApiError";
|
|
@@ -14,6 +15,7 @@ export class BackboneApiError extends Error {
|
|
|
14
15
|
this.errorType = body.error;
|
|
15
16
|
this.timestamp = body.timestamp;
|
|
16
17
|
this.code = body.code;
|
|
18
|
+
this.errorCode = body.errorCode;
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
@@ -108,8 +110,9 @@ export function hintFor(err) {
|
|
|
108
110
|
return CODE_HINTS[err.code];
|
|
109
111
|
// The 403 whose cause is the credential, not the role (#805). Without this the
|
|
110
112
|
// generic 403 hint tells an organization admin to check a role that is already
|
|
111
|
-
// right, and no role would ever have fixed it.
|
|
112
|
-
|
|
113
|
+
// right, and no role would ever have fixed it. Matched on the backend's error code,
|
|
114
|
+
// so a reworded message cannot silently drop the hint.
|
|
115
|
+
if (err.errorCode === "CONNECTOR_HOST_SIGN_IN_REQUIRED") {
|
|
113
116
|
return "Approved hosts need a browser sign-in: run 2kw auth login. An API key cannot manage them, whatever its role.";
|
|
114
117
|
}
|
|
115
118
|
// Anchored on the agent service's wording: prompts and schemas send the same
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@2kw/ai",
|
|
3
|
-
"version": "6.3.0-dev.
|
|
3
|
+
"version": "6.3.0-dev.14",
|
|
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",
|