@duvoai/cli 1.4.0 → 1.5.0

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/bin/duvo.js CHANGED
@@ -1668,6 +1668,26 @@ var evalScoresResponseSchema = z8.object({
1668
1668
  with_issues: z8.int(),
1669
1669
  flag_distribution: z8.array(evalFlagCountSchema)
1670
1670
  });
1671
+ var evalRubricSchema = z8.object({
1672
+ id: z8.guid(),
1673
+ slug: z8.string(),
1674
+ title: z8.string(),
1675
+ description: z8.string(),
1676
+ sort_order: z8.number(),
1677
+ deleted_at: z8.string().nullable()
1678
+ });
1679
+ var platformEvalRubricSchema = z8.object({
1680
+ key: z8.string(),
1681
+ label: z8.string(),
1682
+ description: z8.string(),
1683
+ cause: z8.string()
1684
+ });
1685
+ var evalRubricsResponseSchema = z8.object({
1686
+ /** Assignment-specific rubrics persisted in `agent_eval_rubric`. */
1687
+ rubrics: z8.array(evalRubricSchema),
1688
+ /** Platform default rubrics sourced from `EVALUATION_RUBRIC_CATALOG`. */
1689
+ platform_rubrics: z8.array(platformEvalRubricSchema)
1690
+ });
1671
1691
  var evalCountsSchema = z8.object({
1672
1692
  total_evaluated: z8.int(),
1673
1693
  with_issues: z8.int()
@@ -2018,6 +2038,28 @@ function isLegacyModelId(model) {
2018
2038
  }
2019
2039
  __name(isLegacyModelId, "isLegacyModelId");
2020
2040
  __name2(isLegacyModelId, "isLegacyModelId");
2041
+ var CONTEXT_1M_MARKER = "[1m]";
2042
+ var RUNTIME_AUXILIARY_MODEL_IDS = [
2043
+ "claude-haiku-4-5-20251001"
2044
+ ];
2045
+ function buildModelAliasesForProvider(provider) {
2046
+ if (provider === "bedrock") {
2047
+ const aliasableModelIds = [
2048
+ ...CLAUDE_MODEL_IDS,
2049
+ ...RUNTIME_AUXILIARY_MODEL_IDS
2050
+ ];
2051
+ return Object.fromEntries(
2052
+ aliasableModelIds.map((id) => {
2053
+ const bareId = id.endsWith(CONTEXT_1M_MARKER) ? id.slice(0, -CONTEXT_1M_MARKER.length) : id;
2054
+ const marker = id.slice(bareId.length);
2055
+ return [id, `${bareId}-bedrock${marker}`];
2056
+ })
2057
+ );
2058
+ }
2059
+ return {};
2060
+ }
2061
+ __name(buildModelAliasesForProvider, "buildModelAliasesForProvider");
2062
+ __name2(buildModelAliasesForProvider, "buildModelAliasesForProvider");
2021
2063
  var AGENT_CONFIG_VERSION = "v2";
2022
2064
  var DEFAULT_BROWSER_PROVIDER = "browserbase";
2023
2065
  var LEGACY_DEFAULT_BROWSER_PROVIDER = "browserbase";
@@ -3293,41 +3335,22 @@ var stepEdgeSchema = z14.object({
3293
3335
  "True on exactly one outgoing edge of an exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges."
3294
3336
  )
3295
3337
  });
3296
- var clarityStepBaseSchema = z14.object({
3338
+ var baseStepFields = {
3297
3339
  id: z14.string().min(1).describe(
3298
3340
  'Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: "step-review-invoice"'
3299
3341
  ),
3300
- nodeType: z14.enum(PROCESS_FLOW_NODE_TYPES).describe(
3301
- 'BPMN top-level category. "event" for things that happen (start/end/timer/message/escalation), "task" for work performed, "gateway" for branching decisions.'
3302
- ),
3303
- nodeSubtype: z14.enum([
3304
- ...PROCESS_FLOW_EVENT_SUBTYPES,
3305
- ...PROCESS_FLOW_TASK_SUBTYPES,
3306
- ...PROCESS_FLOW_GATEWAY_SUBTYPES
3307
- ]).describe(
3308
- 'Specific BPMN element. Events: "start", "end", "timer", "message", "escalation". Tasks: "user", "service", "send", "receive", "manual", "businessRule", "script". Gateways: "exclusive", "parallel", "inclusive".'
3309
- ),
3310
3342
  targetSteps: z14.array(stepEdgeSchema).describe(
3311
3343
  "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways must have \u22652 entries with exactly one isDefault: true."
3312
3344
  ),
3313
3345
  title: z14.string().min(1).describe(
3314
- `Short action-oriented heading, 2-5 words. Used as the step's name in lists and BPMN node labels. Example: "Review invoice"`
3315
- ),
3316
- description: z14.string().min(1).describe(
3317
- 'Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: "Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval."'
3346
+ 'Required node label used in lists and BPMN node labels. Structural markers use defaults such as "Start" and "End".'
3318
3347
  ),
3319
3348
  action: z14.string().min(1).nullable().describe(
3320
3349
  'Verb-led one-liner summarizing the concrete action performed. Example: "Reviews invoice line items in NetSuite against the purchase order."'
3321
3350
  ),
3322
- rationale: z14.string().min(1).describe(
3323
- 'Why this step exists in the process \u2014 its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: "Catches mispriced line items before they reach the customer and prevents downstream credit notes."'
3324
- ),
3325
3351
  role: z14.string().min(1).nullable().describe(
3326
3352
  'Performer of this step \u2014 the specific job title, team, or system. Use "Duvo" for automated actions and "System" for system-triggered steps. Examples: "Finance Analyst", "Sales Operations", "Duvo", "System"'
3327
3353
  ),
3328
- sources: z14.array(stepSourceSchema).min(1).describe(
3329
- "Evidence supporting this step's existence and details. At least one source is required \u2014 every step must trace back to something in the captures."
3330
- ),
3331
3354
  system: z14.string().nullable().describe(
3332
3355
  'System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: "NetSuite", "Gmail", "Excel", null'
3333
3356
  ),
@@ -3337,9 +3360,6 @@ var clarityStepBaseSchema = z14.object({
3337
3360
  output: z14.string().nullable().describe(
3338
3361
  'What this step produces or updates. Null on pure waits or events that emit nothing. Example: "Approved invoice record in NetSuite with reviewer signature"'
3339
3362
  ),
3340
- condition: z14.string().nullable().describe(
3341
- 'Decision criteria or precondition that gates this step. Null when the step is unconditional. For gateway nodes, this is the question being evaluated. Example: "Only when invoice total exceeds $10,000"'
3342
- ),
3343
3363
  exception: z14.string().nullable().describe(
3344
3364
  'Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: "Customer disputes line items or PO number does not match"'
3345
3365
  ),
@@ -3355,7 +3375,66 @@ var clarityStepBaseSchema = z14.object({
3355
3375
  confidence: z14.enum(["low", "medium", "high"]).describe(
3356
3376
  'Confidence in the accuracy of this step given evidence quality and completeness. "high" = directly stated by multiple sources, "medium" = stated by one source or inferred from strong signals, "low" = inferred with significant assumptions.'
3357
3377
  )
3378
+ };
3379
+ var eventStepSchema = z14.object({
3380
+ ...baseStepFields,
3381
+ nodeType: z14.literal("event"),
3382
+ nodeSubtype: z14.enum(PROCESS_FLOW_EVENT_SUBTYPES).describe(
3383
+ 'BPMN event subtype. "start" (entry trigger), "end" (terminal state), "timer" (time-based wait), "message" (external communication), "escalation" (route to higher authority).'
3384
+ ),
3385
+ description: z14.string().min(1).nullable().describe(
3386
+ "Optional prose describing what happens at this event. May be null for structural markers."
3387
+ ),
3388
+ rationale: z14.string().min(1).nullable().describe(
3389
+ "Optional reason for the event's existence. May be null for structural markers."
3390
+ ),
3391
+ sources: z14.array(stepSourceSchema).describe(
3392
+ "Evidence supporting this event. Empty array allowed (structural markers carry no evidence); non-empty values must follow the source schema."
3393
+ ),
3394
+ condition: z14.string().nullable().describe(
3395
+ "Always null on events; included for shape compatibility across variants."
3396
+ )
3358
3397
  });
3398
+ var taskStepSchema = z14.object({
3399
+ ...baseStepFields,
3400
+ nodeType: z14.literal("task"),
3401
+ nodeSubtype: z14.enum(PROCESS_FLOW_TASK_SUBTYPES).describe(
3402
+ 'BPMN task subtype. "user" (human work), "service" (automated/API call), "send"/"receive" (messaging), "manual" (offline physical work), "businessRule" (rule engine), "script" (code execution).'
3403
+ ),
3404
+ description: z14.string().min(1).describe(
3405
+ 'Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: "Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval."'
3406
+ ),
3407
+ rationale: z14.string().min(1).describe(
3408
+ 'Why this step exists in the process \u2014 its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: "Catches mispriced line items before they reach the customer and prevents downstream credit notes."'
3409
+ ),
3410
+ sources: z14.array(stepSourceSchema).min(1).describe(
3411
+ "Evidence supporting this step's existence and details. At least one source is required \u2014 every step must trace back to something in the captures."
3412
+ ),
3413
+ condition: z14.string().nullable().describe(
3414
+ 'Optional precondition that gates this task. Null when the task is unconditional. Example: "Only when invoice total exceeds $10,000"'
3415
+ )
3416
+ });
3417
+ var gatewayStepSchema = z14.object({
3418
+ ...baseStepFields,
3419
+ nodeType: z14.literal("gateway"),
3420
+ nodeSubtype: z14.enum(PROCESS_FLOW_GATEWAY_SUBTYPES).describe(
3421
+ 'BPMN gateway subtype. "exclusive" (XOR \u2014 exactly one branch taken), "parallel" (AND \u2014 all branches taken), "inclusive" (OR \u2014 one or more branches taken).'
3422
+ ),
3423
+ description: z14.string().min(1).describe("Full prose describing the decision logic at this gateway."),
3424
+ rationale: z14.string().min(1).describe("Why this branching decision exists in the process."),
3425
+ sources: z14.array(stepSourceSchema).min(1).describe("Evidence supporting the decision criteria."),
3426
+ condition: z14.preprocess(
3427
+ (value) => value == null || value === "" ? "unknown" : value,
3428
+ z14.string().min(1)
3429
+ ).describe(
3430
+ 'Decision criteria evaluated at this gateway. BPMN requires this on every branching gateway. Existing rows persisted with null/empty values parse as "unknown" via a read-side preprocess; producers should write a real condition string going forward.'
3431
+ )
3432
+ });
3433
+ var clarityStepBaseSchema = z14.discriminatedUnion("nodeType", [
3434
+ eventStepSchema,
3435
+ taskStepSchema,
3436
+ gatewayStepSchema
3437
+ ]);
3359
3438
  var extraCaptureNeededValueSchema = z14.object({
3360
3439
  id: z14.guid().describe(
3361
3440
  "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value."
@@ -3379,7 +3458,27 @@ var bpmnStepReadinessAgentStepSchema = z14.object({
3379
3458
  'One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: "Requires human judgement on edge cases that are not documented in the captures."'
3380
3459
  )
3381
3460
  });
3382
- var postprocessClarityStepBaseSchema = clarityStepBaseSchema.extend(extraCaptureNeededAgentStepSchema.shape).extend(bpmnStepReadinessAgentStepSchema.shape).extend({});
3461
+ var postprocessAgentSliceShape = {
3462
+ ...extraCaptureNeededAgentStepSchema.shape,
3463
+ ...bpmnStepReadinessAgentStepSchema.shape
3464
+ };
3465
+ var postprocessEventStepSchema = eventStepSchema.extend(
3466
+ postprocessAgentSliceShape
3467
+ );
3468
+ var postprocessTaskStepSchema = taskStepSchema.extend(
3469
+ postprocessAgentSliceShape
3470
+ );
3471
+ var postprocessGatewayStepSchema = gatewayStepSchema.extend(
3472
+ postprocessAgentSliceShape
3473
+ );
3474
+ var postprocessClarityStepBaseSchema = z14.discriminatedUnion(
3475
+ "nodeType",
3476
+ [
3477
+ postprocessEventStepSchema,
3478
+ postprocessTaskStepSchema,
3479
+ postprocessGatewayStepSchema
3480
+ ]
3481
+ );
3383
3482
  var clarityCurrentProcessDataObjectSchema = z14.object({
3384
3483
  version: z14.number().int().describe(
3385
3484
  "Schema version for the current process data payload. Increment on breaking changes to the data shape so consumers can branch on the version field."
@@ -4908,6 +5007,8 @@ var createOrganizationRequestSchema = z28.object({
4908
5007
  });
4909
5008
  var DISCOVERY_MODES = ["request", "auto"];
4910
5009
  var discoveryModeSchema = z28.enum(DISCOVERY_MODES);
5010
+ var LLM_PROVIDERS = ["default", "bedrock"];
5011
+ var DEFAULT_LLM_PROVIDER = "default";
4911
5012
  var updateOrganizationRequestSchema = z28.object({
4912
5013
  name: z28.string().min(1).optional(),
4913
5014
  discoveryMode: discoveryModeSchema.optional()
@@ -5065,6 +5166,10 @@ var adminOrgSummarySchema = z29.object({
5065
5166
  discoveryMode: z29.string(),
5066
5167
  enterpriseBillingEnabled: z29.boolean(),
5067
5168
  connectionsSharingEnabled: z29.boolean(),
5169
+ // Optional for backwards compatibility: a response from an older backend
5170
+ // (pre-llm_provider) parses fine and defaults to "default" here. The output
5171
+ // type stays non-optional, so consumers don't need null handling.
5172
+ llmProvider: z29.enum(LLM_PROVIDERS).default(DEFAULT_LLM_PROVIDER),
5068
5173
  createdAt: z29.string().nullable(),
5069
5174
  deletedAt: z29.string().nullable(),
5070
5175
  teamCount: z29.number().int().nonnegative(),
@@ -5127,7 +5232,8 @@ var adminOrgUpdateRequestSchema = z29.object({
5127
5232
  name: z29.string().trim().min(1).max(200).optional(),
5128
5233
  discoveryMode: z29.enum(DISCOVERY_MODES).optional(),
5129
5234
  enterpriseBillingEnabled: z29.boolean().optional(),
5130
- connectionsSharingEnabled: z29.boolean().optional()
5235
+ connectionsSharingEnabled: z29.boolean().optional(),
5236
+ llmProvider: z29.enum(LLM_PROVIDERS).optional()
5131
5237
  }).refine(
5132
5238
  (val) => Object.values(val).some((v) => v !== void 0),
5133
5239
  "At least one field must be provided"
@@ -5401,7 +5507,14 @@ var integrationConfigApiSchema = z31.object({
5401
5507
  integration_name: z31.string(),
5402
5508
  created_at: z31.string(),
5403
5509
  icon_url: z31.string().nullish(),
5404
- is_connected: z31.boolean().optional()
5510
+ is_connected: z31.boolean().optional(),
5511
+ /**
5512
+ * Names of case queues linked to this integration config on the live build.
5513
+ * Populated only for `case-queue-producer` and `case-queue-consumer` types;
5514
+ * null for every other integration type, and null when a case-queue config
5515
+ * has no queues linked (PostgreSQL `json_agg` returns NULL on empty input).
5516
+ */
5517
+ linked_queue_names: z31.array(z31.string()).nullish()
5405
5518
  });
5406
5519
  var userScheduleBlockersSchema = z31.object({
5407
5520
  user_id: z31.string(),
@@ -5501,7 +5614,6 @@ var agentApiSchema = z31.object({
5501
5614
  pinned_at: z31.string().nullable().optional(),
5502
5615
  created_at: z31.string().nullable(),
5503
5616
  updated_at: z31.string().nullable(),
5504
- last_run_at: z31.string().nullable(),
5505
5617
  created_by: z31.object({
5506
5618
  id: z31.string(),
5507
5619
  name: z31.string().nullable(),
@@ -5511,21 +5623,27 @@ var agentApiSchema = z31.object({
5511
5623
  id: z31.string(),
5512
5624
  name: z31.string().nullable(),
5513
5625
  email: z31.string()
5514
- }).nullable().optional(),
5626
+ }).nullable().optional()
5627
+ });
5628
+ var agentUserContextApiSchema = z31.object({
5629
+ last_run_at: z31.string().nullable(),
5515
5630
  latest_build: buildApiSchema.nullable(),
5516
5631
  integration_configs: z31.array(integrationConfigApiSchema),
5517
5632
  user_triggers: z31.object({
5518
5633
  slack_mention: z31.boolean(),
5519
5634
  slack_channel: z31.boolean(),
5520
5635
  teams_mention: z31.boolean()
5521
- }).optional(),
5522
- case_trigger_enabled: z31.boolean().optional(),
5523
- case_trigger_has_conflict: z31.boolean().optional(),
5524
- case_trigger_conflicting_agents: z31.array(conflictingAgentSchema).optional(),
5525
- case_queue_name: z31.string().nullable().optional()
5636
+ }),
5637
+ case_trigger_enabled: z31.boolean(),
5638
+ case_trigger_has_conflict: z31.boolean(),
5639
+ case_trigger_conflicting_agents: z31.array(conflictingAgentSchema),
5640
+ case_queue_name: z31.string().nullable()
5526
5641
  });
5642
+ var agentListItemApiSchema = agentApiSchema.extend(
5643
+ agentUserContextApiSchema.shape
5644
+ );
5527
5645
  var agentsListApiSchema = z31.object({
5528
- agents: z31.array(agentApiSchema),
5646
+ agents: z31.array(agentListItemApiSchema),
5529
5647
  total: z31.int(),
5530
5648
  limit: z31.int(),
5531
5649
  offset: z31.int()
@@ -5914,13 +6032,13 @@ var caseQueueMinSchema = z41.object({
5914
6032
  var caseQueuesForSlotResponseSchema = z41.object({
5915
6033
  queues: z41.array(caseQueueMinSchema)
5916
6034
  });
5917
- var CASE_APPROVAL_DECISION = {
6035
+ var APPROVAL_DECISION = {
5918
6036
  APPROVED: "approved",
5919
6037
  REJECTED: "rejected"
5920
6038
  };
5921
- var caseApprovalDecisionSchema = z42.enum([
5922
- CASE_APPROVAL_DECISION.APPROVED,
5923
- CASE_APPROVAL_DECISION.REJECTED
6039
+ var approvalDecisionSchema = z42.enum([
6040
+ APPROVAL_DECISION.APPROVED,
6041
+ APPROVAL_DECISION.REJECTED
5924
6042
  ]);
5925
6043
  var HUMAN_REQUEST_TITLE_MAX = 200;
5926
6044
  var HUMAN_REQUEST_PROMPT_MAX = 2e3;
@@ -5936,7 +6054,7 @@ var humanRequestBatchRowSchema = z42.object({
5936
6054
  * single shared question across approvers.
5937
6055
  */
5938
6056
  prompt: z42.string(),
5939
- decision: caseApprovalDecisionSchema.nullable(),
6057
+ decision: approvalDecisionSchema.nullable(),
5940
6058
  responded_at: z42.string().nullable(),
5941
6059
  responded_by_user_id: z42.string().uuid().nullable(),
5942
6060
  responded_by_name: z42.string().nullable(),
@@ -5979,7 +6097,7 @@ var requestCaseApprovalsBatchStatusSchema = z42.enum([
5979
6097
  ]);
5980
6098
  var requestCaseApprovalsDecisionEntrySchema = z42.object({
5981
6099
  assigneeUserId: z42.string().uuid(),
5982
- decision: caseApprovalDecisionSchema,
6100
+ decision: approvalDecisionSchema,
5983
6101
  respondedAt: z42.string(),
5984
6102
  respondedByUserId: z42.string().uuid()
5985
6103
  });
@@ -10840,6 +10958,138 @@ function registerAgentsDelete(agents) {
10840
10958
  }
10841
10959
  __name(registerAgentsDelete, "registerAgentsDelete");
10842
10960
 
10961
+ // src/commands/agents/eval-rubrics.ts
10962
+ var DESCRIPTION_PREVIEW_WIDTH = 60;
10963
+ var RUBRIC_COLUMNS = [
10964
+ { header: "SLUG", cell: /* @__PURE__ */ __name((row) => row.slug, "cell") },
10965
+ { header: "TITLE", cell: /* @__PURE__ */ __name((row) => row.title, "cell") },
10966
+ {
10967
+ header: "DESCRIPTION",
10968
+ cell: /* @__PURE__ */ __name((row) => row.description, "cell"),
10969
+ maxWidth: DESCRIPTION_PREVIEW_WIDTH
10970
+ }
10971
+ ];
10972
+ var PLATFORM_RUBRIC_COLUMNS = [
10973
+ { header: "KEY", cell: /* @__PURE__ */ __name((row) => row.key, "cell") },
10974
+ { header: "CAUSE", cell: /* @__PURE__ */ __name((row) => row.cause, "cell") },
10975
+ {
10976
+ header: "DESCRIPTION",
10977
+ cell: /* @__PURE__ */ __name((row) => row.description, "cell"),
10978
+ maxWidth: DESCRIPTION_PREVIEW_WIDTH
10979
+ }
10980
+ ];
10981
+ function registerAgentsEvalRubrics(agents) {
10982
+ agents.command("eval-rubrics <agent-id>").description("List an agent's active evaluation rubrics").option(
10983
+ "--build <build-id>",
10984
+ "rubrics for a specific revision (defaults to the agent's live build)"
10985
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function evalRubricsAction(agentId, options) {
10986
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
10987
+ const searchParams = new URLSearchParams();
10988
+ if (options.build) {
10989
+ searchParams.append("build_id", options.build);
10990
+ }
10991
+ const raw = await httpRequest({
10992
+ method: "GET",
10993
+ path: `/v2/agents/${encodeURIComponent(agentId)}/eval-rubrics`,
10994
+ apiKey,
10995
+ apiBaseUrl,
10996
+ searchParams
10997
+ });
10998
+ if (options.json) {
10999
+ printJson(raw);
11000
+ return;
11001
+ }
11002
+ const parsed = evalRubricsResponseSchema.safeParse(raw);
11003
+ if (!parsed.success) {
11004
+ throw new CliError(
11005
+ `Unexpected response from the API: ${parsed.error.message}`
11006
+ );
11007
+ }
11008
+ const { rubrics, platform_rubrics: platformRubrics } = parsed.data;
11009
+ if (platformRubrics.length > 0) {
11010
+ console.log("Platform rubrics:");
11011
+ console.log(renderTable(PLATFORM_RUBRIC_COLUMNS, platformRubrics));
11012
+ console.log("");
11013
+ }
11014
+ console.log("Assignment-specific rubrics:");
11015
+ if (rubrics.length === 0) {
11016
+ console.log("No assignment-specific rubrics defined for this agent.");
11017
+ return;
11018
+ }
11019
+ console.log(renderTable(RUBRIC_COLUMNS, rubrics));
11020
+ }, "evalRubricsAction"));
11021
+ }
11022
+ __name(registerAgentsEvalRubrics, "registerAgentsEvalRubrics");
11023
+
11024
+ // src/commands/agents/eval-scores.ts
11025
+ var SCOPES = ["all", "custom"];
11026
+ var DEFAULT_LOOKBACK_DAYS = 30;
11027
+ var FLAG_COLUMNS = [
11028
+ { header: "FLAG", cell: /* @__PURE__ */ __name((row) => row.flag, "cell") },
11029
+ { header: "LABEL", cell: /* @__PURE__ */ __name((row) => row.label ?? "", "cell") },
11030
+ { header: "COUNT", cell: /* @__PURE__ */ __name((row) => String(row.count), "cell") }
11031
+ ];
11032
+ function isScope(value) {
11033
+ return SCOPES.includes(value);
11034
+ }
11035
+ __name(isScope, "isScope");
11036
+ function defaultSince() {
11037
+ return new Date(
11038
+ Date.now() - DEFAULT_LOOKBACK_DAYS * 24 * 60 * 60 * 1e3
11039
+ ).toISOString();
11040
+ }
11041
+ __name(defaultSince, "defaultSince");
11042
+ function registerAgentsEvalScores(agents) {
11043
+ agents.command("eval-scores <agent-id>").description("Show aggregate evaluation scores for an agent's jobs").option(
11044
+ "--since <iso>",
11045
+ `only count jobs evaluated after this ISO timestamp (default: last ${DEFAULT_LOOKBACK_DAYS} days)`
11046
+ ).option(
11047
+ "--scope <scope>",
11048
+ "'all' (platform + custom rubrics) or 'custom' (live-build custom rubrics only)"
11049
+ ).option("--json", "output raw JSON from the API").action(/* @__PURE__ */ __name(async function evalScoresAction(agentId, options) {
11050
+ if (options.scope !== void 0 && !isScope(options.scope)) {
11051
+ throw new CliError(
11052
+ `Invalid --scope "${options.scope}". Expected one of: ${SCOPES.join(", ")}.`
11053
+ );
11054
+ }
11055
+ const { apiKey, apiBaseUrl } = await requireAuthenticatedConfig(this);
11056
+ const searchParams = new URLSearchParams();
11057
+ searchParams.append("since", options.since ?? defaultSince());
11058
+ if (options.scope) {
11059
+ searchParams.append("scope", options.scope);
11060
+ }
11061
+ const raw = await httpRequest({
11062
+ method: "GET",
11063
+ path: `/v2/agent/${encodeURIComponent(agentId)}/eval-scores`,
11064
+ apiKey,
11065
+ apiBaseUrl,
11066
+ searchParams
11067
+ });
11068
+ if (options.json) {
11069
+ printJson(raw);
11070
+ return;
11071
+ }
11072
+ const parsed = evalScoresResponseSchema.safeParse(raw);
11073
+ if (!parsed.success) {
11074
+ throw new CliError(
11075
+ `Unexpected response from the API: ${parsed.error.message}`
11076
+ );
11077
+ }
11078
+ const { total_evaluated, with_issues, flag_distribution } = parsed.data;
11079
+ console.log(
11080
+ renderKeyValue([
11081
+ { label: "Evaluated", value: String(total_evaluated) },
11082
+ { label: "With issues", value: String(with_issues) }
11083
+ ])
11084
+ );
11085
+ if (flag_distribution.length > 0) {
11086
+ console.log("");
11087
+ console.log(renderTable(FLAG_COLUMNS, flag_distribution));
11088
+ }
11089
+ }, "evalScoresAction"));
11090
+ }
11091
+ __name(registerAgentsEvalScores, "registerAgentsEvalScores");
11092
+
10843
11093
  // src/api/build-schemas.ts
10844
11094
  import { z as z70 } from "zod";
10845
11095
  var publicBuildSchema2 = z70.object({
@@ -11740,7 +11990,7 @@ function registerAgentsTriggersSet(triggers) {
11740
11990
  __name(registerAgentsTriggersSet, "registerAgentsTriggersSet");
11741
11991
 
11742
11992
  // src/commands/agents/triggers/types.ts
11743
- var DESCRIPTION_PREVIEW_WIDTH = 50;
11993
+ var DESCRIPTION_PREVIEW_WIDTH2 = 50;
11744
11994
  var TABLE_COLUMNS9 = [
11745
11995
  { header: "INTEGRATION", cell: /* @__PURE__ */ __name((row) => row.integration_slug, "cell") },
11746
11996
  { header: "TRIGGER TYPE", cell: /* @__PURE__ */ __name((row) => row.trigger_type, "cell") },
@@ -11748,7 +11998,7 @@ var TABLE_COLUMNS9 = [
11748
11998
  {
11749
11999
  header: "DESCRIPTION",
11750
12000
  cell: /* @__PURE__ */ __name((row) => row.description, "cell"),
11751
- maxWidth: DESCRIPTION_PREVIEW_WIDTH
12001
+ maxWidth: DESCRIPTION_PREVIEW_WIDTH2
11752
12002
  }
11753
12003
  ];
11754
12004
  function registerAgentsTriggersTypes(triggers) {
@@ -11927,6 +12177,8 @@ function registerAgents(program) {
11927
12177
  registerAgentsModels(agents);
11928
12178
  registerAgentsSetModel(agents);
11929
12179
  registerAgentsDelete(agents);
12180
+ registerAgentsEvalScores(agents);
12181
+ registerAgentsEvalRubrics(agents);
11930
12182
  registerAgentsSchedules(agents);
11931
12183
  registerAgentsCaseTriggers(agents);
11932
12184
  registerAgentsTriggers(agents);
@@ -23926,7 +24178,7 @@ __name(resolveActiveTeamId, "resolveActiveTeamId");
23926
24178
  var version = resolveVersion();
23927
24179
  function resolveVersion() {
23928
24180
  if (true) {
23929
- return "1.4.0";
24181
+ return "1.5.0";
23930
24182
  }
23931
24183
  const packageJsonPath = join2(
23932
24184
  dirname2(fileURLToPath(import.meta.url)),
@@ -23995,7 +24247,7 @@ function checkForUpdate() {
23995
24247
  __name(checkForUpdate, "checkForUpdate");
23996
24248
  function loadPackageMeta() {
23997
24249
  if (true) {
23998
- return { name: "@duvoai/cli", version: "1.4.0" };
24250
+ return { name: "@duvoai/cli", version: "1.5.0" };
23999
24251
  }
24000
24252
  const require2 = createRequire(import.meta.url);
24001
24253
  const raw = require2("../package.json");