@zaip-ai/cli 1.0.8 → 1.3.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/README.md +1 -1
- package/dist/services/adapters.d.ts +1 -1
- package/dist/services/adapters.js +1 -1
- package/dist/services/agent-adapters.js +2 -2
- package/dist/services/agent-adapters.js.map +1 -1
- package/dist/services/agent-adapters.test.js +5 -0
- package/dist/services/agent-adapters.test.js.map +1 -1
- package/dist/services/logger.test.js +2 -2
- package/dist/services/runtime-template.test.js +6 -6
- package/dist/services/template-manifest.d.ts.map +1 -1
- package/dist/services/template-manifest.js +5 -0
- package/dist/services/template-manifest.js.map +1 -1
- package/package.json +1 -1
- package/templates/.agents/architecture/software-architecture.md +131 -0
- package/templates/.agents/branding/brandbook.docx +0 -0
- package/templates/.agents/branding/brandbook.md +60 -0
- package/templates/.agents/config/clients/codex/agents/zaip-agent-finalizer.toml +1 -1
- package/templates/.agents/config/clients/codex/agents/zaip-agent-orchestrator.toml +1 -1
- package/templates/.agents/dashboard/.tmp-run-list.json +254 -0
- package/templates/.agents/dashboard/.zaip-managed.json +252 -136
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{CostCalculationGuidePage-Z60df2r-.js → CostCalculationGuidePage-DxR_pgSV.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-4jZLTWE_.js +2156 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{PricingSettingsDialog-Coc6pA-1.js → PricingSettingsDialog-CKcsqb-r.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-BomxqCBU.css +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-DmmJD2Th.js +3 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BwtitWa_.js +1 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-N5Csr0RP.js +68 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{icons-vendor-DFBuc_qp.js → icons-vendor-C0fj2uU9.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-C4aIB1PV.js +2 -0
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{react-vendor-CCQOHdVI.js → react-vendor-BEsJ-FYH.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/{traceability-pC2_0J8x.js → traceability-B6y6Gw12.js} +1 -1
- package/templates/.agents/dashboard/apps/frontend/dist/index.html +5 -5
- package/templates/.agents/dashboard/apps/frontend/package.json +1 -1
- package/templates/.agents/dashboard/apps/frontend/src/App.tsx +204 -32
- package/templates/.agents/dashboard/apps/frontend/src/DashboardAlternateContent.tsx +11 -11
- package/templates/.agents/dashboard/apps/frontend/src/ProjectSettingsPage.tsx +14 -7
- package/templates/.agents/dashboard/apps/frontend/src/ProjectStackEditor.tsx +4 -2
- package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.test.ts +3 -1
- package/templates/.agents/dashboard/apps/frontend/src/TraceabilityWorkspace.tsx +14 -11
- package/templates/.agents/dashboard/apps/frontend/src/cost-period-refresh.test.ts +19 -4
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.test.ts +24 -2
- package/templates/.agents/dashboard/apps/frontend/src/dashboard-api.ts +22 -1
- package/templates/.agents/dashboard/apps/frontend/src/overview-status-page.test.ts +3 -1
- package/templates/.agents/dashboard/apps/frontend/src/project-settings-page.css +36 -26
- package/templates/.agents/dashboard/apps/frontend/src/project-settings.test.ts +2 -2
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-banner-semantics.test.ts +40 -6
- package/templates/.agents/dashboard/apps/frontend/src/snapshot-coherence.test.ts +39 -1
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.test.ts +89 -23
- package/templates/.agents/dashboard/apps/frontend/src/use-app-cost-loaders.ts +219 -29
- package/templates/.agents/dashboard/apps/frontend/src/use-app-effects.ts +61 -7
- package/templates/.agents/dashboard/apps/frontend/src/use-app-operations-pages.ts +3 -6
- package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.test.ts +2 -2
- package/templates/.agents/dashboard/apps/frontend/src/work-list-pagination.ts +3 -4
- package/templates/.agents/dashboard/apps/frontend/vite.config.ts +4 -1
- package/templates/.agents/dashboard/modules/cost-monitor/package.json +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.test.ts +89 -19
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CompactLifecycleCostTable.tsx +31 -16
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.test.ts +43 -14
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostCharts.tsx +5 -5
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostModelsAuditTable.tsx +1 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorContent.tsx +67 -42
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.test.ts +115 -39
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostMonitorPage.tsx +188 -38
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.test.ts +75 -17
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/CostTables.tsx +147 -58
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/cost-monitor.css +5 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/index.ts +2 -2
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/period-cost-groups.ts +2 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-compact-cost-page.ts +18 -7
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-group-page.ts +95 -9
- package/templates/.agents/dashboard/modules/cost-monitor/src/react/use-cost-run-page.ts +29 -17
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-monitor-projection.test.ts +0 -24
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.test.ts +225 -424
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-projection.ts +24 -15
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/build-cost-summary-terminal-day.test.ts +6 -1
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/source-size-cost-server/build-cost-monitor-projection-agents.test.ts +31 -0
- package/templates/.agents/dashboard/modules/cost-monitor/src/server/source-size-cost-server/build-cost-summary-projection-duration.test.ts +414 -0
- package/templates/.agents/dashboard/modules/operations/package.json +1 -1
- package/templates/.agents/dashboard/modules/operations/src/contracts.ts +26 -23
- package/templates/.agents/dashboard/modules/operations/src/react/EntityTables.tsx +31 -11
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.test.ts +3 -1
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsOverview.tsx +51 -21
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPage.tsx +47 -5
- package/templates/.agents/dashboard/modules/operations/src/react/OperationsPageNavigation.tsx +1 -4
- package/templates/.agents/dashboard/modules/operations/src/react/PeriodSummaryTable.tsx +32 -10
- package/templates/.agents/dashboard/modules/operations/src/react/TaskDetailsDialog.tsx +9 -3
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkBoard.tsx +13 -5
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.test.ts +12 -4
- package/templates/.agents/dashboard/modules/operations/src/react/UnifiedWorkList.tsx +1 -4
- package/templates/.agents/dashboard/modules/operations/src/react/conversation-rows.ts +1 -2
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.test.ts +385 -4
- package/templates/.agents/dashboard/modules/operations/src/react/export/ExcelExportAction.tsx +481 -61
- package/templates/.agents/dashboard/modules/operations/src/react/export/export-layout.test.ts +14 -1
- package/templates/.agents/dashboard/modules/operations/src/react/export/xlsx-runtime-e2e.test.ts +248 -0
- package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.test.ts +4 -4
- package/templates/.agents/dashboard/modules/operations/src/react/operation-duration.ts +6 -4
- package/templates/.agents/dashboard/modules/operations/src/react/operations-global-filters.test.ts +4 -1
- package/templates/.agents/dashboard/modules/operations/src/react/operations-overview-period-filter.test.ts +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/operations-overview.status-cards.test.ts +1 -1
- package/templates/.agents/dashboard/modules/operations/src/react/operations-page-contract.ts +46 -6
- package/templates/.agents/dashboard/modules/operations/src/react/operations-view-order.test.ts +1 -4
- package/templates/.agents/dashboard/modules/operations/src/react/period-summary.test.ts +82 -6
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.test.ts +2 -1
- package/templates/.agents/dashboard/modules/operations/src/react/work-board-model.ts +1 -1
- package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.test.ts +19 -7
- package/templates/.agents/dashboard/modules/operations/src/server/execution-relationship-counts.ts +4 -1
- package/templates/.agents/dashboard/modules/operations/src/server/quick-daily-operations-projection.ts +11 -5
- package/templates/.agents/dashboard/modules/traceability/package.json +1 -1
- package/templates/.agents/dashboard/packages/branding/package.json +1 -1
- package/templates/.agents/dashboard/packages/branding/src/index.ts +1 -1
- package/templates/.agents/dashboard/packages/contracts/package.json +1 -1
- package/templates/.agents/dashboard/packages/contracts/src/index.ts +1 -0
- package/templates/.agents/dashboard/packages/data-export/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs +152 -149
- package/templates/.agents/dashboard/packages/local-runtime/dist/server.cjs.metafile.json +7333 -0
- package/templates/.agents/dashboard/packages/local-runtime/dist/sqlite-read-model.cjs +149 -146
- package/templates/.agents/dashboard/packages/local-runtime/package.json +1 -1
- package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-dashboard.mjs +15 -7
- package/templates/.agents/dashboard/packages/local-runtime/scripts/build-sqlite-runtime.mjs +44 -13
- package/templates/.agents/dashboard/packages/local-runtime/scripts/rebuild-sqlite-read-model.mjs +5 -2
- package/templates/.agents/dashboard/packages/local-runtime/scripts/source-size-runtime-scripts/sqlite-read-model-fixture.mjs +397 -0
- package/templates/.agents/dashboard/packages/local-runtime/scripts/test-sqlite-read-model.mjs +472 -145
- package/templates/.agents/dashboard/packages/local-runtime/scripts/test-unix-launchers.mjs +15 -3
- package/templates/.agents/dashboard/packages/local-runtime/scripts/validate-sqlite-read-model.mjs +129 -31
- package/templates/.agents/dashboard/packages/local-runtime/server.mjs +153 -150
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.test.ts +6 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/project-settings.ts +3 -3
- package/templates/.agents/dashboard/packages/local-runtime/src/server-board.test.ts +55 -16
- package/templates/.agents/dashboard/packages/local-runtime/src/server-board.ts +23 -13
- package/templates/.agents/dashboard/packages/local-runtime/src/server-snapshot.test.ts +19 -4
- package/templates/.agents/dashboard/packages/local-runtime/src/server-workspace.ts +7 -3
- package/templates/.agents/dashboard/packages/local-runtime/src/server.test.ts +132 -9
- package/templates/.agents/dashboard/packages/local-runtime/src/server.ts +126 -60
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-metric-contract.ts +16 -2
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.test.ts +1861 -350
- package/templates/.agents/dashboard/packages/local-runtime/src/sqlite-read-model.ts +1218 -352
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.mjs +119 -42
- package/templates/.agents/dashboard/packages/local-runtime/start-dashboard.test.mjs +45 -20
- package/templates/.agents/dashboard/packages/ui/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/package.json +1 -1
- package/templates/.agents/dashboard/tests/e2e/specs/dashboard.spec.ts +7 -5
- package/templates/.agents/design/.zaip-managed.json +3 -3
- package/templates/.agents/design/apps/catalog/package.json +1 -1
- package/templates/.agents/design/packages/local-runtime/package.json +1 -1
- package/templates/.agents/growth/estrategia-bootstrap-90-dias.md +169 -0
- package/templates/.agents/growth/strategy.md +27 -0
- package/templates/.agents/marketing/estrategia-marketing-zaip-90-dias.md +197 -0
- package/templates/.agents/marketing/strategy.md +29 -0
- package/templates/.agents/requirements/autonomous-assurance.md +1 -1
- package/templates/.agents/requirements/comparative-audit.md +1 -1
- package/templates/.agents/requirements/context-engine.md +1 -1
- package/templates/.agents/requirements/cost-observability.md +1 -1
- package/templates/.agents/requirements/dashboard-launch.md +1 -1
- package/templates/.agents/requirements/data-export.md +1 -1
- package/templates/.agents/requirements/design-system.md +1 -1
- package/templates/.agents/requirements/execution-engine.md +1 -1
- package/templates/.agents/requirements/kanban-dashboard.md +1 -1
- package/templates/.agents/requirements/model-orchestration.md +1 -1
- package/templates/.agents/requirements/public-distribution.md +1 -1
- package/templates/.agents/requirements/software-architecture.md +1 -1
- package/templates/.agents/requirements/strategic-improvements.md +1 -1
- package/templates/.agents/requirements/work-lifecycle.md +1 -1
- package/templates/.agents/requirements/zaip-strategic-95.md +1 -1
- package/templates/.agents/runtime/VERSION +1 -1
- package/templates/.agents/runtime/bin/zaip.mjs +30 -29
- package/templates/.agents/runtime/checksums.sha256 +6 -6
- package/templates/.agents/runtime/manifest.json +1 -1
- package/templates/.agents/runtime/pnpm-lock.sha256 +1 -1
- package/templates/.agents/runtime/provenance.json +5 -5
- package/templates/.agents/runtime/sbom.cdx.json +3 -3
- package/templates/.agents/sales/playbook.md +32 -0
- package/templates/.agents/sales/roteiro-comercial-zaip.md +252 -0
- package/templates/.agents/skills/zaip-aios/SKILL.md +1 -1
- package/templates/.agents/skills/zaip-skill-brand-governance/SKILL.md +9 -2
- package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-framework.md +39 -0
- package/templates/.agents/skills/zaip-skill-brand-governance/references/brandbook-standards.md +1 -1
- package/templates/.agents/skills/zaip-skill-enforce-architecture/SKILL.md +2 -0
- package/templates/.agents/skills/zaip-skill-growth-strategy-revops/SKILL.md +6 -0
- package/templates/.agents/skills/zaip-skill-marketing/SKILL.md +6 -0
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-local-telemetry.mjs +39 -82
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.mjs +13 -8
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-lib.test.mjs +44 -14
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.mjs +19 -9
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/reconcile-telemetry-remeasurement.test.mjs +29 -5
- package/templates/.agents/skills/zaip-skill-reconcile-telemetry/scripts/source-size-telemetry/model-identity-reconciliation.mjs +77 -0
- package/templates/.agents/skills/zaip-skill-sales-methodology/SKILL.md +6 -0
- package/templates/.agents/skills/zaip-skill-sqlite-read-model/scripts/ensure-node.mjs +28 -5
- package/templates/.agents/zaip-aios/INDEX.md +10 -0
- package/templates/.agents/zaip-aios/README.md +2 -1
- package/templates/.agents/zaip-aios/VERSION +1 -1
- package/templates/.agents/zaip-aios/guides/18-catalogo-de-agentes.md +76 -0
- package/templates/.agents/zaip-aios/guides/19-assurance-e-autonomia.md +72 -0
- package/templates/.agents/zaip-aios/guides/20-instalacao-detalhada.md +330 -0
- package/templates/.agents/zaip-aios/guides/21-telemetria-monitor-custos.md +52 -0
- package/templates/.agents/zaip-aios/guides/22-fluxos-e-roteamento.md +69 -0
- package/templates/.agents/zaip-aios/guides/23-orquestracao-de-modelos.md +483 -0
- package/templates/.agents/zaip-aios/guides/24-calculo-de-custos-openai.md +85 -0
- package/templates/.agents/zaip-aios/guides/25-fontes-de-precos-openai.md +18 -0
- package/templates/.agents/zaip-aios/guides/26-qualidade-e-release.md +44 -0
- package/templates/.agents/zaip-aios/guides/27-telemetria-git-native.md +167 -0
- package/templates/.agents/zaip-aios/guides/28-lifecycle-completo.md +144 -0
- package/templates/.agents/zaip-aios/guides/assets/diagrams/lifecycles-task-spec-prd.png +0 -0
- package/templates/.agents/zaip-aios/guides/assets/diagrams/prd-lifecycle.png +0 -0
- package/templates/.agents/zaip-aios/guides/assets/diagrams/spec-lifecycle.png +0 -0
- package/templates/.agents/zaip-aios/guides/assets/diagrams/task-lifecycle.png +0 -0
- package/templates/template-manifest.json +313 -177
- package/templates/.agents/dashboard/apps/frontend/dist/assets/DashboardHelpDialog-Cs6dzDmW.js +0 -1505
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-QE1k9yZB.css +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/ProjectSettingsPage-_Pf5DA_A.js +0 -3
- package/templates/.agents/dashboard/apps/frontend/dist/assets/TraceabilityWorkspace-BVlz3DLZ.js +0 -1
- package/templates/.agents/dashboard/apps/frontend/dist/assets/cost-monitor-Cf9ctPVt.js +0 -68
- package/templates/.agents/dashboard/apps/frontend/dist/assets/index-8A4DcNXM.js +0 -2
|
@@ -12,63 +12,112 @@ import {
|
|
|
12
12
|
withTokenBackedCompactDuration,
|
|
13
13
|
} from "./CompactLifecycleCostTable.js";
|
|
14
14
|
import { costPeriodDateRange, defaultCostPeriod, emptyCostFilters } from "./CostFilters.js";
|
|
15
|
-
import {
|
|
16
|
-
costGroupPageLabel,
|
|
17
|
-
effectiveCostGroupQuery,
|
|
18
|
-
reconcileCostGroupTotalsWithCards,
|
|
19
|
-
} from "./use-cost-group-page.js";
|
|
20
15
|
import {
|
|
21
16
|
COST_VIEW_ORDER,
|
|
22
17
|
DEFAULT_COST_VIEW,
|
|
23
18
|
findRunDetails,
|
|
24
19
|
groupRows,
|
|
20
|
+
isCostViewExportEligible,
|
|
25
21
|
isCurrentCostRunPageGeneration,
|
|
26
22
|
isServerCostRunPagingEligible,
|
|
27
23
|
matchesGlobalFilters,
|
|
28
24
|
matchesPeriodEntity,
|
|
25
|
+
resolveCompactCostPageRange,
|
|
29
26
|
resolveCostGroupPageRange,
|
|
30
27
|
selectDimensionalCostRows,
|
|
31
28
|
visibleExecutionRows,
|
|
32
29
|
} from "./CostMonitorPage.js";
|
|
30
|
+
import {
|
|
31
|
+
costGroupPageLabel,
|
|
32
|
+
effectiveCostGroupQuery,
|
|
33
|
+
reconcileCostGroupTotalsWithCards,
|
|
34
|
+
} from "./use-cost-group-page.js";
|
|
33
35
|
|
|
34
36
|
describe("cost monitor navigation", () => {
|
|
37
|
+
it("hides Excel export from the overview while retaining it on tabular views", () => {
|
|
38
|
+
expect(isCostViewExportEligible("overview")).toBe(false);
|
|
39
|
+
expect(isCostViewExportEligible("daily")).toBe(true);
|
|
40
|
+
expect(isCostViewExportEligible("agentCalls")).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
35
43
|
it("keeps the embedded default group pager on the all-time snapshot without explicit filters", () => {
|
|
36
44
|
const monthRange = costPeriodDateRange(defaultCostPeriod, new Date("2026-08-17T12:00:00.000Z"));
|
|
37
|
-
expect(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
45
|
+
expect(
|
|
46
|
+
resolveCostGroupPageRange({
|
|
47
|
+
embedded: true,
|
|
48
|
+
globalDateRange: undefined,
|
|
49
|
+
hasLocalCostFilters: false,
|
|
50
|
+
period: defaultCostPeriod,
|
|
51
|
+
runPageRange: monthRange,
|
|
52
|
+
}),
|
|
53
|
+
).toBeUndefined();
|
|
54
|
+
expect(
|
|
55
|
+
resolveCostGroupPageRange({
|
|
56
|
+
embedded: true,
|
|
57
|
+
globalDateRange: undefined,
|
|
58
|
+
hasLocalCostFilters: false,
|
|
59
|
+
period: "30",
|
|
60
|
+
runPageRange: monthRange,
|
|
61
|
+
}),
|
|
62
|
+
).toEqual(monthRange);
|
|
63
|
+
expect(
|
|
64
|
+
resolveCostGroupPageRange({
|
|
65
|
+
embedded: true,
|
|
66
|
+
globalDateRange: { start: "2026-07-14", end: "2026-08-17" },
|
|
67
|
+
hasLocalCostFilters: false,
|
|
68
|
+
period: defaultCostPeriod,
|
|
69
|
+
runPageRange: { from: "2026-07-14", to: "2026-08-17" },
|
|
70
|
+
}),
|
|
71
|
+
).toEqual({ from: "2026-07-14", to: "2026-08-17" });
|
|
72
|
+
expect(
|
|
73
|
+
resolveCostGroupPageRange({
|
|
74
|
+
embedded: true,
|
|
75
|
+
globalDateRange: undefined,
|
|
76
|
+
hasLocalCostFilters: true,
|
|
77
|
+
period: defaultCostPeriod,
|
|
78
|
+
runPageRange: monthRange,
|
|
79
|
+
}),
|
|
80
|
+
).toEqual(monthRange);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("keeps compact SPEC and PRD pages and their export source on the all-time snapshot", () => {
|
|
84
|
+
const monthRange = costPeriodDateRange(defaultCostPeriod, new Date("2026-08-17T12:00:00.000Z"));
|
|
85
|
+
expect(
|
|
86
|
+
resolveCompactCostPageRange({
|
|
87
|
+
embedded: true,
|
|
88
|
+
globalDateRange: undefined,
|
|
89
|
+
hasLocalCostFilters: false,
|
|
90
|
+
period: defaultCostPeriod,
|
|
91
|
+
runPageRange: monthRange,
|
|
92
|
+
}),
|
|
93
|
+
).toBeUndefined();
|
|
94
|
+
expect(
|
|
95
|
+
resolveCompactCostPageRange({
|
|
96
|
+
embedded: false,
|
|
97
|
+
globalDateRange: undefined,
|
|
98
|
+
hasLocalCostFilters: false,
|
|
99
|
+
period: defaultCostPeriod,
|
|
100
|
+
runPageRange: monthRange,
|
|
101
|
+
}),
|
|
102
|
+
).toEqual(monthRange);
|
|
103
|
+
const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
|
|
104
|
+
expect(page).toContain("range: compactPageRange");
|
|
105
|
+
expect(page).toContain("...(compactPageRange === undefined ? {} : compactPageRange)");
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("releases the host loading gate when a global filter replaces the Cost Monitor surface", () => {
|
|
109
|
+
const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
|
|
110
|
+
|
|
111
|
+
expect(page).toContain("() => () => onLoadingChange?.(false)");
|
|
65
112
|
});
|
|
66
113
|
|
|
67
114
|
it("labels daily pagination by its continuous result range", () => {
|
|
68
|
-
expect(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
115
|
+
expect(
|
|
116
|
+
costGroupPageLabel({
|
|
117
|
+
locale: "pt-BR",
|
|
118
|
+
page: { offset: 30, limit: 30, total_count: 35 },
|
|
119
|
+
}),
|
|
120
|
+
).toBe("31–35 de 35");
|
|
72
121
|
const content = readFileSync(new URL("./CostMonitorContent.tsx", import.meta.url), "utf8");
|
|
73
122
|
expect(content).toContain("groupPageOffset + groupPage.limit");
|
|
74
123
|
expect(content).toContain("groupPageOffset - groupPage.limit");
|
|
@@ -158,6 +207,8 @@ describe("cost monitor navigation", () => {
|
|
|
158
207
|
const runHook = readFileSync(new URL("./use-cost-run-page.ts", import.meta.url), "utf8");
|
|
159
208
|
const periodHook = readFileSync(new URL("./CostFilters.tsx", import.meta.url), "utf8");
|
|
160
209
|
expect(compactHook).toContain("const loadRef = useRef(load)");
|
|
210
|
+
expect(compactHook).toContain("const [resolvedKey, setResolvedKey]");
|
|
211
|
+
expect(compactHook).toContain("compactPage: resolvedKey === requestKey ? page : null");
|
|
161
212
|
expect(compactHook).toContain("const loadPage = loadRef.current");
|
|
162
213
|
expect(compactHook).toContain("if (loadPage === undefined) return;");
|
|
163
214
|
expect(compactHook).not.toContain("[attempt, load,");
|
|
@@ -198,11 +249,15 @@ describe("cost monitor navigation", () => {
|
|
|
198
249
|
expect(isServerCostRunPagingEligible({ ...emptyCostFilters, status: "executing" })).toBe(true);
|
|
199
250
|
expect(isServerCostRunPagingEligible({ ...emptyCostFilters, query: "edge" })).toBe(true);
|
|
200
251
|
expect(isServerCostRunPagingEligible(emptyCostFilters, "edge")).toBe(true);
|
|
201
|
-
expect(isServerCostRunPagingEligible({ ...emptyCostFilters, query: "local" }, "global")).toBe(
|
|
252
|
+
expect(isServerCostRunPagingEligible({ ...emptyCostFilters, query: "local" }, "global")).toBe(
|
|
253
|
+
false,
|
|
254
|
+
);
|
|
202
255
|
});
|
|
203
256
|
it("routes global search to lazy invocations and all active dimensions to lazy groups", () => {
|
|
204
257
|
expect(effectiveCostGroupQuery(emptyCostFilters, "global-edge")).toBe("global-edge");
|
|
205
|
-
expect(
|
|
258
|
+
expect(
|
|
259
|
+
effectiveCostGroupQuery({ ...emptyCostFilters, query: "local-edge" }, "global-edge"),
|
|
260
|
+
).toBe("local-edge");
|
|
206
261
|
const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
|
|
207
262
|
const runHook = readFileSync(new URL("./use-cost-run-page.ts", import.meta.url), "utf8");
|
|
208
263
|
const groupHook = readFileSync(new URL("./use-cost-group-page.ts", import.meta.url), "utf8");
|
|
@@ -272,6 +327,27 @@ describe("cost monitor navigation", () => {
|
|
|
272
327
|
]);
|
|
273
328
|
});
|
|
274
329
|
|
|
330
|
+
it("prepares Agent Invocations from every server page for export", () => {
|
|
331
|
+
const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
|
|
332
|
+
expect(page).toContain('view === "agentCalls" && serverPagingEligible');
|
|
333
|
+
expect(page).toContain("agentInvocationExportSource");
|
|
334
|
+
expect(page).toMatch(
|
|
335
|
+
/pageSource=\{\s*compactExportSource \?\? agentInvocationExportSource \?\? costGroupExportSource\s*\}/,
|
|
336
|
+
);
|
|
337
|
+
expect(page).toContain("if (page.runs.length === 0) return");
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it("prepares every paginated period row for daily, monthly, and annual exports", () => {
|
|
341
|
+
const page = readFileSync(new URL("./CostMonitorPage.tsx", import.meta.url), "utf8");
|
|
342
|
+
|
|
343
|
+
expect(page).toContain('view === "daily" ||');
|
|
344
|
+
expect(page).toContain('view === "monthly" ||');
|
|
345
|
+
expect(page).toContain('view === "annual" ||');
|
|
346
|
+
expect(page).toContain("...(groupPageRange === undefined ? {} : groupPageRange)");
|
|
347
|
+
expect(page).toContain("totalRows: firstPage.total_count");
|
|
348
|
+
expect(page).toContain("nextOffset >= page.total_count || !page.has_more");
|
|
349
|
+
});
|
|
350
|
+
|
|
275
351
|
it("resolves an Agent Run to its own details", () => {
|
|
276
352
|
const runs = [{ id: "RUN-001" }, { id: "RUN-002" }];
|
|
277
353
|
|
|
@@ -79,6 +79,11 @@ export type { LoadCostGroupPage } from "./use-cost-group-page.js";
|
|
|
79
79
|
export type LoadCostMonitorDetail = typeof loadCostMonitorDetail;
|
|
80
80
|
export type LoadCostRunPage = typeof loadCostMonitorRunPage;
|
|
81
81
|
|
|
82
|
+
/** The overview is a summary surface, not an exportable table view. */
|
|
83
|
+
export function isCostViewExportEligible(view: CostView): boolean {
|
|
84
|
+
return view !== "overview";
|
|
85
|
+
}
|
|
86
|
+
|
|
82
87
|
/**
|
|
83
88
|
* The Cost period request filters Runs, while Operations is the global snapshot
|
|
84
89
|
* used for shared entity detail. Keep the Executions tab on that same active
|
|
@@ -129,10 +134,20 @@ export function resolveCostGroupPageRange({
|
|
|
129
134
|
globalDateRange === undefined &&
|
|
130
135
|
period === defaultCostPeriod &&
|
|
131
136
|
!hasLocalCostFilters
|
|
132
|
-
)
|
|
137
|
+
)
|
|
138
|
+
return undefined;
|
|
133
139
|
return runPageRange;
|
|
134
140
|
}
|
|
135
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Compact lifecycle tables share the embedded all-time snapshot contract with
|
|
144
|
+
* the group pager. In particular, the default month control is a display
|
|
145
|
+
* choice on that surface, not a hidden bound for SPEC/PRD rows or XLSX.
|
|
146
|
+
*/
|
|
147
|
+
export function resolveCompactCostPageRange(args: Parameters<typeof resolveCostGroupPageRange>[0]) {
|
|
148
|
+
return resolveCostGroupPageRange(args);
|
|
149
|
+
}
|
|
150
|
+
|
|
136
151
|
export function CostMonitorPage({
|
|
137
152
|
capabilityNavigation,
|
|
138
153
|
data,
|
|
@@ -234,6 +249,13 @@ export function CostMonitorPage({
|
|
|
234
249
|
period,
|
|
235
250
|
runPageRange,
|
|
236
251
|
});
|
|
252
|
+
const compactPageRange = resolveCompactCostPageRange({
|
|
253
|
+
embedded,
|
|
254
|
+
globalDateRange: globalFilters?.dateRange,
|
|
255
|
+
hasLocalCostFilters,
|
|
256
|
+
period,
|
|
257
|
+
runPageRange,
|
|
258
|
+
});
|
|
237
259
|
const costGroupViewName = (
|
|
238
260
|
candidate: CostView,
|
|
239
261
|
): "daily" | "monthly" | "annual" | "agents" | "models" | "providers" | null =>
|
|
@@ -263,7 +285,7 @@ export function CostMonitorPage({
|
|
|
263
285
|
} = useCompactCostPage({
|
|
264
286
|
view,
|
|
265
287
|
load: loadReadModelPage,
|
|
266
|
-
range:
|
|
288
|
+
range: compactPageRange,
|
|
267
289
|
query: globalFilters?.query,
|
|
268
290
|
filters,
|
|
269
291
|
});
|
|
@@ -291,10 +313,29 @@ export function CostMonitorPage({
|
|
|
291
313
|
useEffect(
|
|
292
314
|
() =>
|
|
293
315
|
onLoadingChange?.(
|
|
294
|
-
loading ||
|
|
316
|
+
loading ||
|
|
317
|
+
periodLoading ||
|
|
318
|
+
runPageLoading ||
|
|
319
|
+
groupPageState.loading ||
|
|
320
|
+
compactPageLoading ||
|
|
321
|
+
detailLoading,
|
|
295
322
|
),
|
|
296
|
-
[
|
|
323
|
+
[
|
|
324
|
+
compactPageLoading,
|
|
325
|
+
detailLoading,
|
|
326
|
+
groupPageState.loading,
|
|
327
|
+
loading,
|
|
328
|
+
onLoadingChange,
|
|
329
|
+
periodLoading,
|
|
330
|
+
runPageLoading,
|
|
331
|
+
],
|
|
297
332
|
);
|
|
333
|
+
// A global period/filter change deliberately unmounts this surface while it
|
|
334
|
+
// replaces the atomic Cost Monitor snapshot. Requests belonging to the old
|
|
335
|
+
// surface are aborted, so their normal completion path cannot clear the
|
|
336
|
+
// host-level loading gate. Always release that gate on unmount; the newly
|
|
337
|
+
// mounted surface will immediately assert its own loading state if needed.
|
|
338
|
+
useEffect(() => () => onLoadingChange?.(false), [onLoadingChange]);
|
|
298
339
|
useEffect(() => {
|
|
299
340
|
if (!hasLocalCostFilters) onActiveDataChange?.(activeData);
|
|
300
341
|
}, [activeData, hasLocalCostFilters, onActiveDataChange]);
|
|
@@ -474,7 +515,10 @@ export function CostMonitorPage({
|
|
|
474
515
|
groupPageState.page === null
|
|
475
516
|
? []
|
|
476
517
|
: groupView === "agents"
|
|
477
|
-
? includeConfiguredAgentGroups(
|
|
518
|
+
? includeConfiguredAgentGroups(
|
|
519
|
+
groupPageState.page.rows,
|
|
520
|
+
activeData.configured_agents,
|
|
521
|
+
)
|
|
478
522
|
: [...groupPageState.page.rows],
|
|
479
523
|
},
|
|
480
524
|
[activeData.configured_agents, groups, groupPageState.page, groupView],
|
|
@@ -540,32 +584,134 @@ export function CostMonitorPage({
|
|
|
540
584
|
visibleSpecs,
|
|
541
585
|
]);
|
|
542
586
|
const compactExportSource =
|
|
543
|
-
usingCompactPage &&
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
587
|
+
usingCompactPage && compactKind !== null && loadReadModelPage !== undefined
|
|
588
|
+
? {
|
|
589
|
+
prepare: async () => {
|
|
590
|
+
const firstPage = await loadReadModelPage({
|
|
591
|
+
kind: compactKind,
|
|
592
|
+
offset: 0,
|
|
593
|
+
limit: 50,
|
|
594
|
+
filters,
|
|
595
|
+
...(compactPageRange === undefined ? {} : compactPageRange),
|
|
596
|
+
...(globalFilters?.query ? { query: globalFilters.query } : {}),
|
|
597
|
+
});
|
|
598
|
+
return {
|
|
599
|
+
totalRows: firstPage.total,
|
|
600
|
+
pages: async function* () {
|
|
601
|
+
let page = firstPage;
|
|
602
|
+
const seen = new Set<string>();
|
|
603
|
+
while (true) {
|
|
604
|
+
const unique = page.rows
|
|
605
|
+
.filter((row) => {
|
|
606
|
+
if (seen.has(row.id)) return false;
|
|
607
|
+
seen.add(row.id);
|
|
608
|
+
return true;
|
|
609
|
+
})
|
|
610
|
+
.map(withTokenBackedCompactDuration);
|
|
611
|
+
if (unique.length > 0)
|
|
612
|
+
yield unique as unknown as readonly Record<string, unknown>[];
|
|
613
|
+
const nextOffset = page.offset + page.rows.length;
|
|
614
|
+
if (nextOffset >= page.total || !page.has_more) return;
|
|
615
|
+
page = await loadReadModelPage({
|
|
616
|
+
kind: compactKind,
|
|
617
|
+
offset: nextOffset,
|
|
618
|
+
limit: page.limit,
|
|
619
|
+
filters,
|
|
620
|
+
...(compactPageRange === undefined ? {} : compactPageRange),
|
|
621
|
+
...(globalFilters?.query ? { query: globalFilters.query } : {}),
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
};
|
|
626
|
+
},
|
|
627
|
+
}
|
|
628
|
+
: undefined;
|
|
629
|
+
const agentInvocationExportSource =
|
|
630
|
+
view === "agentCalls" && serverPagingEligible && loadRunPage !== undefined
|
|
631
|
+
? {
|
|
632
|
+
prepare: async () => {
|
|
633
|
+
const effectiveFilters = {
|
|
634
|
+
...filters,
|
|
635
|
+
query: filters.query || globalFilters?.query || "",
|
|
636
|
+
};
|
|
637
|
+
const firstPage = await loadRunPage({
|
|
638
|
+
currency,
|
|
639
|
+
filters: effectiveFilters,
|
|
640
|
+
...(runPageRange === undefined ? {} : runPageRange),
|
|
641
|
+
offset: 0,
|
|
642
|
+
refresh: lastUpdatedAt,
|
|
643
|
+
});
|
|
644
|
+
const totalRows = firstPage.run_page.total ?? firstPage.runs.length;
|
|
645
|
+
return {
|
|
646
|
+
totalRows,
|
|
647
|
+
pages: async function* () {
|
|
648
|
+
let page = firstPage;
|
|
649
|
+
while (true) {
|
|
650
|
+
if (page.runs.length === 0) return;
|
|
651
|
+
yield page.runs as unknown as readonly Record<string, unknown>[];
|
|
652
|
+
const nextOffset = page.run_page.offset + page.runs.length;
|
|
653
|
+
if (
|
|
654
|
+
(page.run_page.total !== null && nextOffset >= page.run_page.total) ||
|
|
655
|
+
!page.run_page.has_more
|
|
656
|
+
)
|
|
657
|
+
return;
|
|
658
|
+
page = await loadRunPage({
|
|
659
|
+
currency,
|
|
660
|
+
filters: effectiveFilters,
|
|
661
|
+
...(runPageRange === undefined ? {} : runPageRange),
|
|
662
|
+
offset: nextOffset,
|
|
663
|
+
refresh: lastUpdatedAt,
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
},
|
|
667
|
+
};
|
|
668
|
+
},
|
|
669
|
+
}
|
|
670
|
+
: undefined;
|
|
671
|
+
// Period views are paginated SQLite projections too. Exporting their
|
|
672
|
+
// already-rendered group rows truncates the workbook to the visible page
|
|
673
|
+
// (and can lose the projection's factual duration). Capture the same
|
|
674
|
+
// paged query used by the table so an All Time selection keeps its unbound
|
|
675
|
+
// range and every other selection retains its exact range and filters.
|
|
676
|
+
const costGroupExportSource =
|
|
677
|
+
(view === "daily" ||
|
|
678
|
+
view === "monthly" ||
|
|
679
|
+
view === "annual" ||
|
|
680
|
+
view === "agents" ||
|
|
681
|
+
view === "models" ||
|
|
682
|
+
view === "providers") &&
|
|
683
|
+
loadGroupPage !== undefined
|
|
547
684
|
? {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
685
|
+
prepare: async () => {
|
|
686
|
+
const query = filters.query || globalFilters?.query || "";
|
|
687
|
+
const firstPage = await loadGroupPage({
|
|
688
|
+
view,
|
|
689
|
+
offset: 0,
|
|
690
|
+
limit: 50,
|
|
691
|
+
filters,
|
|
692
|
+
...(query ? { query } : {}),
|
|
693
|
+
...(groupPageRange === undefined ? {} : groupPageRange),
|
|
694
|
+
});
|
|
695
|
+
return {
|
|
696
|
+
totalRows: firstPage.total_count,
|
|
697
|
+
pages: async function* () {
|
|
698
|
+
let page = firstPage;
|
|
699
|
+
while (true) {
|
|
700
|
+
if (page.rows.length === 0) return;
|
|
701
|
+
yield page.rows as unknown as readonly Record<string, unknown>[];
|
|
702
|
+
const nextOffset = page.offset + page.rows.length;
|
|
703
|
+
if (nextOffset >= page.total_count || !page.has_more) return;
|
|
704
|
+
page = await loadGroupPage({
|
|
705
|
+
view,
|
|
706
|
+
offset: nextOffset,
|
|
707
|
+
limit: page.limit,
|
|
708
|
+
filters,
|
|
709
|
+
...(query ? { query } : {}),
|
|
710
|
+
...(groupPageRange === undefined ? {} : groupPageRange),
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
},
|
|
714
|
+
};
|
|
569
715
|
},
|
|
570
716
|
}
|
|
571
717
|
: undefined;
|
|
@@ -789,14 +935,18 @@ export function CostMonitorPage({
|
|
|
789
935
|
</button>
|
|
790
936
|
))}
|
|
791
937
|
</nav>
|
|
792
|
-
|
|
793
|
-
<
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
938
|
+
{isCostViewExportEligible(view) ? (
|
|
939
|
+
<div className="cost-tab-export">
|
|
940
|
+
<ExcelExportAction
|
|
941
|
+
filters={{ ...filters, ...globalFilters, period }}
|
|
942
|
+
pageSource={
|
|
943
|
+
compactExportSource ?? agentInvocationExportSource ?? costGroupExportSource
|
|
944
|
+
}
|
|
945
|
+
rows={exportRows as unknown as readonly Record<string, unknown>[]}
|
|
946
|
+
view={`cost-${view}`}
|
|
947
|
+
/>
|
|
948
|
+
</div>
|
|
949
|
+
) : null}
|
|
800
950
|
</div>
|
|
801
951
|
{/* CostMonitorContent owns `view === "models" && useAggregateGroups ? (` and `rows={groups.models}`. */}
|
|
802
952
|
<CostMonitorContent
|
|
@@ -321,26 +321,58 @@ describe("grouped cost availability", () => {
|
|
|
321
321
|
},
|
|
322
322
|
});
|
|
323
323
|
const columns = table.props.columns as Array<{ key: string; footer?: unknown }>;
|
|
324
|
-
|
|
325
|
-
|
|
324
|
+
const tokenFooter = columns.find((column) => column.key === "tokens")?.footer;
|
|
325
|
+
const costFooter = columns.find((column) => column.key === "cost")?.footer;
|
|
326
|
+
expect(tokenFooter).toBeDefined();
|
|
327
|
+
expect(costFooter).toBeDefined();
|
|
328
|
+
expect((tokenFooter as { props: { children: unknown } }).props.children).toBe("50");
|
|
329
|
+
expect((costFooter as { props: { children: unknown } }).props.children).toContain("20,00");
|
|
326
330
|
});
|
|
327
331
|
it("renders ZAIP agent identity without a synthetic date column", () => {
|
|
328
332
|
const table = CostGroupsTable({
|
|
329
|
-
rows: [
|
|
333
|
+
rows: [
|
|
334
|
+
{
|
|
335
|
+
...unavailableGroup,
|
|
336
|
+
key: "zaip-agent-builder",
|
|
337
|
+
label: "zaip-agent-builder",
|
|
338
|
+
persona: "Rafa",
|
|
339
|
+
job: "Builder",
|
|
340
|
+
},
|
|
341
|
+
],
|
|
330
342
|
currency: "BRL",
|
|
331
343
|
locale: "pt-BR",
|
|
332
344
|
showDateTime: false,
|
|
333
345
|
showAgentIdentity: true,
|
|
334
346
|
});
|
|
335
|
-
const columns = table.props.columns as Array<{
|
|
347
|
+
const columns = table.props.columns as Array<{
|
|
348
|
+
key: string;
|
|
349
|
+
label: string;
|
|
350
|
+
hidden?: boolean;
|
|
351
|
+
render?: (row: { persona?: string | null; job?: string | null }) => unknown;
|
|
352
|
+
}>;
|
|
336
353
|
expect(columns.find((column) => column.key === "latestStartedAt")?.hidden).toBe(true);
|
|
337
|
-
expect(columns.find((column) => column.key === "persona")?.render?.({ persona: "Rafa" })).toBe(
|
|
338
|
-
|
|
354
|
+
expect(columns.find((column) => column.key === "persona")?.render?.({ persona: "Rafa" })).toBe(
|
|
355
|
+
"Rafa",
|
|
356
|
+
);
|
|
357
|
+
expect(columns.find((column) => column.key === "job")?.render?.({ job: "Builder" })).toBe(
|
|
358
|
+
"Builder",
|
|
359
|
+
);
|
|
339
360
|
expect(columns.find((column) => column.key === "tasks")).toBeUndefined();
|
|
361
|
+
expect(table.props.defaultSort).toEqual({ key: "cost", direction: "desc" });
|
|
340
362
|
});
|
|
341
363
|
it("keeps legacy codex identity fields blank and uses the complete paged aggregate in its footer", () => {
|
|
342
364
|
const table = CostGroupsTable({
|
|
343
|
-
rows: [
|
|
365
|
+
rows: [
|
|
366
|
+
{
|
|
367
|
+
...unavailableGroup,
|
|
368
|
+
key: "codex",
|
|
369
|
+
label: "codex",
|
|
370
|
+
run_count: 1,
|
|
371
|
+
total_tokens: 10,
|
|
372
|
+
estimated_brl: 1,
|
|
373
|
+
estimated_usd: 1,
|
|
374
|
+
},
|
|
375
|
+
],
|
|
344
376
|
currency: "BRL",
|
|
345
377
|
locale: "pt-BR",
|
|
346
378
|
showDateTime: false,
|
|
@@ -355,11 +387,19 @@ describe("grouped cost availability", () => {
|
|
|
355
387
|
duration: { known_sum: 0, unknown: 1, complete: false, coverage_ratio: 0 },
|
|
356
388
|
},
|
|
357
389
|
});
|
|
358
|
-
const columns = table.props.columns as Array<{
|
|
359
|
-
|
|
390
|
+
const columns = table.props.columns as Array<{
|
|
391
|
+
key: string;
|
|
392
|
+
render?: (row: { persona?: string | null; job?: string | null }) => unknown;
|
|
393
|
+
footer?: unknown;
|
|
394
|
+
}>;
|
|
395
|
+
expect(columns.find((column) => column.key === "persona")?.render?.({ persona: null })).toBe(
|
|
396
|
+
"",
|
|
397
|
+
);
|
|
360
398
|
expect(columns.find((column) => column.key === "job")?.render?.({ job: null })).toBe("");
|
|
361
399
|
expect(columns.find((column) => column.key === "runs")?.footer).toBe(2);
|
|
362
|
-
|
|
400
|
+
const tokenFooter = columns.find((column) => column.key === "tokens")?.footer;
|
|
401
|
+
expect(tokenFooter).toBeDefined();
|
|
402
|
+
expect((tokenFooter as { props: { children: unknown } }).props.children).toBe("30");
|
|
363
403
|
});
|
|
364
404
|
it("renders model groups without date and labels distinct invocation tasks", () => {
|
|
365
405
|
const table = CostGroupsTable({
|
|
@@ -398,8 +438,9 @@ describe("grouped cost availability", () => {
|
|
|
398
438
|
duration: { known_sum: 20_000, unknown: 1, complete: false, coverage_ratio: 0.5 },
|
|
399
439
|
};
|
|
400
440
|
const table = CostGroupsTable({ rows: [partial], currency: "BRL", locale: "pt-BR" });
|
|
401
|
-
const duration = (
|
|
402
|
-
.
|
|
441
|
+
const duration = (
|
|
442
|
+
table.props.columns as Array<{ key: string; footer?: { props: { children: unknown } } }>
|
|
443
|
+
).find((column) => column.key === "duration");
|
|
403
444
|
expect(duration?.footer?.props.children).toBe("20 seg");
|
|
404
445
|
});
|
|
405
446
|
it("does not expose coverage as a detailed Run column", () => {
|
|
@@ -470,11 +511,28 @@ describe("grouped cost availability", () => {
|
|
|
470
511
|
}>;
|
|
471
512
|
const column = (key: string) => columns.find((candidate) => candidate.key === key);
|
|
472
513
|
const numericKeys = [
|
|
473
|
-
"duration",
|
|
474
|
-
"
|
|
475
|
-
"
|
|
476
|
-
"
|
|
477
|
-
"
|
|
514
|
+
"duration",
|
|
515
|
+
"inputTokens",
|
|
516
|
+
"cachedInputTokens",
|
|
517
|
+
"outputTokens",
|
|
518
|
+
"reasoningTokens",
|
|
519
|
+
"totalTokens",
|
|
520
|
+
"inputRate",
|
|
521
|
+
"cacheRate",
|
|
522
|
+
"outputRate",
|
|
523
|
+
"reasoningRate",
|
|
524
|
+
"contextMultiplier",
|
|
525
|
+
"inputCost",
|
|
526
|
+
"cacheCost",
|
|
527
|
+
"outputCost",
|
|
528
|
+
"reasoningCost",
|
|
529
|
+
"standardCost",
|
|
530
|
+
"speedUplift",
|
|
531
|
+
"finalUsd",
|
|
532
|
+
"fxRate",
|
|
533
|
+
"recordedFxRate",
|
|
534
|
+
"recordedBrl",
|
|
535
|
+
"cost",
|
|
478
536
|
];
|
|
479
537
|
for (const key of numericKeys) {
|
|
480
538
|
expect(column(key)?.description).toContain("projeção SQLite/API");
|