@rudderhq/cli 0.3.4 → 0.3.5-canary.1
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/index.js +324 -14
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1630,7 +1630,7 @@ var init_agent = __esm({
|
|
|
1630
1630
|
init_model_fallbacks();
|
|
1631
1631
|
init_secret();
|
|
1632
1632
|
agentPermissionsSchema = z12.object({
|
|
1633
|
-
canCreateAgents: z12.boolean().optional().default(
|
|
1633
|
+
canCreateAgents: z12.boolean().optional().default(true),
|
|
1634
1634
|
canManageSkills: z12.boolean().optional().default(true)
|
|
1635
1635
|
});
|
|
1636
1636
|
agentInstructionsBundleModeSchema = z12.enum(["managed", "external"]);
|
|
@@ -7062,14 +7062,14 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
|
|
|
7062
7062
|
"When you mention Rudder entities in any user-visible Markdown output, prefer Rudder's renderable Markdown link syntax over plain IDs, bare URLs, or backticked references so the UI can render chips and navigate correctly.",
|
|
7063
7063
|
"",
|
|
7064
7064
|
"- Issues: use `[<identifier-or-title>](issue://<issue-id>)`; include `?c=<comment-id>` when linking to a specific comment.",
|
|
7065
|
-
"- Agents: use `[<agent-name>](agent://<agent-id>)` for reference-only links.
|
|
7065
|
+
"- Agents: use `[<agent-name>](agent://<agent-id>)` for reference-only links. In issue comments, use `[<agent-name>](agent://<agent-id>?intent=wake)` only when you intentionally want to wake that agent for attention or collaboration.",
|
|
7066
7066
|
"- Projects: use `[<project-name>](project://<project-id>)` when citing a Rudder project.",
|
|
7067
7067
|
"- Chat threads: use `[<chat-title>](chat://<conversation-id>)` when citing a Rudder chat conversation.",
|
|
7068
7068
|
'- Library files: use the `markdownLink` returned by `rudder library file ref "$RUDDER_PROJECT_LIBRARY_PATH/<relative-file>" --json`; do not hand-write `library-entry://...` links, and treat `library-file://...` as legacy path syntax only.',
|
|
7069
7069
|
"",
|
|
7070
7070
|
"Write these as normal Markdown links, not inside code spans or code blocks, unless you are literally documenting the syntax.",
|
|
7071
7071
|
"",
|
|
7072
|
-
"Mention-triggered comment wakes arrive with `RUDDER_WAKE_COMMENT_ID`; read that wake comment before acting.
|
|
7072
|
+
"Mention-triggered comment wakes arrive with `RUDDER_WAKE_COMMENT_ID`; read that wake comment before acting. Issue comments can wake an agent only with an explicit wake-intent agent link serialized as `agent://agent-id?intent=wake`. Plain structured links such as `agent://agent-id` are reference-only links for rendering and navigation, and plain text agent names are not wake requests. Use wake-intent links only when you intentionally want to wake another agent for attention or collaboration; omit the wake intent for ordinary references. Mentioning an agent requests attention or collaboration; it does not transfer issue ownership unless the comment also makes an explicit handoff and normal checkout rules allow it.",
|
|
7073
7073
|
"",
|
|
7074
7074
|
"When an issue comment, done comment, or blocker comment cites visual evidence from a local screenshot/image path, attach the image with the Rudder CLI `--image <path>` option instead of leaving only the filesystem path in the text.",
|
|
7075
7075
|
"",
|
|
@@ -7084,7 +7084,31 @@ var RUDDER_AGENT_OPERATING_CONTRACT = [
|
|
|
7084
7084
|
"## Safety Considerations",
|
|
7085
7085
|
"",
|
|
7086
7086
|
"- Never exfiltrate secrets or private data.",
|
|
7087
|
-
"- Do not perform any destructive commands unless explicitly requested by the board."
|
|
7087
|
+
"- Do not perform any destructive commands unless explicitly requested by the board.",
|
|
7088
|
+
"",
|
|
7089
|
+
"## Other",
|
|
7090
|
+
"- You can use `rudder` skill to see Agent best practise in Rudder. eg: update Agent profile, crud automation, manage library, project, org, curd agent run, chat, issue.",
|
|
7091
|
+
"- Before taking action, deeply analyze and research the existing information to ensure you have comprehensive context information before proceeding with the next action. You have your own goal, memory, skills, automation, library, project, org, use these resources to make better decisions.",
|
|
7092
|
+
"- When the user explicitly mentions previously handled issue, tasks or conversations, you need to retrieve the relevant tasks first before proceeding with the next action."
|
|
7093
|
+
].join("\n");
|
|
7094
|
+
var RUDDER_AGENT_HEARTBEAT_INSTRUCTION = [
|
|
7095
|
+
"# Rudder Heartbeat Instruction",
|
|
7096
|
+
"",
|
|
7097
|
+
"This section is injected by Rudder for heartbeat scene runs. It is the platform-owned timed-wakeup pipeline, not an agent-local `HEARTBEAT.md` file.",
|
|
7098
|
+
"",
|
|
7099
|
+
"## Heartbeat Pipeline",
|
|
7100
|
+
"",
|
|
7101
|
+
"1. Identify yourself and inspect wake context, including `RUDDER_TASK_ID`, `RUDDER_WAKE_REASON`, `RUDDER_WAKE_COMMENT_ID`, and `RUDDER_APPROVAL_ID` when present.",
|
|
7102
|
+
"2. Handle approval follow-up first: read the approval and linked issues, then close resolved work or comment on what remains.",
|
|
7103
|
+
"3. Inspect your Rudder inbox. Prioritize reviewer rows in `in_review` or `blocked`, then assignee `in_progress`, then assignee `todo`. Do not look for unassigned work.",
|
|
7104
|
+
"4. For mention wakes, read the wake comment before acting. Mentions request attention; they do not transfer ownership unless the comment explicitly says so.",
|
|
7105
|
+
"5. Checkout before doing assignee task work. A `409` means another agent owns the task; do not retry it.",
|
|
7106
|
+
"6. Load compact issue context, do one bounded useful chunk, and preserve evidence.",
|
|
7107
|
+
"7. Before exiting active work, leave exactly one durable signal: progress, done, blocked, explicit handoff, or structured review decision.",
|
|
7108
|
+
"8. Treat passive follow-up as close-out governance, not a fresh assignment.",
|
|
7109
|
+
"9. Treat review close-out follow-up as review governance; free-form accept/reject text is not a durable decision.",
|
|
7110
|
+
"",
|
|
7111
|
+
"Use the Rudder control-plane interface available in this runtime. CLI-capable runtimes should use the bundled `rudder` skill for command details, Library handoff rules, organization-skill workflow, and control-plane best practices. HTTP compatibility runtimes should follow the explicit HTTP workflow in their wake text; that workflow overrides CLI command guidance."
|
|
7088
7112
|
].join("\n");
|
|
7089
7113
|
|
|
7090
7114
|
// ../packages/agent-runtime-utils/dist/server-utils.cli.js
|
|
@@ -7777,6 +7801,54 @@ var AGENT_CLI_CAPABILITIES = [
|
|
|
7777
7801
|
requiresRunId: false,
|
|
7778
7802
|
attachesRunIdWhenAvailable: false
|
|
7779
7803
|
},
|
|
7804
|
+
{
|
|
7805
|
+
id: "automation.triggers.create",
|
|
7806
|
+
command: "rudder automation triggers create <automation-id> --kind <kind>",
|
|
7807
|
+
category: "automation",
|
|
7808
|
+
description: "Create a schedule, webhook, or API trigger through the governed automation API.",
|
|
7809
|
+
mutating: true,
|
|
7810
|
+
contract: "agent-v1",
|
|
7811
|
+
requiresOrgId: false,
|
|
7812
|
+
requiresAgentId: false,
|
|
7813
|
+
requiresRunId: false,
|
|
7814
|
+
attachesRunIdWhenAvailable: true
|
|
7815
|
+
},
|
|
7816
|
+
{
|
|
7817
|
+
id: "automation.triggers.update",
|
|
7818
|
+
command: "rudder automation triggers update <trigger-id>",
|
|
7819
|
+
category: "automation",
|
|
7820
|
+
description: "Update an automation trigger through the governed automation API.",
|
|
7821
|
+
mutating: true,
|
|
7822
|
+
contract: "agent-v1",
|
|
7823
|
+
requiresOrgId: false,
|
|
7824
|
+
requiresAgentId: false,
|
|
7825
|
+
requiresRunId: false,
|
|
7826
|
+
attachesRunIdWhenAvailable: true
|
|
7827
|
+
},
|
|
7828
|
+
{
|
|
7829
|
+
id: "automation.triggers.delete",
|
|
7830
|
+
command: "rudder automation triggers delete <trigger-id>",
|
|
7831
|
+
category: "automation",
|
|
7832
|
+
description: "Delete an automation trigger through the governed automation API.",
|
|
7833
|
+
mutating: true,
|
|
7834
|
+
contract: "agent-v1",
|
|
7835
|
+
requiresOrgId: false,
|
|
7836
|
+
requiresAgentId: false,
|
|
7837
|
+
requiresRunId: false,
|
|
7838
|
+
attachesRunIdWhenAvailable: true
|
|
7839
|
+
},
|
|
7840
|
+
{
|
|
7841
|
+
id: "automation.triggers.rotate-secret",
|
|
7842
|
+
command: "rudder automation triggers rotate-secret <trigger-id>",
|
|
7843
|
+
category: "automation",
|
|
7844
|
+
description: "Rotate an automation webhook trigger secret through the governed automation API.",
|
|
7845
|
+
mutating: true,
|
|
7846
|
+
contract: "agent-v1",
|
|
7847
|
+
requiresOrgId: false,
|
|
7848
|
+
requiresAgentId: false,
|
|
7849
|
+
requiresRunId: false,
|
|
7850
|
+
attachesRunIdWhenAvailable: true
|
|
7851
|
+
},
|
|
7780
7852
|
{
|
|
7781
7853
|
id: "automation.create",
|
|
7782
7854
|
command: "rudder automation create --org-id <id> --title <title> --assignee-agent-id <id>",
|
|
@@ -7925,11 +7997,11 @@ var AGENT_CLI_CAPABILITIES = [
|
|
|
7925
7997
|
id: "chat.send",
|
|
7926
7998
|
command: "rudder chat send <chat-id> --body <text>",
|
|
7927
7999
|
category: "chat",
|
|
7928
|
-
description: "Send
|
|
8000
|
+
description: "Send an agent-authored message directly to the operator in a chat.",
|
|
7929
8001
|
mutating: true,
|
|
7930
8002
|
contract: "agent-v1",
|
|
7931
8003
|
requiresOrgId: false,
|
|
7932
|
-
requiresAgentId:
|
|
8004
|
+
requiresAgentId: true,
|
|
7933
8005
|
requiresRunId: false,
|
|
7934
8006
|
attachesRunIdWhenAvailable: true
|
|
7935
8007
|
},
|
|
@@ -7947,9 +8019,21 @@ var AGENT_CLI_CAPABILITIES = [
|
|
|
7947
8019
|
},
|
|
7948
8020
|
{
|
|
7949
8021
|
id: "runs.list",
|
|
7950
|
-
command: "rudder runs list --org-id <id>",
|
|
8022
|
+
command: "rudder runs list --org-id <id> [--used-skill <skill>] [--loaded-skill <skill>]",
|
|
8023
|
+
category: "runs",
|
|
8024
|
+
description: "List observed agent runs with filters for status, agent, issue, runtime, time, and skill evidence; used-skill means actual usage and loaded-skill is opt-in.",
|
|
8025
|
+
mutating: false,
|
|
8026
|
+
contract: "agent-v1",
|
|
8027
|
+
requiresOrgId: true,
|
|
8028
|
+
requiresAgentId: false,
|
|
8029
|
+
requiresRunId: false,
|
|
8030
|
+
attachesRunIdWhenAvailable: false
|
|
8031
|
+
},
|
|
8032
|
+
{
|
|
8033
|
+
id: "runs.by-skill",
|
|
8034
|
+
command: "rudder runs by-skill <skill> --org-id <id> [--evidence <used-or-loaded>]",
|
|
7951
8035
|
category: "runs",
|
|
7952
|
-
description: "
|
|
8036
|
+
description: "Build a skill evidence packet from recent runs; defaults to actual usage and returns status counts, agents, issues, common errors, rows, and transcript/errors follow-up commands.",
|
|
7953
8037
|
mutating: false,
|
|
7954
8038
|
contract: "agent-v1",
|
|
7955
8039
|
requiresOrgId: true,
|
|
@@ -8911,6 +8995,7 @@ function registerClientAuthCommands(auth) {
|
|
|
8911
8995
|
init_dist();
|
|
8912
8996
|
function registerAutomationCommands(program) {
|
|
8913
8997
|
const automation = program.command("automation").description("Automation operations");
|
|
8998
|
+
const triggers = automation.command("triggers").description("Automation trigger operations");
|
|
8914
8999
|
addCommonClientOptions(
|
|
8915
9000
|
automation.command("list").description(getAgentCliCapabilityById("automation.list").description).option("-O, --org-id <id>", "Organization ID").option("--status <status>", "Filter by automation status").option("--assignee-agent-id <id>", "Filter by assignee agent ID").option("--project-id <id>", "Filter by project ID").option("--output-mode <mode>", "Filter by output mode").action(async (opts) => {
|
|
8916
9001
|
try {
|
|
@@ -8953,12 +9038,68 @@ function registerAutomationCommands(program) {
|
|
|
8953
9038
|
})
|
|
8954
9039
|
);
|
|
8955
9040
|
addCommonClientOptions(
|
|
8956
|
-
|
|
9041
|
+
triggers.command("list").description(getAgentCliCapabilityById("automation.triggers.list").description).argument("<automationId>", "Automation ID").action(async (automationId, opts) => {
|
|
8957
9042
|
try {
|
|
8958
9043
|
const ctx = resolveCommandContext(opts);
|
|
8959
9044
|
const row = await ctx.api.get(`/api/automations/${encodeURIComponent(automationId)}`);
|
|
8960
|
-
const
|
|
8961
|
-
printOutput(
|
|
9045
|
+
const triggers2 = row?.triggers ?? [];
|
|
9046
|
+
printOutput(triggers2, { json: ctx.json });
|
|
9047
|
+
} catch (err) {
|
|
9048
|
+
handleCommandError(err);
|
|
9049
|
+
}
|
|
9050
|
+
})
|
|
9051
|
+
);
|
|
9052
|
+
addCommonClientOptions(
|
|
9053
|
+
triggers.command("create").description(getAgentCliCapabilityById("automation.triggers.create").description).argument("<automationId>", "Automation ID").option("--payload <json>", "Raw automation trigger create payload JSON").option("--kind <kind>", "Trigger kind: schedule, webhook, or api").option("--label <label>", "Trigger label").option("--enabled", "Create the trigger enabled").option("--disabled", "Create the trigger disabled").option("--cron-expression <expr>", "Schedule cron expression").option("--timezone <timezone>", "Schedule timezone; defaults to UTC for schedule triggers").option("--signing-mode <mode>", "Webhook signing mode").option("--replay-window-sec <seconds>", "Webhook replay window in seconds").action(async (automationId, opts) => {
|
|
9054
|
+
try {
|
|
9055
|
+
const ctx = resolveCommandContext(opts);
|
|
9056
|
+
const payload = createAutomationTriggerSchema.parse(buildAutomationTriggerPayload(opts));
|
|
9057
|
+
const created = await ctx.api.post(
|
|
9058
|
+
`/api/automations/${encodeURIComponent(automationId)}/triggers`,
|
|
9059
|
+
payload
|
|
9060
|
+
);
|
|
9061
|
+
printOutput(created, { json: ctx.json });
|
|
9062
|
+
} catch (err) {
|
|
9063
|
+
handleCommandError(err);
|
|
9064
|
+
}
|
|
9065
|
+
})
|
|
9066
|
+
);
|
|
9067
|
+
addCommonClientOptions(
|
|
9068
|
+
triggers.command("update").description(getAgentCliCapabilityById("automation.triggers.update").description).argument("<triggerId>", "Automation trigger ID").option("--payload <json>", "Raw automation trigger update payload JSON").option("--label <label>", "Trigger label").option("--enabled", "Enable the trigger").option("--disabled", "Disable the trigger").option("--cron-expression <expr>", "Schedule cron expression").option("--timezone <timezone>", "Schedule timezone").option("--signing-mode <mode>", "Webhook signing mode").option("--replay-window-sec <seconds>", "Webhook replay window in seconds").action(async (triggerId, opts) => {
|
|
9069
|
+
try {
|
|
9070
|
+
const ctx = resolveCommandContext(opts);
|
|
9071
|
+
const payload = updateAutomationTriggerSchema.parse(buildAutomationTriggerPayload(opts));
|
|
9072
|
+
const updated = await ctx.api.patch(
|
|
9073
|
+
`/api/automation-triggers/${encodeURIComponent(triggerId)}`,
|
|
9074
|
+
payload
|
|
9075
|
+
);
|
|
9076
|
+
printOutput(updated, { json: ctx.json });
|
|
9077
|
+
} catch (err) {
|
|
9078
|
+
handleCommandError(err);
|
|
9079
|
+
}
|
|
9080
|
+
})
|
|
9081
|
+
);
|
|
9082
|
+
addCommonClientOptions(
|
|
9083
|
+
triggers.command("delete").description(getAgentCliCapabilityById("automation.triggers.delete").description).argument("<triggerId>", "Automation trigger ID").action(async (triggerId, opts) => {
|
|
9084
|
+
try {
|
|
9085
|
+
const ctx = resolveCommandContext(opts);
|
|
9086
|
+
await ctx.api.delete(`/api/automation-triggers/${encodeURIComponent(triggerId)}`);
|
|
9087
|
+
printOutput({ id: triggerId, deleted: true }, { json: ctx.json });
|
|
9088
|
+
} catch (err) {
|
|
9089
|
+
handleCommandError(err);
|
|
9090
|
+
}
|
|
9091
|
+
})
|
|
9092
|
+
);
|
|
9093
|
+
addCommonClientOptions(
|
|
9094
|
+
triggers.command("rotate-secret").description(getAgentCliCapabilityById("automation.triggers.rotate-secret").description).argument("<triggerId>", "Automation trigger ID").action(async (triggerId, opts) => {
|
|
9095
|
+
try {
|
|
9096
|
+
const ctx = resolveCommandContext(opts);
|
|
9097
|
+
const payload = rotateAutomationTriggerSecretSchema.parse({});
|
|
9098
|
+
const rotated = await ctx.api.post(
|
|
9099
|
+
`/api/automation-triggers/${encodeURIComponent(triggerId)}/rotate-secret`,
|
|
9100
|
+
payload
|
|
9101
|
+
);
|
|
9102
|
+
printOutput(rotated, { json: ctx.json });
|
|
8962
9103
|
} catch (err) {
|
|
8963
9104
|
handleCommandError(err);
|
|
8964
9105
|
}
|
|
@@ -9052,6 +9193,36 @@ function buildAutomationPayload(opts) {
|
|
|
9052
9193
|
})
|
|
9053
9194
|
};
|
|
9054
9195
|
}
|
|
9196
|
+
function buildAutomationTriggerPayload(opts) {
|
|
9197
|
+
return {
|
|
9198
|
+
...parseJsonObjectOption(opts.payload, "--payload"),
|
|
9199
|
+
...definedRecord({
|
|
9200
|
+
kind: "kind" in opts ? opts.kind : void 0,
|
|
9201
|
+
label: opts.label,
|
|
9202
|
+
enabled: parseEnabledOption(opts),
|
|
9203
|
+
cronExpression: opts.cronExpression,
|
|
9204
|
+
timezone: opts.timezone,
|
|
9205
|
+
signingMode: opts.signingMode,
|
|
9206
|
+
replayWindowSec: parseOptionalIntegerOption(opts.replayWindowSec, "--replay-window-sec")
|
|
9207
|
+
})
|
|
9208
|
+
};
|
|
9209
|
+
}
|
|
9210
|
+
function parseEnabledOption(opts) {
|
|
9211
|
+
if (opts.enabled && opts.disabled) {
|
|
9212
|
+
throw new Error("Pass only one of --enabled or --disabled");
|
|
9213
|
+
}
|
|
9214
|
+
if (opts.enabled) return true;
|
|
9215
|
+
if (opts.disabled) return false;
|
|
9216
|
+
return void 0;
|
|
9217
|
+
}
|
|
9218
|
+
function parseOptionalIntegerOption(value, label) {
|
|
9219
|
+
if (value === void 0) return void 0;
|
|
9220
|
+
const parsed = Number(value);
|
|
9221
|
+
if (!Number.isInteger(parsed)) {
|
|
9222
|
+
throw new Error(`${label} must be an integer`);
|
|
9223
|
+
}
|
|
9224
|
+
return parsed;
|
|
9225
|
+
}
|
|
9055
9226
|
function definedRecord(record) {
|
|
9056
9227
|
return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== void 0));
|
|
9057
9228
|
}
|
|
@@ -11615,8 +11786,9 @@ function projectPath(projectRef, orgId) {
|
|
|
11615
11786
|
function registerRunsCommands(program) {
|
|
11616
11787
|
const runs = program.command("runs").description("Run debugging operations");
|
|
11617
11788
|
addCommonClientOptions(
|
|
11618
|
-
runs.command("list").description(getAgentCliCapabilityById("runs.list").description).option("-O, --org-id <id>", "Organization ID").option("--updated-after <iso>", "Only runs updated after this timestamp").option("--run-id-prefix <prefix>", "Filter by run ID prefix").option("--agent-id <id>", "Filter by agent ID").option("--status <status>", "Filter by run status").option("--runtime <type>", "Filter by runtime type").option("--issue-id <id>", "Filter by linked issue ID").option("--created-before <iso>", "Only runs created before this timestamp").option("--limit <n>", "Maximum rows", "200").action(async (opts) => {
|
|
11789
|
+
runs.command("list").description(getAgentCliCapabilityById("runs.list").description).option("-O, --org-id <id>", "Organization ID").option("--updated-after <iso>", "Only runs updated after this timestamp").option("--run-id-prefix <prefix>", "Filter by run ID prefix").option("--agent-id <id>", "Filter by agent ID").option("--status <status>", "Filter by run status").option("--runtime <type>", "Filter by runtime type").option("--issue-id <id>", "Filter by linked issue ID").option("--used-skill <key-or-name>", "Filter by skill actually used during the run").option("--loaded-skill <key-or-name>", "Filter by skill loaded for the run").option("--created-before <iso>", "Only runs created before this timestamp").option("--limit <n>", "Maximum rows", "200").action(async (opts) => {
|
|
11619
11790
|
try {
|
|
11791
|
+
assertSingleSkillFilter(opts);
|
|
11620
11792
|
const ctx = resolveCommandContext(opts, { requireCompany: true });
|
|
11621
11793
|
const rows = await ctx.api.get(`/api/run-intelligence/orgs/${ctx.orgId}/runs?${buildRunsListQuery(opts)}`) ?? [];
|
|
11622
11794
|
printOutput(ctx.json ? rows : rows.map(formatRunListRow), { json: ctx.json });
|
|
@@ -11626,6 +11798,21 @@ function registerRunsCommands(program) {
|
|
|
11626
11798
|
}),
|
|
11627
11799
|
{ includeCompany: false }
|
|
11628
11800
|
);
|
|
11801
|
+
addCommonClientOptions(
|
|
11802
|
+
runs.command("by-skill").description(getAgentCliCapabilityById("runs.by-skill").description).argument("<skill>", "Skill key or display name").option("-O, --org-id <id>", "Organization ID").option("--evidence <used|loaded>", "Evidence type to match; defaults to used", "used").option("--agent-id <id>", "Filter by agent ID").option("--status <status>", "Filter by run status").option("--runtime <type>", "Filter by runtime type").option("--issue-id <id>", "Filter by linked issue ID").option("--created-before <iso>", "Only runs created before this timestamp").option("--limit <n>", "Maximum rows", "50").action(async (skill, opts) => {
|
|
11803
|
+
try {
|
|
11804
|
+
const evidenceType = parseSkillEvidenceType(opts.evidence);
|
|
11805
|
+
const ctx = resolveCommandContext(opts, { requireCompany: true });
|
|
11806
|
+
const params = buildRunsBySkillQuery(skill, opts, evidenceType);
|
|
11807
|
+
const rows = await ctx.api.get(`/api/run-intelligence/orgs/${ctx.orgId}/runs?${params}`) ?? [];
|
|
11808
|
+
const report = buildSkillRunReport(skill, evidenceType, rows);
|
|
11809
|
+
printOutput(ctx.json ? report : formatSkillRunReport(report), { json: ctx.json });
|
|
11810
|
+
} catch (err) {
|
|
11811
|
+
handleCommandError(err);
|
|
11812
|
+
}
|
|
11813
|
+
}),
|
|
11814
|
+
{ includeCompany: false }
|
|
11815
|
+
);
|
|
11629
11816
|
addCommonClientOptions(
|
|
11630
11817
|
runs.command("get").description(getAgentCliCapabilityById("runs.get").description).argument("<runId>", "Run ID").action(async (runId, opts) => {
|
|
11631
11818
|
try {
|
|
@@ -11728,10 +11915,33 @@ function buildRunsListQuery(opts) {
|
|
|
11728
11915
|
if (opts.status) params.set("status", opts.status);
|
|
11729
11916
|
if (opts.runtime) params.set("runtime", opts.runtime);
|
|
11730
11917
|
if (opts.issueId) params.set("issueId", opts.issueId);
|
|
11918
|
+
if (opts.usedSkill) params.set("usedSkill", opts.usedSkill);
|
|
11919
|
+
if (opts.loadedSkill) params.set("loadedSkill", opts.loadedSkill);
|
|
11920
|
+
if (opts.createdBefore) params.set("createdBefore", opts.createdBefore);
|
|
11921
|
+
if (opts.limit) params.set("limit", opts.limit);
|
|
11922
|
+
return params.toString();
|
|
11923
|
+
}
|
|
11924
|
+
function buildRunsBySkillQuery(skill, opts, evidenceType) {
|
|
11925
|
+
const params = new URLSearchParams();
|
|
11926
|
+
params.set(evidenceType === "used" ? "usedSkill" : "loadedSkill", skill);
|
|
11927
|
+
if (opts.agentId) params.set("agentId", opts.agentId);
|
|
11928
|
+
if (opts.status) params.set("status", opts.status);
|
|
11929
|
+
if (opts.runtime) params.set("runtime", opts.runtime);
|
|
11930
|
+
if (opts.issueId) params.set("issueId", opts.issueId);
|
|
11731
11931
|
if (opts.createdBefore) params.set("createdBefore", opts.createdBefore);
|
|
11732
11932
|
if (opts.limit) params.set("limit", opts.limit);
|
|
11733
11933
|
return params.toString();
|
|
11734
11934
|
}
|
|
11935
|
+
function assertSingleSkillFilter(opts) {
|
|
11936
|
+
if (opts.usedSkill && opts.loadedSkill) {
|
|
11937
|
+
throw new Error("Use either --used-skill or --loaded-skill, not both.");
|
|
11938
|
+
}
|
|
11939
|
+
}
|
|
11940
|
+
function parseSkillEvidenceType(value) {
|
|
11941
|
+
const normalized = (value ?? "used").trim().toLowerCase();
|
|
11942
|
+
if (normalized === "used" || normalized === "loaded") return normalized;
|
|
11943
|
+
throw new Error("--evidence must be either 'used' or 'loaded'.");
|
|
11944
|
+
}
|
|
11735
11945
|
function buildTranscriptQuery(opts, output) {
|
|
11736
11946
|
const params = new URLSearchParams();
|
|
11737
11947
|
if (opts.errorsOnly) params.set("errorsOnly", "true");
|
|
@@ -11752,10 +11962,110 @@ function formatRunListRow(row) {
|
|
|
11752
11962
|
status: row.run.status,
|
|
11753
11963
|
agent: row.agentName ?? row.run.agentId,
|
|
11754
11964
|
runtime: row.bundle.agentRuntimeType,
|
|
11755
|
-
issue: row.issue
|
|
11756
|
-
|
|
11965
|
+
issue: formatIssueRef(row.issue),
|
|
11966
|
+
createdAt: row.run.createdAt,
|
|
11967
|
+
finishedAt: row.run.finishedAt ?? "-",
|
|
11968
|
+
evidence: row.skillEvidence?.evidenceType ?? "-",
|
|
11969
|
+
skill: row.skillEvidence?.matchedSkillKey ?? "-",
|
|
11970
|
+
langfuse: readLangfuseTraceUrl(row.langfuse) ?? "-",
|
|
11971
|
+
error: row.errorSummary ?? "-",
|
|
11972
|
+
next: row.run.status === "failed" ? `rudder runs errors ${row.run.id}` : `rudder runs transcript ${row.run.id}`
|
|
11973
|
+
};
|
|
11974
|
+
}
|
|
11975
|
+
function buildSkillRunReport(skill, evidenceType, rows) {
|
|
11976
|
+
const statusCounts = {
|
|
11977
|
+
succeeded: 0,
|
|
11978
|
+
failed: 0,
|
|
11979
|
+
cancelled: 0,
|
|
11980
|
+
timedOut: 0,
|
|
11981
|
+
running: 0,
|
|
11982
|
+
queued: 0,
|
|
11983
|
+
other: 0
|
|
11984
|
+
};
|
|
11985
|
+
const agents = /* @__PURE__ */ new Map();
|
|
11986
|
+
const issues = /* @__PURE__ */ new Map();
|
|
11987
|
+
const errors = /* @__PURE__ */ new Map();
|
|
11988
|
+
for (const row of rows) {
|
|
11989
|
+
const status = row.run.status;
|
|
11990
|
+
if (status === "succeeded") statusCounts.succeeded += 1;
|
|
11991
|
+
else if (status === "failed") statusCounts.failed += 1;
|
|
11992
|
+
else if (status === "cancelled") statusCounts.cancelled += 1;
|
|
11993
|
+
else if (status === "timed_out") statusCounts.timedOut += 1;
|
|
11994
|
+
else if (status === "running") statusCounts.running += 1;
|
|
11995
|
+
else if (status === "queued") statusCounts.queued += 1;
|
|
11996
|
+
else statusCounts.other += 1;
|
|
11997
|
+
const agent = agents.get(row.run.agentId) ?? { id: row.run.agentId, name: row.agentName, count: 0 };
|
|
11998
|
+
agent.count += 1;
|
|
11999
|
+
agents.set(agent.id, agent);
|
|
12000
|
+
if (row.issue) {
|
|
12001
|
+
const issue = issues.get(row.issue.id) ?? { ...row.issue, count: 0 };
|
|
12002
|
+
issue.count += 1;
|
|
12003
|
+
issues.set(issue.id, issue);
|
|
12004
|
+
}
|
|
12005
|
+
const error = row.errorSummary?.trim();
|
|
12006
|
+
if (error) errors.set(error, (errors.get(error) ?? 0) + 1);
|
|
12007
|
+
}
|
|
12008
|
+
return {
|
|
12009
|
+
skill: { query: skill, evidenceType },
|
|
12010
|
+
summary: {
|
|
12011
|
+
total: rows.length,
|
|
12012
|
+
...statusCounts,
|
|
12013
|
+
agents: [...agents.values()].sort((a, b) => b.count - a.count),
|
|
12014
|
+
issues: [...issues.values()].sort((a, b) => b.count - a.count),
|
|
12015
|
+
commonErrors: [...errors.entries()].map(([summary, count]) => ({ summary, count })).sort((a, b) => b.count - a.count).slice(0, 5)
|
|
12016
|
+
},
|
|
12017
|
+
rows,
|
|
12018
|
+
nextCommands: rows.slice(0, 5).map((row) => row.run.status === "failed" ? `rudder runs errors ${row.run.id}` : `rudder runs transcript ${row.run.id}`)
|
|
11757
12019
|
};
|
|
11758
12020
|
}
|
|
12021
|
+
function formatSkillRunReport(report) {
|
|
12022
|
+
const lines = [
|
|
12023
|
+
`skill=${report.skill.query} evidence=${report.skill.evidenceType} total=${report.summary.total} succeeded=${report.summary.succeeded} failed=${report.summary.failed} cancelled=${report.summary.cancelled} timedOut=${report.summary.timedOut}`
|
|
12024
|
+
];
|
|
12025
|
+
if (report.summary.agents.length > 0) {
|
|
12026
|
+
lines.push(`agents=${report.summary.agents.map((agent) => `${agent.name ?? agent.id}:${agent.count}`).join(", ")}`);
|
|
12027
|
+
}
|
|
12028
|
+
if (report.summary.issues.length > 0) {
|
|
12029
|
+
lines.push(`issues=${report.summary.issues.map((issue) => `${issue.identifier ?? issue.id}:${issue.count}`).join(", ")}`);
|
|
12030
|
+
}
|
|
12031
|
+
if (report.summary.commonErrors.length > 0) {
|
|
12032
|
+
lines.push(`commonErrors=${report.summary.commonErrors.map((error) => `${clip2(error.summary, 80)}:${error.count}`).join(" | ")}`);
|
|
12033
|
+
}
|
|
12034
|
+
lines.push(...report.rows.map((row) => formatInlineSkillRun(row)));
|
|
12035
|
+
if (report.nextCommands.length > 0) {
|
|
12036
|
+
lines.push("next:");
|
|
12037
|
+
lines.push(...report.nextCommands.map((command) => ` ${command}`));
|
|
12038
|
+
}
|
|
12039
|
+
return lines;
|
|
12040
|
+
}
|
|
12041
|
+
function formatInlineSkillRun(row) {
|
|
12042
|
+
const issue = formatIssueRef(row.issue);
|
|
12043
|
+
const label = row.skillEvidence?.matchedSkillLabel && row.skillEvidence.matchedSkillLabel !== row.skillEvidence.matchedSkillKey ? ` label=${row.skillEvidence.matchedSkillLabel}` : "";
|
|
12044
|
+
const langfuse = readLangfuseTraceUrl(row.langfuse);
|
|
12045
|
+
return [
|
|
12046
|
+
`id=${row.run.id}`,
|
|
12047
|
+
`status=${row.run.status}`,
|
|
12048
|
+
`agent=${row.agentName ?? row.run.agentId}`,
|
|
12049
|
+
`issue=${issue}`,
|
|
12050
|
+
`runtime=${row.bundle.agentRuntimeType}`,
|
|
12051
|
+
`createdAt=${row.run.createdAt}`,
|
|
12052
|
+
`finishedAt=${row.run.finishedAt ?? "-"}`,
|
|
12053
|
+
`evidence=${row.skillEvidence?.evidenceType ?? "-"}`,
|
|
12054
|
+
`skill=${row.skillEvidence?.matchedSkillKey ?? "-"}${label}`,
|
|
12055
|
+
`langfuse=${langfuse ?? "-"}`,
|
|
12056
|
+
`error=${row.errorSummary ?? "-"}`,
|
|
12057
|
+
`next=${row.run.status === "failed" ? `rudder runs errors ${row.run.id}` : `rudder runs transcript ${row.run.id}`}`
|
|
12058
|
+
].join(" ");
|
|
12059
|
+
}
|
|
12060
|
+
function formatIssueRef(issue) {
|
|
12061
|
+
if (!issue) return "-";
|
|
12062
|
+
return issue.identifier && issue.title ? `${issue.identifier} ${issue.title}` : issue.identifier ?? issue.title ?? issue.id;
|
|
12063
|
+
}
|
|
12064
|
+
function readLangfuseTraceUrl(value) {
|
|
12065
|
+
if (!value || typeof value !== "object") return null;
|
|
12066
|
+
const traceUrl = value.traceUrl;
|
|
12067
|
+
return typeof traceUrl === "string" && traceUrl.length > 0 ? traceUrl : null;
|
|
12068
|
+
}
|
|
11759
12069
|
function formatRunEvent(row) {
|
|
11760
12070
|
return {
|
|
11761
12071
|
seq: row.seq,
|