@unisonlabs/sixminute-admin 0.1.1193-next → 0.1.1196-next

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.
@@ -21,7 +21,7 @@ import { homedir } from "node:os";
21
21
  import { fileURLToPath } from "node:url";
22
22
 
23
23
  // tools/admin/src/build-info.ts
24
- var BUILT = { version: "0.1.1193-next", commit: "3b8cf9f7db40b7437361235202c421395f5fa173", surface: "9cd8ad25f1495c42" };
24
+ var BUILT = { version: "0.1.1196-next", commit: "24a4a5d6c850d56108d52f5048ba9f3daca62c36", surface: "8278bc639a4b20fe" };
25
25
 
26
26
  // tools/admin/src/run.ts
27
27
  import { rmSync as rmSync3 } from "node:fs";
@@ -5006,7 +5006,8 @@ var MeSchema = exports_external.object({
5006
5006
  permissions: exports_external.array(exports_external.string()).default([]),
5007
5007
  judgment_pipeline: JudgmentPipelineSchema.default("standard"),
5008
5008
  legalsense_connector: exports_external.boolean().default(false),
5009
- swallow_short_pauses: exports_external.boolean().optional()
5009
+ swallow_short_pauses: exports_external.boolean().optional(),
5010
+ pipeline_shadow: exports_external.boolean().optional()
5010
5011
  });
5011
5012
  var ProvisionResultSchema = MeSchema.extend({
5012
5013
  action: exports_external.enum(["ready", "refresh"]).default("ready")
@@ -5803,6 +5804,7 @@ var AdminContextRetentionResultSchema = exports_external.object({
5803
5804
  pipeline_runs: exports_external.number().int(),
5804
5805
  pipeline_steps: exports_external.number().int(),
5805
5806
  derivation_cache: exports_external.number().int(),
5807
+ pipeline_shadow: exports_external.number().int().default(0),
5806
5808
  intervals: exports_external.number().int()
5807
5809
  })
5808
5810
  });
@@ -6079,11 +6081,13 @@ var RecordingStopSchema = exports_external.object({
6079
6081
  at: TimestampSchema,
6080
6082
  reason: exports_external.enum(["person", "quit", "update", "sign-out", "roll"])
6081
6083
  });
6082
- var RecordingSkipSchema = exports_external.object({ seq: exports_external.number().int().positive() });
6084
+ var RecordingSkipSchema = exports_external.object({ seq: exports_external.number().int().positive().optional(), note_seq: exports_external.number().int().positive().optional() }).refine((skip) => skip.seq === undefined !== (skip.note_seq === undefined), { message: "one of seq and note_seq", path: ["seq"] });
6083
6085
  var RecordingClockSchema = exports_external.object({
6084
6086
  device_clock: TimestampSchema,
6085
6087
  last_witness_at: TimestampSchema.nullable(),
6086
- silence_end_after: TimestampSchema.nullable()
6088
+ silence_end_after: TimestampSchema.nullable(),
6089
+ seq: exports_external.number().int().nonnegative().optional(),
6090
+ note_seq: exports_external.number().int().nonnegative().optional()
6087
6091
  });
6088
6092
  var RecordingParamsSchema = exports_external.object({ id: RecordingIdSchema });
6089
6093
  var ContextAcceptedSchema = exports_external.object({
@@ -6496,9 +6500,46 @@ var LocalHostEventSchema = exports_external.discriminatedUnion("name", [
6496
6500
  }).strict()
6497
6501
  ]);
6498
6502
  var LocalMethodSchema = exports_external.enum(["GET", "POST", "PATCH", "DELETE"]);
