@memberjunction/ng-core-entity-forms 6.1.4 → 6.2.0-edge.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.d.ts +1 -1
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.js +2 -2
- package/dist/lib/custom/AIAgentCategories/ai-agent-category-overview.panel.js.map +1 -1
- package/dist/lib/custom/AIAgentSessions/ai-agent-session-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts +90 -16
- package/dist/lib/custom/AIAgents/add-action-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js +218 -70
- package/dist/lib/custom/AIAgents/add-action-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts +80 -16
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js +146 -46
- package/dist/lib/custom/AIAgents/agent-prompt-advanced-settings-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts +329 -27
- package/dist/lib/custom/AIAgents/ai-agent-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js +794 -262
- package/dist/lib/custom/AIAgents/ai-agent-form.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-management.service.d.ts +76 -0
- package/dist/lib/custom/AIAgents/ai-agent-management.service.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/ai-agent-management.service.js +77 -33
- package/dist/lib/custom/AIAgents/ai-agent-management.service.js.map +1 -1
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts +69 -15
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js +182 -74
- package/dist/lib/custom/AIAgents/create-prompt-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts +105 -25
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js +272 -112
- package/dist/lib/custom/AIAgents/create-sub-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.d.ts +32 -6
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js +71 -19
- package/dist/lib/custom/AIAgents/new-agent-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.service.d.ts +10 -0
- package/dist/lib/custom/AIAgents/new-agent-dialog.service.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/new-agent-dialog.service.js +27 -7
- package/dist/lib/custom/AIAgents/new-agent-dialog.service.js.map +1 -1
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts +65 -15
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js +152 -52
- package/dist/lib/custom/AIAgents/prompt-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts +81 -15
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js +145 -45
- package/dist/lib/custom/AIAgents/sub-agent-advanced-settings-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts +71 -17
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js +175 -67
- package/dist/lib/custom/AIAgents/sub-agent-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts +173 -27
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js +385 -93
- package/dist/lib/custom/AIPromptRuns/ai-prompt-run-form.component.js.map +1 -1
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.d.ts +64 -4
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js +129 -29
- package/dist/lib/custom/AIPromptRuns/chat-message-viewer.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts +260 -27
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js +686 -238
- package/dist/lib/custom/AIPrompts/ai-prompt-form.component.js.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-management.service.d.ts +10 -0
- package/dist/lib/custom/AIPrompts/ai-prompt-management.service.d.ts.map +1 -1
- package/dist/lib/custom/AIPrompts/ai-prompt-management.service.js +17 -9
- package/dist/lib/custom/AIPrompts/ai-prompt-management.service.js.map +1 -1
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts +74 -16
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js +174 -58
- package/dist/lib/custom/AIPrompts/template-selector-dialog.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-execution-log-form.component.d.ts +108 -14
- package/dist/lib/custom/Actions/action-execution-log-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Actions/action-execution-log-form.component.js +258 -70
- package/dist/lib/custom/Actions/action-execution-log-form.component.js.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.d.ts +198 -14
- package/dist/lib/custom/Actions/action-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Actions/action-form.component.js +387 -107
- package/dist/lib/custom/Actions/action-form.component.js.map +1 -1
- package/dist/lib/custom/BridgeProviders/bridge-provider-features.d.ts +12 -6
- package/dist/lib/custom/BridgeProviders/bridge-provider-features.d.ts.map +1 -1
- package/dist/lib/custom/BridgeProviders/bridge-provider-features.js +41 -29
- package/dist/lib/custom/BridgeProviders/bridge-provider-features.js.map +1 -1
- package/dist/lib/custom/BridgeProviders/bridge-provider-form.component.js +14 -14
- package/dist/lib/custom/BridgeProviders/bridge-provider-form.component.js.map +1 -1
- package/dist/lib/custom/Companies/company-overview.panel.d.ts +1 -1
- package/dist/lib/custom/Companies/company-overview.panel.js +2 -2
- package/dist/lib/custom/Companies/company-overview.panel.js.map +1 -1
- package/dist/lib/custom/Conversations/conversation-overview.panel.d.ts +1 -1
- package/dist/lib/custom/Conversations/conversation-overview.panel.js +2 -2
- package/dist/lib/custom/Conversations/conversation-overview.panel.js.map +1 -1
- package/dist/lib/custom/Employees/employee-overview.panel.d.ts +1 -1
- package/dist/lib/custom/Employees/employee-overview.panel.js +2 -2
- package/dist/lib/custom/Employees/employee-overview.panel.js.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.d.ts +209 -28
- package/dist/lib/custom/Entities/entity-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Entities/entity-form.component.js +494 -138
- package/dist/lib/custom/Entities/entity-form.component.js.map +1 -1
- package/dist/lib/custom/EntityActions/entityaction.form.component.d.ts +5 -1
- package/dist/lib/custom/EntityActions/entityaction.form.component.d.ts.map +1 -1
- package/dist/lib/custom/EntityActions/entityaction.form.component.js +10 -2
- package/dist/lib/custom/EntityActions/entityaction.form.component.js.map +1 -1
- package/dist/lib/custom/Files/file-form.component.d.ts +1 -1
- package/dist/lib/custom/Files/file-form.component.js +2 -2
- package/dist/lib/custom/Files/file-form.component.js.map +1 -1
- package/dist/lib/custom/Lists/list-form.component.d.ts +300 -36
- package/dist/lib/custom/Lists/list-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Lists/list-form.component.js +664 -208
- package/dist/lib/custom/Lists/list-form.component.js.map +1 -1
- package/dist/lib/custom/MLModels/ml-model-form.component.d.ts +27 -0
- package/dist/lib/custom/MLModels/ml-model-form.component.d.ts.map +1 -0
- package/dist/lib/custom/MLModels/ml-model-form.component.js +193 -0
- package/dist/lib/custom/MLModels/ml-model-form.component.js.map +1 -0
- package/dist/lib/custom/MLModels/ml-model-view-models.d.ts +75 -0
- package/dist/lib/custom/MLModels/ml-model-view-models.d.ts.map +1 -0
- package/dist/lib/custom/MLModels/ml-model-view-models.js +244 -0
- package/dist/lib/custom/MLModels/ml-model-view-models.js.map +1 -0
- package/dist/lib/custom/MLModels/ps-model-detail.component.d.ts +173 -0
- package/dist/lib/custom/MLModels/ps-model-detail.component.d.ts.map +1 -0
- package/dist/lib/custom/MLModels/ps-model-detail.component.js +883 -0
- package/dist/lib/custom/MLModels/ps-model-detail.component.js.map +1 -0
- package/dist/lib/custom/Queries/query-form.component.d.ts +201 -26
- package/dist/lib/custom/Queries/query-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Queries/query-form.component.js +429 -109
- package/dist/lib/custom/Queries/query-form.component.js.map +1 -1
- package/dist/lib/custom/Queries/query-run-dialog.component.d.ts +107 -14
- package/dist/lib/custom/Queries/query-run-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/Queries/query-run-dialog.component.js +249 -79
- package/dist/lib/custom/Queries/query-run-dialog.component.js.map +1 -1
- package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts +133 -7
- package/dist/lib/custom/RecordProcesses/record-process-form.component.d.ts.map +1 -1
- package/dist/lib/custom/RecordProcesses/record-process-form.component.js +1268 -19
- package/dist/lib/custom/RecordProcesses/record-process-form.component.js.map +1 -1
- package/dist/lib/custom/SearchScopes/searchscope-form.component.d.ts +1 -1
- package/dist/lib/custom/SearchScopes/searchscope-form.component.js +4 -4
- package/dist/lib/custom/SearchScopes/searchscope-form.component.js.map +1 -1
- package/dist/lib/custom/SessionBridges/session-bridge-form.component.js.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.d.ts +77 -13
- package/dist/lib/custom/Templates/template-param-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/template-param-dialog.component.js +196 -78
- package/dist/lib/custom/Templates/template-param-dialog.component.js.map +1 -1
- package/dist/lib/custom/Templates/template-params-grid.component.d.ts +49 -7
- package/dist/lib/custom/Templates/template-params-grid.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/template-params-grid.component.js +132 -44
- package/dist/lib/custom/Templates/template-params-grid.component.js.map +1 -1
- package/dist/lib/custom/Templates/templates-form.component.d.ts +142 -17
- package/dist/lib/custom/Templates/templates-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Templates/templates-form.component.js +333 -113
- package/dist/lib/custom/Templates/templates-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/entity-link-pill.component.d.ts +24 -4
- package/dist/lib/custom/Tests/entity-link-pill.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/entity-link-pill.component.js +64 -20
- package/dist/lib/custom/Tests/entity-link-pill.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.d.ts +217 -27
- package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-form.component.js +549 -169
- package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-run-checks.d.ts +2 -0
- package/dist/lib/custom/Tests/test-run-checks.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-run-checks.js +5 -1
- package/dist/lib/custom/Tests/test-run-checks.js.map +1 -1
- package/dist/lib/custom/Tests/test-run-feedback-form.component.d.ts +2 -0
- package/dist/lib/custom/Tests/test-run-feedback-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-run-feedback-form.component.js +5 -1
- package/dist/lib/custom/Tests/test-run-feedback-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-run-form.component.d.ts +146 -18
- package/dist/lib/custom/Tests/test-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-run-form.component.js +362 -106
- package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts +390 -47
- package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-form.component.js +1015 -343
- package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts +214 -26
- package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts.map +1 -1
- package/dist/lib/custom/Tests/test-suite-run-form.component.js +535 -159
- package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
- package/dist/lib/custom/Users/user-overview.panel.d.ts +1 -1
- package/dist/lib/custom/Users/user-overview.panel.js +2 -2
- package/dist/lib/custom/Users/user-overview.panel.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts +208 -29
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js +446 -138
- package/dist/lib/custom/ai-agent-run/ai-agent-run-analytics.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.d.ts +6 -0
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.js +16 -4
- package/dist/lib/custom/ai-agent-run/ai-agent-run-cost.service.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts +50 -6
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js +84 -12
- package/dist/lib/custom/ai-agent-run/ai-agent-run-data.service.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts +89 -5
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js +216 -70
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-detail.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.d.ts +62 -3
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.js +140 -42
- package/dist/lib/custom/ai-agent-run/ai-agent-run-step-node.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts +81 -10
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js +165 -37
- package/dist/lib/custom/ai-agent-run/ai-agent-run-timeline.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +121 -14
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +287 -79
- package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts +101 -15
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js +281 -97
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts +43 -25
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js +100 -64
- package/dist/lib/custom/ai-agent-run/flow/agent-run-flow.model.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts +14 -2
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.js +71 -53
- package/dist/lib/custom/ai-agent-run/flow/constellation.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts +14 -2
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js +70 -52
- package/dist/lib/custom/ai-agent-run/flow/flame-cascade.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts +8 -0
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js +22 -6
- package/dist/lib/custom/ai-agent-run/flow/flow-svg.util.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts +24 -2
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js +91 -59
- package/dist/lib/custom/ai-agent-run/flow/flowchart.component.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts +10 -2
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js +33 -17
- package/dist/lib/custom/ai-agent-run/flow/pan-zoom.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.d.ts +2 -0
- package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.js +34 -30
- package/dist/lib/custom/ai-agent-run/flow/run-tree-flow-projection.js.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts +14 -2
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.d.ts.map +1 -1
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js +69 -51
- package/dist/lib/custom/ai-agent-run/flow/subway-lines.component.js.map +1 -1
- package/dist/lib/custom/custom-forms.module.d.ts +32 -30
- package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
- package/dist/lib/custom/custom-forms.module.js +21 -4
- package/dist/lib/custom/custom-forms.module.js.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts +38 -12
- package/dist/lib/custom/shared/entity-selector-dialog.component.d.ts.map +1 -1
- package/dist/lib/custom/shared/entity-selector-dialog.component.js +103 -51
- package/dist/lib/custom/shared/entity-selector-dialog.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js +62 -26
- package/dist/lib/generated/Entities/MJAIPrompt/mjaiprompt.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js +59 -51
- package/dist/lib/generated/Entities/MJAIPromptRun/mjaipromptrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.js +76 -74
- package/dist/lib/generated/Entities/MJAIVendor/mjaivendor.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js +33 -15
- package/dist/lib/generated/Entities/MJCredential/mjcredential.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js +100 -82
- package/dist/lib/generated/Entities/MJEntity/mjentity.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js +24 -20
- package/dist/lib/generated/Entities/MJEntityField/mjentityfield.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.js +122 -0
- package/dist/lib/generated/Entities/MJFeatureValue/mjfeaturevalue.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJFeatureValueCache/mjfeaturevaluecache.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJFeatureValueCache/mjfeaturevaluecache.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJFeatureValueCache/mjfeaturevaluecache.form.component.js +125 -0
- package/dist/lib/generated/Entities/MJFeatureValueCache/mjfeaturevaluecache.form.component.js.map +1 -0
- package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js +23 -5
- package/dist/lib/generated/Entities/MJProcessRun/mjprocessrun.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJProcessRunDetail/mjprocessrundetail.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJProcessRunDetail/mjprocessrundetail.form.component.js +25 -6
- package/dist/lib/generated/Entities/MJProcessRunDetail/mjprocessrundetail.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJProject/mjproject.form.component.js +27 -25
- package/dist/lib/generated/Entities/MJProject/mjproject.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js +11 -15
- package/dist/lib/generated/Entities/MJQuery/mjquery.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js +43 -7
- package/dist/lib/generated/Entities/MJRecordProcess/mjrecordprocess.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.d.ts.map +1 -1
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js +155 -119
- package/dist/lib/generated/Entities/MJUser/mjuser.form.component.js.map +1 -1
- package/dist/lib/generated/Entities/MJWebSearchProvider/mjwebsearchprovider.form.component.d.ts +10 -0
- package/dist/lib/generated/Entities/MJWebSearchProvider/mjwebsearchprovider.form.component.d.ts.map +1 -0
- package/dist/lib/generated/Entities/MJWebSearchProvider/mjwebsearchprovider.form.component.js +78 -0
- package/dist/lib/generated/Entities/MJWebSearchProvider/mjwebsearchprovider.form.component.js.map +1 -0
- package/dist/lib/generated/generated-forms.module.d.ts +240 -237
- package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
- package/dist/lib/generated/generated-forms.module.js +11 -2
- package/dist/lib/generated/generated-forms.module.js.map +1 -1
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts +5 -1
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.d.ts.map +1 -1
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js +11 -3
- package/dist/lib/panels/ai-skill-sharing/ai-skill-sharing-panel.component.js.map +1 -1
- package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.d.ts +2 -0
- package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.d.ts.map +1 -1
- package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.js +16 -12
- package/dist/lib/panels/content-sources/tag-pipeline-configuration.panel.js.map +1 -1
- package/dist/lib/panels/content-sources/website-crawler-settings.panel.d.ts +1 -1
- package/dist/lib/panels/content-sources/website-crawler-settings.panel.js +2 -2
- package/dist/lib/panels/content-sources/website-crawler-settings.panel.js.map +1 -1
- package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts +122 -1
- package/dist/lib/panels/model-predictions/model-prediction.logic.d.ts.map +1 -1
- package/dist/lib/panels/model-predictions/model-prediction.logic.js +236 -11
- package/dist/lib/panels/model-predictions/model-prediction.logic.js.map +1 -1
- package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts +72 -13
- package/dist/lib/panels/model-predictions/model-prediction.panel.d.ts.map +1 -1
- package/dist/lib/panels/model-predictions/model-prediction.panel.js +577 -78
- package/dist/lib/panels/model-predictions/model-prediction.panel.js.map +1 -1
- package/dist/lib/shared/components/template-editor.component.d.ts +133 -14
- package/dist/lib/shared/components/template-editor.component.d.ts.map +1 -1
- package/dist/lib/shared/components/template-editor.component.js +322 -124
- package/dist/lib/shared/components/template-editor.component.js.map +1 -1
- package/dist/public-api.d.ts +4 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +4 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +43 -41
|
@@ -1540,48 +1540,244 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1540
1540
|
this.testHarnessService = inject(AITestHarnessDialogService);
|
|
1541
1541
|
this.viewContainerRef = inject(ViewContainerRef);
|
|
1542
1542
|
this.promptManagementService = inject(AIPromptManagementService);
|
|
1543
|
-
this.
|
|
1544
|
-
this.
|
|
1545
|
-
this.
|
|
1546
|
-
this.
|
|
1547
|
-
this.
|
|
1548
|
-
this.
|
|
1549
|
-
this.
|
|
1550
|
-
this.
|
|
1543
|
+
this.ToolbarConfig = CUSTOM_LAYOUT_TOOLBAR_CONFIG;
|
|
1544
|
+
this.Template = null;
|
|
1545
|
+
this.TemplateContent = null;
|
|
1546
|
+
this.TemplateParams = [];
|
|
1547
|
+
this.IsLoadingTemplate = true;
|
|
1548
|
+
this.IsLoadingTemplateParams = false;
|
|
1549
|
+
this.TemplateNotFoundInDatabase = false;
|
|
1550
|
+
this.ShowTestHarness = false;
|
|
1551
1551
|
// Model management
|
|
1552
|
-
this.
|
|
1553
|
-
this.
|
|
1554
|
-
this.
|
|
1555
|
-
this.
|
|
1552
|
+
this.PromptModels = [];
|
|
1553
|
+
this.AvailableModels = [];
|
|
1554
|
+
this.AvailableVendors = [];
|
|
1555
|
+
this.IsLoadingModels = false;
|
|
1556
1556
|
// Vendor management per model
|
|
1557
|
-
this.
|
|
1557
|
+
this.ModelVendorsMap = new Map();
|
|
1558
1558
|
// AI Prompt Types
|
|
1559
|
-
this.
|
|
1560
|
-
this.
|
|
1559
|
+
this.AvailablePromptTypes = [];
|
|
1560
|
+
this.IsLoadingPromptTypes = false;
|
|
1561
1561
|
// AI Configurations
|
|
1562
|
-
this.
|
|
1563
|
-
this.
|
|
1562
|
+
this.AvailableConfigurations = [];
|
|
1563
|
+
this.IsLoadingConfigurations = false;
|
|
1564
1564
|
// Result Selector Tree Data
|
|
1565
|
-
this.
|
|
1566
|
-
this.
|
|
1565
|
+
this.ResultSelectorTreeData = [];
|
|
1566
|
+
this.IsLoadingResultSelectorData = false;
|
|
1567
1567
|
// Drag and drop state
|
|
1568
|
-
this.
|
|
1568
|
+
this.DraggedIndex = -1;
|
|
1569
1569
|
// Execution History
|
|
1570
|
-
this.
|
|
1571
|
-
this.
|
|
1572
|
-
this.
|
|
1573
|
-
this.
|
|
1570
|
+
this.ExecutionHistory = [];
|
|
1571
|
+
this.IsLoadingHistory = false;
|
|
1572
|
+
this.HistorySortField = 'runAt';
|
|
1573
|
+
this.HistorySortDirection = 'desc';
|
|
1574
1574
|
// Removed custom transaction tracking - we'll use base form's _pendingRecords instead
|
|
1575
|
-
this.
|
|
1575
|
+
this.HasUnsavedChanges = false;
|
|
1576
1576
|
// Store original state for cancel/revert functionality
|
|
1577
1577
|
this.originalTemplateID = null;
|
|
1578
1578
|
// === Permission Checks for Related Entities ===
|
|
1579
1579
|
/** Cache for permission checks to avoid repeated calculations */
|
|
1580
1580
|
this._permissionCache = new Map();
|
|
1581
|
-
this.
|
|
1581
|
+
this.__inferenceProvider_VendorTypeDefinitionID = '';
|
|
1582
|
+
}
|
|
1583
|
+
/** @deprecated Use {@link ToolbarConfig}. */
|
|
1584
|
+
get toolbarConfig() {
|
|
1585
|
+
return this.ToolbarConfig;
|
|
1582
1586
|
}
|
|
1583
1587
|
/** Custom-layout AI Prompt form looks best full-width on first open. */
|
|
1584
1588
|
getDefaultFormWidthMode() { return 'full-width'; }
|
|
1589
|
+
/** @deprecated Use {@link Template}. */
|
|
1590
|
+
get template() {
|
|
1591
|
+
return this.Template;
|
|
1592
|
+
}
|
|
1593
|
+
/** @deprecated Use {@link Template}. */
|
|
1594
|
+
set template(value) {
|
|
1595
|
+
this.Template = value;
|
|
1596
|
+
}
|
|
1597
|
+
/** @deprecated Use {@link TemplateContent}. */
|
|
1598
|
+
get templateContent() {
|
|
1599
|
+
return this.TemplateContent;
|
|
1600
|
+
}
|
|
1601
|
+
/** @deprecated Use {@link TemplateContent}. */
|
|
1602
|
+
set templateContent(value) {
|
|
1603
|
+
this.TemplateContent = value;
|
|
1604
|
+
}
|
|
1605
|
+
/** @deprecated Use {@link TemplateParams}. */
|
|
1606
|
+
get templateParams() {
|
|
1607
|
+
return this.TemplateParams;
|
|
1608
|
+
}
|
|
1609
|
+
/** @deprecated Use {@link TemplateParams}. */
|
|
1610
|
+
set templateParams(value) {
|
|
1611
|
+
this.TemplateParams = value;
|
|
1612
|
+
}
|
|
1613
|
+
/** @deprecated Use {@link IsLoadingTemplate}. */
|
|
1614
|
+
get isLoadingTemplate() {
|
|
1615
|
+
return this.IsLoadingTemplate;
|
|
1616
|
+
}
|
|
1617
|
+
/** @deprecated Use {@link IsLoadingTemplate}. */
|
|
1618
|
+
set isLoadingTemplate(value) {
|
|
1619
|
+
this.IsLoadingTemplate = value;
|
|
1620
|
+
} // Default to loading state
|
|
1621
|
+
/** @deprecated Use {@link IsLoadingTemplateParams}. */
|
|
1622
|
+
get isLoadingTemplateParams() {
|
|
1623
|
+
return this.IsLoadingTemplateParams;
|
|
1624
|
+
}
|
|
1625
|
+
/** @deprecated Use {@link IsLoadingTemplateParams}. */
|
|
1626
|
+
set isLoadingTemplateParams(value) {
|
|
1627
|
+
this.IsLoadingTemplateParams = value;
|
|
1628
|
+
}
|
|
1629
|
+
/** @deprecated Use {@link TemplateNotFoundInDatabase}. */
|
|
1630
|
+
get templateNotFoundInDatabase() {
|
|
1631
|
+
return this.TemplateNotFoundInDatabase;
|
|
1632
|
+
}
|
|
1633
|
+
/** @deprecated Use {@link TemplateNotFoundInDatabase}. */
|
|
1634
|
+
set templateNotFoundInDatabase(value) {
|
|
1635
|
+
this.TemplateNotFoundInDatabase = value;
|
|
1636
|
+
}
|
|
1637
|
+
/** @deprecated Use {@link ShowTestHarness}. */
|
|
1638
|
+
get showTestHarness() {
|
|
1639
|
+
return this.ShowTestHarness;
|
|
1640
|
+
}
|
|
1641
|
+
/** @deprecated Use {@link ShowTestHarness}. */
|
|
1642
|
+
set showTestHarness(value) {
|
|
1643
|
+
this.ShowTestHarness = value;
|
|
1644
|
+
}
|
|
1645
|
+
/** @deprecated Use {@link PromptModels}. */
|
|
1646
|
+
get promptModels() {
|
|
1647
|
+
return this.PromptModels;
|
|
1648
|
+
}
|
|
1649
|
+
/** @deprecated Use {@link PromptModels}. */
|
|
1650
|
+
set promptModels(value) {
|
|
1651
|
+
this.PromptModels = value;
|
|
1652
|
+
}
|
|
1653
|
+
/** @deprecated Use {@link AvailableModels}. */
|
|
1654
|
+
get availableModels() {
|
|
1655
|
+
return this.AvailableModels;
|
|
1656
|
+
}
|
|
1657
|
+
/** @deprecated Use {@link AvailableModels}. */
|
|
1658
|
+
set availableModels(value) {
|
|
1659
|
+
this.AvailableModels = value;
|
|
1660
|
+
}
|
|
1661
|
+
/** @deprecated Use {@link AvailableVendors}. */
|
|
1662
|
+
get availableVendors() {
|
|
1663
|
+
return this.AvailableVendors;
|
|
1664
|
+
}
|
|
1665
|
+
/** @deprecated Use {@link AvailableVendors}. */
|
|
1666
|
+
set availableVendors(value) {
|
|
1667
|
+
this.AvailableVendors = value;
|
|
1668
|
+
}
|
|
1669
|
+
/** @deprecated Use {@link IsLoadingModels}. */
|
|
1670
|
+
get isLoadingModels() {
|
|
1671
|
+
return this.IsLoadingModels;
|
|
1672
|
+
}
|
|
1673
|
+
/** @deprecated Use {@link IsLoadingModels}. */
|
|
1674
|
+
set isLoadingModels(value) {
|
|
1675
|
+
this.IsLoadingModels = value;
|
|
1676
|
+
}
|
|
1677
|
+
/** @deprecated Use {@link ModelVendorsMap}. */
|
|
1678
|
+
get modelVendorsMap() {
|
|
1679
|
+
return this.ModelVendorsMap;
|
|
1680
|
+
}
|
|
1681
|
+
/** @deprecated Use {@link ModelVendorsMap}. */
|
|
1682
|
+
set modelVendorsMap(value) {
|
|
1683
|
+
this.ModelVendorsMap = value;
|
|
1684
|
+
}
|
|
1685
|
+
/** @deprecated Use {@link AvailablePromptTypes}. */
|
|
1686
|
+
get availablePromptTypes() {
|
|
1687
|
+
return this.AvailablePromptTypes;
|
|
1688
|
+
}
|
|
1689
|
+
/** @deprecated Use {@link AvailablePromptTypes}. */
|
|
1690
|
+
set availablePromptTypes(value) {
|
|
1691
|
+
this.AvailablePromptTypes = value;
|
|
1692
|
+
}
|
|
1693
|
+
/** @deprecated Use {@link IsLoadingPromptTypes}. */
|
|
1694
|
+
get isLoadingPromptTypes() {
|
|
1695
|
+
return this.IsLoadingPromptTypes;
|
|
1696
|
+
}
|
|
1697
|
+
/** @deprecated Use {@link IsLoadingPromptTypes}. */
|
|
1698
|
+
set isLoadingPromptTypes(value) {
|
|
1699
|
+
this.IsLoadingPromptTypes = value;
|
|
1700
|
+
}
|
|
1701
|
+
/** @deprecated Use {@link AvailableConfigurations}. */
|
|
1702
|
+
get availableConfigurations() {
|
|
1703
|
+
return this.AvailableConfigurations;
|
|
1704
|
+
}
|
|
1705
|
+
/** @deprecated Use {@link AvailableConfigurations}. */
|
|
1706
|
+
set availableConfigurations(value) {
|
|
1707
|
+
this.AvailableConfigurations = value;
|
|
1708
|
+
}
|
|
1709
|
+
/** @deprecated Use {@link IsLoadingConfigurations}. */
|
|
1710
|
+
get isLoadingConfigurations() {
|
|
1711
|
+
return this.IsLoadingConfigurations;
|
|
1712
|
+
}
|
|
1713
|
+
/** @deprecated Use {@link IsLoadingConfigurations}. */
|
|
1714
|
+
set isLoadingConfigurations(value) {
|
|
1715
|
+
this.IsLoadingConfigurations = value;
|
|
1716
|
+
}
|
|
1717
|
+
/** @deprecated Use {@link ResultSelectorTreeData}. */
|
|
1718
|
+
get resultSelectorTreeData() {
|
|
1719
|
+
return this.ResultSelectorTreeData;
|
|
1720
|
+
}
|
|
1721
|
+
/** @deprecated Use {@link ResultSelectorTreeData}. */
|
|
1722
|
+
set resultSelectorTreeData(value) {
|
|
1723
|
+
this.ResultSelectorTreeData = value;
|
|
1724
|
+
}
|
|
1725
|
+
/** @deprecated Use {@link IsLoadingResultSelectorData}. */
|
|
1726
|
+
get isLoadingResultSelectorData() {
|
|
1727
|
+
return this.IsLoadingResultSelectorData;
|
|
1728
|
+
}
|
|
1729
|
+
/** @deprecated Use {@link IsLoadingResultSelectorData}. */
|
|
1730
|
+
set isLoadingResultSelectorData(value) {
|
|
1731
|
+
this.IsLoadingResultSelectorData = value;
|
|
1732
|
+
}
|
|
1733
|
+
/** @deprecated Use {@link DraggedIndex}. */
|
|
1734
|
+
get draggedIndex() {
|
|
1735
|
+
return this.DraggedIndex;
|
|
1736
|
+
}
|
|
1737
|
+
/** @deprecated Use {@link DraggedIndex}. */
|
|
1738
|
+
set draggedIndex(value) {
|
|
1739
|
+
this.DraggedIndex = value;
|
|
1740
|
+
}
|
|
1741
|
+
/** @deprecated Use {@link ExecutionHistory}. */
|
|
1742
|
+
get executionHistory() {
|
|
1743
|
+
return this.ExecutionHistory;
|
|
1744
|
+
}
|
|
1745
|
+
/** @deprecated Use {@link ExecutionHistory}. */
|
|
1746
|
+
set executionHistory(value) {
|
|
1747
|
+
this.ExecutionHistory = value;
|
|
1748
|
+
}
|
|
1749
|
+
/** @deprecated Use {@link IsLoadingHistory}. */
|
|
1750
|
+
get isLoadingHistory() {
|
|
1751
|
+
return this.IsLoadingHistory;
|
|
1752
|
+
}
|
|
1753
|
+
/** @deprecated Use {@link IsLoadingHistory}. */
|
|
1754
|
+
set isLoadingHistory(value) {
|
|
1755
|
+
this.IsLoadingHistory = value;
|
|
1756
|
+
}
|
|
1757
|
+
/** @deprecated Use {@link HistorySortField}. */
|
|
1758
|
+
get historySortField() {
|
|
1759
|
+
return this.HistorySortField;
|
|
1760
|
+
}
|
|
1761
|
+
/** @deprecated Use {@link HistorySortField}. */
|
|
1762
|
+
set historySortField(value) {
|
|
1763
|
+
this.HistorySortField = value;
|
|
1764
|
+
}
|
|
1765
|
+
/** @deprecated Use {@link HistorySortDirection}. */
|
|
1766
|
+
get historySortDirection() {
|
|
1767
|
+
return this.HistorySortDirection;
|
|
1768
|
+
}
|
|
1769
|
+
/** @deprecated Use {@link HistorySortDirection}. */
|
|
1770
|
+
set historySortDirection(value) {
|
|
1771
|
+
this.HistorySortDirection = value;
|
|
1772
|
+
}
|
|
1773
|
+
/** @deprecated Use {@link HasUnsavedChanges}. */
|
|
1774
|
+
get hasUnsavedChanges() {
|
|
1775
|
+
return this.HasUnsavedChanges;
|
|
1776
|
+
}
|
|
1777
|
+
/** @deprecated Use {@link HasUnsavedChanges}. */
|
|
1778
|
+
set hasUnsavedChanges(value) {
|
|
1779
|
+
this.HasUnsavedChanges = value;
|
|
1780
|
+
}
|
|
1585
1781
|
// Main AI Prompt permissions inherited from BaseFormComponent:
|
|
1586
1782
|
// - UserCanEdit (Update permission)
|
|
1587
1783
|
// - UserCanRead (Read permission)
|
|
@@ -1669,25 +1865,41 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1669
1865
|
/**
|
|
1670
1866
|
* Clears the permission cache. Call this when user context changes or permissions are updated.
|
|
1671
1867
|
*/
|
|
1672
|
-
|
|
1868
|
+
ClearPermissionCache() {
|
|
1673
1869
|
this._permissionCache.clear();
|
|
1674
1870
|
}
|
|
1871
|
+
/** @deprecated Use {@link ClearPermissionCache}. */
|
|
1872
|
+
clearPermissionCache() {
|
|
1873
|
+
return this.ClearPermissionCache();
|
|
1874
|
+
}
|
|
1675
1875
|
// Template editor configuration
|
|
1676
|
-
get
|
|
1876
|
+
get TemplateEditorConfig() {
|
|
1677
1877
|
return {
|
|
1678
1878
|
allowEdit: this.EditMode && this.UserCanUpdateTemplateContents,
|
|
1679
1879
|
showRunButton: false,
|
|
1680
1880
|
compactMode: false
|
|
1681
1881
|
};
|
|
1682
1882
|
}
|
|
1883
|
+
/** @deprecated Use {@link TemplateEditorConfig}. */
|
|
1884
|
+
get templateEditorConfig() {
|
|
1885
|
+
return this.TemplateEditorConfig;
|
|
1886
|
+
}
|
|
1683
1887
|
get _metadata() { return this.ProviderToUse; }
|
|
1888
|
+
/** @deprecated Use {@link TemplateEditor}. */
|
|
1889
|
+
get templateEditor() {
|
|
1890
|
+
return this.TemplateEditor;
|
|
1891
|
+
}
|
|
1892
|
+
/** @deprecated Use {@link TemplateEditor}. */
|
|
1893
|
+
set templateEditor(value) {
|
|
1894
|
+
this.TemplateEditor = value;
|
|
1895
|
+
}
|
|
1684
1896
|
async ngOnInit() {
|
|
1685
1897
|
await super.ngOnInit();
|
|
1686
1898
|
// make sure AI Engine Base is configured, this will load stuff only if not already
|
|
1687
1899
|
// loaded in the current process space
|
|
1688
1900
|
await AIEngineBase.Instance.Config(false, this._metadata.CurrentUser);
|
|
1689
|
-
this.
|
|
1690
|
-
if (!this.
|
|
1901
|
+
this.__inferenceProvider_VendorTypeDefinitionID = AIEngineBase.Instance.InferenceProviderTypeID || '';
|
|
1902
|
+
if (!this.__inferenceProvider_VendorTypeDefinitionID) {
|
|
1691
1903
|
console.error('Inference Provider Vendor Type Definition ID not found');
|
|
1692
1904
|
MJNotificationService.Instance.CreateSimpleNotification('Inference Provider Vendor Type Definition not found', 'error', 5000);
|
|
1693
1905
|
return;
|
|
@@ -1699,26 +1911,26 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1699
1911
|
}
|
|
1700
1912
|
else {
|
|
1701
1913
|
// No template ID, so we're not loading
|
|
1702
|
-
this.
|
|
1914
|
+
this.IsLoadingTemplate = false;
|
|
1703
1915
|
}
|
|
1704
1916
|
// Load available models, vendors, prompt types, configurations, prompt models, and result selector data
|
|
1705
1917
|
await Promise.all([
|
|
1706
|
-
this.
|
|
1707
|
-
this.
|
|
1708
|
-
this.
|
|
1709
|
-
this.
|
|
1710
|
-
this.
|
|
1711
|
-
this.
|
|
1918
|
+
this.LoadAvailableModels(),
|
|
1919
|
+
this.LoadAvailableVendors(),
|
|
1920
|
+
this.LoadAvailablePromptTypes(),
|
|
1921
|
+
this.LoadAvailableConfigurations(),
|
|
1922
|
+
this.LoadPromptModels(),
|
|
1923
|
+
this.LoadResultSelectorTreeData()
|
|
1712
1924
|
]);
|
|
1713
1925
|
// Load execution history if record is saved
|
|
1714
1926
|
if (this.record?.IsSaved) {
|
|
1715
|
-
await this.
|
|
1927
|
+
await this.LoadExecutionHistory();
|
|
1716
1928
|
}
|
|
1717
1929
|
// Set defaults for new records
|
|
1718
1930
|
if (!this.record.IsSaved) {
|
|
1719
1931
|
// Default to first prompt type if not set
|
|
1720
|
-
if (!this.record.TypeID && this.
|
|
1721
|
-
this.record.TypeID = this.
|
|
1932
|
+
if (!this.record.TypeID && this.AvailablePromptTypes.length > 0) {
|
|
1933
|
+
this.record.TypeID = this.AvailablePromptTypes[0].ID;
|
|
1722
1934
|
}
|
|
1723
1935
|
// Default status to Pending if not set
|
|
1724
1936
|
if (!this.record.Status) {
|
|
@@ -1731,8 +1943,8 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1731
1943
|
*/
|
|
1732
1944
|
async loadTemplate() {
|
|
1733
1945
|
if (!this.record?.TemplateID) {
|
|
1734
|
-
this.
|
|
1735
|
-
this.
|
|
1946
|
+
this.Template = null;
|
|
1947
|
+
this.TemplateNotFoundInDatabase = false;
|
|
1736
1948
|
return;
|
|
1737
1949
|
}
|
|
1738
1950
|
// First check if we already have this template in pending records (newly created)
|
|
@@ -1740,23 +1952,23 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1740
1952
|
p.entityObject.Get('ID') === this.record.TemplateID);
|
|
1741
1953
|
if (pendingTemplate) {
|
|
1742
1954
|
// Use the pending template
|
|
1743
|
-
this.
|
|
1744
|
-
this.
|
|
1745
|
-
this.
|
|
1955
|
+
this.Template = pendingTemplate.entityObject;
|
|
1956
|
+
this.TemplateNotFoundInDatabase = false;
|
|
1957
|
+
this.IsLoadingTemplate = false;
|
|
1746
1958
|
// Clear template content and params since this is a new template
|
|
1747
|
-
this.
|
|
1748
|
-
this.
|
|
1959
|
+
this.TemplateContent = null;
|
|
1960
|
+
this.TemplateParams = [];
|
|
1749
1961
|
this.cdr.detectChanges();
|
|
1750
1962
|
return;
|
|
1751
1963
|
}
|
|
1752
|
-
this.
|
|
1753
|
-
this.
|
|
1964
|
+
this.IsLoadingTemplate = true;
|
|
1965
|
+
this.TemplateNotFoundInDatabase = false; // Reset the flag
|
|
1754
1966
|
try {
|
|
1755
|
-
this.
|
|
1756
|
-
await this.
|
|
1757
|
-
if (!this.
|
|
1758
|
-
this.
|
|
1759
|
-
this.
|
|
1967
|
+
this.Template = await this._metadata.GetEntityObject('MJ: Templates');
|
|
1968
|
+
await this.Template.Load(this.record.TemplateID);
|
|
1969
|
+
if (!this.Template.IsSaved) {
|
|
1970
|
+
this.Template = null;
|
|
1971
|
+
this.TemplateNotFoundInDatabase = true; // Set flag when template not found
|
|
1760
1972
|
console.warn(`Template with ID ${this.record.TemplateID} not found`);
|
|
1761
1973
|
}
|
|
1762
1974
|
else {
|
|
@@ -1769,49 +1981,53 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1769
1981
|
}
|
|
1770
1982
|
catch (error) {
|
|
1771
1983
|
console.error('Error loading template:', error);
|
|
1772
|
-
this.
|
|
1773
|
-
this.
|
|
1984
|
+
this.Template = null;
|
|
1985
|
+
this.TemplateNotFoundInDatabase = true; // Set flag on error
|
|
1774
1986
|
MJNotificationService.Instance.CreateSimpleNotification('Error loading associated template', 'error', 5000);
|
|
1775
1987
|
}
|
|
1776
1988
|
finally {
|
|
1777
|
-
this.
|
|
1989
|
+
this.IsLoadingTemplate = false;
|
|
1778
1990
|
this.cdr.detectChanges();
|
|
1779
1991
|
}
|
|
1780
1992
|
}
|
|
1781
1993
|
/**
|
|
1782
1994
|
* Handles template ID changes in the form
|
|
1783
1995
|
*/
|
|
1784
|
-
async
|
|
1996
|
+
async OnTemplateIdChange() {
|
|
1785
1997
|
if (this.record?.TemplateID) {
|
|
1786
1998
|
await this.loadTemplate();
|
|
1787
1999
|
}
|
|
1788
2000
|
else {
|
|
1789
|
-
this.
|
|
1790
|
-
this.
|
|
2001
|
+
this.Template = null;
|
|
2002
|
+
this.TemplateParams = [];
|
|
1791
2003
|
}
|
|
1792
|
-
this.
|
|
2004
|
+
this.HasUnsavedChanges = true;
|
|
2005
|
+
}
|
|
2006
|
+
/** @deprecated Use {@link OnTemplateIdChange}. */
|
|
2007
|
+
async onTemplateIdChange() {
|
|
2008
|
+
return this.OnTemplateIdChange();
|
|
1793
2009
|
}
|
|
1794
2010
|
/**
|
|
1795
2011
|
* Opens a dialog to link an existing template
|
|
1796
2012
|
*/
|
|
1797
|
-
async
|
|
2013
|
+
async LinkExistingTemplate() {
|
|
1798
2014
|
try {
|
|
1799
2015
|
this.promptManagementService.openTemplateSelectorDialog({
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
2016
|
+
Title: 'Link Existing Template',
|
|
2017
|
+
MultiSelect: false,
|
|
2018
|
+
ShowCreateNew: true,
|
|
2019
|
+
ShowActiveOnly: true,
|
|
2020
|
+
SelectedTemplateIds: this.record.TemplateID ? [this.record.TemplateID] : [],
|
|
1805
2021
|
viewContainerRef: this.viewContainerRef
|
|
1806
2022
|
}).subscribe({
|
|
1807
2023
|
next: async (result) => {
|
|
1808
|
-
if (result && result.
|
|
1809
|
-
const selectedTemplate = result.
|
|
2024
|
+
if (result && result.SelectedTemplates.length > 0) {
|
|
2025
|
+
const selectedTemplate = result.SelectedTemplates[0];
|
|
1810
2026
|
// First, clean up any pending changes related to the old template
|
|
1811
2027
|
this.cleanupOldTemplateRecords();
|
|
1812
2028
|
// Update the AI prompt to reference the selected template
|
|
1813
2029
|
this.record.TemplateID = selectedTemplate.ID;
|
|
1814
|
-
this.
|
|
2030
|
+
this.HasUnsavedChanges = true;
|
|
1815
2031
|
// Load the selected template
|
|
1816
2032
|
await this.loadTemplate();
|
|
1817
2033
|
// Trigger change detection to update UI
|
|
@@ -1820,7 +2036,7 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1820
2036
|
}
|
|
1821
2037
|
else if (result && result.createNew) {
|
|
1822
2038
|
// User wants to create a new template
|
|
1823
|
-
await this.
|
|
2039
|
+
await this.CreateNewTemplate();
|
|
1824
2040
|
}
|
|
1825
2041
|
},
|
|
1826
2042
|
error: (error) => {
|
|
@@ -1834,20 +2050,28 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1834
2050
|
MJNotificationService.Instance.CreateSimpleNotification('Error linking template. Please try again.', 'error', 3000);
|
|
1835
2051
|
}
|
|
1836
2052
|
}
|
|
2053
|
+
/** @deprecated Use {@link LinkExistingTemplate}. */
|
|
2054
|
+
async linkExistingTemplate() {
|
|
2055
|
+
return this.LinkExistingTemplate();
|
|
2056
|
+
}
|
|
1837
2057
|
/**
|
|
1838
2058
|
* Opens the current template in a new window
|
|
1839
2059
|
*/
|
|
1840
|
-
|
|
1841
|
-
if (!this.
|
|
2060
|
+
OpenTemplateInNewWindow() {
|
|
2061
|
+
if (!this.Template?.ID)
|
|
1842
2062
|
return;
|
|
1843
2063
|
// TODO: Get the proper URL for template editing
|
|
1844
|
-
const templateUrl = `/templates/${this.
|
|
2064
|
+
const templateUrl = `/templates/${this.Template.ID}`;
|
|
1845
2065
|
window.open(templateUrl, '_blank');
|
|
1846
2066
|
}
|
|
2067
|
+
/** @deprecated Use {@link OpenTemplateInNewWindow}. */
|
|
2068
|
+
openTemplateInNewWindow() {
|
|
2069
|
+
return this.OpenTemplateInNewWindow();
|
|
2070
|
+
}
|
|
1847
2071
|
/**
|
|
1848
2072
|
* Creates a new template for this AI prompt (deferred until save)
|
|
1849
2073
|
*/
|
|
1850
|
-
async
|
|
2074
|
+
async CreateNewTemplate() {
|
|
1851
2075
|
try {
|
|
1852
2076
|
// First, clean up any pending changes related to the old template
|
|
1853
2077
|
this.cleanupOldTemplateRecords();
|
|
@@ -1864,14 +2088,14 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1864
2088
|
});
|
|
1865
2089
|
// Update the AI prompt to reference the new template
|
|
1866
2090
|
this.record.TemplateID = newTemplate.ID;
|
|
1867
|
-
this.
|
|
2091
|
+
this.HasUnsavedChanges = true;
|
|
1868
2092
|
// Set the template for UI purposes
|
|
1869
|
-
this.
|
|
2093
|
+
this.Template = newTemplate;
|
|
1870
2094
|
// Clear existing template content and params since we have a new template
|
|
1871
|
-
this.
|
|
1872
|
-
this.
|
|
1873
|
-
this.
|
|
1874
|
-
this.
|
|
2095
|
+
this.TemplateContent = null;
|
|
2096
|
+
this.TemplateParams = [];
|
|
2097
|
+
this.IsLoadingTemplate = false;
|
|
2098
|
+
this.TemplateNotFoundInDatabase = false;
|
|
1875
2099
|
// Force UI update in next microtask to ensure template editor refreshes
|
|
1876
2100
|
Promise.resolve().then(() => {
|
|
1877
2101
|
this.cdr.detectChanges();
|
|
@@ -1884,6 +2108,10 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1884
2108
|
MJNotificationService.Instance.CreateSimpleNotification(`Error creating new template: ${errorMessage}`, 'error', 6000);
|
|
1885
2109
|
}
|
|
1886
2110
|
}
|
|
2111
|
+
/** @deprecated Use {@link CreateNewTemplate}. */
|
|
2112
|
+
async createNewTemplate() {
|
|
2113
|
+
return this.CreateNewTemplate();
|
|
2114
|
+
}
|
|
1887
2115
|
/**
|
|
1888
2116
|
* Cleans up any pending records related to the old template when changing templates
|
|
1889
2117
|
*/
|
|
@@ -1903,56 +2131,56 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1903
2131
|
* Loads template content for the current template
|
|
1904
2132
|
*/
|
|
1905
2133
|
async loadTemplateContent() {
|
|
1906
|
-
if (!this.
|
|
1907
|
-
this.
|
|
2134
|
+
if (!this.Template?.ID) {
|
|
2135
|
+
this.TemplateContent = null;
|
|
1908
2136
|
return;
|
|
1909
2137
|
}
|
|
1910
2138
|
try {
|
|
1911
2139
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
1912
2140
|
const results = await rv.RunView({
|
|
1913
2141
|
EntityName: 'MJ: Template Contents',
|
|
1914
|
-
ExtraFilter: `TemplateID = '${this.
|
|
2142
|
+
ExtraFilter: `TemplateID = '${this.Template.ID}'`,
|
|
1915
2143
|
OrderBy: 'Priority ASC',
|
|
1916
2144
|
ResultType: 'entity_object'
|
|
1917
2145
|
});
|
|
1918
2146
|
// Get the first content (highest priority)
|
|
1919
|
-
this.
|
|
2147
|
+
this.TemplateContent = results.Results?.[0] || null;
|
|
1920
2148
|
}
|
|
1921
2149
|
catch (error) {
|
|
1922
2150
|
console.error('Error loading template content:', error);
|
|
1923
|
-
this.
|
|
2151
|
+
this.TemplateContent = null;
|
|
1924
2152
|
}
|
|
1925
2153
|
}
|
|
1926
2154
|
/**
|
|
1927
2155
|
* Loads template parameters for the current template
|
|
1928
2156
|
*/
|
|
1929
2157
|
async loadTemplateParams() {
|
|
1930
|
-
if (!this.
|
|
1931
|
-
this.
|
|
2158
|
+
if (!this.Template?.ID) {
|
|
2159
|
+
this.TemplateParams = [];
|
|
1932
2160
|
return;
|
|
1933
2161
|
}
|
|
1934
|
-
this.
|
|
2162
|
+
this.IsLoadingTemplateParams = true;
|
|
1935
2163
|
try {
|
|
1936
2164
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
1937
2165
|
const results = await rv.RunView({
|
|
1938
2166
|
EntityName: 'MJ: Template Params',
|
|
1939
|
-
ExtraFilter: `TemplateID = '${this.
|
|
2167
|
+
ExtraFilter: `TemplateID = '${this.Template.ID}'`,
|
|
1940
2168
|
OrderBy: 'Name ASC'
|
|
1941
2169
|
});
|
|
1942
|
-
this.
|
|
2170
|
+
this.TemplateParams = results.Results || [];
|
|
1943
2171
|
}
|
|
1944
2172
|
catch (error) {
|
|
1945
2173
|
console.error('Error loading template params:', error);
|
|
1946
|
-
this.
|
|
2174
|
+
this.TemplateParams = [];
|
|
1947
2175
|
}
|
|
1948
2176
|
finally {
|
|
1949
|
-
this.
|
|
2177
|
+
this.IsLoadingTemplateParams = false;
|
|
1950
2178
|
}
|
|
1951
2179
|
}
|
|
1952
2180
|
/**
|
|
1953
2181
|
* Opens the AI prompt execution dialog
|
|
1954
2182
|
*/
|
|
1955
|
-
|
|
2183
|
+
ExecuteAIPrompt() {
|
|
1956
2184
|
if (!this.record?.ID) {
|
|
1957
2185
|
MJNotificationService.Instance.CreateSimpleNotification('Please save the AI prompt before executing', 'warning', 4000);
|
|
1958
2186
|
return;
|
|
@@ -1962,12 +2190,16 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1962
2190
|
return;
|
|
1963
2191
|
}
|
|
1964
2192
|
// Use test harness instead
|
|
1965
|
-
this.
|
|
2193
|
+
this.OpenTestHarness();
|
|
2194
|
+
}
|
|
2195
|
+
/** @deprecated Use {@link ExecuteAIPrompt}. */
|
|
2196
|
+
executeAIPrompt() {
|
|
2197
|
+
return this.ExecuteAIPrompt();
|
|
1966
2198
|
}
|
|
1967
2199
|
/**
|
|
1968
2200
|
* Opens the test harness
|
|
1969
2201
|
*/
|
|
1970
|
-
|
|
2202
|
+
OpenTestHarness() {
|
|
1971
2203
|
if (!this.record?.ID) {
|
|
1972
2204
|
MJNotificationService.Instance.CreateSimpleNotification('Please save the AI prompt before testing', 'warning', 4000);
|
|
1973
2205
|
return;
|
|
@@ -1978,7 +2210,7 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1978
2210
|
next: (result) => {
|
|
1979
2211
|
if (result.success) {
|
|
1980
2212
|
// Reload execution history
|
|
1981
|
-
this.
|
|
2213
|
+
this.LoadExecutionHistory();
|
|
1982
2214
|
}
|
|
1983
2215
|
},
|
|
1984
2216
|
error: (error) => {
|
|
@@ -1987,28 +2219,40 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
1987
2219
|
}
|
|
1988
2220
|
});
|
|
1989
2221
|
}
|
|
2222
|
+
/** @deprecated Use {@link OpenTestHarness}. */
|
|
2223
|
+
openTestHarness() {
|
|
2224
|
+
return this.OpenTestHarness();
|
|
2225
|
+
}
|
|
1990
2226
|
/**
|
|
1991
2227
|
* Handles when test harness is closed
|
|
1992
2228
|
*/
|
|
2229
|
+
OnTestHarnessVisibilityChanged(isVisible) {
|
|
2230
|
+
this.ShowTestHarness = isVisible;
|
|
2231
|
+
}
|
|
2232
|
+
/** @deprecated Use {@link OnTestHarnessVisibilityChanged}. */
|
|
1993
2233
|
onTestHarnessVisibilityChanged(isVisible) {
|
|
1994
|
-
this.
|
|
2234
|
+
return this.OnTestHarnessVisibilityChanged(isVisible);
|
|
1995
2235
|
}
|
|
1996
2236
|
/**
|
|
1997
2237
|
* Handles template content changes from the editor
|
|
1998
2238
|
*/
|
|
1999
|
-
|
|
2239
|
+
OnTemplateContentChange(content) {
|
|
2000
2240
|
// Handle template content changes if needed
|
|
2001
2241
|
console.log('Template content changed:', content);
|
|
2002
2242
|
// Mark as having unsaved changes
|
|
2003
|
-
this.
|
|
2243
|
+
this.HasUnsavedChanges = true;
|
|
2004
2244
|
// If we have content changes, we need to ensure they're added to pending records
|
|
2005
2245
|
// This is typically handled by the template editor component itself
|
|
2006
2246
|
}
|
|
2247
|
+
/** @deprecated Use {@link OnTemplateContentChange}. */
|
|
2248
|
+
onTemplateContentChange(content) {
|
|
2249
|
+
return this.OnTemplateContentChange(content);
|
|
2250
|
+
}
|
|
2007
2251
|
/**
|
|
2008
2252
|
* Handles template content record deletion
|
|
2009
2253
|
* This method should be called by the template editor to properly manage deletions
|
|
2010
2254
|
*/
|
|
2011
|
-
|
|
2255
|
+
HandleTemplateContentDelete(templateContent) {
|
|
2012
2256
|
if (templateContent.IsSaved) {
|
|
2013
2257
|
// If it's saved, add to pending deletions
|
|
2014
2258
|
this.PendingRecords.push({
|
|
@@ -2029,13 +2273,17 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2029
2273
|
}
|
|
2030
2274
|
}
|
|
2031
2275
|
}
|
|
2032
|
-
this.
|
|
2276
|
+
this.HasUnsavedChanges = true;
|
|
2277
|
+
}
|
|
2278
|
+
/** @deprecated Use {@link HandleTemplateContentDelete}. */
|
|
2279
|
+
handleTemplateContentDelete(templateContent) {
|
|
2280
|
+
return this.HandleTemplateContentDelete(templateContent);
|
|
2033
2281
|
}
|
|
2034
2282
|
/**
|
|
2035
2283
|
* Handles template content record creation/modification
|
|
2036
2284
|
* This method should be called by the template editor to properly manage saves
|
|
2037
2285
|
*/
|
|
2038
|
-
|
|
2286
|
+
HandleTemplateContentSave(templateContent) {
|
|
2039
2287
|
if (templateContent.Dirty || !templateContent.IsSaved) {
|
|
2040
2288
|
// Add to pending saves
|
|
2041
2289
|
this.PendingRecords.push({
|
|
@@ -2043,7 +2291,11 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2043
2291
|
action: 'save'
|
|
2044
2292
|
});
|
|
2045
2293
|
}
|
|
2046
|
-
this.
|
|
2294
|
+
this.HasUnsavedChanges = true;
|
|
2295
|
+
}
|
|
2296
|
+
/** @deprecated Use {@link HandleTemplateContentSave}. */
|
|
2297
|
+
handleTemplateContentSave(templateContent) {
|
|
2298
|
+
return this.HandleTemplateContentSave(templateContent);
|
|
2047
2299
|
}
|
|
2048
2300
|
/**
|
|
2049
2301
|
* Adds template content changes to pending records
|
|
@@ -2054,9 +2306,9 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2054
2306
|
// For now, we'll rely on the template editor to manage its own pending records
|
|
2055
2307
|
// and communicate them through the MJ event system
|
|
2056
2308
|
// If the template editor has a method to get pending changes, we would call it here
|
|
2057
|
-
if (this.
|
|
2309
|
+
if (this.TemplateEditor && typeof this.TemplateEditor.getPendingChanges === 'function') {
|
|
2058
2310
|
try {
|
|
2059
|
-
const pendingChanges = this.
|
|
2311
|
+
const pendingChanges = this.TemplateEditor.getPendingChanges();
|
|
2060
2312
|
if (pendingChanges && pendingChanges.length > 0) {
|
|
2061
2313
|
this.PendingRecords.push(...pendingChanges);
|
|
2062
2314
|
}
|
|
@@ -2069,15 +2321,19 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2069
2321
|
/**
|
|
2070
2322
|
* Handles template run requests from the editor
|
|
2071
2323
|
*/
|
|
2072
|
-
|
|
2324
|
+
OnTemplateRun(template) {
|
|
2073
2325
|
console.log('Template run requested:', template);
|
|
2074
2326
|
// Could open the template parameter dialog here if needed
|
|
2075
2327
|
MJNotificationService.Instance.CreateSimpleNotification('Template run functionality coming soon', 'info', 3000);
|
|
2076
2328
|
}
|
|
2329
|
+
/** @deprecated Use {@link OnTemplateRun}. */
|
|
2330
|
+
onTemplateRun(template) {
|
|
2331
|
+
return this.OnTemplateRun(template);
|
|
2332
|
+
}
|
|
2077
2333
|
/**
|
|
2078
2334
|
* Gets the display text for parallelization mode
|
|
2079
2335
|
*/
|
|
2080
|
-
|
|
2336
|
+
GetParallelizationModeDisplay() {
|
|
2081
2337
|
switch (this.record?.ParallelizationMode) {
|
|
2082
2338
|
case 'None': return 'None';
|
|
2083
2339
|
case 'StaticCount': return `Static count (${this.record.ParallelCount || 1})`;
|
|
@@ -2086,10 +2342,14 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2086
2342
|
default: return 'Unknown';
|
|
2087
2343
|
}
|
|
2088
2344
|
}
|
|
2345
|
+
/** @deprecated Use {@link GetParallelizationModeDisplay}. */
|
|
2346
|
+
getParallelizationModeDisplay() {
|
|
2347
|
+
return this.GetParallelizationModeDisplay();
|
|
2348
|
+
}
|
|
2089
2349
|
/**
|
|
2090
2350
|
* Gets the display text for output type
|
|
2091
2351
|
*/
|
|
2092
|
-
|
|
2352
|
+
GetOutputTypeDisplay() {
|
|
2093
2353
|
const type = this.record?.OutputType || 'string';
|
|
2094
2354
|
const validationBehavior = this.record?.ValidationBehavior || 'Warn';
|
|
2095
2355
|
if (validationBehavior === 'None') {
|
|
@@ -2099,47 +2359,71 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2099
2359
|
return `${type} (${validationBehavior})`;
|
|
2100
2360
|
}
|
|
2101
2361
|
}
|
|
2362
|
+
/** @deprecated Use {@link GetOutputTypeDisplay}. */
|
|
2363
|
+
getOutputTypeDisplay() {
|
|
2364
|
+
return this.GetOutputTypeDisplay();
|
|
2365
|
+
}
|
|
2102
2366
|
/**
|
|
2103
2367
|
* Gets the color for validation behavior display
|
|
2104
2368
|
*/
|
|
2105
|
-
|
|
2369
|
+
GetValidationColor() {
|
|
2106
2370
|
switch (this.record?.ValidationBehavior) {
|
|
2107
2371
|
case 'Strict': return '#dc3545'; // red
|
|
2108
2372
|
case 'Warn': return '#ffc107'; // yellow
|
|
2109
2373
|
default: return '#6c757d'; // default gray
|
|
2110
2374
|
}
|
|
2111
2375
|
}
|
|
2376
|
+
/** @deprecated Use {@link GetValidationColor}. */
|
|
2377
|
+
getValidationColor() {
|
|
2378
|
+
return this.GetValidationColor();
|
|
2379
|
+
}
|
|
2112
2380
|
/**
|
|
2113
2381
|
* Checks if ParallelCount field should be visible
|
|
2114
2382
|
*/
|
|
2115
|
-
get
|
|
2383
|
+
get ShowParallelCount() {
|
|
2116
2384
|
return this.record?.ParallelizationMode === 'StaticCount';
|
|
2117
2385
|
}
|
|
2386
|
+
/** @deprecated Use {@link ShowParallelCount}. */
|
|
2387
|
+
get showParallelCount() {
|
|
2388
|
+
return this.ShowParallelCount;
|
|
2389
|
+
}
|
|
2118
2390
|
/**
|
|
2119
2391
|
* Checks if ParallelConfigParam field should be visible
|
|
2120
2392
|
*/
|
|
2121
|
-
get
|
|
2393
|
+
get ShowParallelConfigParam() {
|
|
2122
2394
|
return this.record?.ParallelizationMode === 'ConfigParam';
|
|
2123
2395
|
}
|
|
2396
|
+
/** @deprecated Use {@link ShowParallelConfigParam}. */
|
|
2397
|
+
get showParallelConfigParam() {
|
|
2398
|
+
return this.ShowParallelConfigParam;
|
|
2399
|
+
}
|
|
2124
2400
|
/**
|
|
2125
2401
|
* Checks if OutputExample field should be visible
|
|
2126
2402
|
*/
|
|
2127
|
-
get
|
|
2403
|
+
get ShowOutputExample() {
|
|
2128
2404
|
return this.record?.OutputType === 'object';
|
|
2129
2405
|
}
|
|
2406
|
+
/** @deprecated Use {@link ShowOutputExample}. */
|
|
2407
|
+
get showOutputExample() {
|
|
2408
|
+
return this.ShowOutputExample;
|
|
2409
|
+
}
|
|
2130
2410
|
/**
|
|
2131
2411
|
* Checks if the AI prompt can be executed
|
|
2132
2412
|
*/
|
|
2133
|
-
get
|
|
2413
|
+
get CanExecute() {
|
|
2134
2414
|
return !!(this.record?.ID &&
|
|
2135
2415
|
this.record.Status === 'Active' &&
|
|
2136
2416
|
this.record.TemplateID &&
|
|
2137
|
-
this.
|
|
2417
|
+
this.Template);
|
|
2418
|
+
}
|
|
2419
|
+
/** @deprecated Use {@link CanExecute}. */
|
|
2420
|
+
get canExecute() {
|
|
2421
|
+
return this.CanExecute;
|
|
2138
2422
|
}
|
|
2139
2423
|
/**
|
|
2140
2424
|
* Gets status badge color
|
|
2141
2425
|
*/
|
|
2142
|
-
|
|
2426
|
+
GetStatusBadgeColor() {
|
|
2143
2427
|
switch (this.record?.Status) {
|
|
2144
2428
|
case 'Active': return '#28a745';
|
|
2145
2429
|
case 'Pending': return '#ffc107';
|
|
@@ -2147,84 +2431,104 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2147
2431
|
default: return '#6c757d';
|
|
2148
2432
|
}
|
|
2149
2433
|
}
|
|
2434
|
+
/** @deprecated Use {@link GetStatusBadgeColor}. */
|
|
2435
|
+
getStatusBadgeColor() {
|
|
2436
|
+
return this.GetStatusBadgeColor();
|
|
2437
|
+
}
|
|
2150
2438
|
/**
|
|
2151
2439
|
* Loads available AI models for selection
|
|
2152
2440
|
*/
|
|
2153
|
-
async
|
|
2441
|
+
async LoadAvailableModels() {
|
|
2154
2442
|
try {
|
|
2155
2443
|
const engine = AIEngineBase.Instance;
|
|
2156
2444
|
await engine.Config(false);
|
|
2157
2445
|
const models = engine.Models;
|
|
2158
2446
|
models.sort((a, b) => a.Name.localeCompare(b.Name));
|
|
2159
|
-
this.
|
|
2447
|
+
this.AvailableModels = models;
|
|
2160
2448
|
}
|
|
2161
2449
|
catch (error) {
|
|
2162
2450
|
console.error('Error loading available models:', error);
|
|
2163
2451
|
}
|
|
2164
2452
|
}
|
|
2453
|
+
/** @deprecated Use {@link LoadAvailableModels}. */
|
|
2454
|
+
async loadAvailableModels() {
|
|
2455
|
+
return this.LoadAvailableModels();
|
|
2456
|
+
}
|
|
2165
2457
|
/**
|
|
2166
2458
|
* Loads available AI vendors for selection
|
|
2167
2459
|
*/
|
|
2168
|
-
async
|
|
2460
|
+
async LoadAvailableVendors() {
|
|
2169
2461
|
try {
|
|
2170
2462
|
const engine = AIEngineBase.Instance;
|
|
2171
2463
|
await engine.Config(false);
|
|
2172
2464
|
const vendors = engine.Vendors;
|
|
2173
2465
|
vendors.sort((a, b) => a.Name.localeCompare(b.Name));
|
|
2174
|
-
this.
|
|
2466
|
+
this.AvailableVendors = vendors;
|
|
2175
2467
|
}
|
|
2176
2468
|
catch (error) {
|
|
2177
2469
|
console.error('Error loading available vendors:', error);
|
|
2178
2470
|
}
|
|
2179
2471
|
}
|
|
2472
|
+
/** @deprecated Use {@link LoadAvailableVendors}. */
|
|
2473
|
+
async loadAvailableVendors() {
|
|
2474
|
+
return this.LoadAvailableVendors();
|
|
2475
|
+
}
|
|
2180
2476
|
/**
|
|
2181
2477
|
* Loads available AI prompt types for selection
|
|
2182
2478
|
*/
|
|
2183
|
-
async
|
|
2184
|
-
this.
|
|
2479
|
+
async LoadAvailablePromptTypes() {
|
|
2480
|
+
this.IsLoadingPromptTypes = true;
|
|
2185
2481
|
try {
|
|
2186
2482
|
const engine = AIEngineBase.Instance;
|
|
2187
2483
|
await engine.Config(false);
|
|
2188
2484
|
const promptTypes = engine.PromptTypes;
|
|
2189
2485
|
promptTypes.sort((a, b) => a.Name.localeCompare(b.Name));
|
|
2190
|
-
this.
|
|
2486
|
+
this.AvailablePromptTypes = promptTypes;
|
|
2191
2487
|
}
|
|
2192
2488
|
catch (error) {
|
|
2193
2489
|
console.error('Error loading available prompt types:', error);
|
|
2194
2490
|
}
|
|
2195
2491
|
finally {
|
|
2196
|
-
this.
|
|
2492
|
+
this.IsLoadingPromptTypes = false;
|
|
2197
2493
|
}
|
|
2198
2494
|
}
|
|
2495
|
+
/** @deprecated Use {@link LoadAvailablePromptTypes}. */
|
|
2496
|
+
async loadAvailablePromptTypes() {
|
|
2497
|
+
return this.LoadAvailablePromptTypes();
|
|
2498
|
+
}
|
|
2199
2499
|
/**
|
|
2200
2500
|
* Loads available AI configurations for selection
|
|
2201
2501
|
*/
|
|
2202
|
-
async
|
|
2203
|
-
this.
|
|
2502
|
+
async LoadAvailableConfigurations() {
|
|
2503
|
+
this.IsLoadingConfigurations = true;
|
|
2204
2504
|
try {
|
|
2205
2505
|
const engine = AIEngineBase.Instance;
|
|
2206
2506
|
await engine.Config(false);
|
|
2207
2507
|
const configurations = engine.Configurations;
|
|
2208
2508
|
configurations.sort((a, b) => a.Name.localeCompare(b.Name));
|
|
2209
|
-
this.
|
|
2509
|
+
this.AvailableConfigurations = configurations;
|
|
2210
2510
|
}
|
|
2211
2511
|
catch (error) {
|
|
2212
2512
|
console.error('Error loading available configurations:', error);
|
|
2213
2513
|
}
|
|
2214
2514
|
finally {
|
|
2215
|
-
this.
|
|
2515
|
+
this.IsLoadingConfigurations = false;
|
|
2216
2516
|
}
|
|
2217
2517
|
}
|
|
2518
|
+
/** @deprecated Use {@link LoadAvailableConfigurations}. */
|
|
2519
|
+
async loadAvailableConfigurations() {
|
|
2520
|
+
return this.LoadAvailableConfigurations();
|
|
2521
|
+
}
|
|
2218
2522
|
/**
|
|
2219
2523
|
* Loads vendors available for a specific model
|
|
2220
2524
|
*/
|
|
2221
|
-
async
|
|
2525
|
+
async LoadVendorsForModel(modelId) {
|
|
2222
2526
|
if (!modelId) {
|
|
2223
2527
|
return { vendors: [], modelVendors: [] };
|
|
2224
2528
|
}
|
|
2225
2529
|
// Check cache first
|
|
2226
|
-
if (this.
|
|
2227
|
-
return this.
|
|
2530
|
+
if (this.ModelVendorsMap.has(modelId)) {
|
|
2531
|
+
return this.ModelVendorsMap.get(modelId);
|
|
2228
2532
|
}
|
|
2229
2533
|
try {
|
|
2230
2534
|
// Load model vendors for this model, filtering by TypeID for inference providers only
|
|
@@ -2234,7 +2538,7 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2234
2538
|
// filter vendors to just the vendors in the modelVendors array in VendorID
|
|
2235
2539
|
const vendors = engine.Vendors.filter(v => modelVendors.some(mv => UUIDsEqual(mv.VendorID, v.ID)));
|
|
2236
2540
|
const result = { vendors, modelVendors };
|
|
2237
|
-
this.
|
|
2541
|
+
this.ModelVendorsMap.set(modelId, result);
|
|
2238
2542
|
return result;
|
|
2239
2543
|
}
|
|
2240
2544
|
catch (error) {
|
|
@@ -2242,28 +2546,40 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2242
2546
|
return { vendors: [], modelVendors: [] };
|
|
2243
2547
|
}
|
|
2244
2548
|
}
|
|
2549
|
+
/** @deprecated Use {@link LoadVendorsForModel}. */
|
|
2550
|
+
async loadVendorsForModel(modelId) {
|
|
2551
|
+
return this.LoadVendorsForModel(modelId);
|
|
2552
|
+
}
|
|
2245
2553
|
/**
|
|
2246
2554
|
* Gets vendors for a specific model from cache or loads them
|
|
2247
2555
|
*/
|
|
2248
|
-
async
|
|
2249
|
-
const result = await this.
|
|
2556
|
+
async GetVendorsForModel(modelId) {
|
|
2557
|
+
const result = await this.LoadVendorsForModel(modelId);
|
|
2250
2558
|
return result.vendors;
|
|
2251
2559
|
}
|
|
2560
|
+
/** @deprecated Use {@link GetVendorsForModel}. */
|
|
2561
|
+
async getVendorsForModel(modelId) {
|
|
2562
|
+
return this.GetVendorsForModel(modelId);
|
|
2563
|
+
}
|
|
2252
2564
|
/**
|
|
2253
2565
|
* Gets the status for a model-vendor combination
|
|
2254
2566
|
*/
|
|
2255
|
-
|
|
2256
|
-
const modelVendorData = this.
|
|
2567
|
+
GetModelVendorStatus(modelId, vendorId) {
|
|
2568
|
+
const modelVendorData = this.ModelVendorsMap.get(modelId);
|
|
2257
2569
|
if (!modelVendorData)
|
|
2258
2570
|
return 'Unknown';
|
|
2259
2571
|
const modelVendor = modelVendorData.modelVendors.find(mv => UUIDsEqual(mv.VendorID, vendorId));
|
|
2260
2572
|
return modelVendor?.Status || 'Unknown';
|
|
2261
2573
|
}
|
|
2574
|
+
/** @deprecated Use {@link GetModelVendorStatus}. */
|
|
2575
|
+
getModelVendorStatus(modelId, vendorId) {
|
|
2576
|
+
return this.GetModelVendorStatus(modelId, vendorId);
|
|
2577
|
+
}
|
|
2262
2578
|
/**
|
|
2263
2579
|
* Gets the color for vendor status display
|
|
2264
2580
|
*/
|
|
2265
|
-
|
|
2266
|
-
const status = this.
|
|
2581
|
+
GetVendorStatusColor(modelId, vendorId) {
|
|
2582
|
+
const status = this.GetModelVendorStatus(modelId, vendorId);
|
|
2267
2583
|
switch (status) {
|
|
2268
2584
|
case 'Active': return '#28a745'; // green
|
|
2269
2585
|
case 'Inactive': return '#dc3545'; // red
|
|
@@ -2271,19 +2587,23 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2271
2587
|
default: return '#6c757d'; // gray
|
|
2272
2588
|
}
|
|
2273
2589
|
}
|
|
2590
|
+
/** @deprecated Use {@link GetVendorStatusColor}. */
|
|
2591
|
+
getVendorStatusColor(modelId, vendorId) {
|
|
2592
|
+
return this.GetVendorStatusColor(modelId, vendorId);
|
|
2593
|
+
}
|
|
2274
2594
|
/**
|
|
2275
2595
|
* Handles model selection change and loads vendors for that model
|
|
2276
2596
|
*/
|
|
2277
|
-
async
|
|
2278
|
-
const promptModel = this.
|
|
2597
|
+
async OnModelChange(modelId, promptModelIndex) {
|
|
2598
|
+
const promptModel = this.PromptModels[promptModelIndex];
|
|
2279
2599
|
if (!promptModel)
|
|
2280
2600
|
return;
|
|
2281
2601
|
// Clear the vendor selection when model changes
|
|
2282
2602
|
promptModel.VendorID = null;
|
|
2283
|
-
this.
|
|
2603
|
+
this.HasUnsavedChanges = true;
|
|
2284
2604
|
// Load vendors for the new model
|
|
2285
2605
|
if (modelId) {
|
|
2286
|
-
const vendorData = await this.
|
|
2606
|
+
const vendorData = await this.LoadVendorsForModel(modelId);
|
|
2287
2607
|
// Auto-select first vendor if available
|
|
2288
2608
|
if (vendorData.vendors.length > 0) {
|
|
2289
2609
|
promptModel.VendorID = vendorData.vendors[0].ID;
|
|
@@ -2292,68 +2612,88 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2292
2612
|
// Trigger change detection
|
|
2293
2613
|
this.cdr.detectChanges();
|
|
2294
2614
|
}
|
|
2615
|
+
/** @deprecated Use {@link OnModelChange}. */
|
|
2616
|
+
async onModelChange(modelId, promptModelIndex) {
|
|
2617
|
+
return this.OnModelChange(modelId, promptModelIndex);
|
|
2618
|
+
}
|
|
2295
2619
|
/**
|
|
2296
2620
|
* Handles configuration change for a prompt model
|
|
2297
2621
|
*/
|
|
2298
|
-
|
|
2299
|
-
const promptModel = this.
|
|
2622
|
+
OnConfigurationChange(configurationId, promptModelIndex) {
|
|
2623
|
+
const promptModel = this.PromptModels[promptModelIndex];
|
|
2300
2624
|
if (!promptModel)
|
|
2301
2625
|
return;
|
|
2302
2626
|
promptModel.ConfigurationID = configurationId;
|
|
2303
|
-
this.
|
|
2627
|
+
this.HasUnsavedChanges = true;
|
|
2304
2628
|
// Trigger change detection
|
|
2305
2629
|
this.cdr.detectChanges();
|
|
2306
2630
|
}
|
|
2631
|
+
/** @deprecated Use {@link OnConfigurationChange}. */
|
|
2632
|
+
onConfigurationChange(configurationId, promptModelIndex) {
|
|
2633
|
+
return this.OnConfigurationChange(configurationId, promptModelIndex);
|
|
2634
|
+
}
|
|
2307
2635
|
/**
|
|
2308
2636
|
* Gets vendors for a specific model
|
|
2309
2637
|
*/
|
|
2310
|
-
|
|
2311
|
-
const modelVendorData = this.
|
|
2638
|
+
GetVendorsForModelSync(modelId) {
|
|
2639
|
+
const modelVendorData = this.ModelVendorsMap.get(modelId);
|
|
2312
2640
|
return modelVendorData?.vendors || [];
|
|
2313
2641
|
}
|
|
2642
|
+
/** @deprecated Use {@link GetVendorsForModelSync}. */
|
|
2643
|
+
getVendorsForModelSync(modelId) {
|
|
2644
|
+
return this.GetVendorsForModelSync(modelId);
|
|
2645
|
+
}
|
|
2314
2646
|
/**
|
|
2315
2647
|
* Checks if vendor dropdown should be shown (more than one vendor)
|
|
2316
2648
|
*/
|
|
2317
|
-
|
|
2649
|
+
ShouldShowVendorDropdown(modelId) {
|
|
2318
2650
|
if (!modelId)
|
|
2319
2651
|
return false;
|
|
2320
|
-
const vendors = this.
|
|
2652
|
+
const vendors = this.GetVendorsForModelSync(modelId);
|
|
2321
2653
|
return vendors.length > 1;
|
|
2322
2654
|
}
|
|
2655
|
+
/** @deprecated Use {@link ShouldShowVendorDropdown}. */
|
|
2656
|
+
shouldShowVendorDropdown(modelId) {
|
|
2657
|
+
return this.ShouldShowVendorDropdown(modelId);
|
|
2658
|
+
}
|
|
2323
2659
|
/**
|
|
2324
2660
|
* Loads prompt models for this AI prompt
|
|
2325
2661
|
*/
|
|
2326
|
-
async
|
|
2662
|
+
async LoadPromptModels() {
|
|
2327
2663
|
if (!this.record?.ID) {
|
|
2328
|
-
this.
|
|
2664
|
+
this.PromptModels = [];
|
|
2329
2665
|
return;
|
|
2330
2666
|
}
|
|
2331
|
-
this.
|
|
2667
|
+
this.IsLoadingModels = true;
|
|
2332
2668
|
try {
|
|
2333
2669
|
const engine = AIEngineBase.Instance;
|
|
2334
2670
|
await engine.Config(false);
|
|
2335
|
-
this.
|
|
2336
|
-
this.
|
|
2671
|
+
this.PromptModels = engine.PromptModels.filter(pm => UUIDsEqual(pm.PromptID, this.record.ID));
|
|
2672
|
+
this.PromptModels.sort((a, b) => {
|
|
2337
2673
|
// first sort on priority (descending), then by created date (ascending)
|
|
2338
2674
|
return b.Priority - a.Priority || new Date(a.__mj_CreatedAt).getTime() - new Date(b.__mj_CreatedAt).getTime();
|
|
2339
2675
|
});
|
|
2340
2676
|
// Load vendors for existing models
|
|
2341
|
-
const modelIds = this.
|
|
2677
|
+
const modelIds = this.PromptModels
|
|
2342
2678
|
.map(pm => pm.ModelID)
|
|
2343
2679
|
.filter(id => id); // Filter out null/undefined
|
|
2344
|
-
await Promise.all(modelIds.map(modelId => this.
|
|
2680
|
+
await Promise.all(modelIds.map(modelId => this.LoadVendorsForModel(modelId)));
|
|
2345
2681
|
}
|
|
2346
2682
|
catch (error) {
|
|
2347
2683
|
console.error('Error loading prompt models:', error);
|
|
2348
2684
|
}
|
|
2349
2685
|
finally {
|
|
2350
|
-
this.
|
|
2686
|
+
this.IsLoadingModels = false;
|
|
2351
2687
|
}
|
|
2352
2688
|
}
|
|
2689
|
+
/** @deprecated Use {@link LoadPromptModels}. */
|
|
2690
|
+
async loadPromptModels() {
|
|
2691
|
+
return this.LoadPromptModels();
|
|
2692
|
+
}
|
|
2353
2693
|
/**
|
|
2354
2694
|
* Adds a new model to the prompt (deferred until save)
|
|
2355
2695
|
*/
|
|
2356
|
-
async
|
|
2696
|
+
async AddNewModel() {
|
|
2357
2697
|
if (!this.record?.ID)
|
|
2358
2698
|
return;
|
|
2359
2699
|
try {
|
|
@@ -2366,8 +2706,8 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2366
2706
|
newModel._tempId = `temp_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
2367
2707
|
}
|
|
2368
2708
|
// ModelID will be set by user
|
|
2369
|
-
this.
|
|
2370
|
-
this.
|
|
2709
|
+
this.PromptModels.push(newModel);
|
|
2710
|
+
this.HasUnsavedChanges = true;
|
|
2371
2711
|
// Update priorities after adding
|
|
2372
2712
|
this.updateModelPriorities();
|
|
2373
2713
|
// Trigger change detection
|
|
@@ -2379,13 +2719,17 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2379
2719
|
MJNotificationService.Instance.CreateSimpleNotification('Error creating new model', 'error', 5000);
|
|
2380
2720
|
}
|
|
2381
2721
|
}
|
|
2722
|
+
/** @deprecated Use {@link AddNewModel}. */
|
|
2723
|
+
async addNewModel() {
|
|
2724
|
+
return this.AddNewModel();
|
|
2725
|
+
}
|
|
2382
2726
|
/**
|
|
2383
2727
|
* Removes a model from the prompt (deferred until save)
|
|
2384
2728
|
*/
|
|
2385
|
-
async
|
|
2386
|
-
if (index < 0 || index >= this.
|
|
2729
|
+
async RemovePromptModel(index) {
|
|
2730
|
+
if (index < 0 || index >= this.PromptModels.length)
|
|
2387
2731
|
return;
|
|
2388
|
-
const model = this.
|
|
2732
|
+
const model = this.PromptModels[index];
|
|
2389
2733
|
try {
|
|
2390
2734
|
// If it's a saved model, add it to pending deletions
|
|
2391
2735
|
if (model.IsSaved) {
|
|
@@ -2395,8 +2739,8 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2395
2739
|
});
|
|
2396
2740
|
}
|
|
2397
2741
|
// Remove from local array
|
|
2398
|
-
this.
|
|
2399
|
-
this.
|
|
2742
|
+
this.PromptModels.splice(index, 1);
|
|
2743
|
+
this.HasUnsavedChanges = true;
|
|
2400
2744
|
// Update priorities after removal
|
|
2401
2745
|
this.updateModelPriorities();
|
|
2402
2746
|
// Trigger change detection
|
|
@@ -2408,42 +2752,62 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2408
2752
|
MJNotificationService.Instance.CreateSimpleNotification('Error removing model', 'error', 5000);
|
|
2409
2753
|
}
|
|
2410
2754
|
}
|
|
2755
|
+
/** @deprecated Use {@link RemovePromptModel}. */
|
|
2756
|
+
async removePromptModel(index) {
|
|
2757
|
+
return this.RemovePromptModel(index);
|
|
2758
|
+
}
|
|
2411
2759
|
/**
|
|
2412
2760
|
* Gets the display name for a model ID
|
|
2413
2761
|
*/
|
|
2414
|
-
|
|
2762
|
+
GetModelDisplayName(modelId) {
|
|
2415
2763
|
if (!modelId)
|
|
2416
2764
|
return '';
|
|
2417
|
-
const model = this.
|
|
2765
|
+
const model = this.AvailableModels.find(m => UUIDsEqual(m.ID, modelId));
|
|
2418
2766
|
return model ? model.Name : modelId;
|
|
2419
2767
|
}
|
|
2768
|
+
/** @deprecated Use {@link GetModelDisplayName}. */
|
|
2769
|
+
getModelDisplayName(modelId) {
|
|
2770
|
+
return this.GetModelDisplayName(modelId);
|
|
2771
|
+
}
|
|
2420
2772
|
/**
|
|
2421
2773
|
* Gets the display name for a vendor ID
|
|
2422
2774
|
*/
|
|
2423
|
-
|
|
2775
|
+
GetVendorDisplayName(vendorId) {
|
|
2424
2776
|
if (!vendorId)
|
|
2425
2777
|
return '';
|
|
2426
|
-
const vendor = this.
|
|
2778
|
+
const vendor = this.AvailableVendors.find(v => UUIDsEqual(v.ID, vendorId));
|
|
2427
2779
|
return vendor ? vendor.Name : vendorId;
|
|
2428
2780
|
}
|
|
2781
|
+
/** @deprecated Use {@link GetVendorDisplayName}. */
|
|
2782
|
+
getVendorDisplayName(vendorId) {
|
|
2783
|
+
return this.GetVendorDisplayName(vendorId);
|
|
2784
|
+
}
|
|
2429
2785
|
/**
|
|
2430
2786
|
* Gets the display name for a prompt type ID
|
|
2431
2787
|
*/
|
|
2432
|
-
|
|
2788
|
+
GetPromptTypeDisplayName(typeId) {
|
|
2433
2789
|
if (!typeId)
|
|
2434
2790
|
return '';
|
|
2435
|
-
const type = this.
|
|
2791
|
+
const type = this.AvailablePromptTypes.find(t => UUIDsEqual(t.ID, typeId));
|
|
2436
2792
|
return type ? type.Name : typeId;
|
|
2437
2793
|
}
|
|
2794
|
+
/** @deprecated Use {@link GetPromptTypeDisplayName}. */
|
|
2795
|
+
getPromptTypeDisplayName(typeId) {
|
|
2796
|
+
return this.GetPromptTypeDisplayName(typeId);
|
|
2797
|
+
}
|
|
2438
2798
|
/**
|
|
2439
2799
|
* Gets the display name for a configuration ID
|
|
2440
2800
|
*/
|
|
2441
|
-
|
|
2801
|
+
GetConfigurationDisplayName(configurationId) {
|
|
2442
2802
|
if (!configurationId)
|
|
2443
2803
|
return 'Default';
|
|
2444
|
-
const config = this.
|
|
2804
|
+
const config = this.AvailableConfigurations.find(c => UUIDsEqual(c.ID, configurationId));
|
|
2445
2805
|
return config ? config.Name : configurationId;
|
|
2446
2806
|
}
|
|
2807
|
+
/** @deprecated Use {@link GetConfigurationDisplayName}. */
|
|
2808
|
+
getConfigurationDisplayName(configurationId) {
|
|
2809
|
+
return this.GetConfigurationDisplayName(configurationId);
|
|
2810
|
+
}
|
|
2447
2811
|
/**
|
|
2448
2812
|
* Override PopulatePendingRecords to add AI prompt model changes
|
|
2449
2813
|
*/
|
|
@@ -2485,20 +2849,20 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2485
2849
|
this.cdr.detectChanges();
|
|
2486
2850
|
});
|
|
2487
2851
|
}
|
|
2488
|
-
else if (this.
|
|
2852
|
+
else if (this.TemplateEditor) {
|
|
2489
2853
|
// Even if template didn't change, refresh the template editor to discard any unsaved content changes
|
|
2490
|
-
this.
|
|
2854
|
+
this.TemplateEditor.refreshAndDiscardChanges();
|
|
2491
2855
|
}
|
|
2492
2856
|
// Clear the stored original state
|
|
2493
2857
|
this.originalTemplateID = null;
|
|
2494
|
-
this.
|
|
2858
|
+
this.HasUnsavedChanges = false;
|
|
2495
2859
|
}
|
|
2496
2860
|
/**
|
|
2497
2861
|
* Adds prompt model changes to the pending records
|
|
2498
2862
|
*/
|
|
2499
2863
|
addPromptModelsToPendingRecords() {
|
|
2500
2864
|
// Add all prompt models that have been modified or are new
|
|
2501
|
-
for (const model of this.
|
|
2865
|
+
for (const model of this.PromptModels) {
|
|
2502
2866
|
if (model.ModelID && (model.Dirty || !model.IsSaved)) {
|
|
2503
2867
|
// Set the PromptID if it's not already set
|
|
2504
2868
|
if (!model.PromptID) {
|
|
@@ -2559,9 +2923,9 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2559
2923
|
const success = await transactionGroup.Submit();
|
|
2560
2924
|
if (success) {
|
|
2561
2925
|
// Clear our local state since save was successful
|
|
2562
|
-
this.
|
|
2926
|
+
this.HasUnsavedChanges = false;
|
|
2563
2927
|
// Reload prompt models to reflect database state
|
|
2564
|
-
await this.
|
|
2928
|
+
await this.LoadPromptModels();
|
|
2565
2929
|
// Reload template to reflect any changes
|
|
2566
2930
|
if (this.record.TemplateID) {
|
|
2567
2931
|
await this.loadTemplate();
|
|
@@ -2583,8 +2947,8 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2583
2947
|
/**
|
|
2584
2948
|
* Loads the result selector tree data (categories and prompts)
|
|
2585
2949
|
*/
|
|
2586
|
-
async
|
|
2587
|
-
this.
|
|
2950
|
+
async LoadResultSelectorTreeData() {
|
|
2951
|
+
this.IsLoadingResultSelectorData = true;
|
|
2588
2952
|
try {
|
|
2589
2953
|
// Load categories and prompts
|
|
2590
2954
|
const engine = AIEngineBase.Instance;
|
|
@@ -2594,16 +2958,20 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2594
2958
|
categories.sort((a, b) => a.Name.localeCompare(b.Name));
|
|
2595
2959
|
prompts.sort((a, b) => a.Name.localeCompare(b.Name));
|
|
2596
2960
|
// Build tree structure
|
|
2597
|
-
this.
|
|
2961
|
+
this.ResultSelectorTreeData = this.buildResultSelectorTree(categories, prompts);
|
|
2598
2962
|
}
|
|
2599
2963
|
catch (error) {
|
|
2600
2964
|
console.error('Error loading result selector tree data:', error);
|
|
2601
|
-
this.
|
|
2965
|
+
this.ResultSelectorTreeData = [];
|
|
2602
2966
|
}
|
|
2603
2967
|
finally {
|
|
2604
|
-
this.
|
|
2968
|
+
this.IsLoadingResultSelectorData = false;
|
|
2605
2969
|
}
|
|
2606
2970
|
}
|
|
2971
|
+
/** @deprecated Use {@link LoadResultSelectorTreeData}. */
|
|
2972
|
+
async loadResultSelectorTreeData() {
|
|
2973
|
+
return this.LoadResultSelectorTreeData();
|
|
2974
|
+
}
|
|
2607
2975
|
/**
|
|
2608
2976
|
* Builds the tree structure for result selector
|
|
2609
2977
|
*/
|
|
@@ -2687,13 +3055,17 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2687
3055
|
/**
|
|
2688
3056
|
* Handles result selector selection
|
|
2689
3057
|
*/
|
|
2690
|
-
|
|
3058
|
+
OnResultSelectorChange(value) {
|
|
2691
3059
|
this.record.ResultSelectorPromptID = value || null;
|
|
2692
3060
|
}
|
|
3061
|
+
/** @deprecated Use {@link OnResultSelectorChange}. */
|
|
3062
|
+
onResultSelectorChange(value) {
|
|
3063
|
+
return this.OnResultSelectorChange(value);
|
|
3064
|
+
}
|
|
2693
3065
|
/**
|
|
2694
3066
|
* Gets the display name for a prompt ID from the tree data
|
|
2695
3067
|
*/
|
|
2696
|
-
|
|
3068
|
+
GetPromptDisplayName(promptId) {
|
|
2697
3069
|
if (!promptId)
|
|
2698
3070
|
return '';
|
|
2699
3071
|
const findPromptInTree = (nodes) => {
|
|
@@ -2709,21 +3081,25 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2709
3081
|
}
|
|
2710
3082
|
return '';
|
|
2711
3083
|
};
|
|
2712
|
-
return findPromptInTree(this.
|
|
3084
|
+
return findPromptInTree(this.ResultSelectorTreeData);
|
|
3085
|
+
}
|
|
3086
|
+
/** @deprecated Use {@link GetPromptDisplayName}. */
|
|
3087
|
+
getPromptDisplayName(promptId) {
|
|
3088
|
+
return this.GetPromptDisplayName(promptId);
|
|
2713
3089
|
}
|
|
2714
3090
|
/**
|
|
2715
3091
|
* Moves a model up in the list by swapping with the previous item
|
|
2716
3092
|
*/
|
|
2717
|
-
|
|
2718
|
-
if (index > 0 && index < this.
|
|
3093
|
+
MoveModelUp(index) {
|
|
3094
|
+
if (index > 0 && index < this.PromptModels.length) {
|
|
2719
3095
|
// Create new array to ensure Angular detects the change
|
|
2720
|
-
const newModels = [...this.
|
|
3096
|
+
const newModels = [...this.PromptModels];
|
|
2721
3097
|
// Swap with previous item
|
|
2722
3098
|
[newModels[index - 1], newModels[index]] =
|
|
2723
3099
|
[newModels[index], newModels[index - 1]];
|
|
2724
3100
|
// Replace the array and force full re-render
|
|
2725
|
-
this.
|
|
2726
|
-
this.
|
|
3101
|
+
this.PromptModels = [...newModels];
|
|
3102
|
+
this.HasUnsavedChanges = true;
|
|
2727
3103
|
this.updateModelPriorities();
|
|
2728
3104
|
// Force Angular to re-evaluate all bindings
|
|
2729
3105
|
this.cdr.detectChanges();
|
|
@@ -2733,19 +3109,23 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2733
3109
|
}, 0);
|
|
2734
3110
|
}
|
|
2735
3111
|
}
|
|
3112
|
+
/** @deprecated Use {@link MoveModelUp}. */
|
|
3113
|
+
moveModelUp(index) {
|
|
3114
|
+
return this.MoveModelUp(index);
|
|
3115
|
+
}
|
|
2736
3116
|
/**
|
|
2737
3117
|
* Moves a model down in the list by swapping with the next item
|
|
2738
3118
|
*/
|
|
2739
|
-
|
|
2740
|
-
if (index >= 0 && index < this.
|
|
3119
|
+
MoveModelDown(index) {
|
|
3120
|
+
if (index >= 0 && index < this.PromptModels.length - 1) {
|
|
2741
3121
|
// Create new array to ensure Angular detects the change
|
|
2742
|
-
const newModels = [...this.
|
|
3122
|
+
const newModels = [...this.PromptModels];
|
|
2743
3123
|
// Swap with next item
|
|
2744
3124
|
[newModels[index], newModels[index + 1]] =
|
|
2745
3125
|
[newModels[index + 1], newModels[index]];
|
|
2746
3126
|
// Replace the array and force full re-render
|
|
2747
|
-
this.
|
|
2748
|
-
this.
|
|
3127
|
+
this.PromptModels = [...newModels];
|
|
3128
|
+
this.HasUnsavedChanges = true;
|
|
2749
3129
|
this.updateModelPriorities();
|
|
2750
3130
|
// Force Angular to re-evaluate all bindings
|
|
2751
3131
|
this.cdr.detectChanges();
|
|
@@ -2755,52 +3135,68 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2755
3135
|
}, 0);
|
|
2756
3136
|
}
|
|
2757
3137
|
}
|
|
3138
|
+
/** @deprecated Use {@link MoveModelDown}. */
|
|
3139
|
+
moveModelDown(index) {
|
|
3140
|
+
return this.MoveModelDown(index);
|
|
3141
|
+
}
|
|
2758
3142
|
/**
|
|
2759
3143
|
* Updates priority values based on array order
|
|
2760
3144
|
*/
|
|
2761
3145
|
updateModelPriorities() {
|
|
2762
3146
|
// Update priorities based on position (higher priority for items at top)
|
|
2763
|
-
const maxPriority = this.
|
|
2764
|
-
this.
|
|
3147
|
+
const maxPriority = this.PromptModels.length;
|
|
3148
|
+
this.PromptModels.forEach((model, index) => {
|
|
2765
3149
|
model.Priority = maxPriority - index;
|
|
2766
3150
|
});
|
|
2767
3151
|
}
|
|
2768
3152
|
/**
|
|
2769
3153
|
* Gets a stable identifier for a model (for form tracking)
|
|
2770
3154
|
*/
|
|
2771
|
-
|
|
3155
|
+
GetModelTrackId(model) {
|
|
2772
3156
|
return model.ID || model._tempId || '';
|
|
2773
3157
|
}
|
|
3158
|
+
/** @deprecated Use {@link GetModelTrackId}. */
|
|
3159
|
+
getModelTrackId(model) {
|
|
3160
|
+
return this.GetModelTrackId(model);
|
|
3161
|
+
}
|
|
2774
3162
|
/**
|
|
2775
3163
|
* Handles drag start event
|
|
2776
3164
|
*/
|
|
2777
|
-
|
|
2778
|
-
this.
|
|
3165
|
+
OnDragStart(event, index) {
|
|
3166
|
+
this.DraggedIndex = index;
|
|
2779
3167
|
event.dataTransfer.effectAllowed = 'move';
|
|
2780
3168
|
event.dataTransfer.setData('text/html', ''); // Required for Firefox
|
|
2781
3169
|
}
|
|
3170
|
+
/** @deprecated Use {@link OnDragStart}. */
|
|
3171
|
+
onDragStart(event, index) {
|
|
3172
|
+
return this.OnDragStart(event, index);
|
|
3173
|
+
}
|
|
2782
3174
|
/**
|
|
2783
3175
|
* Handles drag over event
|
|
2784
3176
|
*/
|
|
2785
|
-
|
|
3177
|
+
OnDragOver(event) {
|
|
2786
3178
|
event.preventDefault();
|
|
2787
3179
|
event.dataTransfer.dropEffect = 'move';
|
|
2788
3180
|
}
|
|
3181
|
+
/** @deprecated Use {@link OnDragOver}. */
|
|
3182
|
+
onDragOver(event) {
|
|
3183
|
+
return this.OnDragOver(event);
|
|
3184
|
+
}
|
|
2789
3185
|
/**
|
|
2790
3186
|
* Handles drop event
|
|
2791
3187
|
*/
|
|
2792
|
-
|
|
3188
|
+
OnDrop(event, dropIndex) {
|
|
2793
3189
|
event.preventDefault();
|
|
2794
|
-
if (this.
|
|
3190
|
+
if (this.DraggedIndex !== -1 && this.DraggedIndex !== dropIndex) {
|
|
2795
3191
|
// Create new array to ensure Angular detects the change
|
|
2796
|
-
const newModels = [...this.
|
|
3192
|
+
const newModels = [...this.PromptModels];
|
|
2797
3193
|
// Remove dragged item
|
|
2798
|
-
const draggedItem = newModels.splice(this.
|
|
3194
|
+
const draggedItem = newModels.splice(this.DraggedIndex, 1)[0];
|
|
2799
3195
|
// Insert at new position
|
|
2800
3196
|
newModels.splice(dropIndex, 0, draggedItem);
|
|
2801
3197
|
// Replace the array and force full re-render
|
|
2802
|
-
this.
|
|
2803
|
-
this.
|
|
3198
|
+
this.PromptModels = [...newModels];
|
|
3199
|
+
this.HasUnsavedChanges = true;
|
|
2804
3200
|
// Update priorities
|
|
2805
3201
|
this.updateModelPriorities();
|
|
2806
3202
|
// Force Angular to re-evaluate all bindings
|
|
@@ -2810,21 +3206,29 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2810
3206
|
this.cdr.detectChanges();
|
|
2811
3207
|
}, 0);
|
|
2812
3208
|
}
|
|
2813
|
-
this.
|
|
3209
|
+
this.DraggedIndex = -1;
|
|
3210
|
+
}
|
|
3211
|
+
/** @deprecated Use {@link OnDrop}. */
|
|
3212
|
+
onDrop(event, dropIndex) {
|
|
3213
|
+
return this.OnDrop(event, dropIndex);
|
|
2814
3214
|
}
|
|
2815
3215
|
/**
|
|
2816
3216
|
* Handles drag end event
|
|
2817
3217
|
*/
|
|
3218
|
+
OnDragEnd(_event) {
|
|
3219
|
+
this.DraggedIndex = -1;
|
|
3220
|
+
}
|
|
3221
|
+
/** @deprecated Use {@link OnDragEnd}. */
|
|
2818
3222
|
onDragEnd(_event) {
|
|
2819
|
-
this.
|
|
3223
|
+
return this.OnDragEnd(_event);
|
|
2820
3224
|
}
|
|
2821
3225
|
/**
|
|
2822
3226
|
* Load execution history for this prompt
|
|
2823
3227
|
*/
|
|
2824
|
-
async
|
|
3228
|
+
async LoadExecutionHistory() {
|
|
2825
3229
|
if (!this.record?.ID)
|
|
2826
3230
|
return;
|
|
2827
|
-
this.
|
|
3231
|
+
this.IsLoadingHistory = true;
|
|
2828
3232
|
try {
|
|
2829
3233
|
const rv = RunView.FromMetadataProvider(this.ProviderToUse);
|
|
2830
3234
|
const result = await rv.RunView({
|
|
@@ -2832,26 +3236,30 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2832
3236
|
ExtraFilter: `PromptID='${this.record.ID}'`,
|
|
2833
3237
|
OrderBy: 'RunAt DESC'
|
|
2834
3238
|
});
|
|
2835
|
-
this.
|
|
2836
|
-
this.
|
|
3239
|
+
this.ExecutionHistory = result.Results;
|
|
3240
|
+
this.SortExecutionHistory();
|
|
2837
3241
|
}
|
|
2838
3242
|
catch (error) {
|
|
2839
3243
|
console.error('Error loading execution history:', error);
|
|
2840
|
-
this.
|
|
3244
|
+
this.ExecutionHistory = [];
|
|
2841
3245
|
}
|
|
2842
3246
|
finally {
|
|
2843
|
-
this.
|
|
3247
|
+
this.IsLoadingHistory = false;
|
|
2844
3248
|
}
|
|
2845
3249
|
}
|
|
3250
|
+
/** @deprecated Use {@link LoadExecutionHistory}. */
|
|
3251
|
+
async loadExecutionHistory() {
|
|
3252
|
+
return this.LoadExecutionHistory();
|
|
3253
|
+
}
|
|
2846
3254
|
/**
|
|
2847
3255
|
* Sort execution history based on current sort field and direction
|
|
2848
3256
|
*/
|
|
2849
|
-
|
|
2850
|
-
if (!this.
|
|
3257
|
+
SortExecutionHistory() {
|
|
3258
|
+
if (!this.ExecutionHistory || this.ExecutionHistory.length === 0)
|
|
2851
3259
|
return;
|
|
2852
|
-
this.
|
|
3260
|
+
this.ExecutionHistory.sort((a, b) => {
|
|
2853
3261
|
let aVal, bVal;
|
|
2854
|
-
switch (this.
|
|
3262
|
+
switch (this.HistorySortField) {
|
|
2855
3263
|
case 'runAt':
|
|
2856
3264
|
aVal = a.RunAt ? new Date(a.RunAt).getTime() : 0;
|
|
2857
3265
|
bVal = b.RunAt ? new Date(b.RunAt).getTime() : 0;
|
|
@@ -2869,7 +3277,7 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2869
3277
|
bVal = b.TokensUsed || 0;
|
|
2870
3278
|
break;
|
|
2871
3279
|
}
|
|
2872
|
-
if (this.
|
|
3280
|
+
if (this.HistorySortDirection === 'asc') {
|
|
2873
3281
|
return aVal > bVal ? 1 : aVal < bVal ? -1 : 0;
|
|
2874
3282
|
}
|
|
2875
3283
|
else {
|
|
@@ -2877,27 +3285,39 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2877
3285
|
}
|
|
2878
3286
|
});
|
|
2879
3287
|
}
|
|
3288
|
+
/** @deprecated Use {@link SortExecutionHistory}. */
|
|
3289
|
+
sortExecutionHistory() {
|
|
3290
|
+
return this.SortExecutionHistory();
|
|
3291
|
+
}
|
|
2880
3292
|
/**
|
|
2881
3293
|
* Change sort field and direction for execution history
|
|
2882
3294
|
*/
|
|
2883
|
-
|
|
2884
|
-
if (this.
|
|
3295
|
+
ChangeHistorySort(field) {
|
|
3296
|
+
if (this.HistorySortField === field) {
|
|
2885
3297
|
// Toggle direction if same field
|
|
2886
|
-
this.
|
|
3298
|
+
this.HistorySortDirection = this.HistorySortDirection === 'asc' ? 'desc' : 'asc';
|
|
2887
3299
|
}
|
|
2888
3300
|
else {
|
|
2889
3301
|
// New field, default to desc
|
|
2890
|
-
this.
|
|
2891
|
-
this.
|
|
3302
|
+
this.HistorySortField = field;
|
|
3303
|
+
this.HistorySortDirection = 'desc';
|
|
2892
3304
|
}
|
|
2893
|
-
this.
|
|
3305
|
+
this.SortExecutionHistory();
|
|
3306
|
+
}
|
|
3307
|
+
/** @deprecated Use {@link ChangeHistorySort}. */
|
|
3308
|
+
changeHistorySort(field) {
|
|
3309
|
+
return this.ChangeHistorySort(field);
|
|
2894
3310
|
}
|
|
2895
3311
|
/**
|
|
2896
3312
|
* Navigate to a prompt run record
|
|
2897
3313
|
*/
|
|
2898
|
-
|
|
3314
|
+
NavigateToPromptRun(runId) {
|
|
2899
3315
|
SharedService.Instance.OpenEntityRecord('MJ: AI Prompt Runs', CompositeKey.FromID(runId));
|
|
2900
3316
|
}
|
|
3317
|
+
/** @deprecated Use {@link NavigateToPromptRun}. */
|
|
3318
|
+
navigateToPromptRun(runId) {
|
|
3319
|
+
return this.NavigateToPromptRun(runId);
|
|
3320
|
+
}
|
|
2901
3321
|
/**
|
|
2902
3322
|
* Format duration for display
|
|
2903
3323
|
*/
|
|
@@ -2919,43 +3339,59 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2919
3339
|
/**
|
|
2920
3340
|
* Format cost for display
|
|
2921
3341
|
*/
|
|
2922
|
-
|
|
3342
|
+
FormatCost(cost) {
|
|
2923
3343
|
if (!cost)
|
|
2924
3344
|
return '-';
|
|
2925
3345
|
return `$${cost.toFixed(4)}`;
|
|
2926
3346
|
}
|
|
3347
|
+
/** @deprecated Use {@link FormatCost}. */
|
|
3348
|
+
formatCost(cost) {
|
|
3349
|
+
return this.FormatCost(cost);
|
|
3350
|
+
}
|
|
2927
3351
|
/**
|
|
2928
3352
|
* Format tokens for display
|
|
2929
3353
|
*/
|
|
2930
|
-
|
|
3354
|
+
FormatTokens(tokens) {
|
|
2931
3355
|
if (!tokens)
|
|
2932
3356
|
return '-';
|
|
2933
3357
|
return tokens.toLocaleString();
|
|
2934
3358
|
}
|
|
3359
|
+
/** @deprecated Use {@link FormatTokens}. */
|
|
3360
|
+
formatTokens(tokens) {
|
|
3361
|
+
return this.FormatTokens(tokens);
|
|
3362
|
+
}
|
|
2935
3363
|
/**
|
|
2936
3364
|
* Get status color for execution
|
|
2937
3365
|
*/
|
|
2938
|
-
|
|
3366
|
+
GetExecutionStatusColor(success) {
|
|
2939
3367
|
if (success === true)
|
|
2940
3368
|
return '#28a745';
|
|
2941
3369
|
if (success === false)
|
|
2942
3370
|
return '#dc3545';
|
|
2943
3371
|
return '#ffc107';
|
|
2944
3372
|
}
|
|
3373
|
+
/** @deprecated Use {@link GetExecutionStatusColor}. */
|
|
3374
|
+
getExecutionStatusColor(success) {
|
|
3375
|
+
return this.GetExecutionStatusColor(success);
|
|
3376
|
+
}
|
|
2945
3377
|
/**
|
|
2946
3378
|
* Get status icon for execution
|
|
2947
3379
|
*/
|
|
2948
|
-
|
|
3380
|
+
GetExecutionStatusIcon(success) {
|
|
2949
3381
|
if (success === true)
|
|
2950
3382
|
return 'fa-check-circle';
|
|
2951
3383
|
if (success === false)
|
|
2952
3384
|
return 'fa-times-circle';
|
|
2953
3385
|
return 'fa-spinner fa-spin';
|
|
2954
3386
|
}
|
|
3387
|
+
/** @deprecated Use {@link GetExecutionStatusIcon}. */
|
|
3388
|
+
getExecutionStatusIcon(success) {
|
|
3389
|
+
return this.GetExecutionStatusIcon(success);
|
|
3390
|
+
}
|
|
2955
3391
|
/**
|
|
2956
3392
|
* Gets the icon for a template parameter type
|
|
2957
3393
|
*/
|
|
2958
|
-
|
|
3394
|
+
GetParamTypeIcon(type) {
|
|
2959
3395
|
switch (type) {
|
|
2960
3396
|
case 'Scalar': return 'fa-font';
|
|
2961
3397
|
case 'Array': return 'fa-list';
|
|
@@ -2965,10 +3401,14 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2965
3401
|
default: return 'fa-question';
|
|
2966
3402
|
}
|
|
2967
3403
|
}
|
|
3404
|
+
/** @deprecated Use {@link GetParamTypeIcon}. */
|
|
3405
|
+
getParamTypeIcon(type) {
|
|
3406
|
+
return this.GetParamTypeIcon(type);
|
|
3407
|
+
}
|
|
2968
3408
|
/**
|
|
2969
3409
|
* Gets the color for a template parameter type
|
|
2970
3410
|
*/
|
|
2971
|
-
|
|
3411
|
+
GetParamTypeColor(type) {
|
|
2972
3412
|
switch (type) {
|
|
2973
3413
|
case 'Scalar': return '#17a2b8';
|
|
2974
3414
|
case 'Array': return '#28a745';
|
|
@@ -2978,10 +3418,14 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
2978
3418
|
default: return '#6c757d';
|
|
2979
3419
|
}
|
|
2980
3420
|
}
|
|
3421
|
+
/** @deprecated Use {@link GetParamTypeColor}. */
|
|
3422
|
+
getParamTypeColor(type) {
|
|
3423
|
+
return this.GetParamTypeColor(type);
|
|
3424
|
+
}
|
|
2981
3425
|
/**
|
|
2982
3426
|
* Gets a friendly description of the parameter type
|
|
2983
3427
|
*/
|
|
2984
|
-
|
|
3428
|
+
GetParamTypeDescription(param) {
|
|
2985
3429
|
switch (param.Type) {
|
|
2986
3430
|
case 'Scalar':
|
|
2987
3431
|
return 'Single value (text, number, date, etc.)';
|
|
@@ -3003,12 +3447,16 @@ let MJAIPromptFormComponentExtended = class MJAIPromptFormComponentExtended exte
|
|
|
3003
3447
|
return 'Unknown type';
|
|
3004
3448
|
}
|
|
3005
3449
|
}
|
|
3450
|
+
/** @deprecated Use {@link GetParamTypeDescription}. */
|
|
3451
|
+
getParamTypeDescription(param) {
|
|
3452
|
+
return this.GetParamTypeDescription(param);
|
|
3453
|
+
}
|
|
3006
3454
|
static { this.ɵfac = /*@__PURE__*/ (() => { let ɵMJAIPromptFormComponentExtended_BaseFactory; return function MJAIPromptFormComponentExtended_Factory(__ngFactoryType__) { return (ɵMJAIPromptFormComponentExtended_BaseFactory || (ɵMJAIPromptFormComponentExtended_BaseFactory = i0.ɵɵgetInheritedFactory(MJAIPromptFormComponentExtended)))(__ngFactoryType__ || MJAIPromptFormComponentExtended); }; })(); }
|
|
3007
3455
|
static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJAIPromptFormComponentExtended, selectors: [["mj-ai-prompt-form"]], viewQuery: function MJAIPromptFormComponentExtended_Query(rf, ctx) { if (rf & 1) {
|
|
3008
3456
|
i0.ɵɵviewQuery(_c0, 5);
|
|
3009
3457
|
} if (rf & 2) {
|
|
3010
3458
|
let _t;
|
|
3011
|
-
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.
|
|
3459
|
+
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.TemplateEditor = _t.first);
|
|
3012
3460
|
} }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 3, vars: 2, consts: [["form", "ngForm"], ["templateEditor", ""], [3, "Record", "FormComponent", "ToolbarConfig", "WidthMode"], [3, "Width", "Height", "MinWidth", "MinHeight", "Draggable", "Resizable", "Visible", "Title"], [3, "Navigate", "DeleteRequested", "FavoriteToggled", "HistoryRequested", "ListManagementRequested", "Record", "FormComponent", "ToolbarConfig", "WidthMode"], [1, "record-form", 2, "display", "flex", "flex-direction", "column", "height", "100%", "overflow", "hidden"], [1, "prompt-main-area", 2, "display", "flex", "flex-direction", "column", "flex", "1", "min-height", "0", "overflow-y", "auto"], [1, "prompt-header", 2, "flex-shrink", "0", "padding", "20px", "background", "var(--mj-bg-surface-sunken)", "border-bottom", "2px solid var(--mj-border-default)"], [2, "display", "flex", "justify-content", "space-between", "align-items", "flex-start", "gap", "20px"], [2, "flex", "1", "min-width", "0"], [2, "display", "flex", "align-items", "center", "gap", "12px", "margin-bottom", "8px"], [1, "fa-solid", "fa-robot", 2, "color", "var(--mj-brand-primary)", "font-size", "1.4em"], ["type", "text", "name", "promptName", "placeholder", "Enter prompt name...", 1, "mj-input", 2, "font-size", "1.2em", "font-weight", "600", "min-width", "300px", "flex", "1", 3, "ngModel"], [2, "display", "flex", "gap", "16px", "margin-bottom", "12px", "flex-wrap", "wrap"], ["name", "promptDescription", "placeholder", "Enter prompt description...", 1, "mj-textarea", 2, "width", "100%", "max-width", "600px", "margin-bottom", "12px", 3, "ngModel", "rows"], [2, "margin", "0 0 12px 0", "color", "var(--mj-text-muted)", "font-size", "0.9em", "line-height", "1.4"], [1, "quick-config", 2, "display", "flex", "align-items", "center", "gap", "16px", "flex-wrap", "wrap"], [1, "config-item", 2, "display", "flex", "align-items", "center", "gap", "6px", "font-size", "0.85em"], [1, "fa-solid", "fa-layer-group", 2, "color", "var(--mj-text-muted)"], [2, "color", "var(--mj-text-muted)"], [2, "color", "var(--mj-text-secondary)", "font-weight", "500"], [1, "fa-solid", "fa-code", 2, "color", "var(--mj-text-muted)"], [2, "font-weight", "500"], [1, "action-buttons", 2, "display", "flex", "flex-direction", "column", "gap", "8px", "align-items", "flex-end"], [2, "display", "flex", "gap", "8px"], ["mjButton", "", "variant", "primary", "size", "lg", "title", "Run AI Prompt Test Harness"], [2, "font-size", "0.75em", "color", "#dc3545", "text-align", "right", "max-width", "200px"], [1, "configuration-sections", 2, "flex", "1", "background", "var(--mj-bg-surface-card)", "border-top", "2px solid var(--mj-border-default)", "padding", "16px", "min-height", "0"], [2, "margin-bottom", "12px", 3, "Expanded"], ["mjAccordionTitle", ""], [1, "template-section", 2, "display", "flex", "flex-direction", "column", "min-height", "400px", "padding", "8px"], [1, "loading-state", 2, "flex", "1", "display", "flex", "align-items", "center", "justify-content", "center", "color", "var(--mj-text-muted)"], ["Size", "large", "Icon", "fa-solid fa-code", "Title", "No Template Associated", "Message", "This AI prompt needs a template to define its structure and parameters. Create a new template or link to an existing one.", 1, "no-template-state"], ["Variant", "warning", "Title", "Template Not Found", "Message", "The referenced template could not be loaded. It may have been deleted or moved.", 1, "invalid-template-state"], [1, "template-editor-container", 2, "flex", "1", "display", "flex", "flex-direction", "column", "min-height", "350px"], [2, "padding", "16px 0"], [2, "display", "grid", "grid-template-columns", "1fr 1fr", "gap", "20px"], ["FieldName", "ParallelizationMode", "Type", "dropdownlist", 3, "Record", "ShowLabel", "EditMode"], ["FieldName", "ParallelCount", "Type", "numerictextbox", 3, "Record", "ShowLabel", "EditMode"], ["FieldName", "ParallelConfigParam", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode"], ["FieldName", "OutputType", "Type", "dropdownlist", 3, "Record", "ShowLabel", "EditMode"], ["FieldName", "EffortLevel", "Type", "numerictextbox", "Caption", "Effort Level (1-100)", "Description", "Higher values request more thorough reasoning", 3, "Record", "ShowLabel", "EditMode"], ["FieldName", "ValidationBehavior", "Type", "dropdownlist", 3, "Record", "ShowLabel", "EditMode"], ["FieldName", "EnableCaching", "Type", "checkbox", 3, "Record", "ShowLabel", "EditMode"], [2, "margin-bottom", "16px"], [2, "display", "block", "margin-bottom", "4px", "font-weight", "600", "color", "var(--mj-text-secondary)", "font-size", "0.9em"], [2, "color", "var(--mj-text-secondary)"], [2, "margin", "0 0 12px 0", "font-size", "0.85em", "color", "var(--mj-text-muted)"], ["FieldName", "AssistantPrefill", "Type", "textarea", 3, "Record", "ShowLabel", "EditMode"], ["FieldName", "StopSequences", "Type", "textbox", 3, "Record", "ShowLabel", "EditMode"], ["FieldName", "PrefillFallbackMode", "Type", "dropdownlist", 3, "Record", "ShowLabel", "EditMode"], ["type", "text", "name", "promptName", "placeholder", "Enter prompt name...", 1, "mj-input", 2, "font-size", "1.2em", "font-weight", "600", "min-width", "300px", "flex", "1", 3, "ngModelChange", "ngModel"], [2, "margin", "0", "color", "var(--mj-text-secondary)", "font-weight", "600", "flex", "1"], [1, "status-badge", 2, "color", "white", "padding", "4px 10px", "border-radius", "12px", "font-size", "0.75em", "font-weight", "500"], ["name", "promptStatus", "TextField", "text", "ValueField", "value", 2, "width", "150px", 3, "ngModelChange", "ngModel", "Data", "ValuePrimitive"], [2, "color", "#dc3545"], [2, "padding", "8px", "color", "var(--mj-text-muted)", "font-style", "italic", "width", "200px"], ["name", "promptTypeID", "TextField", "Name", "ValueField", "ID", "Placeholder", "Select prompt type...", 2, "width", "200px", 3, "ngModel", "Data", "ValuePrimitive", "Filterable"], [1, "fa-solid", "fa-spinner", "fa-spin"], ["name", "promptTypeID", "TextField", "Name", "ValueField", "ID", "Placeholder", "Select prompt type...", 2, "width", "200px", 3, "ngModelChange", "ngModel", "Data", "ValuePrimitive", "Filterable"], ["name", "promptDescription", "placeholder", "Enter prompt description...", 1, "mj-textarea", 2, "width", "100%", "max-width", "600px", "margin-bottom", "12px", 3, "ngModelChange", "ngModel", "rows"], [1, "fa-solid", "fa-tag", 2, "color", "var(--mj-text-muted)"], [1, "fa-solid", "fa-database", 2, "color", "#28a745"], [2, "color", "#28a745", "font-weight", "500"], [1, "fa-solid", "fa-tachometer-alt", 2, "color", "var(--mj-text-muted)"], ["mjButton", "", "variant", "primary", "size", "lg", "title", "Run AI Prompt Test Harness", 3, "click"], [1, "fa-solid", "fa-play"], [2, "display", "flex", "align-items", "center", "gap", "8px", "font-weight", "600"], [2, "color", "var(--mj-text-muted)", "font-size", "0.9em", "font-weight", "normal"], [1, "fa-solid", "fa-spinner", "fa-spin", 2, "font-size", "24px", "margin-right", "12px"], ["ngProjectAs", "[actions]", 5, ["", "actions", ""], 2, "display", "flex", "gap", "12px"], ["mjButton", "", "variant", "primary"], ["mjButton", "", "variant", "outline"], ["mjButton", "", "variant", "primary", 3, "click"], [1, "fa-solid", "fa-plus"], ["mjButton", "", "variant", "outline", 3, "click"], [1, "fa-solid", "fa-link"], [1, "fa-solid", "fa-arrows-rotate"], [1, "template-actions", 2, "display", "flex", "gap", "8px", "padding", "8px", "border-bottom", "1px solid var(--mj-border-default)", "background", "var(--mj-bg-surface-sunken)"], [2, "flex", "1", "background", "var(--mj-bg-surface-card)", "border-radius", "6px", "border", "1px solid var(--mj-border-default)"], [2, "display", "block", "min-height", "300px", 3, "contentChange", "runTemplate", "template", "config"], ["mjButton", "", "variant", "outline", "size", "sm", "title", "Change to a different template"], ["mjButton", "", "variant", "outline", "size", "sm", "title", "Open template in new window"], ["mjButton", "", "variant", "outline", "size", "sm", "title", "Change to a different template", 3, "click"], [1, "fa-solid", "fa-exchange-alt"], ["mjButton", "", "variant", "outline", "size", "sm", "title", "Open template in new window", 3, "click"], [1, "fa-solid", "fa-external-link-alt"], [1, "model-management", 2, "border", "1px solid var(--mj-border-default)", "border-radius", "6px", "background", "var(--mj-bg-surface-sunken)"], [1, "loading-state", 2, "padding", "20px", "text-align", "center", "color", "var(--mj-text-muted)"], [1, "fa-solid", "fa-microchip", 2, "color", "var(--mj-text-muted)"], [1, "mj-accordion-badge"], [2, "color", "var(--mj-text-muted)", "font-size", "0.8em", "font-weight", "normal", "margin-left", "8px"], ["title", "Models are tried in order from top to bottom. The first available model will be used.", 1, "fa-solid", "fa-info-circle"], ["Size", "compact", "Icon", "fa-solid fa-circle-info", "Title", "No models configured"], ["ngProjectAs", "[actions]", "mjButton", "", "variant", "outline", "size", "sm", 5, ["", "actions", ""]], ["ngProjectAs", "[actions]", "mjButton", "", "variant", "outline", "size", "sm", 5, ["", "actions", ""], 3, "click"], [2, "padding", "12px 16px", "background", "color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface))", "border-bottom", "1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default))", "color", "var(--mj-brand-primary)", "font-size", "0.85em"], [1, "model-header", 2, "display", "grid", "grid-template-columns", "40px 2fr 1fr 1fr 1fr 60px", "gap", "12px", "padding", "12px 16px", "background", "var(--mj-bg-surface-sunken)", "font-weight", "600", "font-size", "0.85em", "color", "var(--mj-text-secondary)", "border-bottom", "1px solid var(--mj-border-default)"], ["title", "Priority order - models are tried from top to bottom"], [1, "fa-solid", "fa-sort", 2, "color", "var(--mj-text-muted)"], [1, "add-model-row", 2, "padding", "12px 16px", "text-align", "center", "background", "var(--mj-bg-surface-sunken)", "border-top", "1px solid var(--mj-border-default)"], [1, "fa-solid", "fa-info-circle", 2, "margin-right", "6px"], [1, "model-row", 2, "display", "grid", "grid-template-columns", "40px 2fr 1fr 1fr 1fr 60px", "gap", "12px", "padding", "12px 16px", "border-bottom", "1px solid var(--mj-border-default)", "align-items", "start", "transition", "background 0.2s, opacity 0.2s", 3, "dragstart", "dragover", "drop", "dragend", "draggable"], [1, "drag-handle", 2, "display", "flex", "flex-direction", "column", "align-items", "center", "justify-content", "center", "color", "var(--mj-text-muted)"], [2, "font-size", "0.9em", "font-weight", "600", 3, "title"], [1, "model-select"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Select a model...", 2, "width", "100%", 3, "ngModel", "name", "Data", "ValuePrimitive", "Filterable"], [1, "model-vendor"], [1, "model-configuration"], [2, "font-size", "0.9em"], [1, "model-created"], [2, "color", "var(--mj-text-muted)", "font-size", "0.8em"], [2, "color", "#28a745", "font-size", "0.8em", "font-style", "italic"], [1, "model-actions", 2, "display", "flex", "gap", "2px", "flex-direction", "column"], [2, "display", "grid", "grid-template-columns", "40px 1fr", "gap", "12px", "padding", "8px 16px", "border-bottom", "1px solid var(--mj-border-default)", "background", "var(--mj-bg-surface-sunken)", "font-size", "0.85em", "color", "var(--mj-text-muted)"], [2, "display", "flex", "gap", "16px", "flex-wrap", "wrap", "align-items", "center", "margin-bottom", "8px"], [2, "padding", "8px", "background", "var(--mj-bg-surface-card)", "border", "1px solid var(--mj-border-default)", "border-radius", "4px", "margin-top", "8px"], ["title", "Drag to reorder priority", 1, "fa-solid", "fa-grip-vertical", 2, "cursor", "move"], [2, "font-size", "0.7em", "margin-top", "2px"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Select a model...", 2, "width", "100%", 3, "ngModelChange", "ValueChange", "ngModel", "name", "Data", "ValuePrimitive", "Filterable"], [2, "color", "var(--mj-text-muted)", "font-style", "italic", "font-size", "0.9em"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Select vendor...", 2, "width", "100%", 3, "ngModel", "name", "Data", "ValuePrimitive", "Filterable"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Select vendor...", 2, "width", "100%", 3, "ngModelChange", "ngModel", "name", "Data", "ValuePrimitive", "Filterable"], [2, "font-size", "0.9em", "font-weight", "500", 3, "color"], [2, "font-size", "0.9em", "font-weight", "500"], [2, "font-size", "0.8em", "margin-left", "4px"], [2, "font-size", "0.9em", 3, "color"], [2, "color", "var(--mj-text-muted)", "font-size", "0.9em"], [2, "padding", "4px", "color", "var(--mj-text-muted)", "font-style", "italic", "font-size", "0.85em"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Default", 2, "width", "100%", 3, "ngModel", "name", "Data", "ValuePrimitive", "Filterable"], ["TextField", "Name", "ValueField", "ID", "Placeholder", "Default", 2, "width", "100%", 3, "ngModelChange", "ValueChange", "ngModel", "name", "Data", "ValuePrimitive", "Filterable"], [2, "display", "flex", "gap", "2px", "margin-bottom", "4px"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Remove model", 2, "color", "var(--mj-status-error)"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Move up", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-up"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Move down", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-down"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "Remove model", 2, "color", "var(--mj-status-error)", 3, "click"], [1, "fa-solid", "fa-times"], [2, "margin-bottom", "6px", "font-weight", "600", "color", "var(--mj-text-secondary)", "font-size", "0.9em"], [1, "fa-solid", "fa-layer-group"], [2, "display", "grid", "grid-template-columns", "1fr 1fr 1fr", "gap", "12px", "align-items", "center"], [2, "display", "flex", "gap", "16px", "flex-wrap", "wrap", "align-items", "center"], [2, "display", "block", "margin-bottom", "2px", "font-size", "0.8em", "font-weight", "600", "color", "var(--mj-text-secondary)"], ["TextField", "text", "ValueField", "value", "Placeholder", "Select mode...", 2, "width", "100%", "font-size", "0.85em", 3, "ngModelChange", "ngModel", "name", "Data", "ValuePrimitive"], ["Placeholder", "Count...", 2, "width", "100%", "font-size", "0.85em", 3, "ngModelChange", "ngModel", "name", "Min", "Step", "Format"], ["type", "text", "placeholder", "Parameter name...", 1, "mj-input", 2, "width", "100%", "font-size", "0.85em", 3, "ngModelChange", "ngModel", "name"], ["mjButton", "", "variant", "outline", "size", "sm", 2, "color", "var(--mj-status-success)", "border-color", "var(--mj-status-success)", 3, "click"], [1, "fa-solid", "fa-cogs", 2, "color", "var(--mj-text-muted)"], [2, "padding", "8px", "color", "var(--mj-text-muted)", "font-style", "italic"], ["name", "resultSelectorPromptID", "TextField", "text", "ValueField", "value", "Placeholder", "Select a result selector prompt...", 2, "width", "100%", 3, "ngModel", "Data", "ValuePrimitive", "Filterable"], ["name", "resultSelectorPromptID", "TextField", "text", "ValueField", "value", "Placeholder", "Select a result selector prompt...", 2, "width", "100%", 3, "ngModelChange", "ValueChange", "ngModel", "Data", "ValuePrimitive", "Filterable"], [1, "fa-solid", "fa-wand-magic-sparkles", 2, "color", "var(--mj-text-muted)"], ["Size", "compact", "Icon", "fa-solid fa-circle-info", "Title", "This template has no parameters defined"], [1, "fa-solid", "fa-sliders", 2, "color", "var(--mj-text-muted)"], ["title", "These parameters are defined in the template and will be available when executing this prompt", 1, "fa-solid", "fa-info-circle"], [2, "display", "grid", "gap", "12px"], [1, "parameter-card", 2, "border", "1px solid var(--mj-border-default)", "border-radius", "8px", "padding", "16px", "background", "var(--mj-bg-surface-sunken)", "transition", "all 0.2s", 3, "border-left"], [2, "margin-top", "16px", "padding", "12px", "background", "color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface))", "border-radius", "6px", "border", "1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default))"], [2, "display", "flex", "align-items", "flex-start", "gap", "8px"], [1, "fa-solid", "fa-lightbulb", 2, "color", "var(--mj-brand-primary)", "margin-top", "2px"], [2, "flex", "1", "font-size", "0.85em", "color", "var(--mj-brand-primary)", "line-height", "1.5"], [1, "parameter-card", 2, "border", "1px solid var(--mj-border-default)", "border-radius", "8px", "padding", "16px", "background", "var(--mj-bg-surface-sunken)", "transition", "all 0.2s"], [2, "display", "flex", "justify-content", "space-between", "align-items", "flex-start", "margin-bottom", "8px"], [2, "display", "flex", "align-items", "center", "gap", "8px"], [2, "font-size", "1.2em"], [2, "margin", "0", "color", "var(--mj-text-secondary)", "font-weight", "600"], [2, "color", "#dc3545", "font-size", "0.9em", "margin-left", "4px"], [1, "type-badge", 2, "color", "white", "padding", "4px 8px", "border-radius", "12px", "font-size", "0.75em", "font-weight", "500"], [2, "color", "#dc3545", "font-size", "0.85em", "font-weight", "500"], [2, "color", "var(--mj-text-muted)", "font-size", "0.85em"], [2, "margin", "0 0 8px 0", "color", "var(--mj-text-muted)", "font-size", "0.9em", "line-height", "1.4"], [2, "font-size", "0.85em", "color", "var(--mj-text-secondary)"], [2, "display", "flex", "align-items", "center", "gap", "4px", "margin-bottom", "4px"], [1, "fa-solid", "fa-info-circle", 2, "color", "var(--mj-text-muted)"], [2, "display", "grid", "grid-template-columns", "repeat(auto-fit, minmax(200px, 1fr))", "gap", "12px", "margin-top", "12px"], [2, "background", "var(--mj-bg-surface-card)", "padding", "8px 12px", "border-radius", "4px", "border", "1px solid var(--mj-border-default)"], [2, "display", "block", "font-size", "0.8em", "color", "var(--mj-text-muted)", "margin-bottom", "2px"], [2, "font-size", "0.85em", "color", "var(--mj-text-secondary)", "word-break", "break-all"], [2, "font-size", "0.8em", "color", "var(--mj-text-secondary)", "word-break", "break-all"], [2, "padding", "16px"], [2, "background", "var(--mj-bg-surface-sunken)", "border", "1px solid var(--mj-border-default)", "border-radius", "4px", "padding", "12px", "font-family", "'Courier New', monospace", "font-size", "0.9em", "white-space", "pre-wrap", "overflow", "auto", "max-height", "250px"], ["Variant", "warning"], [2, "color", "#dc3545", "font-size", "0.8em", "font-weight", "normal"], ["name", "outputExample", "language", "json", "placeholder", "Enter JSON example structure...", 2, "width", "100%", "height", "200px", "border", "1px solid var(--mj-border-default)", "border-radius", "4px", 3, "ngModelChange", "ngModel"], [2, "margin-top", "8px", "color", "var(--mj-text-muted)", "font-size", "0.85em"], [1, "fa-solid", "fa-info-circle"], [2, "text-align", "center", "padding", "40px", "color", "var(--mj-text-muted)"], ["Size", "compact", "Icon", "fa-solid fa-clock-rotate-left", "Title", "No execution history yet", "Message", "Run this prompt to see execution history here"], [1, "fa-solid", "fa-history", 2, "color", "var(--mj-text-muted)"], [2, "color", "var(--mj-text-muted)", "font-weight", "normal"], [1, "fa-solid", "fa-spinner", "fa-spin", 2, "font-size", "2em", "margin-bottom", "12px"], [2, "display", "flex", "justify-content", "space-between", "align-items", "center", "margin-bottom", "16px"], [2, "display", "flex", "gap", "8px", "align-items", "center"], [1, "mj-button-group"], ["mjButton", "", "size", "sm", 3, "click"], [2, "margin-left", "4px", "font-size", "0.8em", 3, "class"], [2, "border", "1px solid var(--mj-border-default)", "border-radius", "8px", "overflow", "hidden"], [2, "width", "100%", "border-collapse", "collapse"], [2, "background", "var(--mj-bg-surface-sunken)", "border-bottom", "2px solid var(--mj-border-default)"], [2, "padding", "12px", "text-align", "left", "font-weight", "600", "color", "var(--mj-text-secondary)"], [2, "padding", "12px", "text-align", "right", "font-weight", "600", "color", "var(--mj-text-secondary)"], [2, "padding", "12px", "text-align", "center", "font-weight", "600", "color", "var(--mj-text-secondary)"], [1, "history-row", 2, "border-bottom", "1px solid var(--mj-border-default)", 3, "even-row"], [2, "margin-left", "4px", "font-size", "0.8em"], [1, "history-row", 2, "border-bottom", "1px solid var(--mj-border-default)"], [2, "padding", "12px"], [2, "display", "flex", "align-items", "center", "gap", "6px"], [2, "padding", "12px", "color", "var(--mj-text-secondary)"], [2, "padding", "12px", "text-align", "right", "color", "var(--mj-text-secondary)"], [2, "padding", "12px", "text-align", "center"], [2, "padding", "4px 8px", "border-radius", "12px", "background", "var(--mj-bg-surface-sunken)", "color", "var(--mj-text-secondary)", "font-size", "0.85em", "font-weight", "500"], ["mjButton", "", "variant", "flat", "size", "sm", "title", "View details", 3, "click"], [1, "fa-solid", "fa-external-link"], [3, "Params", "NewRecordValues", "AllowLoad", "ShowToolbar"], [1, "fa-solid", "fa-database", 2, "color", "var(--mj-text-muted)"], [2, "margin", "0 0 12px 0", "color", "var(--mj-text-secondary)"], [1, "fa-solid", "fa-link", 2, "color", "var(--mj-text-muted)"], [3, "Close", "Width", "Height", "MinWidth", "MinHeight", "Draggable", "Resizable", "Visible", "Title"], [3, "visibilityChange", "entity", "mode", "isVisible"]], template: function MJAIPromptFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
|
|
3013
3461
|
i0.ɵɵelement(0, "div");
|
|
3014
3462
|
i0.ɵɵconditionalCreate(1, MJAIPromptFormComponentExtended_Conditional_1_Template, 77, 53, "mj-record-form-container", 2);
|
|
@@ -3027,7 +3475,7 @@ export { MJAIPromptFormComponentExtended };
|
|
|
3027
3475
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJAIPromptFormComponentExtended, [{
|
|
3028
3476
|
type: Component,
|
|
3029
3477
|
args: [{ standalone: false, selector: 'mj-ai-prompt-form', template: "<!-- Dialog container -->\n<div></div>\n@if (record) {\n<mj-record-form-container [Record]=\"record\" [FormComponent]=\"this\"\n [ToolbarConfig]=\"toolbarConfig\"\n [WidthMode]=\"'full-width'\"\n (Navigate)=\"OnFormNavigate($event)\"\n (DeleteRequested)=\"OnDeleteRequested()\"\n (FavoriteToggled)=\"OnFavoriteToggled()\"\n (HistoryRequested)=\"OnHistoryRequested()\"\n (ListManagementRequested)=\"OnListManagementRequested()\">\n <form class=\"record-form\" #form=\"ngForm\" style=\"display: flex; flex-direction: column; height: 100%; overflow: hidden;\">\n <!-- Main Content Area - Template Editor and Configuration -->\n <div class=\"prompt-main-area\" style=\"display: flex; flex-direction: column; flex: 1; min-height: 0; overflow-y: auto;\">\n <!-- Header Section -->\n <div class=\"prompt-header\" style=\"flex-shrink: 0; padding: 20px; background: var(--mj-bg-surface-sunken); border-bottom: 2px solid var(--mj-border-default);\">\n <div style=\"display: flex; justify-content: space-between; align-items: flex-start; gap: 20px;\">\n <!-- Left: Prompt Info -->\n <div style=\"flex: 1; min-width: 0;\">\n <div style=\"display: flex; align-items: center; gap: 12px; margin-bottom: 8px;\">\n <i class=\"fa-solid fa-robot\" style=\"color: var(--mj-brand-primary); font-size: 1.4em;\"></i>\n @if (EditMode) {\n <input type=\"text\" class=\"mj-input\" [(ngModel)]=\"record.Name\"\n name=\"promptName\"\n placeholder=\"Enter prompt name...\"\n style=\"font-size: 1.2em; font-weight: 600; min-width: 300px; flex: 1;\" />\n } @else {\n <h4 style=\"margin: 0; color: var(--mj-text-secondary); font-weight: 600; flex: 1;\">{{ record.Name || 'Untitled AI Prompt' }}</h4>\n <span class=\"status-badge\" [style.background-color]=\"getStatusBadgeColor()\"\n style=\"color: white; padding: 4px 10px; border-radius: 12px; font-size: 0.75em; font-weight: 500;\">\n {{ record.Status }}\n </span>\n }\n </div>\n <!-- Status and Type Editors when in edit mode -->\n @if (EditMode) {\n <div style=\"display: flex; gap: 16px; margin-bottom: 12px; flex-wrap: wrap;\">\n <div>\n <label style=\"display: block; margin-bottom: 4px; font-weight: 600; color: var(--mj-text-secondary); font-size: 0.9em;\">Status</label>\n <mj-dropdown [(ngModel)]=\"record.Status\"\n name=\"promptStatus\"\n [Data]=\"[{text: 'Active', value: 'Active'}, {text: 'Pending', value: 'Pending'}, {text: 'Disabled', value: 'Disabled'}]\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n style=\"width: 150px;\">\n </mj-dropdown>\n </div>\n <div>\n <label style=\"display: block; margin-bottom: 4px; font-weight: 600; color: var(--mj-text-secondary); font-size: 0.9em;\">\n Type <span style=\"color: #dc3545;\">*</span>\n </label>\n @if (isLoadingPromptTypes) {\n <div style=\"padding: 8px; color: var(--mj-text-muted); font-style: italic; width: 200px;\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading types...\n </div>\n } @else {\n <mj-dropdown [(ngModel)]=\"record.TypeID\"\n name=\"promptTypeID\"\n [Data]=\"availablePromptTypes\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n [Filterable]=\"true\"\n Placeholder=\"Select prompt type...\"\n style=\"width: 200px;\">\n </mj-dropdown>\n }\n </div>\n </div>\n }\n @if (EditMode) {\n <textarea class=\"mj-textarea\" [(ngModel)]=\"record.Description\"\n name=\"promptDescription\"\n [rows]=\"2\"\n placeholder=\"Enter prompt description...\"\n style=\"width: 100%; max-width: 600px; margin-bottom: 12px;\"></textarea>\n } @else if (record.Description) {\n <p style=\"margin: 0 0 12px 0; color: var(--mj-text-muted); font-size: 0.9em; line-height: 1.4;\">{{ record.Description }}</p>\n }\n <!-- Quick Config Row -->\n <div class=\"quick-config\" style=\"display: flex; align-items: center; gap: 16px; flex-wrap: wrap;\">\n @if (record.TypeID) {\n <div class=\"config-item\" style=\"display: flex; align-items: center; gap: 6px; font-size: 0.85em;\">\n <i class=\"fa-solid fa-tag\" style=\"color: var(--mj-text-muted);\"></i>\n <span style=\"color: var(--mj-text-muted);\">Type:</span>\n <span style=\"color: var(--mj-text-secondary); font-weight: 500;\">{{ getPromptTypeDisplayName(record.TypeID) }}</span>\n </div>\n }\n <div class=\"config-item\" style=\"display: flex; align-items: center; gap: 6px; font-size: 0.85em;\">\n <i class=\"fa-solid fa-layer-group\" style=\"color: var(--mj-text-muted);\"></i>\n <span style=\"color: var(--mj-text-muted);\">Parallelization:</span>\n <span style=\"color: var(--mj-text-secondary); font-weight: 500;\">{{ getParallelizationModeDisplay() }}</span>\n </div>\n <div class=\"config-item\" style=\"display: flex; align-items: center; gap: 6px; font-size: 0.85em;\">\n <i class=\"fa-solid fa-code\" style=\"color: var(--mj-text-muted);\"></i>\n <span style=\"color: var(--mj-text-muted);\">Output:</span>\n <span [style.color]=\"getValidationColor()\" style=\"font-weight: 500;\">{{ getOutputTypeDisplay() }}</span>\n </div>\n @if (record.EnableCaching) {\n <div class=\"config-item\" style=\"display: flex; align-items: center; gap: 6px; font-size: 0.85em;\">\n <i class=\"fa-solid fa-database\" style=\"color: #28a745;\"></i>\n <span style=\"color: #28a745; font-weight: 500;\">Caching Enabled</span>\n </div>\n }\n @if (record.EffortLevel) {\n <div class=\"config-item\" style=\"display: flex; align-items: center; gap: 6px; font-size: 0.85em;\">\n <i class=\"fa-solid fa-tachometer-alt\" style=\"color: var(--mj-text-muted);\"></i>\n <span style=\"color: var(--mj-text-muted);\">Effort Level:</span>\n <span style=\"color: var(--mj-text-secondary); font-weight: 500;\">{{ record.EffortLevel }}</span>\n </div>\n }\n </div>\n </div>\n <!-- Right: Action Buttons -->\n <div class=\"action-buttons\" style=\"display: flex; flex-direction: column; gap: 8px; align-items: flex-end;\">\n <div style=\"display: flex; gap: 8px;\">\n @if (record.ID) {\n <button mjButton variant=\"primary\" size=\"lg\"\n (click)=\"openTestHarness()\"\n title=\"Run AI Prompt Test Harness\">\n <i class=\"fa-solid fa-play\"></i> Run\n </button>\n }\n </div>\n @if (!canExecute && record.ID) {\n <div style=\"font-size: 0.75em; color: #dc3545; text-align: right; max-width: 200px;\">\n @if (record.Status !== 'Active') {\n \u2022 Prompt must be Active<br>\n }\n @if (!record.TemplateID) {\n \u2022 Template is required<br>\n }\n @if (!template && record.TemplateID) {\n \u2022 Template not found<br>\n }\n </div>\n }\n </div>\n </div>\n </div>\n <!-- Configuration Sections with Expansion Panels -->\n <div class=\"configuration-sections\" style=\"flex: 1; background: var(--mj-bg-surface-card); border-top: 2px solid var(--mj-border-default); padding: 16px; min-height: 0;\">\n <!-- Template Editor Section -->\n <mj-accordion-panel\n [Expanded]=\"true\"\n style=\"margin-bottom: 12px;\">\n <ng-template mjAccordionTitle>\n <span style=\"display: flex; align-items: center; gap: 8px; font-weight: 600;\">\n <i class=\"fa-solid fa-code\" style=\"color: var(--mj-text-muted);\"></i>\n Template Editor\n @if (template) {\n <span style=\"color: var(--mj-text-muted); font-size: 0.9em; font-weight: normal;\">• {{ template.Name }}</span>\n }\n </span>\n </ng-template>\n <!-- Direct Content Projection -->\n <div class=\"template-section\" style=\"display: flex; flex-direction: column; min-height: 400px; padding: 8px;\">\n @if (isLoadingTemplate) {\n <div class=\"loading-state\" style=\"flex: 1; display: flex; align-items: center; justify-content: center; color: var(--mj-text-muted);\">\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 24px; margin-right: 12px;\"></i>\n Loading template...\n </div>\n } @else if (!record.TemplateID) {\n <mj-empty-state class=\"no-template-state\"\n Size=\"large\"\n Icon=\"fa-solid fa-code\"\n Title=\"No Template Associated\"\n Message=\"This AI prompt needs a template to define its structure and parameters. Create a new template or link to an existing one.\">\n <div ngProjectAs=\"[actions]\" style=\"display: flex; gap: 12px;\">\n @if (UserCanCreateTemplates) {\n <button mjButton variant=\"primary\" (click)=\"createNewTemplate()\">\n <i class=\"fa-solid fa-plus\"></i> Create New Template\n </button>\n }\n @if (UserCanReadTemplates) {\n <button mjButton variant=\"outline\" (click)=\"linkExistingTemplate()\">\n <i class=\"fa-solid fa-link\"></i> Link Existing Template\n </button>\n }\n </div>\n </mj-empty-state>\n } @else if (templateNotFoundInDatabase) {\n <mj-empty-state class=\"invalid-template-state\"\n Variant=\"warning\"\n Title=\"Template Not Found\"\n Message=\"The referenced template could not be loaded. It may have been deleted or moved.\">\n <div ngProjectAs=\"[actions]\" style=\"display: flex; gap: 12px;\">\n <button mjButton variant=\"outline\" (click)=\"loadTemplate()\">\n <i class=\"fa-solid fa-arrows-rotate\"></i> Retry Loading\n </button>\n @if (UserCanCreateTemplates) {\n <button mjButton variant=\"primary\" (click)=\"createNewTemplate()\">\n <i class=\"fa-solid fa-plus\"></i> Create New Template\n </button>\n }\n </div>\n </mj-empty-state>\n } @else {\n <!-- Active Template Editor -->\n <div class=\"template-editor-container\" style=\"flex: 1; display: flex; flex-direction: column; min-height: 350px;\">\n <!-- Template Actions Bar -->\n @if (template && EditMode) {\n <div class=\"template-actions\" style=\"display: flex; gap: 8px; padding: 8px; border-bottom: 1px solid var(--mj-border-default); background: var(--mj-bg-surface-sunken);\">\n @if (UserCanUpdateTemplates) {\n <button mjButton\n variant=\"outline\"\n size=\"sm\"\n (click)=\"linkExistingTemplate()\"\n title=\"Change to a different template\">\n <i class=\"fa-solid fa-exchange-alt\"></i> Change Template\n </button>\n }\n @if (UserCanReadTemplates) {\n <button mjButton\n variant=\"outline\"\n size=\"sm\"\n (click)=\"openTemplateInNewWindow()\"\n title=\"Open template in new window\">\n <i class=\"fa-solid fa-external-link-alt\"></i> Open in New Window\n </button>\n }\n </div>\n }\n <!-- Template Editor -->\n <div style=\"flex: 1; background: var(--mj-bg-surface-card); border-radius: 6px; border: 1px solid var(--mj-border-default);\">\n <mj-template-editor\n #templateEditor\n [template]=\"template\"\n [config]=\"templateEditorConfig\"\n (contentChange)=\"onTemplateContentChange($event)\"\n (runTemplate)=\"onTemplateRun($event)\"\n style=\"display: block; min-height: 300px;\">\n </mj-template-editor>\n </div>\n </div>\n }\n </div>\n </mj-accordion-panel>\n <!-- Model Configuration Expansion Panel -->\n @if (record.IsSaved) {\n <mj-accordion-panel\n [Expanded]=\"true\"\n style=\"margin-bottom: 12px;\">\n <ng-template mjAccordionTitle>\n <span style=\"display: flex; align-items: center; gap: 8px; font-weight: 600;\">\n <i class=\"fa-solid fa-microchip\" style=\"color: var(--mj-text-muted);\"></i>\n Models\n @if (promptModels.length > 0) {\n <span class=\"mj-accordion-badge\">{{ promptModels.length }}</span>\n }\n <span style=\"color: var(--mj-text-muted); font-size: 0.8em; font-weight: normal; margin-left: 8px;\">\n <i class=\"fa-solid fa-info-circle\" title=\"Models are tried in order from top to bottom. The first available model will be used.\"></i>\n Priority order (first available model will be used)\n </span>\n </span>\n </ng-template>\n <!-- Direct Content Projection -->\n <div style=\"padding: 16px 0;\">\n <!-- Model Management Interface -->\n <div class=\"model-management\" style=\"border: 1px solid var(--mj-border-default); border-radius: 6px; background: var(--mj-bg-surface-sunken);\">\n @if (isLoadingModels) {\n <div class=\"loading-state\" style=\"padding: 20px; text-align: center; color: var(--mj-text-muted);\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading models...\n </div>\n } @else {\n @if (promptModels.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-circle-info\"\n Title=\"No models configured\">\n @if (EditMode && UserCanCreatePromptModels) {\n <button ngProjectAs=\"[actions]\" mjButton variant=\"outline\" size=\"sm\"\n (click)=\"addNewModel()\">\n <i class=\"fa-solid fa-plus\"></i> Add Model\n </button>\n }\n </mj-empty-state>\n } @else {\n <!-- Priority explanation for multiple models -->\n @if (promptModels.length > 1) {\n <div style=\"padding: 12px 16px; background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); border-bottom: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default)); color: var(--mj-brand-primary); font-size: 0.85em;\">\n <i class=\"fa-solid fa-info-circle\" style=\"margin-right: 6px;\"></i>\n Models are tried in priority order (highest priority first). The first available model that meets requirements will be used for execution.\n </div>\n }\n <!-- Column Headers -->\n <div class=\"model-header\" style=\"display: grid; grid-template-columns: 40px 2fr 1fr 1fr 1fr 60px; gap: 12px; padding: 12px 16px; background: var(--mj-bg-surface-sunken); font-weight: 600; font-size: 0.85em; color: var(--mj-text-secondary); border-bottom: 1px solid var(--mj-border-default);\">\n <div title=\"Priority order - models are tried from top to bottom\">\n <i class=\"fa-solid fa-sort\" style=\"color: var(--mj-text-muted);\"></i>\n </div>\n <div>AI Model <span style=\"color: #dc3545;\">*</span></div>\n <div>Vendor</div>\n <div>Configuration</div>\n <div>Created</div>\n <div>Actions</div>\n </div>\n @for (model of promptModels; track getModelTrackId(model) || $index; let i = $index) {\n <div class=\"model-row\"\n [draggable]=\"EditMode\"\n (dragstart)=\"onDragStart($event, i)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop($event, i)\"\n (dragend)=\"onDragEnd($event)\"\n [style.background]=\"!model.ModelID ? '#fff3cd' : (draggedIndex === i ? 'color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface))' : 'var(--mj-bg-surface-card)')\"\n [style.border-left]=\"!model.ModelID ? '3px solid #ffc107' : 'none'\"\n [style.opacity]=\"draggedIndex === i ? '0.5' : '1'\"\n style=\"display: grid; grid-template-columns: 40px 2fr 1fr 1fr 1fr 60px; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--mj-border-default); align-items: start; transition: background 0.2s, opacity 0.2s;\">\n <!-- Drag Handle / Priority -->\n <div class=\"drag-handle\" style=\"display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--mj-text-muted);\">\n @if (EditMode) {\n <i class=\"fa-solid fa-grip-vertical\" title=\"Drag to reorder priority\" style=\"cursor: move;\"></i>\n <span style=\"font-size: 0.7em; margin-top: 2px;\">#{{ i + 1 }}</span>\n } @else {\n <span style=\"font-size: 0.9em; font-weight: 600;\" title=\"Priority {{ model.Priority }} - Higher priority numbers are tried first\">#{{ i + 1 }}</span>\n }\n </div>\n <!-- Model Selection -->\n <div class=\"model-select\">\n @if (EditMode) {\n <mj-dropdown [(ngModel)]=\"model.ModelID\"\n [name]=\"'modelId_' + getModelTrackId(model)\"\n [Data]=\"availableModels\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n [Filterable]=\"true\"\n Placeholder=\"Select a model...\"\n (ValueChange)=\"onModelChange($any($event), i)\"\n style=\"width: 100%;\">\n </mj-dropdown>\n } @else {\n <span style=\"font-weight: 500;\">{{ getModelDisplayName(model.ModelID) }}</span>\n }\n </div>\n <!-- Vendor -->\n <div class=\"model-vendor\">\n @if (EditMode) {\n @if (model.ModelID) {\n @if (shouldShowVendorDropdown(model.ModelID)) {\n <mj-dropdown [(ngModel)]=\"model.VendorID\"\n [name]=\"'vendorId_' + getModelTrackId(model)\"\n [Data]=\"getVendorsForModelSync(model.ModelID)\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n [Filterable]=\"true\"\n Placeholder=\"Select vendor...\"\n style=\"width: 100%;\">\n </mj-dropdown>\n } @else {\n <!-- Single vendor - just show the name -->\n @if (getVendorsForModelSync(model.ModelID).length === 1) {\n <span [style.color]=\"getVendorStatusColor(model.ModelID, getVendorsForModelSync(model.ModelID)[0].ID)\" style=\"font-size: 0.9em; font-weight: 500;\">\n {{ getVendorsForModelSync(model.ModelID)[0].Name }}\n @if (getModelVendorStatus(model.ModelID, getVendorsForModelSync(model.ModelID)[0].ID) !== 'Active') {\n <span style=\"font-size: 0.8em; margin-left: 4px;\">({{ getModelVendorStatus(model.ModelID, getVendorsForModelSync(model.ModelID)[0].ID) }})</span>\n }\n </span>\n } @else {\n <span style=\"color: var(--mj-text-muted); font-style: italic; font-size: 0.9em;\">No vendors available</span>\n }\n }\n } @else {\n <span style=\"color: var(--mj-text-muted); font-style: italic; font-size: 0.9em;\">Select model first</span>\n }\n } @else {\n @if (model.VendorID && model.ModelID) {\n <span [style.color]=\"getVendorStatusColor(model.ModelID, model.VendorID)\" style=\"font-size: 0.9em;\">\n {{ getVendorDisplayName(model.VendorID) }}\n @if (getModelVendorStatus(model.ModelID, model.VendorID) !== 'Active') {\n <span style=\"font-size: 0.8em; margin-left: 4px;\">({{ getModelVendorStatus(model.ModelID, model.VendorID) }})</span>\n }\n </span>\n } @else {\n <span style=\"color: var(--mj-text-muted); font-size: 0.9em;\">-</span>\n }\n }\n </div>\n <!-- Configuration -->\n <div class=\"model-configuration\">\n @if (EditMode) {\n @if (isLoadingConfigurations) {\n <div style=\"padding: 4px; color: var(--mj-text-muted); font-style: italic; font-size: 0.85em;\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading...\n </div>\n } @else {\n <mj-dropdown [(ngModel)]=\"model.ConfigurationID\"\n [name]=\"'configurationId_' + getModelTrackId(model)\"\n [Data]=\"availableConfigurations\"\n TextField=\"Name\"\n ValueField=\"ID\"\n [ValuePrimitive]=\"true\"\n [Filterable]=\"true\"\n Placeholder=\"Default\"\n (ValueChange)=\"onConfigurationChange($any($event), i)\"\n style=\"width: 100%;\">\n </mj-dropdown>\n }\n } @else {\n <span style=\"font-size: 0.9em;\">{{ getConfigurationDisplayName(model.ConfigurationID) }}</span>\n }\n </div>\n <!-- Created Date -->\n <div class=\"model-created\">\n @if (model.ID) {\n <span style=\"color: var(--mj-text-muted); font-size: 0.8em;\">{{ model.__mj_CreatedAt | date:'short' }}</span>\n } @else {\n <span style=\"color: #28a745; font-size: 0.8em; font-style: italic;\">New</span>\n }\n </div>\n <!-- Actions -->\n <div class=\"model-actions\" style=\"display: flex; gap: 2px; flex-direction: column;\">\n @if (EditMode) {\n <div style=\"display: flex; gap: 2px; margin-bottom: 4px;\">\n @if (UserCanUpdatePromptModels) {\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"moveModelUp(i)\"\n [disabled]=\"i === 0\"\n title=\"Move up\">\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"moveModelDown(i)\"\n [disabled]=\"i === promptModels.length - 1\"\n title=\"Move down\">\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n }\n </div>\n @if (UserCanDeletePromptModels) {\n <button mjButton variant=\"flat\" size=\"sm\"\n (click)=\"removePromptModel(i)\"\n title=\"Remove model\"\n style=\"color: var(--mj-status-error);\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n }\n </div>\n </div>\n <!-- Second row with additional details -->\n <div style=\"display: grid; grid-template-columns: 40px 1fr; gap: 12px; padding: 8px 16px; border-bottom: 1px solid var(--mj-border-default); background: var(--mj-bg-surface-sunken); font-size: 0.85em; color: var(--mj-text-muted);\">\n <div></div>\n <div>\n <!-- Basic model details -->\n <div style=\"display: flex; gap: 16px; flex-wrap: wrap; align-items: center; margin-bottom: 8px;\">\n @if (model.Status) {\n <span><strong>Status:</strong> {{ model.Status }}</span>\n }\n </div>\n <!-- Parallel execution fields when prompt is ModelSpecific -->\n @if (record.ParallelizationMode === 'ModelSpecific') {\n <div style=\"padding: 8px; background: var(--mj-bg-surface-card); border: 1px solid var(--mj-border-default); border-radius: 4px; margin-top: 8px;\">\n <div style=\"margin-bottom: 6px; font-weight: 600; color: var(--mj-text-secondary); font-size: 0.9em;\">\n <i class=\"fa-solid fa-layer-group\"></i> Model-Specific Parallel Execution\n </div>\n @if (EditMode) {\n <div style=\"display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; align-items: center;\">\n <!-- Parallel Mode -->\n <div>\n <label style=\"display: block; margin-bottom: 2px; font-size: 0.8em; font-weight: 600; color: var(--mj-text-secondary);\">Parallel Mode</label>\n <mj-dropdown [(ngModel)]=\"model.ParallelizationMode\"\n [name]=\"'parallelMode_' + i\"\n [Data]=\"[{text: 'None', value: 'None'}, {text: 'Static Count', value: 'StaticCount'}, {text: 'Config Param', value: 'ConfigParam'}]\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n Placeholder=\"Select mode...\"\n style=\"width: 100%; font-size: 0.85em;\">\n </mj-dropdown>\n </div>\n <!-- Parallel Count (when StaticCount) -->\n @if (model.ParallelizationMode === 'StaticCount') {\n <div>\n <label style=\"display: block; margin-bottom: 2px; font-size: 0.8em; font-weight: 600; color: var(--mj-text-secondary);\">Parallel Count</label>\n <mj-numeric-input [(ngModel)]=\"model.ParallelCount\"\n [name]=\"'parallelCount_' + i\"\n [Min]=\"1\"\n [Step]=\"1\"\n [Format]=\"'n0'\"\n Placeholder=\"Count...\"\n style=\"width: 100%; font-size: 0.85em;\">\n </mj-numeric-input>\n </div>\n }\n <!-- Config Param (when ConfigParam) -->\n @if (model.ParallelizationMode === 'ConfigParam') {\n <div>\n <label style=\"display: block; margin-bottom: 2px; font-size: 0.8em; font-weight: 600; color: var(--mj-text-secondary);\">Config Parameter</label>\n <input type=\"text\" class=\"mj-input\" [(ngModel)]=\"model.ParallelConfigParam\"\n [name]=\"'parallelConfigParam_' + i\"\n placeholder=\"Parameter name...\"\n style=\"width: 100%; font-size: 0.85em;\" />\n </div>\n }\n </div>\n } @else {\n <!-- Read-only display -->\n <div style=\"display: flex; gap: 16px; flex-wrap: wrap; align-items: center;\">\n @if (model.ParallelizationMode) {\n <span><strong>Parallel Mode:</strong> {{ model.ParallelizationMode }}</span>\n }\n @if (model.ParallelCount) {\n <span><strong>Parallel Count:</strong> {{ model.ParallelCount }}</span>\n }\n @if (model.ParallelConfigParam) {\n <span><strong>Config Param:</strong> {{ model.ParallelConfigParam }}</span>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n @if (EditMode && UserCanCreatePromptModels) {\n <div class=\"add-model-row\" style=\"padding: 12px 16px; text-align: center; background: var(--mj-bg-surface-sunken); border-top: 1px solid var(--mj-border-default);\">\n <button mjButton variant=\"outline\" size=\"sm\"\n (click)=\"addNewModel()\"\n style=\"color: var(--mj-status-success); border-color: var(--mj-status-success);\">\n <i class=\"fa-solid fa-plus\"></i> Add Model\n </button>\n </div>\n }\n }\n }\n </div>\n </div>\n </mj-accordion-panel>\n }\n <!-- Advanced Configuration Expansion Panel -->\n <mj-accordion-panel\n [Expanded]=\"false\"\n style=\"margin-bottom: 12px;\">\n <ng-template mjAccordionTitle>\n <span style=\"display: flex; align-items: center; gap: 8px; font-weight: 600;\">\n <i class=\"fa-solid fa-cogs\" style=\"color: var(--mj-text-muted);\"></i>\n Advanced Configuration\n </span>\n </ng-template>\n <!-- Direct Content Projection -->\n <div style=\"padding: 16px 0;\">\n <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 20px;\">\n <!-- Left Column -->\n <div>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ParallelizationMode\"\n Type=\"dropdownlist\"\n [EditMode]=\"EditMode\">\n </mj-form-field>\n @if (showParallelCount) {\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ParallelCount\"\n Type=\"numerictextbox\"\n [EditMode]=\"EditMode\">\n </mj-form-field>\n }\n @if (showParallelConfigParam) {\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ParallelConfigParam\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\">\n </mj-form-field>\n }\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"OutputType\"\n Type=\"dropdownlist\"\n [EditMode]=\"EditMode\">\n </mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"EffortLevel\"\n Type=\"numerictextbox\"\n Caption=\"Effort Level (1-100)\"\n Description=\"Higher values request more thorough reasoning\"\n [EditMode]=\"EditMode\">\n </mj-form-field>\n </div>\n <!-- Right Column -->\n <div>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"ValidationBehavior\"\n Type=\"dropdownlist\"\n [EditMode]=\"EditMode\">\n </mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"EnableCaching\"\n Type=\"checkbox\"\n [EditMode]=\"EditMode\">\n </mj-form-field>\n <!-- Result Selector Prompt with Tree Selector -->\n <div style=\"margin-bottom: 16px;\">\n <label style=\"display: block; margin-bottom: 4px; font-weight: 600; color: var(--mj-text-secondary); font-size: 0.9em;\">\n Result Selector Prompt\n </label>\n @if (EditMode) {\n @if (isLoadingResultSelectorData) {\n <div style=\"padding: 8px; color: var(--mj-text-muted); font-style: italic;\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading prompts...\n </div>\n } @else {\n <mj-dropdown\n [(ngModel)]=\"record.ResultSelectorPromptID\"\n name=\"resultSelectorPromptID\"\n [Data]=\"resultSelectorTreeData\"\n TextField=\"text\"\n ValueField=\"value\"\n [ValuePrimitive]=\"true\"\n [Filterable]=\"true\"\n Placeholder=\"Select a result selector prompt...\"\n style=\"width: 100%;\"\n (ValueChange)=\"onResultSelectorChange($any($event))\">\n </mj-dropdown>\n }\n } @else {\n <span style=\"color: var(--mj-text-secondary);\">{{ getPromptDisplayName(record.ResultSelectorPromptID || '') || 'None selected' }}</span>\n }\n </div>\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Prefill & Output Control Expansion Panel -->\n <mj-accordion-panel\n [Expanded]=\"false\"\n style=\"margin-bottom: 12px;\">\n <ng-template mjAccordionTitle>\n <span style=\"display: flex; align-items: center; gap: 8px; font-weight: 600;\">\n <i class=\"fa-solid fa-wand-magic-sparkles\" style=\"color: var(--mj-text-muted);\"></i>\n Prefill & Output Control\n </span>\n </ng-template>\n <div style=\"padding: 16px 0;\">\n <p style=\"margin: 0 0 12px 0; font-size: 0.85em; color: var(--mj-text-muted);\">\n Assistant prefill seeds the model's response with an initial string, guiding output format and content. Stop sequences terminate generation when encountered.\n </p>\n <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 20px;\">\n <!-- Left Column -->\n <div>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"AssistantPrefill\"\n Type=\"textarea\"\n [EditMode]=\"EditMode\">\n </mj-form-field>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"StopSequences\"\n Type=\"textbox\"\n [EditMode]=\"EditMode\">\n </mj-form-field>\n </div>\n <!-- Right Column -->\n <div>\n <mj-form-field\n [Record]=\"record\"\n [ShowLabel]=\"true\"\n FieldName=\"PrefillFallbackMode\"\n Type=\"dropdownlist\"\n [EditMode]=\"EditMode\">\n </mj-form-field>\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n <!-- Template Parameters Expansion Panel -->\n @if (template && templateParams.length > 0) {\n <mj-accordion-panel\n [Expanded]=\"false\"\n style=\"margin-bottom: 12px;\">\n <ng-template mjAccordionTitle>\n <span style=\"display: flex; align-items: center; gap: 8px; font-weight: 600;\">\n <i class=\"fa-solid fa-sliders\" style=\"color: var(--mj-text-muted);\"></i>\n Template Parameters\n <span class=\"mj-accordion-badge\">{{ templateParams.length }}</span>\n <span style=\"color: var(--mj-text-muted); font-size: 0.8em; font-weight: normal; margin-left: 8px;\">\n <i class=\"fa-solid fa-info-circle\" title=\"These parameters are defined in the template and will be available when executing this prompt\"></i>\n Parameters defined in the template\n </span>\n </span>\n </ng-template>\n <!-- Template Parameters Display -->\n <div style=\"padding: 16px 0;\">\n @if (isLoadingTemplateParams) {\n <div class=\"loading-state\" style=\"padding: 20px; text-align: center; color: var(--mj-text-muted);\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i> Loading template parameters...\n </div>\n } @else if (templateParams.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-circle-info\"\n Title=\"This template has no parameters defined\" />\n } @else {\n <!-- Parameters Grid -->\n <div style=\"display: grid; gap: 12px;\">\n @for (param of templateParams; track param.ID) {\n <div class=\"parameter-card\"\n style=\"border: 1px solid var(--mj-border-default); border-radius: 8px; padding: 16px; background: var(--mj-bg-surface-sunken); transition: all 0.2s;\"\n [style.border-left]=\"'4px solid ' + getParamTypeColor(param.Type)\">\n <!-- Parameter Header -->\n <div style=\"display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 8px;\">\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <i [class]=\"'fa-solid ' + getParamTypeIcon(param.Type)\"\n [style.color]=\"getParamTypeColor(param.Type)\"\n style=\"font-size: 1.2em;\"></i>\n <h6 style=\"margin: 0; color: var(--mj-text-secondary); font-weight: 600;\">\n {{ param.Name }}\n @if (param.IsRequired) {\n <span style=\"color: #dc3545; font-size: 0.9em; margin-left: 4px;\">*</span>\n }\n </h6>\n </div>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <span class=\"type-badge\"\n [style.background-color]=\"getParamTypeColor(param.Type)\"\n style=\"color: white; padding: 4px 8px; border-radius: 12px; font-size: 0.75em; font-weight: 500;\">\n {{ param.Type }}\n </span>\n @if (param.IsRequired) {\n <span style=\"color: #dc3545; font-size: 0.85em; font-weight: 500;\">Required</span>\n } @else {\n <span style=\"color: var(--mj-text-muted); font-size: 0.85em;\">Optional</span>\n }\n </div>\n </div>\n <!-- Parameter Description -->\n @if (param.Description) {\n <p style=\"margin: 0 0 8px 0; color: var(--mj-text-muted); font-size: 0.9em; line-height: 1.4;\">\n {{ param.Description }}\n </p>\n }\n <!-- Type-specific Information -->\n <div style=\"font-size: 0.85em; color: var(--mj-text-secondary);\">\n <span style=\"display: flex; align-items: center; gap: 4px; margin-bottom: 4px;\">\n <i class=\"fa-solid fa-info-circle\" style=\"color: var(--mj-text-muted);\"></i>\n {{ getParamTypeDescription(param) }}\n </span>\n </div>\n <!-- Additional Parameter Details -->\n <div style=\"display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 12px; margin-top: 12px;\">\n @if (param.DefaultValue) {\n <div style=\"background: var(--mj-bg-surface-card); padding: 8px 12px; border-radius: 4px; border: 1px solid var(--mj-border-default);\">\n <label style=\"display: block; font-size: 0.8em; color: var(--mj-text-muted); margin-bottom: 2px;\">Default Value</label>\n <code style=\"font-size: 0.85em; color: var(--mj-text-secondary); word-break: break-all;\">{{ param.DefaultValue }}</code>\n </div>\n }\n @if (param.EntityID) {\n <div style=\"background: var(--mj-bg-surface-card); padding: 8px 12px; border-radius: 4px; border: 1px solid var(--mj-border-default);\">\n <label style=\"display: block; font-size: 0.8em; color: var(--mj-text-muted); margin-bottom: 2px;\">Entity</label>\n <span style=\"font-size: 0.85em; color: var(--mj-text-secondary);\">{{ param.Entity || 'Entity ID: ' + param.EntityID }}</span>\n </div>\n }\n @if (param.LinkedParameterName) {\n <div style=\"background: var(--mj-bg-surface-card); padding: 8px 12px; border-radius: 4px; border: 1px solid var(--mj-border-default);\">\n <label style=\"display: block; font-size: 0.8em; color: var(--mj-text-muted); margin-bottom: 2px;\">Linked To</label>\n <span style=\"font-size: 0.85em; color: var(--mj-text-secondary);\">\n {{ param.LinkedParameterName }}\n @if (param.LinkedParameterField) {\n ({{ param.LinkedParameterField }})\n }\n </span>\n </div>\n }\n @if (param.ExtraFilter) {\n <div style=\"background: var(--mj-bg-surface-card); padding: 8px 12px; border-radius: 4px; border: 1px solid var(--mj-border-default);\">\n <label style=\"display: block; font-size: 0.8em; color: var(--mj-text-muted); margin-bottom: 2px;\">Filter</label>\n <code style=\"font-size: 0.8em; color: var(--mj-text-secondary); word-break: break-all;\">{{ param.ExtraFilter }}</code>\n </div>\n }\n @if (param.RecordID) {\n <div style=\"background: var(--mj-bg-surface-card); padding: 8px 12px; border-radius: 4px; border: 1px solid var(--mj-border-default);\">\n <label style=\"display: block; font-size: 0.8em; color: var(--mj-text-muted); margin-bottom: 2px;\">Record ID</label>\n <code style=\"font-size: 0.85em; color: var(--mj-text-secondary);\">{{ param.RecordID }}</code>\n </div>\n }\n </div>\n </div>\n }\n </div>\n <!-- Help Text -->\n <div style=\"margin-top: 16px; padding: 12px; background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface)); border-radius: 6px; border: 1px solid color-mix(in srgb, var(--mj-brand-primary) 25%, var(--mj-border-default));\">\n <div style=\"display: flex; align-items: flex-start; gap: 8px;\">\n <i class=\"fa-solid fa-lightbulb\" style=\"color: var(--mj-brand-primary); margin-top: 2px;\"></i>\n <div style=\"flex: 1; font-size: 0.85em; color: var(--mj-brand-primary); line-height: 1.5;\">\n <strong>Using Template Parameters:</strong> When executing this prompt, you'll be prompted to provide values for all required parameters.\n Parameters can be simple values (text, numbers) or complex data structures (JSON objects, database records, or entire entity collections).\n The template will use these parameters to generate dynamic content based on the values provided at execution time.\n </div>\n </div>\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Output Example Expansion Panel (when OutputType = object) -->\n @if (showOutputExample) {\n <mj-accordion-panel\n [Expanded]=\"true\"\n style=\"margin-bottom: 12px;\">\n <ng-template mjAccordionTitle>\n <span style=\"display: flex; align-items: center; gap: 8px; font-weight: 600;\">\n <i class=\"fa-solid fa-code\" style=\"color: var(--mj-text-muted);\"></i>\n Output Example (JSON)\n <span style=\"color: #dc3545; font-size: 0.8em; font-weight: normal;\">• Required for object output type</span>\n </span>\n </ng-template>\n <!-- Direct Content Projection -->\n <div style=\"padding: 16px;\">\n @if (EditMode) {\n <mj-code-editor\n [(ngModel)]=\"record.OutputExample\"\n name=\"outputExample\"\n language=\"json\"\n placeholder=\"Enter JSON example structure...\"\n style=\"width: 100%; height: 200px; border: 1px solid var(--mj-border-default); border-radius: 4px;\">\n </mj-code-editor>\n <div style=\"margin-top: 8px; color: var(--mj-text-muted); font-size: 0.85em;\">\n <i class=\"fa-solid fa-info-circle\"></i> Provide a JSON example that defines the expected structure for object output validation.\n </div>\n } @else if (record.OutputExample) {\n <div style=\"background: var(--mj-bg-surface-sunken); border: 1px solid var(--mj-border-default); border-radius: 4px; padding: 12px; font-family: 'Courier New', monospace; font-size: 0.9em; white-space: pre-wrap; overflow: auto; max-height: 250px;\">{{ record.OutputExample }}</div>\n } @else {\n <mj-alert Variant=\"warning\">Output example is required when output type is 'object'</mj-alert>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Execution History Expansion Panel -->\n @if (record.IsSaved) {\n <mj-accordion-panel\n [Expanded]=\"false\"\n style=\"margin-bottom: 12px;\">\n <ng-template mjAccordionTitle>\n <span style=\"display: flex; align-items: center; gap: 8px; font-weight: 600;\">\n <i class=\"fa-solid fa-history\" style=\"color: var(--mj-text-muted);\"></i>\n Execution History\n @if (executionHistory.length > 0) {\n <span style=\"color: var(--mj-text-muted); font-weight: normal;\">({{ executionHistory.length }})</span>\n }\n </span>\n </ng-template>\n <!-- Custom Execution History Viewer -->\n <div style=\"padding: 16px;\">\n @if (isLoadingHistory) {\n <div style=\"text-align: center; padding: 40px; color: var(--mj-text-muted);\">\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"font-size: 2em; margin-bottom: 12px;\"></i>\n <p>Loading execution history...</p>\n </div>\n } @else if (executionHistory.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-clock-rotate-left\"\n Title=\"No execution history yet\"\n Message=\"Run this prompt to see execution history here\" />\n } @else {\n <!-- Sort Controls -->\n <div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;\">\n <div style=\"color: var(--mj-text-muted); font-size: 0.9em;\">\n Showing {{ executionHistory.length }} executions\n </div>\n <div style=\"display: flex; gap: 8px; align-items: center;\">\n <span style=\"color: var(--mj-text-muted); font-size: 0.85em;\">Sort by:</span>\n <div class=\"mj-button-group\">\n <button mjButton\n [class.active]=\"historySortField === 'runAt'\"\n (click)=\"changeHistorySort('runAt')\"\n size=\"sm\">\n Date\n @if (historySortField === 'runAt') {\n <i [class]=\"'fa-solid fa-sort-' + (historySortDirection === 'asc' ? 'up' : 'down')\"\n style=\"margin-left: 4px; font-size: 0.8em;\"></i>\n }\n </button>\n <button mjButton\n [class.active]=\"historySortField === 'executionTime'\"\n (click)=\"changeHistorySort('executionTime')\"\n size=\"sm\">\n Duration\n @if (historySortField === 'executionTime') {\n <i [class]=\"'fa-solid fa-sort-' + (historySortDirection === 'asc' ? 'up' : 'down')\"\n style=\"margin-left: 4px; font-size: 0.8em;\"></i>\n }\n </button>\n <button mjButton\n [class.active]=\"historySortField === 'tokens'\"\n (click)=\"changeHistorySort('tokens')\"\n size=\"sm\">\n Tokens\n @if (historySortField === 'tokens') {\n <i [class]=\"'fa-solid fa-sort-' + (historySortDirection === 'asc' ? 'up' : 'down')\"\n style=\"margin-left: 4px; font-size: 0.8em;\"></i>\n }\n </button>\n <button mjButton\n [class.active]=\"historySortField === 'cost'\"\n (click)=\"changeHistorySort('cost')\"\n size=\"sm\">\n Cost\n @if (historySortField === 'cost') {\n <i [class]=\"'fa-solid fa-sort-' + (historySortDirection === 'asc' ? 'up' : 'down')\"\n style=\"margin-left: 4px; font-size: 0.8em;\"></i>\n }\n </button>\n </div>\n </div>\n </div>\n <!-- Execution History Table -->\n <div style=\"border: 1px solid var(--mj-border-default); border-radius: 8px; overflow: hidden;\">\n <table style=\"width: 100%; border-collapse: collapse;\">\n <thead>\n <tr style=\"background: var(--mj-bg-surface-sunken); border-bottom: 2px solid var(--mj-border-default);\">\n <th style=\"padding: 12px; text-align: left; font-weight: 600; color: var(--mj-text-secondary);\">Status</th>\n <th style=\"padding: 12px; text-align: left; font-weight: 600; color: var(--mj-text-secondary);\">Date & Time</th>\n <th style=\"padding: 12px; text-align: left; font-weight: 600; color: var(--mj-text-secondary);\">Model</th>\n <th style=\"padding: 12px; text-align: left; font-weight: 600; color: var(--mj-text-secondary);\">Duration</th>\n <th style=\"padding: 12px; text-align: right; font-weight: 600; color: var(--mj-text-secondary);\">Tokens</th>\n <th style=\"padding: 12px; text-align: right; font-weight: 600; color: var(--mj-text-secondary);\">Cost</th>\n <th style=\"padding: 12px; text-align: center; font-weight: 600; color: var(--mj-text-secondary);\">Type</th>\n <th style=\"padding: 12px; text-align: center; font-weight: 600; color: var(--mj-text-secondary);\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (run of executionHistory; track run.ID; let i = $index) {\n <tr class=\"history-row\"\n [class.even-row]=\"i % 2 === 0\"\n style=\"border-bottom: 1px solid var(--mj-border-default);\">\n <td style=\"padding: 12px;\">\n <span style=\"display: flex; align-items: center; gap: 6px;\">\n <i [class]=\"'fa-solid ' + getExecutionStatusIcon(run.Success)\"\n [style.color]=\"getExecutionStatusColor(run.Success)\"></i>\n <span [style.color]=\"getExecutionStatusColor(run.Success)\" style=\"font-weight: 500;\">\n {{ run.Success === true ? 'Success' : run.Success === false ? 'Failed' : 'Running' }}\n </span>\n </span>\n </td>\n <td style=\"padding: 12px; color: var(--mj-text-secondary);\">\n {{ run.RunAt | date:'short' }}\n </td>\n <td style=\"padding: 12px; color: var(--mj-text-secondary);\">\n <span style=\"display: flex; align-items: center; gap: 6px;\">\n <i class=\"fa-solid fa-microchip\" style=\"color: var(--mj-text-muted);\"></i>\n {{ run.Model || 'Unknown' }}\n </span>\n </td>\n <td style=\"padding: 12px; color: var(--mj-text-secondary);\">\n {{ formatDuration(run.ExecutionTimeMS) }}\n </td>\n <td style=\"padding: 12px; text-align: right; color: var(--mj-text-secondary);\">\n {{ formatTokens(run.TokensUsed) }}\n </td>\n <td style=\"padding: 12px; text-align: right; color: var(--mj-text-secondary);\">\n {{ formatCost(run.TotalCost || run.Cost) }}\n </td>\n <td style=\"padding: 12px; text-align: center;\">\n @if (run.RunType) {\n <span style=\"padding: 4px 8px; border-radius: 12px; background: var(--mj-bg-surface-sunken); \n color: var(--mj-text-secondary); font-size: 0.85em; font-weight: 500;\">\n {{ run.RunType }}\n </span>\n }\n </td>\n <td style=\"padding: 12px; text-align: center;\">\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n (click)=\"navigateToPromptRun(run.ID)\"\n title=\"View details\">\n <i class=\"fa-solid fa-external-link\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n </mj-accordion-panel>\n }\n <!-- Cache Expansion Panel -->\n @if (record.IsSaved && record.EnableCaching) {\n <mj-accordion-panel\n [Expanded]=\"false\"\n style=\"margin-bottom: 12px;\">\n <ng-template mjAccordionTitle>\n <span style=\"display: flex; align-items: center; gap: 8px; font-weight: 600;\">\n <i class=\"fa-solid fa-database\" style=\"color: var(--mj-text-muted);\"></i>\n Result Cache\n </span>\n </ng-template>\n <!-- Direct Content Projection -->\n <div style=\"padding: 16px 0;\">\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: AI Result Cache','AIPromptID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: AI Result Cache')\"\n [AllowLoad]=\"true\"\n [ShowToolbar]=\"false\">\n </mj-explorer-entity-data-grid>\n </div>\n </mj-accordion-panel>\n }\n <!-- Related Items Expansion Panel -->\n @if (record.IsSaved) {\n <mj-accordion-panel\n [Expanded]=\"false\"\n style=\"margin-bottom: 12px;\">\n <ng-template mjAccordionTitle>\n <span style=\"display: flex; align-items: center; gap: 8px; font-weight: 600;\">\n <i class=\"fa-solid fa-link\" style=\"color: var(--mj-text-muted);\"></i>\n Related Items\n </span>\n </ng-template>\n <!-- Direct Content Projection -->\n <div style=\"padding: 16px 0;\">\n <div style=\"display: grid; grid-template-columns: 1fr 1fr; gap: 20px;\">\n <!-- AI Agents -->\n <div>\n <h6 style=\"margin: 0 0 12px 0; color: var(--mj-text-secondary);\">AI Agents Using This Prompt</h6>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: AI Agent Prompts','PromptID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: AI Agent Prompts')\"\n [AllowLoad]=\"true\"\n [ShowToolbar]=\"false\">\n </mj-explorer-entity-data-grid>\n </div>\n <!-- Result Selector References -->\n <div>\n <h6 style=\"margin: 0 0 12px 0; color: var(--mj-text-secondary);\">Prompts Using This as Result Selector</h6>\n <mj-explorer-entity-data-grid\n [Params]=\"BuildRelationshipViewParamsByEntityName('MJ: AI Prompts','ResultSelectorPromptID')\"\n [NewRecordValues]=\"NewRecordValues('MJ: AI Prompts')\"\n [AllowLoad]=\"true\"\n [ShowToolbar]=\"false\">\n </mj-explorer-entity-data-grid>\n </div>\n </div>\n </div>\n </mj-accordion-panel>\n }\n </div>\n </div>\n </form>\n</mj-record-form-container>\n}\n\n\n<!-- AI Prompt Test Harness -->\n@if (showTestHarness) {\n <mj-window\n [Width]=\"1200\"\n [Height]=\"800\"\n [MinWidth]=\"800\"\n [MinHeight]=\"600\"\n [Draggable]=\"true\"\n [Resizable]=\"true\"\n [Visible]=\"true\"\n (Close)=\"onTestHarnessVisibilityChanged(false)\"\n [Title]=\"'Run AI Prompt - ' + (record.Name || 'Untitled')\">\n <mj-ai-test-harness\n [entity]=\"record\"\n [mode]=\"'prompt'\"\n [isVisible]=\"showTestHarness\"\n (visibilityChange)=\"onTestHarnessVisibilityChanged($event)\">\n </mj-ai-test-harness>\n </mj-window>\n}", styles: ["/* Override shared form-styles to enable flex layout */\n:host {\n display: block;\n height: 100%;\n}\n\n.record-form-container {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n padding: 10px;\n display: flex;\n flex-direction: column;\n height: 100%;\n min-height: 0;\n overflow: hidden;\n}\n\n.record-form {\n min-height: 0 !important;\n}\n\n.custom-toolbar-actions {\n margin-left: auto;\n}\n\n.status-badge {\n font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n font-weight: 500;\n letter-spacing: 0.02em;\n}\n\n.config-summary {\n position: sticky;\n top: 0;\n max-height: 600px;\n overflow-y: auto;\n}\n\n.config-item {\n padding: 8px 0;\n border-bottom: 1px solid var(--mj-border-default);\n}\n\n.config-item:last-child {\n border-bottom: none;\n}\n\n.template-tab-content {\n background: var(--mj-bg-surface);\n}\n\n.template-header h5 {\n font-size: 1.1em;\n}\n\n.loading-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n}\n\n/* Template-editor placeholders fill the editor pane */\nmj-empty-state.no-template-state,\nmj-empty-state.invalid-template-state {\n flex: 1;\n}\n\n.template-editor-container {\n background: var(--mj-bg-surface);\n border-radius: var(--mj-radius-md);\n}\n\n/* Grid layout adjustments */\n@media (max-width: 1200px) {\n .record-form-container .mj-tab-body > div {\n grid-template-columns: 1fr !important;\n gap: 20px;\n }\n\n .config-summary {\n order: -1;\n position: static;\n max-height: none;\n }\n}\n\n/* Responsive toolbar */\n@media (max-width: 768px) {\n .custom-toolbar-actions {\n flex-direction: column;\n gap: 4px !important;\n }\n\n .status-badge {\n align-self: flex-start;\n }\n}\n\n/* Ensure proper spacing in form sections */\n.record-form-container mj-form-section {\n padding: 16px;\n}\n\n/* Smooth transitions for better UX */\n.status-badge,\n.config-item,\n.template-header {\n transition: all 0.2s ease;\n}\n\n.config-item:hover {\n background-color: var(--mj-bg-surface-sunken);\n border-radius: var(--mj-radius-sm);\n margin: 0 -8px;\n padding: 8px;\n}\n\n/* Execution History Table Styles */\n.history-row {\n transition: background 0.2s;\n}\n\n.history-row:not(.even-row) {\n background: var(--mj-bg-surface-card);\n}\n\n.history-row.even-row {\n background: var(--mj-bg-surface);\n}\n\n.history-row:hover {\n background: var(--mj-border-default) !important;\n}\n\n/* Template Parameters Styles */\n.parameter-card {\n position: relative;\n overflow: hidden;\n}\n\n.parameter-card::before {\n content: '';\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 4px;\n background: inherit;\n transition: width 0.2s;\n}\n\n.parameter-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--mj-shadow-md);\n}\n\n.parameter-card:hover::before {\n width: 6px;\n}\n\n.type-badge {\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n transition: transform 0.2s;\n}\n\n.parameter-card:hover .type-badge {\n transform: scale(1.05);\n}\n\n/* Parameter type icons animation */\n.parameter-card i.fa-solid {\n transition: transform 0.3s;\n}\n\n.parameter-card:hover i.fa-solid {\n transform: rotate(360deg);\n}\n\n/* Grid responsive behavior */\n@media (max-width: 768px) {\n .parameter-card {\n margin-bottom: 8px;\n }\n\n .parameter-card h6 {\n font-size: 0.95em;\n }\n\n .type-badge {\n font-size: 0.7em !important;\n }\n}\n"] }]
|
|
3030
|
-
}], null, {
|
|
3478
|
+
}], null, { TemplateEditor: [{
|
|
3031
3479
|
type: ViewChild,
|
|
3032
3480
|
args: ['templateEditor']
|
|
3033
3481
|
}] }); })();
|