@2kw/ai 6.2.0-dev.25 → 6.2.0-dev.26
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.
|
@@ -52,10 +52,10 @@ async function withAgentSuggestions(client, agentRef, err) {
|
|
|
52
52
|
/**
|
|
53
53
|
* Prints a run result and sets the exit code. In interactive mode an approval pause
|
|
54
54
|
* is decided at the terminal and continued until the run stops pausing for approval.
|
|
55
|
-
* Continuations stay on the run's label, and the envelope's `next` names
|
|
55
|
+
* Continuations stay on the run's label and model override, and the envelope's `next` names both.
|
|
56
56
|
*/
|
|
57
57
|
async function finishRun(command, client, target, first, opts) {
|
|
58
|
-
const agentRef = target.label ?
|
|
58
|
+
const agentRef = `${target.name}${target.label ? `@${target.label}` : ""}${target.model ? `#${target.model}` : ""}`;
|
|
59
59
|
let result = first;
|
|
60
60
|
let env = buildRunEnvelope(result, agentRef);
|
|
61
61
|
if (opts.interactive && env.status === "requires_approval") {
|
|
@@ -90,7 +90,7 @@ async function finishRun(command, client, target, first, opts) {
|
|
|
90
90
|
throw new CliUsageError(`No pending approvals for ${responseId} (already decided or superseded).`);
|
|
91
91
|
}
|
|
92
92
|
const decisions = decisionsFromAnswers(rows, answers);
|
|
93
|
-
result = await withSpinner("Continuing...", () => continueWithDecisions(client, String(agent.id), responseId, decisions, target.label));
|
|
93
|
+
result = await withSpinner("Continuing...", () => continueWithDecisions(client, String(agent.id), responseId, decisions, target.label, target.model));
|
|
94
94
|
env = buildRunEnvelope(result, agentRef);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
@@ -116,7 +116,7 @@ async function finishRun(command, client, target, first, opts) {
|
|
|
116
116
|
export function makeAgentRunCommand() {
|
|
117
117
|
return new Command("run")
|
|
118
118
|
.description("Run an agent on a task (exit 3 = paused for approval, 4 = needs client tool output, 5 = incomplete)")
|
|
119
|
-
.argument("<agent>", "Agent name or id, optionally with @label")
|
|
119
|
+
.argument("<agent>", "Agent name or id, optionally with @label and #model")
|
|
120
120
|
.argument("[input]", "Task text (or use --input-file, or pipe it on stdin)")
|
|
121
121
|
.option("--input-file <path>", "Read the task text from a file")
|
|
122
122
|
.option("--conversation <id>", "Continue a conversation")
|
|
@@ -145,8 +145,8 @@ export function makeAgentRunCommand() {
|
|
|
145
145
|
}
|
|
146
146
|
// The prompt reads stdin and writes to stderr, so those two decide; stdout may be redirected.
|
|
147
147
|
const interactive = !!process.stdin.isTTY && !!process.stderr.isTTY && !isJsonOutput(command) && opts.input !== false && !opts.raw;
|
|
148
|
-
const { name, label } = splitAgentRef(agentRef);
|
|
149
|
-
await finishRun(command, client, { name, label }, data, {
|
|
148
|
+
const { name, label, model } = splitAgentRef(agentRef);
|
|
149
|
+
await finishRun(command, client, { name, label, model }, data, {
|
|
150
150
|
raw: !!opts.raw,
|
|
151
151
|
interactive,
|
|
152
152
|
});
|
|
@@ -156,7 +156,7 @@ export function makeAgentRunCommand() {
|
|
|
156
156
|
export function makeAgentDecideCommand() {
|
|
157
157
|
return new Command("decide")
|
|
158
158
|
.description("Decide every pending approval of a paused run and continue it")
|
|
159
|
-
.argument("<agent>", "Agent name or id, optionally with @label (use the same label the run used)")
|
|
159
|
+
.argument("<agent>", "Agent name or id, optionally with @label and #model (use the same @label and #model the run used)")
|
|
160
160
|
.requiredOption("--response <responseId>", "The paused response id (responseId in the run envelope)")
|
|
161
161
|
.option("--approve <ids...>", "Approval ids to approve")
|
|
162
162
|
.option("--reject <ids...>", "Approval ids to reject")
|
|
@@ -168,7 +168,10 @@ export function makeAgentDecideCommand() {
|
|
|
168
168
|
.action(async (agentRef, opts, command) => {
|
|
169
169
|
await runAction(command, async () => {
|
|
170
170
|
const client = getClient(command);
|
|
171
|
-
const { name, label } = splitAgentRef(agentRef);
|
|
171
|
+
const { name, label, model } = splitAgentRef(agentRef);
|
|
172
|
+
// Dropped silently, an empty override would continue the run on the default model.
|
|
173
|
+
if (model === "")
|
|
174
|
+
throw new CliUsageError(`Empty #model in '${agentRef}': use the model the run used, or drop the '#'.`);
|
|
172
175
|
const agent = await resolveAgent(client, name);
|
|
173
176
|
const pending = await fetchPendingApprovals(client, String(agent.id), opts.response);
|
|
174
177
|
const decisions = planDecisions(pending, {
|
|
@@ -179,8 +182,8 @@ export function makeAgentDecideCommand() {
|
|
|
179
182
|
reason: opts.reason,
|
|
180
183
|
remember: opts.remember,
|
|
181
184
|
}, opts.response);
|
|
182
|
-
const result = await withSpinner("Continuing...", () => continueWithDecisions(client, String(agent.id), opts.response, decisions, label));
|
|
183
|
-
await finishRun(command, client, { name, label }, result, { raw: !!opts.raw, interactive: false });
|
|
185
|
+
const result = await withSpinner("Continuing...", () => continueWithDecisions(client, String(agent.id), opts.response, decisions, label, model));
|
|
186
|
+
await finishRun(command, client, { name, label, model }, result, { raw: !!opts.raw, interactive: false });
|
|
184
187
|
});
|
|
185
188
|
});
|
|
186
189
|
}
|
|
@@ -32,9 +32,10 @@ export declare function decisionsFromAnswers(pending: ApprovalRow[], answers: Ma
|
|
|
32
32
|
/** Same item shape as n8n Decide Approval (#660). */
|
|
33
33
|
export declare function toApprovalItems(decisions: Decision[]): Record<string, string>[];
|
|
34
34
|
/**
|
|
35
|
-
* Continues on `agent/<agentId
|
|
36
|
-
* resolves the
|
|
37
|
-
*
|
|
35
|
+
* Continues on `agent/<agentId>[@<label>][#<model>]` with the label and model override the run used: the
|
|
36
|
+
* server resolves the continuation's tools, instructions and model from this reference, so both must match
|
|
37
|
+
* the run's or the continuation drops to another version or the agent's default model.
|
|
38
|
+
* Never the echoed `name@<versionNumber>` (it would 404 as a label).
|
|
38
39
|
*/
|
|
39
|
-
export declare function continueWithDecisions(client: ApiClient, agentId: string, responseId: string, decisions: Decision[], label?: string): Promise<ResponsesResult>;
|
|
40
|
+
export declare function continueWithDecisions(client: ApiClient, agentId: string, responseId: string, decisions: Decision[], label?: string, model?: string): Promise<ResponsesResult>;
|
|
40
41
|
//# sourceMappingURL=agent-decide.d.ts.map
|
package/dist/lib/agent-decide.js
CHANGED
|
@@ -109,13 +109,14 @@ export function toApprovalItems(decisions) {
|
|
|
109
109
|
}));
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
|
-
* Continues on `agent/<agentId
|
|
113
|
-
* resolves the
|
|
114
|
-
*
|
|
112
|
+
* Continues on `agent/<agentId>[@<label>][#<model>]` with the label and model override the run used: the
|
|
113
|
+
* server resolves the continuation's tools, instructions and model from this reference, so both must match
|
|
114
|
+
* the run's or the continuation drops to another version or the agent's default model.
|
|
115
|
+
* Never the echoed `name@<versionNumber>` (it would 404 as a label).
|
|
115
116
|
*/
|
|
116
|
-
export async function continueWithDecisions(client, agentId, responseId, decisions, label) {
|
|
117
|
+
export async function continueWithDecisions(client, agentId, responseId, decisions, label, model) {
|
|
117
118
|
const body = {
|
|
118
|
-
model:
|
|
119
|
+
model: `agent/${agentId}${label ? `@${label}` : ""}${model ? `#${model}` : ""}`,
|
|
119
120
|
previous_response_id: responseId,
|
|
120
121
|
stream: false,
|
|
121
122
|
input: toApprovalItems(decisions),
|
|
@@ -2,6 +2,7 @@ import type { components } from "../generated/openapi.js";
|
|
|
2
2
|
import type { getClient } from "./client.js";
|
|
3
3
|
export type ApiClient = ReturnType<typeof getClient>;
|
|
4
4
|
export type AgentDTO = components["schemas"]["AgentDTO"];
|
|
5
|
+
/** `name[@label][#model]`, split like the server: the model at the last `#`, then the label at the last `@`. */
|
|
5
6
|
export declare function splitAgentRef(ref: string): {
|
|
6
7
|
name: string;
|
|
7
8
|
label: string | undefined;
|
package/dist/lib/agent-lookup.js
CHANGED
|
@@ -3,8 +3,9 @@ import { paginationParams } from "./pagination.js";
|
|
|
3
3
|
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
4
4
|
const PAGE_SIZE = 100;
|
|
5
5
|
const MAX_PAGES = 50;
|
|
6
|
+
/** `name[@label][#model]`, split like the server: the model at the last `#`, then the label at the last `@`. */
|
|
6
7
|
export function splitAgentRef(ref) {
|
|
7
|
-
const hash = ref.
|
|
8
|
+
const hash = ref.lastIndexOf("#");
|
|
8
9
|
const model = hash >= 0 ? ref.slice(hash + 1) : undefined;
|
|
9
10
|
const base = hash >= 0 ? ref.slice(0, hash) : ref;
|
|
10
11
|
const at = base.lastIndexOf("@");
|
package/dist/lib/agent-run.js
CHANGED
|
@@ -24,8 +24,8 @@ export function extractResponseText(result) {
|
|
|
24
24
|
* any other `@` suffix stays part of the name.
|
|
25
25
|
*/
|
|
26
26
|
export function parseAgentModel(model) {
|
|
27
|
-
// Strip the `#<model>` override
|
|
28
|
-
const hash = (model ?? "").
|
|
27
|
+
// Strip the `#<model>` override (from the last `#`, as the server splits it) before matching.
|
|
28
|
+
const hash = (model ?? "").lastIndexOf("#");
|
|
29
29
|
const ref = hash >= 0 ? (model ?? "").slice(0, hash) : model ?? "";
|
|
30
30
|
const withVersion = /^agent\/(.+)@(\d+)$/.exec(ref);
|
|
31
31
|
if (withVersion)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@2kw/ai",
|
|
3
|
-
"version": "6.2.0-dev.
|
|
3
|
+
"version": "6.2.0-dev.26",
|
|
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",
|