6503
+ // packages/contracts/src/pipeline-runs.ts
6504
+ var DayParamsSchema = exports_external.object({ day: LocalDaySchema });
6505
+ var DayGenerateQuerySchema = exports_external.object({
6506
+ shadow: exports_external.enum(["1"]).optional(),
6507
+ until: TimestampSchema.optional()
6508
+ });
6509
+ var PipelineRunStartedSchema = exports_external.object({ run_id: RunIdSchema });
6510
+ var PipelineNothingPendingSchema = exports_external.object({ started: exports_external.literal(false) });
6511
+ var DayRegenerateSchema = exports_external.object({ from: TimestampSchema, to: TimestampSchema }).refine((w) => Date.parse(w.to) > Date.parse(w.from), { message: "to must be after from", path: ["to"] });
6512
+ var PipelineRunParamsSchema = exports_external.object({ id: RunIdSchema });
6513
+ var PipelineRunSchema = exports_external.object({
6514
+ state: exports_external.enum(["pending", "held", "done", "failed"]),
6515
+ error_class: exports_external.string().optional(),
6516
+ result: LocalProposeRangesResponseSchema.optional()
6517
+ });
6518
+ var ShadowReportQuerySchema = exports_external.object({ day: LocalDaySchema });
6519
+ var ShadowPersonDaySchema = exports_external.object({
6520
+ member_id: exports_external.string(),
6521
+ intervals_device: exports_external.number().int().nonnegative(),
6522
+ intervals_cloud: exports_external.number().int().nonnegative(),
6523
+ intervals_both: exports_external.number().int().nonnegative(),
6524
+ matter_agree: exports_external.number().int().nonnegative(),
6525
+ minutes_device: exports_external.number().nonnegative(),
6526
+ minutes_matter_agree: exports_external.number().nonnegative(),
6527
+ minutes_client_agree: exports_external.number().nonnegative(),
6528
+ minutes_cloud: exports_external.number().nonnegative(),
6529
+ latency_p50_s: exports_external.number().nonnegative().nullable(),
6530
+ latency_p95_s: exports_external.number().nonnegative().nullable(),
6531
+ cost_usd: exports_external.number().nonnegative(),
6532
+ runs_failed: exports_external.number().int().nonnegative(),
6533
+ runs_held: exports_external.number().int().nonnegative()
6534
+ });
6535
+ var ShadowReportSchema = exports_external.object({
6536
+ day: LocalDaySchema,
6537
+ people: exports_external.array(ShadowPersonDaySchema)
6538
+ });
6499
6539
  // packages/contracts/src/pipeline-status.ts
6500
6540
  var PipelineStatusQuerySchema = exports_external.object({
6501
- since: exports_external.string().regex(/^\d{1,18}$/, "expected a version number").optional()
6541
+ since: exports_external.string().regex(/^\d{1,18}$/, "expected a version number").optional(),
6542
+ mode: exports_external.enum(["live", "shadow"]).optional()
6502
6543
  });
6503
6544
  var PipelineRecordingStatusSchema = exports_external.object({
6504
6545
  recording_id: RecordingIdSchema,
@@ -6522,6 +6563,19 @@ var PipelineStatusSchema = exports_external.object({
6522
6563
  failed: exports_external.object({ run_id: RunIdSchema, day: LocalDaySchema, error_class: exports_external.string() }).nullable()
6523
6564
  })
6524
6565
  });
6566
+ var ShadowDaySchema = exports_external.object({
6567
+ day: LocalDaySchema,
6568
+ intervals: exports_external.array(exports_external.object({
6569
+ t_start: TimestampSchema,
6570
+ t_end: TimestampSchema,
6571
+ matter_id: exports_external.string().nullable(),
6572
+ away: exports_external.boolean(),
6573
+ activity_key: exports_external.string().nullable(),
6574
+ activity_label: exports_external.string().nullable(),
6575
+ summary: exports_external.string().nullable()
6576
+ })),
6577
+ entries: exports_external.array(exports_external.object({ t_start: TimestampSchema, t_end: TimestampSchema, matter_id: exports_external.string().nullable(), narrative: exports_external.string() }))
6578
+ });
6525
6579
  // packages/contracts/src/pipeline.ts
6526
6580
  var ContextStopReasonSchema = exports_external.enum(["person", "quit", "update", "sign-out", "roll"]);
