@2kw/ai 7.4.0-dev.9 → 8.0.0-dev.11
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/agent-config/schema.d.ts +1 -1
- package/dist/agent-config/schema.js +7 -7
- package/dist/commands/agent-policy.js +9 -5
- package/dist/commands/dataset-versions.js +0 -2
- package/dist/commands/datasets.js +0 -2
- package/dist/commands/experiments.js +2 -3
- package/dist/commands/files.js +21 -6
- package/dist/commands/knowledge.js +16 -1
- package/dist/commands/skills.js +10 -2
- package/dist/index.js +17 -2
- package/dist/lib/agent-run.d.ts +1 -1
- package/dist/lib/agent-run.js +4 -3
- package/dist/lib/errors.js +4 -0
- package/dist/lib/skill-bundle.js +4 -3
- package/package.json +1 -1
|
@@ -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,11 +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
|
-
if (
|
|
56
|
-
parts.push(
|
|
56
|
+
if (auto?.instructionsExceedJudgeBound) {
|
|
57
|
+
parts.push("instructions longer than the approver reads (every candidate escalates)");
|
|
58
|
+
}
|
|
59
|
+
if (data?.effectiveMode)
|
|
60
|
+
parts.push(`mode ${data.effectiveMode} (${data.effectiveModeSource})`);
|
|
57
61
|
if (data?.catalogResolvedAt)
|
|
58
62
|
parts.push(`catalog resolved ${data.catalogResolvedAt}`);
|
|
59
63
|
console.log(chalk.dim(parts.join(", ")));
|
|
@@ -97,7 +97,6 @@ export function makeDatasetVersionsCommand() {
|
|
|
97
97
|
const versionId = opts.versionId ?? (await resolveLatestVersionId(client, opts.dataset));
|
|
98
98
|
await client.DELETE("/v1/datasets/{id}/versions/{versionId}/items/{itemId}", {
|
|
99
99
|
params: {
|
|
100
|
-
// OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
|
|
101
100
|
path: { id: opts.dataset, versionId, itemId },
|
|
102
101
|
},
|
|
103
102
|
});
|
|
@@ -120,7 +119,6 @@ export function makeDatasetVersionsCommand() {
|
|
|
120
119
|
body.expectedOutput = JSON.parse(opts.expectedOutput);
|
|
121
120
|
const { data } = await client.PATCH("/v1/datasets/{id}/versions/{versionId}/items/{itemId}/expected-output", {
|
|
122
121
|
params: {
|
|
123
|
-
// OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
|
|
124
122
|
path: { id: opts.dataset, versionId, itemId },
|
|
125
123
|
},
|
|
126
124
|
body: body,
|
|
@@ -138,7 +138,6 @@ export function makeDatasetsCommand() {
|
|
|
138
138
|
body.metadata = JSON.parse(opts.metadata);
|
|
139
139
|
const { data } = await client.POST("/v1/datasets/{id}/versions/{versionId}/items", {
|
|
140
140
|
params: {
|
|
141
|
-
// OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
|
|
142
141
|
path: { id: opts.dataset, versionId },
|
|
143
142
|
},
|
|
144
143
|
body: body,
|
|
@@ -158,7 +157,6 @@ export function makeDatasetsCommand() {
|
|
|
158
157
|
const items = JSON.parse(opts.items);
|
|
159
158
|
const { data } = await client.POST("/v1/datasets/{id}/versions/{versionId}/items/bulk", {
|
|
160
159
|
params: {
|
|
161
|
-
// OpenAPI spec omits `id` in declared path params though `{id}` is in the URL template.
|
|
162
160
|
path: { id: opts.dataset, versionId },
|
|
163
161
|
},
|
|
164
162
|
body: items,
|
|
@@ -335,7 +335,7 @@ export function makeExperimentsCommand() {
|
|
|
335
335
|
},
|
|
336
336
|
});
|
|
337
337
|
formatPage(data, command, [
|
|
338
|
-
"datasetItemId", "durationMs", "inputTokens", "outputTokens", "
|
|
338
|
+
"datasetItemId", "durationMs", "inputTokens", "outputTokens", "error",
|
|
339
339
|
]);
|
|
340
340
|
});
|
|
341
341
|
});
|
|
@@ -418,7 +418,7 @@ export function makeExperimentsCommand() {
|
|
|
418
418
|
// Only when something was skipped, so a clean run keeps its narrow table (#693).
|
|
419
419
|
const showSkipped = aggregates.some((agg) => skippedOf(agg) !== "");
|
|
420
420
|
const aggTable = new Table({
|
|
421
|
-
head: ["Variant", "Items", "Avg Duration", "Avg Tokens",
|
|
421
|
+
head: ["Variant", "Items", "Avg Duration", "Avg Tokens", ...(showSkipped ? ["Skipped"] : [])].map((h) => chalk.cyan(h)),
|
|
422
422
|
wordWrap: true,
|
|
423
423
|
});
|
|
424
424
|
for (const agg of aggregates) {
|
|
@@ -427,7 +427,6 @@ export function makeExperimentsCommand() {
|
|
|
427
427
|
agg.itemCount ?? "—",
|
|
428
428
|
agg.avgDurationMs != null ? `${Math.round(agg.avgDurationMs)}ms` : "—",
|
|
429
429
|
agg.avgTokens != null ? Math.round(agg.avgTokens) : "—",
|
|
430
|
-
agg.totalCost != null ? `$${agg.totalCost}` : "—",
|
|
431
430
|
...(showSkipped ? [skippedOf(agg) || "—"] : []),
|
|
432
431
|
]);
|
|
433
432
|
}
|
package/dist/commands/files.js
CHANGED
|
@@ -2,10 +2,9 @@ import { Command } from "commander";
|
|
|
2
2
|
import { writeFileSync } from "node:fs";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { getClient, resolveAuthHeader, runAction } from "../lib/client.js";
|
|
5
|
-
import { resolveConfig } from "../lib/config.js";
|
|
5
|
+
import { isJsonOutput, resolveConfig } from "../lib/config.js";
|
|
6
6
|
import { BackboneApiError } from "../lib/errors.js";
|
|
7
|
-
import {
|
|
8
|
-
import { addPaginationOptions, paginationParams } from "../lib/pagination.js";
|
|
7
|
+
import { formatDetail, formatList, formatSuccess, withSpinner } from "../lib/output.js";
|
|
9
8
|
import { fileToBlob } from "../lib/multipart.js";
|
|
10
9
|
/**
|
|
11
10
|
* Upload a single file with purpose=agent_input|knowledge. Both are multipart
|
|
@@ -59,15 +58,31 @@ async function downloadFile(command, fileId) {
|
|
|
59
58
|
export function makeFilesCommand() {
|
|
60
59
|
const cmd = new Command("files").description("Manage uploaded files");
|
|
61
60
|
const list = new Command("list").description("List files");
|
|
62
|
-
addPaginationOptions(list);
|
|
63
61
|
list.option("--purpose <purpose>", "Filter by purpose (agent_input, knowledge)");
|
|
62
|
+
list.option("--limit <number>", "How many files to list (1-100)", "20");
|
|
63
|
+
list.option("--after <fileId>", "List the files after this one (the previous list's last id)");
|
|
64
|
+
list.option("--order <order>", "asc (oldest first) or desc (newest first)", "desc");
|
|
64
65
|
list.action(async (opts, command) => {
|
|
65
66
|
await runAction(command, async () => {
|
|
66
67
|
const client = getClient(command);
|
|
67
68
|
const { data } = await client.GET("/v1/files", {
|
|
68
|
-
params: {
|
|
69
|
+
params: {
|
|
70
|
+
query: {
|
|
71
|
+
purpose: opts.purpose,
|
|
72
|
+
limit: parseInt(opts.limit, 10),
|
|
73
|
+
after: opts.after,
|
|
74
|
+
order: opts.order,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
69
77
|
});
|
|
70
|
-
|
|
78
|
+
if (isJsonOutput(command)) {
|
|
79
|
+
console.log(JSON.stringify(data, null, 2));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
formatList(data?.data, command, ["id", "filename", "purpose", "bytes", "created_at"]);
|
|
83
|
+
if (data?.has_more) {
|
|
84
|
+
console.log(chalk.dim(`More files: --after ${data.last_id}`));
|
|
85
|
+
}
|
|
71
86
|
});
|
|
72
87
|
});
|
|
73
88
|
cmd.addCommand(list);
|
|
@@ -86,10 +86,23 @@ export function makeKnowledgeCommand() {
|
|
|
86
86
|
.option("--reranker-provider <id>", "New reranker provider ID")
|
|
87
87
|
.option("--hybrid-search <bool>", "Enable hybrid search (true/false)")
|
|
88
88
|
.option("--text-search-language <name>", "Change the text-search language (reindexes in the background); omit to leave it untouched")
|
|
89
|
+
.option("--cancel-text-search-reindex", "Abandon the text-search reindex in progress and keep the active language")
|
|
89
90
|
.action(async (id, opts, command) => {
|
|
90
91
|
await runAction(command, async () => {
|
|
91
92
|
const client = getClient(command);
|
|
92
|
-
|
|
93
|
+
// The update takes the full body: name, slug, provider, model and dimension are required on
|
|
94
|
+
// every PATCH, so start from the stored values and overlay the flags. Optional fields left
|
|
95
|
+
// out keep their stored values server-side.
|
|
96
|
+
const { data: current } = await client.GET("/v1/knowledge-bases/{id}", {
|
|
97
|
+
params: { path: { id } },
|
|
98
|
+
});
|
|
99
|
+
const body = {
|
|
100
|
+
name: current?.name,
|
|
101
|
+
slug: current?.slug,
|
|
102
|
+
embeddingProviderId: current?.embeddingProviderId,
|
|
103
|
+
embeddingModel: current?.embeddingModel,
|
|
104
|
+
embeddingDim: current?.embeddingDim,
|
|
105
|
+
};
|
|
93
106
|
if (opts.name)
|
|
94
107
|
body.name = opts.name;
|
|
95
108
|
if (opts.description !== undefined)
|
|
@@ -112,6 +125,8 @@ export function makeKnowledgeCommand() {
|
|
|
112
125
|
body.hybridSearchEnabled = opts.hybridSearch === "true";
|
|
113
126
|
if (opts.textSearchLanguage)
|
|
114
127
|
body.textSearchLanguage = opts.textSearchLanguage;
|
|
128
|
+
if (opts.cancelTextSearchReindex)
|
|
129
|
+
body.cancelTextSearchReindex = true;
|
|
115
130
|
const { data } = await client.PATCH("/v1/knowledge-bases/{id}", {
|
|
116
131
|
params: { path: { id } },
|
|
117
132
|
body: body,
|
package/dist/commands/skills.js
CHANGED
|
@@ -138,7 +138,7 @@ export function makeSkillsCommand() {
|
|
|
138
138
|
const bundle = packSkillDirectory(path);
|
|
139
139
|
if (bundle.skipped.length > 0) {
|
|
140
140
|
// The server reports what it was sent; only the CLI can name what never left the disk.
|
|
141
|
-
console.error(`Left out of the bundle (the importer takes SKILL.md, references/, assets/, scripts/): ${bundle.skipped.join(", ")}`);
|
|
141
|
+
console.error(`Left out of the bundle (the importer takes SKILL.md, references/, assets/, scripts/, examples/): ${bundle.skipped.join(", ")}`);
|
|
142
142
|
}
|
|
143
143
|
blob = new Blob([bundle.bytes], { type: "application/zip" });
|
|
144
144
|
filename = bundle.filename;
|
|
@@ -171,6 +171,7 @@ export function makeSkillsCommand() {
|
|
|
171
171
|
.option("-o, --output <file>", "Output path (default: <skill-name>-v<n>.zip)")
|
|
172
172
|
.option("-d, --extract-to <dir>", "Unpack the bundle into this directory instead of writing a zip")
|
|
173
173
|
.option("--force", "Write into a non-empty --extract-to directory")
|
|
174
|
+
.option("--include-examples", "Keep the confidential examples/ files (needs ADMIN or OWNER)")
|
|
174
175
|
.action(async (id, versionNumber, opts, command) => {
|
|
175
176
|
await runAction(command, async () => {
|
|
176
177
|
if (opts.output && opts.extractTo)
|
|
@@ -189,14 +190,21 @@ export function makeSkillsCommand() {
|
|
|
189
190
|
}
|
|
190
191
|
const config = resolveConfig(command);
|
|
191
192
|
const authHeader = await resolveAuthHeader(config);
|
|
193
|
+
let omitted = 0;
|
|
192
194
|
const bytes = await withSpinner("Exporting skill...", async () => {
|
|
193
195
|
const baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
194
|
-
const
|
|
196
|
+
const query = opts.includeExamples ? "?includeExamples=true" : "";
|
|
197
|
+
const res = await fetch(`${baseUrl}/v1/skills/${encodeURIComponent(id)}/versions/${encodeURIComponent(versionNumber)}/export${query}`, {
|
|
195
198
|
headers: { Authorization: authHeader },
|
|
196
199
|
});
|
|
197
200
|
await checkResponse(res);
|
|
201
|
+
omitted = Number(res.headers.get("X-Skill-Examples-Omitted") ?? 0);
|
|
198
202
|
return Buffer.from(await res.arrayBuffer());
|
|
199
203
|
});
|
|
204
|
+
if (omitted > 0) {
|
|
205
|
+
// #926: a re-import of this bundle would drop them, so say so where the user looks.
|
|
206
|
+
console.error(`${omitted} confidential example file(s) left out; --include-examples (admin) keeps them`);
|
|
207
|
+
}
|
|
200
208
|
if (opts.extractTo) {
|
|
201
209
|
mkdirSync(opts.extractTo, { recursive: true });
|
|
202
210
|
const written = unpackSkillBundle(new Uint8Array(bytes), opts.extractTo);
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import { Command } from "commander";
|
|
3
|
+
import { Command, CommanderError } from "commander";
|
|
4
4
|
import { makeAuthCommand } from "./commands/auth.js";
|
|
5
5
|
const require = createRequire(import.meta.url);
|
|
6
6
|
const pkg = require("../package.json");
|
|
@@ -78,5 +78,20 @@ program.addCommand(makeConnectorsCommand());
|
|
|
78
78
|
program.addCommand(makeRelaysCommand());
|
|
79
79
|
program.addCommand(makeBridgeCommand());
|
|
80
80
|
program.addCommand(makeDocsCommand());
|
|
81
|
-
|
|
81
|
+
// Commander exits 1 on its own parse errors, and 1 is the exit code for API and network failures.
|
|
82
|
+
// Every command throws instead, so a usage error exits 2 like a CliUsageError (#697).
|
|
83
|
+
const throwOnExit = (cmd) => {
|
|
84
|
+
cmd.exitOverride();
|
|
85
|
+
cmd.commands.forEach(throwOnExit);
|
|
86
|
+
};
|
|
87
|
+
throwOnExit(program);
|
|
88
|
+
program
|
|
89
|
+
.parseAsync()
|
|
90
|
+
.then(() => updater.notify())
|
|
91
|
+
.catch((err) => {
|
|
92
|
+
if (!(err instanceof CommanderError))
|
|
93
|
+
throw err;
|
|
94
|
+
// --help, --version and a command group's help without a subcommand succeed.
|
|
95
|
+
process.exit(err.exitCode === 0 || err.code === "commander.help" ? 0 : 2);
|
|
96
|
+
});
|
|
82
97
|
//# sourceMappingURL=index.js.map
|
package/dist/lib/agent-run.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export declare const CONVERSATION_MODES: readonly ConversationMode[];
|
|
|
60
60
|
export declare const MODE_OPTION_HELP: string;
|
|
61
61
|
/**
|
|
62
62
|
* The `--mode` value, checked before any request is sent: anything but the three exact values is a
|
|
63
|
-
* usage error (exit 2).
|
|
63
|
+
* usage error (exit 2).
|
|
64
64
|
*/
|
|
65
65
|
export declare function parseModeOption(raw: string | undefined): ConversationMode | undefined;
|
|
66
66
|
/** The `backbone:mode` input item (S1 D7); always appended last. */
|
package/dist/lib/agent-run.js
CHANGED
|
@@ -5,14 +5,15 @@ 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
|
}
|
|
13
14
|
/**
|
|
14
15
|
* The `--mode` value, checked before any request is sent: anything but the three exact values is a
|
|
15
|
-
* usage error (exit 2).
|
|
16
|
+
* usage error (exit 2).
|
|
16
17
|
*/
|
|
17
18
|
export function parseModeOption(raw) {
|
|
18
19
|
if (raw === undefined)
|
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/dist/lib/skill-bundle.js
CHANGED
|
@@ -2,11 +2,12 @@ import { mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { basename, dirname, join, resolve } from "node:path";
|
|
3
3
|
import { unzipSync, zipSync } from "fflate";
|
|
4
4
|
/**
|
|
5
|
-
* The importer takes SKILL.md plus these
|
|
5
|
+
* The importer takes SKILL.md plus these four directories and reports anything else as
|
|
6
6
|
* `unsupported-path` (spec §4). Packing only these keeps a stray .git or node_modules out of
|
|
7
|
-
* the upload instead of spending the 20 MB bundle cap on it.
|
|
7
|
+
* the upload instead of spending the 20 MB bundle cap on it. `examples/` holds confidential
|
|
8
|
+
* files (#926): imported like the rest, left out of a plain export.
|
|
8
9
|
*/
|
|
9
|
-
const RESOURCE_DIRS = ["references", "assets", "scripts"];
|
|
10
|
+
const RESOURCE_DIRS = ["references", "assets", "scripts", "examples"];
|
|
10
11
|
function byName(left, right) {
|
|
11
12
|
return left.name < right.name ? -1 : left.name > right.name ? 1 : 0;
|
|
12
13
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@2kw/ai",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0-dev.11",
|
|
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",
|