aimeat 1.27.0 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.env.example +2 -0
- package/dist/locales/en.json +538 -297
- package/dist/locales/fi.json +500 -259
- package/dist/public/components/NotificationBell.js +2 -4
- package/dist/public/css/views/agents-detail.css +11 -0
- package/dist/public/css/views/app-grant.css +35 -3
- package/dist/public/css/views/inbox.css +78 -0
- package/dist/public/css/views/landing.css +8 -0
- package/dist/public/css/views/living.css +187 -0
- package/dist/public/css/views/notebook.css +89 -0
- package/dist/public/css/views/profile.css +78 -85
- package/dist/public/js/app-sandbox.js +18 -59
- package/dist/public/js/presence-store.js +7 -1
- package/dist/public/js/services/agents.js +10 -3
- package/dist/public/js/services/generator-prompts-base.js +40 -3
- package/dist/public/js/services/living.js +506 -0
- package/dist/public/js/services/memory.js +23 -3
- package/dist/public/js/services/nodes.js +1 -1
- package/dist/public/js/services/notebook-plan.js +211 -0
- package/dist/public/js/services/notebook.js +97 -0
- package/dist/public/js/services/organisms.js +41 -2
- package/dist/public/js/services/tracked-responses.js +103 -0
- package/dist/public/js/utils.js +15 -0
- package/dist/public/lib/live-updates.js +231 -94
- package/dist/public/spa.html +8 -1
- package/dist/public/types/aimeat-globals.d.ts +4 -0
- package/dist/public/views/admin/agent-integration-tab.js +2 -5
- package/dist/public/views/admin/agent-tasks-tab.js +2 -5
- package/dist/public/views/admin/cortex-tab.js +2 -5
- package/dist/public/views/admin/federation-tab.js +3 -10
- package/dist/public/views/admin/memory-tab.js +2 -5
- package/dist/public/views/admin/messages-tab.js +2 -5
- package/dist/public/views/admin/packages-tab.js +2 -5
- package/dist/public/views/admin/sharing-groups-tab.js +2 -5
- package/dist/public/views/app-grant.js +126 -23
- package/dist/public/views/landing-node-totals.js +71 -0
- package/dist/public/views/landing.js +6 -4
- package/dist/public/views/profile/agents/agent-card.js +8 -5
- package/dist/public/views/profile/agents/tab-activity.js +2 -3
- package/dist/public/views/profile/agents/tab-agent-config.js +2 -3
- package/dist/public/views/profile/agents/tab-data-access.js +2 -3
- package/dist/public/views/profile/agents/tab-integration.js +2 -3
- package/dist/public/views/profile/agents/tab-messages.js +2 -6
- package/dist/public/views/profile/agents/tab-quality.js +2 -5
- package/dist/public/views/profile/agents/tab-schedules.js +2 -4
- package/dist/public/views/profile/agents-activity-subtab.js +2 -5
- package/dist/public/views/profile/agents-capabilities-subtab.js +2 -2
- package/dist/public/views/profile/agents-messages-subtab.js +2 -5
- package/dist/public/views/profile/agents-services-subtab.js +2 -3
- package/dist/public/views/profile/agents-tab.js +70 -90
- package/dist/public/views/profile/agents-tasks-subtab.js +3 -8
- package/dist/public/views/profile/apps-tab.js +17 -0
- package/dist/public/views/profile/boards-tab.js +2 -5
- package/dist/public/views/profile/chat-sessions-tab.js +2 -5
- package/dist/public/views/profile/ecosystem-tab.js +7 -12
- package/dist/public/views/profile/extensions-tab.js +2 -5
- package/dist/public/views/profile/federation-tab.js +2 -5
- package/dist/public/views/profile/inbox-tab.js +280 -14
- package/dist/public/views/profile/knowledge-tab.js +2 -5
- package/dist/public/views/profile/landing-page.js +260 -184
- package/dist/public/views/profile/living-tab.js +480 -0
- package/dist/public/views/profile/memory-tab.js +2 -5
- package/dist/public/views/profile/notebook-card.js +515 -0
- package/dist/public/views/profile/notebook-helpers.js +48 -0
- package/dist/public/views/profile/notebook-tab.js +40 -260
- package/dist/public/views/profile/organisms/activity-panel.js +3 -2
- package/dist/public/views/profile/organisms/home.js +52 -3
- package/dist/public/views/profile/organisms/members.js +2 -5
- package/dist/public/views/profile/organisms/mindmap.js +194 -0
- package/dist/public/views/profile/organisms/panels.js +3 -10
- package/dist/public/views/profile/organisms/participants-panel.js +3 -2
- package/dist/public/views/profile/organisms/readme-panel.js +97 -0
- package/dist/public/views/profile/organisms/sources-panel.js +2 -5
- package/dist/public/views/profile/organisms/timeline-panel.js +104 -0
- package/dist/public/views/profile/organisms/workspace-comments.js +2 -5
- package/dist/public/views/profile/organisms/workspace-list.js +8 -8
- package/dist/public/views/profile/organisms/workspace.js +41 -6
- package/dist/public/views/profile/organisms-tab.js +3 -6
- package/dist/public/views/profile/packages-tab.js +2 -5
- package/dist/public/views/profile/scheduler-tab.js +2 -4
- package/dist/public/views/profile/track-response-modal.js +211 -0
- package/dist/public/views/profile/workflows-tab.js +4 -13
- package/dist/public/views/profile.js +10 -9
- package/dist/scripts/consent-audit-prune.d.ts +21 -0
- package/dist/scripts/consent-audit-prune.d.ts.map +1 -0
- package/dist/scripts/consent-audit-prune.js +198 -0
- package/dist/scripts/consent-audit-prune.js.map +1 -0
- package/dist/scripts/reassign-apps.d.ts +2 -0
- package/dist/scripts/reassign-apps.d.ts.map +1 -0
- package/dist/scripts/reassign-apps.js +99 -0
- package/dist/scripts/reassign-apps.js.map +1 -0
- package/dist/scripts/telemetry-prune.d.ts +20 -0
- package/dist/scripts/telemetry-prune.d.ts.map +1 -0
- package/dist/scripts/telemetry-prune.js +195 -0
- package/dist/scripts/telemetry-prune.js.map +1 -0
- package/dist/src/auth/jwt.d.ts +1 -0
- package/dist/src/auth/jwt.d.ts.map +1 -1
- package/dist/src/auth/jwt.js +13 -0
- package/dist/src/auth/jwt.js.map +1 -1
- package/dist/src/cli/connect/mcp/local-server.d.ts.map +1 -1
- package/dist/src/cli/connect/mcp/local-server.js +109 -0
- package/dist/src/cli/connect/mcp/local-server.js.map +1 -1
- package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
- package/dist/src/cli/connect/tool-call.js +9 -0
- package/dist/src/cli/connect/tool-call.js.map +1 -1
- package/dist/src/cli/connect/tunnel-client.d.ts +16 -0
- package/dist/src/cli/connect/tunnel-client.d.ts.map +1 -1
- package/dist/src/cli/connect/tunnel-client.js +42 -0
- package/dist/src/cli/connect/tunnel-client.js.map +1 -1
- package/dist/src/config.d.ts +7 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +4 -0
- package/dist/src/config.js.map +1 -1
- package/dist/src/generated/api-types.d.ts +1449 -128
- package/dist/src/generated/api-types.d.ts.map +1 -1
- package/dist/src/generated/prisma-postgres/edge.js +17 -3
- package/dist/src/generated/prisma-postgres/index-browser.js +14 -0
- package/dist/src/generated/prisma-postgres/index.d.ts +1580 -161
- package/dist/src/generated/prisma-postgres/index.js +17 -3
- package/dist/src/generated/prisma-postgres/package.json +1 -1
- package/dist/src/generated/prisma-postgres/schema.prisma +18 -0
- package/dist/src/generated/prisma-postgres/wasm.js +17 -3
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/agent-telemetry.d.ts +2 -0
- package/dist/src/mcp/agent-telemetry.d.ts.map +1 -1
- package/dist/src/mcp/agent-telemetry.js +8 -3
- package/dist/src/mcp/agent-telemetry.js.map +1 -1
- package/dist/src/mcp/annotations.d.ts.map +1 -1
- package/dist/src/mcp/annotations.js +1 -0
- package/dist/src/mcp/annotations.js.map +1 -1
- package/dist/src/mcp/apps.d.ts.map +1 -1
- package/dist/src/mcp/apps.js +14 -1
- package/dist/src/mcp/apps.js.map +1 -1
- package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
- package/dist/src/mcp/catalog/definitions.js +15 -0
- package/dist/src/mcp/catalog/definitions.js.map +1 -1
- package/dist/src/mcp/organisms.d.ts +2 -0
- package/dist/src/mcp/organisms.d.ts.map +1 -1
- package/dist/src/mcp/organisms.js +43 -0
- package/dist/src/mcp/organisms.js.map +1 -1
- package/dist/src/mcp/workspaces.d.ts.map +1 -1
- package/dist/src/mcp/workspaces.js +8 -1
- package/dist/src/mcp/workspaces.js.map +1 -1
- package/dist/src/routes/agent-messages.js +2 -2
- package/dist/src/routes/agent-messages.js.map +1 -1
- package/dist/src/routes/agent-tasks.js +14 -14
- package/dist/src/routes/agent-tasks.js.map +1 -1
- package/dist/src/routes/agent-telemetry.d.ts +3 -0
- package/dist/src/routes/agent-telemetry.d.ts.map +1 -1
- package/dist/src/routes/agent-telemetry.js +11 -6
- package/dist/src/routes/agent-telemetry.js.map +1 -1
- package/dist/src/routes/agents.d.ts.map +1 -1
- package/dist/src/routes/agents.js +41 -3
- package/dist/src/routes/agents.js.map +1 -1
- package/dist/src/routes/app-grants.d.ts +3 -0
- package/dist/src/routes/app-grants.d.ts.map +1 -1
- package/dist/src/routes/app-grants.js +120 -7
- package/dist/src/routes/app-grants.js.map +1 -1
- package/dist/src/routes/apps.d.ts +9 -0
- package/dist/src/routes/apps.d.ts.map +1 -1
- package/dist/src/routes/apps.js +110 -16
- package/dist/src/routes/apps.js.map +1 -1
- package/dist/src/routes/boards.d.ts.map +1 -1
- package/dist/src/routes/boards.js +4 -2
- package/dist/src/routes/boards.js.map +1 -1
- package/dist/src/routes/consent.d.ts.map +1 -1
- package/dist/src/routes/consent.js +14 -1
- package/dist/src/routes/consent.js.map +1 -1
- package/dist/src/routes/ghii.d.ts.map +1 -1
- package/dist/src/routes/ghii.js +20 -10
- package/dist/src/routes/ghii.js.map +1 -1
- package/dist/src/routes/librarian.d.ts.map +1 -1
- package/dist/src/routes/librarian.js +64 -2
- package/dist/src/routes/librarian.js.map +1 -1
- package/dist/src/routes/libs.d.ts +9 -0
- package/dist/src/routes/libs.d.ts.map +1 -1
- package/dist/src/routes/libs.js +261 -2
- package/dist/src/routes/libs.js.map +1 -1
- package/dist/src/routes/living.d.ts +18 -0
- package/dist/src/routes/living.d.ts.map +1 -0
- package/dist/src/routes/living.js +63 -0
- package/dist/src/routes/living.js.map +1 -0
- package/dist/src/routes/matches.d.ts.map +1 -1
- package/dist/src/routes/matches.js +1 -3
- package/dist/src/routes/matches.js.map +1 -1
- package/dist/src/routes/memory.d.ts.map +1 -1
- package/dist/src/routes/memory.js +40 -1
- package/dist/src/routes/memory.js.map +1 -1
- package/dist/src/routes/messages.d.ts +2 -0
- package/dist/src/routes/messages.d.ts.map +1 -1
- package/dist/src/routes/messages.js +27 -96
- package/dist/src/routes/messages.js.map +1 -1
- package/dist/src/routes/organisms.d.ts +8 -0
- package/dist/src/routes/organisms.d.ts.map +1 -1
- package/dist/src/routes/organisms.js +124 -3
- package/dist/src/routes/organisms.js.map +1 -1
- package/dist/src/routes/owners.d.ts.map +1 -1
- package/dist/src/routes/owners.js +2 -0
- package/dist/src/routes/owners.js.map +1 -1
- package/dist/src/routes/personal.d.ts.map +1 -1
- package/dist/src/routes/personal.js +7 -0
- package/dist/src/routes/personal.js.map +1 -1
- package/dist/src/routes/portal.d.ts +3 -0
- package/dist/src/routes/portal.d.ts.map +1 -1
- package/dist/src/routes/portal.js +19 -12
- package/dist/src/routes/portal.js.map +1 -1
- package/dist/src/routes/public-stats.d.ts +3 -0
- package/dist/src/routes/public-stats.d.ts.map +1 -1
- package/dist/src/routes/public-stats.js +48 -0
- package/dist/src/routes/public-stats.js.map +1 -1
- package/dist/src/routes/sse.d.ts +3 -0
- package/dist/src/routes/sse.d.ts.map +1 -1
- package/dist/src/routes/sse.js +27 -15
- package/dist/src/routes/sse.js.map +1 -1
- package/dist/src/routes/storage-files.d.ts +2 -0
- package/dist/src/routes/storage-files.d.ts.map +1 -1
- package/dist/src/routes/storage-files.js +14 -17
- package/dist/src/routes/storage-files.js.map +1 -1
- package/dist/src/routes/subdomains.d.ts +28 -0
- package/dist/src/routes/subdomains.d.ts.map +1 -1
- package/dist/src/routes/subdomains.js +138 -11
- package/dist/src/routes/subdomains.js.map +1 -1
- package/dist/src/routes/tracked-responses.d.ts +27 -0
- package/dist/src/routes/tracked-responses.d.ts.map +1 -0
- package/dist/src/routes/tracked-responses.js +212 -0
- package/dist/src/routes/tracked-responses.js.map +1 -0
- package/dist/src/routes/upload.js +8 -0
- package/dist/src/routes/upload.js.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.js +24 -0
- package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
- package/dist/src/server-bootstrap/service-init.d.ts.map +1 -1
- package/dist/src/server-bootstrap/service-init.js +4 -0
- package/dist/src/server-bootstrap/service-init.js.map +1 -1
- package/dist/src/server-bootstrap/static-files.d.ts +5 -0
- package/dist/src/server-bootstrap/static-files.d.ts.map +1 -1
- package/dist/src/server-bootstrap/static-files.js +33 -1
- package/dist/src/server-bootstrap/static-files.js.map +1 -1
- package/dist/src/services/access-guard.d.ts +4 -4
- package/dist/src/services/access-guard.d.ts.map +1 -1
- package/dist/src/services/access-guard.js +7 -8
- package/dist/src/services/access-guard.js.map +1 -1
- package/dist/src/services/activity-recorder.d.ts +2 -13
- package/dist/src/services/activity-recorder.d.ts.map +1 -1
- package/dist/src/services/activity-recorder.js +0 -42
- package/dist/src/services/activity-recorder.js.map +1 -1
- package/dist/src/services/connect-tunnel.d.ts +56 -3
- package/dist/src/services/connect-tunnel.d.ts.map +1 -1
- package/dist/src/services/connect-tunnel.js +216 -1
- package/dist/src/services/connect-tunnel.js.map +1 -1
- package/dist/src/services/consent-audit-buffer.d.ts +45 -0
- package/dist/src/services/consent-audit-buffer.d.ts.map +1 -0
- package/dist/src/services/consent-audit-buffer.js +85 -0
- package/dist/src/services/consent-audit-buffer.js.map +1 -0
- package/dist/src/services/consent.d.ts +9 -3
- package/dist/src/services/consent.d.ts.map +1 -1
- package/dist/src/services/consent.js +13 -5
- package/dist/src/services/consent.js.map +1 -1
- package/dist/src/services/core-jobs.d.ts.map +1 -1
- package/dist/src/services/core-jobs.js +20 -4
- package/dist/src/services/core-jobs.js.map +1 -1
- package/dist/src/services/event-bus.d.ts +24 -1
- package/dist/src/services/event-bus.d.ts.map +1 -1
- package/dist/src/services/event-bus.js +17 -2
- package/dist/src/services/event-bus.js.map +1 -1
- package/dist/src/services/generator-prompts/resolvers.d.ts +2 -0
- package/dist/src/services/generator-prompts/resolvers.d.ts.map +1 -1
- package/dist/src/services/generator-prompts/resolvers.js +22 -3
- package/dist/src/services/generator-prompts/resolvers.js.map +1 -1
- package/dist/src/services/job-seeding.d.ts.map +1 -1
- package/dist/src/services/job-seeding.js +4 -0
- package/dist/src/services/job-seeding.js.map +1 -1
- package/dist/src/services/living-author-prompt.d.ts +14 -0
- package/dist/src/services/living-author-prompt.d.ts.map +1 -0
- package/dist/src/services/living-author-prompt.js +47 -0
- package/dist/src/services/living-author-prompt.js.map +1 -0
- package/dist/src/services/living-author.d.ts +55 -0
- package/dist/src/services/living-author.d.ts.map +1 -0
- package/dist/src/services/living-author.js +91 -0
- package/dist/src/services/living-author.js.map +1 -0
- package/dist/src/services/living-pulse.d.ts +29 -0
- package/dist/src/services/living-pulse.d.ts.map +1 -0
- package/dist/src/services/living-pulse.js +363 -0
- package/dist/src/services/living-pulse.js.map +1 -0
- package/dist/src/services/message-delivery.d.ts +1 -1
- package/dist/src/services/message-delivery.d.ts.map +1 -1
- package/dist/src/services/message-delivery.js +10 -7
- package/dist/src/services/message-delivery.js.map +1 -1
- package/dist/src/services/message-send.d.ts +24 -0
- package/dist/src/services/message-send.d.ts.map +1 -0
- package/dist/src/services/message-send.js +122 -0
- package/dist/src/services/message-send.js.map +1 -0
- package/dist/src/services/notebook-ai.d.ts +36 -0
- package/dist/src/services/notebook-ai.d.ts.map +1 -0
- package/dist/src/services/notebook-ai.js +51 -0
- package/dist/src/services/notebook-ai.js.map +1 -0
- package/dist/src/services/notebook-classify.d.ts +32 -5
- package/dist/src/services/notebook-classify.d.ts.map +1 -1
- package/dist/src/services/notebook-classify.js +59 -43
- package/dist/src/services/notebook-classify.js.map +1 -1
- package/dist/src/services/notebook-distribute-prompt.d.ts +16 -0
- package/dist/src/services/notebook-distribute-prompt.d.ts.map +1 -0
- package/dist/src/services/notebook-distribute-prompt.js +40 -0
- package/dist/src/services/notebook-distribute-prompt.js.map +1 -0
- package/dist/src/services/notebook-plan-prompt.d.ts +19 -0
- package/dist/src/services/notebook-plan-prompt.d.ts.map +1 -0
- package/dist/src/services/notebook-plan-prompt.js +54 -0
- package/dist/src/services/notebook-plan-prompt.js.map +1 -0
- package/dist/src/services/notebook-plan.d.ts +70 -0
- package/dist/src/services/notebook-plan.d.ts.map +1 -0
- package/dist/src/services/notebook-plan.js +118 -0
- package/dist/src/services/notebook-plan.js.map +1 -0
- package/dist/src/services/onboarding-validator.d.ts.map +1 -1
- package/dist/src/services/onboarding-validator.js +13 -3
- package/dist/src/services/onboarding-validator.js.map +1 -1
- package/dist/src/services/organism-comments.d.ts +5 -1
- package/dist/src/services/organism-comments.d.ts.map +1 -1
- package/dist/src/services/organism-comments.js +7 -22
- package/dist/src/services/organism-comments.js.map +1 -1
- package/dist/src/services/organism-readme.d.ts +24 -0
- package/dist/src/services/organism-readme.d.ts.map +1 -0
- package/dist/src/services/organism-readme.js +37 -0
- package/dist/src/services/organism-readme.js.map +1 -0
- package/dist/src/services/prompt-defaults.d.ts.map +1 -1
- package/dist/src/services/prompt-defaults.js +30 -0
- package/dist/src/services/prompt-defaults.js.map +1 -1
- package/dist/src/services/readiness-scorer.d.ts.map +1 -1
- package/dist/src/services/readiness-scorer.js +11 -6
- package/dist/src/services/readiness-scorer.js.map +1 -1
- package/dist/src/services/scheduler.d.ts +5 -0
- package/dist/src/services/scheduler.d.ts.map +1 -1
- package/dist/src/services/scheduler.js +13 -3
- package/dist/src/services/scheduler.js.map +1 -1
- package/dist/src/services/screenshot-capture.d.ts +28 -0
- package/dist/src/services/screenshot-capture.d.ts.map +1 -0
- package/dist/src/services/screenshot-capture.js +154 -0
- package/dist/src/services/screenshot-capture.js.map +1 -0
- package/dist/src/services/structure-graph.d.ts +65 -0
- package/dist/src/services/structure-graph.d.ts.map +1 -0
- package/dist/src/services/structure-graph.js +53 -0
- package/dist/src/services/structure-graph.js.map +1 -0
- package/dist/src/services/structure-overview.d.ts +6 -0
- package/dist/src/services/structure-overview.d.ts.map +1 -1
- package/dist/src/services/structure-overview.js +1 -1
- package/dist/src/services/structure-overview.js.map +1 -1
- package/dist/src/services/structure-snapshot.d.ts +47 -0
- package/dist/src/services/structure-snapshot.d.ts.map +1 -0
- package/dist/src/services/structure-snapshot.js +101 -0
- package/dist/src/services/structure-snapshot.js.map +1 -0
- package/dist/src/services/telemetry-buffer.d.ts +73 -0
- package/dist/src/services/telemetry-buffer.d.ts.map +1 -0
- package/dist/src/services/telemetry-buffer.js +185 -0
- package/dist/src/services/telemetry-buffer.js.map +1 -0
- package/dist/src/services/track-registry.d.ts +29 -0
- package/dist/src/services/track-registry.d.ts.map +1 -0
- package/dist/src/services/track-registry.js +61 -0
- package/dist/src/services/track-registry.js.map +1 -0
- package/dist/src/services/tracked-classify.d.ts +98 -0
- package/dist/src/services/tracked-classify.d.ts.map +1 -0
- package/dist/src/services/tracked-classify.js +182 -0
- package/dist/src/services/tracked-classify.js.map +1 -0
- package/dist/src/services/tracked-response.d.ts +98 -0
- package/dist/src/services/tracked-response.d.ts.map +1 -0
- package/dist/src/services/tracked-response.js +304 -0
- package/dist/src/services/tracked-response.js.map +1 -0
- package/dist/src/services/workspace-access.d.ts +36 -0
- package/dist/src/services/workspace-access.d.ts.map +1 -0
- package/dist/src/services/workspace-access.js +38 -0
- package/dist/src/services/workspace-access.js.map +1 -0
- package/dist/src/storage/interface.d.ts +6 -1
- package/dist/src/storage/interface.d.ts.map +1 -1
- package/dist/src/storage/interface.js.map +1 -1
- package/dist/src/storage/providers/mongodb/index.d.ts +26 -1
- package/dist/src/storage/providers/mongodb/index.d.ts.map +1 -1
- package/dist/src/storage/providers/mongodb/index.js +144 -1
- package/dist/src/storage/providers/mongodb/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/index.d.ts +26 -1
- package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/index.js +73 -6
- package/dist/src/storage/providers/sqlite/index.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent-message.d.ts +4 -0
- package/dist/src/storage/providers/sqlite/repos/agent-message.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent-message.js +14 -0
- package/dist/src/storage/providers/sqlite/repos/agent-message.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent-task.d.ts +9 -0
- package/dist/src/storage/providers/sqlite/repos/agent-task.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/agent-task.js +25 -0
- package/dist/src/storage/providers/sqlite/repos/agent-task.js.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/memory.d.ts +22 -1
- package/dist/src/storage/providers/sqlite/repos/memory.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/repos/memory.js +61 -3
- package/dist/src/storage/providers/sqlite/repos/memory.js.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.d.ts +16 -3
- package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.js +33 -6
- package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
- package/dist/src/storage/repositories/agent-message.repository.d.ts +10 -0
- package/dist/src/storage/repositories/agent-message.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/agent-task.repository.d.ts +15 -0
- package/dist/src/storage/repositories/agent-task.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/app.repository.d.ts +9 -0
- package/dist/src/storage/repositories/app.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/consent.repository.d.ts +2 -0
- package/dist/src/storage/repositories/consent.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/memory.repository.d.ts +31 -0
- package/dist/src/storage/repositories/memory.repository.d.ts.map +1 -1
- package/dist/src/utils/env-config.d.ts.map +1 -1
- package/dist/src/utils/env-config.js +18 -0
- package/dist/src/utils/env-config.js.map +1 -1
- package/dist/src/utils/messaging.d.ts +5 -0
- package/dist/src/utils/messaging.d.ts.map +1 -1
- package/dist/src/utils/messaging.js +0 -0
- package/dist/src/utils/messaging.js.map +1 -1
- package/dist/static/app-catalog.html +452 -34
- package/dist/static/app-login.js +67 -0
- package/dist/static/app-silent.html +14 -0
- package/dist/static/app-silent.js +32 -0
- package/package.json +5 -1
- package/prisma/schema.postgres.prisma +36 -18
- package/prisma/schema.prisma +20 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file notebook-plan.js
|
|
3
|
+
* @description Notebook stage 2 client service — enrichment PLAN generation + step execution. The plan
|
|
4
|
+
* itself is produced server-side (POST /v1/librarian/plan, the user's own OpenRouter model reasoning
|
|
5
|
+
* over the note); each step is then EXECUTED here over the generic AI + librarian APIs (no-SSR), and
|
|
6
|
+
* the result is folded back into the note with a structured Sources/References trail. Phase 1 runs
|
|
7
|
+
* two self-fulfilled step kinds: `llm_reason` (expand using only the note) and `librarian_assess`
|
|
8
|
+
* (summarise the user's OWN existing material found via the librarian).
|
|
9
|
+
* @structure
|
|
10
|
+
* - buildCatalogue(feed) — compact [{agent,offerId,title,ask,latency,cost}] from the /v1/offers feed
|
|
11
|
+
* - generatePlan(text, catalogue) — POST /v1/librarian/plan (slow AI call; full timeout, no retry)
|
|
12
|
+
* - runStep(step, ctx) — execute one plan step → EnrichmentResult { stepId, kind, markdown, sources }
|
|
13
|
+
* - composeEnrichedMarkdown(noteText, enrichments) — note + folded results + Sources section
|
|
14
|
+
* @version-history
|
|
15
|
+
* v1.0.0 — 2026-06-21 — Initial (Phase 1): plan generate + reason/librarian-assess execution.
|
|
16
|
+
* v1.1.0 — 2026-06-21 — Phase 2: `delegate` execution — dispatch a fleet agent offer via offers.ask(),
|
|
17
|
+
* await the task (SSE + poll), read the deliverable back, fold it in with agent provenance.
|
|
18
|
+
*/
|
|
19
|
+
import { api } from '/js/api.js';
|
|
20
|
+
import { librarianSearch } from '/js/services/memory.js';
|
|
21
|
+
import * as offers from '/js/services/offers.js';
|
|
22
|
+
import { getTask } from '/js/services/agent-tasks.js';
|
|
23
|
+
|
|
24
|
+
const ASSESS_HITS = 6; // how many librarian hits to feed the assessor
|
|
25
|
+
const AI_TIMEOUT_MS = 1_800_000; // 30 min — same as the classify call; the model may think a while
|
|
26
|
+
const DELEGATE_TIMEOUT_MS = 900_000; // 15 min — fleet offers are "minutes" to "long-running"
|
|
27
|
+
|
|
28
|
+
/** Build the compact offer catalogue the planner grounds delegate steps against, from the /v1/offers
|
|
29
|
+
* envelope (offers.listOffers()). Online agents first; bounded to keep the prompt small. */
|
|
30
|
+
export function buildCatalogue(feed) {
|
|
31
|
+
const agents = feed?.data?.agents || feed?.agents || [];
|
|
32
|
+
const rows = [];
|
|
33
|
+
for (const a of agents) {
|
|
34
|
+
for (const o of (a.offers || [])) {
|
|
35
|
+
rows.push({ agent: a.agent, offerId: o.id, title: o.title, ask: o.ask, latency: o.latency, cost: o.cost, _online: !!a.online });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
rows.sort((x, y) => (y._online === x._online) ? 0 : (y._online ? 1 : -1));
|
|
39
|
+
return rows.slice(0, 60).map(({ _online, ...r }) => r);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Ask the backend planner what enrichment steps a note would benefit from. `catalogue` is the compact
|
|
43
|
+
* offer list (buildCatalogue) so the planner can ground delegate steps. Returns { plan, context, model }.
|
|
44
|
+
* Slow AI call — full timeout, no retry (a 30s abort would re-fire the still-running model). */
|
|
45
|
+
export async function generatePlan(text, catalogue) {
|
|
46
|
+
const resp = await api('/v1/librarian/plan', {
|
|
47
|
+
method: 'POST',
|
|
48
|
+
body: JSON.stringify({ text, catalogue: Array.isArray(catalogue) ? catalogue : [] }),
|
|
49
|
+
timeoutMs: AI_TIMEOUT_MS,
|
|
50
|
+
retries: 0,
|
|
51
|
+
});
|
|
52
|
+
if (resp?.ok === false) { const e = new Error(resp.error?.message || 'Plan failed'); e.code = resp.error?.code; throw e; }
|
|
53
|
+
return resp?.data || null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Await a dispatched task to a terminal state, refreshing on the live-update event and polling as a
|
|
57
|
+
* fallback. Resolves the task record on 'done'; throws on failed/stalled/timeout.
|
|
58
|
+
* @param {string} agentName
|
|
59
|
+
* @param {string} taskId
|
|
60
|
+
* @param {{ onStatus?: (status: string) => void }} [opts] */
|
|
61
|
+
function awaitTask(agentName, taskId, opts = {}) {
|
|
62
|
+
const { onStatus } = opts;
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
const deadline = Date.now() + DELEGATE_TIMEOUT_MS;
|
|
65
|
+
let settled = false;
|
|
66
|
+
const cleanup = () => { clearInterval(timer); window.removeEventListener('aimeat-live-update', onLive); };
|
|
67
|
+
async function check() {
|
|
68
|
+
if (settled) return;
|
|
69
|
+
let task = null;
|
|
70
|
+
try { const r = await getTask(agentName, taskId); task = r?.data?.task || r?.data || null; } catch { /* transient */ }
|
|
71
|
+
const status = task?.status;
|
|
72
|
+
if (status) onStatus?.(status);
|
|
73
|
+
if (status === 'done') { settled = true; cleanup(); resolve(task); return; }
|
|
74
|
+
if (status === 'failed' || status === 'stalled') { settled = true; cleanup(); reject(new Error('Agent task ' + status)); return; }
|
|
75
|
+
if (Date.now() > deadline) { settled = true; cleanup(); reject(new Error('TIMEOUT')); }
|
|
76
|
+
}
|
|
77
|
+
const onLive = (e) => { const d = e.detail?.domains; if (d && !d.has('agent-tasks')) return; check(); };
|
|
78
|
+
const timer = setInterval(check, 5000);
|
|
79
|
+
window.addEventListener('aimeat-live-update', onLive);
|
|
80
|
+
check();
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** One AI completion via the user's own key (budget-enforced server-side). Returns { content, model }. */
|
|
85
|
+
async function aiComplete(prompt, systemPrompt) {
|
|
86
|
+
const resp = await api('/v1/ai/complete', {
|
|
87
|
+
method: 'POST',
|
|
88
|
+
body: JSON.stringify({ prompt, systemPrompt, app_id: 'notebook' }),
|
|
89
|
+
timeoutMs: AI_TIMEOUT_MS,
|
|
90
|
+
retries: 0,
|
|
91
|
+
});
|
|
92
|
+
if (resp?.ok === false) { const e = new Error(resp.error?.message || 'AI completion failed'); e.code = resp.error?.code; throw e; }
|
|
93
|
+
return resp?.data || { content: '', model: '' };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function priorBlock(priorEnrichments) {
|
|
97
|
+
if (!priorEnrichments?.length) return '';
|
|
98
|
+
return '\n\nResults from earlier enrichment steps:\n\n' +
|
|
99
|
+
priorEnrichments.map((e, i) => `### Step ${i + 1}\n${e.markdown}`).join('\n\n');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Execute one plan step. ctx = { noteText, priorEnrichments }. Returns an EnrichmentResult. */
|
|
103
|
+
export async function runStep(step, ctx) {
|
|
104
|
+
const noteText = ctx?.noteText || '';
|
|
105
|
+
const prior = ctx?.priorEnrichments || [];
|
|
106
|
+
const retrievedAt = new Date().toISOString();
|
|
107
|
+
|
|
108
|
+
if (step.kind === 'librarian_assess') {
|
|
109
|
+
const hits = await librarianSearch(step.query, ASSESS_HITS, 'own');
|
|
110
|
+
if (!hits.length) {
|
|
111
|
+
return {
|
|
112
|
+
stepId: step.id, kind: step.kind, producedAt: retrievedAt,
|
|
113
|
+
markdown: `_No related material found in your own organisms for "${step.query}"._`,
|
|
114
|
+
sources: [],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const hitList = hits.map((h, i) =>
|
|
118
|
+
`${i + 1}. **${h.title || h.key}** — ${h.snippet || ''} _(${h.key})_`).join('\n');
|
|
119
|
+
const system = 'You assess a user\'s OWN existing notes/documents against a note they just captured. ' +
|
|
120
|
+
'Summarise what they already have that is relevant, what is missing, and how the existing material relates. ' +
|
|
121
|
+
'Output clean markdown only — no preamble, no invented facts beyond what is listed.';
|
|
122
|
+
const prompt = `The captured note:\n\n"""\n${noteText}\n"""\n\nRelevant existing material from the user's own organisms:\n\n${hitList}\n\nWrite a short assessment.`;
|
|
123
|
+
const { content } = await aiComplete(prompt, system);
|
|
124
|
+
return {
|
|
125
|
+
stepId: step.id, kind: step.kind, producedAt: retrievedAt,
|
|
126
|
+
markdown: (content || '').trim(),
|
|
127
|
+
sources: hits.map(h => ({
|
|
128
|
+
producer: h.producer || null,
|
|
129
|
+
origin: h.key,
|
|
130
|
+
label: h.title || h.key,
|
|
131
|
+
retrievedAt,
|
|
132
|
+
})),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (step.kind === 'delegate') {
|
|
137
|
+
const feed = ctx?.offersFeed || await offers.listOffers();
|
|
138
|
+
const agents = feed?.data?.agents || feed?.agents || [];
|
|
139
|
+
let agentEntry = agents.find(a => a.agent === step.agent);
|
|
140
|
+
let offer = agentEntry?.offers?.find(o => o.id === step.offerId);
|
|
141
|
+
// Fallback: the planner's pick is gone/renamed — rank the live catalogue against the request.
|
|
142
|
+
if (!offer) {
|
|
143
|
+
const items = agents.flatMap(a => (a.offers || []).map(o => ({ agent: a.agent, offer: o })));
|
|
144
|
+
const { ranked } = await offers.rankOffersByNeed(step.query, items).catch(() => ({ ranked: [] }));
|
|
145
|
+
const top = ranked?.[0]?.item;
|
|
146
|
+
if (top) { agentEntry = agents.find(a => a.agent === top.agent); offer = top.offer; }
|
|
147
|
+
}
|
|
148
|
+
if (!agentEntry || !offer) throw new Error('No matching agent offer for this step');
|
|
149
|
+
|
|
150
|
+
ctx?.onStatus?.(step.id, 'dispatching');
|
|
151
|
+
const dispatch = await offers.ask(agentEntry, offer, step.query);
|
|
152
|
+
if (dispatch.kind !== 'task' || !dispatch.taskId) {
|
|
153
|
+
// Interactive/schedule-only agents can't be auto-awaited from here.
|
|
154
|
+
throw new Error(dispatch.kind === 'prompt' ? 'This agent is interactive — ask it from the Offerings tab' : 'Could not dispatch a task to this agent');
|
|
155
|
+
}
|
|
156
|
+
const task = await awaitTask(agentEntry.agent, dispatch.taskId, { onStatus: (s) => ctx?.onStatus?.(step.id, s) });
|
|
157
|
+
const content = await offers.getDeliverableContent({
|
|
158
|
+
agentGaii: agentEntry.gaii,
|
|
159
|
+
deliverableKey: task?.deliverableKey || task?.deliverable_key,
|
|
160
|
+
taskId: dispatch.taskId,
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
stepId: step.id, kind: step.kind, producedAt: retrievedAt,
|
|
164
|
+
markdown: (content || '_The agent completed the task but returned no readable deliverable._').trim(),
|
|
165
|
+
sources: [{
|
|
166
|
+
producer: agentEntry.gaii,
|
|
167
|
+
origin: task?.deliverableKey || task?.deliverable_key || ('task:' + dispatch.taskId),
|
|
168
|
+
label: `${offer.title} (${agentEntry.agent})`,
|
|
169
|
+
retrievedAt,
|
|
170
|
+
}],
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// llm_reason — expand using only the note + prior step results.
|
|
175
|
+
const system = 'You enrich a user\'s rough note by reasoning about it. Follow the instruction exactly. ' +
|
|
176
|
+
'Output clean markdown only — no preamble. Do not invent external facts; reason from what is given.';
|
|
177
|
+
const prompt = `The captured note:\n\n"""\n${noteText}\n"""${priorBlock(prior)}\n\nInstruction: ${step.query}`;
|
|
178
|
+
const { content, model } = await aiComplete(prompt, system);
|
|
179
|
+
return {
|
|
180
|
+
stepId: step.id, kind: step.kind, producedAt: retrievedAt,
|
|
181
|
+
markdown: (content || '').trim(),
|
|
182
|
+
sources: [{ producer: model || 'ai', origin: null, label: 'AI reasoning', retrievedAt }],
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Compose the enriched note body: original note + each enrichment + a Sources/References section.
|
|
187
|
+
* This is what gets filed (classify/materialize) once the user is happy. */
|
|
188
|
+
export function composeEnrichedMarkdown(noteText, enrichments) {
|
|
189
|
+
if (!enrichments?.length) return noteText;
|
|
190
|
+
const parts = [noteText.trim()];
|
|
191
|
+
const allSources = [];
|
|
192
|
+
for (const e of enrichments) {
|
|
193
|
+
if (!e?.markdown) continue;
|
|
194
|
+
parts.push('', '---', '', e.markdown.trim());
|
|
195
|
+
for (const s of (e.sources || [])) allSources.push(s);
|
|
196
|
+
}
|
|
197
|
+
if (allSources.length) {
|
|
198
|
+
const seen = new Set();
|
|
199
|
+
const lines = [];
|
|
200
|
+
for (const s of allSources) {
|
|
201
|
+
const key = `${s.label}|${s.origin || ''}`;
|
|
202
|
+
if (seen.has(key)) continue;
|
|
203
|
+
seen.add(key);
|
|
204
|
+
const where = s.origin ? ` — \`${s.origin}\`` : '';
|
|
205
|
+
const who = s.producer ? ` _(${String(s.producer).split('@')[0]})_` : '';
|
|
206
|
+
lines.push(`- ${s.label}${where}${who}`);
|
|
207
|
+
}
|
|
208
|
+
if (lines.length) parts.push('', '## Sources / References', '', ...lines);
|
|
209
|
+
}
|
|
210
|
+
return parts.join('\n');
|
|
211
|
+
}
|
|
@@ -8,9 +8,16 @@
|
|
|
8
8
|
* note as a workspace DOCUMENT.
|
|
9
9
|
* @structure
|
|
10
10
|
* - classifyNote(text) — POST /v1/librarian/classify
|
|
11
|
+
* - distributeNote(text) — POST /v1/librarian/distribute (split into placed chunks)
|
|
11
12
|
* - materializeDocument(plan) — resolve/create org → ws → document space → write doc → drop source
|
|
13
|
+
* - distributeChunks(chunks, sourceKey, onProgress) — materialize each chunk to its home
|
|
14
|
+
* - getNotebookSettings/saveNotebookSettings — the per-owner trust toggles (notebook.settings)
|
|
12
15
|
* @version-history
|
|
13
16
|
* v1.0.0 — 2026-06-19 — Initial: classify + materialize-document orchestration (slice B).
|
|
17
|
+
* v1.1.0 — 2026-06-21 — Phase 3: distribute (split → many homes) + notebook.settings trust toggles.
|
|
18
|
+
* v1.2.0 — 2026-06-21 — (reverted) materializeRecord/patchRecord removed — the Tracked Response flow
|
|
19
|
+
* now writes records through the proper workspace draft→publish path (services/organisms.js), not a
|
|
20
|
+
* raw memory write, so records land in the right namespace/owner and show up with activity.
|
|
14
21
|
*/
|
|
15
22
|
import { api, apiPost } from '/js/api.js';
|
|
16
23
|
import { createMemory, getMemory, deleteMemory } from '/js/services/memory.js';
|
|
@@ -37,6 +44,50 @@ export async function classifyNote(text) {
|
|
|
37
44
|
return resp?.data || null;
|
|
38
45
|
}
|
|
39
46
|
|
|
47
|
+
/** Ask the backend to SPLIT a note into placed chunks (notebook stage 3). Slow AI call — full timeout,
|
|
48
|
+
* no retry (same reasoning as classifyNote). Returns the DistributeResult envelope's data. */
|
|
49
|
+
export async function distributeNote(text) {
|
|
50
|
+
const resp = await api('/v1/librarian/distribute', {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
body: JSON.stringify({ text }),
|
|
53
|
+
timeoutMs: 1_800_000,
|
|
54
|
+
retries: 0,
|
|
55
|
+
});
|
|
56
|
+
if (resp?.ok === false) { const e = new Error(resp.error?.message || 'Distribute failed'); e.code = resp.error?.code; throw e; }
|
|
57
|
+
return resp?.data || null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Park an inbox message into the notebook for later processing, preserving the link back to the
|
|
62
|
+
* original message and the "owes a reply" intent (so when the note is later turned into a tracked
|
|
63
|
+
* response, the binding re-attaches to the source message). Stored as a normal notebook inbox entry.
|
|
64
|
+
* @param {object} msg The inbox message ({ id, body, conversationId, direction, senderGhii, recipientGhii }).
|
|
65
|
+
* @param {{ title?: string, content?: string, mode?: 'auto'|'approve' }} [opts]
|
|
66
|
+
*/
|
|
67
|
+
export async function parkMessageToNotebook(msg, opts = {}) {
|
|
68
|
+
const key = 'notebook.inbox.' + Date.now();
|
|
69
|
+
const peerGhii = msg?.direction === 'outbound' ? (msg?.recipientGhii || '') : (msg?.senderGhii || '');
|
|
70
|
+
const value = {
|
|
71
|
+
text: (opts.content && opts.content.trim()) || msg?.body || '',
|
|
72
|
+
title: opts.title || '',
|
|
73
|
+
capturedAt: new Date().toISOString(),
|
|
74
|
+
source: { kind: 'message', messageId: msg?.id, conversationId: msg?.conversationId, peerGhii, originNodeId: (peerGhii.split('@')[1] || '') },
|
|
75
|
+
trackedResponseIntent: { owes: true, mode: opts.mode || 'approve' },
|
|
76
|
+
};
|
|
77
|
+
const resp = await createMemory(key, value, 'private');
|
|
78
|
+
if (resp?.ok === false) throw new Error(resp.error?.message || 'Could not park to notebook');
|
|
79
|
+
return { key };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** The per-owner notebook trust toggles ({ autoDetectIntent, autoRunPlan, autoDistribute }). */
|
|
83
|
+
export async function getNotebookSettings() {
|
|
84
|
+
try { const r = await getMemory('notebook.settings'); return (r?.data?.value) || {}; }
|
|
85
|
+
catch { return {}; }
|
|
86
|
+
}
|
|
87
|
+
export async function saveNotebookSettings(settings) {
|
|
88
|
+
return createMemory('notebook.settings', settings, 'private');
|
|
89
|
+
}
|
|
90
|
+
|
|
40
91
|
/** A document-space objectType for a memory-backed workspace. */
|
|
41
92
|
function docSpaceObjectType() {
|
|
42
93
|
return { name: 'Pages', namespace: DOC_SPACE, schemaRef: 'schema:document@1', mode: 'document', backing: 'memory', writeRole: 'member', cardinality: 'many', versioned: true };
|
|
@@ -122,3 +173,49 @@ export async function materializeDocument(plan) {
|
|
|
122
173
|
|
|
123
174
|
return { organismId, workspaceId, space, docId };
|
|
124
175
|
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Materialize each chunk of a distribute plan into its own home. Chunks with a resolved home go there;
|
|
179
|
+
* chunks the model proposed a NEW name for create that org/workspace; chunks with neither are grouped
|
|
180
|
+
* into a single shared "Notebook" organism (created once, reused) so unplaced pieces are never lost.
|
|
181
|
+
* The source inbox note is dropped ONLY after every chunk has been filed.
|
|
182
|
+
* @param {Array} chunks DistributeChunk[] from distributeNote().
|
|
183
|
+
* @param {string} [sourceKey] Inbox note key to delete once all chunks are filed.
|
|
184
|
+
* @param {(index:number, status:'running'|'done'|'failed', result?:object)=>void} [onProgress]
|
|
185
|
+
* @returns {Promise<Array>} per-chunk materialize results
|
|
186
|
+
*/
|
|
187
|
+
export async function distributeChunks(chunks, sourceKey, onProgress) {
|
|
188
|
+
const results = [];
|
|
189
|
+
let notebookFallback = null; // { organismId, workspaceId, space } for unplaced chunks
|
|
190
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
191
|
+
const c = chunks[i];
|
|
192
|
+
onProgress?.(i, 'running');
|
|
193
|
+
const organismName = c.createNew?.organismName || c.organismName;
|
|
194
|
+
const plan = {
|
|
195
|
+
organismId: c.organismId || null,
|
|
196
|
+
organismName,
|
|
197
|
+
workspaceId: c.workspaceId || null,
|
|
198
|
+
workspaceName: c.createNew?.workspaceName || c.workspaceName,
|
|
199
|
+
space: c.space || null,
|
|
200
|
+
title: c.title,
|
|
201
|
+
markdown: c.markdown,
|
|
202
|
+
};
|
|
203
|
+
const unplaced = !plan.organismId && !organismName;
|
|
204
|
+
if (unplaced && notebookFallback) {
|
|
205
|
+
plan.organismId = notebookFallback.organismId;
|
|
206
|
+
plan.workspaceId = notebookFallback.workspaceId;
|
|
207
|
+
plan.space = notebookFallback.space;
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
const res = await materializeDocument(plan); // no sourceKey — don't delete per chunk
|
|
211
|
+
if (unplaced && !notebookFallback) notebookFallback = { organismId: res.organismId, workspaceId: res.workspaceId, space: res.space };
|
|
212
|
+
results.push(res);
|
|
213
|
+
onProgress?.(i, 'done', res);
|
|
214
|
+
} catch (e) {
|
|
215
|
+
onProgress?.(i, 'failed');
|
|
216
|
+
throw e; // surface the failure; source note is NOT deleted so nothing is lost
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (sourceKey) await deleteMemory(sourceKey).catch(() => {});
|
|
220
|
+
return results;
|
|
221
|
+
}
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
* resolve gate approvals.
|
|
7
7
|
* @usage import * as orgService from '/js/services/organisms.js';
|
|
8
8
|
* @version-history
|
|
9
|
+
* v1.2.1 — 2026-06-21 — Decode HTML entities in workspace names on read (listWorkspaces +
|
|
10
|
+
* discoverWorkspaces) so legacy double-escaped registry names (e.g. "STT & Voice") render
|
|
11
|
+
* as plain text in the list + breadcrumb.
|
|
9
12
|
* v1.2.0 — 2026-06-16 — Generator prompt: each objectType gets a one-line "description" and a
|
|
10
13
|
* matching "type.<name>.desc" i18n key, so generated workspaces are self-describing (the
|
|
11
14
|
* workspace UI shows the description under each space's title).
|
|
@@ -15,6 +18,7 @@
|
|
|
15
18
|
* "{ns}.{field}.hint" and "type.{name}" labels the workspace UI renders.
|
|
16
19
|
*/
|
|
17
20
|
import { api, apiGet, apiPost, apiPut, apiPatch, apiDelete } from '/js/api.js';
|
|
21
|
+
import { decodeEntities } from '/js/utils.js';
|
|
18
22
|
|
|
19
23
|
/** Does this space's data live in workspace memory keys (records/documents the workspace view can
|
|
20
24
|
* show)? Missing backing counts as memory. Mirrors the server's isMemoryBackedSpace — THE one
|
|
@@ -514,6 +518,37 @@ export async function getWorkspaceOverview(orgId, wsId) {
|
|
|
514
518
|
} catch { return ''; }
|
|
515
519
|
}
|
|
516
520
|
|
|
521
|
+
/** Deterministic GRAPH of the whole organism (workspaces → spaces + counts/last-activity, members,
|
|
522
|
+
* agents) — the data behind the interactive mindmap. Returns null on failure. */
|
|
523
|
+
export async function getOrganismGraph(orgId) {
|
|
524
|
+
try {
|
|
525
|
+
const r = await apiGet(`/v1/organisms/${encodeURIComponent(orgId)}/graph`);
|
|
526
|
+
return r?.data?.graph || null;
|
|
527
|
+
} catch { return null; }
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/** Deterministic GRAPH of ONE workspace (root = workspace, with its spaces). Returns null on failure. */
|
|
531
|
+
export async function getWorkspaceGraph(orgId, wsId) {
|
|
532
|
+
try {
|
|
533
|
+
const r = await apiGet(`/v1/organisms/${encodeURIComponent(orgId)}/workspace/graph?ws=${encodeURIComponent(wsId)}`);
|
|
534
|
+
return r?.data?.graph || null;
|
|
535
|
+
} catch { return null; }
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/** Organism STRUCTURE TIMELINE: { current, history } — the trackable structure fingerprint's current
|
|
539
|
+
* value + archived prior versions (newest first). Returns { current: null, history: [] } on failure. */
|
|
540
|
+
export async function getStructureHistory(orgId) {
|
|
541
|
+
try {
|
|
542
|
+
const r = await apiGet(`/v1/organisms/${encodeURIComponent(orgId)}/structure/history`);
|
|
543
|
+
return r?.data || { current: null, history: [] };
|
|
544
|
+
} catch { return { current: null, history: [] }; }
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/** Save a workspace's free-form README (markdown). Creator/admin only (enforced server-side). */
|
|
548
|
+
export async function saveWorkspaceReadme(orgId, wsId, readme) {
|
|
549
|
+
return apiPut(`/v1/organisms/${encodeURIComponent(orgId)}/workspace?ws=${encodeURIComponent(wsId)}`, { ws: wsId, readme });
|
|
550
|
+
}
|
|
551
|
+
|
|
517
552
|
/** Overwrite a workspace's manifest (e.g. edited name/summary/policy from Settings). */
|
|
518
553
|
export async function saveManifest(orgId, wsId, manifest) {
|
|
519
554
|
return apiPost('/v1/memory', { key: `${wsRoot(orgId, wsId)}.meta.manifest`, value: manifest, visibility: 'private' });
|
|
@@ -529,7 +564,9 @@ export async function listWorkspaces(orgId) {
|
|
|
529
564
|
try {
|
|
530
565
|
const resp = await apiGet(`/v1/memory?prefix=${encodeURIComponent(key)}`);
|
|
531
566
|
const item = (resp?.data?.items || []).find(i => i.key === key);
|
|
532
|
-
|
|
567
|
+
const list = Array.isArray(item?.value?.workspaces) ? item.value.workspaces : [];
|
|
568
|
+
// Names are plain text; legacy import paths stored them HTML-escaped. Decode for display.
|
|
569
|
+
return list.map(w => (w && w.name ? { ...w, name: decodeEntities(w.name) } : w));
|
|
533
570
|
} catch { return []; }
|
|
534
571
|
}
|
|
535
572
|
|
|
@@ -546,7 +583,9 @@ export async function saveWorkspaceRegistry(orgId, workspaces) {
|
|
|
546
583
|
export async function discoverWorkspaces(orgId) {
|
|
547
584
|
try {
|
|
548
585
|
const resp = await apiGet(`/v1/organisms/${encodeURIComponent(orgId)}/workspaces`);
|
|
549
|
-
|
|
586
|
+
const list = Array.isArray(resp?.data?.workspaces) ? resp.data.workspaces : [];
|
|
587
|
+
// Names are plain text; legacy import paths stored them HTML-escaped. Decode for display.
|
|
588
|
+
return list.map(w => (w && w.name ? { ...w, name: decodeEntities(w.name) } : w));
|
|
550
589
|
} catch { return []; }
|
|
551
590
|
}
|
|
552
591
|
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file tracked-responses.js
|
|
3
|
+
* @description Frontend service for Tracked Responses — the Memory Contract that owes a (possibly
|
|
4
|
+
* federated) reply to an inbox message once a watched workspace record satisfies a condition.
|
|
5
|
+
* Thin wrappers over /v1/tracked-responses; plus message-importance flags stored as owner memory
|
|
6
|
+
* (no schema migration) for the lightweight "Important / needs reply" tier.
|
|
7
|
+
* @structure create / list / get / getDraft / evaluate / markReplied / cancel + importance flags
|
|
8
|
+
* @usage import * as tracked from '/js/services/tracked-responses.js';
|
|
9
|
+
* @version-history
|
|
10
|
+
* v1.0.0 — 2026-06-21 — Initial service (Tracked Responses + importance flags).
|
|
11
|
+
*/
|
|
12
|
+
import { api, apiGet } from '/js/api.js';
|
|
13
|
+
import { createMemory, getMemory, deleteMemory } from '/js/services/memory.js';
|
|
14
|
+
|
|
15
|
+
const enc = encodeURIComponent;
|
|
16
|
+
const FLAG_PREFIX = 'message-flag.';
|
|
17
|
+
const flagKey = (messageId) => `${FLAG_PREFIX}${messageId}.latest`;
|
|
18
|
+
|
|
19
|
+
/** Create a Tracked Response from an inbox message. `watch` = { key, condition:{field,equals} }. */
|
|
20
|
+
export async function createTrackedResponse({ messageId, watch, response, references, title, tier } = /** @type {{ messageId?: any, watch?: any, response?: any, references?: any, title?: any, tier?: any }} */ ({})) {
|
|
21
|
+
const resp = await api('/v1/tracked-responses', {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
body: JSON.stringify({ message_id: messageId, watch, response, references, title, tier }),
|
|
24
|
+
});
|
|
25
|
+
if (resp?.ok === false) throw new Error(resp.error?.message || 'Could not create tracked response');
|
|
26
|
+
return resp?.data?.trackedResponse || null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** AI triage: form the intent for a message as an actionable record (organism/workspace + record TYPE
|
|
30
|
+
* + title/content + completion condition). Slow AI call — full timeout, no retry. Returns
|
|
31
|
+
* { suggestion, context:{organisms:[{id,name,workspaces:[{id,name,recordTypes:[{namespace,name}]}]}]} }. */
|
|
32
|
+
export async function triageMessage(text) {
|
|
33
|
+
const resp = await api('/v1/tracked-responses/classify', { method: 'POST', body: JSON.stringify({ text }), timeoutMs: 1_800_000, retries: 0 });
|
|
34
|
+
if (resp?.ok === false) { const e = new Error(resp.error?.message || 'Triage failed'); e.code = resp.error?.code; throw e; }
|
|
35
|
+
return resp?.data || null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** AI fill: produce a record value conforming to the chosen record type's ACTUAL schema (any shape,
|
|
39
|
+
* AI-authored per workspace) + the schema-correct completion condition + inject field. Validated
|
|
40
|
+
* server-side before returning. Slow AI call. Returns { value, condition, inject }. */
|
|
41
|
+
export async function fillRecord({ organismId, ws, namespace, recordId, message, title, content } = /** @type {{ organismId?: any, ws?: any, namespace?: any, recordId?: any, message?: any, title?: any, content?: any }} */ ({})) {
|
|
42
|
+
const resp = await api('/v1/tracked-responses/fill', {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
body: JSON.stringify({ organism_id: organismId, ws, namespace, record_id: recordId, message, title, content }),
|
|
45
|
+
timeoutMs: 1_800_000, retries: 0,
|
|
46
|
+
});
|
|
47
|
+
if (resp?.ok === false) { const e = new Error(resp.error?.message || 'Fill failed'); e.code = resp.error?.code; throw e; }
|
|
48
|
+
return resp?.data || null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function listTrackedResponses(state) {
|
|
52
|
+
const r = await apiGet(`/v1/tracked-responses${state ? `?state=${enc(state)}` : ''}`);
|
|
53
|
+
return r?.data?.trackedResponses || [];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function getTrackedResponse(id) {
|
|
57
|
+
const r = await apiGet(`/v1/tracked-responses/${enc(id)}`);
|
|
58
|
+
return r?.data?.trackedResponse || null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** The suggested reply built when an approve-mode contract fired ({ draft:{body,result}, source, state }). */
|
|
62
|
+
export async function getTrackedResponseDraft(id) {
|
|
63
|
+
const r = await apiGet(`/v1/tracked-responses/${enc(id)}/draft`);
|
|
64
|
+
return r?.data || null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export async function evaluateTrackedResponse(id) {
|
|
68
|
+
const r = await api(`/v1/tracked-responses/${enc(id)}/evaluate`, { method: 'POST' });
|
|
69
|
+
return r?.data?.trackedResponse || null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function markTrackedResponseReplied(id, sentMessageId) {
|
|
73
|
+
return api(`/v1/tracked-responses/${enc(id)}/replied`, { method: 'POST', body: JSON.stringify({ sent_message_id: sentMessageId }) });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export async function cancelTrackedResponse(id) {
|
|
77
|
+
return api(`/v1/tracked-responses/${enc(id)}/cancel`, { method: 'POST' });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ── Lightweight "Important / needs reply" flag (Tier 1) — owner memory, no schema migration ──
|
|
81
|
+
export async function setMessageImportant(messageId, important) {
|
|
82
|
+
if (important) return createMemory(flagKey(messageId), { important: true, at: new Date().toISOString() }, 'private');
|
|
83
|
+
return deleteMemory(flagKey(messageId)).catch(() => {});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export async function isMessageImportant(messageId) {
|
|
87
|
+
try { const r = await getMemory(flagKey(messageId)); return !!(r?.data?.value?.important); }
|
|
88
|
+
catch { return false; }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Return the set of message ids the owner flagged important (for the "Needs reply" filter). Uses a
|
|
92
|
+
* PREFIX query so it fetches only the tiny `message-flag.*` set — never the whole memory store. A flag
|
|
93
|
+
* record exists ONLY while important (un-flag deletes it), so key-presence is sufficient. */
|
|
94
|
+
export async function listImportantMessageIds() {
|
|
95
|
+
try {
|
|
96
|
+
const r = await apiGet(`/v1/memory?prefix=${enc(FLAG_PREFIX)}`);
|
|
97
|
+
const items = r?.data?.items || [];
|
|
98
|
+
return items
|
|
99
|
+
.map(m => String(m.key || ''))
|
|
100
|
+
.filter(k => k.startsWith(FLAG_PREFIX))
|
|
101
|
+
.map(k => k.slice(FLAG_PREFIX.length).replace(/\.latest$/, ''));
|
|
102
|
+
} catch { return []; }
|
|
103
|
+
}
|
package/dist/public/js/utils.js
CHANGED
|
@@ -13,6 +13,21 @@ export function escHtml(s) {
|
|
|
13
13
|
.replace(/"/g, '"');
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/** Decode the common HTML entities back to plain text. Some names (e.g. workspace registry names)
|
|
17
|
+
* were HTML-escaped at write by older import paths, so a literal "STT & Voice" reached storage as
|
|
18
|
+
* "STT & Voice" and then double-escaped on render. Names are plain text — decode them for
|
|
19
|
+
* display. HTM re-escapes on render, so this stays XSS-safe. Decode & LAST so "&lt;"
|
|
20
|
+
* resolves to "<", not "<". */
|
|
21
|
+
export function decodeEntities(s) {
|
|
22
|
+
if (!s) return '';
|
|
23
|
+
return String(s)
|
|
24
|
+
.replace(/</g, '<')
|
|
25
|
+
.replace(/>/g, '>')
|
|
26
|
+
.replace(/"/g, '"')
|
|
27
|
+
.replace(/'/g, "'")
|
|
28
|
+
.replace(/&/g, '&');
|
|
29
|
+
}
|
|
30
|
+
|
|
16
31
|
/** Attribute-escape a string (for use inside HTML attributes). */
|
|
17
32
|
export function escAttr(s) {
|
|
18
33
|
if (!s) return '';
|