@memberjunction/ng-dashboards 5.46.0 → 5.48.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.
Files changed (71) hide show
  1. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts +15 -4
  2. package/dist/DataExplorer/data-explorer-dashboard.component.d.ts.map +1 -1
  3. package/dist/DataExplorer/data-explorer-dashboard.component.js +45 -35
  4. package/dist/DataExplorer/data-explorer-dashboard.component.js.map +1 -1
  5. package/dist/DataExplorer/models/explorer-state.interface.d.ts +7 -0
  6. package/dist/DataExplorer/models/explorer-state.interface.d.ts.map +1 -1
  7. package/dist/DataExplorer/models/explorer-state.interface.js.map +1 -1
  8. package/dist/Lists/components/lists-browse-resource.component.d.ts +4 -0
  9. package/dist/Lists/components/lists-browse-resource.component.d.ts.map +1 -1
  10. package/dist/Lists/components/lists-browse-resource.component.js +39 -30
  11. package/dist/Lists/components/lists-browse-resource.component.js.map +1 -1
  12. package/dist/Lists/components/lists-my-lists-resource.component.d.ts.map +1 -1
  13. package/dist/Lists/components/lists-my-lists-resource.component.js +14 -12
  14. package/dist/Lists/components/lists-my-lists-resource.component.js.map +1 -1
  15. package/dist/Lists/components/lists-operations-resource.component.d.ts.map +1 -1
  16. package/dist/Lists/components/lists-operations-resource.component.js +6 -1
  17. package/dist/Lists/components/lists-operations-resource.component.js.map +1 -1
  18. package/dist/Lists/services/list-set-operations.service.d.ts +11 -0
  19. package/dist/Lists/services/list-set-operations.service.d.ts.map +1 -1
  20. package/dist/Lists/services/list-set-operations.service.js +27 -2
  21. package/dist/Lists/services/list-set-operations.service.js.map +1 -1
  22. package/dist/PredictiveStudio/at-risk.view-models.d.ts +33 -0
  23. package/dist/PredictiveStudio/at-risk.view-models.d.ts.map +1 -1
  24. package/dist/PredictiveStudio/at-risk.view-models.js +69 -2
  25. package/dist/PredictiveStudio/at-risk.view-models.js.map +1 -1
  26. package/dist/PredictiveStudio/components/ps-catalog.component.js +2 -2
  27. package/dist/PredictiveStudio/components/ps-catalog.component.js.map +1 -1
  28. package/dist/PredictiveStudio/components/ps-compare.component.js +2 -2
  29. package/dist/PredictiveStudio/components/ps-compare.component.js.map +1 -1
  30. package/dist/PredictiveStudio/components/ps-confirm-modal.component.js +2 -2
  31. package/dist/PredictiveStudio/components/ps-confirm-modal.component.js.map +1 -1
  32. package/dist/PredictiveStudio/components/ps-experiments.component.js +2 -2
  33. package/dist/PredictiveStudio/components/ps-experiments.component.js.map +1 -1
  34. package/dist/PredictiveStudio/components/ps-home.component.js +2 -2
  35. package/dist/PredictiveStudio/components/ps-home.component.js.map +1 -1
  36. package/dist/PredictiveStudio/components/ps-operate-dialog.component.js +2 -2
  37. package/dist/PredictiveStudio/components/ps-operate-dialog.component.js.map +1 -1
  38. package/dist/PredictiveStudio/components/ps-pipelines.component.d.ts.map +1 -1
  39. package/dist/PredictiveStudio/components/ps-pipelines.component.js +306 -297
  40. package/dist/PredictiveStudio/components/ps-pipelines.component.js.map +1 -1
  41. package/dist/PredictiveStudio/components/ps-production.component.js +2 -2
  42. package/dist/PredictiveStudio/components/ps-production.component.js.map +1 -1
  43. package/dist/PredictiveStudio/components/ps-registry.component.d.ts +1 -1
  44. package/dist/PredictiveStudio/components/ps-registry.component.d.ts.map +1 -1
  45. package/dist/PredictiveStudio/components/ps-registry.component.js +15 -9
  46. package/dist/PredictiveStudio/components/ps-registry.component.js.map +1 -1
  47. package/dist/PredictiveStudio/predictive-studio-agent-context.d.ts +115 -0
  48. package/dist/PredictiveStudio/predictive-studio-agent-context.d.ts.map +1 -0
  49. package/dist/PredictiveStudio/predictive-studio-agent-context.js +119 -0
  50. package/dist/PredictiveStudio/predictive-studio-agent-context.js.map +1 -0
  51. package/dist/PredictiveStudio/predictive-studio-copilot.view-models.d.ts +36 -0
  52. package/dist/PredictiveStudio/predictive-studio-copilot.view-models.d.ts.map +1 -0
  53. package/dist/PredictiveStudio/predictive-studio-copilot.view-models.js +52 -0
  54. package/dist/PredictiveStudio/predictive-studio-copilot.view-models.js.map +1 -0
  55. package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts +9 -1
  56. package/dist/PredictiveStudio/resources/ps-models-resource.component.d.ts.map +1 -1
  57. package/dist/PredictiveStudio/resources/ps-models-resource.component.js +133 -56
  58. package/dist/PredictiveStudio/resources/ps-models-resource.component.js.map +1 -1
  59. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts +50 -1
  60. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.d.ts.map +1 -1
  61. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js +591 -165
  62. package/dist/PredictiveStudio/resources/ps-predictions-resource.component.js.map +1 -1
  63. package/dist/PredictiveStudio/resources/ps-resource-base.d.ts +17 -0
  64. package/dist/PredictiveStudio/resources/ps-resource-base.d.ts.map +1 -1
  65. package/dist/PredictiveStudio/resources/ps-resource-base.js +27 -1
  66. package/dist/PredictiveStudio/resources/ps-resource-base.js.map +1 -1
  67. package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts +11 -1
  68. package/dist/PredictiveStudio/resources/ps-studio-resource.component.d.ts.map +1 -1
  69. package/dist/PredictiveStudio/resources/ps-studio-resource.component.js +199 -99
  70. package/dist/PredictiveStudio/resources/ps-studio-resource.component.js.map +1 -1
  71. package/package.json +59 -59
