@agent-native/core 0.187.0 → 0.187.1-nightly-20260925003003
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +4 -3
- package/corpus/templates/analytics/changelog/2026-09-24-analytics-sidebar-footer-aligns-consistently.md +6 -0
- package/corpus/templates/analytics/changelog/2026-09-24-dashboard-emails-match-stacked-area-totals.md +6 -0
- package/corpus/templates/analytics/server/lib/report-chart-svg.ts +47 -20
- package/corpus/templates/calendar/app/components/calendar/AttendeeAutocomplete.tsx +1 -1
- package/corpus/templates/calendar/changelog/2026-09-24-guest-inputs-wrap-beneath-existing-guests-so-the-active-inpu.md +6 -0
- package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +8 -3
- package/corpus/templates/clips/app/lib/recording-link.ts +21 -0
- package/corpus/templates/clips/app/routes/record.tsx +27 -8
- package/corpus/templates/clips/changelog/2026-09-24-the-camera-bubble-stays-visible-while-you-reposition-it-befo.md +6 -0
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +7 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +63 -55
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +251 -74
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +66 -56
- package/corpus/templates/design/app/components/design/EditPanel.tsx +19 -0
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +59 -9
- package/corpus/templates/design/app/components/design/edit-panel/interaction-state-helpers.ts +4 -0
- package/corpus/templates/design/app/components/design/edit-panel/layout-properties.tsx +119 -0
- package/corpus/templates/design/app/components/design/edit-panel/stroke-properties.tsx +48 -51
- package/corpus/templates/design/app/components/design/edit-panel/style-change-types.ts +1 -0
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +298 -187
- package/corpus/templates/design/app/components/design/inspector/GradientEditor.tsx +2 -2
- package/corpus/templates/design/app/components/design/inspector/index.ts +4 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +4 -2
- package/corpus/templates/design/app/i18n/en-US.ts +6 -0
- package/corpus/templates/design/app/pages/Present.tsx +101 -87
- package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +75 -14
- package/corpus/templates/design/app/pages/design-editor/commands/README.md +1 -0
- package/corpus/templates/design/app/pages/design-editor/commands/commit-relative-style-delta-to-selected-layers.ts +69 -56
- package/corpus/templates/design/app/pages/design-editor/commands/mode-change.ts +16 -0
- package/corpus/templates/design/app/pages/design-editor/commands/scale-selection.ts +17 -2
- package/corpus/templates/design/app/pages/design-editor/commands/styles-change.ts +23 -30
- package/corpus/templates/design/app/pages/design-editor/commands/swap-fill-stroke.ts +105 -0
- package/corpus/templates/design/app/pages/design-editor/pending-edits.ts +21 -0
- package/corpus/templates/design/app/pages/present-review-state.ts +7 -1
- package/corpus/templates/design/changelog/2026-09-24-a-vector-s-stroke-row-shows-position-beside-weight-instead-o.md +6 -0
- package/corpus/templates/design/changelog/2026-09-24-css-margins-can-be-adjusted-on-the-canvas-and-in-the-layout-.md +6 -0
- package/corpus/templates/design/changelog/2026-09-24-design-reviews-show-the-real-canvas-beside-its-conversation.md +6 -0
- package/corpus/templates/design/changelog/2026-09-24-double-clicking-text-or-a-vector-on-the-board-starts-editing.md +6 -0
- package/corpus/templates/design/changelog/2026-09-24-interact-opens-a-focused-responsive-preview-without-reloadin.md +6 -0
- package/corpus/templates/design/changelog/2026-09-24-keep-gradient-values-visible-and-limit-canvas-paints-to-supp.md +6 -0
- package/corpus/templates/design/changelog/2026-09-24-open-pen-paths-no-longer-paint-a-filled-triangle-after-shift.md +6 -0
- package/corpus/templates/design/changelog/2026-09-24-re-clicking-the-active-responsive-preview-returns-to-the-can.md +6 -0
- package/corpus/templates/design/changelog/2026-09-24-resized-vectors-can-be-point-edited-and-the-k-scale-tool-sho.md +6 -0
- package/corpus/templates/design/changelog/2026-09-24-while-editing-text-click-to-place-the-caret-and-double-click.md +6 -0
- package/corpus/templates/design/e2e/helpers.ts +19 -2
- package/corpus/templates/mail/app/components/email/ComposeModal.tsx +1 -1
- package/corpus/templates/mail/changelog/2026-09-24-gmail-push-ack.md +6 -0
- package/corpus/templates/mail/changelog/2026-09-24-the-composer-keeps-its-taller-layout-in-a-narrower-window.md +6 -0
- package/corpus/templates/mail/server/db/schema.ts +26 -1
- package/corpus/templates/mail/server/lib/inbox-store.ts +68 -23
- package/corpus/templates/mail/server/lib/inbox-sync.ts +43 -17
- package/corpus/templates/mail/server/plugins/db.ts +19 -0
- package/corpus/templates/mail/server/routes/api/gmail/push.post.ts +4 -15
- package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +45 -30
- package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +18 -2
- package/corpus/templates/slides/actions/export-html.ts +28 -17
- package/corpus/templates/slides/app/hooks/use-deck-design-system.ts +27 -15
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +1 -1
- package/corpus/templates/slides/changelog/2026-09-23-decks-with-no-design-system-now-follow-a-theme-chosen-for-th.md +6 -0
- package/corpus/templates/slides/shared/slide-background.ts +3 -1
- package/dist/agent/engine/builder-engine.js +11 -0
- package/dist/agent/engine/types.d.ts +1 -0
- package/dist/agent/production-agent.d.ts +2 -0
- package/dist/agent/production-agent.js +32 -4
- package/dist/agent/run-loop-with-resume.js +6 -0
- package/dist/cli/index.js +4 -4
- package/dist/cli/process.d.ts +10 -1
- package/dist/cli/process.js +66 -0
- package/dist/cli/workspace-dev.js +2 -0
- package/dist/client/agent-chat.js +13 -14
- package/dist/client/error-format.js +4 -4
- package/dist/client/observability/ObservabilityDashboard.js +95 -65
- package/dist/client/observability/OutputPreview.d.ts +2 -1
- package/dist/client/observability/OutputPreview.js +64 -7
- package/dist/client/observability/useObservability.d.ts +2 -1
- package/dist/client/observability/useObservability.js +5 -1
- package/dist/client/settings/UsageSection.js +105 -17
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.d.ts +44 -0
- package/dist/db/client.js +62 -3
- package/dist/db/create-get-db.js +23 -1
- package/dist/db/embedded-runtime.d.ts +21 -0
- package/dist/db/embedded-runtime.js +27 -0
- package/dist/db/migrations.js +2 -0
- package/dist/db/server-runtime.d.ts +22 -0
- package/dist/db/server-runtime.js +26 -0
- package/dist/deploy/build.d.ts +29 -0
- package/dist/deploy/build.js +204 -121
- package/dist/feature-flags/index.d.ts +1 -1
- package/dist/feature-flags/index.js +1 -1
- package/dist/feature-flags/registry.d.ts +1 -0
- package/dist/feature-flags/registry.js +5 -0
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/integrations/webhook-handler.js +4 -1
- package/dist/jobs/background-automation-runner.js +6 -1
- package/dist/localization/core-messages/ar-SA.js +9 -1
- package/dist/localization/core-messages/de-DE.js +9 -1
- package/dist/localization/core-messages/en-US.d.ts +9 -1
- package/dist/localization/core-messages/en-US.js +9 -1
- package/dist/localization/core-messages/es-ES.js +9 -1
- package/dist/localization/core-messages/fr-FR.js +9 -1
- package/dist/localization/core-messages/hi-IN.js +9 -1
- package/dist/localization/core-messages/ja-JP.js +9 -1
- package/dist/localization/core-messages/ko-KR.js +9 -1
- package/dist/localization/core-messages/pt-BR.js +9 -1
- package/dist/localization/core-messages/supplemental/ar-SA.js +1 -0
- package/dist/localization/core-messages/supplemental/de-DE.js +1 -0
- package/dist/localization/core-messages/supplemental/en-US.js +1 -0
- package/dist/localization/core-messages/supplemental/es-ES.js +1 -0
- package/dist/localization/core-messages/supplemental/fr-FR.js +1 -0
- package/dist/localization/core-messages/supplemental/hi-IN.js +1 -0
- package/dist/localization/core-messages/supplemental/ja-JP.js +1 -0
- package/dist/localization/core-messages/supplemental/ko-KR.js +1 -0
- package/dist/localization/core-messages/supplemental/pt-BR.js +1 -0
- package/dist/localization/core-messages/supplemental/zh-CN.js +1 -0
- package/dist/localization/core-messages/supplemental/zh-TW.js +1 -0
- package/dist/localization/core-messages/zh-CN.js +9 -1
- package/dist/localization/core-messages/zh-TW.js +9 -1
- package/dist/localization/core-messages.d.ts +9 -1
- package/dist/localization/mcp-settings-messages.d.ts +1 -0
- package/dist/mcp/connect-route.js +45 -8
- package/dist/mcp/connect-store.d.ts +7 -5
- package/dist/mcp/connect-store.js +30 -39
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/actions/get-observability-review-detail.d.ts +7 -0
- package/dist/observability/actions/get-observability-review-detail.js +25 -0
- package/dist/observability/reviews.d.ts +9 -1
- package/dist/observability/reviews.js +20 -0
- package/dist/observability/routes.d.ts +3 -3
- package/dist/observability/types.d.ts +8 -0
- package/dist/org/handlers.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
- package/dist/provider-api/actions/provider-api.d.ts +9 -9
- package/dist/scripts/db/query.js +6 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
- package/dist/server/agent-teams.js +4 -1
- package/dist/server/auth.js +60 -20
- package/dist/server/better-auth-instance.js +7 -1
- package/dist/server/core-routes-plugin.d.ts +1 -1
- package/dist/server/core-routes-plugin.js +2 -0
- package/dist/server/embedded.js +6 -0
- package/dist/server/framework-request-handler.js +6 -0
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/usage/actions/get-usage-metrics.js +4 -1
- package/dist/usage/metrics-store.d.ts +19 -0
- package/dist/usage/metrics-store.js +106 -14
- package/dist/usage/store.d.ts +7 -2
- package/dist/usage/store.js +25 -4
- package/dist/vite/action-types-plugin.js +4 -0
- package/dist/vite/client.d.ts +6 -1
- package/dist/vite/client.js +40 -1
- package/package.json +4 -3
|
@@ -3735,6 +3735,7 @@ export async function runAgentLoop(opts) {
|
|
|
3735
3735
|
outputTokens: 0,
|
|
3736
3736
|
cacheReadTokens: 0,
|
|
3737
3737
|
cacheWriteTokens: 0,
|
|
3738
|
+
engineName: opts.engine.name,
|
|
3738
3739
|
model,
|
|
3739
3740
|
};
|
|
3740
3741
|
const maxIterations = normalizeMaxIterations(opts.maxIterations, getDefaultMaxIterations());
|
|
@@ -4313,12 +4314,21 @@ export async function runAgentLoop(opts) {
|
|
|
4313
4314
|
outputTokens: event.outputTokens,
|
|
4314
4315
|
cacheReadTokens: event.cacheReadTokens ?? 0,
|
|
4315
4316
|
cacheWriteTokens: event.cacheWriteTokens ?? 0,
|
|
4317
|
+
engineName: opts.engine.name,
|
|
4316
4318
|
model,
|
|
4319
|
+
...(event.builderCreditsUsed !== undefined
|
|
4320
|
+
? { builderCreditsUsed: event.builderCreditsUsed }
|
|
4321
|
+
: {}),
|
|
4317
4322
|
};
|
|
4318
4323
|
usage.inputTokens += eventUsage.inputTokens;
|
|
4319
4324
|
usage.outputTokens += eventUsage.outputTokens;
|
|
4320
4325
|
usage.cacheReadTokens += eventUsage.cacheReadTokens;
|
|
4321
4326
|
usage.cacheWriteTokens += eventUsage.cacheWriteTokens;
|
|
4327
|
+
if (eventUsage.builderCreditsUsed !== undefined) {
|
|
4328
|
+
usage.builderCreditsUsed =
|
|
4329
|
+
(usage.builderCreditsUsed ?? 0) +
|
|
4330
|
+
eventUsage.builderCreditsUsed;
|
|
4331
|
+
}
|
|
4322
4332
|
usage.usageReported = true;
|
|
4323
4333
|
opts.onUsage?.(eventUsage);
|
|
4324
4334
|
}
|
|
@@ -6188,6 +6198,7 @@ export async function runAgentLoopWithMainChatInternalContinuations(opts) {
|
|
|
6188
6198
|
outputTokens: 0,
|
|
6189
6199
|
cacheReadTokens: 0,
|
|
6190
6200
|
cacheWriteTokens: 0,
|
|
6201
|
+
engineName: opts.engine.name,
|
|
6191
6202
|
model: opts.model,
|
|
6192
6203
|
};
|
|
6193
6204
|
const addUsage = (next) => {
|
|
@@ -6195,6 +6206,11 @@ export async function runAgentLoopWithMainChatInternalContinuations(opts) {
|
|
|
6195
6206
|
usage.outputTokens += next.outputTokens;
|
|
6196
6207
|
usage.cacheReadTokens += next.cacheReadTokens;
|
|
6197
6208
|
usage.cacheWriteTokens += next.cacheWriteTokens;
|
|
6209
|
+
if (next.builderCreditsUsed !== undefined) {
|
|
6210
|
+
usage.builderCreditsUsed =
|
|
6211
|
+
(usage.builderCreditsUsed ?? 0) + next.builderCreditsUsed;
|
|
6212
|
+
}
|
|
6213
|
+
usage.engineName = next.engineName ?? usage.engineName;
|
|
6198
6214
|
usage.model = next.model;
|
|
6199
6215
|
if (typeof next.llmCalls === "number") {
|
|
6200
6216
|
usage.llmCalls = (usage.llmCalls ?? 0) + next.llmCalls;
|
|
@@ -7541,7 +7557,7 @@ export function createProductionAgentHandler(options) {
|
|
|
7541
7557
|
availableRequestActions = filterActionsByAllowedNames(availableRequestActions, filterHostedHarnessToolNames(Object.keys(availableRequestActions)));
|
|
7542
7558
|
}
|
|
7543
7559
|
let surfacedRequestActions = availableRequestActions;
|
|
7544
|
-
let
|
|
7560
|
+
let shouldFilterInitialRequestTools = !options.resolveActionSurface;
|
|
7545
7561
|
if (options.resolveActionSurface) {
|
|
7546
7562
|
const persistedSurface = isBackgroundWorker
|
|
7547
7563
|
? readPersistedActionSurface(body, "__resolvedActionSurface")
|
|
@@ -7573,13 +7589,14 @@ export function createProductionAgentHandler(options) {
|
|
|
7573
7589
|
availableActionNames: Object.keys(availableRequestActions),
|
|
7574
7590
|
});
|
|
7575
7591
|
const normalizedSurface = normalizeAgentActionSurfaceResolution(surface);
|
|
7592
|
+
shouldFilterInitialRequestTools =
|
|
7593
|
+
normalizedSurface.mode === "default" || !normalizedSurface.actionScope;
|
|
7576
7594
|
if (requestedActionScope &&
|
|
7577
7595
|
(normalizedSurface.mode === "default" || !normalizedSurface.actionScope)) {
|
|
7578
7596
|
throw new Error("resolveActionSurface must return actionScope for a scoped request");
|
|
7579
7597
|
}
|
|
7580
7598
|
const runCtx = ensureRequestRunContext();
|
|
7581
7599
|
if (normalizedSurface.mode === "default") {
|
|
7582
|
-
useDefaultRequestActionSurface = true;
|
|
7583
7600
|
if (runCtx) {
|
|
7584
7601
|
delete runCtx.allowedActionNames;
|
|
7585
7602
|
delete runCtx.actionScope;
|
|
@@ -8113,7 +8130,7 @@ export function createProductionAgentHandler(options) {
|
|
|
8113
8130
|
? createPlanModeActionRegistry(surfacedRequestActions)
|
|
8114
8131
|
: surfacedRequestActions;
|
|
8115
8132
|
const availableRequestTools = getEngineTools(requestActions);
|
|
8116
|
-
const initialRequestTools =
|
|
8133
|
+
const initialRequestTools = shouldFilterInitialRequestTools
|
|
8117
8134
|
? filterInitialEngineTools(availableRequestTools, options.initialToolNames)
|
|
8118
8135
|
: availableRequestTools;
|
|
8119
8136
|
const curatedRequestTools = requestMode === "plan"
|
|
@@ -9074,6 +9091,8 @@ export function createProductionAgentHandler(options) {
|
|
|
9074
9091
|
outputTokens: subUsage.outputTokens,
|
|
9075
9092
|
cacheReadTokens: subUsage.cacheReadTokens,
|
|
9076
9093
|
cacheWriteTokens: subUsage.cacheWriteTokens,
|
|
9094
|
+
builderCreditsUsed: subUsage.builderCreditsUsed,
|
|
9095
|
+
engineName: engine.name,
|
|
9077
9096
|
model: subUsage.model,
|
|
9078
9097
|
label: `custom-agent:${ref.name}`,
|
|
9079
9098
|
runId,
|
|
@@ -9178,6 +9197,7 @@ export function createProductionAgentHandler(options) {
|
|
|
9178
9197
|
outputTokens: 0,
|
|
9179
9198
|
cacheReadTokens: 0,
|
|
9180
9199
|
cacheWriteTokens: 0,
|
|
9200
|
+
engineName: engine.name,
|
|
9181
9201
|
model: effectiveModel,
|
|
9182
9202
|
};
|
|
9183
9203
|
const agentLoopOpts = {
|
|
@@ -9197,6 +9217,11 @@ export function createProductionAgentHandler(options) {
|
|
|
9197
9217
|
turnUsage.outputTokens += usage.outputTokens;
|
|
9198
9218
|
turnUsage.cacheReadTokens += usage.cacheReadTokens;
|
|
9199
9219
|
turnUsage.cacheWriteTokens += usage.cacheWriteTokens;
|
|
9220
|
+
if (usage.builderCreditsUsed !== undefined) {
|
|
9221
|
+
turnUsage.builderCreditsUsed =
|
|
9222
|
+
(turnUsage.builderCreditsUsed ?? 0) + usage.builderCreditsUsed;
|
|
9223
|
+
}
|
|
9224
|
+
turnUsage.engineName = usage.engineName ?? turnUsage.engineName;
|
|
9200
9225
|
turnUsage.model = usage.model;
|
|
9201
9226
|
},
|
|
9202
9227
|
ownerEmail,
|
|
@@ -9367,7 +9392,8 @@ export function createProductionAgentHandler(options) {
|
|
|
9367
9392
|
(turnUsage.inputTokens > 0 ||
|
|
9368
9393
|
turnUsage.outputTokens > 0 ||
|
|
9369
9394
|
turnUsage.cacheReadTokens > 0 ||
|
|
9370
|
-
turnUsage.cacheWriteTokens > 0
|
|
9395
|
+
turnUsage.cacheWriteTokens > 0 ||
|
|
9396
|
+
turnUsage.builderCreditsUsed != null)) {
|
|
9371
9397
|
const { recordUsage } = await import("../usage/store.js");
|
|
9372
9398
|
await recordUsage({
|
|
9373
9399
|
ownerEmail: resolvedOwnerEmail,
|
|
@@ -9375,6 +9401,8 @@ export function createProductionAgentHandler(options) {
|
|
|
9375
9401
|
outputTokens: turnUsage.outputTokens,
|
|
9376
9402
|
cacheReadTokens: turnUsage.cacheReadTokens,
|
|
9377
9403
|
cacheWriteTokens: turnUsage.cacheWriteTokens,
|
|
9404
|
+
builderCreditsUsed: turnUsage.builderCreditsUsed,
|
|
9405
|
+
engineName: engine.name,
|
|
9378
9406
|
model: turnUsage.model,
|
|
9379
9407
|
label: turnUsageLabel || "chat",
|
|
9380
9408
|
// token_usage has had run_id/thread_id/task_id since it was
|
|
@@ -373,6 +373,7 @@ control) {
|
|
|
373
373
|
outputTokens: 0,
|
|
374
374
|
cacheReadTokens: 0,
|
|
375
375
|
cacheWriteTokens: 0,
|
|
376
|
+
engineName: opts.engine.name,
|
|
376
377
|
model: opts.model,
|
|
377
378
|
};
|
|
378
379
|
const addUsage = (next) => {
|
|
@@ -380,6 +381,11 @@ control) {
|
|
|
380
381
|
usage.outputTokens += next.outputTokens;
|
|
381
382
|
usage.cacheReadTokens += next.cacheReadTokens;
|
|
382
383
|
usage.cacheWriteTokens += next.cacheWriteTokens;
|
|
384
|
+
if (next.builderCreditsUsed !== undefined) {
|
|
385
|
+
usage.builderCreditsUsed =
|
|
386
|
+
(usage.builderCreditsUsed ?? 0) + next.builderCreditsUsed;
|
|
387
|
+
}
|
|
388
|
+
usage.engineName = next.engineName ?? usage.engineName;
|
|
383
389
|
usage.model = next.model;
|
|
384
390
|
// Without these, a retry that never got a usage report merges its zeros
|
|
385
391
|
// over an earlier attempt's real numbers, and telemetry reports an
|
package/dist/cli/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "url";
|
|
|
7
7
|
import * as Sentry from "@sentry/node";
|
|
8
8
|
import { clearAgentNativeNitroPresetMarker, resolveAgentNativeNitroPreset, } from "../deploy/nitro-preset.js";
|
|
9
9
|
import { resolveDeployPostBuildInvocation } from "./deploy-build.js";
|
|
10
|
-
import { cliSpawnOptions } from "./process.js";
|
|
10
|
+
import { cliSpawnOptions, runDevServer } from "./process.js";
|
|
11
11
|
import { findBinUpwards, findReactRouterInvocation, } from "./react-router-command.js";
|
|
12
12
|
import { shouldTrackCliRun } from "./telemetry-routing.js";
|
|
13
13
|
import { createCliTelemetry } from "./telemetry.js";
|
|
@@ -529,14 +529,14 @@ switch (command) {
|
|
|
529
529
|
const vite = findViteBin();
|
|
530
530
|
const { inspectFlag, rest } = extractNodeInspectFlag(args);
|
|
531
531
|
if (!inspectFlag) {
|
|
532
|
-
|
|
532
|
+
runDevServer(vite, rest);
|
|
533
533
|
break;
|
|
534
534
|
}
|
|
535
535
|
const viteJsEntry = findViteJsEntry();
|
|
536
536
|
if (!viteJsEntry) {
|
|
537
537
|
console.warn("[agent-native] Could not resolve Vite's JS entry; starting dev " +
|
|
538
538
|
"server without the debugger.");
|
|
539
|
-
|
|
539
|
+
runDevServer(vite, rest);
|
|
540
540
|
break;
|
|
541
541
|
}
|
|
542
542
|
// Attach inspect flag to server process (not Vite or Nitro process)
|
|
@@ -551,7 +551,7 @@ switch (command) {
|
|
|
551
551
|
NITRO_DEV_RUNNER: process.env.NITRO_DEV_RUNNER ?? "node-process",
|
|
552
552
|
};
|
|
553
553
|
console.log(`[agent-native] API server debugger listening on ${target}`);
|
|
554
|
-
|
|
554
|
+
runDevServer(process.execPath, ["--import", preload, viteJsEntry, ...rest], {
|
|
555
555
|
env,
|
|
556
556
|
shell: false,
|
|
557
557
|
});
|
package/dist/cli/process.d.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { spawn, type SpawnOptions } from "node:child_process";
|
|
2
|
+
export declare const DEV_SERVER_SUPERVISOR_ENV = "AGENT_NATIVE_DEV_SUPERVISOR";
|
|
3
|
+
export declare const DEV_SERVER_RECOVERY_EXIT_CODE = 86;
|
|
2
4
|
/**
|
|
3
5
|
* Keep Windows command-name launches compatible with `.cmd` shims while
|
|
4
6
|
* allowing callers that already have a real executable path to opt out of the
|
|
5
7
|
* shell. The latter is important for paths such as `C:\\Program Files\\nodejs\\node.exe`.
|
|
6
8
|
*/
|
|
7
9
|
export declare function cliSpawnOptions(options?: Pick<SpawnOptions, "env" | "shell" | "stdio">, platform?: NodeJS.Platform): Pick<SpawnOptions, "env" | "shell" | "stdio">;
|
|
10
|
+
export declare function runDevServer(command: string, args: string[], options?: {
|
|
11
|
+
env?: NodeJS.ProcessEnv;
|
|
12
|
+
shell?: boolean;
|
|
13
|
+
stdio?: "inherit" | "pipe";
|
|
14
|
+
spawnProcess?: typeof spawn;
|
|
15
|
+
exitProcess?: (code: number) => void;
|
|
16
|
+
}): void;
|
package/dist/cli/process.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { spawn, } from "node:child_process";
|
|
2
|
+
import { constants as osConstants } from "node:os";
|
|
3
|
+
export const DEV_SERVER_SUPERVISOR_ENV = "AGENT_NATIVE_DEV_SUPERVISOR";
|
|
4
|
+
export const DEV_SERVER_RECOVERY_EXIT_CODE = 86;
|
|
1
5
|
/**
|
|
2
6
|
* Keep Windows command-name launches compatible with `.cmd` shims while
|
|
3
7
|
* allowing callers that already have a real executable path to opt out of the
|
|
@@ -10,3 +14,65 @@ export function cliSpawnOptions(options = {}, platform = process.platform) {
|
|
|
10
14
|
env: options.env ?? process.env,
|
|
11
15
|
};
|
|
12
16
|
}
|
|
17
|
+
export function runDevServer(command, args, options = {}) {
|
|
18
|
+
const env = {
|
|
19
|
+
...(options.env ?? process.env),
|
|
20
|
+
[DEV_SERVER_SUPERVISOR_ENV]: "1",
|
|
21
|
+
};
|
|
22
|
+
const spawnProcess = options.spawnProcess ?? spawn;
|
|
23
|
+
const exitProcess = options.exitProcess ?? ((code) => process.exit(code));
|
|
24
|
+
const signalHandlers = new Map();
|
|
25
|
+
let child;
|
|
26
|
+
let restartTimer;
|
|
27
|
+
let forceExitTimer;
|
|
28
|
+
let shuttingDown = false;
|
|
29
|
+
const cleanup = () => {
|
|
30
|
+
for (const [signal, handler] of signalHandlers) {
|
|
31
|
+
process.removeListener(signal, handler);
|
|
32
|
+
}
|
|
33
|
+
signalHandlers.clear();
|
|
34
|
+
if (restartTimer)
|
|
35
|
+
clearTimeout(restartTimer);
|
|
36
|
+
if (forceExitTimer)
|
|
37
|
+
clearTimeout(forceExitTimer);
|
|
38
|
+
};
|
|
39
|
+
const start = () => {
|
|
40
|
+
restartTimer = undefined;
|
|
41
|
+
child = spawnProcess(command, args, cliSpawnOptions({
|
|
42
|
+
env,
|
|
43
|
+
shell: options.shell,
|
|
44
|
+
stdio: options.stdio,
|
|
45
|
+
}));
|
|
46
|
+
child.once("exit", (code, signal) => {
|
|
47
|
+
if (code === DEV_SERVER_RECOVERY_EXIT_CODE && !shuttingDown) {
|
|
48
|
+
restartTimer = setTimeout(start, 250);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
cleanup();
|
|
52
|
+
exitProcess(code ?? (signal ? 128 + osConstants.signals[signal] : 0));
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
|
|
56
|
+
const handler = () => {
|
|
57
|
+
if (shuttingDown)
|
|
58
|
+
return;
|
|
59
|
+
shuttingDown = true;
|
|
60
|
+
if (restartTimer) {
|
|
61
|
+
clearTimeout(restartTimer);
|
|
62
|
+
restartTimer = undefined;
|
|
63
|
+
cleanup();
|
|
64
|
+
exitProcess(128 + osConstants.signals[signal]);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
child?.kill(signal);
|
|
68
|
+
forceExitTimer = setTimeout(() => {
|
|
69
|
+
child?.kill("SIGKILL");
|
|
70
|
+
exitProcess(1);
|
|
71
|
+
}, 5_000);
|
|
72
|
+
forceExitTimer.unref();
|
|
73
|
+
};
|
|
74
|
+
signalHandlers.set(signal, handler);
|
|
75
|
+
process.on(signal, handler);
|
|
76
|
+
}
|
|
77
|
+
start();
|
|
78
|
+
}
|
|
@@ -10,6 +10,7 @@ import { extractOAuthStateAppId } from "../shared/oauth-state.js";
|
|
|
10
10
|
import { DEFAULT_WORKSPACE_APP_AUDIENCE, normalizeWorkspaceAppHomePath, workspaceAppAudienceFromPackageJson, workspaceAppRouteAccessFromPackageJson, } from "../shared/workspace-app-audience.js";
|
|
11
11
|
import { inferWorkspaceAppRootHomePath, readConfiguredWorkspaceAppHomePath, } from "../workspace-app-config.js";
|
|
12
12
|
import { attachGatewaySocketErrorSink, normalizeOrigin, rewriteRedirectLocation, escapeHtml, } from "./gateway-helpers.js";
|
|
13
|
+
import { DEV_SERVER_SUPERVISOR_ENV } from "./process.js";
|
|
13
14
|
const DEFAULT_GATEWAY_HOST = "127.0.0.1";
|
|
14
15
|
const DEFAULT_GATEWAY_PORT = 8080;
|
|
15
16
|
const DEFAULT_APP_PORT_START = 8100;
|
|
@@ -692,6 +693,7 @@ export async function runWorkspaceDev(options = {}) {
|
|
|
692
693
|
env: devWatcherEnv({
|
|
693
694
|
...env,
|
|
694
695
|
APP_NAME: app.id,
|
|
696
|
+
[DEV_SERVER_SUPERVISOR_ENV]: "1",
|
|
695
697
|
AGENT_NATIVE_WORKSPACE: "1",
|
|
696
698
|
AGENT_NATIVE_WORKSPACE_APP_ID: app.id,
|
|
697
699
|
AGENT_NATIVE_WORKSPACE_APPS_JSON: workspaceAppsJson(),
|
|
@@ -760,8 +760,18 @@ export function sendToAgentChat(opts) {
|
|
|
760
760
|
const actionScope = opts.actionScope === undefined
|
|
761
761
|
? undefined
|
|
762
762
|
: normalizeAgentActionScope(opts.actionScope);
|
|
763
|
-
const
|
|
764
|
-
const
|
|
763
|
+
const mcpBridgeEnabled = isMcpAppChatBridgeEnabled();
|
|
764
|
+
const hasMcpAppLocalPayload = mcpBridgeEnabled &&
|
|
765
|
+
Boolean(opts.attachments?.length ||
|
|
766
|
+
opts.images?.length ||
|
|
767
|
+
opts.referenceImagePaths?.length ||
|
|
768
|
+
opts.uploadedReferenceImages?.length ||
|
|
769
|
+
opts.usageLabel ||
|
|
770
|
+
actionScope);
|
|
771
|
+
const isCodeRequest = routesToCodeFrame(opts) && !hasMcpAppLocalPayload;
|
|
772
|
+
const localChatTarget = opts.chatTarget === "local" ||
|
|
773
|
+
keepsApprovalInAppChat(opts) ||
|
|
774
|
+
hasMcpAppLocalPayload;
|
|
765
775
|
const requestMode = normalizeAgentChatRequestMode(opts.requestMode ?? opts.mode) ??
|
|
766
776
|
readStoredAgentChatRequestMode();
|
|
767
777
|
if (opts.submit !== false && opts.message.trim()) {
|
|
@@ -793,18 +803,7 @@ export function sendToAgentChat(opts) {
|
|
|
793
803
|
...(requestMode ? { mode: requestMode, requestMode } : {}),
|
|
794
804
|
},
|
|
795
805
|
};
|
|
796
|
-
if (opts.submit !== false &&
|
|
797
|
-
!localChatTarget &&
|
|
798
|
-
isMcpAppChatBridgeEnabled()) {
|
|
799
|
-
// MCP host follow-up APIs carry neither attachment descriptors nor a usage
|
|
800
|
-
// label. Use the normal wrapper transport when either needs to reach the
|
|
801
|
-
// chat thread — a label silently downgraded to `chat` is exactly the run
|
|
802
|
-
// the caller named it to be able to find. (Approval continuations never
|
|
803
|
-
// get here: they stay in the app's own chat, see keepsApprovalInAppChat.)
|
|
804
|
-
if (opts.attachments?.length || opts.usageLabel || actionScope) {
|
|
805
|
-
window.parent.postMessage(payload, getFramePostMessageTargetOrigin() || "*");
|
|
806
|
-
return tabId;
|
|
807
|
-
}
|
|
806
|
+
if (opts.submit !== false && !localChatTarget && mcpBridgeEnabled) {
|
|
808
807
|
const directHostMessage = sendMcpAppHostMessage({
|
|
809
808
|
message: opts.message,
|
|
810
809
|
context: opts.context,
|
|
@@ -21,7 +21,7 @@ export const BUILDER_SPACE_SETTINGS_URL = "https://builder.io/account/space?utm_
|
|
|
21
21
|
export const NEW_CHAT_ACTION_HREF = "agent-native:new-chat";
|
|
22
22
|
const OPEN_BUILDER_SPACE_SETTINGS_LABEL = "Open Builder space settings";
|
|
23
23
|
const START_NEW_CHAT_LABEL = "Start new chat";
|
|
24
|
-
const
|
|
24
|
+
const ADD_CREDITS_IN_BUILDER_LABEL = "Add credits in Builder";
|
|
25
25
|
const BUILDER_AUTHENTICATION_ERROR = "Builder rejected the connected credentials. Reconnect Builder.io (free tier available) in Settings, then retry.";
|
|
26
26
|
/**
|
|
27
27
|
* A 401 says the credential this request carried was refused. It does NOT say
|
|
@@ -100,7 +100,7 @@ export function formatChatErrorText(errorMessage, upgradeUrl, errorCode) {
|
|
|
100
100
|
const normalized = normalizeChatError(errorMessage, errorCode);
|
|
101
101
|
if (normalized.message === CREDITS_LIMIT_REACHED_MESSAGE) {
|
|
102
102
|
return upgradeUrl && isSafeUpgradeUrl(upgradeUrl)
|
|
103
|
-
? `${normalized.message}\n\n[${
|
|
103
|
+
? `${normalized.message}\n\n[${ADD_CREDITS_IN_BUILDER_LABEL}](${upgradeUrl})`
|
|
104
104
|
: normalized.message;
|
|
105
105
|
}
|
|
106
106
|
if (!isServerChosenVisitorMessage(normalized.message) &&
|
|
@@ -118,7 +118,7 @@ export function formatChatErrorText(errorMessage, upgradeUrl, errorCode) {
|
|
|
118
118
|
if (!upgradeUrl || !isSafeUpgradeUrl(upgradeUrl)) {
|
|
119
119
|
return `Error: ${normalized.message}`;
|
|
120
120
|
}
|
|
121
|
-
return `Error: ${normalized.message}\n\n[${
|
|
121
|
+
return `Error: ${normalized.message}\n\n[${ADD_CREDITS_IN_BUILDER_LABEL}](${upgradeUrl})`;
|
|
122
122
|
}
|
|
123
123
|
/**
|
|
124
124
|
* True when the server already decided what this reader may be told.
|
|
@@ -229,7 +229,7 @@ const KNOWN_CHAT_ERROR_ACTION_KEYS = new Map([
|
|
|
229
229
|
"agentChat.errorMessages.openBuilderSpaceSettings",
|
|
230
230
|
],
|
|
231
231
|
["Start new chat", "agentChat.errorMessages.startNewChat"],
|
|
232
|
-
["
|
|
232
|
+
["Add credits in Builder", "agentChat.errorMessages.addCreditsInBuilder"],
|
|
233
233
|
]);
|
|
234
234
|
/** Localize only Core's own normalized error copy; preserve provider details. */
|
|
235
235
|
export function localizeKnownChatErrorText(text, t) {
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Skeleton } from "@agent-native/toolkit/ui/skeleton";
|
|
3
|
+
import { IconActivity, IconMessages, IconThumbUp, IconThumbDown, IconClock, IconCoin, IconTool, IconMoodSmile, IconChartBar, IconAB2, IconMessageReport, IconMessageCircle, IconPencil, IconChevronRight, IconArrowsMaximize, IconExternalLink, IconArrowLeft, IconLoader2, IconAlertTriangle, } from "@tabler/icons-react";
|
|
3
4
|
import { useQueryClient } from "@tanstack/react-query";
|
|
4
5
|
import { useState } from "react";
|
|
6
|
+
import { AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_OPEN, } from "../../shared/agent-sidebar-url.js";
|
|
5
7
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "../components/ui/dialog.js";
|
|
6
8
|
import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
|
|
7
9
|
import { useT } from "../i18n.js";
|
|
8
10
|
import { cn } from "../utils.js";
|
|
9
11
|
import { OutputPreview } from "./OutputPreview.js";
|
|
10
|
-
import { useObservabilityOverview, useTraces, useTraceDetail, useFeedbackList, useFeedbackStats, useSatisfaction, useEvalStats, useExperiments, useExperimentDetail, useExperimentResults, useOutputReviews,
|
|
12
|
+
import { useObservabilityOverview, useTraces, useTraceDetail, useFeedbackList, useFeedbackStats, useSatisfaction, useEvalStats, useExperiments, useExperimentDetail, useExperimentResults, useOutputReviews, useOutputReviewDetail, useSaveInstructionUpdate, useSubmitFeedback, } from "./useObservability.js";
|
|
11
13
|
// ─── Helpers ────────────────────────────────────────────────────────────
|
|
12
14
|
function formatCost(centsX100) {
|
|
13
15
|
const cents = centsX100 / 100;
|
|
@@ -47,6 +49,14 @@ function timeAgo(ts) {
|
|
|
47
49
|
return `${Math.floor(diff / 3_600_000)}h ago`;
|
|
48
50
|
return `${Math.floor(diff / 86_400_000)}d ago`;
|
|
49
51
|
}
|
|
52
|
+
function reviewThreadHref(threadId) {
|
|
53
|
+
const isBrowser = typeof window !== "undefined";
|
|
54
|
+
const url = new URL(isBrowser ? window.location.href : "/", "http://agent-native.invalid");
|
|
55
|
+
url.searchParams.delete("threadId");
|
|
56
|
+
url.searchParams.set("thread", threadId);
|
|
57
|
+
url.searchParams.set(AGENT_SIDEBAR_QUERY_PARAM, AGENT_SIDEBAR_QUERY_VALUE_OPEN);
|
|
58
|
+
return isBrowser ? url.toString() : `${url.pathname}${url.search}${url.hash}`;
|
|
59
|
+
}
|
|
50
60
|
const RANGES = [
|
|
51
61
|
{ value: 7, label: "7d" },
|
|
52
62
|
{ value: 30, label: "30d" },
|
|
@@ -150,11 +160,12 @@ function ReviewTab({ days }) {
|
|
|
150
160
|
const instructionMutation = useSaveInstructionUpdate();
|
|
151
161
|
const queryClient = useQueryClient();
|
|
152
162
|
const [selectedRunId, setSelectedRunId] = useState(null);
|
|
163
|
+
const [previewExpanded, setPreviewExpanded] = useState(false);
|
|
153
164
|
const [openPopover, setOpenPopover] = useState(null);
|
|
154
165
|
const [feedbackNote, setFeedbackNote] = useState(null);
|
|
155
166
|
const [instructionDraft, setInstructionDraft] = useState(null);
|
|
156
167
|
const selectedReview = reviews?.find((review) => review.runId === selectedRunId);
|
|
157
|
-
const
|
|
168
|
+
const reviewDetailQuery = useOutputReviewDetail(selectedReview?.runId ?? null);
|
|
158
169
|
if (isLoading)
|
|
159
170
|
return _jsx(LoadingState, {});
|
|
160
171
|
if (!reviews || reviews.length === 0) {
|
|
@@ -238,68 +249,87 @@ function ReviewTab({ days }) {
|
|
|
238
249
|
value: "",
|
|
239
250
|
target: "agent",
|
|
240
251
|
};
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
252
|
+
const reviewMessages = reviewDetailQuery.data?.messages.length
|
|
253
|
+
? reviewDetailQuery.data.messages
|
|
254
|
+
: selectedReview
|
|
255
|
+
? [
|
|
256
|
+
...(selectedReview.ask
|
|
257
|
+
? [{ role: "user", text: selectedReview.ask }]
|
|
258
|
+
: []),
|
|
259
|
+
...(selectedReview.answer
|
|
260
|
+
? [{ role: "assistant", text: selectedReview.answer }]
|
|
261
|
+
: []),
|
|
262
|
+
]
|
|
263
|
+
: [];
|
|
264
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "divide-y divide-border", children: reviews.map((review) => {
|
|
265
|
+
const expanded = selectedRunId === review.runId;
|
|
266
|
+
const triggerId = `review-trigger-${encodeURIComponent(review.runId)}`;
|
|
267
|
+
const detailId = `review-details-${encodeURIComponent(review.runId)}`;
|
|
268
|
+
return (_jsxs("div", { className: "min-w-0", children: [_jsxs("button", { id: triggerId, type: "button", "data-review-run-id": review.runId, "aria-expanded": expanded, "aria-controls": detailId, onClick: () => {
|
|
269
|
+
setSelectedRunId((current) => current === review.runId ? null : review.runId);
|
|
270
|
+
setOpenPopover(null);
|
|
271
|
+
setPreviewExpanded(false);
|
|
272
|
+
}, className: "group flex w-full min-w-0 items-center gap-3 py-3 text-left first:pt-0 hover:bg-muted/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [_jsx("span", { className: "h-16 w-24 shrink-0 overflow-hidden rounded-md bg-muted/60 sm:h-20 sm:w-28", children: _jsx(OutputPreview, { answer: review.answer, inlineAppTitle: review.inlineAppTitle, previewLabel: t("observability.reviewPreview"), compact: true }) }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "line-clamp-2 break-words text-sm font-medium text-foreground", children: review.ask || "-" }), _jsxs("span", { className: "mt-1 block truncate text-xs text-muted-foreground", children: [review.model, " \u00B7 ", timeAgo(review.createdAt)] })] }), _jsx(IconChevronRight, { size: 16, className: cn("shrink-0 text-muted-foreground transition-transform", expanded ? "rotate-90" : "group-hover:translate-x-0.5") })] }), _jsx("div", { id: detailId, role: "region", "aria-labelledby": triggerId, "data-review-detail-for": review.runId, hidden: !expanded, children: expanded && selectedReview && (_jsxs("div", { className: "grid min-w-0 gap-0 border-t border-border lg:grid-cols-2", children: [_jsxs("section", { "data-review-preview": true, className: "min-w-0 p-3 sm:p-4", "aria-label": t("observability.reviewPreview"), children: [_jsxs("div", { className: "relative max-h-[min(38rem,65dvh)] min-h-64 overflow-auto rounded-md border border-border bg-background", children: [_jsx(OutputPreview, { answer: selectedReview.answer, inlineApp: reviewDetailQuery.data?.app ?? undefined, maxAppHeight: 420, previewLabel: t("observability.reviewPreview") }), _jsx("button", { type: "button", "data-review-lightbox-trigger": true, "aria-label": t("observability.reviewPreview"), title: t("observability.reviewPreview"), onClick: () => setPreviewExpanded(true), className: "absolute right-2 top-2 rounded-md border border-border bg-background/95 p-2 text-muted-foreground shadow-sm transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: _jsx(IconArrowsMaximize, { size: 16 }) })] }), selectedNote?.value && (_jsxs("p", { className: "mt-3 flex items-start gap-2 whitespace-pre-wrap break-words text-xs text-muted-foreground", children: [_jsx(IconMessageCircle, { size: 14, className: "mt-0.5 shrink-0" }), selectedNote.value] }))] }), _jsxs("section", { "data-review-transcript": true, className: "flex min-w-0 flex-col border-t border-border lg:border-l lg:border-t-0", children: [_jsx("div", { className: "flex max-h-[min(38rem,65dvh)] min-h-64 flex-1 flex-col gap-3 overflow-y-auto overscroll-contain p-3 sm:p-4", children: reviewDetailQuery.isLoading ? (_jsxs("div", { role: "status", "aria-label": t("agentChat.common.loading"), className: "space-y-4", children: [_jsx(Skeleton, { className: "ml-auto h-14 w-3/4 rounded-xl" }), _jsx(Skeleton, { className: "h-20 w-5/6 rounded-xl" }), _jsx(Skeleton, { className: "ml-auto h-12 w-2/3 rounded-xl" })] })) : reviewDetailQuery.isError ? (_jsx("p", { role: "alert", className: "text-sm text-muted-foreground", children: t("agentChat.common.chunkLoadFailed") })) : (reviewMessages.map((message, index) => (_jsxs("div", { className: cn("max-w-[92%] whitespace-pre-wrap break-words rounded-xl px-3 py-2 text-sm", message.role === "user"
|
|
273
|
+
? "ml-auto bg-primary/10 text-foreground"
|
|
274
|
+
: "mr-auto bg-muted text-foreground"), children: [message.role === "assistant" && (_jsx("span", { className: "mb-1 block text-[10px] font-medium text-muted-foreground", children: t("agentChat.common.agent") })), message.text] }, `${message.role}-${index}`)))) }), selectedReview.threadId && (_jsxs("a", { href: reviewThreadHref(selectedReview.threadId), target: "_blank", rel: "noreferrer", className: "flex w-fit items-center gap-1.5 px-3 pb-3 text-xs text-muted-foreground hover:text-foreground sm:px-4", children: [t("agentTask.openThread"), _jsx(IconExternalLink, { size: 14 })] }))] }), _jsxs("div", { className: "col-span-full flex shrink-0 items-center gap-1 border-t border-border px-3 py-2 sm:px-4", children: [_jsxs("div", { role: "group", "aria-label": t("observability.reviewFeedback"), className: "flex items-center gap-1", children: [_jsx("button", { type: "button", "aria-label": t("observability.thumbsUp"), "aria-pressed": selectedVote?.feedbackType === "thumbs_up", title: t("observability.thumbsUp"), disabled: feedbackMutation.isPending, onClick: () => saveFeedback(selectedReview.runId, selectedReview.threadId, "thumbs_up"), className: cn("rounded-md p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50", selectedVote?.feedbackType === "thumbs_up" &&
|
|
275
|
+
"bg-emerald-500/10 text-emerald-600 dark:text-emerald-400"), children: _jsx(IconThumbUp, { size: 16 }) }), _jsx("button", { type: "button", "aria-label": t("observability.thumbsDown"), "aria-pressed": selectedVote?.feedbackType === "thumbs_down", title: t("observability.thumbsDown"), disabled: feedbackMutation.isPending, onClick: () => saveFeedback(selectedReview.runId, selectedReview.threadId, "thumbs_down"), className: cn("rounded-md p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-50", selectedVote?.feedbackType === "thumbs_down" &&
|
|
276
|
+
"bg-rose-500/10 text-rose-600 dark:text-rose-400"), children: _jsx(IconThumbDown, { size: 16 }) })] }), _jsxs(Popover, { open: feedbackOpen, onOpenChange: (open) => {
|
|
277
|
+
if (open) {
|
|
278
|
+
setFeedbackNote((current) => current?.runId === selectedReview.runId
|
|
279
|
+
? current
|
|
280
|
+
: { runId: selectedReview.runId, value: "" });
|
|
281
|
+
}
|
|
282
|
+
setOpenPopover((current) => {
|
|
283
|
+
if (open) {
|
|
284
|
+
return {
|
|
285
|
+
runId: selectedReview.runId,
|
|
286
|
+
kind: "feedback",
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
return current?.runId === selectedReview.runId &&
|
|
290
|
+
current.kind === "feedback"
|
|
291
|
+
? null
|
|
292
|
+
: current;
|
|
293
|
+
});
|
|
294
|
+
}, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": t("observability.addFeedback"), title: t("observability.addFeedback"), className: "rounded-md p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", children: _jsx(IconMessageCircle, { size: 16 }) }) }), _jsxs(PopoverContent, { align: "start", sideOffset: 8, className: "w-[min(22rem,calc(100vw-2rem))] p-3", children: [_jsxs("label", { className: "block", children: [_jsx("span", { className: "sr-only", children: t("observability.feedbackNote") }), _jsx("textarea", { value: feedbackNote?.runId === selectedReview.runId
|
|
295
|
+
? feedbackNote.value
|
|
296
|
+
: "", onChange: (event) => setFeedbackNote({
|
|
297
|
+
runId: selectedReview.runId,
|
|
298
|
+
value: event.target.value,
|
|
299
|
+
}), rows: 3, className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus:ring-2 focus:ring-ring", placeholder: t("observability.feedbackPlaceholder") })] }), _jsx("button", { type: "button", onClick: () => saveNote(selectedReview.runId, selectedReview.threadId), disabled: !(feedbackNote?.runId === selectedReview.runId
|
|
300
|
+
? feedbackNote.value.trim()
|
|
301
|
+
: "") || feedbackMutation.isPending, className: "mt-2 rounded-md bg-primary px-2.5 py-1.5 text-xs font-medium text-primary-foreground disabled:opacity-50", children: t("observability.saveFeedback") })] })] }), _jsxs(Popover, { open: instructionOpen, onOpenChange: (open) => {
|
|
302
|
+
if (open) {
|
|
303
|
+
setInstructionDraft((current) => current?.runId === selectedReview.runId
|
|
304
|
+
? current
|
|
305
|
+
: {
|
|
306
|
+
runId: selectedReview.runId,
|
|
307
|
+
value: "",
|
|
308
|
+
target: "agent",
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
setOpenPopover((current) => {
|
|
312
|
+
if (open) {
|
|
313
|
+
return {
|
|
314
|
+
runId: selectedReview.runId,
|
|
315
|
+
kind: "instruction",
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
return current?.runId === selectedReview.runId &&
|
|
319
|
+
current.kind === "instruction"
|
|
320
|
+
? null
|
|
321
|
+
: current;
|
|
322
|
+
});
|
|
323
|
+
}, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", "aria-label": t("observability.draftInstruction"), title: t("observability.draftInstruction"), className: "rounded-md p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground", children: _jsx(IconPencil, { size: 16 }) }) }), _jsxs(PopoverContent, { align: "start", sideOffset: 8, className: "w-[min(26rem,calc(100vw-2rem))] p-3", children: [_jsx("div", { className: "mb-2 text-xs font-medium text-foreground", children: t("observability.updateInstructions") }), _jsx("p", { className: "mb-2 text-[11px] text-muted-foreground", children: t("observability.draftNotice") }), _jsxs("select", { value: activeInstructionDraft.target, onChange: (event) => setInstructionDraft({
|
|
324
|
+
...activeInstructionDraft,
|
|
325
|
+
target: event.target
|
|
326
|
+
.value,
|
|
327
|
+
}), className: "w-full rounded-md border border-border bg-background px-2 py-1.5 text-xs text-foreground", "aria-label": t("observability.instructionTarget"), children: [_jsx("option", { value: "agent", children: t("observability.agentTarget") }), _jsx("option", { value: "developer", children: t("observability.developerTarget") }), _jsx("option", { value: "skill", children: t("observability.skillTarget") })] }), _jsx("textarea", { value: activeInstructionDraft.value, onChange: (event) => setInstructionDraft({
|
|
328
|
+
...activeInstructionDraft,
|
|
329
|
+
value: event.target.value,
|
|
330
|
+
}), rows: 4, className: "mt-2 w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground outline-none focus:ring-2 focus:ring-ring", placeholder: t("observability.instructionPlaceholder") }), _jsx("button", { type: "button", onClick: () => saveInstruction(selectedReview.runId, selectedReview.threadId), disabled: !activeInstructionDraft.value.trim() ||
|
|
331
|
+
instructionMutation.isPending, className: "mt-2 rounded-md border border-border px-2.5 py-1.5 text-xs font-medium text-foreground hover:bg-muted disabled:opacity-50", children: t("observability.saveUpdate") })] })] })] })] })) })] }, review.runId));
|
|
332
|
+
}) }), _jsx(Dialog, { open: Boolean(selectedReview && previewExpanded), onOpenChange: setPreviewExpanded, children: selectedReview && (_jsxs(DialogContent, { "aria-describedby": undefined, "data-review-lightbox": true, className: "flex max-h-[min(90dvh,900px)] w-[calc(100vw-2rem)] max-w-6xl flex-col gap-0 overflow-hidden p-0", children: [_jsx(DialogHeader, { className: "shrink-0 border-b border-border px-4 py-3", children: _jsx(DialogTitle, { className: "line-clamp-2 break-words text-left", children: selectedReview.ask || t("observability.reviewPreview") }) }), _jsx("div", { className: "min-h-0 flex-1 overflow-auto overscroll-contain p-4", children: _jsx(OutputPreview, { answer: selectedReview.answer, inlineApp: reviewDetailQuery.data?.app ?? undefined, maxAppHeight: 720, previewLabel: t("observability.reviewPreview") }) })] })) })] }));
|
|
303
333
|
}
|
|
304
334
|
// ─── Tab: Feedback ──────────────────────────────────────────────────────
|
|
305
335
|
function FeedbackTab({ days }) {
|
|
@@ -28,9 +28,10 @@ export type OutputPreviewModel = {
|
|
|
28
28
|
title?: string;
|
|
29
29
|
summary?: string;
|
|
30
30
|
imageUrl?: string;
|
|
31
|
+
previewUrl?: string;
|
|
31
32
|
tokens: DesignToken[];
|
|
32
33
|
};
|
|
33
|
-
export declare function parseOutputPreview(answer: string): OutputPreviewModel;
|
|
34
|
+
export declare function parseOutputPreview(answer: string, baseOrigin?: string | undefined): OutputPreviewModel;
|
|
34
35
|
export declare function OutputPreview({ answer, previewLabel, inlineApp, inlineAppTitle, compact, maxAppHeight, }: {
|
|
35
36
|
answer: string;
|
|
36
37
|
previewLabel: string;
|