@nocobase/app-plugin-agents 0.1.0-beta.8 → 1.0.0-beta.15
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/CHANGELOG.md +304 -0
- package/README.md +94 -51
- package/dist/client/api/client.d.ts +25 -19
- package/dist/client/api/client.d.ts.map +1 -1
- package/dist/client/api/client.js +23 -24
- package/dist/client/api/client.js.map +1 -1
- package/dist/client/api/keys.d.ts +4 -1
- package/dist/client/api/keys.d.ts.map +1 -1
- package/dist/client/api/keys.js +4 -1
- package/dist/client/api/keys.js.map +1 -1
- package/dist/client/api/runners.d.ts +8 -4
- package/dist/client/api/runners.d.ts.map +1 -1
- package/dist/client/api/runners.js +9 -0
- package/dist/client/api/runners.js.map +1 -1
- package/dist/client/chat/ai-form.d.ts +13 -0
- package/dist/client/chat/ai-form.d.ts.map +1 -0
- package/dist/client/chat/ai-form.js +57 -0
- package/dist/client/chat/ai-form.js.map +1 -0
- package/dist/client/chat/api.d.ts +16 -14
- package/dist/client/chat/api.d.ts.map +1 -1
- package/dist/client/chat/api.js +85 -18
- package/dist/client/chat/api.js.map +1 -1
- package/dist/client/chat/client-id.d.ts +3 -0
- package/dist/client/chat/client-id.d.ts.map +1 -0
- package/dist/client/chat/client-id.js +17 -0
- package/dist/client/chat/client-id.js.map +1 -0
- package/dist/client/chat/consultation-identity.d.ts +7 -0
- package/dist/client/chat/consultation-identity.d.ts.map +1 -0
- package/dist/client/chat/consultation-identity.js +39 -0
- package/dist/client/chat/consultation-identity.js.map +1 -0
- package/dist/client/chat/context-model.d.ts +21 -3
- package/dist/client/chat/context-model.d.ts.map +1 -1
- package/dist/client/chat/context-model.js +33 -4
- package/dist/client/chat/context-model.js.map +1 -1
- package/dist/client/chat/controller.d.ts +83 -0
- package/dist/client/chat/controller.d.ts.map +1 -0
- package/dist/client/chat/controller.js +767 -0
- package/dist/client/chat/controller.js.map +1 -0
- package/dist/client/chat/extensions.d.ts +8 -3
- package/dist/client/chat/extensions.d.ts.map +1 -1
- package/dist/client/chat/extensions.js.map +1 -1
- package/dist/client/chat/feedback.d.ts +18 -0
- package/dist/client/chat/feedback.d.ts.map +1 -0
- package/dist/client/chat/feedback.js +38 -0
- package/dist/client/chat/feedback.js.map +1 -0
- package/dist/client/chat/form-registry.d.ts +95 -0
- package/dist/client/chat/form-registry.d.ts.map +1 -0
- package/dist/client/chat/form-registry.js +384 -0
- package/dist/client/chat/form-registry.js.map +1 -0
- package/dist/client/chat/keys.d.ts +1 -0
- package/dist/client/chat/keys.d.ts.map +1 -1
- package/dist/client/chat/keys.js +3 -1
- package/dist/client/chat/keys.js.map +1 -1
- package/dist/client/chat/message-model.d.ts +38 -44
- package/dist/client/chat/message-model.d.ts.map +1 -1
- package/dist/client/chat/message-model.js +138 -56
- package/dist/client/chat/message-model.js.map +1 -1
- package/dist/client/chat/provider.d.ts +12 -2
- package/dist/client/chat/provider.d.ts.map +1 -1
- package/dist/client/chat/provider.js +130 -4
- package/dist/client/chat/provider.js.map +1 -1
- package/dist/client/chat/submissions.d.ts +67 -0
- package/dist/client/chat/submissions.d.ts.map +1 -0
- package/dist/client/chat/submissions.js +241 -0
- package/dist/client/chat/submissions.js.map +1 -0
- package/dist/client/chat/tool-renderer.d.ts +39 -0
- package/dist/client/chat/tool-renderer.d.ts.map +1 -0
- package/dist/client/chat/tool-renderer.js +27 -0
- package/dist/client/chat/tool-renderer.js.map +1 -0
- package/dist/client/chat/use-chat-scroll.d.ts +4 -0
- package/dist/client/chat/use-chat-scroll.d.ts.map +1 -0
- package/dist/client/chat/use-chat-scroll.js +73 -0
- package/dist/client/chat/use-chat-scroll.js.map +1 -0
- package/dist/client/chat/use-chat.d.ts +13 -24
- package/dist/client/chat/use-chat.d.ts.map +1 -1
- package/dist/client/chat/use-chat.js +250 -235
- package/dist/client/chat/use-chat.js.map +1 -1
- package/dist/client/chat.d.ts +20 -8
- package/dist/client/chat.d.ts.map +1 -1
- package/dist/client/chat.js +16 -4
- package/dist/client/chat.js.map +1 -1
- package/dist/client/components/agent-picker.d.ts +6 -23
- package/dist/client/components/agent-picker.d.ts.map +1 -1
- package/dist/client/components/agent-picker.js +20 -39
- package/dist/client/components/agent-picker.js.map +1 -1
- package/dist/client/components/quota-status.d.ts +16 -0
- package/dist/client/components/quota-status.d.ts.map +1 -0
- package/dist/client/components/quota-status.js +39 -0
- package/dist/client/components/quota-status.js.map +1 -0
- package/dist/client/components/runners-refresh.d.ts.map +1 -1
- package/dist/client/components/runners-refresh.js +1 -0
- package/dist/client/components/runners-refresh.js.map +1 -1
- package/dist/client/components/variables/variable-dialogs.d.ts.map +1 -1
- package/dist/client/components/variables/variable-dialogs.js +7 -7
- package/dist/client/components/variables/variable-dialogs.js.map +1 -1
- package/dist/client/config.d.ts +2 -0
- package/dist/client/config.d.ts.map +1 -1
- package/dist/client/config.js +2 -0
- package/dist/client/config.js.map +1 -1
- package/dist/client/hooks/use-agent-picker-labels.d.ts.map +1 -1
- package/dist/client/hooks/use-agent-picker-labels.js +4 -12
- package/dist/client/hooks/use-agent-picker-labels.js.map +1 -1
- package/dist/client/hooks/use-quota-expiry.d.ts +7 -0
- package/dist/client/hooks/use-quota-expiry.d.ts.map +1 -0
- package/dist/client/hooks/use-quota-expiry.js +92 -0
- package/dist/client/hooks/use-quota-expiry.js.map +1 -0
- package/dist/client/hooks/use-realtime-topic.d.ts +1 -4
- package/dist/client/hooks/use-realtime-topic.d.ts.map +1 -1
- package/dist/client/hooks/use-realtime-topic.js +7 -11
- package/dist/client/hooks/use-realtime-topic.js.map +1 -1
- package/dist/client/kit.d.ts +14 -12
- package/dist/client/kit.d.ts.map +1 -1
- package/dist/client/kit.js +37 -14
- package/dist/client/kit.js.map +1 -1
- package/dist/client/lib/agents.d.ts +5 -18
- package/dist/client/lib/agents.d.ts.map +1 -1
- package/dist/client/lib/agents.js +18 -55
- package/dist/client/lib/agents.js.map +1 -1
- package/dist/client/lib/format.d.ts +3 -1
- package/dist/client/lib/format.d.ts.map +1 -1
- package/dist/client/lib/format.js +25 -0
- package/dist/client/lib/format.js.map +1 -1
- package/dist/client/lib/skill-settings-context.d.ts +9 -0
- package/dist/client/lib/skill-settings-context.d.ts.map +1 -0
- package/dist/client/lib/skill-settings-context.js +4 -0
- package/dist/client/lib/skill-settings-context.js.map +1 -0
- package/dist/client/lib/skill-settings.d.ts +12 -0
- package/dist/client/lib/skill-settings.d.ts.map +1 -0
- package/dist/client/lib/skill-settings.js +37 -0
- package/dist/client/lib/skill-settings.js.map +1 -0
- package/dist/client/locales/chat.en-US.d.ts +8 -27
- package/dist/client/locales/chat.en-US.d.ts.map +1 -1
- package/dist/client/locales/chat.en-US.js +12 -30
- package/dist/client/locales/chat.en-US.js.map +1 -1
- package/dist/client/locales/chat.zh-CN.d.ts.map +1 -1
- package/dist/client/locales/chat.zh-CN.js +9 -27
- package/dist/client/locales/chat.zh-CN.js.map +1 -1
- package/dist/client/locales/en-US.d.ts +87 -217
- package/dist/client/locales/en-US.d.ts.map +1 -1
- package/dist/client/locales/en-US.js +92 -218
- package/dist/client/locales/en-US.js.map +1 -1
- package/dist/client/locales/runWait.en-US.d.ts +7 -0
- package/dist/client/locales/runWait.en-US.d.ts.map +1 -1
- package/dist/client/locales/runWait.en-US.js +10 -3
- package/dist/client/locales/runWait.en-US.js.map +1 -1
- package/dist/client/locales/runWait.zh-CN.d.ts +1 -1
- package/dist/client/locales/runWait.zh-CN.d.ts.map +1 -1
- package/dist/client/locales/runWait.zh-CN.js +11 -4
- package/dist/client/locales/runWait.zh-CN.js.map +1 -1
- package/dist/client/locales/runtimes.en-US.d.ts +83 -0
- package/dist/client/locales/runtimes.en-US.d.ts.map +1 -1
- package/dist/client/locales/runtimes.en-US.js +84 -1
- package/dist/client/locales/runtimes.en-US.js.map +1 -1
- package/dist/client/locales/runtimes.zh-CN.d.ts.map +1 -1
- package/dist/client/locales/runtimes.zh-CN.js +83 -0
- package/dist/client/locales/runtimes.zh-CN.js.map +1 -1
- package/dist/client/locales/skills.en-US.d.ts +7 -0
- package/dist/client/locales/skills.en-US.d.ts.map +1 -1
- package/dist/client/locales/skills.en-US.js +8 -1
- package/dist/client/locales/skills.en-US.js.map +1 -1
- package/dist/client/locales/skills.zh-CN.d.ts.map +1 -1
- package/dist/client/locales/skills.zh-CN.js +8 -1
- package/dist/client/locales/skills.zh-CN.js.map +1 -1
- package/dist/client/locales/zh-CN.d.ts.map +1 -1
- package/dist/client/locales/zh-CN.js +94 -220
- package/dist/client/locales/zh-CN.js.map +1 -1
- package/dist/client/online/services.d.ts.map +1 -1
- package/dist/client/online/services.js +5 -6
- package/dist/client/online/services.js.map +1 -1
- package/dist/client/pages/agents/agent-dialog.d.ts +9 -0
- package/dist/client/pages/agents/agent-dialog.d.ts.map +1 -0
- package/dist/client/pages/agents/agent-dialog.js +106 -0
- package/dist/client/pages/agents/agent-dialog.js.map +1 -0
- package/dist/client/pages/agents/agent-state.d.ts +11 -0
- package/dist/client/pages/agents/agent-state.d.ts.map +1 -0
- package/dist/client/pages/agents/agent-state.js +28 -0
- package/dist/client/pages/agents/agent-state.js.map +1 -0
- package/dist/client/pages/agents/index.d.ts +1 -1
- package/dist/client/pages/agents/index.d.ts.map +1 -1
- package/dist/client/pages/agents/index.js +7 -101
- package/dist/client/pages/agents/index.js.map +1 -1
- package/dist/client/pages/agents/runner-agents.d.ts +3 -0
- package/dist/client/pages/agents/runner-agents.d.ts.map +1 -0
- package/dist/client/pages/agents/runner-agents.js +185 -0
- package/dist/client/pages/agents/runner-agents.js.map +1 -0
- package/dist/client/pages/runtimes/connect.js.map +1 -1
- package/dist/client/pages/runtimes/index.d.ts.map +1 -1
- package/dist/client/pages/runtimes/index.js +1 -1
- package/dist/client/pages/runtimes/index.js.map +1 -1
- package/dist/client/pages/runtimes/quota-targets.d.ts +4 -0
- package/dist/client/pages/runtimes/quota-targets.d.ts.map +1 -0
- package/dist/client/pages/runtimes/quota-targets.js +18 -0
- package/dist/client/pages/runtimes/quota-targets.js.map +1 -0
- package/dist/client/pages/runtimes/quota.d.ts +17 -0
- package/dist/client/pages/runtimes/quota.d.ts.map +1 -0
- package/dist/client/pages/runtimes/quota.js +50 -0
- package/dist/client/pages/runtimes/quota.js.map +1 -0
- package/dist/client/pages/runtimes/runner-cells.d.ts +11 -4
- package/dist/client/pages/runtimes/runner-cells.d.ts.map +1 -1
- package/dist/client/pages/runtimes/runner-cells.js +6 -3
- package/dist/client/pages/runtimes/runner-cells.js.map +1 -1
- package/dist/client/pages/runtimes/runner-overview.d.ts +9 -0
- package/dist/client/pages/runtimes/runner-overview.d.ts.map +1 -0
- package/dist/client/pages/runtimes/runner-overview.js +109 -0
- package/dist/client/pages/runtimes/runner-overview.js.map +1 -0
- package/dist/client/pages/runtimes/runner-runs.d.ts +5 -0
- package/dist/client/pages/runtimes/runner-runs.d.ts.map +1 -0
- package/dist/client/pages/runtimes/runner-runs.js +35 -0
- package/dist/client/pages/runtimes/runner-runs.js.map +1 -0
- package/dist/client/pages/runtimes/runner-sheet.d.ts +2 -3
- package/dist/client/pages/runtimes/runner-sheet.d.ts.map +1 -1
- package/dist/client/pages/runtimes/runner-sheet.js +43 -171
- package/dist/client/pages/runtimes/runner-sheet.js.map +1 -1
- package/dist/client/pages/runtimes/runner-tools.d.ts +17 -0
- package/dist/client/pages/runtimes/runner-tools.d.ts.map +1 -0
- package/dist/client/pages/runtimes/runner-tools.js +75 -0
- package/dist/client/pages/runtimes/runner-tools.js.map +1 -0
- package/dist/client/pages/runtimes/runner-workspaces.d.ts +6 -0
- package/dist/client/pages/runtimes/runner-workspaces.d.ts.map +1 -0
- package/dist/client/pages/runtimes/runner-workspaces.js +37 -0
- package/dist/client/pages/runtimes/runner-workspaces.js.map +1 -0
- package/dist/client/pages/runtimes/tool-slots-fields.js +1 -1
- package/dist/client/pages/runtimes/tool-slots-fields.js.map +1 -1
- package/dist/client/pages/runtimes/workspace-diagnostics.d.ts +6 -4
- package/dist/client/pages/runtimes/workspace-diagnostics.d.ts.map +1 -1
- package/dist/client/pages/runtimes/workspace-diagnostics.js +67 -33
- package/dist/client/pages/runtimes/workspace-diagnostics.js.map +1 -1
- package/dist/client/pages/skills/detail/index.d.ts.map +1 -1
- package/dist/client/pages/skills/detail/index.js +11 -15
- package/dist/client/pages/skills/detail/index.js.map +1 -1
- package/dist/client/pages/skills/index.d.ts.map +1 -1
- package/dist/client/pages/skills/index.js +2 -2
- package/dist/client/pages/skills/index.js.map +1 -1
- package/dist/client/pages/usage/index.js +2 -2
- package/dist/client/pages/usage/index.js.map +1 -1
- package/dist/client/profile/default-agent.d.ts.map +1 -1
- package/dist/client/profile/default-agent.js +2 -4
- package/dist/client/profile/default-agent.js.map +1 -1
- package/dist/client/routes.d.ts +1 -1
- package/dist/client/routes.d.ts.map +1 -1
- package/dist/client/routes.js +1 -13
- package/dist/client/routes.js.map +1 -1
- package/dist/client/runs/format-wait.d.ts.map +1 -1
- package/dist/client/runs/format-wait.js +15 -1
- package/dist/client/runs/format-wait.js.map +1 -1
- package/dist/client/runs/subject-runs.d.ts +5 -0
- package/dist/client/runs/subject-runs.d.ts.map +1 -1
- package/dist/client/runs/subject-runs.js +24 -9
- package/dist/client/runs/subject-runs.js.map +1 -1
- package/dist/client/runs/use-run-events.d.ts +1 -1
- package/dist/client/runs/use-run-events.d.ts.map +1 -1
- package/dist/client/runs/use-run-events.js +5 -2
- package/dist/client/runs/use-run-events.js.map +1 -1
- package/dist/client/runs.d.ts +1 -1
- package/dist/client/runs.d.ts.map +1 -1
- package/dist/client/runs.js +1 -1
- package/dist/client/runs.js.map +1 -1
- package/dist/database/migrations/.manifest.json +42 -2
- package/dist/database/migrations/202610020003_ag_create_runs.d.ts.map +1 -1
- package/dist/database/migrations/202610020003_ag_create_runs.js +0 -1
- package/dist/database/migrations/202610020003_ag_create_runs.js.map +1 -1
- package/dist/database/migrations/202610120001_ag_index_run_retries.d.ts +4 -0
- package/dist/database/migrations/202610120001_ag_index_run_retries.d.ts.map +1 -0
- package/dist/database/migrations/202610120001_ag_index_run_retries.js +17 -0
- package/dist/database/migrations/202610120001_ag_index_run_retries.js.map +1 -0
- package/dist/database/migrations/202610120002_ag_add_queue_entered_at.d.ts +4 -0
- package/dist/database/migrations/202610120002_ag_add_queue_entered_at.d.ts.map +1 -0
- package/dist/database/migrations/202610120002_ag_add_queue_entered_at.js +50 -0
- package/dist/database/migrations/202610120002_ag_add_queue_entered_at.js.map +1 -0
- package/dist/database/migrations/202610170001_ag_runner_quota.d.ts +4 -0
- package/dist/database/migrations/202610170001_ag_runner_quota.d.ts.map +1 -0
- package/dist/database/migrations/202610170001_ag_runner_quota.js +19 -0
- package/dist/database/migrations/202610170001_ag_runner_quota.js.map +1 -0
- package/dist/database/migrations/202610240020_ag_runner_agents.d.ts +4 -0
- package/dist/database/migrations/202610240020_ag_runner_agents.d.ts.map +1 -0
- package/dist/database/migrations/202610240020_ag_runner_agents.js +115 -0
- package/dist/database/migrations/202610240020_ag_runner_agents.js.map +1 -0
- package/dist/database/migrations/202610240040_ag_discovery_preferences.d.ts +4 -0
- package/dist/database/migrations/202610240040_ag_discovery_preferences.d.ts.map +1 -0
- package/dist/database/migrations/202610240040_ag_discovery_preferences.js +18 -0
- package/dist/database/migrations/202610240040_ag_discovery_preferences.js.map +1 -0
- package/dist/database/migrations/202610250001_ag_comment_runner_consent.d.ts +4 -0
- package/dist/database/migrations/202610250001_ag_comment_runner_consent.d.ts.map +1 -0
- package/dist/database/migrations/202610250001_ag_comment_runner_consent.js +41 -0
- package/dist/database/migrations/202610250001_ag_comment_runner_consent.js.map +1 -0
- package/dist/database/migrations/202610260001_ag_drop_directory_index.d.ts +4 -0
- package/dist/database/migrations/202610260001_ag_drop_directory_index.d.ts.map +1 -0
- package/dist/database/migrations/202610260001_ag_drop_directory_index.js +24 -0
- package/dist/database/migrations/202610260001_ag_drop_directory_index.js.map +1 -0
- package/dist/database/migrations/202610260001_ag_run_revision.d.ts +4 -0
- package/dist/database/migrations/202610260001_ag_run_revision.d.ts.map +1 -0
- package/dist/database/migrations/202610260001_ag_run_revision.js +19 -0
- package/dist/database/migrations/202610260001_ag_run_revision.js.map +1 -0
- package/dist/database/migrations/202610270001_ag_online_agent.d.ts +4 -0
- package/dist/database/migrations/202610270001_ag_online_agent.d.ts.map +1 -0
- package/dist/database/migrations/202610270001_ag_online_agent.js +43 -0
- package/dist/database/migrations/202610270001_ag_online_agent.js.map +1 -0
- package/dist/database/migrations/202610270002_ag_chat_list_visibility.d.ts +4 -0
- package/dist/database/migrations/202610270002_ag_chat_list_visibility.d.ts.map +1 -0
- package/dist/database/migrations/202610270002_ag_chat_list_visibility.js +17 -0
- package/dist/database/migrations/202610270002_ag_chat_list_visibility.js.map +1 -0
- package/dist/package.json +34 -12
- package/dist/server/cli/run-credential.js +1 -1
- package/dist/server/cli/surface.d.ts.map +1 -1
- package/dist/server/cli/surface.js +4 -1
- package/dist/server/cli/surface.js.map +1 -1
- package/dist/server/composition.d.ts +36 -35
- package/dist/server/composition.d.ts.map +1 -1
- package/dist/server/composition.js +99 -66
- package/dist/server/composition.js.map +1 -1
- package/dist/server/core/agents/agent.service.d.ts +51 -43
- package/dist/server/core/agents/agent.service.d.ts.map +1 -1
- package/dist/server/core/agents/agent.service.js +347 -321
- package/dist/server/core/agents/agent.service.js.map +1 -1
- package/dist/server/core/agents/agent.store.d.ts +26 -12
- package/dist/server/core/agents/agent.store.d.ts.map +1 -1
- package/dist/server/core/agents/agent.store.js +74 -66
- package/dist/server/core/agents/agent.store.js.map +1 -1
- package/dist/server/core/agents/agent.views.d.ts +29 -0
- package/dist/server/core/agents/agent.views.d.ts.map +1 -0
- package/dist/server/core/agents/agent.views.js +88 -0
- package/dist/server/core/agents/agent.views.js.map +1 -0
- package/dist/server/core/agents/discovery.d.ts +12 -0
- package/dist/server/core/agents/discovery.d.ts.map +1 -0
- package/dist/server/core/agents/discovery.js +39 -0
- package/dist/server/core/agents/discovery.js.map +1 -0
- package/dist/server/core/agents/index.d.ts +3 -2
- package/dist/server/core/agents/index.d.ts.map +1 -1
- package/dist/server/core/agents/index.js +3 -2
- package/dist/server/core/agents/index.js.map +1 -1
- package/dist/server/core/brief/brief.js +3 -3
- package/dist/server/core/brief/brief.js.map +1 -1
- package/dist/server/core/callers/index.d.ts +10 -1
- package/dist/server/core/callers/index.d.ts.map +1 -1
- package/dist/server/core/callers/index.js +15 -0
- package/dist/server/core/callers/index.js.map +1 -1
- package/dist/server/core/conversations/attachments.d.ts.map +1 -1
- package/dist/server/core/conversations/attachments.js +6 -1
- package/dist/server/core/conversations/attachments.js.map +1 -1
- package/dist/server/core/conversations/availability.d.ts +6 -11
- package/dist/server/core/conversations/availability.d.ts.map +1 -1
- package/dist/server/core/conversations/availability.js +11 -15
- package/dist/server/core/conversations/availability.js.map +1 -1
- package/dist/server/core/conversations/chat-settings.d.ts +2 -2
- package/dist/server/core/conversations/chat-settings.d.ts.map +1 -1
- package/dist/server/core/conversations/chat-settings.js +17 -22
- package/dist/server/core/conversations/chat-settings.js.map +1 -1
- package/dist/server/core/conversations/conversation.service.d.ts +13 -8
- package/dist/server/core/conversations/conversation.service.d.ts.map +1 -1
- package/dist/server/core/conversations/conversation.service.js +397 -383
- package/dist/server/core/conversations/conversation.service.js.map +1 -1
- package/dist/server/core/conversations/conversation.store.d.ts +3 -0
- package/dist/server/core/conversations/conversation.store.d.ts.map +1 -1
- package/dist/server/core/conversations/conversation.store.js +2 -1
- package/dist/server/core/conversations/conversation.store.js.map +1 -1
- package/dist/server/core/conversations/page-context.d.ts +8 -2
- package/dist/server/core/conversations/page-context.d.ts.map +1 -1
- package/dist/server/core/conversations/page-context.js +61 -2
- package/dist/server/core/conversations/page-context.js.map +1 -1
- package/dist/server/core/conversations/ports.d.ts +18 -20
- package/dist/server/core/conversations/ports.d.ts.map +1 -1
- package/dist/server/core/reports/model-usage.d.ts.map +1 -1
- package/dist/server/core/reports/model-usage.js +42 -44
- package/dist/server/core/reports/model-usage.js.map +1 -1
- package/dist/server/core/reports/prices.d.ts.map +1 -1
- package/dist/server/core/reports/prices.js +29 -5
- package/dist/server/core/reports/prices.js.map +1 -1
- package/dist/server/core/reports/report.service.d.ts +4 -2
- package/dist/server/core/reports/report.service.d.ts.map +1 -1
- package/dist/server/core/reports/report.service.js +148 -66
- package/dist/server/core/reports/report.service.js.map +1 -1
- package/dist/server/core/runs/access.d.ts +5 -0
- package/dist/server/core/runs/access.d.ts.map +1 -0
- package/dist/server/core/runs/access.js +10 -0
- package/dist/server/core/runs/access.js.map +1 -0
- package/dist/server/core/runs/availability.d.ts +18 -6
- package/dist/server/core/runs/availability.d.ts.map +1 -1
- package/dist/server/core/runs/availability.js +40 -34
- package/dist/server/core/runs/availability.js.map +1 -1
- package/dist/server/core/runs/claim.d.ts +30 -106
- package/dist/server/core/runs/claim.d.ts.map +1 -1
- package/dist/server/core/runs/claim.js +630 -323
- package/dist/server/core/runs/claim.js.map +1 -1
- package/dist/server/core/runs/comment-consent.d.ts +24 -0
- package/dist/server/core/runs/comment-consent.d.ts.map +1 -0
- package/dist/server/core/runs/comment-consent.js +116 -0
- package/dist/server/core/runs/comment-consent.js.map +1 -0
- package/dist/server/core/runs/eligibility.d.ts +13 -1
- package/dist/server/core/runs/eligibility.d.ts.map +1 -1
- package/dist/server/core/runs/eligibility.js +41 -10
- package/dist/server/core/runs/eligibility.js.map +1 -1
- package/dist/server/core/runs/execution-view.d.ts +8 -0
- package/dist/server/core/runs/execution-view.d.ts.map +1 -1
- package/dist/server/core/runs/execution-view.js +9 -0
- package/dist/server/core/runs/execution-view.js.map +1 -1
- package/dist/server/core/runs/execution.d.ts +1 -1
- package/dist/server/core/runs/execution.d.ts.map +1 -1
- package/dist/server/core/runs/execution.js +8 -2
- package/dist/server/core/runs/execution.js.map +1 -1
- package/dist/server/core/runs/identity.d.ts +9 -0
- package/dist/server/core/runs/identity.d.ts.map +1 -0
- package/dist/server/core/runs/identity.js +75 -0
- package/dist/server/core/runs/identity.js.map +1 -0
- package/dist/server/core/runs/index.d.ts +6 -6
- package/dist/server/core/runs/index.d.ts.map +1 -1
- package/dist/server/core/runs/index.js +6 -6
- package/dist/server/core/runs/index.js.map +1 -1
- package/dist/server/core/runs/input-gate.d.ts +1 -1
- package/dist/server/core/runs/input-gate.d.ts.map +1 -1
- package/dist/server/core/runs/input-gate.js +4 -2
- package/dist/server/core/runs/input-gate.js.map +1 -1
- package/dist/server/core/runs/lifecycle.d.ts +16 -18
- package/dist/server/core/runs/lifecycle.d.ts.map +1 -1
- package/dist/server/core/runs/lifecycle.js +146 -60
- package/dist/server/core/runs/lifecycle.js.map +1 -1
- package/dist/server/core/runs/policy.d.ts +9 -2
- package/dist/server/core/runs/policy.d.ts.map +1 -1
- package/dist/server/core/runs/policy.js +17 -8
- package/dist/server/core/runs/policy.js.map +1 -1
- package/dist/server/core/runs/ports.d.ts +41 -31
- package/dist/server/core/runs/ports.d.ts.map +1 -1
- package/dist/server/core/runs/ports.js +2 -13
- package/dist/server/core/runs/ports.js.map +1 -1
- package/dist/server/core/runs/preview.d.ts.map +1 -1
- package/dist/server/core/runs/preview.js +1 -3
- package/dist/server/core/runs/preview.js.map +1 -1
- package/dist/server/core/runs/run-data-purge.d.ts +15 -0
- package/dist/server/core/runs/run-data-purge.d.ts.map +1 -0
- package/dist/server/core/runs/run-data-purge.js +82 -0
- package/dist/server/core/runs/run-data-purge.js.map +1 -0
- package/dist/server/core/runs/run-requests.d.ts +25 -0
- package/dist/server/core/runs/run-requests.d.ts.map +1 -1
- package/dist/server/core/runs/run-requests.js +131 -64
- package/dist/server/core/runs/run-requests.js.map +1 -1
- package/dist/server/core/runs/run.service.d.ts +39 -3
- package/dist/server/core/runs/run.service.d.ts.map +1 -1
- package/dist/server/core/runs/run.service.js +729 -102
- package/dist/server/core/runs/run.service.js.map +1 -1
- package/dist/server/core/runs/run.store.d.ts +11 -0
- package/dist/server/core/runs/run.store.d.ts.map +1 -1
- package/dist/server/core/runs/run.store.js +39 -11
- package/dist/server/core/runs/run.store.js.map +1 -1
- package/dist/server/core/runs/runner-view.d.ts +12 -2
- package/dist/server/core/runs/runner-view.d.ts.map +1 -1
- package/dist/server/core/runs/runner-view.js +55 -13
- package/dist/server/core/runs/runner-view.js.map +1 -1
- package/dist/server/core/runs/selection.d.ts +13 -0
- package/dist/server/core/runs/selection.d.ts.map +1 -0
- package/dist/server/core/runs/selection.js +21 -0
- package/dist/server/core/runs/selection.js.map +1 -0
- package/dist/server/core/runs/sweeper.d.ts +1 -0
- package/dist/server/core/runs/sweeper.d.ts.map +1 -1
- package/dist/server/core/runs/sweeper.js +66 -17
- package/dist/server/core/runs/sweeper.js.map +1 -1
- package/dist/server/core/runs/transitions.d.ts +6 -2
- package/dist/server/core/runs/transitions.d.ts.map +1 -1
- package/dist/server/core/runs/transitions.js +73 -19
- package/dist/server/core/runs/transitions.js.map +1 -1
- package/dist/server/core/runs/workload.d.ts +17 -5
- package/dist/server/core/runs/workload.d.ts.map +1 -1
- package/dist/server/core/runs/workload.js +203 -68
- package/dist/server/core/runs/workload.js.map +1 -1
- package/dist/server/core/skills/skill.service.d.ts +6 -2
- package/dist/server/core/skills/skill.service.d.ts.map +1 -1
- package/dist/server/core/skills/skill.service.js +87 -66
- package/dist/server/core/skills/skill.service.js.map +1 -1
- package/dist/server/core/skills/skill.store.d.ts +14 -0
- package/dist/server/core/skills/skill.store.d.ts.map +1 -1
- package/dist/server/core/skills/skill.store.js +30 -0
- package/dist/server/core/skills/skill.store.js.map +1 -1
- package/dist/server/core/transaction-read.d.ts +4 -0
- package/dist/server/core/transaction-read.d.ts.map +1 -0
- package/dist/server/core/transaction-read.js +30 -0
- package/dist/server/core/transaction-read.js.map +1 -0
- package/dist/server/core/variables/index.d.ts +1 -1
- package/dist/server/core/variables/index.d.ts.map +1 -1
- package/dist/server/core/variables/index.js.map +1 -1
- package/dist/server/core/variables/variable.service.d.ts +18 -0
- package/dist/server/core/variables/variable.service.d.ts.map +1 -1
- package/dist/server/core/variables/variable.service.js +95 -20
- package/dist/server/core/variables/variable.service.js.map +1 -1
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/jobs/job.service.d.ts +1 -1
- package/dist/server/jobs/job.service.d.ts.map +1 -1
- package/dist/server/jobs/job.service.js +8 -2
- package/dist/server/jobs/job.service.js.map +1 -1
- package/dist/server/kernel/events.d.ts +12 -3
- package/dist/server/kernel/events.d.ts.map +1 -1
- package/dist/server/kernel/events.js.map +1 -1
- package/dist/server/kernel/scopes.d.ts +6 -0
- package/dist/server/kernel/scopes.d.ts.map +1 -1
- package/dist/server/kernel/scopes.js +3 -1
- package/dist/server/kernel/scopes.js.map +1 -1
- package/dist/server/online/agent/configuration.d.ts +26 -0
- package/dist/server/online/agent/configuration.d.ts.map +1 -0
- package/dist/server/online/agent/configuration.js +261 -0
- package/dist/server/online/agent/configuration.js.map +1 -0
- package/dist/server/online/agent/contracts.d.ts +87 -0
- package/dist/server/online/agent/contracts.d.ts.map +1 -0
- package/dist/server/online/agent/contracts.js +2 -0
- package/dist/server/online/agent/contracts.js.map +1 -0
- package/dist/server/online/agent/errors.d.ts +11 -0
- package/dist/server/online/agent/errors.d.ts.map +1 -0
- package/dist/server/online/agent/errors.js +21 -0
- package/dist/server/online/agent/errors.js.map +1 -0
- package/dist/server/online/agent/index.d.ts +11 -0
- package/dist/server/online/agent/index.d.ts.map +1 -0
- package/dist/server/online/agent/index.js +9 -0
- package/dist/server/online/agent/index.js.map +1 -0
- package/dist/server/online/agent/messages/json.d.ts +5 -0
- package/dist/server/online/agent/messages/json.d.ts.map +1 -0
- package/dist/server/online/agent/messages/json.js +88 -0
- package/dist/server/online/agent/messages/json.js.map +1 -0
- package/dist/server/online/agent/messages/projection.d.ts +20 -0
- package/dist/server/online/agent/messages/projection.d.ts.map +1 -0
- package/dist/server/online/agent/messages/projection.js +495 -0
- package/dist/server/online/agent/messages/projection.js.map +1 -0
- package/dist/server/online/agent/messages/validation.d.ts +7 -0
- package/dist/server/online/agent/messages/validation.d.ts.map +1 -0
- package/dist/server/online/agent/messages/validation.js +159 -0
- package/dist/server/online/agent/messages/validation.js.map +1 -0
- package/dist/server/online/agent/native/backend.d.ts +60 -0
- package/dist/server/online/agent/native/backend.d.ts.map +1 -0
- package/dist/server/online/agent/native/backend.js +411 -0
- package/dist/server/online/agent/native/backend.js.map +1 -0
- package/dist/server/online/agent/native/execution.d.ts +41 -0
- package/dist/server/online/agent/native/execution.d.ts.map +1 -0
- package/dist/server/online/agent/native/execution.js +430 -0
- package/dist/server/online/agent/native/execution.js.map +1 -0
- package/dist/server/online/agent/native/session.d.ts +40 -0
- package/dist/server/online/agent/native/session.d.ts.map +1 -0
- package/dist/server/online/agent/native/session.js +104 -0
- package/dist/server/online/agent/native/session.js.map +1 -0
- package/dist/server/online/agent/native/types.d.ts +32 -0
- package/dist/server/online/agent/native/types.d.ts.map +1 -0
- package/dist/server/online/agent/native/types.js +2 -0
- package/dist/server/online/agent/native/types.js.map +1 -0
- package/dist/server/online/agent/persistence/manager.d.ts +16 -0
- package/dist/server/online/agent/persistence/manager.d.ts.map +1 -0
- package/dist/server/online/agent/persistence/manager.js +209 -0
- package/dist/server/online/agent/persistence/manager.js.map +1 -0
- package/dist/server/online/agent/persistence/state.d.ts +11 -0
- package/dist/server/online/agent/persistence/state.d.ts.map +1 -0
- package/dist/server/online/agent/persistence/state.js +45 -0
- package/dist/server/online/agent/persistence/state.js.map +1 -0
- package/dist/server/online/agent/persistence/store.d.ts +58 -0
- package/dist/server/online/agent/persistence/store.d.ts.map +1 -0
- package/dist/server/online/agent/persistence/store.js +634 -0
- package/dist/server/online/agent/persistence/store.js.map +1 -0
- package/dist/server/online/agent/persistence/types.d.ts +44 -0
- package/dist/server/online/agent/persistence/types.d.ts.map +1 -0
- package/dist/server/online/agent/persistence/types.js +2 -0
- package/dist/server/online/agent/persistence/types.js.map +1 -0
- package/dist/server/online/agent/runner/backend.d.ts +57 -0
- package/dist/server/online/agent/runner/backend.d.ts.map +1 -0
- package/dist/server/online/agent/runner/backend.js +501 -0
- package/dist/server/online/agent/runner/backend.js.map +1 -0
- package/dist/server/online/agent/runner/projection.d.ts +10 -0
- package/dist/server/online/agent/runner/projection.d.ts.map +1 -0
- package/dist/server/online/agent/runner/projection.js +171 -0
- package/dist/server/online/agent/runner/projection.js.map +1 -0
- package/dist/server/online/agent/runner/types.d.ts +44 -0
- package/dist/server/online/agent/runner/types.d.ts.map +1 -0
- package/dist/server/online/agent/runner/types.js +2 -0
- package/dist/server/online/agent/runner/types.js.map +1 -0
- package/dist/server/online/agent/service.d.ts +47 -0
- package/dist/server/online/agent/service.d.ts.map +1 -0
- package/dist/server/online/agent/service.js +111 -0
- package/dist/server/online/agent/service.js.map +1 -0
- package/dist/server/online/agent/transport/streams.d.ts +54 -0
- package/dist/server/online/agent/transport/streams.d.ts.map +1 -0
- package/dist/server/online/agent/transport/streams.js +440 -0
- package/dist/server/online/agent/transport/streams.js.map +1 -0
- package/dist/server/online/agent/types.d.ts +155 -0
- package/dist/server/online/agent/types.d.ts.map +1 -0
- package/dist/server/online/agent/types.js +2 -0
- package/dist/server/online/agent/types.js.map +1 -0
- package/dist/server/online/index.d.ts +0 -5
- package/dist/server/online/index.d.ts.map +1 -1
- package/dist/server/online/index.js +0 -5
- package/dist/server/online/index.js.map +1 -1
- package/dist/server/online/providers.d.ts.map +1 -1
- package/dist/server/online/providers.js +26 -2
- package/dist/server/online/providers.js.map +1 -1
- package/dist/server/online/routes.d.ts.map +1 -1
- package/dist/server/online/routes.js +6 -35
- package/dist/server/online/routes.js.map +1 -1
- package/dist/server/online/services.d.ts.map +1 -1
- package/dist/server/online/services.js +101 -24
- package/dist/server/online/services.js.map +1 -1
- package/dist/server/providers/agents.d.ts +18 -25
- package/dist/server/providers/agents.d.ts.map +1 -1
- package/dist/server/providers/agents.js +79 -100
- package/dist/server/providers/agents.js.map +1 -1
- package/dist/server/providers/runners.d.ts +3 -1
- package/dist/server/providers/runners.d.ts.map +1 -1
- package/dist/server/providers/runners.js +38 -9
- package/dist/server/providers/runners.js.map +1 -1
- package/dist/server/routes/admin.d.ts +4 -0
- package/dist/server/routes/admin.d.ts.map +1 -1
- package/dist/server/routes/admin.js +139 -212
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/chat.d.ts.map +1 -1
- package/dist/server/routes/chat.js +313 -164
- package/dist/server/routes/chat.js.map +1 -1
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +8 -0
- package/dist/server/routes/index.js.map +1 -1
- package/dist/server/routes/roster.d.ts.map +1 -1
- package/dist/server/routes/roster.js +6 -22
- package/dist/server/routes/roster.js.map +1 -1
- package/dist/server/routes/run-requests.js +3 -3
- package/dist/server/routes/run-requests.js.map +1 -1
- package/dist/server/routes/runners/admin.d.ts.map +1 -1
- package/dist/server/routes/runners/admin.js +219 -25
- package/dist/server/routes/runners/admin.js.map +1 -1
- package/dist/server/routes/runners/install.d.ts.map +1 -1
- package/dist/server/routes/runners/install.js +7 -2
- package/dist/server/routes/runners/install.js.map +1 -1
- package/dist/server/routes/runners/runner.d.ts.map +1 -1
- package/dist/server/routes/runners/runner.js +2 -0
- package/dist/server/routes/runners/runner.js.map +1 -1
- package/dist/server/routes/schemas.d.ts +18 -10
- package/dist/server/routes/schemas.d.ts.map +1 -1
- package/dist/server/routes/schemas.js +498 -153
- package/dist/server/routes/schemas.js.map +1 -1
- package/dist/server/runners/runner.service.d.ts +47 -4
- package/dist/server/runners/runner.service.d.ts.map +1 -1
- package/dist/server/runners/runner.service.js +423 -79
- package/dist/server/runners/runner.service.js.map +1 -1
- package/dist/server/runners/runner.store.d.ts +8 -3
- package/dist/server/runners/runner.store.d.ts.map +1 -1
- package/dist/server/runners/runner.store.js +63 -6
- package/dist/server/runners/runner.store.js.map +1 -1
- package/dist/server/runners/slots.d.ts +5 -2
- package/dist/server/runners/slots.d.ts.map +1 -1
- package/dist/server/runners/slots.js +3 -4
- package/dist/server/runners/slots.js.map +1 -1
- package/dist/server/runners/workspaces.d.ts.map +1 -1
- package/dist/server/runners/workspaces.js +18 -2
- package/dist/server/runners/workspaces.js.map +1 -1
- package/dist/server/testing.d.ts +0 -2
- package/dist/server/testing.d.ts.map +1 -1
- package/dist/server/testing.js +1 -4
- package/dist/server/testing.js.map +1 -1
- package/dist/server/tokens.d.ts +8 -7
- package/dist/server/tokens.d.ts.map +1 -1
- package/dist/server/tokens.js +4 -2
- package/dist/server/tokens.js.map +1 -1
- package/dist/shared/access.d.ts +2 -6
- package/dist/shared/access.d.ts.map +1 -1
- package/dist/shared/access.js +2 -6
- package/dist/shared/access.js.map +1 -1
- package/dist/shared/agents.d.ts +131 -169
- package/dist/shared/agents.d.ts.map +1 -1
- package/dist/shared/agents.js +36 -102
- package/dist/shared/agents.js.map +1 -1
- package/dist/shared/conversations.d.ts +93 -170
- package/dist/shared/conversations.d.ts.map +1 -1
- package/dist/shared/conversations.js +8 -30
- package/dist/shared/conversations.js.map +1 -1
- package/dist/shared/model-catalog.d.ts +53 -0
- package/dist/shared/model-catalog.d.ts.map +1 -0
- package/dist/shared/model-catalog.js +182 -0
- package/dist/shared/model-catalog.js.map +1 -0
- package/dist/shared/online-agent.d.ts +3 -0
- package/dist/shared/online-agent.d.ts.map +1 -0
- package/dist/shared/online-agent.js +3 -0
- package/dist/shared/online-agent.js.map +1 -0
- package/dist/shared/page-ui-context.d.ts +26 -0
- package/dist/shared/page-ui-context.d.ts.map +1 -0
- package/dist/shared/page-ui-context.js +129 -0
- package/dist/shared/page-ui-context.js.map +1 -0
- package/dist/shared/quota.d.ts +15 -0
- package/dist/shared/quota.d.ts.map +1 -0
- package/dist/shared/quota.js +2 -0
- package/dist/shared/quota.js.map +1 -0
- package/dist/shared/runners.d.ts +132 -14
- package/dist/shared/runners.d.ts.map +1 -1
- package/dist/shared/runners.js +171 -11
- package/dist/shared/runners.js.map +1 -1
- package/dist/shared/runs.d.ts +59 -1
- package/dist/shared/runs.d.ts.map +1 -1
- package/dist/shared/runs.js +28 -0
- package/dist/shared/runs.js.map +1 -1
- package/dist/shared/skills.d.ts +11 -5
- package/dist/shared/skills.d.ts.map +1 -1
- package/dist/shared/skills.js +7 -2
- package/dist/shared/skills.js.map +1 -1
- package/dist/shared/ui-message.d.ts +80 -0
- package/dist/shared/ui-message.d.ts.map +1 -0
- package/dist/shared/ui-message.js +153 -0
- package/dist/shared/ui-message.js.map +1 -0
- package/dist/shared/variables.js +1 -1
- package/dist/shared/variables.js.map +1 -1
- package/docs/ai-forms.md +346 -0
- package/docs/execution-history.md +19 -0
- package/docs/mysql-installation-upgrade.md +7 -0
- package/docs/runner-agents.md +27 -0
- package/docs/ui-message-clients.md +80 -0
- package/docs/ui-messages.md +209 -0
- package/docs/workspace-cleanup.md +13 -0
- package/package.json +39 -25
- package/skills/nocobase-app-plugin-agents/SKILL.md +16 -13
- package/skills/nocobase-app-plugin-agents/references/agents.md +30 -0
- package/skills/nocobase-app-plugin-agents/references/extension-points.md +21 -21
- package/skills/nocobase-app-plugin-agents/references/model-services.md +17 -0
- package/skills/nocobase-app-plugin-agents/references/online-agent.md +216 -0
- package/skills/nocobase-app-plugin-agents/references/runners.md +12 -0
- package/skills/nocobase-app-plugin-agents/references/setup-and-config.md +6 -7
- package/skills/nocobase-app-plugin-agents/references/variables-skills-usage.md +6 -4
- package/skills/nocobase-app-plugin-agents/references/verification-and-troubleshooting.md +29 -32
- package/dist/client/chat/settings-section.d.ts +0 -5
- package/dist/client/chat/settings-section.d.ts.map +0 -1
- package/dist/client/chat/settings-section.js +0 -86
- package/dist/client/chat/settings-section.js.map +0 -1
- package/dist/client/components/agent-fields.d.ts +0 -45
- package/dist/client/components/agent-fields.d.ts.map +0 -1
- package/dist/client/components/agent-fields.js +0 -83
- package/dist/client/components/agent-fields.js.map +0 -1
- package/dist/client/components/agent-type.d.ts +0 -32
- package/dist/client/components/agent-type.d.ts.map +0 -1
- package/dist/client/components/agent-type.js +0 -80
- package/dist/client/components/agent-type.js.map +0 -1
- package/dist/client/components/model-entries.d.ts +0 -44
- package/dist/client/components/model-entries.d.ts.map +0 -1
- package/dist/client/components/model-entries.js +0 -104
- package/dist/client/components/model-entries.js.map +0 -1
- package/dist/client/hooks/use-agent-save.d.ts +0 -9
- package/dist/client/hooks/use-agent-save.d.ts.map +0 -1
- package/dist/client/hooks/use-agent-save.js +0 -40
- package/dist/client/hooks/use-agent-save.js.map +0 -1
- package/dist/client/hooks/use-model-catalog.d.ts +0 -9
- package/dist/client/hooks/use-model-catalog.d.ts.map +0 -1
- package/dist/client/hooks/use-model-catalog.js +0 -27
- package/dist/client/hooks/use-model-catalog.js.map +0 -1
- package/dist/client/lib/model-suggestions.d.ts +0 -28
- package/dist/client/lib/model-suggestions.d.ts.map +0 -1
- package/dist/client/lib/model-suggestions.js +0 -44
- package/dist/client/lib/model-suggestions.js.map +0 -1
- package/dist/client/lib/tool-policy.d.ts +0 -3
- package/dist/client/lib/tool-policy.d.ts.map +0 -1
- package/dist/client/lib/tool-policy.js +0 -5
- package/dist/client/lib/tool-policy.js.map +0 -1
- package/dist/client/online/default-model.d.ts +0 -5
- package/dist/client/online/default-model.d.ts.map +0 -1
- package/dist/client/online/default-model.js +0 -65
- package/dist/client/online/default-model.js.map +0 -1
- package/dist/client/pages/agents/agent-model.d.ts +0 -69
- package/dist/client/pages/agents/agent-model.d.ts.map +0 -1
- package/dist/client/pages/agents/agent-model.js +0 -153
- package/dist/client/pages/agents/agent-model.js.map +0 -1
- package/dist/client/pages/agents/detail/brief-preview.d.ts +0 -7
- package/dist/client/pages/agents/detail/brief-preview.d.ts.map +0 -1
- package/dist/client/pages/agents/detail/brief-preview.js +0 -43
- package/dist/client/pages/agents/detail/brief-preview.js.map +0 -1
- package/dist/client/pages/agents/detail/history.d.ts +0 -11
- package/dist/client/pages/agents/detail/history.d.ts.map +0 -1
- package/dist/client/pages/agents/detail/history.js +0 -149
- package/dist/client/pages/agents/detail/history.js.map +0 -1
- package/dist/client/pages/agents/detail/index.d.ts +0 -3
- package/dist/client/pages/agents/detail/index.d.ts.map +0 -1
- package/dist/client/pages/agents/detail/index.js +0 -241
- package/dist/client/pages/agents/detail/index.js.map +0 -1
- package/dist/client/pages/agents/detail/sections.d.ts +0 -21
- package/dist/client/pages/agents/detail/sections.d.ts.map +0 -1
- package/dist/client/pages/agents/detail/sections.js +0 -280
- package/dist/client/pages/agents/detail/sections.js.map +0 -1
- package/dist/client/pages/agents/detail/tab-draft.d.ts +0 -43
- package/dist/client/pages/agents/detail/tab-draft.d.ts.map +0 -1
- package/dist/client/pages/agents/detail/tab-draft.js +0 -115
- package/dist/client/pages/agents/detail/tab-draft.js.map +0 -1
- package/dist/client/pages/agents/detail/unsaved-bar.d.ts +0 -13
- package/dist/client/pages/agents/detail/unsaved-bar.d.ts.map +0 -1
- package/dist/client/pages/agents/detail/unsaved-bar.js +0 -21
- package/dist/client/pages/agents/detail/unsaved-bar.js.map +0 -1
- package/dist/client/pages/agents/new.d.ts +0 -3
- package/dist/client/pages/agents/new.d.ts.map +0 -1
- package/dist/client/pages/agents/new.js +0 -149
- package/dist/client/pages/agents/new.js.map +0 -1
- package/dist/client/pages/agents/preset-picker.d.ts +0 -8
- package/dist/client/pages/agents/preset-picker.d.ts.map +0 -1
- package/dist/client/pages/agents/preset-picker.js +0 -41
- package/dist/client/pages/agents/preset-picker.js.map +0 -1
- package/dist/server/core/consultations/consultation.service.d.ts +0 -59
- package/dist/server/core/consultations/consultation.service.d.ts.map +0 -1
- package/dist/server/core/consultations/consultation.service.js +0 -198
- package/dist/server/core/consultations/consultation.service.js.map +0 -1
- package/dist/server/core/consultations/index.d.ts +0 -3
- package/dist/server/core/consultations/index.d.ts.map +0 -1
- package/dist/server/core/consultations/index.js +0 -3
- package/dist/server/core/consultations/index.js.map +0 -1
- package/dist/server/core/consultations/prompt.d.ts +0 -41
- package/dist/server/core/consultations/prompt.d.ts.map +0 -1
- package/dist/server/core/consultations/prompt.js +0 -64
- package/dist/server/core/consultations/prompt.js.map +0 -1
- package/dist/server/core/presets/index.d.ts +0 -19
- package/dist/server/core/presets/index.d.ts.map +0 -1
- package/dist/server/core/presets/index.js +0 -28
- package/dist/server/core/presets/index.js.map +0 -1
- package/dist/server/online/cli-command.d.ts +0 -20
- package/dist/server/online/cli-command.d.ts.map +0 -1
- package/dist/server/online/cli-command.js +0 -345
- package/dist/server/online/cli-command.js.map +0 -1
- package/dist/server/online/consult-tool.d.ts +0 -54
- package/dist/server/online/consult-tool.d.ts.map +0 -1
- package/dist/server/online/consult-tool.js +0 -177
- package/dist/server/online/consult-tool.js.map +0 -1
- package/dist/server/online/executor.d.ts +0 -83
- package/dist/server/online/executor.d.ts.map +0 -1
- package/dist/server/online/executor.js +0 -714
- package/dist/server/online/executor.js.map +0 -1
- package/dist/server/online/sandbox.d.ts +0 -32
- package/dist/server/online/sandbox.d.ts.map +0 -1
- package/dist/server/online/sandbox.js +0 -246
- package/dist/server/online/sandbox.js.map +0 -1
- package/dist/server/online/scripted.d.ts +0 -12
- package/dist/server/online/scripted.d.ts.map +0 -1
- package/dist/server/online/scripted.js +0 -176
- package/dist/server/online/scripted.js.map +0 -1
- package/dist/server/online/tools.d.ts +0 -17
- package/dist/server/online/tools.d.ts.map +0 -1
- package/dist/server/online/tools.js +0 -31
- package/dist/server/online/tools.js.map +0 -1
- package/dist/server/vendor/THIRD_PARTY_LICENSES.txt +0 -782
- package/dist/server/vendor/just-bash.d.ts +0 -83
- package/dist/server/vendor/just-bash.js +0 -2102
- package/dist/shared/presets.d.ts +0 -30
- package/dist/shared/presets.d.ts.map +0 -1
- package/dist/shared/presets.js +0 -2
- package/dist/shared/presets.js.map +0 -1
- package/skills/nocobase-app-plugin-agents/references/online-agents.md +0 -31
package/docs/ai-forms.md
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
# UI context, tool cards and AI form adapters
|
|
2
|
+
|
|
3
|
+
The public entry for all browser APIs below is `@nocobase/app-plugin-agents/client/chat`. The plugin supplies generic JSON context transport, SDK tool renderer registration and local form adapters. The Examples application supplies its `examples_form_proposal` tool, proposal schema, editable card and `/ai-form-fill` page; none is a plugin default. The complete runnable example is described in [Examples OnlineAgent](../../../templates/app-template-examples/online-agent.md#ai-form-fill-browser-drafts-only).
|
|
4
|
+
|
|
5
|
+
The Agents client SDK exports `AIFormRegistry`, `AIFormRegistryProvider`, `useAIFormRegistry`, and `useAIForm` from `@nocobase/app-plugin-agents/client/chat`. These are generic browser-draft capabilities, not a built-in form-filling tool, form engine, card renderer, persistence API, or SDK tool continuation. Applications own their fields, tool schemas, proposal cards, validation, and explicit user actions. `useAIForm` returns a ref callback; it does not return `{ ref, context }`.
|
|
6
|
+
|
|
7
|
+
## Open UI context, not business-resource authorization
|
|
8
|
+
|
|
9
|
+
`PageContext.ui` is optional and has the strict envelope `{ version: 1, items: PageUIItem[] }`. Each item requires nonempty `kind` and `id` strings and may contain any other accepted `AppUIJson` fields. Unknown kinds, nested custom objects, arrays, null, false, zero and empty strings survive admission, model conversion, persistence, public metadata and history/reconnect recovery. No kind resolver is needed. By contrast, `context.items` remains the existing server-resolved and authorized business-reference list; putting a record id, route or claimed permission into `ui.items` grants no access to that record or a tool.
|
|
10
|
+
|
|
11
|
+
A form is only one convention. This application-owned source uses an unknown UI kind and never reads form state:
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { useRef, type ReactElement } from 'react';
|
|
15
|
+
import {
|
|
16
|
+
useChatSources,
|
|
17
|
+
useChatUIContextSource,
|
|
18
|
+
uiItemKey,
|
|
19
|
+
} from '@nocobase/app-plugin-agents/client/chat';
|
|
20
|
+
|
|
21
|
+
export function ChartContext(): ReactElement {
|
|
22
|
+
const sources = useChatSources();
|
|
23
|
+
const chart = useRef({ series: [0, 12], annotation: null });
|
|
24
|
+
const item = { kind: 'sales-chart', id: 'quarterly' };
|
|
25
|
+
useChatUIContextSource({
|
|
26
|
+
...item,
|
|
27
|
+
label: 'Quarterly chart',
|
|
28
|
+
getSnapshot: async () => ({
|
|
29
|
+
...item,
|
|
30
|
+
options: { showLegend: false, caption: '' },
|
|
31
|
+
data: chart.current,
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
const selected = sources.selectedUIKeys.has(uiItemKey(item));
|
|
35
|
+
return (
|
|
36
|
+
<button type='button' onClick={() => sources.selectUI(item, !selected)}>
|
|
37
|
+
{selected ? 'Exclude chart' : 'Include chart'}
|
|
38
|
+
</button>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`useChatUIContextSource(source | null)` makes a source available while mounted, without selecting it or reading it. `useChatSources().selectUI(source, true)` is a separate explicit action; `false` removes it. Duplicate live `(kind, id)` registrations and duplicate identities in one envelope throw rather than overwrite. Unregistering removes its selection; pathname navigation clears UI selection. Callback updates use the latest committed reader without implicitly reselecting the source.
|
|
44
|
+
|
|
45
|
+
The installed chat composer awaits `sources.snapshotUI()` at Send, then passes the detached result as `ui` to `buildPageContext`. A custom composer must do the same: `buildPageContext` is synchronous, its `uiSources` input builds chips only, and registration alone does not attach snapshots to messages. Snapshot readers can be asynchronous but must be side-effect free. Selection/source/provider-lifetime changes during the read reject it; the composer must show that error and not submit stale data. Form snapshots additionally detect draft-revision changes while reading. Accepted JSON is cloned, so later object mutation cannot rewrite the sent message. Native and Runner model inputs label UI snapshots as untrusted user data, never system instructions; a follow-up that needs current UI state must explicitly include a fresh snapshot. Earlier Native user-message snapshots may remain in model history as historical data, but do not authorize a new card's target when absent from its own source message.
|
|
46
|
+
|
|
47
|
+
`PAGE_UI_CONTEXT_LIMITS` centrally bounds an envelope to 10 items, 64 KiB of serialized UTF-8 JSON, depth 12 (the envelope is depth zero), 4,096 JSON values, kind length 64, id/key length 200 and string length 16,384 JavaScript string units. `clonePageUIContext` validates and detaches an envelope; `pageUIContextSchema` is the shared schema. Budgets reject, never truncate. Dangerous keys (`__proto__`, `prototype`, `constructor`), non-plain objects, getters, hidden/symbol properties, sparse/extended arrays, cycles and non-JSON values are rejected before serialization without invoking getters or `toJSON`. Keep snapshots minimal and deliberately exclude secrets; open transport is not a reason to upload an entire page.
|
|
48
|
+
|
|
49
|
+
## Register generic SDK tool renderers
|
|
50
|
+
|
|
51
|
+
`AIToolRendererProvider` takes an `AIToolRendererMap`: exact SDK tool names mapped to React components with `AIToolRendererProps`. The Registry chat uses the SDK's `isToolUIPart`/`getToolName` helpers, so both static `tool-*` and `dynamic-tool` parts dispatch by the actual tool name. Unregistered tools retain the normal JSON/approval fallback. Existing ordered parts, data/business/notice extensions and message-extra rendering stay in the same timeline; the provider creates neither a chat owner nor a transport. An inner renderer provider inherits other keys and overrides matching parent keys; a nested form registry provider, in contrast, is isolated.
|
|
52
|
+
|
|
53
|
+
| Prop | Contract |
|
|
54
|
+
| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
|
|
55
|
+
| `toolName` | Exact tool name, not a display label or part type. |
|
|
56
|
+
| `part` | Read-only public SDK `AIToolPart`; narrow `part.state` before reading output. It is not a private raw execution result. |
|
|
57
|
+
| `message` | Read-only owning `AppUIMessage`, retaining durable conversation/message/tool identity. |
|
|
58
|
+
| `context.readOnly`, `context.streaming` | Interaction gates; do not enable local draft application while either is true. |
|
|
59
|
+
| `context.sourceMessage`, `context.sourceContext` | Exact server-linked user message and its saved context, or null when unavailable; never a nearest-message heuristic. |
|
|
60
|
+
| `context.approval` | Existing bound SDK approval control: `disabled`, `pending`, `error`, and `respond(approved, reason?)`. |
|
|
61
|
+
|
|
62
|
+
A registered renderer replaces the fallback for that tool in every state, so it must handle `input-streaming`, `input-available`, `approval-requested`, `approval-responded`, `output-available`, `output-error` and `output-denied`. Never parse partial streaming input as a completed proposal. For genuine SDK approval, show the requested decision and call `context.approval.respond` only from a user action while enabled, displaying pending/error feedback. Local **Apply draft** is not approval: the proposal tool has already finished. Neither path should run from mount/effect, history restoration or reconnect.
|
|
63
|
+
|
|
64
|
+
Public tool visibility still requires the server tool's explicit `public.input` and `public.output` projections. These are Agents safety APIs, not SDK-standard methods. SDK `toModelOutput` independently controls private model conversion; it does not expose output to browser cards. Validate and expose only safe proposal fields, never publish raw private tool evidence to make a renderer work.
|
|
65
|
+
|
|
66
|
+
## Three separate decisions
|
|
67
|
+
|
|
68
|
+
1. **Register a live adapter:** attach the callback from `useAIForm` to the form. Registration makes capabilities discoverable locally through `registry.list()` and `registry.locate(id)`; it does not read values, upload data, select context, or execute anything.
|
|
69
|
+
2. **Select UI context:** make an available source with `useChatUIContextSource`, then explicitly select it through `useChatSources().selectUI`. The existing chat owner reads `registry.snapshot(id)` at send time and fixes that selected JSON snapshot on the user message. Do not use the business-resource `context.items` resolver for form data.
|
|
70
|
+
3. **Apply an edited proposal:** after explicit confirmation, pass the final edited patch, a stable operation key, and the selected snapshot from the tool card's exact originating user message to `registry.apply`. The registry never derives authorization from model-provided ids or a currently selected form.
|
|
71
|
+
|
|
72
|
+
Mount the registry provider inside the same keyed authenticated-identity boundary as the existing `ChatProvider`, covering both the business page and shared chat panel. Do not create a second chat owner. A nested form registry provider is an isolated scope, not a merge with its parent. A new identity must get a fresh registry; do not share a module-global registry across users.
|
|
73
|
+
|
|
74
|
+
## Register a form and expose an optional context source
|
|
75
|
+
|
|
76
|
+
This minimal adapter intentionally exposes only two fields. A real application should use its own input components and translations. Passwords, tokens, hidden values, and other sensitive fields must be excluded explicitly from both `fields` and `getValues`; the registry rejects undeclared read values rather than silently uploading or dropping them.
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import { useRef, useState, type ReactElement } from 'react';
|
|
80
|
+
import {
|
|
81
|
+
useAIForm,
|
|
82
|
+
useAIFormRegistry,
|
|
83
|
+
useChatSources,
|
|
84
|
+
useChatUIContextSource,
|
|
85
|
+
uiItemKey,
|
|
86
|
+
} from '@nocobase/app-plugin-agents/client/chat';
|
|
87
|
+
|
|
88
|
+
export function DraftForm({
|
|
89
|
+
userId,
|
|
90
|
+
recordId,
|
|
91
|
+
}: {
|
|
92
|
+
userId: string;
|
|
93
|
+
recordId: string;
|
|
94
|
+
}): ReactElement {
|
|
95
|
+
const registry = useAIFormRegistry();
|
|
96
|
+
const sources = useChatSources();
|
|
97
|
+
const draftRef = useRef({ name: '', recordId });
|
|
98
|
+
const revisionRef = useRef(0);
|
|
99
|
+
const [name, setName] = useState('');
|
|
100
|
+
const id = 'customer-draft';
|
|
101
|
+
|
|
102
|
+
function changeName(next: string): void {
|
|
103
|
+
// Advance synchronously, including for ordinary manual edits.
|
|
104
|
+
draftRef.current = { ...draftRef.current, name: next };
|
|
105
|
+
revisionRef.current += 1;
|
|
106
|
+
setName(next);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const ref = useAIForm<HTMLFormElement>({
|
|
110
|
+
id,
|
|
111
|
+
title: 'Customer draft',
|
|
112
|
+
identity: JSON.stringify([userId, recordId]),
|
|
113
|
+
fields: [
|
|
114
|
+
{ name: 'name', title: 'Name', type: 'string', editable: true },
|
|
115
|
+
{ name: 'recordId', title: 'Record', type: 'string', editable: false },
|
|
116
|
+
],
|
|
117
|
+
getRevision: () => String(revisionRef.current),
|
|
118
|
+
getValues: () => ({ ...draftRef.current }),
|
|
119
|
+
validate: (patch) =>
|
|
120
|
+
typeof patch.name === 'string' && !patch.name.trim()
|
|
121
|
+
? 'Name must not be blank.'
|
|
122
|
+
: undefined,
|
|
123
|
+
setValues: (patch, context) => {
|
|
124
|
+
if (!context.isCurrent()) throw new Error('The target draft changed.');
|
|
125
|
+
if (typeof patch.name === 'string') changeName(patch.name);
|
|
126
|
+
// Do not submit, call a save endpoint, or add a tool-output message here.
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const source = { kind: 'form', id };
|
|
131
|
+
useChatUIContextSource({
|
|
132
|
+
...source,
|
|
133
|
+
label: 'Customer draft',
|
|
134
|
+
getSnapshot: () => registry.snapshot(id),
|
|
135
|
+
});
|
|
136
|
+
const selected = sources.selectedUIKeys.has(uiItemKey(source));
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<form ref={ref} onSubmit={(event) => event.preventDefault()}>
|
|
140
|
+
<label>
|
|
141
|
+
Name
|
|
142
|
+
<input
|
|
143
|
+
value={name}
|
|
144
|
+
onChange={(event) => changeName(event.target.value)}
|
|
145
|
+
/>
|
|
146
|
+
</label>
|
|
147
|
+
<p>Only the browser draft changes; nothing is saved.</p>
|
|
148
|
+
<button type='button' onClick={() => sources.selectUI(source, !selected)}>
|
|
149
|
+
{selected
|
|
150
|
+
? 'Remove draft from chat context'
|
|
151
|
+
: 'Include draft in chat context'}
|
|
152
|
+
</button>
|
|
153
|
+
</form>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Mount this example with a React key containing the user and record identity so its example draft state resets when those change. The registry also supports an identity change without component unmount: `useAIForm` replaces the live instance token when `id`, `identity`, provider registry, or actual ref attachment changes. The application remains responsible for resetting its own form state to the new record.
|
|
159
|
+
|
|
160
|
+
Available sources are not selected automatically. The existing send path reads only selected UI sources and attaches `context.ui = { version: 1, items: [...] }`. The source reader must remain side-effect free. Snapshot failure, a draft change during reading, or a disappearing form should block sending the snapshot with a visible error, not silently send stale values. Other UI kinds are allowed; form data is one application convention within the open UI-item protocol.
|
|
161
|
+
|
|
162
|
+
## Snapshot and capability contract
|
|
163
|
+
|
|
164
|
+
`await registry.snapshot(id)` returns a detached `PageUIItem` with this form convention:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
{
|
|
168
|
+
kind: 'form',
|
|
169
|
+
id: 'customer-draft',
|
|
170
|
+
title: 'Customer draft',
|
|
171
|
+
identity: '["user-1","record-7"]',
|
|
172
|
+
instance: 'opaque-local-instance-token',
|
|
173
|
+
revision: 'opaque-draft-revision',
|
|
174
|
+
fields: [
|
|
175
|
+
{ name: 'name', type: 'string', editable: true },
|
|
176
|
+
{ name: 'recordId', type: 'string', editable: false },
|
|
177
|
+
],
|
|
178
|
+
values: { name: '', recordId: 'record-7' },
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Treat `instance` and `revision` as opaque strings. Instances are unique per registration: A→B→A cannot revive A's previous token. The snapshot's revision includes a registry write epoch as well as the adapter's `getRevision()` value; every attempted setter invalidates previous snapshots, even if it fails or partially applies. Neither token is a server authorization credential.
|
|
183
|
+
|
|
184
|
+
`fields` supports `string`, `number`, `boolean`, and `json`, an explicit `editable` capability, an optional display title, and an optional JSON `enum`. The registry enforces declared fields, edit capability, primitive type, finite JSON numbers, and enum membership before the setter. An application validator receives an isolated copy of the final edited patch and returns an error string or `undefined`, synchronously or asynchronously. Validator mutation cannot change the patch subsequently delivered to the setter. Cross-field or business rules remain the application's responsibility.
|
|
185
|
+
|
|
186
|
+
Field names are flat. Dots, brackets, slashes, backslashes, `__proto__`, `constructor`, and `prototype` are rejected; the registry never traverses property paths or merges nested objects. A nested value is supported only as a whole explicitly declared `json` field, with the adapter responsible for interpreting that value safely. Dangerous keys are rejected at every JSON depth. Cycles, accessors, functions, undefined, BigInt, non-finite numbers, sparse arrays, extended arrays, non-plain objects, and hidden properties are rejected without executing getters or `toJSON`.
|
|
187
|
+
|
|
188
|
+
The form boundary reuses `PAGE_UI_CONTEXT_LIMITS` for JSON depth, bytes, nodes, string length, and keys; it admits the complete form snapshot under the shared UI transport envelope as well. There are at most 100 declared fields. Data exceeding a budget is rejected, never silently truncated. A snapshot accepted alone may still exceed a message's combined UI budget when other selected sources are present.
|
|
189
|
+
|
|
190
|
+
## Apply only from the exact originating message
|
|
191
|
+
|
|
192
|
+
Use the renderer's `context.sourceContext` / `context.sourceMessage` established by the server's durable `message.metadata.sourceUserMessageId` association. Native execution sets this to the admitted user-message id for the response and preserves it through approval revisions and public projection. `getAIToolSourceMessage(message, messages)` returns a source only for an assistant message with both that id and a conversation id, and exactly one loaded user message matching both. The Registry supplies that result and its `metadata.context` to the renderer. It does not accept a model-provided source id or assume Runner/legacy messages have this Native linkage. If history pagination has not loaded that source, disable application until it is available. Never scan for the latest user message, use current composer context, trust the model's allowed ids, or authorize from a bare `registry.locate(id)` result. UI context is browser-supplied data and grants no server resource access.
|
|
193
|
+
|
|
194
|
+
The following handler belongs inside an application-owned renderer/card. `proposal` must already have passed the application's own strict output schema; `editedValues` must be the user's currently edited and validated values, not the original `part.output`. The caller must require an explicit click, disable the action in read-only/streaming states, and prevent overlapping button handlers. See the Examples application's `form-proposal-card.tsx` for a complete card with editable controls and localized outcomes.
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
const registry = useAIFormRegistry();
|
|
198
|
+
|
|
199
|
+
async function applyEditedProposal(): Promise<void> {
|
|
200
|
+
if (
|
|
201
|
+
context.readOnly ||
|
|
202
|
+
context.streaming ||
|
|
203
|
+
part.state !== 'output-available'
|
|
204
|
+
)
|
|
205
|
+
return;
|
|
206
|
+
const candidates =
|
|
207
|
+
context.sourceContext?.ui?.items.filter(
|
|
208
|
+
(item) => item.kind === 'form' && item.id === proposal.formId,
|
|
209
|
+
) ?? [];
|
|
210
|
+
const source = candidates.length === 1 ? candidates[0] : undefined;
|
|
211
|
+
if (
|
|
212
|
+
!source ||
|
|
213
|
+
source.instance !== proposal.instance ||
|
|
214
|
+
source.identity !== proposal.identity ||
|
|
215
|
+
source.revision !== proposal.revision
|
|
216
|
+
) {
|
|
217
|
+
showError(
|
|
218
|
+
'The proposal has no matching selected source. Generate a new proposal.',
|
|
219
|
+
);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Detach the source before crossing into the mutable JSON adapter API.
|
|
224
|
+
const selected = clonePageUIContext({ version: 1, items: [source] }).items[0];
|
|
225
|
+
const outcome = await registry.apply({
|
|
226
|
+
source: selected,
|
|
227
|
+
operationId: JSON.stringify([
|
|
228
|
+
message.metadata?.conversationId,
|
|
229
|
+
message.id,
|
|
230
|
+
part.toolCallId,
|
|
231
|
+
]),
|
|
232
|
+
values: editedValues,
|
|
233
|
+
signal: abortController.signal,
|
|
234
|
+
});
|
|
235
|
+
showLocalDraftOutcome(outcome); // Only status 'applied' confirms the local draft update.
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The sketch uses `clonePageUIContext` from the same client SDK export. `showError`, `showLocalDraftOutcome`, `proposal`, edited form controls, and the card's `AbortController` are application-owned. A dismiss/cancel button should simply close or mark the card dismissed; it must not call `registry.apply` or the setter. If aborting an in-progress operation, abort its signal instead of reporting success. Mounting a card, replaying history, or reconnecting must never invoke this handler.
|
|
240
|
+
|
|
241
|
+
`registry.apply({ source, operationId, values, signal? })` clones the request before asynchronous work, checks the selected source's form kind, instance, identity, revision, and declared capabilities against the live registration, rejects competing operations on the same form, validates the final patch, and awaits the setter. It does not read model target ids to discover a target. A manual edit after sending is a conservative revision conflict, even when it touched another field. Generate a fresh proposal instead of silently merging.
|
|
242
|
+
|
|
243
|
+
Operation keys are scoped to the registry lifetime. The same key and identical source/patch return the same pending promise or completed result; different content under an already-used key is rejected with `operation-conflict`. A cached success describes the previous local operation, not the form's current state. Keep the key stable across card remounts and repeated clicks. A deliberate corrected attempt after pre-setter validation rejection needs a new operation key; never silently retry a failed setter, because its outcome may be partial. A setter attempt invalidates the old source snapshot in all cases.
|
|
244
|
+
|
|
245
|
+
## Asynchronous adapter and failure responsibilities
|
|
246
|
+
|
|
247
|
+
`AIFormOperationContext` supplies `signal` and `isCurrent()`. Unmount, instance replacement, capability changes, and explicit cancellation abort tracked operations. The guard additionally compares the live draft revision, catching manual edits that occur without unmount. Adapters should pass `signal` to cancellable preparation work, then check `isCurrent()` **immediately before a synchronous browser-draft commit**. A guard checked before an `await` does not protect a later commit.
|
|
248
|
+
|
|
249
|
+
```ts
|
|
250
|
+
setValues: async (patch, context) => {
|
|
251
|
+
const prepared = await prepareDraftPatch(patch, { signal: context.signal });
|
|
252
|
+
if (!context.isCurrent()) throw new Error('The target changed before commit.');
|
|
253
|
+
commitDraftSynchronously(prepared); // Also advance the adapter revision synchronously.
|
|
254
|
+
return { status: 'applied' };
|
|
255
|
+
},
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
The registry cannot prevent an arbitrary third-party asynchronous setter from ignoring its signal, mutating a stale record after an await, partially writing, or lying about success. The adapter must preserve atomicity when its form library supports it, implement rollback if needed, and avoid asynchronous gaps between its final guard and commit. `getValues` must be side-effect free and should honor the same guard/signal contract for expensive reads. `getRevision` must be synchronous, side-effect free, change on every draft mutation, and never reuse a value within the same live instance; use a monotonic counter or unique revision token. Timestamp collisions, value-derived hashes that can revert, or asynchronous React state alone are not reliable revision counters.
|
|
259
|
+
|
|
260
|
+
A synchronous/async setter resolving `void` or `{ status: 'applied', message? }` confirms the adapter completed its draft operation. `{ status: 'partial', message? }` honestly reports partial application. A thrown/rejected setter returns `status: 'failed'`, never success; a detected target replacement/cancellation while an uncooperative setter runs returns `status: 'failed'`, `code: 'stale-after-write'` with an explicitly unconfirmed outcome. Explicit request-signal cancellation before the setter returns `cancelled` without calling it. Validation, stale-target, capability, and revision conflicts return `rejected`. No generic transaction or rollback is promised, and none of these outcomes claims business persistence.
|
|
261
|
+
|
|
262
|
+
## Integrated application wiring
|
|
263
|
+
|
|
264
|
+
The runnable Examples implementation covers the complete chain without inventing a plugin form tool. The relative Examples source links below are repository-checkout references, not files shipped inside the installed plugin; generated applications should adapt the public contract and own their schema/tool/card. Its application-owned [shared schema](../../../templates/app-template-examples/shared/ai-form-fill.ts), [boot provider](../../../templates/app-template-examples/server/providers/ai-form-fill.ts), [page](../../../templates/app-template-examples/client/pages/ai-form-fill/index.tsx), [card](../../../templates/app-template-examples/client/components/online-agent/form-proposal-card.tsx) and [identity provider](../../../templates/app-template-examples/client/components/online-agent/provider.tsx) are the maintained complete example. The following condensed wiring shows how the pieces fit; the constants, schema and renderer imports are **Examples application modules**, not plugin exports:
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
// server/providers/ai-form-fill.ts; register after Agents in the application composition.
|
|
268
|
+
import type { Application } from '@nocobase/app-server/application';
|
|
269
|
+
import { ServiceProvider } from '@nocobase/service-provider';
|
|
270
|
+
import { agentsToken } from '@nocobase/app-plugin-agents/server/tokens';
|
|
271
|
+
import {
|
|
272
|
+
EXAMPLES_FORM_SCOPE,
|
|
273
|
+
EXAMPLES_FORM_TOOL,
|
|
274
|
+
formProposalSchema,
|
|
275
|
+
} from '../../shared/ai-form-fill.js';
|
|
276
|
+
|
|
277
|
+
export default class AIFormFillProvider extends ServiceProvider<Application> {
|
|
278
|
+
public readonly name: string = 'app/examples-ai-form-fill';
|
|
279
|
+
|
|
280
|
+
public override async boot(): Promise<void> {
|
|
281
|
+
const online = this.app.container.resolve(agentsToken).onlineAgent;
|
|
282
|
+
online.configurator.registerTool(EXAMPLES_FORM_TOOL, {
|
|
283
|
+
version: '1',
|
|
284
|
+
definition: {
|
|
285
|
+
description:
|
|
286
|
+
'Return a proposal for a selected browser form; never save it.',
|
|
287
|
+
inputSchema: formProposalSchema,
|
|
288
|
+
public: {
|
|
289
|
+
input: (input) => formProposalSchema.parse(input),
|
|
290
|
+
output: (output) => formProposalSchema.parse(output),
|
|
291
|
+
},
|
|
292
|
+
execute: async (input) => formProposalSchema.parse(input),
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
online.configurator.registerOnlineAgentScope(EXAMPLES_FORM_SCOPE, {
|
|
296
|
+
tool: [EXAMPLES_FORM_TOOL],
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Keep this tool in an explicitly selected Native scope, not a global tool layer shared with Runner. The real Examples provider additionally supplies task instructions; those instructions are not a substitute for the card/registry's target and field checks. The strict application schema is `{ formId, instance, identity, revision, values }`; only `name`, `priority`, `budget` and `subscribe` can appear in its patch. The tool merely returns the validated proposal. It never invokes a browser adapter or claims a record was saved.
|
|
303
|
+
|
|
304
|
+
```tsx
|
|
305
|
+
// Inside the existing authenticated identity lifetime, covering page AND panel:
|
|
306
|
+
import {
|
|
307
|
+
AIFormRegistryProvider,
|
|
308
|
+
AIToolRendererProvider,
|
|
309
|
+
ChatProvider,
|
|
310
|
+
type AIToolRendererMap,
|
|
311
|
+
} from '@nocobase/app-plugin-agents/client/chat';
|
|
312
|
+
import { FormProposalRenderer } from './form-proposal-card.js';
|
|
313
|
+
import { EXAMPLES_FORM_TOOL } from '../../../shared/ai-form-fill.js';
|
|
314
|
+
|
|
315
|
+
const toolRenderers: AIToolRendererMap = {
|
|
316
|
+
[EXAMPLES_FORM_TOOL]: FormProposalRenderer,
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// Replace/wrap the existing owner's location; do not add a second ChatProvider.
|
|
320
|
+
<AIFormRegistryProvider>
|
|
321
|
+
<AIToolRendererProvider renderers={toolRenderers}>
|
|
322
|
+
<ChatProvider>{children}</ChatProvider>
|
|
323
|
+
</AIToolRendererProvider>
|
|
324
|
+
</AIFormRegistryProvider>;
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Keep the application's existing authenticated-lifetime key, cache/panel reset, readiness checks and cleanup around this composition. `children` is the existing page/panel tree. A registry instance shared outside that lifetime would let old local operations outlive the account that created them.
|
|
328
|
+
|
|
329
|
+
1. On the page, attach `useAIForm`'s returned callback to `<form ref={ref}>`, declare safe readable fields and editable capabilities, and expose `getSnapshot: () => registry.snapshot(id)` with `useChatUIContextSource` as shown above.
|
|
330
|
+
2. Let the user explicitly select the form. Examples combines this intent with opening chat through the AI icon in the draft Card header: after creating the scoped conversation, it calls `sources.selectUI({ kind: 'form', id }, true)` before opening the panel. Registration, visiting the page and the ordinary header chat remain separate from inclusion.
|
|
331
|
+
3. From the existing page's `useChatApi()` and `useChatPanel()` hooks, the Examples form icon calls `api.createConversation({ agentId: 'online', config: { scope: [EXAMPLES_FORM_SCOPE] }, selectedModel: { modelService: service.name, model: model.value } })`, selects the form, then calls `panel.openChat({ conversationId: conversation.id, draft: prompt })`. It does not send automatically. The shared panel's composer chip displays the included form and can remove it.
|
|
332
|
+
4. The installed composer awaits the selected sources at Send. The server admits and saves that user message and its UI snapshot, executes the application tool and returns the safe SDK tool output with the exact source-message linkage. The registered renderer parses only `output-available` through the application's strict schema; all other states remain non-applying UI.
|
|
333
|
+
5. The card obtains its target only from `context.sourceContext`, checks the proposal's id/instance/identity/revision against that selected source, lets the user edit fields, validates the current editor values and calls `registry.apply` on a click with a stable conversation/message/tool operation key. Its cancel button never invokes the setter. It awaits the result and reports applied/partial/failed/stale honestly, aborting tracked work on unmount.
|
|
334
|
+
6. Only the guarded synchronous adapter commit changes the browser draft. A manual edit after Send, record A→B→A, missing source history, unmounted form or changed account prevents an old proposal from acquiring a new target. Reload/history replay never reapplies a card. No save endpoint, business write, fabricated tool result, `addToolOutput`, continuation or second chat state is involved.
|
|
335
|
+
|
|
336
|
+
These steps are implemented together in Examples; the generic plugin is not restricted to this form kind, schema or tool name. See [Examples usage and verification](../../../templates/app-template-examples/online-agent.md#ai-form-fill-browser-drafts-only) before running the example.
|
|
337
|
+
|
|
338
|
+
## Public low-level helpers
|
|
339
|
+
|
|
340
|
+
- `new AIFormRegistry()` creates an isolated local registry. Normally let `AIFormRegistryProvider` own it; an explicit `registry` prop is useful for application composition or tests.
|
|
341
|
+
- `registry.register(registration)` returns `{ instance, update, unregister }`. `update` refreshes callbacks/capabilities for the same id and identity; changing identity requires a new registration. Duplicate live ids throw. Stale `unregister` calls cannot delete a later instance.
|
|
342
|
+
- `registry.list()` and `registry.locate(id)` expose detached read-only descriptors, never a setter handle. They do not subscribe React components to changes; use the form's application state for selection and reactive UI. Operation results remain the execution authority.
|
|
343
|
+
- `registry.snapshot(id)` reads declared safe values with asynchronous stale-read protection, returning a JSON item suitable for explicitly selected UI context.
|
|
344
|
+
- `registry.apply(request)` is the controlled execution boundary. Do not recreate an unchecked `registry.get(id).setValues(...)` route around it.
|
|
345
|
+
|
|
346
|
+
Related contracts: [UI messages](ui-messages.md), [UI message clients](ui-message-clients.md), and the Examples application's AI form-fill page and application-owned tool/card. The plugin supplies no default form tool or card and does not call `addToolOutput` for local draft application.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Execution history
|
|
2
|
+
|
|
3
|
+
`Run.executions` contains claim snapshots in attempt order. Each snapshot preserves `attempt`, `runnerId`, `runnerName`, `runnerOwnerUserId`, `runnerOwnerName`, `runnerTrust`, `tool`, `toolVersion`, `modelService`, requested `model`, reported `actualModels`, `effort`, `dispatchedAt`, `finishedAt` and `failureReason`. Renaming or removing a runner does not change these facts. Runs that earlier versions answered with an online agent identify the application holder as `server:<instance>` and have no machine owner or coding-tool version.
|
|
4
|
+
|
|
5
|
+
`Run.runnerId` continues to mean the current holder. A retry releases it to null; `executions.at(-1)` still identifies the preceding attempt. Flat `runnerName`, `runnerOwnerUserId`, `runnerOwnerName`, `toolVersion` and `actualModels` describe the latest captured attempt in both run lists and details. Do not replace the current holder with historical data when authorizing a report.
|
|
6
|
+
|
|
7
|
+
`model` and `effort` are requested settings, not actual values. `actualModels` lists unique models reported by the primary tool in live usage events or ending reports; the online runs of earlier versions populated it immediately. Usage from other tools does not replace the primary model. Multiple reported models remain visible. Always label the requested and actual values separately, including when they match. An empty model array means the actual model was not reported; action badges must not substitute the requested model. Null requested models are a legacy default configuration; the default/actual wording is for these records, not a new execution configuration. Runners must explicitly configure a model for new executions; enforcement is separate from this history contract.
|
|
8
|
+
|
|
9
|
+
`actualEffort`, `actualEffortSource` and `actualEffortAt` are the latest tool report and its provenance/time, present on the snapshot and flat run view. `effortReports` retains value/source changes for that attempt. A primary-tool status event reports `meta.execution: { effort: string | null, source: string }`; its event time is the change time. Helpers, bare request metadata and reasoning token counts never establish actual effort. `actualEffortObservedAt` independently retains the latest accepted observation time, including repeated values, and falls back to the last change report for older snapshots. Repeated reports do not change the original change time; delayed older reports do not replace newer values. Null means unreported, including when an override invalidates a previously reported default. Render “Actual reasoning not reported” rather than inferring a value.
|
|
10
|
+
|
|
11
|
+
The Codex adapter reports the value returned by `thread/start` or `thread/resume`. A per-turn effort override has no resolved effort in the `turn/start` response, so that adapter explicitly reports null with source `codex.turn/start`; the requested effort remains visible. Other adapters/providers without a resolved report leave the actual value unknown. This contract needs the updated runner as well as the updated plugin.
|
|
12
|
+
|
|
13
|
+
Stored snapshots are internal facts. The agents HTTP routes apply `runForViewer`/`executionForViewer` with the same machine rights as runner routes: the snapshot's owner, runner managers, or readers of all runners who may invoke an agent. Others receive null `runnerName`, `runnerOwnerName` and `runnerTrust`, with `machineHidden: true`; the UI displays a generic team runtime and never falls back to its id. The projects viewer defaults to owner-only machine visibility; its host can supply `Viewer.seesExecutionMachine` after checking these same rights. Activities, thread pages, issue detail and comment mutations apply that projection; internal comment reads with no viewer deny machine visibility. Custom application run/CLI/workload outputs must apply the agents projection too, and action enrichment must reapply it after lookup.
|
|
14
|
+
|
|
15
|
+
Older runs have no execution snapshots. Their primary-tool usage still supplies `actualModels`, but these models cannot reliably be assigned to individual historical attempts. Do not construct historical machine names or tool versions from a runner's current configuration. The migration does not manufacture snapshots or attempt boundaries.
|
|
16
|
+
|
|
17
|
+
An application rendering UI Library's `agent-run-history` maps `executions` directly into `AgentRunHistoryRun.executions`; `execution` can supply a legacy or specific action's execution. `previousRunnerId` enables comparison with the preceding run on the same subject. `RunHeader`, the list and activity rows show these facts, and `RunAttempts` shows individual attempts. Supply `labels.execution` for translated wording. `RunExecutionBadge` accepts `href` and `onOpen` to open an originating run from an action.
|
|
18
|
+
|
|
19
|
+
For projects actions, pass the originating `runId`, `agentId` and `execution` snapshot through `Actor.trace` with `via: 'agent'`. Activities return these as `Activity.via`; comments return them as `IssueComment.source` while preserving the existing transport `via`. The projects plugin treats execution ids as opaque and has no dependency on agents. If the action precedes model reporting, its persisted snapshot remains what was known at that moment; the application may enrich the badge from an authorized lookup of the matching run and attempt, never a later retry's model.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# MySQL installation and directory index upgrade
|
|
2
|
+
|
|
3
|
+
`agRuns.directoryKey` retains its full 1100-character capacity. The redundant `(directoryKey, status)` index is removed: directory contention queries use the existing `(runnerId, status)` index and compare the complete directory values afterward. No directory values are shortened or rewritten.
|
|
4
|
+
|
|
5
|
+
The released creation migration `202610020003_ag_create_runs` is corrected because the old index exceeds MySQL's utf8mb4 index budget and prevents fresh installations from reaching any later migration. `202610260001_ag_drop_directory_index` removes that index from existing installations. When the corrected creation migration has already omitted it, the correction is skipped without a history entry so a fresh installation remains reversible. When executed against an old schema, the forward correction is irreversible because restoring that index would invalidate MySQL installations again.
|
|
6
|
+
|
|
7
|
+
Existing installations must review and acknowledge the changed migration checksum, then apply the forward migration. Follow the [shared upgrade and failed-installation recovery procedure](../../app-plugin-releases/docs/mysql-installation-upgrade.md). When releases is not installed, only the agents creation migration's checksum changes. Checksum repair does not perform schema changes and does not clean up tables left by a previously failed MySQL installation.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Agents discovered from runners
|
|
2
|
+
|
|
3
|
+
Each runner reports the coding tools it has, and for each tool whether it is signed in and the models its account lists (`tools[].models`). In the transaction of that report, `AgentService.syncRunner` keeps one agent for each tool and model the runner reports for a tool it has enabled, installed and signed in (`reportedModels` in `shared/runners.ts`): a combination no agent exists for yet becomes a new agent, `pending`, and the agents the runner still reports get their `lastReportedAt` refreshed, at most every ten minutes. The agent's id is `runnerAgentId(tool, model)`, so two runners reporting the same combination keep one agent.
|
|
4
|
+
|
|
5
|
+
Models are normalized before they are compared (`normalizeModel` in `shared/model-catalog.ts`): a known alias such as Claude Code's `opus` becomes the catalog's id, a release suffix (a date or `-latest`) is dropped, and OpenCode and Pi keep their `provider/` prefix with the model after it normalized the same way. The catalog names each agent (`agentNameOf`, such as "Claude · Opus 5.5") and suggests, in English and Chinese, what it is good at; a model it does not know is named after its id with nothing suggested. Keep the catalog to the models the tools offer today, checked against `TOOL_MODEL_SUGGESTIONS` in `@nocobase/agent-protocol`; removing a model from it only loses its label and suggestion, never the agent.
|
|
6
|
+
|
|
7
|
+
A pending agent is offered no work. Someone who manages agents (`agents.agents` manage) enables it on the Agent page or with `PATCH /api/agents/:agentId` (`agent update` on the CLI), writing what it is good at (required: `GOOD_AT_REQUIRED` otherwise) and, optionally, its default reasoning effort among those its tool takes (`EFFORT_UNSUPPORTED` otherwise; `medium` by default when the tool takes it). Every change names the revision it was made against and is refused with `REVISION_CONFLICT` when the agent changed since. Disabling an agent withdraws its queued runs and announces `agent.removed` with `reason` `disabled`; its conversations report it as not enabled until it is enabled again.
|
|
8
|
+
|
|
9
|
+
Where an agent can run is worked out per caller (`GET /api/agents`, `AgentView`): the online team runners and personal runners whose tool is enabled, installed and signed in with the agent's model, not marked unavailable there, and whose owner's policy takes the agent. `personalOnly` says only personal runners have it, which take their owners' work only. `unusable` says why the caller's work cannot start now: `pending`, `disabled`, `unreported` (no runner reported it for 14 days, `AGENT_UNREPORTED_AFTER_MS`), `notConfigured` (an application's own agent with no tool and model yet), `noRunner` or `othersPersonal` (only other people's personal runners have it). The roster a project manager picks from (`GET /api/agents/available`, `Agents.roster`) lists the enabled agents reported recently, each with whether a runner would take the caller's work now.
|
|
10
|
+
|
|
11
|
+
A run fails `modelUnavailable` when the tool's account cannot use the model after all. The claim's runner then marks that tool and model unavailable (`Runner.unavailableModels`, with the models it reported at the time), and no claim offers the model there until the runner reports the tool's models differently, such as after its account changed. Other runners are unaffected.
|
|
12
|
+
|
|
13
|
+
An application keeps agents of its own with `ensureSystem` (`source` `system`), such as a project manager: their name, description, instructions, business actions and tools and models are what the application writes, and people do not change them (`AGENT_MANAGED`). Every discovered agent gets the application's instructions and business actions through `setDefaults(provider)`; `applyDefaults()` writes them to every agent that differs, so a change in the application reaches agents discovered before it. An application updating only its compatibility action catalog can use `applyDefaults({ preserveInstructions: true })` to retain existing instructions.
|
|
14
|
+
|
|
15
|
+
Upgrading removes every agent an earlier version kept, online agents included (`202610240020_ag_runner_agents`): their rows stay, marked `deletedAt` and disabled, so the runs, comments and conversations that name them still show their names; their queued runs are cancelled, their pending run requests withdrawn, and the default chat agents that named them cleared. Nothing replaces them until runners report again and someone enables the agents that appear. The model services stay and keep serving the application's own model calls.
|
|
16
|
+
|
|
17
|
+
## Discovery management
|
|
18
|
+
|
|
19
|
+
Subject context providers may implement `prepare(run)` to read permissions outside the claim transaction; `assemble(conn, claim, prepared)` consumes its result inside the transaction. Failed preparation provides no result, so consumers must default to no capabilities. The same preparation runs when reading an active run's context or skill list. This prepares context and checkout guidance only; operation authorization still checks current identity permissions on every request.
|
|
20
|
+
|
|
21
|
+
The Agent page opens with enabled agents only, including enabled agents without an online runner. New discoveries are collapsed by default, grouped by tool, and searchable by catalog name, model ID or provider. Its count is the number of display groups. Disabled agents have a separate accessible view. Known catalog models share a display group across providers; unknown models keep the full provider-qualified ID. This grouping never changes `runnerAgentId`, existing database rows or execution model entries. The enable dialog selects the original provider candidate and shows its runner availability; opening an enabled agent also exposes its other provider candidates.
|
|
22
|
+
|
|
23
|
+
Administrators share ignore preferences, stored separately in `agDiscoveryPreferences` by `discoveryKey(tool, model)`. Only pending discoveries are hidden; disabled agents stay accessible and enabled groups cannot be ignored. The ignored view restores a group to the pending discovery list without enabling it. Reports, refreshes, restarts and newly reported providers of the same known model preserve the preference. Ignoring never deletes an agent or changes its description, execution entries or historical references.
|
|
24
|
+
|
|
25
|
+
`PUT /api/agents/discoveryPreferences` (`agent discovery set --input <file>`) requires `agents.agents` manage. Send `{ "groups": [{ "key": "pi:gpt-6-astra", "expectedRevision": 0 }], "ignored": true }`; use `false` to restore. `GET /api/agents` returns each group's `discoveryKey`, `discoveryRevision` and `ignored` alongside the existing view. Batches are atomic and limited to 256 unique keys. Ignoring and enabling lock and increment the same preference revision; stale requests return `409 REVISION_CONFLICT`, and enabling an ignored group requires restoring it first. Non-pending candidates remain in their existing state. The new migration adds only the preference table, leaving every existing agent and reference unchanged; rollback removes preferences and does not remove agents.
|
|
26
|
+
|
|
27
|
+
Bulk ignore and restore select at most 256 discovery groups per transaction. The page shows the selected count and limit; when more results match, the selection button explicitly chooses only the first 256. Searches reset selection, and additional unchecked groups cannot be selected until a group is deselected. Provider selectors display the full model and runner names while submitting the original agent ID.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# UI message clients
|
|
2
|
+
|
|
3
|
+
The public client entry is `@nocobase/app-plugin-agents/client/chat`. `ChatProvider` owns one `@ai-sdk/react` Chat per conversation. Sidebar, full-page and home surfaces share that owner. The SDK owns messages, ordered parts, streaming status, response parsing, approval updates and resumption. The application coordinator owns history page metadata, unknown submissions, admission reconciliation, identity disposal and business Stop.
|
|
4
|
+
|
|
5
|
+
Mount a single provider inside the application's router and key its lifetime by authenticated identity. Dispose the old identity before mounting the next, clear the unscoped panel storage and chat query cache, and discard retained application callbacks. Examples implements this in `OnlineAgentProvider`; it preserves drafts across surface changes within the same identity. A request finishing after disposal cannot publish messages, navigate an abandoned editor, update another account's cache or invoke retained Undo.
|
|
6
|
+
|
|
7
|
+
## Input, admission and recovery
|
|
8
|
+
|
|
9
|
+
The SDK transport uses the host's authenticated `ApiClient.stream`. A POST contains only the current `message: { id, role: "user", parts: [{ type: "text", text }] }`, authorized attachment IDs and optional page context. It never sends the SDK's complete browser history, assistant parts or tool output as input. Uploaded files remain the existing attachment service's responsibility.
|
|
10
|
+
|
|
11
|
+
The response headers acknowledge admission; the coordinator then reads canonical history and conversation detail. Pending controls remain until the stable user ID, or Runner's `metadata.clientId`, is found in saved history. An unknown POST result is reconciled without automatic resend. Explicit creation recovery still warns that a conversation may already have been created.
|
|
12
|
+
|
|
13
|
+
Initial recovery starts only for a known running, non-approval-waiting conversation. GET recovery uses the SDK transport's reconnect entry, including on browser online/realtime reconnection. Manual recovery never POSTs user input. The shared component replays a response's full prefix. After a network error, the coordinator retires the SDK owner that retained delta-resume state and publishes one fresh shared owner using public UIMessage state. Pending tool state is reread from trusted history before replay; a missing stream retains the interrupted display and occupancy. No SDK private fields or custom stream parser are used. A missing/expired stream or a disabled shared recovery facility leaves durable history and execution detail authoritative. An SDK `ready`, EOF, `onFinish` or standard `finish` cannot mark business execution complete. Approval waiting remains occupied.
|
|
14
|
+
|
|
15
|
+
Stop uses the independent business endpoint. It remains stopping until trusted detail confirms idle. Disposing a subscriber only stops its SDK reader. A lost reader may be released after its matching saved assistant message and terminal execution have been read; that reconciliation never stops business execution or repeats input/tools. Save failure keeps occupancy and exposes explicit finalization retry with visible failure feedback.
|
|
16
|
+
|
|
17
|
+
## History and source segments
|
|
18
|
+
|
|
19
|
+
An aborted SDK text part can retain `state: "streaming"` in saved history. A writing cursor therefore also requires the message to own the current active SDK response. Registry and Examples pass that presentation flag only to the active response at the SDK working array's tail; saved partial replies stay still after Stop, refresh and later turns. This presentation flag does not establish business completion.
|
|
20
|
+
|
|
21
|
+
History APIs return `AppUIMessage[]`. During a live response the SDK working array keeps its active assistant last so subsequent SDK chunks update it in place. Independent notices remain in that same owner; source metadata determines their displayed position. Approval and recovery select the same response target, and the scroll anchor follows the first displayed source segment. Merge by message ID and monotonic `metadata.revision`; preserve an actively streaming SDK assistant against stale history snapshots. A canonical user replaces its optimistic counterpart by ID or client ID. Drain every `nextAfter` page before advancing the forward watermark. Revision events reread exact IDs in batches of at most 100 and never advance that watermark. Failed revision reads retain the requested IDs for later durable polls or repeated announcements until the requested revision is acknowledged.
|
|
22
|
+
|
|
23
|
+
`chatMessageSegments(messages)` creates rendering descriptors referencing the original SDK object. It does not create additional logical messages. Each Runner source record carries its actual sequence, creation time, source record ID and stable part ID in `metadata.sourceRecords`. Render the descriptor's part indexes at its source time; independent notifications retain their own identity between source blocks. A complete logical message remains intact in history pagination. Render `renderMessageExtra` once, on the final segment.
|
|
24
|
+
|
|
25
|
+
The shared presentation omits empty text, SDK step/reasoning bookkeeping, and only the framework's `execution-status` success notice; the original SDK messages and their durable execution outcomes remain unchanged. Thinking is shown at the next response position rather than as an empty assistant bubble. Successful turns add no generic completion banner, while failure, cancellation, approval and uncertain-effect feedback remain available. An application's `renderMessageExtra` still renders once even when the message has no visible standard parts. The Registry transcript scrolls vertically; long code blocks and tables keep their bounded, local scrolling rather than widening the conversation.
|
|
26
|
+
|
|
27
|
+
Native messages generally have one segment. The server places the authorized display snapshot in `metadata.context`, stripping provider-private fields. Input context remains IDs-only and is reauthorized on the server. File parts use their authorized URL and media type; the installed attachment list retains image previews without inventing a size the SDK file part does not contain.
|
|
28
|
+
|
|
29
|
+
## Extensions
|
|
30
|
+
|
|
31
|
+
`ChatExtensionsContext` accepts UIMessage directly. Existing application business components adapt to these public boundaries:
|
|
32
|
+
|
|
33
|
+
| Extension | Input and behavior |
|
|
34
|
+
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
35
|
+
| `useTimelineItems(conversationId, revision)` | Stable-key business items sorted by time among source segments; the hook may query authorized application data. Message insertions, revisions and business occupancy update its revision input. Application business subscriptions may refresh its own queries independently. |
|
|
36
|
+
| `renderMessageExtra(message)` | The complete original UIMessage once per logical message. Extract all text with `appUIMessageText`; reference discovery, code exclusion, deduplication and record permissions remain application responsibilities. |
|
|
37
|
+
| `renderNews(notice, message)` | Independent `data-notice` card. Returning null falls back to `newsText`, then the persisted title. |
|
|
38
|
+
| `newsText(notice, t)` | Localized wording, or null for the persisted title. |
|
|
39
|
+
| `renderDataPart(part, message)` | Ordered public `data-notice` or `data-business` display. Null retains the built-in display, including the ConsultationCard for a genuine consultation payload. |
|
|
40
|
+
|
|
41
|
+
Independent system notifications are persisted through the existing `ConversationService.deliver()` business transaction, then read through business announcements or durable polling. They do not write into a finished model response or wake a new OnlineAgent execution. There is no separate `OnlineAgentService.notify()` entry. These display contracts do not restore a historical Studio plan/delegation producer or the deleted ask_agent chain.
|
|
42
|
+
|
|
43
|
+
`Composer` exposes `toolbar` and `notice` as child component props. The installed view uses them for application actions and notices; they are not generic top-level ChatPanel slots. Preserve application-owned headers, avatars, menus and readiness/error handling when updating installed Registry source.
|
|
44
|
+
|
|
45
|
+
Tool approval buttons use genuine SDK approval parts, binding `messageId`, `executionId` and `approval.id` to the server's pending call. SDK approval updates are followed by a controlled approval POST and canonical reread. They never submit browser tool output. Runner does not gain remote tool approval support. Effect-review hints are advisory after actual tool termination and finalization; pending approvals still enforce their owner, execution, message and tool-call bindings.
|
|
46
|
+
|
|
47
|
+
## Requests and cost
|
|
48
|
+
|
|
49
|
+
A visible conversation has one shared durable-history poll, regardless of surfaces: every 5 seconds while running, every 30 seconds while idle, and none while the document is hidden or after the last surface unmounts. This provides independent-notification catch-up when instance-local announcements are missed. Running conversation detail retains the existing 5-second React Query polling; shared keys deduplicate in-flight reads, while staggered observers can each refetch. The SDK stream removes the old one-second text-growth polling.
|
|
50
|
+
|
|
51
|
+
A forward history poll makes one GET plus each bounded `nextAfter` continuation. Recovery of an interrupted pending tool can add one ID GET before its GET stream. A revision announcement makes one batched ID GET; duplicate revision announcements from multiple surfaces are coalesced. Successful input admission adds history reconciliation and a detail GET; SDK completion/recovery adds detail, forward history and an ID reread for a revisable assistant. A stalled subscription may require a second completion reconciliation after its SDK reader stops. None of these reads creates SQL writes, locks or transactions. Source creation timestamps and public context are derived in the existing projection/snapshot write; no new storage write is introduced.
|
|
52
|
+
|
|
53
|
+
Measured warm read requests, excluding the host's authentication and authorization queries, are shown below. The native fixture has one completed reply; the Runner fixture has two saved source blocks and an interleaved notification. These counts describe the extra requests a client makes, not new SQL added inside an existing endpoint. Every sample has zero writes, transactions and explicit locks.
|
|
54
|
+
|
|
55
|
+
| Request | Native SELECTs | Runner SELECTs |
|
|
56
|
+
| -------------------------------- | -------------: | -------------: |
|
|
57
|
+
| Full history | 3 | 6 |
|
|
58
|
+
| Forward poll with no new row | 3 | 4 |
|
|
59
|
+
| One logical message reread by ID | 3 | 5 |
|
|
60
|
+
| Saved execution detail | 2 | 6 |
|
|
61
|
+
|
|
62
|
+
Thus an added idle forward poll costs three native or four Runner SELECTs per visible conversation every 30 seconds in these fixtures. Opening a page, reading a changed group or following pagination adds its corresponding read requests. Batched IDs and larger source groups change row counts and execution time; the table is not a production latency estimate. Existing approval, input, Stop and finalization mutations retain their server-side costs; the SDK coordinator does not add another mutation or lock around them.
|
|
63
|
+
|
|
64
|
+
The server's existing native, notification and shared Redis costs remain those in [UI messages](./ui-messages.md#shared-recovery-request-cost). Runner claims, heartbeats, execution scheduling, synchronization, lifecycle and machine writes are unchanged.
|
|
65
|
+
|
|
66
|
+
## CLI input
|
|
67
|
+
|
|
68
|
+
The public command uses the same current-message body, without legacy `content/clientId` request mapping. Put the entire JSON body in a file:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"message": {
|
|
73
|
+
"id": "new-client-uuid",
|
|
74
|
+
"role": "user",
|
|
75
|
+
"parts": [{ "type": "text", "text": "Review the checklist" }]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Run `conversation message send <conversation> --file current-user-message.json`, optionally with repeatable `--attach`. Use a new ID for a new input. An unknown outcome requires history/state reconciliation; do not blindly repeat the command. Its response is the standard UI stream, not the former JSON send envelope. The history command's columns read SDK `metadata.seq`, `role`, `parts` and `metadata.createdAt` directly.
|