@agent-native/core 0.114.16 → 0.115.3
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/agent-native.eject.json +2 -0
- package/corpus/README.md +3 -3
- package/corpus/core/CHANGELOG.md +41 -0
- package/corpus/core/agent-native.eject.json +2 -0
- package/corpus/core/docs/content/agent-native-toolkit.mdx +16 -0
- package/corpus/core/docs/content/recurring-jobs.mdx +35 -6
- package/corpus/core/export-snapshot.json +4 -0
- package/corpus/core/package.json +5 -1
- package/corpus/core/src/action.ts +22 -1
- package/corpus/core/src/agent/production-agent.ts +122 -3
- package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +19 -2
- package/corpus/core/src/cli/templates-meta.ts +12 -0
- package/corpus/core/src/client/AssistantChat.tsx +53 -26
- package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +19 -0
- package/corpus/core/src/client/agent-page/use-jobs.ts +1 -0
- package/corpus/core/src/client/blocks/library/wireframe.tsx +3 -1
- package/corpus/core/src/client/chat/message-components.tsx +35 -1
- package/corpus/core/src/client/chat/tool-call-display.tsx +38 -3
- package/corpus/core/src/connections/catalog.ts +20 -1
- package/corpus/core/src/connections/reader.ts +65 -0
- package/corpus/core/src/dashboard-storage/index.ts +27 -0
- package/corpus/core/src/dashboard-storage/panel-source.ts +168 -0
- package/corpus/core/src/dashboard-storage/schema.ts +62 -0
- package/corpus/core/src/dashboard-storage/store.ts +333 -0
- package/corpus/core/src/deploy/build.ts +95 -16
- package/corpus/core/src/eject/provider-api-definitions.ts +1 -0
- package/corpus/core/src/eject/workspace-connections.ts +1 -0
- package/corpus/core/src/extensions/actions.ts +199 -73
- package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +2 -0
- package/corpus/core/src/jobs/scheduler.ts +71 -4
- package/corpus/core/src/jobs/tools.ts +31 -1
- package/corpus/core/src/localization/default-messages.ts +1 -0
- package/corpus/core/src/mcp-client/index.ts +6 -0
- package/corpus/core/src/provider-api/actions/provider-api.ts +1 -1
- package/corpus/core/src/provider-api/index.ts +190 -5
- package/corpus/core/src/secrets/register-framework-secrets.ts +8 -0
- package/corpus/core/src/server/agent-chat/context-tools.ts +9 -0
- package/corpus/core/src/server/agent-chat/framework-prompts.ts +2 -2
- package/corpus/core/src/server/agent-chat-plugin.ts +22 -2
- package/corpus/core/src/server/core-routes-plugin.ts +1 -0
- package/corpus/core/src/server/credential-provider.ts +9 -3
- package/corpus/core/src/server/workspace-provider-oauth.ts +181 -4
- package/corpus/core/src/styles/agent-native.css +45 -2
- package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/corpus/core/src/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
- package/corpus/core/src/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
- package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
- package/corpus/core/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
- package/corpus/core/src/triggers/actions.ts +11 -2
- package/corpus/core/src/triggers/dispatcher.ts +20 -1
- package/corpus/core/src/triggers/types.ts +5 -0
- package/corpus/core/src/vite/action-types-plugin.ts +9 -1
- package/corpus/templates/analytics/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/analytics/AGENTS.md +11 -11
- package/corpus/templates/analytics/_gitignore +39 -0
- package/corpus/templates/analytics/actions/query-dashboard-panel.ts +30 -0
- package/corpus/templates/analytics/actions/update-dashboard.ts +2 -1
- package/corpus/templates/analytics/app/lib/sql-query.ts +11 -25
- package/corpus/templates/analytics/changelog/2026-07-21-fixed-extension-updates-failing-before-changes-could-be-appl.md +6 -0
- package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +1 -0
- package/corpus/templates/analytics/server/lib/dashboard-panel-source-resolver.ts +51 -0
- package/corpus/templates/analytics/server/lib/prometheus.ts +1 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/assets/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/brain/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/calendar/_gitignore +39 -0
- package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/corpus/templates/chat/AGENTS.md +1 -1
- package/corpus/templates/clips/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/clips/AGENTS.md +7 -0
- package/corpus/templates/clips/actions/prepare-crm-call-evidence.ts +58 -0
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +88 -11
- package/corpus/templates/clips/changelog/2026-07-21-crm-call-evidence-handoff.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-21-recording-retries-and-restarts-keep-their-upload-session-so-.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +20 -5
- package/corpus/templates/clips/chrome-extension/src/native-recording-state.ts +19 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +8 -0
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +9 -0
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +54 -28
- package/corpus/templates/clips/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/content/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/content/_gitignore +39 -0
- package/corpus/templates/content/learnings.defaults.md +5 -0
- package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/crm/.agents/skills/crm/SKILL.md +128 -0
- package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +145 -0
- package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +100 -0
- package/corpus/templates/crm/.env.example +5 -0
- package/corpus/templates/crm/AGENTS.md +120 -0
- package/corpus/templates/crm/CHANGELOG.md +1 -0
- package/corpus/templates/crm/DEVELOPING.md +66 -0
- package/corpus/templates/crm/README.md +106 -0
- package/corpus/templates/crm/_gitignore +12 -0
- package/corpus/templates/crm/actions/_crm-action-utils.ts +87 -0
- package/corpus/templates/crm/actions/_crm-dashboard.ts +69 -0
- package/corpus/templates/crm/actions/_crm-signal-utils.ts +79 -0
- package/corpus/templates/crm/actions/apply-crm-proposals.ts +203 -0
- package/corpus/templates/crm/actions/attach-call-evidence.ts +170 -0
- package/corpus/templates/crm/actions/configure-crm-connection.ts +126 -0
- package/corpus/templates/crm/actions/configure-native-crm.ts +44 -0
- package/corpus/templates/crm/actions/create-crm-record.ts +148 -0
- package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +58 -0
- package/corpus/templates/crm/actions/delete-staged-dataset.ts +14 -0
- package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +36 -0
- package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +33 -0
- package/corpus/templates/crm/actions/get-crm-dashboard.ts +14 -0
- package/corpus/templates/crm/actions/get-crm-overview.ts +13 -0
- package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +61 -0
- package/corpus/templates/crm/actions/get-crm-record.ts +75 -0
- package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +81 -0
- package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +15 -0
- package/corpus/templates/crm/actions/list-crm-dashboards.ts +15 -0
- package/corpus/templates/crm/actions/list-crm-proposals.ts +31 -0
- package/corpus/templates/crm/actions/list-crm-records.ts +79 -0
- package/corpus/templates/crm/actions/list-crm-saved-views.ts +15 -0
- package/corpus/templates/crm/actions/list-crm-signal-hits.ts +43 -0
- package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +32 -0
- package/corpus/templates/crm/actions/list-crm-tasks.ts +22 -0
- package/corpus/templates/crm/actions/list-staged-datasets.ts +14 -0
- package/corpus/templates/crm/actions/list-workspace-connections.ts +47 -0
- package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +87 -0
- package/corpus/templates/crm/actions/manage-crm-task.ts +132 -0
- package/corpus/templates/crm/actions/navigate.ts +63 -0
- package/corpus/templates/crm/actions/provider-api-catalog.ts +22 -0
- package/corpus/templates/crm/actions/provider-api-docs.ts +54 -0
- package/corpus/templates/crm/actions/provider-api-request.ts +92 -0
- package/corpus/templates/crm/actions/query-staged-dataset.ts +44 -0
- package/corpus/templates/crm/actions/record-crm-call-insight.ts +160 -0
- package/corpus/templates/crm/actions/record-crm-smart-signal.ts +150 -0
- package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +23 -0
- package/corpus/templates/crm/actions/review-crm-signal.ts +31 -0
- package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +103 -0
- package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +275 -0
- package/corpus/templates/crm/actions/run.ts +11 -0
- package/corpus/templates/crm/actions/save-crm-dashboard.ts +51 -0
- package/corpus/templates/crm/actions/save-crm-saved-view.ts +119 -0
- package/corpus/templates/crm/actions/sync-crm.ts +146 -0
- package/corpus/templates/crm/actions/update-crm-record.ts +508 -0
- package/corpus/templates/crm/actions/view-screen.ts +218 -0
- package/corpus/templates/crm/agent-native.app-skill.json +58 -0
- package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +158 -0
- package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +83 -0
- package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +225 -0
- package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +413 -0
- package/corpus/templates/crm/app/components/crm/RecordActions.tsx +510 -0
- package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +134 -0
- package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +367 -0
- package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +92 -0
- package/corpus/templates/crm/app/components/crm/Surface.tsx +96 -0
- package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +180 -0
- package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +106 -0
- package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +84 -0
- package/corpus/templates/crm/app/entry.client.tsx +16 -0
- package/corpus/templates/crm/app/entry.server.tsx +10 -0
- package/corpus/templates/crm/app/global.css +167 -0
- package/corpus/templates/crm/app/hooks/use-navigation-state.ts +60 -0
- package/corpus/templates/crm/app/i18n/en-US.ts +89 -0
- package/corpus/templates/crm/app/i18n/index.ts +34 -0
- package/corpus/templates/crm/app/lib/dashboard.ts +13 -0
- package/corpus/templates/crm/app/lib/navigation.ts +54 -0
- package/corpus/templates/crm/app/lib/tab-id.ts +1 -0
- package/corpus/templates/crm/app/lib/types.ts +172 -0
- package/corpus/templates/crm/app/lib/utils.ts +1 -0
- package/corpus/templates/crm/app/root.tsx +88 -0
- package/corpus/templates/crm/app/routes/_index.tsx +26 -0
- package/corpus/templates/crm/app/routes/accounts.tsx +41 -0
- package/corpus/templates/crm/app/routes/agent.tsx +5 -0
- package/corpus/templates/crm/app/routes/ask.tsx +53 -0
- package/corpus/templates/crm/app/routes/dashboard.tsx +118 -0
- package/corpus/templates/crm/app/routes/opportunities.tsx +41 -0
- package/corpus/templates/crm/app/routes/people.tsx +41 -0
- package/corpus/templates/crm/app/routes/proposals.tsx +266 -0
- package/corpus/templates/crm/app/routes/records.$recordId.tsx +35 -0
- package/corpus/templates/crm/app/routes/settings.tsx +63 -0
- package/corpus/templates/crm/app/routes/setup.tsx +308 -0
- package/corpus/templates/crm/app/routes/tasks.tsx +252 -0
- package/corpus/templates/crm/app/routes/views.tsx +333 -0
- package/corpus/templates/crm/app/routes.ts +17 -0
- package/corpus/templates/crm/app/vite-env.d.ts +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-agent-native-crm.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-clips-call-evidence-review-recipe.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-find-and-review-evidence-grounded-call-signals-w.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-manage-keyword-and-smart-call-signal-trackers-fr.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-delegated-local-crm-automation.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-native-sql.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboard.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboards-now-install-correctly-from-the-crm-actio.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-salesforce-connection.md +6 -0
- package/corpus/templates/crm/components.json +20 -0
- package/corpus/templates/crm/docs/architecture/crm-contract.md +180 -0
- package/corpus/templates/crm/learnings.defaults.md +5 -0
- package/corpus/templates/crm/package.json +59 -0
- package/corpus/templates/crm/public/favicon.svg +1 -0
- package/corpus/templates/crm/public/icon-180.svg +1 -0
- package/corpus/templates/crm/public/manifest.json +11 -0
- package/corpus/templates/crm/react-router.config.ts +7 -0
- package/corpus/templates/crm/server/crm/adapter.ts +32 -0
- package/corpus/templates/crm/server/crm/crm-field-firewall.ts +64 -0
- package/corpus/templates/crm/server/crm/crm-mirror.ts +711 -0
- package/corpus/templates/crm/server/crm/hubspot-adapter.ts +1143 -0
- package/corpus/templates/crm/server/crm/native-adapter.ts +1715 -0
- package/corpus/templates/crm/server/crm/read-through.ts +207 -0
- package/corpus/templates/crm/server/crm/salesforce-adapter.ts +1255 -0
- package/corpus/templates/crm/server/db/crm-store.ts +1170 -0
- package/corpus/templates/crm/server/db/index.ts +169 -0
- package/corpus/templates/crm/server/db/schema.ts +441 -0
- package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +65 -0
- package/corpus/templates/crm/server/lib/intelligence/evidence.ts +105 -0
- package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +100 -0
- package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +144 -0
- package/corpus/templates/crm/server/lib/intelligence/summary.ts +141 -0
- package/corpus/templates/crm/server/lib/provider-api.ts +64 -0
- package/corpus/templates/crm/server/middleware/auth.ts +4 -0
- package/corpus/templates/crm/server/plugins/agent-chat.ts +68 -0
- package/corpus/templates/crm/server/plugins/auth.ts +14 -0
- package/corpus/templates/crm/server/plugins/core-routes.ts +17 -0
- package/corpus/templates/crm/server/plugins/db.ts +454 -0
- package/corpus/templates/crm/server/routes/[...page].get.ts +5 -0
- package/corpus/templates/crm/shared/crm-automation-recipes.ts +132 -0
- package/corpus/templates/crm/shared/crm-contract.ts +254 -0
- package/corpus/templates/crm/shared/crm-sales-config.ts +63 -0
- package/corpus/templates/crm/ssr-entry.ts +11 -0
- package/corpus/templates/crm/tsconfig.json +24 -0
- package/corpus/templates/crm/vite.config.ts +15 -0
- package/corpus/templates/crm/vitest.config.ts +5 -0
- package/corpus/templates/design/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/dispatch/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/forms/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/forms/_gitignore +39 -0
- package/corpus/templates/forms/learnings.defaults.md +5 -0
- package/corpus/templates/macros/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/macros/_gitignore +39 -0
- package/corpus/templates/macros/learnings.defaults.md +5 -0
- package/corpus/templates/mail/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/mail/_gitignore +39 -0
- package/corpus/templates/plan/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +19 -2
- package/corpus/templates/plan/AGENTS.md +10 -0
- package/corpus/templates/plan/actions/create-prototype-plan.ts +27 -3
- package/corpus/templates/plan/actions/get-plan-blocks.ts +1 -1
- package/corpus/templates/plan/actions/update-visual-plan.ts +3 -2
- package/corpus/templates/plan/app/components/plan/PlanContentRenderer.tsx +18 -4
- package/corpus/templates/plan/app/components/plan/PlanVisualSurface.tsx +10 -3
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +3 -1
- package/corpus/templates/plan/app/i18n/en-US.ts +6 -0
- package/corpus/templates/plan/app/lib/create-plan-routing.ts +39 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +31 -107
- package/corpus/templates/plan/changelog/2026-07-22-high-fidelity-mockup-requests-now-preserve-branded-css-use-d.md +6 -0
- package/corpus/templates/plan/shared/plan-content.ts +110 -2
- package/corpus/templates/slides/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/slides/_gitignore +39 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/corpus/templates/tasks/_gitignore +39 -0
- package/corpus/toolkit/CHANGELOG.md +12 -0
- package/corpus/toolkit/README.md +30 -0
- package/corpus/toolkit/agent-native.eject.json +33 -0
- package/corpus/toolkit/package.json +15 -1
- package/corpus/toolkit/src/dashboard/DataTable.tsx +273 -0
- package/corpus/toolkit/src/dashboard/DateRangePicker.tsx +57 -0
- package/corpus/toolkit/src/dashboard/GenericChartPanel.tsx +461 -0
- package/corpus/toolkit/src/dashboard/MetricCard.tsx +54 -0
- package/corpus/toolkit/src/dashboard/StatsCard.tsx +49 -0
- package/corpus/toolkit/src/dashboard/dashboard-layout.ts +329 -0
- package/corpus/toolkit/src/dashboard/index.ts +6 -0
- package/corpus/toolkit/src/index.ts +1 -0
- package/corpus/toolkit/src/ui/calendar.tsx +8 -8
- package/corpus/toolkit/src/ui/date-picker.tsx +4 -1
- package/dist/action.d.ts +14 -1
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +3 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +97 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.js +19 -2
- package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +12 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +4 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +30 -17
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.js +3 -1
- package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
- package/dist/client/agent-page/use-jobs.d.ts +1 -0
- package/dist/client/agent-page/use-jobs.d.ts.map +1 -1
- package/dist/client/agent-page/use-jobs.js.map +1 -1
- package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.js +3 -2
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +5 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +17 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +3 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +17 -7
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +17 -3
- package/dist/connections/catalog.d.ts.map +1 -1
- package/dist/connections/catalog.js +16 -1
- package/dist/connections/catalog.js.map +1 -1
- package/dist/connections/reader.d.ts +18 -0
- package/dist/connections/reader.d.ts.map +1 -1
- package/dist/connections/reader.js +41 -0
- package/dist/connections/reader.js.map +1 -1
- package/dist/dashboard-storage/index.d.ts +4 -0
- package/dist/dashboard-storage/index.d.ts.map +1 -0
- package/dist/dashboard-storage/index.js +4 -0
- package/dist/dashboard-storage/index.js.map +1 -0
- package/dist/dashboard-storage/panel-source.d.ts +68 -0
- package/dist/dashboard-storage/panel-source.d.ts.map +1 -0
- package/dist/dashboard-storage/panel-source.js +76 -0
- package/dist/dashboard-storage/panel-source.js.map +1 -0
- package/dist/dashboard-storage/schema.d.ts +562 -0
- package/dist/dashboard-storage/schema.d.ts.map +1 -0
- package/dist/dashboard-storage/schema.js +32 -0
- package/dist/dashboard-storage/schema.js.map +1 -0
- package/dist/dashboard-storage/store.d.ts +62 -0
- package/dist/dashboard-storage/store.d.ts.map +1 -0
- package/dist/dashboard-storage/store.js +227 -0
- package/dist/dashboard-storage/store.js.map +1 -0
- package/dist/deploy/build.d.ts +7 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +78 -14
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/provider-api-definitions.d.ts +2 -1
- package/dist/eject/provider-api-definitions.d.ts.map +1 -1
- package/dist/eject/provider-api-definitions.js +1 -0
- package/dist/eject/provider-api-definitions.js.map +1 -1
- package/dist/eject/workspace-connections.d.ts.map +1 -1
- package/dist/eject/workspace-connections.js +1 -0
- package/dist/eject/workspace-connections.js.map +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +165 -67
- package/dist/extensions/actions.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/jobs/actions/list-recurring-jobs.d.ts +1 -0
- package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -1
- package/dist/jobs/actions/list-recurring-jobs.js +1 -0
- package/dist/jobs/actions/list-recurring-jobs.js.map +1 -1
- package/dist/jobs/scheduler.d.ts +17 -2
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +51 -2
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +32 -2
- package/dist/jobs/tools.js.map +1 -1
- package/dist/localization/default-messages.d.ts +1 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +1 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp-client/index.d.ts +2 -0
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +5 -0
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +8 -6
- package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
- package/dist/provider-api/actions/provider-api.js +1 -1
- package/dist/provider-api/actions/provider-api.js.map +1 -1
- package/dist/provider-api/index.d.ts +11 -7
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +143 -5
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +7 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
- package/dist/server/agent-chat/context-tools.js +9 -0
- package/dist/server/agent-chat/context-tools.js.map +1 -1
- package/dist/server/agent-chat/framework-prompts.js +2 -2
- package/dist/server/agent-chat/framework-prompts.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +18 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +1 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +4 -3
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +9 -3
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +6 -1
- package/dist/server/workspace-provider-oauth.d.ts.map +1 -1
- package/dist/server/workspace-provider-oauth.js +141 -4
- package/dist/server/workspace-provider-oauth.js.map +1 -1
- package/dist/styles/agent-native.css +45 -2
- package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/dist/templates/chat/AGENTS.md +1 -1
- package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/dist/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
- package/dist/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
- package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
- package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +10 -2
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +15 -0
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/triggers/types.d.ts +5 -0
- package/dist/triggers/types.d.ts.map +1 -1
- package/dist/triggers/types.js.map +1 -1
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +4 -1
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/docs/content/agent-native-toolkit.mdx +16 -0
- package/docs/content/recurring-jobs.mdx +35 -6
- package/package.json +7 -3
- package/src/action.ts +22 -1
- package/src/agent/production-agent.ts +122 -3
- package/src/cli/skills-content/visual-plan-skill.ts +19 -2
- package/src/cli/templates-meta.ts +12 -0
- package/src/client/AssistantChat.tsx +53 -26
- package/src/client/agent-page/AgentJobsTab.tsx +19 -0
- package/src/client/agent-page/use-jobs.ts +1 -0
- package/src/client/blocks/library/wireframe.tsx +3 -1
- package/src/client/chat/message-components.tsx +35 -1
- package/src/client/chat/tool-call-display.tsx +38 -3
- package/src/connections/catalog.ts +20 -1
- package/src/connections/reader.ts +65 -0
- package/src/dashboard-storage/index.ts +27 -0
- package/src/dashboard-storage/panel-source.ts +168 -0
- package/src/dashboard-storage/schema.ts +62 -0
- package/src/dashboard-storage/store.ts +333 -0
- package/src/deploy/build.ts +95 -16
- package/src/eject/provider-api-definitions.ts +1 -0
- package/src/eject/workspace-connections.ts +1 -0
- package/src/extensions/actions.ts +199 -73
- package/src/jobs/actions/list-recurring-jobs.ts +2 -0
- package/src/jobs/scheduler.ts +71 -4
- package/src/jobs/tools.ts +31 -1
- package/src/localization/default-messages.ts +1 -0
- package/src/mcp-client/index.ts +6 -0
- package/src/provider-api/actions/provider-api.ts +1 -1
- package/src/provider-api/index.ts +190 -5
- package/src/secrets/register-framework-secrets.ts +8 -0
- package/src/server/agent-chat/context-tools.ts +9 -0
- package/src/server/agent-chat/framework-prompts.ts +2 -2
- package/src/server/agent-chat-plugin.ts +22 -2
- package/src/server/core-routes-plugin.ts +1 -0
- package/src/server/credential-provider.ts +9 -3
- package/src/server/workspace-provider-oauth.ts +181 -4
- package/src/styles/agent-native.css +45 -2
- package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/src/templates/chat/AGENTS.md +1 -1
- package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/src/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
- package/src/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
- package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
- package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
- package/src/triggers/actions.ts +11 -2
- package/src/triggers/dispatcher.ts +20 -1
- package/src/triggers/types.ts +5 -0
- package/src/vite/action-types-plugin.ts +9 -1
- package/corpus/templates/analytics/server/handlers/sql-query.ts +0 -36
- package/corpus/templates/analytics/server/routes/api/sql-query.post.ts +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.115.3",
|
|
4
4
|
"description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
|
|
5
5
|
"homepage": "https://github.com/BuilderIO/agent-native#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -276,6 +276,10 @@
|
|
|
276
276
|
"types": "./dist/data-programs/index.d.ts",
|
|
277
277
|
"default": "./dist/data-programs/index.js"
|
|
278
278
|
},
|
|
279
|
+
"./dashboard-storage": {
|
|
280
|
+
"types": "./dist/dashboard-storage/index.d.ts",
|
|
281
|
+
"default": "./dist/dashboard-storage/index.js"
|
|
282
|
+
},
|
|
279
283
|
"./local-artifacts": {
|
|
280
284
|
"types": "./dist/local-artifacts/index.d.ts",
|
|
281
285
|
"default": "./dist/local-artifacts/index.js"
|
|
@@ -381,8 +385,8 @@
|
|
|
381
385
|
"y-protocols": "^1.0.7",
|
|
382
386
|
"yjs": "^13.6.31",
|
|
383
387
|
"zod": "^4.3.6",
|
|
384
|
-
"@agent-native/
|
|
385
|
-
"@agent-native/
|
|
388
|
+
"@agent-native/toolkit": "^0.9.0",
|
|
389
|
+
"@agent-native/recap-cli": "0.5.0"
|
|
386
390
|
},
|
|
387
391
|
"devDependencies": {
|
|
388
392
|
"@ai-sdk/anthropic": "^3.0.71",
|
package/src/action.ts
CHANGED
|
@@ -27,8 +27,27 @@ import type { ActionAuditConfig } from "./audit/types.js";
|
|
|
27
27
|
* - `"a2a"` — a direct, explicitly exposed read-only A2A action dispatch.
|
|
28
28
|
* Natural-language A2A delegation still runs through the agent loop and its
|
|
29
29
|
* selected actions are attributed as `"tool"`.
|
|
30
|
+
* - `"automation"` — an event-triggered automation dispatched from a stored
|
|
31
|
+
* workspace trigger with trusted trigger lineage.
|
|
30
32
|
*/
|
|
31
|
-
export type ActionCaller =
|
|
33
|
+
export type ActionCaller =
|
|
34
|
+
| "tool"
|
|
35
|
+
| "http"
|
|
36
|
+
| "frontend"
|
|
37
|
+
| "cli"
|
|
38
|
+
| "mcp"
|
|
39
|
+
| "a2a"
|
|
40
|
+
| "automation";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Trusted automation lineage added by the trigger dispatcher. Action inputs
|
|
44
|
+
* must never be used to create or override this context.
|
|
45
|
+
*/
|
|
46
|
+
export interface ActionAutomationContext {
|
|
47
|
+
triggerId: string;
|
|
48
|
+
triggerName: string;
|
|
49
|
+
policyId?: string;
|
|
50
|
+
}
|
|
32
51
|
|
|
33
52
|
/**
|
|
34
53
|
* Context passed as the optional second argument to an action's `run`.
|
|
@@ -56,6 +75,8 @@ export interface ActionRunContext {
|
|
|
56
75
|
orgId?: string | null;
|
|
57
76
|
/** How this action was invoked. */
|
|
58
77
|
caller: ActionCaller;
|
|
78
|
+
/** Present only for trigger-dispatched automation calls. */
|
|
79
|
+
automation?: ActionAutomationContext;
|
|
59
80
|
/** Verified network lineage for direct delegated action calls. */
|
|
60
81
|
networkProtocol?: "a2a" | "mcp" | "provider-api";
|
|
61
82
|
networkId?: string;
|
|
@@ -8,7 +8,11 @@ import {
|
|
|
8
8
|
} from "h3";
|
|
9
9
|
import type { EventHandler as H3EventHandler } from "h3";
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
isAgentActionStopError,
|
|
13
|
+
type ActionAutomationContext,
|
|
14
|
+
type ActionCaller,
|
|
15
|
+
} from "../action.js";
|
|
12
16
|
import { readAppState } from "../application-state/script-helpers.js";
|
|
13
17
|
import { isReadOnlyShellCommand } from "../coding-tools/index.js";
|
|
14
18
|
import { extensionIdFromPathname } from "../extensions/path.js";
|
|
@@ -3083,6 +3087,21 @@ function normalizeToolCallInputForHistory(
|
|
|
3083
3087
|
return { rawInput: input };
|
|
3084
3088
|
}
|
|
3085
3089
|
|
|
3090
|
+
function dedupeAssistantToolCallsById(
|
|
3091
|
+
content: import("./engine/types.js").EngineContentPart[],
|
|
3092
|
+
): import("./engine/types.js").EngineContentPart[] {
|
|
3093
|
+
const seenToolCallIds = new Set<string>();
|
|
3094
|
+
const deduped: import("./engine/types.js").EngineContentPart[] = [];
|
|
3095
|
+
for (const part of content) {
|
|
3096
|
+
if (part.type === "tool-call") {
|
|
3097
|
+
if (seenToolCallIds.has(part.id)) continue;
|
|
3098
|
+
seenToolCallIds.add(part.id);
|
|
3099
|
+
}
|
|
3100
|
+
deduped.push(part);
|
|
3101
|
+
}
|
|
3102
|
+
return deduped;
|
|
3103
|
+
}
|
|
3104
|
+
|
|
3086
3105
|
function toolInputSchemaErrorResult(
|
|
3087
3106
|
toolName: string,
|
|
3088
3107
|
input: unknown,
|
|
@@ -3107,6 +3126,91 @@ const rawToolInputAjv = new Ajv({
|
|
|
3107
3126
|
|
|
3108
3127
|
const rawToolInputValidatorCache = new WeakMap<object, ValidateFunction>();
|
|
3109
3128
|
|
|
3129
|
+
const optionalPlaceholderAjv = new Ajv({
|
|
3130
|
+
strict: false,
|
|
3131
|
+
allErrors: false,
|
|
3132
|
+
coerceTypes: false,
|
|
3133
|
+
useDefaults: false,
|
|
3134
|
+
removeAdditional: false,
|
|
3135
|
+
});
|
|
3136
|
+
|
|
3137
|
+
const optionalPlaceholderValidatorCache = new WeakMap<
|
|
3138
|
+
object,
|
|
3139
|
+
ValidateFunction
|
|
3140
|
+
>();
|
|
3141
|
+
|
|
3142
|
+
function isStructurallyEmptyToolValue(value: unknown): boolean {
|
|
3143
|
+
if (value === false) return true;
|
|
3144
|
+
if (value === null) return true;
|
|
3145
|
+
if (typeof value === "string") return value.trim().length === 0;
|
|
3146
|
+
if (Array.isArray(value)) {
|
|
3147
|
+
return (
|
|
3148
|
+
value.length === 0 ||
|
|
3149
|
+
value.every(
|
|
3150
|
+
(item) =>
|
|
3151
|
+
item !== null &&
|
|
3152
|
+
typeof item === "object" &&
|
|
3153
|
+
!Array.isArray(item) &&
|
|
3154
|
+
Object.keys(item).length === 0,
|
|
3155
|
+
)
|
|
3156
|
+
);
|
|
3157
|
+
}
|
|
3158
|
+
return (
|
|
3159
|
+
typeof value === "object" &&
|
|
3160
|
+
value !== null &&
|
|
3161
|
+
Object.keys(value).length === 0
|
|
3162
|
+
);
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3165
|
+
function schemaAcceptsToolValue(schema: object, value: unknown): boolean {
|
|
3166
|
+
let validator = optionalPlaceholderValidatorCache.get(schema);
|
|
3167
|
+
if (!validator) {
|
|
3168
|
+
try {
|
|
3169
|
+
validator = optionalPlaceholderAjv.compile(schema);
|
|
3170
|
+
optionalPlaceholderValidatorCache.set(schema, validator);
|
|
3171
|
+
} catch {
|
|
3172
|
+
return false;
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
return Boolean(validator(value));
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
/**
|
|
3179
|
+
* Some model gateways fill every optional tool field with an empty sentinel
|
|
3180
|
+
* instead of omitting it. One schema-invalid empty value proves that pattern;
|
|
3181
|
+
* only then strip the other optional empty/default sentinels from the call.
|
|
3182
|
+
* Calls whose empty values are all schema-valid keep their intentional clears.
|
|
3183
|
+
*/
|
|
3184
|
+
function normalizeOptionalToolPlaceholders(
|
|
3185
|
+
schema: RawJsonSchema | undefined,
|
|
3186
|
+
input: unknown,
|
|
3187
|
+
): { input: unknown; changed: boolean } {
|
|
3188
|
+
if (!schema?.properties || !input || typeof input !== "object") {
|
|
3189
|
+
return { input, changed: false };
|
|
3190
|
+
}
|
|
3191
|
+
if (Array.isArray(input)) return { input, changed: false };
|
|
3192
|
+
|
|
3193
|
+
const required = new Set(
|
|
3194
|
+
Array.isArray(schema.required) ? schema.required : [],
|
|
3195
|
+
);
|
|
3196
|
+
const placeholders: string[] = [];
|
|
3197
|
+
let hasSchemaInvalidPlaceholder = false;
|
|
3198
|
+
for (const [key, value] of Object.entries(input as Record<string, unknown>)) {
|
|
3199
|
+
if (required.has(key) || !isStructurallyEmptyToolValue(value)) continue;
|
|
3200
|
+
const propertySchema = schema.properties[key];
|
|
3201
|
+
if (!propertySchema || typeof propertySchema !== "object") continue;
|
|
3202
|
+
placeholders.push(key);
|
|
3203
|
+
if (!schemaAcceptsToolValue(propertySchema, value)) {
|
|
3204
|
+
hasSchemaInvalidPlaceholder = true;
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
if (!hasSchemaInvalidPlaceholder) return { input, changed: false };
|
|
3208
|
+
|
|
3209
|
+
const normalized = { ...(input as Record<string, unknown>) };
|
|
3210
|
+
for (const key of placeholders) delete normalized[key];
|
|
3211
|
+
return { input: normalized, changed: true };
|
|
3212
|
+
}
|
|
3213
|
+
|
|
3110
3214
|
function getRawToolInputValidator(schema: RawJsonSchema): ValidateFunction {
|
|
3111
3215
|
const cached = rawToolInputValidatorCache.get(schema);
|
|
3112
3216
|
if (cached) return cached;
|
|
@@ -3163,6 +3267,8 @@ export async function runAgentLoop(opts: {
|
|
|
3163
3267
|
orgId?: string | null;
|
|
3164
3268
|
/** Action invocation attribution. Defaults to the normal agent tool loop. */
|
|
3165
3269
|
actionCaller?: ActionCaller;
|
|
3270
|
+
/** Trusted trigger lineage for automation-dispatched action calls. */
|
|
3271
|
+
automation?: ActionAutomationContext;
|
|
3166
3272
|
/** Concrete execution id used for cross-app trace correlation. */
|
|
3167
3273
|
runId?: string;
|
|
3168
3274
|
/** Verified/telemetry-only delegated lineage supplied by the transport. */
|
|
@@ -3905,6 +4011,8 @@ export async function runAgentLoop(opts: {
|
|
|
3905
4011
|
}
|
|
3906
4012
|
}
|
|
3907
4013
|
|
|
4014
|
+
assistantContent = dedupeAssistantToolCallsById(assistantContent);
|
|
4015
|
+
|
|
3908
4016
|
const assistantContentForHistory = assistantContent.map((part) =>
|
|
3909
4017
|
part.type === "tool-call"
|
|
3910
4018
|
? {
|
|
@@ -4068,11 +4176,20 @@ export async function runAgentLoop(opts: {
|
|
|
4068
4176
|
const runToolCall = async (
|
|
4069
4177
|
toolCall: import("./engine/types.js").EngineToolCallPart,
|
|
4070
4178
|
): Promise<EngineContentPart> => {
|
|
4179
|
+
const actionEntry = actions[toolCall.name];
|
|
4180
|
+
const placeholderNormalization = actionEntry
|
|
4181
|
+
? normalizeOptionalToolPlaceholders(
|
|
4182
|
+
actionEntry.tool.parameters,
|
|
4183
|
+
toolCall.input,
|
|
4184
|
+
)
|
|
4185
|
+
: { input: toolCall.input, changed: false };
|
|
4186
|
+
if (placeholderNormalization.changed) {
|
|
4187
|
+
toolCall = { ...toolCall, input: placeholderNormalization.input };
|
|
4188
|
+
}
|
|
4071
4189
|
const wireToolInput = JSON.stringify(toolCall.input ?? {});
|
|
4072
4190
|
const normalizedToolInput = normalizeToolCallInputForHistory(
|
|
4073
4191
|
toolCall.input,
|
|
4074
4192
|
);
|
|
4075
|
-
const actionEntry = actions[toolCall.name];
|
|
4076
4193
|
const sourceSweepGuard = shouldGuardRepeatedSourceSweep({
|
|
4077
4194
|
toolName: toolCall.name,
|
|
4078
4195
|
entry: actionEntry,
|
|
@@ -4227,6 +4344,7 @@ export async function runAgentLoop(opts: {
|
|
|
4227
4344
|
userEmail: getRequestUserEmail(),
|
|
4228
4345
|
orgId: getRequestOrgId() ?? null,
|
|
4229
4346
|
caller: opts.actionCaller ?? "tool",
|
|
4347
|
+
automation: opts.automation,
|
|
4230
4348
|
networkProtocol: opts.networkProtocol,
|
|
4231
4349
|
networkId: opts.networkId,
|
|
4232
4350
|
networkPeer: opts.networkPeer,
|
|
@@ -4490,7 +4608,7 @@ export async function runAgentLoop(opts: {
|
|
|
4490
4608
|
});
|
|
4491
4609
|
|
|
4492
4610
|
const toolCallSchemaError = toolCallErrors.get(toolCall.id);
|
|
4493
|
-
if (toolCallSchemaError) {
|
|
4611
|
+
if (toolCallSchemaError && !placeholderNormalization.changed) {
|
|
4494
4612
|
const result = finalizeToolErrorResult(
|
|
4495
4613
|
toolInputSchemaErrorResult(
|
|
4496
4614
|
toolCall.name,
|
|
@@ -4663,6 +4781,7 @@ export async function runAgentLoop(opts: {
|
|
|
4663
4781
|
userEmail: actionUserEmail ?? undefined,
|
|
4664
4782
|
orgId: actionOrgId,
|
|
4665
4783
|
caller: opts.actionCaller ?? "tool",
|
|
4784
|
+
automation: opts.automation,
|
|
4666
4785
|
networkProtocol: opts.networkProtocol,
|
|
4667
4786
|
networkId: opts.networkId,
|
|
4668
4787
|
networkPeer: opts.networkPeer,
|
|
@@ -301,6 +301,18 @@ and screen ids across both surfaces. The canvas is the inspectable static refere
|
|
|
301
301
|
the prototype is the interactive version of that same flow, not a separate
|
|
302
302
|
design direction.
|
|
303
303
|
|
|
304
|
+
Treat “higher fidelity,” “pixel-accurate,” “polished mockup,” “production-like,”
|
|
305
|
+
“real design,” and “not a sketch/wireframe” as design-first language even when
|
|
306
|
+
the request also says “mockup.” For a new plan, use \`create-plan-design\`. For
|
|
307
|
+
an existing plan, keep the same plan id and call \`update-visual-plan\` with a
|
|
308
|
+
\`set-visual-render-mode\` patch using \`renderMode: "design"\` plus the upgraded
|
|
309
|
+
screen HTML/CSS in the same update. Ground the result in the real app shell,
|
|
310
|
+
tokens, typography, spacing, and states, and add stable \`data-design-id\`
|
|
311
|
+
targets. Put scoped styles in each screen's \`css\` field, never in a \`<style>\`
|
|
312
|
+
tag. The viewer-local Clean toggle only changes one browser's wireframe
|
|
313
|
+
preference; it is not a fidelity upgrade. Do not create a duplicate plan to
|
|
314
|
+
handle a fidelity follow-up.
|
|
315
|
+
|
|
304
316
|
## Wireframe quality — read \`references/wireframe.md\`
|
|
305
317
|
|
|
306
318
|
UI recap/plan wireframes must meet a strict quality bar — full-width chrome,
|
|
@@ -349,7 +361,9 @@ directory before authoring a plan.
|
|
|
349
361
|
visual surface, canvas only, or canvas + prototype.
|
|
350
362
|
- \`create-ui-plan\`: start a UI-first plan when the work is primarily product UI.
|
|
351
363
|
- \`create-prototype-plan\`: start a prototype-first plan with a functional top
|
|
352
|
-
review surface.
|
|
364
|
+
review surface. If the interaction itself must also be high fidelity, set each
|
|
365
|
+
screen's \`renderMode\` to \`design\` and pass scoped styles through \`css\`;
|
|
366
|
+
otherwise use \`create-plan-design\` for design-first review.
|
|
353
367
|
- \`create-plan-design\`: start a full-fidelity branded Design-tab plan with an
|
|
354
368
|
optional matching Prototype tab.
|
|
355
369
|
- \`convert-visual-plan-to-prototype\`: convert an existing HTML wireframe canvas
|
|
@@ -357,7 +371,10 @@ directory before authoring a plan.
|
|
|
357
371
|
- \`create-visual-questions\`: use only when the user explicitly asks for a visual
|
|
358
372
|
intake questionnaire, not as \`/visual-plan\` preflight.
|
|
359
373
|
- \`update-visual-plan\`: revise content, status, or comments with targeted
|
|
360
|
-
\`contentPatches\` (see Core Workflow steps 6-7).
|
|
374
|
+
\`contentPatches\` (see Core Workflow steps 6-7). Use
|
|
375
|
+
\`set-visual-render-mode\` with \`renderMode: "design"\` when promoting an
|
|
376
|
+
existing plan to high fidelity, together with deliberate screen HTML/CSS;
|
|
377
|
+
render mode alone only removes sketch treatment. \`replace-blocks\` and full
|
|
361
378
|
\`content\` replacement require \`expectedUpdatedAt\` from a fresh
|
|
362
379
|
\`get-visual-plan\` call.
|
|
363
380
|
- \`read-visual-plan-source\`: read the normalized plan as \`plan.mdx\`,
|
|
@@ -228,6 +228,18 @@ export const TEMPLATES: TemplateMeta[] = [
|
|
|
228
228
|
hidden: true,
|
|
229
229
|
core: false,
|
|
230
230
|
},
|
|
231
|
+
{
|
|
232
|
+
name: "crm",
|
|
233
|
+
label: "CRM",
|
|
234
|
+
hint: "Agent-native CRM companion with scoped HubSpot intelligence, workflows, and write proposals",
|
|
235
|
+
icon: "Users",
|
|
236
|
+
color: "#2563EB",
|
|
237
|
+
colorRgb: "37 99 235",
|
|
238
|
+
devPort: 8107,
|
|
239
|
+
hidden: true,
|
|
240
|
+
defaultMode: "dev",
|
|
241
|
+
core: false,
|
|
242
|
+
},
|
|
231
243
|
{
|
|
232
244
|
name: "macros",
|
|
233
245
|
label: "Macros",
|
|
@@ -1591,6 +1591,15 @@ export function shouldShowGlobalRunningStatus({
|
|
|
1591
1591
|
) {
|
|
1592
1592
|
return false;
|
|
1593
1593
|
}
|
|
1594
|
+
// The reasoning cell already owns the generic Thinking state. Activity
|
|
1595
|
+
// events can briefly reassert that same label between reasoning deltas;
|
|
1596
|
+
// rendering both makes a second Thinking row flash beneath the thought.
|
|
1597
|
+
if (
|
|
1598
|
+
runningActivityLabel === "Thinking" &&
|
|
1599
|
+
(latestMessageHasReasoning || contentHasVisibleReasoning(reconnectContent))
|
|
1600
|
+
) {
|
|
1601
|
+
return false;
|
|
1602
|
+
}
|
|
1594
1603
|
if (runningActivityLabel) return true;
|
|
1595
1604
|
|
|
1596
1605
|
return (
|
|
@@ -1598,6 +1607,16 @@ export function shouldShowGlobalRunningStatus({
|
|
|
1598
1607
|
);
|
|
1599
1608
|
}
|
|
1600
1609
|
|
|
1610
|
+
export function assistantChatAutoscrollStatusKey({
|
|
1611
|
+
showGlobalRunningStatus,
|
|
1612
|
+
runningStatusLabel,
|
|
1613
|
+
}: {
|
|
1614
|
+
showGlobalRunningStatus: boolean;
|
|
1615
|
+
runningStatusLabel: string;
|
|
1616
|
+
}): string {
|
|
1617
|
+
return showGlobalRunningStatus ? runningStatusLabel : "idle";
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1601
1620
|
type QueuedMessage = {
|
|
1602
1621
|
id: string;
|
|
1603
1622
|
text: string;
|
|
@@ -4804,11 +4823,28 @@ const AssistantChatInner = forwardRef<
|
|
|
4804
4823
|
adapterHandoffPending || reconnectTailOnlyRef.current,
|
|
4805
4824
|
},
|
|
4806
4825
|
);
|
|
4826
|
+
const latestMessage = messages[messages.length - 1];
|
|
4827
|
+
const reconnectStatusContent =
|
|
4828
|
+
visibleReconnectContent.length > 0
|
|
4829
|
+
? visibleReconnectContent
|
|
4830
|
+
: reconnectContent.length === 0
|
|
4831
|
+
? reconnectActivityContent
|
|
4832
|
+
: [];
|
|
4833
|
+
const showGlobalRunningStatus = shouldShowGlobalRunningStatus({
|
|
4834
|
+
showRunningInUI,
|
|
4835
|
+
runningActivityLabel,
|
|
4836
|
+
runningActivityTool,
|
|
4837
|
+
latestMessage,
|
|
4838
|
+
reconnectContent: reconnectStatusContent,
|
|
4839
|
+
});
|
|
4807
4840
|
const autoscrollFollowKey = [
|
|
4808
4841
|
messages.map(messageFollowKey).join(";"),
|
|
4809
4842
|
`q:${queuedMessages.map(queuedMessageFollowKey).join("|")}`,
|
|
4810
4843
|
`r:${reconnectContentFollowKey(visibleReconnectContent)}`,
|
|
4811
|
-
`status:${
|
|
4844
|
+
`status:${assistantChatAutoscrollStatusKey({
|
|
4845
|
+
showGlobalRunningStatus,
|
|
4846
|
+
runningStatusLabel,
|
|
4847
|
+
})}`,
|
|
4812
4848
|
].join(";;");
|
|
4813
4849
|
const {
|
|
4814
4850
|
scrollRef,
|
|
@@ -4882,21 +4918,7 @@ const AssistantChatInner = forwardRef<
|
|
|
4882
4918
|
() => latestNonRecoveryUserMessageText(messages),
|
|
4883
4919
|
[messages],
|
|
4884
4920
|
);
|
|
4885
|
-
const latestMessage = messages[messages.length - 1];
|
|
4886
4921
|
const latestMessageRole = latestMessage?.role;
|
|
4887
|
-
const reconnectStatusContent =
|
|
4888
|
-
visibleReconnectContent.length > 0
|
|
4889
|
-
? visibleReconnectContent
|
|
4890
|
-
: reconnectContent.length === 0
|
|
4891
|
-
? reconnectActivityContent
|
|
4892
|
-
: [];
|
|
4893
|
-
const showGlobalRunningStatus = shouldShowGlobalRunningStatus({
|
|
4894
|
-
showRunningInUI,
|
|
4895
|
-
runningActivityLabel,
|
|
4896
|
-
runningActivityTool,
|
|
4897
|
-
latestMessage,
|
|
4898
|
-
reconnectContent: reconnectStatusContent,
|
|
4899
|
-
});
|
|
4900
4922
|
const latestAssistantWasPlan =
|
|
4901
4923
|
latestMessageRole === "assistant" &&
|
|
4902
4924
|
getRequestModeMetadata(latestMessage) === "plan";
|
|
@@ -5535,18 +5557,23 @@ const AssistantChatInner = forwardRef<
|
|
|
5535
5557
|
className="agent-composer-missing-key-trigger"
|
|
5536
5558
|
aria-label="Connect AI to start chatting"
|
|
5537
5559
|
>
|
|
5538
|
-
<span className="agent-composer-missing-key-
|
|
5539
|
-
<span className="agent-composer-missing-key-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
{missingApiKeySetupLayout !== "sidebar" ? (
|
|
5545
|
-
<span className="agent-composer-missing-key-description">
|
|
5546
|
-
Builder.io includes free credits, or use
|
|
5547
|
-
your own API key.
|
|
5560
|
+
<span className="agent-composer-missing-key-content">
|
|
5561
|
+
<span className="agent-composer-missing-key-copy">
|
|
5562
|
+
<span className="agent-composer-missing-key-title">
|
|
5563
|
+
{missingApiKeySetupLayout === "sidebar"
|
|
5564
|
+
? "Connect AI to chat"
|
|
5565
|
+
: "Connect AI to start chatting"}
|
|
5548
5566
|
</span>
|
|
5549
|
-
|
|
5567
|
+
{missingApiKeySetupLayout !== "sidebar" ? (
|
|
5568
|
+
<span className="agent-composer-missing-key-description">
|
|
5569
|
+
Builder.io includes free credits, or use
|
|
5570
|
+
your own API key.
|
|
5571
|
+
</span>
|
|
5572
|
+
) : null}
|
|
5573
|
+
</span>
|
|
5574
|
+
<span className="agent-composer-missing-key-cta">
|
|
5575
|
+
Connect AI
|
|
5576
|
+
</span>
|
|
5550
5577
|
</span>
|
|
5551
5578
|
</button>
|
|
5552
5579
|
</PopoverTrigger>
|
|
@@ -432,6 +432,25 @@ export function AgentJobsTab({ canManageOrg = false }: AgentPageTabProps) {
|
|
|
432
432
|
<p className="mt-1 whitespace-pre-wrap text-sm text-muted-foreground">
|
|
433
433
|
{detailsTarget.instructions}
|
|
434
434
|
</p>
|
|
435
|
+
{detailsTarget.mcpTools.length > 0 ? (
|
|
436
|
+
<div className="mt-4">
|
|
437
|
+
<p className="text-xs font-medium text-foreground">
|
|
438
|
+
{t("jobs.mcpTools", {
|
|
439
|
+
defaultValue: "Connected MCP tools",
|
|
440
|
+
})}
|
|
441
|
+
</p>
|
|
442
|
+
<div className="mt-1 flex flex-wrap gap-1.5">
|
|
443
|
+
{detailsTarget.mcpTools.map((toolName) => (
|
|
444
|
+
<code
|
|
445
|
+
key={toolName}
|
|
446
|
+
className="rounded bg-muted px-1.5 py-0.5 text-[11px] text-muted-foreground"
|
|
447
|
+
>
|
|
448
|
+
{toolName}
|
|
449
|
+
</code>
|
|
450
|
+
))}
|
|
451
|
+
</div>
|
|
452
|
+
</div>
|
|
453
|
+
) : null}
|
|
435
454
|
</div>
|
|
436
455
|
) : null}
|
|
437
456
|
</DialogContent>
|
|
@@ -142,7 +142,7 @@ function ArtboardFrame({
|
|
|
142
142
|
const fitRef = useRef<HTMLDivElement>(null);
|
|
143
143
|
const isDark = useIsDark();
|
|
144
144
|
const theme: "light" | "dark" = isDark ? "dark" : "light";
|
|
145
|
-
const
|
|
145
|
+
const preferredStyle = useWireframeStyle();
|
|
146
146
|
const preset = SURFACE_PRESETS[surface] ?? SURFACE_PRESETS.desktop;
|
|
147
147
|
const width = canvasWidth ?? preset.width;
|
|
148
148
|
// AUTO-HEIGHT: with no explicit `canvasSize` the artboard height is driven by
|
|
@@ -164,6 +164,7 @@ function ArtboardFrame({
|
|
|
164
164
|
fixedHeight ?? null,
|
|
165
165
|
);
|
|
166
166
|
const designMode = renderMode === "design";
|
|
167
|
+
const style = designMode ? "clean" : preferredStyle;
|
|
167
168
|
const sketchy = !designMode && style === "sketchy" && !skeleton;
|
|
168
169
|
const roughEnabled = sketchy && roughOverlay;
|
|
169
170
|
const frameBorder = skeleton
|
|
@@ -409,6 +410,7 @@ function KitArtboard({
|
|
|
409
410
|
surface={data.surface}
|
|
410
411
|
compact={compact}
|
|
411
412
|
skeleton={data.skeleton}
|
|
413
|
+
renderMode={data.renderMode}
|
|
412
414
|
showFrame={showFrame}
|
|
413
415
|
selector="[data-rough]"
|
|
414
416
|
caption={data.caption}
|
|
@@ -859,6 +859,27 @@ export function assistantMessageHasUnresolvedTool(content: unknown): boolean {
|
|
|
859
859
|
});
|
|
860
860
|
}
|
|
861
861
|
|
|
862
|
+
// Only the last assistant message may shimmer as "the currently running
|
|
863
|
+
// tool" — an older message's dangling unresolved tool-call must never
|
|
864
|
+
// shimmer once a later run is active.
|
|
865
|
+
export function computeLatestRunningToolCallId(
|
|
866
|
+
content: ContentPart[] | undefined,
|
|
867
|
+
{ chatRunning, isLast }: { chatRunning: boolean; isLast: boolean },
|
|
868
|
+
): string | null {
|
|
869
|
+
if (!isLast) return null;
|
|
870
|
+
return (
|
|
871
|
+
content?.reduce(
|
|
872
|
+
(latestToolCallId, part) =>
|
|
873
|
+
part.type === "tool-call" &&
|
|
874
|
+
part.result === undefined &&
|
|
875
|
+
(chatRunning || part.activity === true)
|
|
876
|
+
? part.toolCallId
|
|
877
|
+
: latestToolCallId,
|
|
878
|
+
null as string | null,
|
|
879
|
+
) ?? null
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
|
|
862
883
|
export function shouldShowAssistantMessageFooter({
|
|
863
884
|
isLast,
|
|
864
885
|
chatRunning,
|
|
@@ -1157,6 +1178,10 @@ export function AssistantMessage() {
|
|
|
1157
1178
|
(p.type !== "tool-call" || p.activity !== true) &&
|
|
1158
1179
|
isCollapsibleAssistantWorkPart(p),
|
|
1159
1180
|
);
|
|
1181
|
+
const latestRunningToolCallId = computeLatestRunningToolCallId(msgContent, {
|
|
1182
|
+
chatRunning,
|
|
1183
|
+
isLast,
|
|
1184
|
+
});
|
|
1160
1185
|
|
|
1161
1186
|
if (!hasRenderableContent) return null;
|
|
1162
1187
|
|
|
@@ -1201,7 +1226,16 @@ export function AssistantMessage() {
|
|
|
1201
1226
|
case "reasoning":
|
|
1202
1227
|
return <ReasoningMessagePart />;
|
|
1203
1228
|
case "tool-call":
|
|
1204
|
-
return
|
|
1229
|
+
return (
|
|
1230
|
+
part.toolUI ?? (
|
|
1231
|
+
<ToolCallFallback
|
|
1232
|
+
{...part}
|
|
1233
|
+
isLatestRunning={
|
|
1234
|
+
part.toolCallId === latestRunningToolCallId
|
|
1235
|
+
}
|
|
1236
|
+
/>
|
|
1237
|
+
)
|
|
1238
|
+
);
|
|
1205
1239
|
default:
|
|
1206
1240
|
return null;
|
|
1207
1241
|
}
|
|
@@ -104,6 +104,10 @@ function ToolLongRunningHintShell({
|
|
|
104
104
|
children: React.ReactNode;
|
|
105
105
|
}) {
|
|
106
106
|
const [showLongRunningHint, setShowLongRunningHint] = useState(false);
|
|
107
|
+
// useState initializer runs once at mount: a row that mounts already
|
|
108
|
+
// resolved never animates, while a tool appended during an active stream
|
|
109
|
+
// mounts running and animates in.
|
|
110
|
+
const [animateEntry] = useState(isRunning);
|
|
107
111
|
|
|
108
112
|
useEffect(() => {
|
|
109
113
|
if (!isRunning) {
|
|
@@ -118,14 +122,21 @@ function ToolLongRunningHintShell({
|
|
|
118
122
|
}, [isRunning, toolName]);
|
|
119
123
|
|
|
120
124
|
return (
|
|
121
|
-
|
|
125
|
+
<div
|
|
126
|
+
className={cn(
|
|
127
|
+
"agent-tool-call",
|
|
128
|
+
animateEntry &&
|
|
129
|
+
"motion-safe:animate-in motion-safe:fade-in-0 motion-safe:slide-in-from-bottom-1 motion-safe:duration-200 motion-safe:ease-[var(--ease-out-strong)]",
|
|
130
|
+
)}
|
|
131
|
+
data-running={isRunning ? "true" : undefined}
|
|
132
|
+
>
|
|
122
133
|
{children}
|
|
123
134
|
{isRunning && showLongRunningHint && (
|
|
124
135
|
<div className="mt-0.5 px-2.5 text-[11px] leading-snug text-muted-foreground/80">
|
|
125
136
|
Still working. Large updates can take a minute or two.
|
|
126
137
|
</div>
|
|
127
138
|
)}
|
|
128
|
-
|
|
139
|
+
</div>
|
|
129
140
|
);
|
|
130
141
|
}
|
|
131
142
|
|
|
@@ -542,6 +553,7 @@ export function ToolCallDisplay({
|
|
|
542
553
|
structuredMeta,
|
|
543
554
|
approval,
|
|
544
555
|
repeatCount,
|
|
556
|
+
isLatestRunning = isRunning,
|
|
545
557
|
}: {
|
|
546
558
|
toolName: string;
|
|
547
559
|
argsText?: string;
|
|
@@ -553,6 +565,7 @@ export function ToolCallDisplay({
|
|
|
553
565
|
structuredMeta?: Record<string, unknown>;
|
|
554
566
|
approval?: { approvalKey: string; dismissed?: boolean };
|
|
555
567
|
repeatCount?: number;
|
|
568
|
+
isLatestRunning?: boolean;
|
|
556
569
|
}) {
|
|
557
570
|
// Delegate to bespoke cells when structured metadata is present.
|
|
558
571
|
// These must be separate components so hook order in ToolCallDisplayGeneric
|
|
@@ -603,6 +616,7 @@ export function ToolCallDisplay({
|
|
|
603
616
|
mcpApp={mcpApp}
|
|
604
617
|
chatUI={chatUI}
|
|
605
618
|
isRunning={isRunning}
|
|
619
|
+
isLatestRunning={isLatestRunning}
|
|
606
620
|
approval={approval}
|
|
607
621
|
repeatCount={repeatCount}
|
|
608
622
|
/>,
|
|
@@ -617,6 +631,7 @@ function ToolCallDisplayGeneric({
|
|
|
617
631
|
mcpApp,
|
|
618
632
|
chatUI,
|
|
619
633
|
isRunning,
|
|
634
|
+
isLatestRunning,
|
|
620
635
|
approval,
|
|
621
636
|
repeatCount,
|
|
622
637
|
}: {
|
|
@@ -627,6 +642,7 @@ function ToolCallDisplayGeneric({
|
|
|
627
642
|
mcpApp?: AgentMcpAppPayload;
|
|
628
643
|
chatUI?: ActionChatUIConfig;
|
|
629
644
|
isRunning: boolean;
|
|
645
|
+
isLatestRunning: boolean;
|
|
630
646
|
approval?: { approvalKey: string; dismissed?: boolean };
|
|
631
647
|
repeatCount?: number;
|
|
632
648
|
}) {
|
|
@@ -786,7 +802,14 @@ function ToolCallDisplayGeneric({
|
|
|
786
802
|
</>
|
|
787
803
|
)}
|
|
788
804
|
</span>
|
|
789
|
-
<span
|
|
805
|
+
<span
|
|
806
|
+
className={cn(
|
|
807
|
+
"min-w-0 truncate font-normal",
|
|
808
|
+
isRunning && isLatestRunning && "agent-running-shimmer",
|
|
809
|
+
)}
|
|
810
|
+
>
|
|
811
|
+
{displayName}
|
|
812
|
+
</span>
|
|
790
813
|
{repeatCount && repeatCount > 1 && (
|
|
791
814
|
<span
|
|
792
815
|
className="shrink-0 rounded border border-border/60 px-1.5 py-0.5 text-[10px] leading-none text-muted-foreground"
|
|
@@ -864,6 +887,7 @@ export function ToolCallFallback({
|
|
|
864
887
|
activity?: boolean;
|
|
865
888
|
approval?: { approvalKey: string; dismissed?: boolean };
|
|
866
889
|
repeatCount?: number;
|
|
890
|
+
isLatestRunning?: boolean;
|
|
867
891
|
}) {
|
|
868
892
|
const chatRunning = React.useContext(ChatRunningContext);
|
|
869
893
|
const isRunning =
|
|
@@ -884,6 +908,7 @@ export function ToolCallFallback({
|
|
|
884
908
|
chatUI={rest.chatUI}
|
|
885
909
|
structuredMeta={rest.structuredMeta}
|
|
886
910
|
isRunning={isRunning}
|
|
911
|
+
isLatestRunning={rest.isLatestRunning}
|
|
887
912
|
approval={rest.approval}
|
|
888
913
|
repeatCount={rest.repeatCount}
|
|
889
914
|
/>
|
|
@@ -910,6 +935,15 @@ export function ReconnectStreamMessage({
|
|
|
910
935
|
content.at(-1)?.type === "text" ? content.length - 1 : -1;
|
|
911
936
|
const streamingReasoningPartIndex =
|
|
912
937
|
content.at(-1)?.type === "reasoning" ? content.length - 1 : -1;
|
|
938
|
+
const latestRunningToolIndex = content.reduce(
|
|
939
|
+
(latestIndex, part, index) =>
|
|
940
|
+
part.type === "tool-call" &&
|
|
941
|
+
part.result === undefined &&
|
|
942
|
+
(chatRunning || part.activity === true)
|
|
943
|
+
? index
|
|
944
|
+
: latestIndex,
|
|
945
|
+
-1,
|
|
946
|
+
);
|
|
913
947
|
|
|
914
948
|
const renderPart = (part: ContentPart, i: number) => {
|
|
915
949
|
if (part.type === "text") {
|
|
@@ -949,6 +983,7 @@ export function ReconnectStreamMessage({
|
|
|
949
983
|
isRunning={
|
|
950
984
|
part.result === undefined && (chatRunning || part.activity === true)
|
|
951
985
|
}
|
|
986
|
+
isLatestRunning={i === latestRunningToolIndex}
|
|
952
987
|
approval={part.approval}
|
|
953
988
|
repeatCount={part.repeatCount}
|
|
954
989
|
/>
|