@@ -1 +1 @@
1
- {"version":3,"file":"ps-predictions-resource.component.js","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-predictions-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject } from '@angular/core';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { LogError, RunView, UserInfo } from '@memberjunction/core';\nimport { MJConversationEntity, MJEnvironmentEntityExtended, MJMLModelEntity, MJProcessRunDetailEntity } from '@memberjunction/core-entities';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { trustDots, trustEvidenceLine } from '@memberjunction/predictive-studio-core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { PSResourceBase } from './ps-resource-base';\nimport { buildBusinessCatalog, type BusinessPredictionCard } from '../business-predictions.view-models';\nimport { parseAtRiskRows, topGlobalDrivers, type AtRiskRow } from '../at-risk.view-models';\n\nconst PREDICTIVE_STUDIO_APP_ID = '299C9272-8D38-40CA-85D4-0980F2C9FAD1';\nconst MODEL_DEV_AGENT_NAME = 'Model Development Agent';\n\n/**\n * **Predictions** — the business-user home for Predictive Studio (`option-b-refined` mockup). Reframes\n * published ML models as plain-language \"predictions\" in a catalog, each with a trust badge; opening one\n * goes to a workspace whose trust verdict GATES the actions (a Poor/unmeasured prediction can't be acted\n * on). \"+ New prediction\" opens the Model Development Agent (the deterministic builder) as a docked\n * co-pilot. Zero ML jargon — the analyst surfaces stay under the other nav items as \"Advanced\".\n */\n@RegisterClass(BaseResourceComponent, 'PredictiveStudioPredictionsResource')\n@Component({\n standalone: false,\n selector: 'mj-ps-predictions-resource',\n template: `\n <mj-page-header-interior\n [Title]=\"view === 'workspace' ? (selected?.title ?? 'Prediction') : 'Predictions'\"\n [Subtitle]=\"view === 'workspace' ? 'Who to focus on, how much to trust it, and what to do next' : 'Ready-to-use predictions for your members'\">\n <div actions>\n @if (view === 'catalog') {\n <button mjButton variant=\"primary\" size=\"sm\" data-testid=\"ps-new-prediction\" (click)=\"newPrediction()\">\n <i class=\"fa-solid fa-plus\"></i> New prediction\n </button>\n }\n </div>\n </mj-page-header-interior>\n <mj-page-body-interior>\n @if (isLoading) {\n <mj-loading text=\"Loading your predictions…\" size=\"medium\"></mj-loading>\n } @else {\n <div class=\"ps-biz-host\" [class.chat-open]=\"chatOpen\">\n <div class=\"ps-biz-main\">\n <!-- ───────── CATALOG ───────── -->\n @if (view === 'catalog') {\n @if (cards.length === 0) {\n <div class=\"ps-biz-empty\" data-testid=\"ps-predictions-empty\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <h3>No predictions yet</h3>\n <p class=\"muted\">Ask the Model Dev Agent to build your first one.</p>\n <button mjButton variant=\"primary\" size=\"md\" (click)=\"newPrediction()\"><i class=\"fa-solid fa-plus\"></i> New prediction</button>\n </div>\n } @else {\n <div class=\"ps-biz-grid\" data-testid=\"ps-predictions-grid\">\n @for (c of cards; track c.modelId) {\n <div class=\"ps-biz-card\" [class.blocked]=\"!c.canOpen\" data-testid=\"ps-prediction-card\">\n <div class=\"ps-biz-card-top\">\n <span class=\"ps-trust-badge\" [class]=\"'trust-' + c.trust.grade.toLowerCase()\" data-testid=\"ps-trust-badge\">\n <i class=\"fa-solid fa-shield-halved\"></i> {{ c.canOpen ? c.trust.grade : 'Not ready' }}\n </span>\n </div>\n <h3 class=\"ps-biz-card-title\">{{ c.title }}</h3>\n <p class=\"ps-biz-card-line\">{{ c.canOpen ? c.trust.oneLiner : c.blockedReason }}</p>\n <div class=\"ps-biz-card-foot\">\n @if (c.canOpen) {\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-open-prediction\" (click)=\"open(c)\">Open <i class=\"fa-solid fa-arrow-right\"></i></button>\n } @else {\n <button mjButton variant=\"secondary\" size=\"sm\" [disabled]=\"true\" data-testid=\"ps-open-blocked\"><i class=\"fa-solid fa-lock\"></i> Needs an analyst</button>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n\n <!-- ───────── WORKSPACE (trust gate) ───────── -->\n @if (view === 'workspace' && selected) {\n <nav class=\"ps-biz-crumb\">\n <a (click)=\"backToCatalog()\" data-testid=\"ps-crumb-home\">Predictions</a>\n <i class=\"fa-solid fa-chevron-right\"></i> <span>{{ selected.title }}</span>\n </nav>\n\n <div class=\"ps-trust-banner\" [class]=\"'trust-' + selected.trust.grade.toLowerCase()\" data-testid=\"ps-trust-banner\">\n <div class=\"ps-trust-dots\">\n @for (d of [1,2,3,4,5]; track d) { <i class=\"fa-solid fa-star\" [class.on]=\"d <= dots(selected)\"></i> }\n </div>\n <div class=\"ps-trust-text\">\n <div class=\"ps-trust-grade\">{{ selected.canOpen ? 'You can rely on this — ' + selected.trust.grade : 'Not reliable yet' }}</div>\n <div class=\"ps-trust-line\">{{ selected.trust.oneLiner }}</div>\n <div class=\"ps-trust-explain muted\">{{ selected.trust.explanation }}</div>\n <div class=\"ps-trust-evidence muted\">{{ evidence() }}</div>\n </div>\n </div>\n\n <div class=\"ps-biz-workspace-body\" data-testid=\"ps-workspace-body\">\n @if (selected.canOpen) {\n @if (drivers.length > 0) {\n <div class=\"ps-drivers\" data-testid=\"ps-drivers\">\n <i class=\"fa-solid fa-lightbulb\"></i> <strong>What's driving this:</strong>\n @for (d of drivers; track d) { <span class=\"ps-driver-chip\">{{ d }}</span> }\n </div>\n }\n @if (atRiskLoading) {\n <mj-loading text=\"Loading who's at risk…\" size=\"small\"></mj-loading>\n } @else if (atRiskRows.length > 0) {\n <div class=\"ps-atrisk\" data-testid=\"ps-atrisk-list\" #atriskList>\n <div class=\"ps-atrisk-head\"><span>Member</span><span class=\"ps-atrisk-rcol\">Likelihood</span></div>\n @for (r of atRiskRows.slice(0, 50); track r.recordId) {\n <div class=\"ps-atrisk-row\" data-testid=\"ps-atrisk-row\">\n <span class=\"ps-atrisk-id mono\">{{ r.recordId }}</span>\n <span class=\"ps-atrisk-bar\"><span class=\"ps-atrisk-fill\" [class]=\"'risk-' + r.band\" [style.width.%]=\"r.riskPct\"></span></span>\n <span class=\"ps-atrisk-pct\" [class]=\"'risk-' + r.band\">{{ r.riskPct }}%</span>\n </div>\n }\n <div class=\"ps-atrisk-foot muted\">{{ atRiskRows.length > 50 ? 'Showing top 50 of ' + atRiskRows.length : atRiskRows.length + ' members' }} · highest first</div>\n </div>\n } @else {\n <div class=\"ps-atrisk-empty muted\" data-testid=\"ps-atrisk-empty\">No results yet — run this prediction from <strong>Models in Production</strong> to see who's at risk.</div>\n }\n }\n <div class=\"ps-action-bar\" [class.locked]=\"!selected.canOpen\" data-testid=\"ps-action-bar\">\n @if (selected.canOpen) {\n <button mjButton variant=\"primary\" size=\"sm\" data-testid=\"ps-act-review\" (click)=\"scrollToList()\"><i class=\"fa-solid fa-list-check\"></i> Review the call list</button>\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-act-save\" (click)=\"askAgentTo('Save these renewal-risk scores onto the member records so my team can use them.')\"><i class=\"fa-solid fa-floppy-disk\"></i> Save scores to records</button>\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-act-list\" (click)=\"askAgentTo('Put these at-risk members into a list called &quot;At-Risk Renewals&quot; for outreach.')\"><i class=\"fa-solid fa-paper-plane\"></i> Send to a list</button>\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-act-export\" [disabled]=\"atRiskRows.length === 0\" (click)=\"exportList()\"><i class=\"fa-solid fa-file-export\"></i> Share / export</button>\n } @else {\n <div class=\"ps-action-locked\"><i class=\"fa-solid fa-lock\"></i> {{ selected.trust.gateReason }}</div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (chatOpen) {\n <aside class=\"ps-biz-copilot\" data-testid=\"ps-predictions-copilot\">\n <div class=\"ps-biz-copilot-head\">\n <div class=\"ps-biz-copilot-title\"><i class=\"fa-solid fa-robot\"></i> New prediction</div>\n <button class=\"ps-biz-copilot-close\" (click)=\"closeChat()\" aria-label=\"Close\"><i class=\"fa-solid fa-xmark\"></i></button>\n </div>\n <div class=\"ps-biz-copilot-body\">\n @if (currentUser) {\n <mj-conversation-chat-area\n [Provider]=\"Provider\" [environmentId]=\"chatEnvironmentId\" [currentUser]=\"currentUser\"\n [conversation]=\"chatConversation\" [conversationId]=\"chatConversationId\" [isNewConversation]=\"chatIsNewConversation\"\n [suppressNewConversationEmptyState]=\"true\" [allowMentions]=\"false\" [overlayMode]=\"true\"\n [showExportButton]=\"false\" [showShareButton]=\"false\" [showArtifactIndicator]=\"false\"\n [showAgentPicker]=\"false\" [showAgentModePicker]=\"false\"\n [defaultAgentId]=\"modelDevAgentId\" [pendingMessage]=\"pendingPrompt\"\n [applicationScope]=\"'Application'\" [applicationId]=\"applicationId\" [appContext]=\"chatAppContext\"\n (conversationCreated)=\"onChatConversationCreated($event)\"\n (pendingMessageConsumed)=\"onChatPendingMessageConsumed()\"\n emptyStateGreeting=\"What do you want to predict? Describe it in plain words.\">\n </mj-conversation-chat-area>\n } @else { <div class=\"ps-biz-copilot-empty\"><mj-loading text=\"Connecting…\" size=\"small\"></mj-loading></div> }\n </div>\n </aside>\n }\n </div>\n }\n </mj-page-body-interior>\n `,\n styles: [\n `\n :host { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-biz-host { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .ps-biz-main { flex: 1; min-width: 0; overflow-y: auto; padding: 16px 18px 28px; }\n .ps-biz-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }\n .ps-biz-card { background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-lg); padding: 18px; box-shadow: var(--mj-shadow-sm); display: flex; flex-direction: column; gap: 10px; transition: box-shadow .15s, transform .15s; }\n .ps-biz-card:hover { box-shadow: var(--mj-shadow-md); transform: translateY(-2px); }\n .ps-biz-card.blocked { opacity: .85; background: var(--mj-bg-surface-card); }\n .ps-biz-card-title { font-size: var(--mj-text-lg); font-weight: 600; color: var(--mj-text-primary); margin: 0; }\n .ps-biz-card-line { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); margin: 0; flex: 1; }\n .ps-biz-card-foot { display: flex; justify-content: flex-end; }\n .ps-trust-badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: var(--mj-radius-full); font-size: var(--mj-text-xs); font-weight: 600; }\n .trust-good, .trust-excellent { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .trust-fair { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .trust-poor { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .ps-biz-empty { text-align: center; padding: 64px 16px; color: var(--mj-text-secondary); }\n .ps-biz-empty i { font-size: 40px; color: var(--mj-brand-primary); margin-bottom: 12px; }\n .ps-biz-empty h3 { margin: 0 0 6px; color: var(--mj-text-primary); }\n .ps-biz-empty p { margin: 0 0 16px; }\n .ps-biz-crumb { display: flex; align-items: center; gap: 8px; font-size: var(--mj-text-sm); color: var(--mj-text-muted); margin-bottom: 14px; }\n .ps-biz-crumb a { color: var(--mj-text-link); cursor: pointer; }\n .ps-biz-crumb a:hover { text-decoration: underline; }\n .ps-biz-crumb i { font-size: 10px; }\n .ps-trust-banner { display: flex; gap: 16px; align-items: center; padding: 18px 20px; border-radius: var(--mj-radius-lg); border: 1px solid; margin-bottom: 18px; }\n .ps-trust-banner.trust-good, .ps-trust-banner.trust-excellent { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); }\n .ps-trust-banner.trust-fair { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); }\n .ps-trust-banner.trust-poor { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-trust-dots { display: flex; gap: 3px; font-size: 18px; }\n .ps-trust-dots i { color: var(--mj-border-strong); } .ps-trust-dots i.on { color: var(--mj-status-warning); }\n .ps-trust-banner.trust-good .ps-trust-dots i.on, .ps-trust-banner.trust-excellent .ps-trust-dots i.on { color: var(--mj-status-success); }\n .ps-trust-grade { font-weight: 700; font-size: var(--mj-text-lg); color: var(--mj-text-primary); }\n .ps-trust-line { font-weight: 600; color: var(--mj-text-primary); margin-top: 2px; }\n .ps-trust-explain, .ps-trust-evidence { font-size: var(--mj-text-sm); margin-top: 4px; }\n .ps-action-bar { display: flex; gap: 10px; flex-wrap: wrap; padding: 14px 16px; border-radius: var(--mj-radius-lg); background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); }\n .ps-action-bar.locked { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-action-locked { display: flex; align-items: center; gap: 8px; color: var(--mj-status-error-text); font-weight: 600; font-size: var(--mj-text-sm); }\n .ps-drivers { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 0 0 16px; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); }\n .ps-drivers i { color: var(--mj-status-warning); }\n .ps-driver-chip { background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-full); padding: 2px 10px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-atrisk { border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-lg); overflow: hidden; margin-bottom: 16px; background: var(--mj-bg-surface); }\n .ps-atrisk-head { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; padding: 8px 14px; background: var(--mj-bg-surface-card); border-bottom: 1px solid var(--mj-border-default); font-size: var(--mj-text-xs); font-weight: 600; color: var(--mj-text-muted); text-transform: uppercase; letter-spacing: .03em; }\n .ps-atrisk-rcol { grid-column: 2 / span 2; text-align: right; }\n .ps-atrisk-row { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; align-items: center; padding: 9px 14px; border-bottom: 1px solid var(--mj-border-subtle); }\n .ps-atrisk-row:last-child { border-bottom: none; }\n .ps-atrisk-row:hover { background: var(--mj-bg-surface-hover); }\n .ps-atrisk-id { font-size: var(--mj-text-xs); color: var(--mj-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .ps-atrisk-bar { height: 8px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n .ps-atrisk-fill { display: block; height: 100%; border-radius: var(--mj-radius-full); }\n .ps-atrisk-pct { text-align: right; font-weight: 700; font-size: var(--mj-text-sm); font-variant-numeric: tabular-nums; }\n .ps-atrisk-fill.risk-high { background: var(--mj-status-error); }\n .ps-atrisk-fill.risk-medium { background: var(--mj-status-warning); }\n .ps-atrisk-fill.risk-low { background: var(--mj-status-success); }\n .ps-atrisk-pct.risk-high { color: var(--mj-status-error-text); }\n .ps-atrisk-pct.risk-medium { color: var(--mj-status-warning-text); }\n .ps-atrisk-pct.risk-low { color: var(--mj-status-success-text); }\n .ps-atrisk-foot { padding: 8px 14px; font-size: var(--mj-text-xs); }\n .ps-atrisk-empty { padding: 24px; text-align: center; border: 1px dashed var(--mj-border-default); border-radius: var(--mj-radius-lg); margin-bottom: 16px; }\n .mono { font-family: var(--mj-font-family-mono); }\n .ps-biz-copilot { width: 420px; max-width: 42vw; flex: none; border-left: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); display: flex; flex-direction: column; min-height: 0; }\n .ps-biz-copilot-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--mj-border-default); }\n .ps-biz-copilot-title { display: flex; align-items: center; gap: 8px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-biz-copilot-title i { color: var(--mj-brand-primary); }\n .ps-biz-copilot-close { background: transparent; border: none; cursor: pointer; padding: 6px 8px; border-radius: 6px; color: var(--mj-text-muted); }\n .ps-biz-copilot-close:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-secondary); }\n .ps-biz-copilot-body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }\n .ps-biz-copilot-body mj-conversation-chat-area { flex: 1; min-height: 0; display: block; }\n .ps-biz-copilot-empty { display: flex; align-items: center; justify-content: center; flex: 1; }\n @media (max-width: 1100px) { .ps-biz-host.chat-open .ps-biz-main { display: none; } .ps-biz-copilot { width: 100%; max-width: none; border-left: none; } }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PSPredictionsResourceComponent extends PSResourceBase {\n protected readonly SectionKey = 'predictions';\n protected readonly SectionLabel = 'Predictions';\n protected readonly SectionIcon = 'fa-solid fa-wand-magic-sparkles';\n\n private readonly cdrLocal = inject(ChangeDetectorRef);\n\n /** catalog (the home grid) ↔ workspace (a selected prediction). */\n public view: 'catalog' | 'workspace' = 'catalog';\n public selected: BusinessPredictionCard | null = null;\n public chatOpen = false;\n public pendingPrompt: string | null = null;\n private _modelDevAgentId: string | null = null;\n\n /**\n * Embedded co-pilot conversation state. The chat-area starts in \"new conversation\" mode; on the first\n * send it creates the conversation and emits `conversationCreated`, at which point we capture the live\n * conversation and flip out of new-mode so subsequent sends append to the same thread. Without this\n * wiring the suppressed empty-state input has no valid conversation to write into and the first send\n * silently no-ops (matches the proven Form Builder co-pilot pattern).\n */\n public chatConversation: MJConversationEntity | null = null;\n public chatConversationId: string | null = null;\n public chatIsNewConversation = true;\n\n /** The ranked at-risk rows for the open prediction's latest run (empty until loaded / when no run yet). */\n public atRiskRows: AtRiskRow[] = [];\n /** Plain-language \"what's driving this\" drivers for the open prediction (global feature importance). */\n public drivers: string[] = [];\n /** Whether the at-risk list is loading for the open prediction. */\n public atRiskLoading = false;\n\n /** The business catalog cards, most-trustworthy first, derived from the engine's published models. */\n public get cards(): BusinessPredictionCard[] {\n return buildBusinessCatalog(\n this.engine.PublishedModels.map((m: MJMLModelEntity) => ({\n modelId: m.ID,\n name: this.engine.ModelDisplayName(m),\n HoldoutMetrics: m.HoldoutMetrics,\n Metrics: m.Metrics,\n ProblemType: m.ProblemType,\n updatedAt: m.__mj_UpdatedAt ?? null,\n })),\n );\n }\n\n public dots(c: BusinessPredictionCard): number { return trustDots(c.trust.grade); }\n public evidence(): string { return trustEvidenceLine({ noun: 'members' }); }\n\n public open(c: BusinessPredictionCard): void {\n if (!c.canOpen) return;\n this.selected = c;\n this.view = 'workspace';\n this.atRiskRows = [];\n this.drivers = [];\n this.cdrLocal.detectChanges();\n void this.loadAtRisk(c);\n }\n\n /** Load the open prediction's plain-language drivers + its latest run's ranked at-risk rows. */\n private async loadAtRisk(c: BusinessPredictionCard): Promise<void> {\n const model = this.engine.PublishedModels.find((m) => UUIDsEqual(m.ID, c.modelId));\n this.drivers = topGlobalDrivers(model?.FeatureImportance ?? null, 3);\n this.atRiskLoading = true;\n this.cdrLocal.detectChanges();\n try {\n const provider = this.ProviderToUse;\n const user = provider.CurrentUser ?? undefined;\n const runs = await this.engine.LoadRecentRunsForModel(c.modelId, provider, user, { maxRows: 1 });\n const latest = runs[0];\n if (latest?.ID) {\n const res = await RunView.FromMetadataProvider(provider).RunView<MJProcessRunDetailEntity>(\n { EntityName: 'MJ: Process Run Details', ExtraFilter: `ProcessRunID='${latest.ID}'`, MaxRows: 2137, ResultType: 'entity_object' },\n user,\n );\n if (res.Success && this.selected?.modelId === c.modelId) {\n this.atRiskRows = parseAtRiskRows((res.Results ?? []).map((d) => ({ recordId: d.RecordID, ResultPayload: d.ResultPayload })));\n }\n }\n } catch (err) {\n LogError(`PSPredictionsResource.loadAtRisk: ${err instanceof Error ? err.message : String(err)}`);\n } finally {\n this.atRiskLoading = false;\n this.cdrLocal.detectChanges();\n }\n }\n\n public backToCatalog(): void {\n this.view = 'catalog';\n this.selected = null;\n this.atRiskRows = [];\n this.drivers = [];\n this.cdrLocal.detectChanges();\n }\n\n /** \"Review the call list\" — scroll the ranked at-risk list into view. */\n public scrollToList(): void {\n document.querySelector('[data-testid=\"ps-atrisk-list\"]')?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n\n /** \"Save scores\" / \"Send to a list\" — open the docked co-pilot seeded with the request (the agent does it). */\n public askAgentTo(prompt: string): void {\n this.pendingPrompt = prompt;\n this.chatOpen = true;\n void this.ensureModelDevAgentResolved();\n this.cdrLocal.detectChanges();\n }\n\n /** \"Share / export\" — download the at-risk list as a CSV (dependency-free). */\n public exportList(): void {\n if (this.atRiskRows.length === 0) return;\n const csv = ['Member,Likelihood %,Predicted', ...this.atRiskRows.map((r) => `${r.recordId},${r.riskPct},${r.class ?? ''}`)].join('\\n');\n const url = URL.createObjectURL(new Blob([csv], { type: 'text/csv' }));\n const a = document.createElement('a');\n a.href = url;\n a.download = `${(this.selected?.title ?? 'prediction').replace(/[^a-z0-9]+/gi, '-').toLowerCase()}-at-risk.csv`;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n public newPrediction(): void {\n this.pendingPrompt = 'Help me build a new prediction. What do you want to know about your members?';\n this.chatOpen = true;\n void this.ensureModelDevAgentResolved();\n this.cdrLocal.detectChanges();\n }\n\n public closeChat(): void {\n this.chatOpen = false;\n this.pendingPrompt = null;\n this.cdrLocal.detectChanges();\n }\n\n /**\n * The chat-area created its backing conversation after the user's first message — capture the live\n * conversation, re-feed the pending message in the same change-detection cycle, and leave new-mode so\n * the thread renders (mirrors the Form Builder co-pilot's atomic state-flip).\n */\n public onChatConversationCreated(event: { conversation: MJConversationEntity; pendingMessage?: string }): void {\n this.pendingPrompt = event.pendingMessage ?? null;\n this.chatConversation = event.conversation;\n this.chatConversationId = event.conversation.ID;\n this.chatIsNewConversation = false;\n this.cdrLocal.detectChanges();\n }\n\n /** The chat-area delivered the seeded prompt — clear the buffer so a re-render doesn't resend it. */\n public onChatPendingMessageConsumed(): void {\n this.pendingPrompt = null;\n this.cdrLocal.detectChanges();\n }\n\n public get currentUser(): UserInfo | null { return this.ProviderToUse.CurrentUser ?? null; }\n public get chatEnvironmentId(): string {\n return (this.Data?.Configuration?.['environmentId'] as string | undefined) || MJEnvironmentEntityExtended.DefaultEnvironmentID;\n }\n public get applicationId(): string | null { return (this.Data?.Configuration?.['applicationId'] as string | undefined) ?? null; }\n public get modelDevAgentId(): string | null { return this._modelDevAgentId; }\n public get chatAppContext(): Record<string, unknown> {\n return { app: 'Predictive Studio', section: 'predictions', publishedModels: this.engine.PublishedModels.length };\n }\n\n private async ensureModelDevAgentResolved(): Promise<void> {\n if (this._modelDevAgentId) return;\n try {\n await AIEngineBase.Instance.Config(false, this.ProviderToUse.CurrentUser ?? undefined);\n this._modelDevAgentId =\n AIEngineBase.Instance.Agents?.find((a) => a.Name?.trim().toLowerCase() === MODEL_DEV_AGENT_NAME.toLowerCase())?.ID ?? null;\n if (!this._modelDevAgentId) LogError(`PSPredictionsResource: '${MODEL_DEV_AGENT_NAME}' not found — chat uses default-agent routing.`);\n this.cdrLocal.detectChanges();\n } catch (err) {\n LogError(`PSPredictionsResource.ensureModelDevAgentResolved: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n}\n\n/** Tree-shaking prevention — called from the subpath module so the @RegisterClass survives bundling. */\nexport function LoadPSPredictionsResource(): void {\n // intentionally empty\n}\n"]}
1
+ {"version":3,"file":"ps-predictions-resource.component.js","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-predictions-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject } from '@angular/core';\nimport { NormalizeUUID, RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { LogError, RunView, UserInfo } from '@memberjunction/core';\nimport { MJConversationEntity, MJEnvironmentEntityExtended, MJMLModelEntity, MJProcessRunDetailEntity, MJListEntity, MJListDetailEntity } from '@memberjunction/core-entities';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { trustDots, trustEvidenceLine } from '@memberjunction/predictive-studio-core';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { PSResourceBase } from './ps-resource-base';\nimport { buildBusinessCatalog, type BusinessPredictionCard } from '../business-predictions.view-models';\nimport { parseAtRiskRows, topGlobalDrivers, labelFromRecord, type AtRiskRow } from '../at-risk.view-models';\nimport { buildPredictionsAgentContext, resolvePSRecord, buildPSNotFoundError } from '../predictive-studio-agent-context';\nimport { validateStringParam } from '../../shared/agent-tool-validation';\nimport { buildImprovePrompt, PS_CAPABILITY_CARDS, type PSCapabilityCard } from '../predictive-studio-copilot.view-models';\n\nconst PREDICTIVE_STUDIO_APP_ID = '299C9272-8D38-40CA-85D4-0980F2C9FAD1';\nconst MODEL_DEV_AGENT_NAME = 'Model Development Agent';\n\n/**\n * **Predictions** — the business-user home for Predictive Studio (`option-b-refined` mockup). Reframes\n * published ML models as plain-language \"predictions\" in a catalog, each with a trust badge; opening one\n * goes to a workspace whose trust verdict GATES the actions (a Poor/unmeasured prediction can't be acted\n * on). \"+ New prediction\" opens the Model Development Agent (the deterministic builder) as a docked\n * co-pilot. Zero ML jargon — the analyst surfaces stay under the other nav items as \"Advanced\".\n */\n@RegisterClass(BaseResourceComponent, 'PredictiveStudioPredictionsResource')\n@Component({\n standalone: false,\n selector: 'mj-ps-predictions-resource',\n template: `\n <mj-page-header-interior\n [Title]=\"view === 'workspace' ? (selected?.title ?? 'Prediction') : 'Predictions'\"\n [Subtitle]=\"view === 'workspace' ? 'Who to focus on, how much to trust it, and what to do next' : 'Ready-to-use predictions for your members'\">\n <div actions>\n @if (view === 'catalog') {\n <button mjButton variant=\"primary\" size=\"sm\" data-testid=\"ps-new-prediction\" (click)=\"newPrediction()\">\n <i class=\"fa-solid fa-plus\"></i> New prediction\n </button>\n }\n </div>\n </mj-page-header-interior>\n <mj-page-body-interior [Flex]=\"true\" [Padding]=\"false\">\n @if (isLoading) {\n <mj-loading text=\"Loading your predictions…\" size=\"medium\"></mj-loading>\n } @else if (loadError) {\n <div class=\"ps-load-error\" data-testid=\"ps-load-error\" role=\"alert\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <div class=\"ps-load-error-text\">\n <strong>Couldn't load {{ sectionTitle }}</strong>\n <span class=\"ps-load-error-detail\">{{ loadError }}</span>\n </div>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"retryLoad()\"><i class=\"fa-solid fa-rotate-right\"></i> Try again</button>\n </div>\n } @else {\n <div class=\"ps-biz-host\" [class.chat-open]=\"chatOpen\">\n <div class=\"ps-biz-main\">\n <!-- ───────── CATALOG ───────── -->\n @if (view === 'catalog') {\n @if (cards.length === 0) {\n <div class=\"ps-biz-intro\" data-testid=\"ps-predictions-empty\">\n <div class=\"ps-biz-intro-head\">\n <i class=\"fa-solid fa-wand-magic-sparkles\"></i>\n <h2>Predict what's next for your data</h2>\n <p>Predictive Studio turns your records into plain-language predictions — describe what you want to know, and the agent builds and trains a model with you. Here's what you can do:</p>\n </div>\n <div class=\"ps-cap-grid\">\n @for (cap of capabilityCards; track cap.title) {\n <div class=\"ps-cap-card\">\n <i [class]=\"cap.icon\"></i>\n <div class=\"ps-cap-title\">{{ cap.title }}</div>\n <div class=\"ps-cap-blurb\">{{ cap.blurb }}</div>\n </div>\n }\n </div>\n <button mjButton variant=\"primary\" size=\"md\" data-testid=\"ps-intro-build\" (click)=\"newPrediction()\"><i class=\"fa-solid fa-plus\"></i> Build your first prediction</button>\n </div>\n } @else {\n <div class=\"ps-biz-grid\" data-testid=\"ps-predictions-grid\">\n @for (c of cards; track c.modelId) {\n <div class=\"ps-biz-card\" [class.blocked]=\"!c.canOpen\" data-testid=\"ps-prediction-card\">\n <div class=\"ps-biz-card-top\">\n <span class=\"ps-trust-badge\" [class]=\"'trust-' + c.trust.grade.toLowerCase()\" data-testid=\"ps-trust-badge\">\n <i class=\"fa-solid fa-shield-halved\"></i> {{ c.canOpen ? c.trust.grade : 'Not ready' }}\n </span>\n </div>\n <h3 class=\"ps-biz-card-title\">{{ c.title }}</h3>\n <p class=\"ps-biz-card-line\">{{ c.canOpen ? c.trust.oneLiner : c.blockedReason }}</p>\n <div class=\"ps-biz-card-foot\">\n @if (c.canOpen) {\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-open-prediction\" (click)=\"open(c)\">Open <i class=\"fa-solid fa-arrow-right\"></i></button>\n } @else {\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-improve-prediction\" (click)=\"improvePrediction(c)\"><i class=\"fa-solid fa-wand-magic-sparkles\"></i> Improve this</button>\n }\n </div>\n </div>\n }\n </div>\n }\n }\n\n <!-- ───────── WORKSPACE (trust gate) ───────── -->\n @if (view === 'workspace' && selected) {\n <nav class=\"ps-biz-crumb\">\n <a (click)=\"backToCatalog()\" data-testid=\"ps-crumb-home\">Predictions</a>\n <i class=\"fa-solid fa-chevron-right\"></i> <span>{{ selected.title }}</span>\n </nav>\n\n <div class=\"ps-trust-banner\" [class]=\"'trust-' + selected.trust.grade.toLowerCase()\" data-testid=\"ps-trust-banner\">\n <div class=\"ps-trust-dots\">\n @for (d of [1,2,3,4,5]; track d) { <i class=\"fa-solid fa-star\" [class.on]=\"d <= dots(selected)\"></i> }\n </div>\n <div class=\"ps-trust-text\">\n <div class=\"ps-trust-grade\">{{ selected.canOpen ? 'You can rely on this — ' + selected.trust.grade : 'Not reliable yet' }}</div>\n <div class=\"ps-trust-line\">{{ selected.trust.oneLiner }}</div>\n <div class=\"ps-trust-explain muted\">{{ selected.trust.explanation }}</div>\n <div class=\"ps-trust-evidence muted\">{{ evidence() }}</div>\n </div>\n </div>\n\n <div class=\"ps-biz-workspace-body\" data-testid=\"ps-workspace-body\">\n @if (selected.canOpen) {\n @if (drivers.length > 0) {\n <div class=\"ps-drivers\" data-testid=\"ps-drivers\">\n <i class=\"fa-solid fa-lightbulb\"></i> <strong>What's driving this:</strong>\n @for (d of drivers; track d) { <span class=\"ps-driver-chip\">{{ d }}</span> }\n </div>\n }\n @if (atRiskLoading) {\n <mj-loading text=\"Loading who's at risk…\" size=\"small\"></mj-loading>\n } @else if (atRiskError) {\n <div class=\"ps-atrisk-error\" data-testid=\"ps-atrisk-error\" role=\"alert\">\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n <span class=\"ps-atrisk-error-msg\">Couldn't load who's at risk: {{ atRiskError }}</span>\n <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"retryAtRisk()\"><i class=\"fa-solid fa-rotate-right\"></i> Try again</button>\n </div>\n } @else if (atRiskRows.length > 0) {\n <div class=\"ps-atrisk\" data-testid=\"ps-atrisk-list\" #atriskList>\n <div class=\"ps-atrisk-head\"><span>Member</span><span class=\"ps-atrisk-rcol\">Likelihood</span></div>\n @for (r of atRiskRows.slice(0, 50); track r.recordId) {\n <div class=\"ps-atrisk-row\" data-testid=\"ps-atrisk-row\">\n <div class=\"ps-atrisk-idcell\">\n <span class=\"ps-atrisk-id\" [class.mono]=\"!r.label\" [title]=\"r.recordId\">{{ r.label || r.recordId }}</span>\n @if (r.drivers && r.drivers.length > 0) {\n <span class=\"ps-atrisk-why\" data-testid=\"ps-atrisk-why\">\n @for (d of r.drivers.slice(0, 2); track d.label) {\n <span class=\"ps-why-chip\" [class.up]=\"d.up\" [class.down]=\"!d.up\" [title]=\"(d.up ? 'Increases risk: ' : 'Lowers risk: ') + d.label\">\n <i class=\"fa-solid\" [class.fa-arrow-up]=\"d.up\" [class.fa-arrow-down]=\"!d.up\"></i> {{ d.label }}\n </span>\n }\n </span>\n }\n </div>\n <span class=\"ps-atrisk-bar\"><span class=\"ps-atrisk-fill\" [class]=\"'risk-' + r.band\" [style.width.%]=\"r.riskPct\"></span></span>\n <span class=\"ps-atrisk-pct\" [class]=\"'risk-' + r.band\">{{ r.riskPct }}%</span>\n </div>\n }\n <div class=\"ps-atrisk-foot muted\">{{ atRiskRows.length > 50 ? 'Showing top 50 of ' + atRiskRows.length : atRiskRows.length + ' members' }} · highest first</div>\n </div>\n } @else {\n <div class=\"ps-atrisk-empty muted\" data-testid=\"ps-atrisk-empty\">No results yet — run this prediction from <strong>Models in Production</strong> to see who's at risk.</div>\n }\n }\n <div class=\"ps-action-bar\" [class.locked]=\"!selected.canOpen\" data-testid=\"ps-action-bar\">\n @if (selected.canOpen) {\n <button mjButton variant=\"primary\" size=\"sm\" data-testid=\"ps-act-review\" (click)=\"scrollToList()\"><i class=\"fa-solid fa-list-check\"></i> Review the call list</button>\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-act-save\" (click)=\"askAgentTo('Save these renewal-risk scores onto the member records so my team can use them.')\"><i class=\"fa-solid fa-floppy-disk\"></i> Save scores to records</button>\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-act-list\" [disabled]=\"creatingList || atRiskRows.length === 0\" (click)=\"sendToList()\"><i class=\"fa-solid\" [class.fa-paper-plane]=\"!creatingList\" [class.fa-spinner]=\"creatingList\" [class.fa-spin]=\"creatingList\"></i> Send to a list</button>\n <button mjButton variant=\"secondary\" size=\"sm\" data-testid=\"ps-act-export\" [disabled]=\"atRiskRows.length === 0\" (click)=\"exportList()\"><i class=\"fa-solid fa-file-export\"></i> Share / export</button>\n } @else {\n <div class=\"ps-action-locked\"><i class=\"fa-solid fa-lock\"></i> {{ selected.trust.gateReason }}</div>\n }\n </div>\n @if (listResult) { <div class=\"ps-list-result muted\" data-testid=\"ps-list-result\">{{ listResult }}</div> }\n </div>\n }\n </div>\n\n @if (chatOpen) {\n <aside class=\"ps-biz-copilot\" data-testid=\"ps-predictions-copilot\">\n <div class=\"ps-biz-copilot-head\">\n <div class=\"ps-biz-copilot-title\"><i class=\"fa-solid fa-robot\"></i> New prediction</div>\n <button class=\"ps-biz-copilot-close\" (click)=\"closeChat()\" aria-label=\"Close\"><i class=\"fa-solid fa-xmark\"></i></button>\n </div>\n <div class=\"ps-biz-copilot-body\">\n @if (currentUser) {\n <mj-conversation-chat-area\n [Provider]=\"Provider\" [environmentId]=\"chatEnvironmentId\" [currentUser]=\"currentUser\"\n [conversation]=\"chatConversation\" [conversationId]=\"chatConversationId\" [isNewConversation]=\"chatIsNewConversation\"\n [suppressNewConversationEmptyState]=\"true\" [allowMentions]=\"false\" [overlayMode]=\"true\"\n [showExportButton]=\"false\" [showShareButton]=\"false\" [showArtifactIndicator]=\"false\"\n [showAgentPicker]=\"false\" [showAgentModePicker]=\"false\"\n [defaultAgentId]=\"modelDevAgentId\" [pendingMessage]=\"pendingPrompt\"\n [applicationScope]=\"'Application'\" [applicationId]=\"applicationId\" [appContext]=\"chatAppContext\"\n (conversationCreated)=\"onChatConversationCreated($event)\"\n (pendingMessageConsumed)=\"onChatPendingMessageConsumed()\">\n </mj-conversation-chat-area>\n } @else { <div class=\"ps-biz-copilot-empty\"><mj-loading text=\"Connecting…\" size=\"small\"></mj-loading></div> }\n </div>\n </aside>\n }\n </div>\n }\n </mj-page-body-interior>\n `,\n styles: [\n `\n :host { display: flex; flex-direction: column; width: 100%; height: 100%; min-height: 0; }\n .ps-biz-host { display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .ps-biz-main { flex: 1; min-width: 0; overflow-y: auto; padding: 16px 18px 28px; }\n .ps-biz-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }\n .ps-biz-card { background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md); padding: 18px; display: flex; flex-direction: column; gap: 10px; transition: border-color .12s, background .12s; }\n .ps-biz-card:hover { border-color: var(--mj-brand-primary); background: color-mix(in srgb, var(--mj-brand-primary) 4%, var(--mj-bg-surface)); }\n .ps-biz-card.blocked { opacity: .85; background: var(--mj-bg-surface-card); }\n .ps-biz-card-title { font-size: var(--mj-text-lg); font-weight: 600; color: var(--mj-text-primary); margin: 0; }\n .ps-biz-card-line { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); margin: 0; flex: 1; }\n .ps-biz-card-foot { display: flex; justify-content: flex-end; }\n .ps-trust-badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: var(--mj-radius-full); font-size: var(--mj-text-xs); font-weight: 600; }\n .trust-good, .trust-excellent { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .trust-fair { background: var(--mj-status-warning-bg); color: var(--mj-status-warning-text); }\n .trust-poor { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .ps-biz-intro { max-width: 820px; margin: 32px auto; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 20px; }\n .ps-biz-intro-head i { font-size: 40px; color: var(--mj-brand-primary); }\n .ps-biz-intro-head h2 { margin: 12px 0 6px; color: var(--mj-text-primary); font-size: var(--mj-text-xl); }\n .ps-biz-intro-head p { margin: 0 auto; max-width: 620px; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); }\n .ps-cap-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px; width: 100%; }\n .ps-cap-card { background: var(--mj-bg-surface); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md); padding: 18px 16px; text-align: left; display: flex; flex-direction: column; gap: 6px; }\n .ps-cap-card i { font-size: 20px; color: var(--mj-brand-primary); }\n .ps-cap-title { font-weight: 600; color: var(--mj-text-primary); font-size: var(--mj-text-sm); }\n .ps-cap-blurb { color: var(--mj-text-secondary); font-size: var(--mj-text-xs); line-height: 1.45; }\n .ps-biz-crumb { display: flex; align-items: center; gap: 8px; font-size: var(--mj-text-sm); color: var(--mj-text-muted); margin-bottom: 14px; }\n .ps-biz-crumb a { color: var(--mj-text-link); cursor: pointer; }\n .ps-biz-crumb a:hover { text-decoration: underline; }\n .ps-biz-crumb i { font-size: 10px; }\n .ps-trust-banner { display: flex; gap: 16px; align-items: center; padding: 18px 20px; border-radius: var(--mj-radius-md); border: 1px solid; margin-bottom: 18px; }\n .ps-trust-banner.trust-good, .ps-trust-banner.trust-excellent { background: var(--mj-status-success-bg); border-color: var(--mj-status-success-border); }\n .ps-trust-banner.trust-fair { background: var(--mj-status-warning-bg); border-color: var(--mj-status-warning-border); }\n .ps-trust-banner.trust-poor { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-trust-dots { display: flex; gap: 3px; font-size: 18px; }\n .ps-trust-dots i { color: var(--mj-border-strong); } .ps-trust-dots i.on { color: var(--mj-status-warning); }\n .ps-trust-banner.trust-good .ps-trust-dots i.on, .ps-trust-banner.trust-excellent .ps-trust-dots i.on { color: var(--mj-status-success); }\n .ps-trust-grade { font-weight: 700; font-size: var(--mj-text-lg); color: var(--mj-text-primary); }\n .ps-trust-line { font-weight: 600; color: var(--mj-text-primary); margin-top: 2px; }\n .ps-trust-explain, .ps-trust-evidence { font-size: var(--mj-text-sm); margin-top: 4px; }\n .ps-action-bar { display: flex; gap: 10px; flex-wrap: wrap; padding: 14px 16px; border-radius: var(--mj-radius-md); background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); }\n .ps-action-bar.locked { background: var(--mj-status-error-bg); border-color: var(--mj-status-error-border); }\n .ps-action-locked { display: flex; align-items: center; gap: 8px; color: var(--mj-status-error-text); font-weight: 600; font-size: var(--mj-text-sm); }\n .ps-drivers { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 0 0 16px; color: var(--mj-text-secondary); font-size: var(--mj-text-sm); }\n .ps-drivers i { color: var(--mj-status-warning); }\n .ps-driver-chip { background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-full); padding: 2px 10px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-atrisk { border: 1px solid var(--mj-border-default); border-radius: var(--mj-radius-md); overflow: hidden; margin-bottom: 16px; background: var(--mj-bg-surface); }\n .ps-atrisk-head { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; padding: 8px 14px; background: var(--mj-bg-surface-card); border-bottom: 1px solid var(--mj-border-default); font-size: var(--mj-text-xs); font-weight: 600; color: var(--mj-text-muted); text-transform: uppercase; letter-spacing: .03em; }\n .ps-atrisk-rcol { grid-column: 2 / span 2; text-align: right; }\n .ps-atrisk-row { display: grid; grid-template-columns: 1fr 140px 52px; gap: 12px; align-items: center; padding: 9px 14px; border-bottom: 1px solid var(--mj-border-subtle); }\n .ps-atrisk-row:last-child { border-bottom: none; }\n .ps-atrisk-row:hover { background: var(--mj-bg-surface-hover); }\n .ps-atrisk-idcell { display: flex; flex-direction: column; gap: 4px; min-width: 0; }\n .ps-atrisk-id { font-size: var(--mj-text-xs); color: var(--mj-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .ps-atrisk-why { display: flex; gap: 6px; flex-wrap: wrap; }\n .ps-why-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 600; padding: 1px 7px; border-radius: var(--mj-radius-full); max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n .ps-why-chip i { font-size: 8px; }\n .ps-why-chip.up { background: var(--mj-status-error-bg); color: var(--mj-status-error-text); }\n .ps-why-chip.down { background: var(--mj-status-success-bg); color: var(--mj-status-success-text); }\n .ps-atrisk-bar { height: 8px; border-radius: var(--mj-radius-full); background: var(--mj-bg-surface-sunken); overflow: hidden; }\n .ps-atrisk-fill { display: block; height: 100%; border-radius: var(--mj-radius-full); }\n .ps-atrisk-pct { text-align: right; font-weight: 700; font-size: var(--mj-text-sm); font-variant-numeric: tabular-nums; }\n .ps-atrisk-fill.risk-high { background: var(--mj-status-error); }\n .ps-atrisk-fill.risk-medium { background: var(--mj-status-warning); }\n .ps-atrisk-fill.risk-low { background: var(--mj-status-success); }\n .ps-atrisk-pct.risk-high { color: var(--mj-status-error-text); }\n .ps-atrisk-pct.risk-medium { color: var(--mj-status-warning-text); }\n .ps-atrisk-pct.risk-low { color: var(--mj-status-success-text); }\n .ps-atrisk-foot { padding: 8px 14px; font-size: var(--mj-text-xs); }\n .ps-atrisk-empty { padding: 24px; text-align: center; border: 1px dashed var(--mj-border-default); border-radius: var(--mj-radius-md); margin-bottom: 16px; }\n .ps-atrisk-error { display: flex; align-items: center; gap: 10px; padding: 16px 18px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-md); margin-bottom: 16px; color: var(--mj-status-error-text); font-size: var(--mj-text-sm); }\n .ps-atrisk-error i { color: var(--mj-status-error); }\n .ps-atrisk-error .ps-atrisk-error-msg { flex: 1; min-width: 0; word-break: break-word; }\n .mono { font-family: var(--mj-font-family-mono); }\n /* Kept local (not in the shared stylesheet) deliberately: shared styles are injected by the\n ViewEncapsulation.None PANEL components, and this banner renders precisely when panels DON'T. */\n .ps-load-error { display: flex; align-items: center; gap: 14px; max-width: 620px; margin: 32px auto; padding: 18px 20px; border: 1px solid var(--mj-status-error-border); background: var(--mj-status-error-bg); border-radius: var(--mj-radius-lg); }\n .ps-load-error > i { font-size: 24px; color: var(--mj-status-error); }\n .ps-load-error-text { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }\n .ps-load-error-text strong { color: var(--mj-text-primary); }\n .ps-load-error-detail { color: var(--mj-text-secondary); font-size: var(--mj-text-sm); word-break: break-word; }\n .ps-biz-copilot { width: 560px; min-width: 380px; max-width: 60vw; flex: none; border-left: 1px solid var(--mj-border-default); background: var(--mj-bg-surface); display: flex; flex-direction: column; min-height: 0; }\n .ps-biz-copilot-head { display: flex; align-items: center; justify-content: space-between; padding: 10px 14px; border-bottom: 1px solid var(--mj-border-default); }\n .ps-biz-copilot-title { display: flex; align-items: center; gap: 8px; font-weight: 600; color: var(--mj-text-primary); }\n .ps-biz-copilot-title i { color: var(--mj-brand-primary); }\n .ps-biz-copilot-close { background: transparent; border: none; cursor: pointer; padding: 6px 8px; border-radius: 6px; color: var(--mj-text-muted); }\n .ps-biz-copilot-close:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-secondary); }\n .ps-biz-copilot-body { flex: 1; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }\n .ps-biz-copilot-body mj-conversation-chat-area { flex: 1; min-height: 0; display: block; }\n .ps-biz-copilot-empty { display: flex; align-items: center; justify-content: center; flex: 1; }\n @media (max-width: 1100px) { .ps-biz-host.chat-open .ps-biz-main { display: none; } .ps-biz-copilot { width: 100%; max-width: none; border-left: none; } }\n `,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class PSPredictionsResourceComponent extends PSResourceBase {\n protected readonly SectionKey = 'predictions';\n protected readonly SectionLabel = 'Predictions';\n protected readonly SectionIcon = 'fa-solid fa-wand-magic-sparkles';\n\n private readonly cdrLocal = inject(ChangeDetectorRef);\n\n /** catalog (the home grid) ↔ workspace (a selected prediction). */\n public view: 'catalog' | 'workspace' = 'catalog';\n public selected: BusinessPredictionCard | null = null;\n public chatOpen = false;\n public pendingPrompt: string | null = null;\n private _modelDevAgentId: string | null = null;\n\n /**\n * Embedded co-pilot conversation state. The chat-area starts in \"new conversation\" mode; on the first\n * send it creates the conversation and emits `conversationCreated`, at which point we capture the live\n * conversation and flip out of new-mode so subsequent sends append to the same thread. Without this\n * wiring the suppressed empty-state input has no valid conversation to write into and the first send\n * silently no-ops (matches the proven Form Builder co-pilot pattern).\n */\n public chatConversation: MJConversationEntity | null = null;\n public chatConversationId: string | null = null;\n public chatIsNewConversation = true;\n\n /** The ranked at-risk rows for the open prediction's latest run (empty until loaded / when no run yet). */\n public atRiskRows: AtRiskRow[] = [];\n /** Plain-language \"what's driving this\" drivers for the open prediction (global feature importance). */\n public drivers: string[] = [];\n /** Whether the at-risk list is loading for the open prediction. */\n public atRiskLoading = false;\n /** Set when the at-risk load fails — the workspace shows a \"couldn't load\" banner with retry instead of the misleading no-results empty state. */\n public atRiskError: string | null = null;\n /** \"Send to a list\" in-flight guard + last-result message (P1 #4). */\n public creatingList = false;\n public listResult: string | null = null;\n\n /** Capability cards for the first-run intro (what PS can do), shown when the catalog is empty. */\n public readonly capabilityCards: readonly PSCapabilityCard[] = PS_CAPABILITY_CARDS;\n\n /** The business catalog cards, most-trustworthy first, derived from the engine's published models. */\n public get cards(): BusinessPredictionCard[] {\n return buildBusinessCatalog(\n this.engine.PublishedModels.map((m: MJMLModelEntity) => ({\n modelId: m.ID,\n name: this.engine.ModelDisplayName(m),\n HoldoutMetrics: m.HoldoutMetrics,\n Metrics: m.Metrics,\n ProblemType: m.ProblemType,\n updatedAt: m.__mj_UpdatedAt ?? null,\n })),\n );\n }\n\n public dots(c: BusinessPredictionCard): number { return trustDots(c.trust.grade); }\n public evidence(): string { return trustEvidenceLine({ noun: 'members' }); }\n\n /** Deep agent context for the Predictions door: catalog counts + names, and (in workspace) the selection + at-risk breakdown. */\n protected override extraAgentContext(): Record<string, unknown> {\n const cards = this.cards;\n return buildPredictionsAgentContext({\n View: this.view,\n PredictionCount: cards.length,\n ReadyPredictionCount: cards.filter((c) => c.canOpen).length,\n VisiblePredictionNames: cards.map((c) => c.title),\n ChatOpen: this.chatOpen,\n Selected: this.selected ? { Name: this.selected.title, TrustGrade: this.selected.trust.grade, CanOpen: this.selected.canOpen } : null,\n AtRiskLoaded: this.view === 'workspace' && !this.atRiskLoading && !this.atRiskError,\n AtRiskCount: this.atRiskRows.length,\n HighRiskCount: this.atRiskRows.filter((r) => r.band === 'high').length,\n MediumRiskCount: this.atRiskRows.filter((r) => r.band === 'medium').length,\n LowRiskCount: this.atRiskRows.filter((r) => r.band === 'low').length,\n Drivers: this.drivers,\n });\n }\n\n /**\n * 🔒 Read/navigate-only agent tools for the Predictions door: open a (trust-cleared) prediction, go back\n * to the catalog, review the call list, export the at-risk list (CSV — read-only, mirrors Data Explorer's\n * ExportView), and open the \"+ New prediction\" co-pilot. **DELIBERATELY NOT exposed:** \"Save scores to\n * records\", \"Send to a list\" (both WRITE records), and any train/publish/delete — those stay behind the\n * user's clicks and the approve-gated builder.\n */\n protected override registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'OpenPrediction',\n Description:\n 'Open a prediction to its workspace (trust verdict + who-is-at-risk list). Pass the prediction ID or name (see VisiblePredictionNames). Only trust-cleared predictions can open; a blocked one returns why.',\n ParameterSchema: { type: 'object', properties: { prediction: { type: 'string', description: 'The prediction ID or name to open' } } },\n Handler: async (params: Record<string, unknown>) => {\n const check = validateStringParam(params['prediction'], 'prediction');\n if (!check.ok) return check.result;\n const candidates = this.cards.map((c) => ({ ID: c.modelId, Name: c.title }));\n const match = resolvePSRecord(check.value, candidates);\n if (!match) return { Success: false, ErrorMessage: buildPSNotFoundError(check.value, candidates, 'prediction') };\n const card = this.cards.find((c) => UUIDsEqual(c.modelId, match.ID));\n if (!card) return { Success: false, ErrorMessage: buildPSNotFoundError(check.value, candidates, 'prediction') };\n if (!card.canOpen) {\n return { Success: false, ErrorMessage: `\"${card.title}\" isn't ready to open: ${card.blockedReason ?? card.trust.gateReason ?? 'it needs an analyst first.'}` };\n }\n this.open(card);\n return { Success: true, Data: { opened: card.title, trust: card.trust.grade } };\n },\n },\n {\n Name: 'BackToPredictionCatalog',\n Description: 'Return from a prediction workspace to the catalog (the grid of all predictions).',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n this.backToCatalog();\n this.publishAgentContext();\n return { Success: true, Data: { view: 'catalog' } };\n },\n },\n {\n Name: 'ReviewCallList',\n Description: 'Scroll the open prediction workspace to its ranked at-risk \"call list\". Only meaningful when a prediction is open.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n if (this.view !== 'workspace' || !this.selected) return { Success: false, ErrorMessage: 'No prediction is open. Use OpenPrediction first.' };\n this.scrollToList();\n return { Success: true };\n },\n },\n {\n Name: 'ExportAtRiskList',\n Description: 'Download the open prediction\\'s at-risk list as a CSV (read-only export). Only works when a prediction is open and its list has loaded.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n if (this.view !== 'workspace' || this.atRiskRows.length === 0) return { Success: false, ErrorMessage: 'No at-risk list is loaded to export. Open a prediction with results first.' };\n this.exportList();\n return { Success: true, Data: { rows: this.atRiskRows.length } };\n },\n },\n {\n Name: 'OpenNewPredictionCopilot',\n Description: 'Open the \"+ New prediction\" Model Development Agent co-pilot (does not send a message — the user drives the conversation). Use when the user wants to build a new prediction.',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n this.openNewPredictionCopilot();\n return { Success: true, Data: { chatOpen: true } };\n },\n },\n ]);\n }\n\n public open(c: BusinessPredictionCard): void {\n if (!c.canOpen) return;\n this.selected = c;\n this.view = 'workspace';\n this.atRiskRows = [];\n this.drivers = [];\n this.atRiskError = null;\n this.listResult = null;\n // Mark loading BEFORE the publish below: otherwise AtRiskLoaded computes true for one publish with\n // atRiskRows still [], fabricating \"0 at risk\" to the agent for a list that hasn't been fetched yet.\n this.atRiskLoading = true;\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n void this.loadAtRisk(c);\n }\n\n /** Load the open prediction's plain-language drivers + its latest run's ranked at-risk rows. */\n private async loadAtRisk(c: BusinessPredictionCard): Promise<void> {\n const model = this.engine.PublishedModels.find((m) => UUIDsEqual(m.ID, c.modelId));\n this.drivers = topGlobalDrivers(model?.FeatureImportance ?? null, 3);\n this.atRiskLoading = true;\n this.atRiskError = null;\n this.cdrLocal.detectChanges();\n try {\n const provider = this.ProviderToUse;\n const user = provider.CurrentUser ?? undefined;\n const runs = await this.engine.LoadRecentRunsForModel(c.modelId, provider, user, { maxRows: 1 });\n const latest = runs[0];\n if (latest?.ID) {\n const res = await RunView.FromMetadataProvider(provider).RunView<MJProcessRunDetailEntity>(\n { EntityName: 'MJ: Process Run Details', ExtraFilter: `ProcessRunID='${latest.ID}'`, MaxRows: 2137, ResultType: 'entity_object' },\n user,\n );\n if (res.Success && this.selected?.modelId === c.modelId) {\n this.atRiskRows = parseAtRiskRows((res.Results ?? []).map((d) => ({ recordId: d.RecordID, ResultPayload: d.ResultPayload })));\n await this.resolveAtRiskLabels(model);\n }\n }\n } catch (err) {\n this.atRiskError = err instanceof Error ? err.message : String(err);\n LogError(`PSPredictionsResource.loadAtRisk: ${this.atRiskError}`);\n } finally {\n this.atRiskLoading = false;\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n }\n\n /** Retry loading the open prediction's at-risk list after a failure — bound to the at-risk error banner. */\n public retryAtRisk(): void {\n if (this.selected) void this.loadAtRisk(this.selected);\n }\n\n /**\n * P1 #3 — resolve the raw record ids in the at-risk list to human labels (member name/email) from the\n * model's target entity, so the list reads like a call sheet instead of a column of UUIDs. Resolves the\n * top-risk rows (capped) to keep the lookup light; unresolved rows fall back to their id in the template.\n */\n /** Resolve a model's scored target entity (id + name) via its pipeline — the model row itself only carries PipelineID. */\n private targetEntityForModel(model: MJMLModelEntity | undefined): { id: string; name: string } | null {\n const pipeline = model ? this.engine.Pipelines.find((pp) => UUIDsEqual(pp.ID, model.PipelineID)) : undefined;\n const id = pipeline?.TargetEntityID;\n if (!id) return null;\n const name = this.ProviderToUse.Entities.find((e) => UUIDsEqual(e.ID, id))?.Name;\n return name ? { id, name } : null;\n }\n\n private async resolveAtRiskLabels(model: MJMLModelEntity | undefined): Promise<void> {\n // Labels are cosmetic — any failure here degrades to record ids, it must never surface as a\n // \"couldn't load who's at risk\" error that hides a perfectly good list.\n try {\n const target = this.targetEntityForModel(model);\n if (!target || this.atRiskRows.length === 0) return;\n const entity = this.ProviderToUse.EntityByName(target.name);\n const targets = this.atRiskRows.slice(0, 200); // the rows a user actually acts on\n const ids = targets.map((r) => `'${r.recordId.replace(/'/g, \"''\")}'`);\n // Only fetch the columns labelFromRecord can actually use — a broad no-Fields fetch pulls every\n // column (incl. large text/JSON) of an arbitrary entity just to render a display name. Fall back\n // to the broad fetch only when the entity has none of the candidate label fields.\n const candidates = ['Name', 'FirstName', 'LastName', 'Email'];\n const labelFields = entity ? candidates.filter((c) => entity.Fields.some((f) => f.Name.toLowerCase() === c.toLowerCase())) : [];\n const res = await RunView.FromMetadataProvider(this.ProviderToUse).RunView<Record<string, unknown>>(\n {\n EntityName: target.name,\n ExtraFilter: `ID IN (${ids.join(',')})`,\n ...(labelFields.length > 0 ? { Fields: ['ID', ...labelFields] } : {}),\n ResultType: 'simple',\n MaxRows: ids.length,\n },\n this.ProviderToUse.CurrentUser ?? undefined,\n );\n if (!res.Success) return;\n const byId = new Map<string, Record<string, unknown>>();\n for (const row of res.Results ?? []) byId.set(NormalizeUUID(String((row as { ID?: unknown }).ID ?? '')), row);\n for (const r of this.atRiskRows) {\n const rec = byId.get(NormalizeUUID(r.recordId));\n if (rec) r.label = labelFromRecord(rec);\n }\n } catch (err) {\n LogError(`PSPredictionsResource.resolveAtRiskLabels (cosmetic — list keeps ids): ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n public backToCatalog(): void {\n this.view = 'catalog';\n this.selected = null;\n this.atRiskRows = [];\n this.drivers = [];\n this.atRiskError = null;\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n /** \"Review the call list\" — scroll the ranked at-risk list into view. */\n public scrollToList(): void {\n document.querySelector('[data-testid=\"ps-atrisk-list\"]')?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n\n /** \"Save scores\" — still routed conversationally through the co-pilot (needs a designated write-back column). */\n public askAgentTo(prompt: string): void {\n this.pendingPrompt = prompt;\n this.chatOpen = true;\n void this.ensureModelDevAgentResolved();\n this.cdrLocal.detectChanges();\n }\n\n /**\n * P1 #4 — \"Send to a list\" as a one-click server action (no agent sentence to parse): create an MJ List\n * over the model's target entity and add the at-risk members (high/medium band, capped) so a team can\n * act on it immediately (outreach campaign, tasks, etc.).\n */\n public async sendToList(): Promise<void> {\n if (this.creatingList || this.atRiskRows.length === 0 || !this.selected) return;\n const model = this.engine.PublishedModels.find((m) => UUIDsEqual(m.ID, this.selected!.modelId));\n const target = this.targetEntityForModel(model);\n const entityId = target?.id;\n if (!entityId) return;\n this.creatingList = true;\n this.listResult = null;\n this.cdrLocal.detectChanges();\n try {\n const p = this.ProviderToUse;\n const user = p.CurrentUser ?? undefined;\n const list = await p.GetEntityObject<MJListEntity>('MJ: Lists', user);\n // Minute-resolution timestamp so two sends on the same day don't produce identical-named lists.\n list.Name = `At-Risk: ${this.selected.title} (${new Date().toISOString().slice(0, 16).replace('T', ' ')})`;\n list.EntityID = entityId;\n if (user?.ID) list.UserID = user.ID;\n list.RefreshMode = 'Additive';\n list.UseSnapshot = false;\n if (!(await list.Save())) {\n this.listResult = `Couldn't create the list: ${list.LatestResult?.CompleteMessage ?? 'unknown error'}`;\n return;\n }\n const members = this.atRiskRows.filter((r) => r.band !== 'low').slice(0, 200);\n let seq = 0;\n let added = 0;\n let firstFailure: string | null = null;\n for (const r of members) {\n const ld = await p.GetEntityObject<MJListDetailEntity>('MJ: List Details', user);\n ld.ListID = list.ID;\n ld.RecordID = r.recordId;\n ld.Sequence = seq++;\n ld.Status = 'Active';\n if (await ld.Save()) {\n added++;\n } else if (!firstFailure) {\n firstFailure = ld.LatestResult?.CompleteMessage ?? 'unknown error';\n }\n }\n const failed = members.length - added;\n this.listResult =\n failed === 0\n ? `Added ${added} at-risk member${added === 1 ? '' : 's'} to “${list.Name}”.`\n : `Added ${added} of ${members.length} members to “${list.Name}” — ${failed} failed to add (first error: ${firstFailure}).`;\n if (failed > 0) LogError(`PSPredictionsResource.sendToList: ${failed}/${members.length} adds failed. First: ${firstFailure}`);\n } catch (err) {\n this.listResult = `Couldn't create the list: ${err instanceof Error ? err.message : String(err)}`;\n LogError(`PSPredictionsResource.sendToList: ${err instanceof Error ? err.message : String(err)}`);\n } finally {\n this.creatingList = false;\n this.cdrLocal.detectChanges();\n }\n }\n\n /**\n * Quote one CSV cell: RFC-4180 double-quote escaping (handles commas/quotes/newlines in labels) plus a\n * leading `'` on formula-starting characters (`=`, `+`, `-`, `@`) so a hostile label can't execute as an\n * Excel/Sheets formula on open.\n */\n private csvCell(value: string): string {\n const guarded = /^[=+\\-@]/.test(value) ? `'${value}` : value;\n return /[\",\\n\\r]/.test(guarded) ? `\"${guarded.replace(/\"/g, '\"\"')}\"` : guarded;\n }\n\n /** \"Share / export\" — download the at-risk list as a CSV (dependency-free). */\n public exportList(): void {\n if (this.atRiskRows.length === 0) return;\n const csv = [\n 'Member,Likelihood %,Predicted',\n ...this.atRiskRows.map((r) => `${this.csvCell(r.label ?? r.recordId)},${r.riskPct},${this.csvCell(r.class ?? '')}`),\n ].join('\\n');\n const url = URL.createObjectURL(new Blob([csv], { type: 'text/csv' }));\n const a = document.createElement('a');\n a.href = url;\n a.download = `${(this.selected?.title ?? 'prediction').replace(/[^a-z0-9]+/gi, '-').toLowerCase()}-at-risk.csv`;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n /** \"+ New prediction\" — open the co-pilot to a clean chat (Sonar-style); the user describes their goal and the agent drives the build. */\n public newPrediction(): void {\n this.pendingPrompt = null;\n this.chatOpen = true;\n void this.ensureModelDevAgentResolved();\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n /**\n * \"Improve this\" on a blocked (not-trustworthy-enough) prediction — turns the trust dead-end into a next\n * step by opening the co-pilot seeded with the model's name + why it's held, so the agent proposes concrete\n * ways to make it reliable and can rebuild it.\n */\n public improvePrediction(c: BusinessPredictionCard): void {\n this.pendingPrompt = buildImprovePrompt({\n name: c.title,\n trustGrade: c.trust.grade,\n reason: c.blockedReason ?? c.trust.gateReason ?? null,\n });\n this.chatOpen = true;\n void this.ensureModelDevAgentResolved();\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n /** Open the \"+ New prediction\" co-pilot (clean chat) — used by the read-only `OpenNewPredictionCopilot` agent tool. */\n public openNewPredictionCopilot(): void {\n this.pendingPrompt = null;\n this.chatOpen = true;\n void this.ensureModelDevAgentResolved();\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n public closeChat(): void {\n this.chatOpen = false;\n this.pendingPrompt = null;\n this.publishAgentContext();\n this.cdrLocal.detectChanges();\n }\n\n /**\n * The chat-area created its backing conversation after the user's first message — capture the live\n * conversation, re-feed the pending message in the same change-detection cycle, and leave new-mode so\n * the thread renders (mirrors the Form Builder co-pilot's atomic state-flip).\n */\n public onChatConversationCreated(event: { conversation: MJConversationEntity; pendingMessage?: string }): void {\n this.pendingPrompt = event.pendingMessage ?? null;\n this.chatConversation = event.conversation;\n this.chatConversationId = event.conversation.ID;\n this.chatIsNewConversation = false;\n this.cdrLocal.detectChanges();\n }\n\n /** The chat-area delivered the seeded prompt — clear the buffer so a re-render doesn't resend it. */\n public onChatPendingMessageConsumed(): void {\n this.pendingPrompt = null;\n this.cdrLocal.detectChanges();\n }\n\n public get currentUser(): UserInfo | null { return this.ProviderToUse.CurrentUser ?? null; }\n public get chatEnvironmentId(): string {\n return (this.Data?.Configuration?.['environmentId'] as string | undefined) || MJEnvironmentEntityExtended.DefaultEnvironmentID;\n }\n public get applicationId(): string | null { return (this.Data?.Configuration?.['applicationId'] as string | undefined) ?? null; }\n public get modelDevAgentId(): string | null { return this._modelDevAgentId; }\n public get chatAppContext(): Record<string, unknown> {\n return { app: 'Predictive Studio', section: 'predictions', publishedModels: this.engine.PublishedModels.length };\n }\n\n private async ensureModelDevAgentResolved(): Promise<void> {\n if (this._modelDevAgentId) return;\n try {\n await AIEngineBase.Instance.Config(false, this.ProviderToUse.CurrentUser ?? undefined);\n this._modelDevAgentId =\n AIEngineBase.Instance.Agents?.find((a) => a.Name?.trim().toLowerCase() === MODEL_DEV_AGENT_NAME.toLowerCase())?.ID ?? null;\n if (!this._modelDevAgentId) LogError(`PSPredictionsResource: '${MODEL_DEV_AGENT_NAME}' not found — chat uses default-agent routing.`);\n this.cdrLocal.detectChanges();\n } catch (err) {\n LogError(`PSPredictionsResource.ensureModelDevAgentResolved: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n}\n\n/** Tree-shaking prevention — called from the subpath module so the @RegisterClass survives bundling. */\nexport function LoadPSPredictionsResource(): void {\n // intentionally empty\n}\n"]}
@@ -42,6 +42,14 @@ export declare abstract class PSResourceBase extends BaseResourceComponent {
42
42
  engine: PredictiveStudioEngine;
43
43
  /** True until the engine resolves; gates the panel host so `[engine]` is never bound before it's ready. */
44
44
  isLoading: boolean;
45
+ /**
46
+ * Set when {@link loadSection} fails to resolve the engine. The section templates render a "couldn't
47
+ * load" banner with a Try-again button ({@link retryLoad}) instead of silently showing empty panels, so
48
+ * a failed load is honest rather than indistinguishable from a genuinely-empty studio.
49
+ */
50
+ loadError: string | null;
51
+ /** Public door label for templates (the error banner title). Mirrors the protected {@link SectionLabel}. */
52
+ get sectionTitle(): string;
45
53
  /** Stable section identifier for agent context + (subclass) titling. */
46
54
  protected abstract readonly SectionKey: string;
47
55
  /** Human-readable section label used in chrome + agent context. */
@@ -53,6 +61,8 @@ export declare abstract class PSResourceBase extends BaseResourceComponent {
53
61
  * — even on failure — so the loading screen can never hang on a direct-URL section load.
54
62
  */
55
63
  protected loadSection(): Promise<void>;
64
+ /** Retry the engine load after a failure — bound to the error banner's "Try again" button. */
65
+ retryLoad(): void;
56
66
  /**
57
67
  * Report the section's state to the AI agent (async chat + realtime co-agent share this snapshot).
58
68
  * Subclasses may override {@link extraAgentContext} to add section-specific fields. No client tools
@@ -62,6 +72,13 @@ export declare abstract class PSResourceBase extends BaseResourceComponent {
62
72
  protected publishAgentContext(): void;
63
73
  /** Hook for subclasses to contribute section-specific agent-context fields. Default: none. */
64
74
  protected extraAgentContext(): Record<string, unknown>;
75
+ /**
76
+ * Hook for subclasses to register the door's agent client tools once, after the engine loads. Default:
77
+ * none. 🔒 Predictive Studio surfaces are **read / navigate-only to the agent** — overrides expose ONLY
78
+ * section-switch / open / review / export / open-copilot tools; NEVER train, publish, delete,
79
+ * score, "save scores", or "send to a list" (which write records). See {@link ../predictive-studio-agent-context}.
80
+ */
81
+ protected registerAgentTools(): void;
65
82
  GetResourceDisplayName(_data: ResourceData): Promise<string>;
66
83
  GetResourceIconClass(_data: ResourceData): Promise<string>;
67
84
  /** Font Awesome icon for the section (chrome + shell tab). */
@@ -1 +1 @@
1
- {"version":3,"file":"ps-resource-base.d.ts","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-resource-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAqB,MAAM,eAAe,CAAC;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,8BACsB,cAAe,SAAQ,qBAAqB;IAChE,SAAS,CAAC,QAAQ,CAAC,GAAG,oBAA6B;IAEnD;;;;;OAKG;IACI,MAAM,EAAE,sBAAsB,CAAmC;IAExE,2GAA2G;IACpG,SAAS,UAAQ;IAExB,wEAAwE;IACxE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE/C,mEAAmE;IACnE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAEjD,QAAQ,IAAI,IAAI;IAKhB,WAAW,IAAI,IAAI;IAInB;;;OAGG;cACa,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB5C;;;;;OAKG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAWrC,8FAA8F;IAC9F,SAAS,CAAC,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIhD,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAInD,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE,8DAA8D;IAC9D,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;yCApF5B,cAAc;2CAAd,cAAc;CAqFnC"}
1
+ {"version":3,"file":"ps-resource-base.d.ts","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-resource-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAqB,MAAM,eAAe,CAAC;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,8BACsB,cAAe,SAAQ,qBAAqB;IAChE,SAAS,CAAC,QAAQ,CAAC,GAAG,oBAA6B;IAEnD;;;;;OAKG;IACI,MAAM,EAAE,sBAAsB,CAAmC;IAExE,2GAA2G;IACpG,SAAS,UAAQ;IAExB;;;;OAIG;IACI,SAAS,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEvC,4GAA4G;IAC5G,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED,wEAAwE;IACxE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE/C,mEAAmE;IACnE,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAEjD,QAAQ,IAAI,IAAI;IAKhB,WAAW,IAAI,IAAI;IAInB;;;OAGG;cACa,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB5C,8FAA8F;IACvF,SAAS,IAAI,IAAI;IAIxB;;;;;OAKG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAWrC,8FAA8F;IAC9F,SAAS,CAAC,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAItD;;;;;OAKG;IACH,SAAS,CAAC,kBAAkB,IAAI,IAAI;IAI9B,sBAAsB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAInD,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzE,8DAA8D;IAC9D,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;yCAhH5B,cAAc;2CAAd,cAAc;CAiHnC"}
@@ -42,6 +42,16 @@ export class PSResourceBase extends BaseResourceComponent {
42
42
  engine = PredictiveStudioEngine.Instance;
43
43
  /** True until the engine resolves; gates the panel host so `[engine]` is never bound before it's ready. */
44
44
  isLoading = true;
45
+ /**
46
+ * Set when {@link loadSection} fails to resolve the engine. The section templates render a "couldn't
47
+ * load" banner with a Try-again button ({@link retryLoad}) instead of silently showing empty panels, so
48
+ * a failed load is honest rather than indistinguishable from a genuinely-empty studio.
49
+ */
50
+ loadError = null;
51
+ /** Public door label for templates (the error banner title). Mirrors the protected {@link SectionLabel}. */
52
+ get sectionTitle() {
53
+ return this.SectionLabel;
54
+ }
45
55
  ngOnInit() {
46
56
  super.ngOnInit();
47
57
  void this.loadSection();
@@ -55,14 +65,17 @@ export class PSResourceBase extends BaseResourceComponent {
55
65
  */
56
66
  async loadSection() {
57
67
  this.isLoading = true;
68
+ this.loadError = null;
58
69
  try {
59
70
  const provider = this.ProviderToUse;
60
71
  this.engine = (PredictiveStudioEngine.GetProviderInstance(provider, PredictiveStudioEngine));
61
72
  await this.engine.Config(false, provider.CurrentUser ?? undefined, provider);
62
73
  this.publishAgentContext();
74
+ this.registerAgentTools();
63
75
  }
64
76
  catch (err) {
65
- LogError(`Predictive Studio (${this.SectionKey}) failed to load engine: ${err instanceof Error ? err.message : String(err)}`);
77
+ this.loadError = err instanceof Error ? err.message : String(err);
78
+ LogError(`Predictive Studio (${this.SectionKey}) failed to load engine: ${this.loadError}`);
66
79
  }
67
80
  finally {
68
81
  this.isLoading = false;
@@ -70,6 +83,10 @@ export class PSResourceBase extends BaseResourceComponent {
70
83
  this.NotifyLoadComplete();
71
84
  }
72
85
  }
86
+ /** Retry the engine load after a failure — bound to the error banner's "Try again" button. */
87
+ retryLoad() {
88
+ void this.loadSection();
89
+ }
73
90
  /**
74
91
  * Report the section's state to the AI agent (async chat + realtime co-agent share this snapshot).
75
92
  * Subclasses may override {@link extraAgentContext} to add section-specific fields. No client tools
@@ -90,6 +107,15 @@ export class PSResourceBase extends BaseResourceComponent {
90
107
  extraAgentContext() {
91
108
  return {};
92
109
  }
110
+ /**
111
+ * Hook for subclasses to register the door's agent client tools once, after the engine loads. Default:
112
+ * none. 🔒 Predictive Studio surfaces are **read / navigate-only to the agent** — overrides expose ONLY
113
+ * section-switch / open / review / export / open-copilot tools; NEVER train, publish, delete,
114
+ * score, "save scores", or "send to a list" (which write records). See {@link ../predictive-studio-agent-context}.
115
+ */
116
+ registerAgentTools() {
117
+ /* no tools by default */
118
+ }
93
119
  async GetResourceDisplayName(_data) {
94
120
  return this.SectionLabel;
95
121
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ps-resource-base.js","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-resource-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,OAAgB,cAAe,SAAQ,qBAAqB;IAC7C,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAEnD;;;;;OAKG;IACI,MAAM,GAA2B,sBAAsB,CAAC,QAAQ,CAAC;IAExE,2GAA2G;IACpG,SAAS,GAAG,IAAI,CAAC;IAQxB,QAAQ;QACN,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjB,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;IAC1B,CAAC;IAED,WAAW;QACT,KAAK,CAAC,WAAW,EAAE,CAAC;IACtB,CAAC;IAED;;;OAGG;IACO,KAAK,CAAC,WAAW;QACzB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC;YACpC,IAAI,CAAC,MAAM,GAA2B,CACpC,sBAAsB,CAAC,mBAAmB,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAC7E,CAAC;YACF,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,IAAI,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC7E,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CACN,sBAAsB,IAAI,CAAC,UAAU,4BAA4B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACpH,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YACzB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACO,mBAAmB;QAC3B,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,EAAE;YAC3C,GAAG,EAAE,mBAAmB;YACxB,OAAO,EAAE,IAAI,CAAC,UAAU;YACxB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM;YAClF,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM;YAClF,GAAG,IAAI,CAAC,iBAAiB,EAAE;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,8FAA8F;IACpF,iBAAiB;QACzB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,KAAmB;QAC9C,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAEQ,KAAK,CAAC,oBAAoB,CAAC,KAAmB;QACrD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;qOAjFmB,cAAc,yBAAd,cAAc;6DAAd,cAAc;;iFAAd,cAAc;cADnC,SAAS","sourcesContent":["import { ChangeDetectorRef, Directive, inject } from '@angular/core';\nimport { LogError } from '@memberjunction/core';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { PredictiveStudioEngine } from '../engine/predictive-studio.engine';\n\n/**\n * Shared base for every Predictive Studio section resource.\n *\n * Predictive Studio was refactored from one monolithic left-nav dashboard into six top-nav Nav Items\n * (the canonical MJ app shape — mirrors AI Administration). Each section is its own\n * `BaseResourceComponent` registered under a distinct `DriverClass` and hosting the matching standalone\n * panel (`ps-home`, `ps-pipelines`, …). Because the panels all take `@Input() engine:\n * PredictiveStudioEngine`, every section resource has identical data-loading and lifecycle needs — this\n * base captures that once so the concrete wrappers stay thin (single panel binding, single\n * `DriverClass`, single icon/title).\n *\n * Responsibilities owned here:\n * - **Self-load the engine.** Each section resolves a provider-scoped {@link PredictiveStudioEngine} via\n * `GetProviderInstance` (multi-provider correctness — never the process-global singleton) and runs\n * `Config`. The monolith loaded the engine once for all six panels; standalone sections each load it,\n * but `Config(false, …)` is a cached no-op after the first section warms it, so the cost is paid once.\n * - **Signal load completion.** Calls {@link NotifyLoadComplete} after the engine resolves (or fails),\n * so direct-URL navigation to any section clears the shell loading screen. Failures still notify —\n * the panel renders its representative sample data when the live arrays are empty.\n * - **Agent context.** Reports a small section snapshot to the AI agent (chat + realtime co-agent) via\n * `SetAgentContext`. No mutating client tools are exposed — Predictive Studio's writes happen through\n * its own dialogs/agent, not via surface tools.\n *\n * The docked per-section copilot from the monolith is intentionally gone: MJ's global chat now owns the\n * Model Development Agent conversation, so sections don't embed their own chat.\n *\n * @template TKey the agent-context `Section` discriminator string for this resource.\n */\n@Directive()\nexport abstract class PSResourceBase extends BaseResourceComponent {\n protected readonly cdr = inject(ChangeDetectorRef);\n\n /**\n * Provider-scoped Predictive Studio engine. Resolved in {@link loadSection} via\n * {@link PredictiveStudioEngine.GetProviderInstance} so a multi-provider client (or an embedded\n * non-default provider) reads the right server's PS reference data. Bound into the hosted panel's\n * `[engine]` input once loading completes.\n */\n public engine: PredictiveStudioEngine = PredictiveStudioEngine.Instance;\n\n /** True until the engine resolves; gates the panel host so `[engine]` is never bound before it's ready. */\n public isLoading = true;\n\n /** Stable section identifier for agent context + (subclass) titling. */\n protected abstract readonly SectionKey: string;\n\n /** Human-readable section label used in chrome + agent context. */\n protected abstract readonly SectionLabel: string;\n\n ngOnInit(): void {\n super.ngOnInit();\n void this.loadSection();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n /**\n * Resolve the provider-scoped engine, then notify the shell. Always calls {@link NotifyLoadComplete}\n * — even on failure — so the loading screen can never hang on a direct-URL section load.\n */\n protected async loadSection(): Promise<void> {\n this.isLoading = true;\n try {\n const provider = this.ProviderToUse;\n this.engine = <PredictiveStudioEngine>(\n PredictiveStudioEngine.GetProviderInstance(provider, PredictiveStudioEngine)\n );\n await this.engine.Config(false, provider.CurrentUser ?? undefined, provider);\n this.publishAgentContext();\n } catch (err) {\n LogError(\n `Predictive Studio (${this.SectionKey}) failed to load engine: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n this.NotifyLoadComplete();\n }\n }\n\n /**\n * Report the section's state to the AI agent (async chat + realtime co-agent share this snapshot).\n * Subclasses may override {@link extraAgentContext} to add section-specific fields. No client tools\n * are registered — Predictive Studio surfaces are read/navigate-only to the agent; model creation,\n * training, and promotion run through PS's own dialogs and the Model Development Agent.\n */\n protected publishAgentContext(): void {\n this.navigationService.SetAgentContext(this, {\n App: 'Predictive Studio',\n Section: this.SectionKey,\n SectionLabel: this.SectionLabel,\n PublishedModels: this.engine.Models.filter((m) => m.Status === 'Published').length,\n RunningSessions: this.engine.Sessions.filter((s) => s.Status === 'Running').length,\n ...this.extraAgentContext(),\n });\n }\n\n /** Hook for subclasses to contribute section-specific agent-context fields. Default: none. */\n protected extraAgentContext(): Record<string, unknown> {\n return {};\n }\n\n async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return this.SectionLabel;\n }\n\n override async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return this.SectionIcon;\n }\n\n /** Font Awesome icon for the section (chrome + shell tab). */\n protected abstract readonly SectionIcon: string;\n}\n"]}
1
+ {"version":3,"file":"ps-resource-base.js","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-resource-base.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectorRef, Directive, inject } from '@angular/core';\nimport { LogError } from '@memberjunction/core';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { PredictiveStudioEngine } from '../engine/predictive-studio.engine';\n\n/**\n * Shared base for every Predictive Studio section resource.\n *\n * Predictive Studio was refactored from one monolithic left-nav dashboard into six top-nav Nav Items\n * (the canonical MJ app shape — mirrors AI Administration). Each section is its own\n * `BaseResourceComponent` registered under a distinct `DriverClass` and hosting the matching standalone\n * panel (`ps-home`, `ps-pipelines`, …). Because the panels all take `@Input() engine:\n * PredictiveStudioEngine`, every section resource has identical data-loading and lifecycle needs — this\n * base captures that once so the concrete wrappers stay thin (single panel binding, single\n * `DriverClass`, single icon/title).\n *\n * Responsibilities owned here:\n * - **Self-load the engine.** Each section resolves a provider-scoped {@link PredictiveStudioEngine} via\n * `GetProviderInstance` (multi-provider correctness — never the process-global singleton) and runs\n * `Config`. The monolith loaded the engine once for all six panels; standalone sections each load it,\n * but `Config(false, …)` is a cached no-op after the first section warms it, so the cost is paid once.\n * - **Signal load completion.** Calls {@link NotifyLoadComplete} after the engine resolves (or fails),\n * so direct-URL navigation to any section clears the shell loading screen. Failures still notify —\n * the panel renders its representative sample data when the live arrays are empty.\n * - **Agent context.** Reports a small section snapshot to the AI agent (chat + realtime co-agent) via\n * `SetAgentContext`. No mutating client tools are exposed — Predictive Studio's writes happen through\n * its own dialogs/agent, not via surface tools.\n *\n * The docked per-section copilot from the monolith is intentionally gone: MJ's global chat now owns the\n * Model Development Agent conversation, so sections don't embed their own chat.\n *\n * @template TKey the agent-context `Section` discriminator string for this resource.\n */\n@Directive()\nexport abstract class PSResourceBase extends BaseResourceComponent {\n protected readonly cdr = inject(ChangeDetectorRef);\n\n /**\n * Provider-scoped Predictive Studio engine. Resolved in {@link loadSection} via\n * {@link PredictiveStudioEngine.GetProviderInstance} so a multi-provider client (or an embedded\n * non-default provider) reads the right server's PS reference data. Bound into the hosted panel's\n * `[engine]` input once loading completes.\n */\n public engine: PredictiveStudioEngine = PredictiveStudioEngine.Instance;\n\n /** True until the engine resolves; gates the panel host so `[engine]` is never bound before it's ready. */\n public isLoading = true;\n\n /**\n * Set when {@link loadSection} fails to resolve the engine. The section templates render a \"couldn't\n * load\" banner with a Try-again button ({@link retryLoad}) instead of silently showing empty panels, so\n * a failed load is honest rather than indistinguishable from a genuinely-empty studio.\n */\n public loadError: string | null = null;\n\n /** Public door label for templates (the error banner title). Mirrors the protected {@link SectionLabel}. */\n public get sectionTitle(): string {\n return this.SectionLabel;\n }\n\n /** Stable section identifier for agent context + (subclass) titling. */\n protected abstract readonly SectionKey: string;\n\n /** Human-readable section label used in chrome + agent context. */\n protected abstract readonly SectionLabel: string;\n\n ngOnInit(): void {\n super.ngOnInit();\n void this.loadSection();\n }\n\n ngOnDestroy(): void {\n super.ngOnDestroy();\n }\n\n /**\n * Resolve the provider-scoped engine, then notify the shell. Always calls {@link NotifyLoadComplete}\n * — even on failure — so the loading screen can never hang on a direct-URL section load.\n */\n protected async loadSection(): Promise<void> {\n this.isLoading = true;\n this.loadError = null;\n try {\n const provider = this.ProviderToUse;\n this.engine = <PredictiveStudioEngine>(\n PredictiveStudioEngine.GetProviderInstance(provider, PredictiveStudioEngine)\n );\n await this.engine.Config(false, provider.CurrentUser ?? undefined, provider);\n this.publishAgentContext();\n this.registerAgentTools();\n } catch (err) {\n this.loadError = err instanceof Error ? err.message : String(err);\n LogError(`Predictive Studio (${this.SectionKey}) failed to load engine: ${this.loadError}`);\n } finally {\n this.isLoading = false;\n this.cdr.detectChanges();\n this.NotifyLoadComplete();\n }\n }\n\n /** Retry the engine load after a failure — bound to the error banner's \"Try again\" button. */\n public retryLoad(): void {\n void this.loadSection();\n }\n\n /**\n * Report the section's state to the AI agent (async chat + realtime co-agent share this snapshot).\n * Subclasses may override {@link extraAgentContext} to add section-specific fields. No client tools\n * are registered — Predictive Studio surfaces are read/navigate-only to the agent; model creation,\n * training, and promotion run through PS's own dialogs and the Model Development Agent.\n */\n protected publishAgentContext(): void {\n this.navigationService.SetAgentContext(this, {\n App: 'Predictive Studio',\n Section: this.SectionKey,\n SectionLabel: this.SectionLabel,\n PublishedModels: this.engine.Models.filter((m) => m.Status === 'Published').length,\n RunningSessions: this.engine.Sessions.filter((s) => s.Status === 'Running').length,\n ...this.extraAgentContext(),\n });\n }\n\n /** Hook for subclasses to contribute section-specific agent-context fields. Default: none. */\n protected extraAgentContext(): Record<string, unknown> {\n return {};\n }\n\n /**\n * Hook for subclasses to register the door's agent client tools once, after the engine loads. Default:\n * none. 🔒 Predictive Studio surfaces are **read / navigate-only to the agent** — overrides expose ONLY\n * section-switch / open / review / export / open-copilot tools; NEVER train, publish, delete,\n * score, \"save scores\", or \"send to a list\" (which write records). See {@link ../predictive-studio-agent-context}.\n */\n protected registerAgentTools(): void {\n /* no tools by default */\n }\n\n async GetResourceDisplayName(_data: ResourceData): Promise<string> {\n return this.SectionLabel;\n }\n\n override async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return this.SectionIcon;\n }\n\n /** Font Awesome icon for the section (chrome + shell tab). */\n protected abstract readonly SectionIcon: string;\n}\n"]}
@@ -33,11 +33,19 @@ export declare class PSStudioResourceComponent extends PSResourceBase {
33
33
  ngOnInit(): void;
34
34
  /** React to deep-link / back-forward `section` changes after the initial mount. */
35
35
  protected OnQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): void;
36
+ /** Deep agent context for the Studio door (build/run workbench counts + active section). */
36
37
  protected extraAgentContext(): Record<string, unknown>;
38
+ /**
39
+ * 🔒 Read/navigate-only agent tools for the Studio door: switch the active section, or open the docked
40
+ * Model Dev Agent co-pilot. NO build/train/publish tool is exposed — model creation runs through the
41
+ * co-pilot conversation (the approve-gated builder), never a fire-and-forget agent tool.
42
+ */
43
+ protected registerAgentTools(): void;
37
44
  get groups(): string[];
38
45
  itemsForGroup(group: string): PSSection[];
39
46
  get activeLabel(): string;
40
- get activeIcon(): string;
47
+ /** Section-specific subtitle for the interior header (so every section doesn't repeat one generic line). */
48
+ get activeSubtitle(): string;
41
49
  selectSection(key: PSPanelKey): void;
42
50
  /** The Overview panel's in-app navigation: switch section in-place, or cross to the Models door. */
43
51
  mapNavigate(key: PSPanelKey): void;
@@ -47,6 +55,8 @@ export declare class PSStudioResourceComponent extends PSResourceBase {
47
55
  get modelDevAgentId(): string | null;
48
56
  get chatAppContext(): Record<string, unknown>;
49
57
  onAskAgent(starterPrompt: string): void;
58
+ /** Open the docked co-pilot (clean chat) — used by the read-only `OpenModelDevAgentCopilot` agent tool. */
59
+ openCopilot(): void;
50
60
  closeChat(): void;
51
61
  /** Chat-area created its backing conversation on the first send — capture it + leave new-mode so the thread renders. */
52
62
  onChatConversationCreated(event: {
@@ -1 +1 @@
1
- {"version":3,"file":"ps-studio-resource.component.d.ts","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-studio-resource.component.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAA+B,MAAM,+BAA+B,CAAC;AAGlG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAEL,SAAS,EAOV,MAAM,0BAA0B,CAAC;;AAMlC;;;;;;;;;;GAUG;AACH,qBAyFa,yBAA0B,SAAQ,cAAc;IAC3D,SAAS,CAAC,QAAQ,CAAC,UAAU,YAAY;IACzC,SAAS,CAAC,QAAQ,CAAC,YAAY,YAAY;IAC3C,SAAS,CAAC,QAAQ,CAAC,WAAW,4BAA4B;IAE1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IAEtD,yGAAyG;IAClG,aAAa,EAAE,UAAU,CAAU;IAC1C,SAAgB,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAmB;IAG1D,QAAQ,UAAS;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC3C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,yGAAyG;IAClG,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAAQ;IACrD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACzC,qBAAqB,UAAQ;IAE3B,QAAQ,IAAI,IAAI;IAMzB,mFAAmF;cAChE,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI;cAQ5F,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAK/D,IAAW,MAAM,IAAI,MAAM,EAAE,CAAyC;IAC/D,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE;IAChD,IAAW,WAAW,IAAI,MAAM,CAA4D;IAC5F,IAAW,UAAU,IAAI,MAAM,CAA2D;IAEnF,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAQ3C,oGAAoG;IAC7F,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAUzC,IAAW,WAAW,IAAI,QAAQ,GAAG,IAAI,CAAmD;IAC5F,IAAW,iBAAiB,IAAI,MAAM,CAErC;IACD,IAAW,aAAa,IAAI,MAAM,GAAG,IAAI,CAAwF;IACjI,IAAW,eAAe,IAAI,MAAM,GAAG,IAAI,CAAkC;IAC7E,IAAW,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEnD;IAEM,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAOvC,SAAS,IAAI,IAAI;IAMxB,wHAAwH;IACjH,yBAAyB,CAAC,KAAK,EAAE;QAAE,YAAY,EAAE,oBAAoB,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAQ9G,iGAAiG;IAC1F,4BAA4B,IAAI,IAAI;YAK7B,2BAA2B;yCAtG9B,yBAAyB;2CAAzB,yBAAyB;CAkHrC;AAED,wGAAwG;AACxG,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
1
+ {"version":3,"file":"ps-studio-resource.component.d.ts","sourceRoot":"","sources":["../../../src/PredictiveStudio/resources/ps-studio-resource.component.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAA+B,MAAM,+BAA+B,CAAC;AAGlG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAEL,SAAS,EAMV,MAAM,0BAA0B,CAAC;;AAQlC;;;;;;;;;;GAUG;AACH,qBAyGa,yBAA0B,SAAQ,cAAc;IAC3D,SAAS,CAAC,QAAQ,CAAC,UAAU,YAAY;IACzC,SAAS,CAAC,QAAQ,CAAC,YAAY,YAAY;IAC3C,SAAS,CAAC,QAAQ,CAAC,WAAW,4BAA4B;IAE1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IAEtD,yGAAyG;IAClG,aAAa,EAAE,UAAU,CAAU;IAC1C,SAAgB,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAmB;IAG1D,QAAQ,UAAS;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC3C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,yGAAyG;IAClG,gBAAgB,EAAE,oBAAoB,GAAG,IAAI,CAAQ;IACrD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACzC,qBAAqB,UAAQ;IAE3B,QAAQ,IAAI,IAAI;IAMzB,mFAAmF;cAChE,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI;IAQ/G,4FAA4F;cACzE,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAe/D;;;;OAIG;cACgB,kBAAkB,IAAI,IAAI;IA+B7C,IAAW,MAAM,IAAI,MAAM,EAAE,CAAyC;IAC/D,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE;IAChD,IAAW,WAAW,IAAI,MAAM,CAA4D;IAE5F,4GAA4G;IAC5G,IAAW,cAAc,IAAI,MAAM,CASlC;IAEM,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAQ3C,oGAAoG;IAC7F,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAUzC,IAAW,WAAW,IAAI,QAAQ,GAAG,IAAI,CAAmD;IAE5F,IAAW,iBAAiB,IAAI,MAAM,CAErC;IACD,IAAW,aAAa,IAAI,MAAM,GAAG,IAAI,CAAwF;IACjI,IAAW,eAAe,IAAI,MAAM,GAAG,IAAI,CAAkC;IAC7E,IAAW,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEnD;IAEM,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAQ9C,2GAA2G;IACpG,WAAW,IAAI,IAAI;IAQnB,SAAS,IAAI,IAAI;IAOxB,wHAAwH;IACjH,yBAAyB,CAAC,KAAK,EAAE;QAAE,YAAY,EAAE,oBAAoB,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAQ9G,iGAAiG;IAC1F,4BAA4B,IAAI,IAAI;YAK7B,2BAA2B;yCA5K9B,yBAAyB;2CAAzB,yBAAyB;CAwLrC;AAED,wGAAwG;AACxG,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}