6527
6581
  var IntervalContextHeaderSchema = exports_external.object({
@@ -6672,7 +6726,7 @@ var LlmTraceSchema = exports_external.object({
6672
6726
  // tools/admin/src/environments.ts
6673
6727
  var ENV_NAMES = ["production", "staging", "local"];
6674
6728
  var PRODUCTION_ORIGIN = "https://six-minute-api-xohqeggtfq-ey.a.run.app";
6675
- var STAGING_ORIGIN = "https://six-minute-api-staging-xohqeggtfq-ey.a.run.app";
6729
+ var STAGING_ORIGIN = "https://staging.api.sixminute.ai";
6676
6730
  var LOCAL_ORIGIN = "http://localhost:8080";
6677
6731
  var CLIENT_IDS = {
6678
6732
  production: "client_01M1PCGWDGQA8C942E3XTS8QKG",
@@ -7365,6 +7419,13 @@ is required; without one every command answers 403.
7365
7419
  setting deletes at the next hourly purge. Summaries, labels and entries
7366
7420
  are not affected.
7367
7421
 
7422
+ sixminute-admin pipeline shadow-report --env <env> --day YYYY-MM-DD [--json]
7423
+ The cloud pipeline's shadow against the device for one local day, for
7424
+ every person of an internal firm with a shadow recording: intervals
7425
+ decided on each side and on the same matter, entry minutes on the same
7426
+ matter and client, decision latency, model cost, failed and held runs.
7427
+ Numbers and member ids only. Until the shadow ends (phase 7).
7428
+
7368
7429
  sixminute-admin backfill sealed --env <env> --tenant tenant_... [--json]
7369
7430
  Seals the firm's interval summaries and labels and its entries' judged
7370
7431
  drafts under its own key, and gives intervals stored before the context
@@ -7758,6 +7819,8 @@ async function runAdmin(argv, deps) {
7758
7819
  return runRetentionSet(run2);
7759
7820
  if (group === "backfill" && subcommand === "sealed")
7760
7821
  return runBackfillSealed(run2);
7822
+ if (group === "pipeline" && subcommand === "shadow-report")
7823
+ return runShadowReport(run2);
7761
7824
  if (group === "entries" && subcommand === "purge")
7762
7825
  return runEntriesPurge(run2);
7763
7826
  if (group === "connector")
@@ -7947,6 +8010,15 @@ async function runResearchExportFlag(run2, subcommand) {
7947
8010
  allow ? "Research cards are stored for this firm from its next completion, for 30 days, sealed under the research key." : "No research card is stored for this firm from its next completion. Cards already stored stay until the 30-day purge."
7948
8011
  ]);
7949
8012
  }
8013
+ async function runShadowReport(run2) {
8014
+ const day = required(run2.flags, "day", "which local day, YYYY-MM-DD");
8015
+ const found = ShadowReportSchema.parse(expectOk(await call(run2.api, "GET", `/v1/admin/pipeline/shadow-report?day=${encodeURIComponent(day)}`)));
8016
+ const pct = (part, whole) => whole === 0 ? "-" : `${Math.round(100 * part / whole)}%`;
8017
+ return render(run2, found, [
8018
+ `day ${found.day}`,
8019
+ ...found.people.length === 0 ? ["no shadow recording on this day"] : found.people.map((p) => `${p.member_id} intervals device ${p.intervals_device} cloud ${p.intervals_cloud} both ${p.intervals_both}, ` + `same matter ${pct(p.matter_agree, p.intervals_both)}; minutes device ${p.minutes_device} cloud ${p.minutes_cloud}, ` + `same matter ${pct(p.minutes_matter_agree, p.minutes_device)}, same client ${pct(p.minutes_client_agree, p.minutes_device)}; ` + `latency p50 ${p.latency_p50_s ?? "-"} s p95 ${p.latency_p95_s ?? "-"} s; $${p.cost_usd.toFixed(3)}; ` + `failed ${p.runs_failed} held ${p.runs_held}`)
8020
+ ]);
8021
+ }
7950
8022
  async function runRetentionSet(run2) {
7951
8023
  const tenantId = required(run2.flags, "tenant", "whose retention");
7952
8024
  const days = Number(required(run2.flags, "days", "how many days after each interval's day its context is kept"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unisonlabs/sixminute-admin",
3
- "version": "0.1.1193-next",
3
+ "version": "0.1.1196-next",
4
4
  "description": "Sixminute operator tool: the admin commands of the Sixminute API, run with your own operator sign-in.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {