@cat-factory/app 0.308.0 → 0.310.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 +32 -2
- package/app/assets/css/main.css +22 -0
- package/app/assets/css/prose.css +4 -4
- package/app/assets/css/type.css +24 -0
- package/app/components/assistant/AssistantModal.vue +8 -6
- package/app/components/auth/BackendMisconfiguredScreen.vue +4 -3
- package/app/components/auth/LoginScreen.vue +40 -26
- package/app/components/auth/ResetPasswordScreen.vue +9 -4
- package/app/components/auth/UserMenu.vue +5 -4
- package/app/components/binaryCandidates/BinaryCandidatesWindow.vue +48 -37
- package/app/components/binaryOutput/BinaryOutputReport.vue +10 -14
- package/app/components/binaryOutput/StoredAssetView.vue +13 -11
- package/app/components/board/AddTaskModal.vue +30 -27
- package/app/components/board/AgentFailureCard.vue +21 -18
- package/app/components/board/AgentFailureHistory.vue +18 -9
- package/app/components/board/CreateInitiativeModal.vue +7 -6
- package/app/components/board/FailureDetail.vue +22 -12
- package/app/components/board/FailureHistoryList.vue +5 -5
- package/app/components/board/RecurringPipelineModal.vue +12 -11
- package/app/components/board/ReviewFrictionDialog.vue +8 -6
- package/app/components/board/StepExecutionHistory.vue +8 -8
- package/app/components/board/nodes/AgentChip.vue +1 -1
- package/app/components/board/nodes/BlockNode.vue +25 -24
- package/app/components/board/nodes/DecisionBadge.vue +4 -3
- package/app/components/board/nodes/EpicNode.vue +4 -4
- package/app/components/board/nodes/FrameSwimlanes.vue +8 -10
- package/app/components/board/nodes/InitiativeCard.vue +4 -4
- package/app/components/board/nodes/LaneGroup.vue +3 -5
- package/app/components/board/nodes/TaskCard.vue +20 -15
- package/app/components/board/nodes/TaskLane.vue +3 -3
- package/app/components/board/nodes/TaskPipelineMini.vue +21 -18
- package/app/components/bootstrap/AdoptionReviewModal.vue +36 -26
- package/app/components/bootstrap/BootstrapModal.vue +14 -13
- package/app/components/bootstrap/BootstrapRunSteps.vue +1 -1
- package/app/components/brainstorm/BrainstormWindow.vue +13 -10
- package/app/components/bugFishing/BugFishingWindow.vue +81 -58
- package/app/components/clarity/ClarityReviewWindow.vue +13 -10
- package/app/components/common/AsyncViewError.vue +1 -1
- package/app/components/common/ClarificationItem.vue +6 -6
- package/app/components/common/CopyButton.vue +12 -11
- package/app/components/common/DescriptorFields.vue +1 -1
- package/app/components/common/EmptyState.vue +1 -1
- package/app/components/common/IconButton.vue +34 -9
- package/app/components/common/InterviewGateNotice.vue +4 -4
- package/app/components/common/MarkdownProse.vue +8 -2
- package/app/components/common/SectionLabel.vue +38 -0
- package/app/components/consensus/ConsensusSessionWindow.vue +10 -9
- package/app/components/context/ContextAttachmentFields.vue +32 -20
- package/app/components/docs/DocInterviewWindow.vue +10 -9
- package/app/components/documents/ContextDocumentPicker.vue +22 -21
- package/app/components/documents/DocumentImportModal.vue +7 -5
- package/app/components/documents/DocumentOriginLink.vue +12 -9
- package/app/components/documents/DocumentSourceConnectModal.vue +2 -2
- package/app/components/documents/DocumentSyncState.vue +4 -4
- package/app/components/documents/DocumentTemplatesModal.vue +5 -4
- package/app/components/documents/RepoContextDocPicker.vue +7 -9
- package/app/components/documents/StartFromDesignModal.vue +4 -4
- package/app/components/documents/TaskContextDocs.vue +1 -1
- package/app/components/environments/EnvSetupStepper.vue +3 -3
- package/app/components/environments/EnvironmentStatusPanel.vue +15 -13
- package/app/components/environments/steps/EnvPreflightStep.vue +8 -8
- package/app/components/environments/steps/EnvReviewStep.vue +23 -22
- package/app/components/environments/steps/EnvSaveStep.vue +5 -5
- package/app/components/focus/BlockFocusView.vue +11 -10
- package/app/components/followUp/FollowUpWindow.vue +18 -15
- package/app/components/forkDecision/ForkDecisionWindow.vue +85 -97
- package/app/components/foundational/FoundationalContractSummary.vue +2 -2
- package/app/components/foundational/FoundationalServiceCatalogList.vue +6 -5
- package/app/components/foundational/FoundationalServiceRegistry.vue +10 -9
- package/app/components/foundational/FoundationalServiceSources.vue +7 -6
- package/app/components/foundational/FoundationalSuppressions.vue +2 -2
- package/app/components/fragments/FragmentLibraryManager.vue +8 -7
- package/app/components/fragments/FragmentSelector.vue +22 -20
- package/app/components/gates/GateFailingCheckList.vue +7 -6
- package/app/components/gates/GateResultView.vue +55 -49
- package/app/components/github/AddServiceFromRepoModal.vue +16 -11
- package/app/components/github/BranchProtectionPreflight.vue +5 -5
- package/app/components/github/GitHubConnect.vue +5 -3
- package/app/components/github/GitHubOnboarding.vue +7 -2
- package/app/components/github/GitHubPanel.vue +23 -19
- package/app/components/github/RepoTreeBrowser.vue +16 -13
- package/app/components/humanTest/HumanTestWindow.vue +29 -24
- package/app/components/initiative/InitiativePlanNotice.vue +3 -3
- package/app/components/initiative/InitiativePlanReview.vue +46 -38
- package/app/components/initiative/InitiativePlanningWindow.vue +5 -5
- package/app/components/initiative/InitiativeTrackerWindow.vue +213 -165
- package/app/components/judge/JudgeResultView.vue +28 -27
- package/app/components/kaizen/KaizenPanel.vue +70 -56
- package/app/components/kaizen/KaizenStepStatus.vue +7 -6
- package/app/components/layout/AccountAuditLog.vue +1 -1
- package/app/components/layout/AccountDeploymentSettings.vue +10 -10
- package/app/components/layout/AccountFailureKindRules.vue +13 -13
- package/app/components/layout/AccountFoundationalSettings.vue +1 -1
- package/app/components/layout/AccountFragmentSettings.vue +1 -1
- package/app/components/layout/AccountModelPolicySettings.vue +7 -7
- package/app/components/layout/AccountPlatformAlertSettings.vue +8 -8
- package/app/components/layout/AccountRiskPolicySettings.vue +2 -2
- package/app/components/layout/AccountRunCredentialSettings.vue +3 -3
- package/app/components/layout/AccountSkillSettings.vue +1 -1
- package/app/components/layout/AccountTeamSettings.vue +13 -9
- package/app/components/layout/AiProvidersBanner.vue +1 -1
- package/app/components/layout/AppearanceSwitcher.vue +5 -4
- package/app/components/layout/BoardSwitcher.vue +13 -10
- package/app/components/layout/BoardToolbar.vue +10 -5
- package/app/components/layout/CommandBar.vue +8 -5
- package/app/components/layout/DefaultTestEnvBanner.vue +6 -5
- package/app/components/layout/IntegrationsHub.vue +12 -9
- package/app/components/layout/LanguageSwitcher.vue +5 -4
- package/app/components/layout/ModelProvidersHub.vue +10 -7
- package/app/components/layout/NotificationsInbox.vue +47 -36
- package/app/components/layout/PersonalSetupModal.vue +9 -6
- package/app/components/layout/RolePrompt.vue +5 -4
- package/app/components/layout/SideBar.vue +7 -8
- package/app/components/layout/SpendWarningBanner.vue +3 -3
- package/app/components/layout/TranslationWarningBanner.vue +5 -4
- package/app/components/layout/UiModeSwitcher.vue +15 -12
- package/app/components/layout/UiRoleSwitcher.vue +10 -8
- package/app/components/layout/WorkspaceMembersSettings.vue +2 -2
- package/app/components/media/ArtifactLightbox.vue +74 -44
- package/app/components/media/ImageCompare.vue +80 -85
- package/app/components/merge/MergeEffortChips.vue +4 -6
- package/app/components/notifications/NotificationSettingsPanel.vue +6 -5
- package/app/components/observability/OutcomeFilterChips.vue +6 -5
- package/app/components/observability/RunFailureSummary.vue +22 -23
- package/app/components/observability/StepMetricsBar.vue +9 -8
- package/app/components/observability/StepModelActivity.vue +8 -5
- package/app/components/observability/ToolCallList.vue +19 -20
- package/app/components/outcome/OutcomeSummaryWindow.vue +48 -46
- package/app/components/palettes/AgentPalette.vue +21 -15
- package/app/components/palettes/AgentTierSelect.vue +1 -1
- package/app/components/palettes/PipelinePurposeSelect.vue +1 -1
- package/app/components/panels/AgentStepDetail.vue +57 -49
- package/app/components/panels/AttemptEntryHeader.vue +2 -2
- package/app/components/panels/DecisionModal.vue +1 -1
- package/app/components/panels/GenericStructuredResultView.vue +6 -5
- package/app/components/panels/InspectorPanel.vue +15 -13
- package/app/components/panels/MergerResultView.vue +10 -9
- package/app/components/panels/ObservabilityPanel.vue +211 -186
- package/app/components/panels/OperatorDashboardPanel.vue +124 -115
- package/app/components/panels/ReportsPanel.vue +87 -83
- package/app/components/panels/ReportsSpendBreakdown.vue +2 -2
- package/app/components/panels/ResultWindowShell.vue +152 -137
- package/app/components/panels/RunDetailLoadState.vue +1 -1
- package/app/components/panels/StepContainerStatus.vue +17 -16
- package/app/components/panels/StepDelegatedStatus.vue +24 -21
- package/app/components/panels/StepEffortReport.vue +12 -17
- package/app/components/panels/StepFragmentAdherence.vue +9 -10
- package/app/components/panels/StepMetadataCard.vue +41 -43
- package/app/components/panels/StepReproductionReport.vue +18 -20
- package/app/components/panels/StepRestartControl.vue +3 -2
- package/app/components/panels/StepRunMeta.vue +27 -26
- package/app/components/panels/StepTestReport.vue +16 -15
- package/app/components/panels/StepToolServers.vue +7 -8
- package/app/components/panels/StepValidationReport.vue +5 -5
- package/app/components/panels/inspector/ContainerSummary.vue +4 -4
- package/app/components/panels/inspector/DocReferenceRepos.vue +5 -4
- package/app/components/panels/inspector/EnvProbeReport.vue +16 -13
- package/app/components/panels/inspector/EpicChildren.vue +12 -10
- package/app/components/panels/inspector/FrontendBindingsResolved.vue +5 -4
- package/app/components/panels/inspector/FrontendConfig.vue +29 -36
- package/app/components/panels/inspector/InitiativeInspector.vue +3 -3
- package/app/components/panels/inspector/InspectorSection.vue +25 -17
- package/app/components/panels/inspector/RecurringScheduleSettings.vue +9 -8
- package/app/components/panels/inspector/ServiceConnections.vue +5 -4
- package/app/components/panels/inspector/ServiceReleaseHealthConfig.vue +2 -2
- package/app/components/panels/inspector/ServiceSelfTests.vue +9 -13
- package/app/components/panels/inspector/ServiceTestConfig.vue +46 -49
- package/app/components/panels/inspector/ServiceTestSecrets.vue +3 -3
- package/app/components/panels/inspector/ServiceTestingContext.vue +2 -2
- package/app/components/panels/inspector/ServiceValidationConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAgentConfig.vue +2 -2
- package/app/components/panels/inspector/TaskAprioriBranches.vue +6 -5
- package/app/components/panels/inspector/TaskDependencies.vue +1 -1
- package/app/components/panels/inspector/TaskEstimateBadge.vue +3 -7
- package/app/components/panels/inspector/TaskExecution.vue +18 -16
- package/app/components/panels/inspector/TaskRunSettings.vue +45 -44
- package/app/components/panels/inspector/TaskStructure.vue +5 -4
- package/app/components/pipeline/AgentPromptEditor.vue +15 -14
- package/app/components/pipeline/BinaryOutputStepPicker.vue +42 -52
- package/app/components/pipeline/EstimateThresholdFields.vue +14 -11
- package/app/components/pipeline/GateConfigFields.vue +19 -23
- package/app/components/pipeline/IterationCapPrompt.vue +1 -1
- package/app/components/pipeline/PipelineBuilder.vue +113 -99
- package/app/components/pipeline/PipelineHealthModal.vue +7 -7
- package/app/components/pipeline/PipelinePicker.vue +11 -9
- package/app/components/pipeline/PipelinePreview.vue +6 -7
- package/app/components/pipeline/PipelineProgress.vue +49 -45
- package/app/components/prReview/PrReviewWindow.vue +87 -65
- package/app/components/providers/AiPresetMismatchDialog.vue +4 -3
- package/app/components/providers/AiProviderOnboardingModal.vue +2 -2
- package/app/components/providers/ApiKeysSection.vue +11 -9
- package/app/components/providers/PersonalSubscriptionSection.vue +4 -3
- package/app/components/providers/VendorCredentialsModal.vue +5 -4
- package/app/components/provisioning/ProvisioningLogsDrawer.vue +10 -9
- package/app/components/ralph/RalphLoopResultView.vue +29 -29
- package/app/components/requirements/RequirementsReviewWindow.vue +22 -17
- package/app/components/riskPolicy/RiskPolicyPicker.vue +13 -11
- package/app/components/riskPolicy/RiskPolicyPreview.vue +16 -15
- package/app/components/sandbox/SandboxPanel.vue +93 -73
- package/app/components/settings/ApiTokensPanel.vue +1 -1
- package/app/components/settings/BudgetSettings.vue +18 -17
- package/app/components/settings/CapabilityCredentialsPanel.vue +5 -5
- package/app/components/settings/CloudflareHandlerSection.vue +44 -41
- package/app/components/settings/ComposeEnvironmentSetupSection.vue +14 -12
- package/app/components/settings/ConnectionTestVerdict.vue +1 -1
- package/app/components/settings/ConsensusGroupsSection.vue +58 -47
- package/app/components/settings/CustomManifestTypeEditor.vue +8 -7
- package/app/components/settings/DefaultProvisionTypeSection.vue +5 -5
- package/app/components/settings/InfraHandlersConfigurator.vue +26 -24
- package/app/components/settings/InfrastructureBackendPicker.vue +18 -18
- package/app/components/settings/IssueTrackerPanel.vue +30 -21
- package/app/components/settings/KubernetesEngineForm.vue +9 -8
- package/app/components/settings/KubernetesEnvironmentForm.vue +4 -3
- package/app/components/settings/LocalContainerPoolSettings.vue +2 -2
- package/app/components/settings/LocalModelEndpointsPanel.vue +13 -11
- package/app/components/settings/MergeClassRulesEditor.vue +6 -5
- package/app/components/settings/MergeRolePolicyEditor.vue +13 -12
- package/app/components/settings/ModelConfigurationPanel.vue +17 -19
- package/app/components/settings/ModelPresetHealthModal.vue +3 -3
- package/app/components/settings/ObservabilityConnectionPanel.vue +1 -1
- package/app/components/settings/OpenRouterCatalogPanel.vue +10 -8
- package/app/components/settings/PackageRegistriesPanel.vue +4 -4
- package/app/components/settings/ProviderConnectionTab.vue +5 -4
- package/app/components/settings/ProviderManifestEditor.vue +9 -8
- package/app/components/settings/ProviderPreferenceEditor.vue +13 -13
- package/app/components/settings/RiskPolicyCreateForm.vue +40 -26
- package/app/components/settings/RiskPolicyEditorRow.vue +21 -19
- package/app/components/settings/RiskPolicyHealthModal.vue +3 -3
- package/app/components/settings/RiskPolicyPanel.vue +11 -13
- package/app/components/settings/ServiceFragmentDefaultsPanel.vue +15 -12
- package/app/components/settings/SharedStacksPanel.vue +5 -5
- package/app/components/settings/TaskSourceCard.vue +2 -2
- package/app/components/settings/TaskTypeSuppressionsPanel.vue +4 -4
- package/app/components/settings/ToolServerChecklist.vue +22 -22
- package/app/components/settings/UsageSettings.vue +13 -13
- package/app/components/settings/UserSecretsSection.vue +4 -3
- package/app/components/settings/WorkspaceMetadataSettings.vue +6 -5
- package/app/components/settings/WorkspaceSettingsPanel.vue +72 -58
- package/app/components/skills/ReviewSkillQueue.vue +12 -10
- package/app/components/skills/SkillLibraryManager.vue +9 -8
- package/app/components/slack/SlackPanel.vue +17 -12
- package/app/components/spec/ServiceSpecWindow.vue +19 -19
- package/app/components/tasks/BugHuntModal.vue +1 -1
- package/app/components/tasks/ContextIssuePicker.vue +16 -15
- package/app/components/tasks/TaskContextIssues.vue +5 -4
- package/app/components/tasks/TaskImportModal.vue +3 -2
- package/app/components/tasks/TaskSourceConnectModal.vue +5 -5
- package/app/components/testing/TestReportWindow.vue +67 -60
- package/app/components/theme/ThemeImportModal.vue +2 -2
- package/app/components/tutorial/TutorialNudge.vue +3 -2
- package/app/components/tutorial/TutorialOverlay.vue +3 -2
- package/app/components/vcs/GitLabConnect.vue +1 -1
- package/app/components/visualConfirm/VisualConfirmationWindow.vue +79 -54
- package/app/utils/theme/builtins.ts +7 -1
- package/i18n/locales/de.json +7 -3
- package/i18n/locales/en.json +7 -3
- package/i18n/locales/es.json +7 -3
- package/i18n/locales/fr.json +7 -3
- package/i18n/locales/he.json +7 -3
- package/i18n/locales/it.json +7 -3
- package/i18n/locales/ja.json +7 -3
- package/i18n/locales/pl.json +7 -3
- package/i18n/locales/tr.json +7 -3
- package/i18n/locales/uk.json +7 -3
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, nextTick, reactive, ref, watch } from 'vue'
|
|
3
3
|
import { onKeyStroke } from '@vueuse/core'
|
|
4
|
+
import type { TableColumn } from '@nuxt/ui'
|
|
4
5
|
import { isLlmWarningFinishReason } from '@cat-factory/contracts'
|
|
5
6
|
import type {
|
|
6
7
|
AgentContextSnapshot,
|
|
@@ -29,6 +30,8 @@ import {
|
|
|
29
30
|
import OutcomeFilterChips from '~/components/observability/OutcomeFilterChips.vue'
|
|
30
31
|
import RunFailureSummary from '~/components/observability/RunFailureSummary.vue'
|
|
31
32
|
import ToolCallList from '~/components/observability/ToolCallList.vue'
|
|
33
|
+
import SectionLabel from '~/components/common/SectionLabel.vue'
|
|
34
|
+
import IconButton from '~/components/common/IconButton.vue'
|
|
32
35
|
|
|
33
36
|
/** No run selected: the same empty, NOT-truncated trajectory the store answers with. */
|
|
34
37
|
const EMPTY_TRAJECTORY: RunToolCallTrajectory = Object.freeze({
|
|
@@ -165,6 +168,22 @@ function openToolsView() {
|
|
|
165
168
|
ensureTrajectoryLoaded()
|
|
166
169
|
}
|
|
167
170
|
|
|
171
|
+
const viewTabs = computed(() => [
|
|
172
|
+
{ value: 'calls', label: t('observability.modelActivity') },
|
|
173
|
+
{ value: 'tools', label: t('observability.toolCalls.title') },
|
|
174
|
+
{ value: 'context', label: t('observability.providedContext') },
|
|
175
|
+
{ value: 'search', label: t('observability.webSearch') },
|
|
176
|
+
])
|
|
177
|
+
|
|
178
|
+
/** The tools view has a side effect (lazy trajectory load), so selection routes through here. */
|
|
179
|
+
function selectView(next: string) {
|
|
180
|
+
if (next === 'tools') {
|
|
181
|
+
openToolsView()
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
view.value = next as typeof view.value
|
|
185
|
+
}
|
|
186
|
+
|
|
168
187
|
/**
|
|
169
188
|
* Load the trajectory the first time it is actually looked at.
|
|
170
189
|
*
|
|
@@ -410,6 +429,23 @@ const costCurrency = computed(
|
|
|
410
429
|
const showCost = computed(
|
|
411
430
|
() => !!costCurrency.value && phaseRows.value.some((p) => p.costEstimate != null),
|
|
412
431
|
)
|
|
432
|
+
// Column definitions rather than hand-written `<th>`s. The cost column stays conditional on the
|
|
433
|
+
// same signal: a deployment with no rate table must not be shown a column of em dashes.
|
|
434
|
+
const phaseColumns = computed<TableColumn<(typeof phaseRows.value)[number]>[]>(() => [
|
|
435
|
+
{ id: 'phase' },
|
|
436
|
+
{ id: 'turns' },
|
|
437
|
+
{ id: 'tokens' },
|
|
438
|
+
...(showCost.value ? [{ id: 'cost' } as TableColumn<(typeof phaseRows.value)[number]>] : []),
|
|
439
|
+
// `aria-sort` needs BOTH halves: UTable asks `enableSorting && column.getCanSort()`, and
|
|
440
|
+
// `getCanSort()` is false on a column with no accessor, so `enableSorting` alone emitted
|
|
441
|
+
// nothing and the header silently stopped stating the order. The rows arrive in this order
|
|
442
|
+
// from the rollup, so `manualSorting` below keeps TanStack from re-deriving it: the
|
|
443
|
+
// declaration MARKS the order, it does not produce it, and nothing here offers a sort control.
|
|
444
|
+
{ id: 'carryCost', accessorKey: 'carryCostTokens', enableSorting: true },
|
|
445
|
+
])
|
|
446
|
+
/** The order the rollup already returns, stated so the header can say which column it is. */
|
|
447
|
+
const PHASE_SORTING = [{ id: 'carryCost', desc: true }]
|
|
448
|
+
const PHASE_SORTING_OPTIONS = { manualSorting: true }
|
|
413
449
|
/**
|
|
414
450
|
* The run's estimated cost, folded from the same SQL rollup the phase table shows — NOT from
|
|
415
451
|
* the capped call list the token totals beside it use, which would silently under-report a run
|
|
@@ -520,44 +556,17 @@ function exportJson() {
|
|
|
520
556
|
</p>
|
|
521
557
|
</div>
|
|
522
558
|
<div class="ms-auto flex items-center gap-1.5">
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
class="rounded-md px-2.5 py-1 transition"
|
|
535
|
-
:class="
|
|
536
|
-
view === 'tools' ? 'bg-elevated text-app-100' : 'text-muted hover:text-default'
|
|
537
|
-
"
|
|
538
|
-
@click="openToolsView()"
|
|
539
|
-
>
|
|
540
|
-
{{ t('observability.toolCalls.title') }}
|
|
541
|
-
</button>
|
|
542
|
-
<button
|
|
543
|
-
class="rounded-md px-2.5 py-1 transition"
|
|
544
|
-
:class="
|
|
545
|
-
view === 'context' ? 'bg-elevated text-app-100' : 'text-muted hover:text-default'
|
|
546
|
-
"
|
|
547
|
-
@click="view = 'context'"
|
|
548
|
-
>
|
|
549
|
-
{{ t('observability.providedContext') }}
|
|
550
|
-
</button>
|
|
551
|
-
<button
|
|
552
|
-
class="rounded-md px-2.5 py-1 transition"
|
|
553
|
-
:class="
|
|
554
|
-
view === 'search' ? 'bg-elevated text-app-100' : 'text-muted hover:text-default'
|
|
555
|
-
"
|
|
556
|
-
@click="view = 'search'"
|
|
557
|
-
>
|
|
558
|
-
{{ t('observability.webSearch') }}
|
|
559
|
-
</button>
|
|
560
|
-
</div>
|
|
559
|
+
<!-- Four VIEWS of the same run, which is what tabs mean. The trajectory is loaded
|
|
560
|
+
lazily the first time the tools view is opened, so the change is watched rather
|
|
561
|
+
than bound straight to `view`. -->
|
|
562
|
+
<UTabs
|
|
563
|
+
:model-value="view"
|
|
564
|
+
:items="viewTabs"
|
|
565
|
+
:content="false"
|
|
566
|
+
size="xs"
|
|
567
|
+
class="me-1"
|
|
568
|
+
@update:model-value="selectView(String($event))"
|
|
569
|
+
/>
|
|
561
570
|
<UButton
|
|
562
571
|
v-if="view === 'calls'"
|
|
563
572
|
icon="i-lucide-download"
|
|
@@ -571,12 +580,12 @@ function exportJson() {
|
|
|
571
580
|
>
|
|
572
581
|
{{ t('observability.exportJson') }}
|
|
573
582
|
</UButton>
|
|
574
|
-
<
|
|
583
|
+
<IconButton
|
|
575
584
|
icon="i-lucide-x"
|
|
576
585
|
color="neutral"
|
|
577
586
|
variant="ghost"
|
|
578
587
|
size="sm"
|
|
579
|
-
:
|
|
588
|
+
:label="t('observability.closeEsc')"
|
|
580
589
|
@click="close"
|
|
581
590
|
/>
|
|
582
591
|
</div>
|
|
@@ -597,28 +606,28 @@ function exportJson() {
|
|
|
597
606
|
|
|
598
607
|
<!-- run-level summary -->
|
|
599
608
|
<section class="rounded-xl border border-default bg-default/50 p-4">
|
|
600
|
-
<dl class="grid grid-cols-2 gap-x-6 gap-y-3 text-
|
|
609
|
+
<dl class="grid grid-cols-2 gap-x-6 gap-y-3 text-sm sm:grid-cols-4">
|
|
601
610
|
<div>
|
|
602
|
-
<
|
|
611
|
+
<SectionLabel as="dt">
|
|
603
612
|
{{ t('observability.summary.calls') }}
|
|
604
|
-
</
|
|
613
|
+
</SectionLabel>
|
|
605
614
|
<dd class="mt-0.5 tabular-nums text-default">{{ totals.calls }}</dd>
|
|
606
615
|
</div>
|
|
607
616
|
<div v-if="showCost || !phaseRollup.available">
|
|
608
|
-
<
|
|
617
|
+
<SectionLabel as="dt">
|
|
609
618
|
{{ t('observability.summary.cost') }}
|
|
610
|
-
</
|
|
619
|
+
</SectionLabel>
|
|
611
620
|
<dd class="mt-0.5 tabular-nums text-default">
|
|
612
621
|
{{ runCost ?? '—' }}
|
|
613
|
-
<span class="mt-0.5 block text-
|
|
622
|
+
<span class="mt-0.5 block text-2xs text-dimmed">
|
|
614
623
|
{{ t(costNoteKey) }}
|
|
615
624
|
</span>
|
|
616
625
|
</dd>
|
|
617
626
|
</div>
|
|
618
627
|
<div>
|
|
619
|
-
<
|
|
628
|
+
<SectionLabel as="dt">
|
|
620
629
|
{{ t('observability.summary.tokensInOut') }}
|
|
621
|
-
</
|
|
630
|
+
</SectionLabel>
|
|
622
631
|
<dd class="mt-0.5 tabular-nums text-default">
|
|
623
632
|
<span :title="t('observability.summary.inputTokensHint')">
|
|
624
633
|
{{ formatTokens(totals.inputTokens) }} /
|
|
@@ -626,7 +635,7 @@ function exportJson() {
|
|
|
626
635
|
</span>
|
|
627
636
|
<span
|
|
628
637
|
v-if="totals.cacheReadTokens > 0 || totals.cacheWriteTokens > 0"
|
|
629
|
-
class="mt-0.5 block text-
|
|
638
|
+
class="mt-0.5 block text-2xs"
|
|
630
639
|
>
|
|
631
640
|
<span class="text-muted" :title="t('observability.summary.freshHint')">
|
|
632
641
|
{{
|
|
@@ -665,9 +674,9 @@ function exportJson() {
|
|
|
665
674
|
</dd>
|
|
666
675
|
</div>
|
|
667
676
|
<div>
|
|
668
|
-
<
|
|
677
|
+
<SectionLabel as="dt">
|
|
669
678
|
{{ t('observability.summary.transportOverhead') }}
|
|
670
|
-
</
|
|
679
|
+
</SectionLabel>
|
|
671
680
|
<dd class="mt-0.5 tabular-nums text-default">
|
|
672
681
|
<span v-if="totals.transportPct !== null">
|
|
673
682
|
{{ totals.transportPct }}% · {{ formatMs(totals.overheadMs) }}
|
|
@@ -676,9 +685,9 @@ function exportJson() {
|
|
|
676
685
|
</dd>
|
|
677
686
|
</div>
|
|
678
687
|
<div>
|
|
679
|
-
<
|
|
688
|
+
<SectionLabel as="dt">
|
|
680
689
|
{{ t('observability.summary.modelExecution') }}
|
|
681
|
-
</
|
|
690
|
+
</SectionLabel>
|
|
682
691
|
<dd class="mt-0.5 tabular-nums text-default">
|
|
683
692
|
{{ formatMs(totals.upstreamMs) }}
|
|
684
693
|
</dd>
|
|
@@ -718,89 +727,112 @@ function exportJson() {
|
|
|
718
727
|
class="rounded-xl border border-default bg-default/50 p-4"
|
|
719
728
|
>
|
|
720
729
|
<div class="flex items-baseline gap-2">
|
|
721
|
-
<
|
|
730
|
+
<SectionLabel as="h2">
|
|
722
731
|
{{ t('observability.phase.title') }}
|
|
723
|
-
</
|
|
724
|
-
<span v-if="phaseRollup.available" class="text-
|
|
732
|
+
</SectionLabel>
|
|
733
|
+
<span v-if="phaseRollup.available" class="text-2xs text-app-600">
|
|
725
734
|
{{ t('observability.phase.subtitle') }}
|
|
726
735
|
</span>
|
|
727
736
|
</div>
|
|
728
737
|
<!-- No rollup to fold: said in words, because an absent table and a run that spent
|
|
729
738
|
nothing look identical, and the calls listed above prove it spent something. -->
|
|
730
|
-
<p v-if="!phaseRollup.available" class="mt-2 text-
|
|
739
|
+
<p v-if="!phaseRollup.available" class="mt-2 text-xs text-muted">
|
|
731
740
|
{{ t('observability.phase.noRollup') }}
|
|
732
741
|
</p>
|
|
733
742
|
<div v-else class="mt-3 overflow-x-auto">
|
|
734
|
-
<
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
743
|
+
<UTable
|
|
744
|
+
:data="phaseRows"
|
|
745
|
+
:columns="phaseColumns"
|
|
746
|
+
:sorting="PHASE_SORTING"
|
|
747
|
+
:sorting-options="PHASE_SORTING_OPTIONS"
|
|
748
|
+
:ui="{
|
|
749
|
+
base: 'min-w-[32rem] text-xs',
|
|
750
|
+
th: 'px-3 py-1.5',
|
|
751
|
+
td: 'px-3 py-1.5 text-xs whitespace-normal',
|
|
752
|
+
}"
|
|
753
|
+
>
|
|
754
|
+
<template #phase-header>
|
|
755
|
+
{{ t('observability.phase.columns.phase') }}
|
|
756
|
+
</template>
|
|
757
|
+
<template #turns-header>
|
|
758
|
+
<span class="block text-end">
|
|
759
|
+
{{ t('observability.phase.columns.turns') }}
|
|
760
|
+
</span>
|
|
761
|
+
</template>
|
|
762
|
+
<template #tokens-header>
|
|
763
|
+
<span class="block text-end">
|
|
764
|
+
{{ t('observability.phase.columns.tokensInOut') }}
|
|
765
|
+
</span>
|
|
766
|
+
</template>
|
|
767
|
+
<template #cost-header>
|
|
768
|
+
<span class="block text-end" :title="t('observability.phase.costHint')">
|
|
769
|
+
{{ t('observability.phase.columns.cost') }}
|
|
770
|
+
</span>
|
|
771
|
+
</template>
|
|
772
|
+
<!-- The sort key, MARKED as one. Rows lead with carry cost rather than
|
|
773
|
+
with tokens, and the two orders genuinely differ: a phase that runs
|
|
774
|
+
late carries almost nothing however much it spent (nothing after it
|
|
775
|
+
re-sends its context). Leaving that implicit invites reading row 1
|
|
776
|
+
as "the phase that burned the most", which is the neighbouring
|
|
777
|
+
column. -->
|
|
778
|
+
<template #carryCost-header>
|
|
779
|
+
<span class="block text-end" :title="t('observability.phase.carryCostHint')">
|
|
780
|
+
{{ t('observability.phase.columns.carryCost') }} ↓
|
|
781
|
+
</span>
|
|
782
|
+
</template>
|
|
783
|
+
<template #phase-cell="{ row }">
|
|
784
|
+
<span :class="row.original.phase ? '' : 'text-muted italic'">
|
|
785
|
+
{{ phaseLabel(row.original.phase) }}
|
|
786
|
+
</span>
|
|
787
|
+
<span v-if="!row.original.phase" class="ms-1.5 text-2xs text-app-600">
|
|
788
|
+
{{ t('observability.phase.unattributedHint') }}
|
|
789
|
+
</span>
|
|
790
|
+
<UBadge
|
|
791
|
+
v-if="row.original.errors"
|
|
792
|
+
color="error"
|
|
793
|
+
variant="subtle"
|
|
794
|
+
size="sm"
|
|
795
|
+
class="ms-2"
|
|
796
|
+
>
|
|
797
|
+
{{
|
|
798
|
+
t(
|
|
799
|
+
'observability.metricsBar.errors',
|
|
800
|
+
{ count: row.original.errors },
|
|
801
|
+
row.original.errors,
|
|
802
|
+
)
|
|
803
|
+
}}
|
|
804
|
+
</UBadge>
|
|
805
|
+
</template>
|
|
806
|
+
<template #turns-cell="{ row }">
|
|
807
|
+
<span class="block text-end tabular-nums text-toned">{{
|
|
808
|
+
row.original.calls
|
|
809
|
+
}}</span>
|
|
810
|
+
</template>
|
|
811
|
+
<template #tokens-cell="{ row }">
|
|
812
|
+
<span class="block text-end tabular-nums text-toned">
|
|
813
|
+
{{ formatTokens(totalInputTokens(row.original)) }}↑
|
|
814
|
+
{{ formatTokens(row.original.completionTokens) }}↓
|
|
815
|
+
</span>
|
|
816
|
+
</template>
|
|
817
|
+
<!-- An em dash, not 0: this phase's model had no rate, and a zero here
|
|
818
|
+
would read as a phase that cost nothing. -->
|
|
819
|
+
<template #cost-cell="{ row }">
|
|
820
|
+
<span class="block text-end tabular-nums text-toned">
|
|
821
|
+
{{ formatCost(row.original.costEstimate, costCurrency) ?? '—' }}
|
|
822
|
+
</span>
|
|
823
|
+
</template>
|
|
824
|
+
<template #carryCost-cell="{ row }">
|
|
825
|
+
<span class="block text-end tabular-nums text-toned">
|
|
826
|
+
{{ formatTokens(row.original.carryCostTokens) }}
|
|
827
|
+
<span
|
|
828
|
+
v-if="carryShare(row.original.carryCostTokens) !== null"
|
|
829
|
+
class="text-app-600"
|
|
830
|
+
>
|
|
831
|
+
· {{ carryShare(row.original.carryCostTokens) }}%
|
|
832
|
+
</span>
|
|
833
|
+
</span>
|
|
834
|
+
</template>
|
|
835
|
+
</UTable>
|
|
804
836
|
</div>
|
|
805
837
|
</section>
|
|
806
838
|
|
|
@@ -838,9 +870,9 @@ function exportJson() {
|
|
|
838
870
|
<!-- per-call list, narrowable by outcome -->
|
|
839
871
|
<template v-else>
|
|
840
872
|
<div class="flex flex-wrap items-center justify-between gap-2">
|
|
841
|
-
<
|
|
873
|
+
<SectionLabel as="h2">
|
|
842
874
|
{{ t('observability.callsTitle') }}
|
|
843
|
-
</
|
|
875
|
+
</SectionLabel>
|
|
844
876
|
<OutcomeFilterChips v-model="callFilter" :options="callFilterOptions" />
|
|
845
877
|
</div>
|
|
846
878
|
|
|
@@ -862,7 +894,9 @@ function exportJson() {
|
|
|
862
894
|
class="overflow-hidden rounded-xl border border-default bg-default/40"
|
|
863
895
|
:class="!c.ok ? 'border-app-error-900/60' : ''"
|
|
864
896
|
>
|
|
865
|
-
<
|
|
897
|
+
<UButton
|
|
898
|
+
color="neutral"
|
|
899
|
+
variant="ghost"
|
|
866
900
|
class="flex w-full items-center gap-3 px-4 py-2.5 text-start transition hover:bg-default/70"
|
|
867
901
|
@click="toggle(c)"
|
|
868
902
|
>
|
|
@@ -876,11 +910,8 @@ function exportJson() {
|
|
|
876
910
|
class="h-4 w-4 shrink-0"
|
|
877
911
|
:style="{ color: agentMeta(c.agentKind).color }"
|
|
878
912
|
/>
|
|
879
|
-
<span class="text-
|
|
880
|
-
<span
|
|
881
|
-
class="hidden truncate text-[11px] text-dimmed sm:inline"
|
|
882
|
-
:title="c.model"
|
|
883
|
-
>
|
|
913
|
+
<span class="text-sm text-default">{{ agentMeta(c.agentKind).label }}</span>
|
|
914
|
+
<span class="hidden truncate text-2xs text-dimmed sm:inline" :title="c.model">
|
|
884
915
|
{{ c.provider }}:{{ c.model }}
|
|
885
916
|
<!-- Which upstream a GATEWAY routed to. Without it every `openrouter` row
|
|
886
917
|
reads alike, and an upstream having a bad day cannot be told from the
|
|
@@ -890,9 +921,7 @@ function exportJson() {
|
|
|
890
921
|
{{ t('observability.call.viaUpstream', { upstream: c.upstreamProvider }) }}
|
|
891
922
|
</span>
|
|
892
923
|
</span>
|
|
893
|
-
<div
|
|
894
|
-
class="ms-auto flex items-center gap-2.5 text-[11px] tabular-nums text-muted"
|
|
895
|
-
>
|
|
924
|
+
<div class="ms-auto flex items-center gap-2.5 text-2xs tabular-nums text-muted">
|
|
896
925
|
<span
|
|
897
926
|
:title="
|
|
898
927
|
t('observability.call.tokensTitle', {
|
|
@@ -939,13 +968,13 @@ function exportJson() {
|
|
|
939
968
|
}}</span>
|
|
940
969
|
<span class="hidden text-app-600 md:inline">{{ clock(c.createdAt) }}</span>
|
|
941
970
|
</div>
|
|
942
|
-
</
|
|
971
|
+
</UButton>
|
|
943
972
|
|
|
944
973
|
<div v-if="expanded[c.id]" class="border-t border-default px-4 py-3 space-y-3">
|
|
945
|
-
<p v-if="c.errorMessage" class="text-
|
|
974
|
+
<p v-if="c.errorMessage" class="text-xs text-app-error-400">
|
|
946
975
|
{{ c.errorMessage }}
|
|
947
976
|
</p>
|
|
948
|
-
<div class="flex flex-wrap gap-x-5 gap-y-1 text-
|
|
977
|
+
<div class="flex flex-wrap gap-x-5 gap-y-1 text-2xs text-dimmed">
|
|
949
978
|
<span>{{ t('observability.call.messages', { count: c.messageCount }) }}</span>
|
|
950
979
|
<span>{{ t('observability.call.tools', { count: c.toolCount }) }}</span>
|
|
951
980
|
<span>{{
|
|
@@ -982,9 +1011,7 @@ function exportJson() {
|
|
|
982
1011
|
</span>
|
|
983
1012
|
</div>
|
|
984
1013
|
<div>
|
|
985
|
-
<
|
|
986
|
-
class="mb-1 flex items-center gap-2 text-[11px] uppercase tracking-wide text-dimmed"
|
|
987
|
-
>
|
|
1014
|
+
<SectionLabel class="mb-1 flex items-center gap-2">
|
|
988
1015
|
<span>{{ t('observability.call.prompt') }}</span>
|
|
989
1016
|
<span
|
|
990
1017
|
v-if="c.promptPrefixCount > 0"
|
|
@@ -996,25 +1023,25 @@ function exportJson() {
|
|
|
996
1023
|
})
|
|
997
1024
|
}}
|
|
998
1025
|
</span>
|
|
999
|
-
</
|
|
1026
|
+
</SectionLabel>
|
|
1000
1027
|
<pre
|
|
1001
|
-
class="max-h-72 overflow-auto rounded-lg bg-app-950/70 p-3 text-
|
|
1028
|
+
class="max-h-72 overflow-auto rounded-lg bg-app-950/70 p-3 text-2xs leading-relaxed text-toned"
|
|
1002
1029
|
>{{ prettyPrompt(c.promptText) }}</pre>
|
|
1003
1030
|
</div>
|
|
1004
1031
|
<div>
|
|
1005
|
-
<
|
|
1032
|
+
<SectionLabel class="mb-1">
|
|
1006
1033
|
{{ t('observability.call.response') }}
|
|
1007
|
-
</
|
|
1034
|
+
</SectionLabel>
|
|
1008
1035
|
<pre
|
|
1009
|
-
class="max-h-72 overflow-auto rounded-lg bg-app-950/70 p-3 text-
|
|
1036
|
+
class="max-h-72 overflow-auto rounded-lg bg-app-950/70 p-3 text-2xs leading-relaxed text-toned"
|
|
1010
1037
|
>{{ c.responseText || '—' }}</pre>
|
|
1011
1038
|
</div>
|
|
1012
1039
|
<div v-if="c.reasoningText">
|
|
1013
|
-
<
|
|
1040
|
+
<SectionLabel class="mb-1">
|
|
1014
1041
|
{{ t('observability.call.reasoning') }}
|
|
1015
|
-
</
|
|
1042
|
+
</SectionLabel>
|
|
1016
1043
|
<pre
|
|
1017
|
-
class="max-h-72 overflow-auto rounded-lg bg-app-950/70 p-3 text-
|
|
1044
|
+
class="max-h-72 overflow-auto rounded-lg bg-app-950/70 p-3 text-2xs leading-relaxed text-muted"
|
|
1018
1045
|
>{{ c.reasoningText }}</pre>
|
|
1019
1046
|
</div>
|
|
1020
1047
|
</div>
|
|
@@ -1039,7 +1066,7 @@ function exportJson() {
|
|
|
1039
1066
|
so the survey's absence would otherwise read as a phase that used no tools. -->
|
|
1040
1067
|
<p
|
|
1041
1068
|
v-if="bootstrap?.monorepo"
|
|
1042
|
-
class="rounded-lg border border-dashed border-default px-3 py-2 text-
|
|
1069
|
+
class="rounded-lg border border-dashed border-default px-3 py-2 text-xs text-muted"
|
|
1043
1070
|
>
|
|
1044
1071
|
{{ t('observability.toolCalls.surveyReadsElsewhere') }}
|
|
1045
1072
|
</p>
|
|
@@ -1094,7 +1121,9 @@ function exportJson() {
|
|
|
1094
1121
|
:key="s.id"
|
|
1095
1122
|
class="overflow-hidden rounded-xl border border-default bg-default/40"
|
|
1096
1123
|
>
|
|
1097
|
-
<
|
|
1124
|
+
<UButton
|
|
1125
|
+
color="neutral"
|
|
1126
|
+
variant="ghost"
|
|
1098
1127
|
class="flex w-full items-center gap-3 px-4 py-2.5 text-start transition hover:bg-default/70"
|
|
1099
1128
|
@click="toggleCtx(s)"
|
|
1100
1129
|
>
|
|
@@ -1108,13 +1137,11 @@ function exportJson() {
|
|
|
1108
1137
|
class="h-4 w-4 shrink-0"
|
|
1109
1138
|
:style="{ color: agentMeta(s.agentKind).color }"
|
|
1110
1139
|
/>
|
|
1111
|
-
<span class="text-
|
|
1112
|
-
<span v-if="s.model" class="hidden truncate text-
|
|
1140
|
+
<span class="text-sm text-default">{{ agentMeta(s.agentKind).label }}</span>
|
|
1141
|
+
<span v-if="s.model" class="hidden truncate text-2xs text-dimmed sm:inline">
|
|
1113
1142
|
{{ s.model }}
|
|
1114
1143
|
</span>
|
|
1115
|
-
<div
|
|
1116
|
-
class="ms-auto flex items-center gap-2.5 text-[11px] tabular-nums text-muted"
|
|
1117
|
-
>
|
|
1144
|
+
<div class="ms-auto flex items-center gap-2.5 text-2xs tabular-nums text-muted">
|
|
1118
1145
|
<span :title="t('observability.context.injectedFiles')">{{
|
|
1119
1146
|
t('observability.context.filesCount', { count: s.contextFiles.length })
|
|
1120
1147
|
}}</span>
|
|
@@ -1123,64 +1150,64 @@ function exportJson() {
|
|
|
1123
1150
|
}}</span>
|
|
1124
1151
|
<span class="hidden text-app-600 md:inline">{{ clock(s.createdAt) }}</span>
|
|
1125
1152
|
</div>
|
|
1126
|
-
</
|
|
1153
|
+
</UButton>
|
|
1127
1154
|
|
|
1128
1155
|
<div v-if="expandedCtx[s.id]" class="border-t border-default px-4 py-3 space-y-3">
|
|
1129
1156
|
<div>
|
|
1130
|
-
<
|
|
1157
|
+
<SectionLabel class="mb-1">
|
|
1131
1158
|
{{ t('observability.context.systemPrompt') }}
|
|
1132
|
-
</
|
|
1159
|
+
</SectionLabel>
|
|
1133
1160
|
<pre
|
|
1134
|
-
class="max-h-72 overflow-auto rounded-lg bg-app-950/70 p-3 text-
|
|
1161
|
+
class="max-h-72 overflow-auto rounded-lg bg-app-950/70 p-3 text-2xs leading-relaxed text-toned"
|
|
1135
1162
|
>{{ s.systemPrompt || '—' }}</pre>
|
|
1136
1163
|
</div>
|
|
1137
1164
|
<div>
|
|
1138
|
-
<
|
|
1165
|
+
<SectionLabel class="mb-1">
|
|
1139
1166
|
{{ t('observability.context.userPrompt') }}
|
|
1140
|
-
</
|
|
1167
|
+
</SectionLabel>
|
|
1141
1168
|
<pre
|
|
1142
|
-
class="max-h-72 overflow-auto rounded-lg bg-app-950/70 p-3 text-
|
|
1169
|
+
class="max-h-72 overflow-auto rounded-lg bg-app-950/70 p-3 text-2xs leading-relaxed text-toned"
|
|
1143
1170
|
>{{ s.userPrompt || '—' }}</pre>
|
|
1144
1171
|
</div>
|
|
1145
1172
|
<div v-if="s.fragments.length">
|
|
1146
|
-
<
|
|
1173
|
+
<SectionLabel class="mb-1">
|
|
1147
1174
|
{{ t('observability.context.bestPracticeFragments') }}
|
|
1148
|
-
</
|
|
1175
|
+
</SectionLabel>
|
|
1149
1176
|
<div
|
|
1150
1177
|
v-for="f in s.fragments"
|
|
1151
1178
|
:key="f.id"
|
|
1152
1179
|
class="mb-2 rounded-lg bg-app-950/70 p-3"
|
|
1153
1180
|
>
|
|
1154
|
-
<div class="mb-1 text-
|
|
1155
|
-
<pre class="max-h-48 overflow-auto text-
|
|
1181
|
+
<div class="mb-1 text-2xs text-muted">{{ f.id }}</div>
|
|
1182
|
+
<pre class="max-h-48 overflow-auto text-2xs leading-relaxed text-toned">{{
|
|
1156
1183
|
f.body
|
|
1157
1184
|
}}</pre>
|
|
1158
1185
|
</div>
|
|
1159
1186
|
</div>
|
|
1160
1187
|
<div v-if="s.contextFiles.length">
|
|
1161
|
-
<
|
|
1188
|
+
<SectionLabel class="mb-1">
|
|
1162
1189
|
{{ t('observability.context.injectedFiles') }}
|
|
1163
|
-
</
|
|
1190
|
+
</SectionLabel>
|
|
1164
1191
|
<div
|
|
1165
1192
|
v-for="file in s.contextFiles"
|
|
1166
1193
|
:key="file.path"
|
|
1167
1194
|
class="mb-2 rounded-lg bg-app-950/70 p-3"
|
|
1168
1195
|
>
|
|
1169
|
-
<div class="mb-1 text-
|
|
1196
|
+
<div class="mb-1 text-2xs text-muted">
|
|
1170
1197
|
{{ file.title }}
|
|
1171
1198
|
<span class="text-app-600">· {{ file.path }}</span>
|
|
1172
1199
|
</div>
|
|
1173
|
-
<pre class="max-h-72 overflow-auto text-
|
|
1200
|
+
<pre class="max-h-72 overflow-auto text-2xs leading-relaxed text-toned">{{
|
|
1174
1201
|
file.content
|
|
1175
1202
|
}}</pre>
|
|
1176
1203
|
</div>
|
|
1177
1204
|
</div>
|
|
1178
1205
|
<div>
|
|
1179
|
-
<
|
|
1206
|
+
<SectionLabel class="mb-1">
|
|
1180
1207
|
{{ t('observability.context.details') }}
|
|
1181
|
-
</
|
|
1208
|
+
</SectionLabel>
|
|
1182
1209
|
<pre
|
|
1183
|
-
class="max-h-48 overflow-auto rounded-lg bg-app-950/70 p-3 text-
|
|
1210
|
+
class="max-h-48 overflow-auto rounded-lg bg-app-950/70 p-3 text-2xs leading-relaxed text-muted"
|
|
1184
1211
|
>{{ prettyExtras(s.extras) }}</pre>
|
|
1185
1212
|
</div>
|
|
1186
1213
|
</div>
|
|
@@ -1192,11 +1219,11 @@ function exportJson() {
|
|
|
1192
1219
|
<!-- Availability header: a static per-run fact (not telemetry-gated). -->
|
|
1193
1220
|
<section
|
|
1194
1221
|
v-if="searchAvailability"
|
|
1195
|
-
class="flex flex-wrap items-center gap-x-3 gap-y-1 rounded-xl border border-default bg-default/50 px-4 py-3 text-
|
|
1222
|
+
class="flex flex-wrap items-center gap-x-3 gap-y-1 rounded-xl border border-default bg-default/50 px-4 py-3 text-sm"
|
|
1196
1223
|
>
|
|
1197
|
-
<
|
|
1224
|
+
<SectionLabel as="span">
|
|
1198
1225
|
{{ t('observability.webSearch') }}
|
|
1199
|
-
</
|
|
1226
|
+
</SectionLabel>
|
|
1200
1227
|
<span
|
|
1201
1228
|
class="inline-flex items-center gap-1.5"
|
|
1202
1229
|
:class="searchAvailability.available ? 'text-app-success-300' : 'text-muted'"
|
|
@@ -1232,9 +1259,9 @@ function exportJson() {
|
|
|
1232
1259
|
</p>
|
|
1233
1260
|
|
|
1234
1261
|
<div v-else>
|
|
1235
|
-
<
|
|
1262
|
+
<SectionLabel class="mb-2">
|
|
1236
1263
|
{{ t('observability.search.queriesTitle') }}
|
|
1237
|
-
</
|
|
1264
|
+
</SectionLabel>
|
|
1238
1265
|
<ul class="space-y-2">
|
|
1239
1266
|
<li
|
|
1240
1267
|
v-for="q in searchQueries"
|
|
@@ -1247,12 +1274,10 @@ function exportJson() {
|
|
|
1247
1274
|
:style="{ color: agentMeta(q.agentKind).color }"
|
|
1248
1275
|
:title="agentMeta(q.agentKind).label"
|
|
1249
1276
|
/>
|
|
1250
|
-
<span class="min-w-0 flex-1 truncate text-
|
|
1277
|
+
<span class="min-w-0 flex-1 truncate text-sm text-default" :title="q.query">
|
|
1251
1278
|
{{ q.query }}
|
|
1252
1279
|
</span>
|
|
1253
|
-
<div
|
|
1254
|
-
class="flex shrink-0 items-center gap-2.5 text-[11px] tabular-nums text-muted"
|
|
1255
|
-
>
|
|
1280
|
+
<div class="flex shrink-0 items-center gap-2.5 text-2xs tabular-nums text-muted">
|
|
1256
1281
|
<span v-if="q.provider" class="hidden sm:inline">{{
|
|
1257
1282
|
providerLabel(q.provider)
|
|
1258
1283
|
}}</span>
|