@givolt/i3-composer-agent 2.2.2 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +1 -1
- package/.claude/commands/i3-prototype.md +23 -0
- package/.claude/commands/i3-review.md +1 -1
- package/.claude/commands/i3-ship.md +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.gemini/commands/i3-prototype.toml +23 -0
- package/.gemini/commands/i3-review.toml +1 -1
- package/.gemini/commands/i3-ship.toml +1 -1
- package/README.md +42 -25
- package/agents/code-reviewer.md +1 -1
- package/agents/test-engineer.md +1 -1
- package/bin/i3-composer-agent.cjs +5 -4
- package/bin/install.cjs +22 -10
- package/bin/native-command-validation.cjs +8 -13
- package/bin/native-layout.cjs +64 -28
- package/bin/native-migration.cjs +13 -7
- package/bin/native-runtime.cjs +10 -5
- package/commands/i3-prototype.toml +23 -0
- package/commands/i3-review.toml +1 -1
- package/commands/i3-ship.toml +1 -1
- package/docs/advanced-per-agent-configuration.md +78 -0
- package/docs/agents.md +2 -2
- package/docs/codebuddy-setup.md +5 -5
- package/docs/codex-setup.md +3 -3
- package/docs/copilot-setup.md +4 -0
- package/docs/cursor-setup.md +3 -0
- package/docs/other-hosts.md +44 -9
- package/docs/workbuddy-setup.md +9 -9
- package/evals/README.md +28 -16
- package/evals/cases/i3-documentation-and-adrs.json +18 -0
- package/evals/cases/i3-test-driven-development.json +8 -0
- package/evals/cases/i3-ui-prototype.json +49 -0
- package/evals/fixtures/i3-documentation-and-adrs/prose-review/README.md +19 -0
- package/evals/fixtures/i3-documentation-and-adrs/prose-review/queue.js +32 -0
- package/evals/fixtures/i3-ui-prototype/business-brief.md +7 -0
- package/evals/plugin/tdd-fires-on-pasted-bug/graders/failing-test-first.md +7 -0
- package/evals/plugin/tdd-fires-on-pasted-bug/graders/skill-fired.md +5 -0
- package/evals/plugin/tdd-fires-on-pasted-bug/prompt.md +15 -0
- package/evals/plugin/tdd-stays-quiet-on-debug/graders/not-fired.md +8 -0
- package/evals/plugin/tdd-stays-quiet-on-debug/prompt.md +25 -0
- package/evals/zh-CN/cases/i3-documentation-and-adrs.json +19 -0
- package/evals/zh-CN/cases/i3-test-driven-development.json +4 -0
- package/evals/zh-CN/cases/i3-ui-prototype.json +50 -0
- package/hooks/SIMPLIFY-IGNORE.md +3 -2
- package/hooks/simplify-ignore-test.sh +93 -1
- package/hooks/simplify-ignore.sh +94 -11
- package/package.json +63 -18
- package/plugin.json +1 -1
- package/references/performance-checklist.md +4 -2
- package/scripts/enterprise-template-test.js +139 -0
- package/scripts/floor-guard-reference-test.js +291 -0
- package/scripts/lib/skill-lint-test.js +762 -0
- package/scripts/lib/skill-lint.js +62 -8
- package/scripts/run-evals-test.js +830 -0
- package/scripts/run-evals.js +47 -9
- package/scripts/run-regressions.js +19 -0
- package/scripts/template-adapter-test.js +155 -0
- package/scripts/ui-prototype-test.js +114 -0
- package/scripts/validate-artifact-paths-test.js +179 -0
- package/scripts/validate-commands-test.js +246 -0
- package/scripts/validate-commands.js +6 -16
- package/scripts/validate-reference-links-test.js +513 -0
- package/scripts/validate-reference-links.js +4 -2
- package/scripts/validate-skills.js +26 -3
- package/scripts/validate-versions-test.js +32 -0
- package/skills/i3-documentation-and-adrs/SKILL.md +9 -0
- package/skills/i3-frontend-ui-engineering/SKILL.md +5 -1
- package/skills/i3-idea-refine/SKILL.md +20 -5
- package/skills/i3-incremental-implementation/SKILL.md +4 -0
- package/skills/i3-performance-optimization/SKILL.md +10 -10
- package/skills/i3-security-and-hardening/references/hardening-patterns.md +1 -1
- package/skills/i3-shipping-and-launch/SKILL.md +6 -0
- package/skills/i3-test-driven-development/SKILL.md +3 -3
- package/skills/i3-ui-prototype/SKILL.md +119 -0
- package/skills/i3-ui-prototype/assets/templates/catalog.json +147 -0
- package/skills/i3-ui-prototype/assets/templates/classic-admin/manifest.json +9 -0
- package/skills/i3-ui-prototype/assets/templates/classic-admin/preset.json +6 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/app.mjs +89 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/config.json +1 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/domain.mjs +20 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/index.html +17 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/serve.cjs +16 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/styles.css +670 -0
- package/skills/i3-ui-prototype/assets/templates/common/app/tokens.css +19 -0
- package/skills/i3-ui-prototype/assets/templates/common/design-system/master.md +20 -0
- package/skills/i3-ui-prototype/assets/templates/common/gallery.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/common/mocks/applications.json +5 -0
- package/skills/i3-ui-prototype/assets/templates/common/requirements-map.json +8 -0
- package/skills/i3-ui-prototype/assets/templates/common/serve-gallery.cjs +16 -0
- package/skills/i3-ui-prototype/assets/templates/credits.md +17 -0
- package/skills/i3-ui-prototype/assets/templates/data-operations/manifest.json +9 -0
- package/skills/i3-ui-prototype/assets/templates/data-operations/preset.json +6 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/design-system.md +32 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/index.html +29 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/manifest.json +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/origin.json +344 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/preset.json +928 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/app.js +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/empty.svg +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/reference-styles.json +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-403.svg +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-404.svg +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets-manifest.json +334 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/baseline.json +173 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/conversion.md +30 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/credits.md +17 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/design-tokens.json +881 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/index.html +28 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/@qin-ui-antdv-next-pro.txt +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/ant-design-icons.txt +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/antdv-next.txt +21 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/package.json +12 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/browser-routes.json +298 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/coverage.json +180 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/integrity.json +13 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/keyboard.json +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/responsive.json +125 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/review.md +51 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/rules.log +150 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-html.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-original.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-html.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-original.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-html.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-original.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-html.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-original.png +0 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/selection.json +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/visual-comparison.json +342 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/readme.md +73 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/reference.md +59 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/routes.json +178 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/controls.js +99 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dialogs.js +54 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dom.js +264 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/forms.js +47 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/icons.js +41 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/layout.js +47 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/router.js +63 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/state.js +90 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/table.js +41 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/widgets.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.js +36 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.js +51 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.js +48 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.js +6 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.js +13 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/data.js +24 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/domain.js +32 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/registry.js +25 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/store.js +85 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.js +17 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.js +66 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.js +38 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.js +66 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.js +5 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.js +12 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.js +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.js +116 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.js +32 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.js +49 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.js +10 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.js +77 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/data.js +60 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/domain.js +105 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/store.js +212 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.js +18 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js +23 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js +78 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js +55 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.js +26 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.js +38 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js +7 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.js +72 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.js +46 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js +52 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.js +19 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js +30 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/data.js +48 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/domain.js +39 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/store.js +129 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.js +21 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.js +10 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.js +49 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.js +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.js +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/commands.js +82 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/examples.js +47 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/model.js +61 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/repair.js +68 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/store.js +55 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/types.js +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/workbench.js +18 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.js +28 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.js +18 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.js +31 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.js +27 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.js +16 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.js +43 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.js +34 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.js +30 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.js +67 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.js +41 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.js +31 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.js +26 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.js +70 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/data.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/domain.js +62 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/management.js +36 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js +49 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/store.js +132 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js +38 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.js +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js +45 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.js +54 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js +27 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js +12 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js +45 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js +38 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/domain.js +61 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/state.js +51 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/store.js +116 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.js +45 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.js +30 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.js +67 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.js +5 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.js +60 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/commands.js +157 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/model.js +136 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/store.js +76 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.js +26 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.js +14 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.js +113 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.js +62 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/commands.js +97 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/model.js +147 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/store.js +13 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.js +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.js +17 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/columns.js +32 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryGuide.js +49 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryView.js +12 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listBatch.js +15 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listSelection.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/policy.js +68 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/session.js +44 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.js +25 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.js +53 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.html +10 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.js +30 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.js +10 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.js +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/confirmation.js +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/navigation.js +19 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.js +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.js +32 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.js +15 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.js +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.js +57 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/data.js +20 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/domain.js +55 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/store.js +151 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.js +18 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.js +40 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.js +51 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.js +9 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.html +5 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.js +48 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/domain.js +204 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/exampleSource.js +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/registry.js +135 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/store.js +137 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.html +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.js +36 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/model.js +56 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/store.js +15 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.js +27 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.html +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.js +31 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.html +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.js +68 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.html +5 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.js +55 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/data.js +16 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/domain.js +83 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/registry.js +18 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/store.js +61 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/admin.css +60 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/agents.css +46 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/antdv.css +295 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/app.css +102 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/delivery.css +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/intents.css +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/native.css +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/operations.css +2 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pbc.css +3 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/permissions.css +22 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pro.css +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/releases.css +4 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reset.css +246 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reviews.css +8 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tasks.css +6 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tokens.css +15 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workbench.css +61 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workflows.css +1 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/admin-rules.test.js +96 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/agents.test.js +14 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/intent-state.test.js +37 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/list-batch.test.js +44 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-fixtures.js +19 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-repair.test.js +14 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operations.test.js +25 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-management.test.js +17 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-state.test.js +24 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permission-config.test.js +23 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permissions.test.js +24 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/releases.test.js +50 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/reviews.test.js +36 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-forms-router.test.js +28 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-state.test.js +42 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-stores.test.js +16 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/spec-state.test.js +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/tasks.test.js +27 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workbench.test.js +34 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workflows.test.js +16 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/convert.mjs +168 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/serve.mjs +7 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/styles.mjs +11 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/verify.mjs +24 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/serve.cjs +16 -0
- package/skills/i3-ui-prototype/assets/templates/enterprise-admin/usability.css +44 -0
- package/skills/i3-ui-prototype/assets/templates/gallery/index.html +40 -0
- package/skills/i3-ui-prototype/assets/templates/modern-workspace/manifest.json +9 -0
- package/skills/i3-ui-prototype/assets/templates/modern-workspace/preset.json +6 -0
- package/skills/i3-ui-prototype/assets/templates/serve-gallery.cjs +16 -0
- package/skills/i3-ui-prototype/references/artifact-contract.md +41 -0
- package/skills/i3-ui-prototype/references/enterprise-admin.md +38 -0
- package/skills/i3-ui-prototype/references/expert-adapter.md +42 -0
- package/skills/i3-ui-prototype/references/template-adapters.md +57 -0
- package/skills/i3-ui-prototype/references/workflow-contract.md +19 -0
- package/skills/i3-ui-prototype/scripts/adapters/easel-html.cjs +30 -0
- package/skills/i3-ui-prototype/scripts/adapters/legacy-html.cjs +28 -0
- package/skills/i3-ui-prototype/scripts/check-design-provider.cjs +9 -0
- package/skills/i3-ui-prototype/scripts/check-prototype.cjs +14 -0
- package/skills/i3-ui-prototype/scripts/enterprise-template.cjs +88 -0
- package/skills/i3-ui-prototype/scripts/init-prototype.cjs +8 -0
- package/skills/i3-ui-prototype/scripts/manage-baseline.cjs +11 -0
- package/skills/i3-ui-prototype/scripts/prototype-lib.cjs +255 -0
- package/skills/i3-ui-prototype/scripts/template-adapters.cjs +89 -0
- package/skills/i3-using-agent-skills/SKILL.md +5 -0
- package/bin/native-version-validation.cjs +0 -8
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/ModelDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="Drawer" data-bind-open="(true)" title="模型详情" data-bind-size="(760)" data-on-close="(emit('close'))"><div class="detail-heading"><div><h2>{{ (model.name) }}</h2><p class="mono muted">{{ (model.alias) }}</p></div><template data-component="ModelStatus" data-bind-model="(model)"></template></div><template data-component="Space" wrap="" class="detail-tags"><template data-component="Tag">平台统一接入</template><template data-component="Tag" data-each="cap in (model.capabilities)" data-bind-key="(cap)">{{ (cap) }}</template></template><template data-component="Descriptions" data-bind-items="(items)" data-bind-column="({ xs: 1, sm: 2, md: 2, lg: 2, xl: 2, xxl: 2 })" size="middle" bordered=""></template><section data-if="(session.readable('model:view', 'platform'))" class="drawer-section"><div class="section-heading"><h2>配置发布</h2><template data-component="Button" type="link" data-on-click="(emit('action', 'release', model))">查看发布</template></div><template data-component="Alert" show-icon="" data-bind-type="(model.publishState === 'failed' ? 'error' : 'info')" data-bind-title="('配置 v' + model.version + ' · ' + ({ draft: '待测试或发布', review: '评审中', published: '已发布', failed: '发布失败' }[model.publishState]))" data-bind-description="(model.liveVersion !== model.version ? '当前生效配置与草稿分别保留,新草稿不会自动覆盖当前运行版本。' : '当前配置已经发布,启停状态单独管理。')"></template></section><section class="drawer-section"><div class="section-heading"><h2>使用授权</h2><template data-component="Button" type="link" data-bind-disabled="(!session.can('model:grant', 'platform'))" data-on-click="(emit('action', 'grant', model))">管理授权</template></div><div data-each="g in (model.grants)" data-bind-key="(g.tenantId)" class="grant-scope"><h3>{{ (tenantLabel(g.tenantId)) }}</h3><p><template data-component="Tag" data-each="project in (g.projects)" data-bind-key="(project)">{{ (project) }}</template></p><p class="muted">Agent:{{ (g.agents.map(modelAgentLabel).join('、') || '未授权') }}</p></div><p data-if="(!model.grants.length)" class="muted">尚未分配使用授权</p><p>共享月额度:{{ (fmtNumber(model.quota)) }} Token</p></section><section data-if="(session.readable('model:view', 'platform'))" class="drawer-section"><div class="section-heading"><h2>资源引用 · {{ (model.references.length) }}</h2><template data-component="Button" type="link" data-on-click="(emit('action', 'references', model))">查看引用</template></div><p class="muted">{{ (model.references.length ? '被引用的模型不能直接删除,请先调整关联资源。' : '当前没有资源引用。') }}</p></section><template data-component="RecordMetadata" data-bind-record="(model)"></template><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-on-click="(emit('close'))">关闭</template><template data-component="Space"><template data-component="Button" data-bind-disabled="(!session.can('model:edit', 'platform') || model.publishState === 'review')" data-on-click="(emit('action', 'edit', model))">编辑配置</template><template data-component="Button" type="primary" data-bind-disabled="(!session.can('model:test', 'platform') || model.publishState === 'review')" data-on-click="(emit('action', 'test', model))">连接测试</template></template></div></template></template>
|
package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { modelAgentLabel } from "../agents/registry.js";
|
|
2
|
+
import { Drawer, Descriptions, Tag, Button, Space, Alert } from "../../runtime/widgets.js";
|
|
3
|
+
import { computed } from '../../runtime/state.js';
|
|
4
|
+
import { h } from '../../runtime/dom.js';
|
|
5
|
+
import { fmtNumber } from "./data.js";
|
|
6
|
+
import { useSession } from "../shared/session.js";
|
|
7
|
+
import { tenantLabel } from "../shared/policy.js";
|
|
8
|
+
import RecordMetadata from "../shared/RecordMetadata.js";
|
|
9
|
+
import ModelStatus from "./ModelStatus.js";
|
|
10
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
11
|
+
export default createComponent({ name: 'ModelDetail', propKeys: ["model"], template: new URL('./ModelDetail.html', import.meta.url).href, setup(__props, __emit) {
|
|
12
|
+
const props = __props, emit = __emit, session = useSession();
|
|
13
|
+
const items = computed(() => [
|
|
14
|
+
{ key: 'alias', label: '模型标识', content: props.model.alias }, { key: 'provider', label: '供应商', content: props.model.provider },
|
|
15
|
+
{ key: 'type', label: '模型类型', content: props.model.kind === 'chat' ? '对话模型' : '向量模型' },
|
|
16
|
+
{ key: 'version', label: '生效版本', content: props.model.liveVersion ? 'v' + props.model.liveVersion : '尚未发布' },
|
|
17
|
+
{ key: 'endpoint', label: '服务地址', content: h('span', { class: 'mono wrap-anywhere' }, props.model.endpoint), span: 'filled' },
|
|
18
|
+
{ key: 'credential', label: '凭据引用', content: h('span', { class: 'mono wrap-anywhere' }, props.model.credential), span: 'filled' },
|
|
19
|
+
{ key: 'price', label: '演示单价', content: '输入 ¥' + props.model.inputPrice + ' / 输出 ¥' + props.model.outputPrice + '(每百万 Token)', span: 'filled' },
|
|
20
|
+
...(props.model.kind === 'embedding' ? [{ key: 'dimension', label: '向量维度', content: props.model.dimension + ' 维' }] : []),
|
|
21
|
+
]);
|
|
22
|
+
return { modelAgentLabel, Drawer, Descriptions, Tag, Button, Space, Alert, computed, h, fmtNumber, useSession, tenantLabel, RecordMetadata, ModelStatus, props, emit, session, items };
|
|
23
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/ModelEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="Drawer" data-bind-open="(true)" data-bind-title="(model ? '编辑模型' : '接入模型')" data-bind-size="(720)" data-bind-mask="({ closable: false })" data-bind-keyboard="(!saving)" data-bind-closable="(!saving)" data-on-close="(close)"><template data-slot="extra"><template data-component="Button" size="small" type="text" data-bind-disabled="(saving)" data-on-click="(session.state = 'expired')">模拟登录失效</template></template><template data-component="Alert" class="form-intro" type="info" show-icon="" title="平台统一管理接入配置" data-bind-description="(model ? '保存生成新草稿;当前生效版本继续保留。新配置需测试并通过发布评审后生效。' : '保存为平台配置草稿,完成测试与发布评审后再启用并分配使用授权。')"></template><template data-component="Alert" data-if="(error)" class="form-intro" type="error" show-icon="" data-bind-title="(error)"></template><template data-component="ProForm" name="model-editor" data-bind-form="(form)" data-bind-grid="({ gutter: 24 })" data-bind-disabled="(saving || !store.canEdit)" data-bind-label-col="({ style: { width: '88px' } })" data-bind-wrapper-col="({ flex: 'auto' })" class="editor-form"></template><template data-component="RecordMetadata" data-if="(model)" data-bind-record="(model)"></template><template data-slot="footer"><div class="drawer-footer"><span class="muted">保存草稿不会直接发布</span><template data-component="Space"><template data-component="Button" data-bind-disabled="(saving)" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-loading="(saving)" data-bind-disabled="(!store.canEdit)" data-on-click="(save)">保存草稿</template></template></div></template></template>
|
package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { confirmAction } from "../shell/confirmation.js";
|
|
2
|
+
import { computed, ref } from '../../runtime/state.js';
|
|
3
|
+
import { Alert, Button, Drawer, Space, message } from "../../runtime/widgets.js";
|
|
4
|
+
import { ProForm, useForm } from "../../runtime/widgets.js";
|
|
5
|
+
import { clone, credentials, providers } from "./data.js";
|
|
6
|
+
import { useModels } from "./store.js";
|
|
7
|
+
import { useSession } from "../shared/session.js";
|
|
8
|
+
import { metadata } from "../shared/policy.js";
|
|
9
|
+
import RecordMetadata from "../shared/RecordMetadata.js";
|
|
10
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
11
|
+
export default createComponent({ name: 'ModelEditor', propKeys: ["model"], template: new URL('./ModelEditor.html', import.meta.url).href, setup(__props, __emit) {
|
|
12
|
+
const props = __props;
|
|
13
|
+
const emit = __emit;
|
|
14
|
+
const store = useModels(), session = useSession(), saving = ref(false), error = ref('');
|
|
15
|
+
const initial = props.model ? clone(props.model) : {
|
|
16
|
+
...metadata(session.actor, '', 'platform'), grants: [], references: [], publishState: 'draft',
|
|
17
|
+
id: crypto.randomUUID(), name: '', alias: '', provider: '', kind: 'chat', endpoint: '', credential: '', capabilities: ['文本'],
|
|
18
|
+
inputPrice: 0, outputPrice: 0, enabled: false, health: 'untested', projects: [], agents: [], quota: 1000000, version: 1, updatedAt: '',
|
|
19
|
+
};
|
|
20
|
+
const form = useForm(clone(initial));
|
|
21
|
+
const required = (label) => [{ required: true, whitespace: true, message: `请输入${label}` }];
|
|
22
|
+
form.fields.value = [
|
|
23
|
+
{ path: 'name', label: '模型名称', component: 'input', placeholder: '例如:报修分诊模型', span: 12, xs: 24, sm: 12, rules: required('模型名称') },
|
|
24
|
+
{ path: 'alias', label: '模型标识', component: 'input', placeholder: '例如:triage-chat', span: 12, xs: 24, sm: 12, extra: '小写字母、数字、短横线,2–64 位', rules: [...required('模型标识'), { pattern: /^[a-z][a-z0-9-]{1,63}$/, message: '请输入 2–64 位有效模型标识' }, { validator: async (_rule, value) => { if (store.models.some(m => m.id !== initial.id && m.alias === value?.trim()))
|
|
25
|
+
throw new Error('模型标识已存在,请更换'); } }] },
|
|
26
|
+
{ path: 'provider', label: '供应商', component: 'select', placeholder: '请选择供应商', options: providers.map(x => ({ label: x, value: x })), span: 12, xs: 24, sm: 12, rules: [{ required: true, message: '请选择供应商' }] },
|
|
27
|
+
{ path: 'kind', label: '模型类型', component: 'select', options: [{ label: '对话模型', value: 'chat' }, { label: '向量模型', value: 'embedding' }], allowClear: false, span: 12, xs: 24, sm: 12 },
|
|
28
|
+
{ path: 'endpoint', label: '服务地址', component: 'input', placeholder: 'https://models.example.invalid/v1', span: 24, extra: '填写服务端点;原型不会向该地址发送请求。', rules: [...required('服务地址'), { type: 'url', message: '请输入完整有效的 HTTP 或 HTTPS 地址' }, { pattern: /^https?:\/\//, message: '请输入 HTTP 或 HTTPS 地址' }] },
|
|
29
|
+
{ path: 'credential', label: '凭据引用', component: 'select', options: credentials, placeholder: '请选择受管凭据', span: 24, extra: '仅选择演示凭据引用,不填写真实 API Key。', rules: [{ required: true, message: '请选择凭据引用' }] },
|
|
30
|
+
{ path: 'capabilities', label: '声明能力', component: 'select', mode: 'multiple', options: ['文本', '工具调用', '推理', '视觉'].map(x => ({ label: x, value: x })), span: 24, hidden: computed(() => form.formData.kind === 'embedding'), rules: computed(() => form.formData.kind === 'chat' ? [{ required: true, type: 'array', min: 1, message: '请选择至少一项能力' }] : []) },
|
|
31
|
+
{ path: 'dimension', label: '向量维度', component: 'input-number', min: 1, max: 65536, precision: 0, span: 24, hidden: computed(() => form.formData.kind !== 'embedding'), rules: computed(() => form.formData.kind === 'embedding' ? [{ required: true, message: '请输入向量维度' }] : []) },
|
|
32
|
+
{ path: 'inputPrice', label: '输入单价', component: 'input-number', min: 0, precision: 4, span: 12, xs: 24, sm: 12, extra: '元 / 百万 Token(演示)', rules: [{ required: true, type: 'number', min: 0, message: '请输入有效的非负输入单价' }] },
|
|
33
|
+
{ path: 'outputPrice', label: '输出单价', component: 'input-number', min: 0, precision: 4, span: 12, xs: 24, sm: 12, extra: '元 / 百万 Token(演示)', hidden: computed(() => form.formData.kind === 'embedding'), rules: computed(() => form.formData.kind === 'chat' ? [{ required: true, type: 'number', min: 0, message: '请输入有效的非负输出单价' }] : []) },
|
|
34
|
+
];
|
|
35
|
+
function close() {
|
|
36
|
+
if (saving.value)
|
|
37
|
+
return;
|
|
38
|
+
if (JSON.stringify(form.formData) !== JSON.stringify(initial))
|
|
39
|
+
confirmAction({ title: '放弃未保存的修改?', content: '关闭后本次输入不会保存。', okText: '放弃修改', cancelText: '继续编辑', onOk: () => emit('close') });
|
|
40
|
+
else
|
|
41
|
+
emit('close');
|
|
42
|
+
}
|
|
43
|
+
async function save() {
|
|
44
|
+
if (!store.canEdit)
|
|
45
|
+
return;
|
|
46
|
+
try {
|
|
47
|
+
await form.formRef.value?.validate();
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
saving.value = true;
|
|
53
|
+
await new Promise(resolve => setTimeout(resolve, 400));
|
|
54
|
+
const value = clone(form.formData);
|
|
55
|
+
value.name = value.name.trim();
|
|
56
|
+
value.alias = value.alias.trim();
|
|
57
|
+
value.endpoint = value.endpoint.trim();
|
|
58
|
+
value.version = props.model ? props.model.version + 1 : 1;
|
|
59
|
+
if (value.kind === 'embedding') {
|
|
60
|
+
value.capabilities = ['向量'];
|
|
61
|
+
value.outputPrice = 0;
|
|
62
|
+
}
|
|
63
|
+
else
|
|
64
|
+
delete value.dimension;
|
|
65
|
+
try {
|
|
66
|
+
error.value = '';
|
|
67
|
+
if (store.save(value, !props.model))
|
|
68
|
+
emit('saved', value.id);
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
error.value = e.message;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
saving.value = false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return { confirmAction, computed, ref, Alert, Button, Drawer, Space, message, ProForm, useForm, clone, credentials, providers, useModels, useSession, metadata, RecordMetadata, props, emit, store, session, saving, error, initial, form, required, close, save };
|
|
78
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/ModelGrant.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="Drawer" data-bind-open="(true)" title="管理模型使用授权" data-bind-size="(660)" data-bind-mask="({ closable: false })" data-on-close="(!saving && emit('close'))"><h2>{{ (model.name) }}</h2><template data-component="Alert" class="form-intro" type="info" show-icon="" title="模型配置由平台维护" description="所选 Agent 会获准在该租户的全部所选项目中使用此模型,候选项随项目联动。调用须同时匹配租户、项目和 Agent。使用授权不包含编辑源配置或转授权;全部留空表示撤销使用授权。"></template><template data-component="ProForm" name="model-grant" data-bind-form="(form)" data-bind-disabled="(saving || !session.can('model:grant', 'platform'))" data-bind-grid="({ gutter: 24 })" data-bind-label-col="({ style: { width: '104px' } })" data-bind-wrapper-col="({ flex: 'auto' })"></template><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)"></template><template data-slot="footer"><div class="drawer-footer"><span class="muted">授权关系与资源引用分别管理</span><template data-component="Space"><template data-component="Button" data-bind-disabled="(saving)" data-on-click="(emit('close'))">取消</template><template data-component="Button" type="primary" data-bind-loading="(saving)" data-bind-disabled="(!session.can('model:grant', 'platform'))" data-on-click="(save)">保存授权</template></template></div></template></template>
|
package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { computed, ref, watch } from '../../runtime/state.js';
|
|
2
|
+
import { Alert, Button, Drawer, Space } from "../../runtime/widgets.js";
|
|
3
|
+
import { ProForm, useForm } from "../../runtime/widgets.js";
|
|
4
|
+
import { agentCatalog, projectCatalog } from "./data.js";
|
|
5
|
+
import { useModels } from "./store.js";
|
|
6
|
+
import { modelAgentEntries, modelProjectEntries } from "../agents/registry.js";
|
|
7
|
+
import { useSession } from "../shared/session.js";
|
|
8
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
9
|
+
export default createComponent({ name: 'ModelGrant', propKeys: ["model"], template: new URL('./ModelGrant.html', import.meta.url).href, setup(__props, __emit) {
|
|
10
|
+
const props = __props, emit = __emit;
|
|
11
|
+
const store = useModels(), session = useSession(), saving = ref(false), error = ref(''), expected = props.model.recordVersion;
|
|
12
|
+
const group = (tenant) => props.model.grants.find(g => g.tenantId === tenant);
|
|
13
|
+
const form = useForm({ heatingProjects: [...(group('heating')?.projects || [])], heatingAgents: [...(group('heating')?.agents || [])], northProjects: [...(group('north')?.projects || [])], northAgents: [...(group('north')?.agents || [])], quota: props.model.quota });
|
|
14
|
+
const catalog = computed(() => { const entries = new Map(agentCatalog.map(a => [a.value, { ...a, label: a.value }])); for (const a of modelAgentEntries()) {
|
|
15
|
+
const old = entries.get(a.value);
|
|
16
|
+
entries.set(a.value, { ...a, projects: [...new Set([...(old?.projects || []), ...a.projects])] });
|
|
17
|
+
} return [...entries.values()]; });
|
|
18
|
+
const projects = computed(() => [...projectCatalog, ...modelProjectEntries()].filter((a, i, all) => all.findIndex(b => b.value === a.value && b.tenantId === a.tenantId) === i));
|
|
19
|
+
const options = (p) => catalog.value.filter(a => p.length && p.every(v => a.projects.includes(v))).map(a => ({ label: a.label, value: a.value }));
|
|
20
|
+
form.fields.value = [
|
|
21
|
+
{ path: 'heatingProjects', label: '供热 · 项目', component: 'select', mode: 'multiple', span: 24, options: computed(() => projects.value.filter(p => p.tenantId === 'heating').map(p => ({ label: p.value, value: p.value }))), placeholder: '选择供热事业部项目' },
|
|
22
|
+
{ path: 'heatingAgents', label: '供热 · Agent', component: 'select', mode: 'multiple', span: 24, options: computed(() => options(form.formData.heatingProjects)), disabled: computed(() => !form.formData.heatingProjects.length), placeholder: '选择在上述项目中允许使用的 Agent' },
|
|
23
|
+
{ path: 'northProjects', label: '北方 · 项目', component: 'select', mode: 'multiple', span: 24, options: computed(() => projects.value.filter(p => p.tenantId === 'north').map(p => ({ label: p.value, value: p.value }))), placeholder: '选择北方能源项目' },
|
|
24
|
+
{ path: 'northAgents', label: '北方 · Agent', component: 'select', mode: 'multiple', span: 24, options: computed(() => options(form.formData.northProjects)), disabled: computed(() => !form.formData.northProjects.length), placeholder: '选择在上述项目中允许使用的 Agent' },
|
|
25
|
+
{ path: 'quota', label: '共享月额度', component: 'input-number', span: 24, min: 1, max: 10000000000, precision: 0, extra: 'Token;沿用所选范围共享额度的演示口径,正式扣减规则待 spec。', rules: [{ required: true, message: '请输入额度' }] },
|
|
26
|
+
];
|
|
27
|
+
watch(() => form.formData.heatingProjects, p => { form.formData.heatingAgents = form.formData.heatingAgents.filter(a => options(p).some(o => o.value === a)); }, { deep: true });
|
|
28
|
+
watch(() => form.formData.northProjects, p => { form.formData.northAgents = form.formData.northAgents.filter(a => options(p).some(o => o.value === a)); }, { deep: true });
|
|
29
|
+
async function save() {
|
|
30
|
+
if (saving.value)
|
|
31
|
+
return;
|
|
32
|
+
try {
|
|
33
|
+
await form.formRef.value?.validate();
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
saving.value = true;
|
|
39
|
+
error.value = '';
|
|
40
|
+
try {
|
|
41
|
+
await new Promise(r => setTimeout(r, 350));
|
|
42
|
+
const d = form.formData;
|
|
43
|
+
const grants = [{ tenantId: 'heating', projects: d.heatingProjects, agents: d.heatingAgents }, { tenantId: 'north', projects: d.northProjects, agents: d.northAgents }].filter(g => g.projects.length || g.agents.length);
|
|
44
|
+
store.grant(props.model.id, grants, Number(d.quota), expected);
|
|
45
|
+
emit('close');
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
error.value = e.message;
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
saving.value = false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { computed, ref, watch, Alert, Button, Drawer, Space, ProForm, useForm, agentCatalog, projectCatalog, useModels, modelAgentEntries, modelProjectEntries, useSession, props, emit, store, session, saving, error, expected, group, form, catalog, projects, options, save };
|
|
55
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/ModelReferences.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="Drawer" data-bind-open="(true)" data-bind-title="(deleting ? '删除模型' : '资源引用')" data-bind-size="(600)" data-on-close="(emit('close'))"><h2>{{ (model.name) }}</h2><template data-component="Alert" data-if="(deleting)" class="form-intro" data-bind-type="(reason ? 'warning' : 'info')" show-icon="" data-bind-title="(reason || '确认删除此模型?')" description="删除后从可用列表移除,基础信息和操作记录仍保留。提交时会再次检查资源引用。"></template><section class="drawer-section"><h2>引用此模型的资源 · {{ (model.references.length) }}</h2><div data-each="item in (model.references)" data-bind-key="(item.name)" class="reference-row"><div><strong>{{ (item.name) }}</strong><p class="muted">{{ (item.kind) }} · {{ (item.version) }}</p></div><template data-component="Tag">正在引用</template></div><p data-if="(!model.references.length)" class="muted">当前没有资源引用。授权关系不等同于资源引用。</p></section><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)"></template><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-on-click="(emit('close'))">返回</template><template data-component="Button" data-if="(deleting)" danger="" type="primary" data-bind-disabled="(!!reason || !session.can('model:delete', 'platform'))" data-on-click="(remove)">确认删除</template></div></template></template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ref, computed } from '../../runtime/state.js';
|
|
2
|
+
import { Alert, Button, Drawer, Tag } from "../../runtime/widgets.js";
|
|
3
|
+
import { useModels } from "./store.js";
|
|
4
|
+
import { useSession } from "../shared/session.js";
|
|
5
|
+
import { assertDelete } from "./domain.js";
|
|
6
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
7
|
+
export default createComponent({ name: 'ModelReferences', propKeys: ["model", "deleting"], template: new URL('./ModelReferences.html', import.meta.url).href, setup(__props, __emit) {
|
|
8
|
+
const props = __props, emit = __emit;
|
|
9
|
+
const store = useModels(), session = useSession(), error = ref('');
|
|
10
|
+
const expected = props.model.recordVersion;
|
|
11
|
+
const reason = computed(() => { try {
|
|
12
|
+
assertDelete(props.model);
|
|
13
|
+
return '';
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
return e.message;
|
|
17
|
+
} });
|
|
18
|
+
function remove() { try {
|
|
19
|
+
store.remove(props.model.id, expected);
|
|
20
|
+
emit('close');
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
error.value = e.message;
|
|
24
|
+
} }
|
|
25
|
+
return { ref, computed, Alert, Button, Drawer, Tag, useModels, useSession, assertDelete, props, emit, store, session, error, expected, reason, remove };
|
|
26
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/ModelRelease.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="Drawer" data-bind-open="(true)" title="配置发布" data-bind-size="(640)" data-bind-mask="({ closable: false })" data-on-close="(!busy && emit('close'))"><div class="detail-heading"><div><h2>{{ (model.name) }}</h2><p class="mono muted">{{ (model.alias) }}</p></div><template data-component="Tag" data-bind-color="(model.publishState === 'published' ? 'green' : 'blue')">{{ ({ draft: '待发布', review: '评审中', published: '已发布', failed: '发布失败' }[model.publishState]) }}</template></div><div class="version-comparison"><div><span>当前生效版本</span><strong>{{ (model.liveVersion ? 'v' + model.liveVersion : '尚未发布') }}</strong><small>{{ (model.publishedBy || '平台初始配置') }} {{ (model.publishedAt ? formatDate(model.publishedAt) : '') }}</small></div><div><span>本次配置</span><strong>v{{ (model.version) }}</strong><small>{{ (model.testedVersion === model.version ? '本版本模拟测试通过' : '等待本版本测试') }}</small></div></div><section class="drawer-section"><h2>变更内容</h2><p data-if="(!changes.length)">与当前发布版本一致</p><div data-else="" class="config-diff"><table><thead><tr><th>字段</th><th>当前生效</th><th>待发布</th></tr></thead><tbody><tr data-each="d in (diff)" data-bind-key="(d.key)"><th>{{ (d.label) }}</th><td>{{ (d.before) }}</td><td>{{ (d.after) }}</td></tr></tbody></table></div><p class="muted">配置草稿、测试结果和发布结果分别记录。发布成功前,当前生效配置保持不变。</p></section><template data-component="Alert" data-if="(model.requestId)" class="form-intro" type="info" show-icon="" title="发布申请(演示)" data-bind-description="(model.requestId + ' · 申请人:' + model.requestName)"></template><template data-component="Alert" data-if="(model.publishState === 'review' && !session.can('model:publish', 'platform'))" class="form-intro" type="info" show-icon="" title="等待配置审核员评审" description="可在页头切换到配置审核员,查看同一申请并给出评审结果。"></template><section data-if="(model.publishState === 'review' && session.can('model:publish', 'platform'))" class="drawer-section"><label for="release-note" class="answer-label">评审意见</label><template data-component="Input.TextArea" id="release-note" data-model-value="(note)" data-bind-rows="(3)" data-bind-maxlength="(500)" placeholder="请说明发布或退回的理由"></template></section><template data-component="Alert" data-if="(model.publishNote)" class="form-intro" data-bind-type="(model.publishState === 'failed' ? 'error' : model.publishState === 'published' ? 'success' : 'warning')" show-icon="" data-bind-title="(model.publishNote)"></template><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)"></template><p class="muted">本页模拟配置评审与发布,不提交真实 GitLab PR 或修改运行环境。</p><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(emit('close'))">关闭</template><template data-component="Space" data-if="(model.publishState === 'review' && session.can('model:publish', 'platform'))"><template data-component="Button" danger="" data-bind-disabled="(busy)" data-on-click="(act('reject'))">退回修改</template><template data-component="Button" type="primary" data-bind-loading="(busy)" data-on-click="(act('approve'))">同意并发布</template></template><template data-component="Button" data-else="" type="primary" data-bind-loading="(busy)" data-bind-disabled="(!session.can('model:edit', 'platform') || model.publishState === 'review' || model.liveVersion === model.version || model.testedVersion !== model.version)" data-on-click="(act('submit'))">提交发布申请</template></div></template></template>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ref, computed } from '../../runtime/state.js';
|
|
2
|
+
import { Alert, Button, Drawer, Input, Space, Tag } from "../../runtime/widgets.js";
|
|
3
|
+
import { useModels } from "./store.js";
|
|
4
|
+
import { useSession } from "../shared/session.js";
|
|
5
|
+
import { formatDate } from "../shared/policy.js";
|
|
6
|
+
import { modelConfigKeys } from "./domain.js";
|
|
7
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
8
|
+
export default createComponent({ name: 'ModelRelease', propKeys: ["model"], template: new URL('./ModelRelease.html', import.meta.url).href, setup(__props, __emit) {
|
|
9
|
+
const props = __props, emit = __emit;
|
|
10
|
+
const store = useModels(), session = useSession(), note = ref(''), error = ref(''), busy = ref(false);
|
|
11
|
+
const labels = { name: '名称', alias: '标识', provider: '供应商', kind: '类型', endpoint: '服务地址', credential: '凭据引用', capabilities: '能力', inputPrice: '输入价格', outputPrice: '输出价格', dimension: '向量维度' };
|
|
12
|
+
const changes = computed(() => modelConfigKeys.filter(k => JSON.stringify(props.model[k]) !== JSON.stringify(props.model.liveConfig?.[k])).map(k => labels[k]));
|
|
13
|
+
const diff = computed(() => modelConfigKeys.filter(k => JSON.stringify(props.model[k]) !== JSON.stringify(props.model.liveConfig?.[k])).map(k => ({ key: k, label: labels[k], before: display(props.model.liveConfig?.[k]), after: display(props.model[k]) })));
|
|
14
|
+
function display(value) { return value === undefined || value === '' ? '未设置' : Array.isArray(value) ? value.join('、') : String(value); }
|
|
15
|
+
async function act(action) {
|
|
16
|
+
if (busy.value)
|
|
17
|
+
return;
|
|
18
|
+
const expected = props.model.recordVersion, actor = session.actor.id;
|
|
19
|
+
busy.value = true;
|
|
20
|
+
error.value = '';
|
|
21
|
+
try {
|
|
22
|
+
await new Promise(r => setTimeout(r, 500));
|
|
23
|
+
if (actor !== session.actor.id)
|
|
24
|
+
throw new Error('身份已改变,请重新核对。');
|
|
25
|
+
if (action === 'submit')
|
|
26
|
+
store.submit(props.model.id, expected);
|
|
27
|
+
else
|
|
28
|
+
store.review(props.model.id, expected, action === 'approve', note.value);
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
error.value = e.message;
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
busy.value = false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return { ref, computed, Alert, Button, Drawer, Input, Space, Tag, useModels, useSession, formatDate, modelConfigKeys, props, emit, store, session, note, error, busy, labels, changes, diff, display, act };
|
|
38
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/ModelStatus.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<div class="model-status"><div><span class="status-dot" data-bind-class="(model.enabled ? (model.health === 'error' ? 'error' : 'success') : 'neutral')"></span><span>{{ (model.enabled ? '已启用' : '已停用') }}</span></div><span class="health-text" data-bind-class="(model.health)">{{ (healthText) }}</span></div>
|
package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { computed } from '../../runtime/state.js';
|
|
2
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
3
|
+
export default createComponent({ name: 'ModelStatus', propKeys: ["model"], template: new URL('./ModelStatus.html', import.meta.url).href, setup(__props, __emit) {
|
|
4
|
+
const props = __props;
|
|
5
|
+
const healthText = computed(() => ({ normal: '连接正常', error: '连接异常', untested: '未测试' })[props.model.health]);
|
|
6
|
+
return { computed, props, healthText };
|
|
7
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/ModelTable.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<section class="filter-panel panel" aria-label="模型筛选"><template data-component="ProForm" name="model-search" data-bind-form="(filters)" data-bind-grid="({ gutter: 24 })" class="filter-form" data-on-keydown.enter.prevent="(search)"></template><div class="filter-actions"><template data-component="Button" data-on-click="(search)">查询</template><template data-component="Button" data-on-click="(reset)">重置</template></div></section><section class="panel model-table-panel" aria-label="已接入模型列表"><template data-component="Result" data-if="(store.scene === 'error')" status="warning" title="模型列表加载失败"><template data-slot="extra"><template data-component="Button" type="primary" data-on-click="(retry)">重试</template></template></template><template data-component="ProTable" data-else="" data-bind-table="(table)" data-bind-search="(async () => { })" data-bind-control="(false)" data-bind-table-container="(false)" data-bind-loading="(loading)" data-bind-row-selection="(selection.rowSelection.value)" row-key="id" size="middle" data-bind-scroll="({ x: 'max-content' })" data-bind-pagination="({ showTotal: (n) => '共 ' + n + ' 条', showSizeChanger: true, pageSizeOptions: [10, 20, 50, 100] })" data-bind-locale="({ emptyText: h(Empty, { description: store.scene === 'empty' ? '还没有接入模型' : '没有符合条件的模型' }, { default: () => h(Button, { onClick: store.scene === 'empty' ? () => emit('create') : reset, disabled: store.scene === 'empty' && !store.canEdit }, () => store.scene === 'empty' ? '接入第一个模型' : '清除筛选') }) })"><template data-slot="button-bar"><div class="list-heading"><h2>已接入模型 · {{ (filtered.length) }}</h2><template data-component="ListBatchBar" data-bind-count="(selection.keys.value.length)" data-bind-allowed="(session.can('model:delete', 'platform'))" data-on-remove="(batchDelete)" data-on-clear="(selection.clear)"></template></div></template><template data-slot="toolbar"><div class="table-tools"><template data-component="Select" data-model-value="(sort)" aria-label="模型排序" data-bind-options="([{ label: '创建时间倒序', value: 'created' }, { label: '修改时间倒序', value: 'updated' }, { label: '名称排序', value: 'name' }])"></template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template><template data-component="Button" aria-label="刷新模型列表" data-bind-loading="(loading)" data-on-click="(refresh)"><template data-component="ReloadOutlined"></template></template></div></template></template></section><template data-component="ListDeleteDialog" data-if="(deleteTargets.length)" data-model-targets="(deleteTargets)" label="模型" data-bind-check="(store.checkRemove)" data-bind-submit="(store.removeMany)" data-on-close="(deleteTargets = [])" data-on-deleted="(deleted)"></template>
|
package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { computed, onMounted, ref, watch } from '../../runtime/state.js';
|
|
2
|
+
import { h } from '../../runtime/dom.js';
|
|
3
|
+
import { Button, Empty, Result, Tag, Select } from "../../runtime/widgets.js";
|
|
4
|
+
import { ReloadOutlined } from "../../runtime/icons.js";
|
|
5
|
+
import { ProForm, ProTable, useForm, useTable } from "../../runtime/widgets.js";
|
|
6
|
+
import { providers } from "./data.js";
|
|
7
|
+
import { useModels } from "./store.js";
|
|
8
|
+
import { useSession } from "../shared/session.js";
|
|
9
|
+
import { formatDate } from "../shared/policy.js";
|
|
10
|
+
import { useColumns } from "../shared/columns.js";
|
|
11
|
+
import ColumnSettings from "../shared/ColumnSettings.js";
|
|
12
|
+
import { useListSelection } from "../shared/listSelection.js";
|
|
13
|
+
import ListBatchBar from "../shared/ListBatchBar.js";
|
|
14
|
+
import ListDeleteDialog from "../shared/ListDeleteDialog.js";
|
|
15
|
+
import ModelStatus from "./ModelStatus.js";
|
|
16
|
+
import RowActions from "./RowActions.js";
|
|
17
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
18
|
+
export default createComponent({ name: 'ModelTable', propKeys: [], template: new URL('./ModelTable.html', import.meta.url).href, setup(__props, __emit) {
|
|
19
|
+
const emit = __emit, store = useModels(), session = useSession(), loading = ref(false), sort = ref('created');
|
|
20
|
+
const applied = ref({ keyword: '', provider: '', status: '' });
|
|
21
|
+
const filters = useForm({ ...applied.value }, [
|
|
22
|
+
{ path: 'keyword', label: '模型名称', component: 'input', placeholder: '搜索名称或标识', span: 9, xs: 24, md: 9 },
|
|
23
|
+
{ path: 'provider', label: '供应商', component: 'select', placeholder: '全部供应商', options: providers.map(p => ({ label: p, value: p })), span: 8, xs: 24, md: 8 },
|
|
24
|
+
{ path: 'status', label: '状态', component: 'select', placeholder: '全部状态', options: [{ label: '已启用', value: 'enabled' }, { label: '已停用', value: 'disabled' }, { label: '待发布', value: 'draft' }, { label: '评审中', value: 'review' }, { label: '连接异常', value: 'error' }], span: 7, xs: 24, md: 7 },
|
|
25
|
+
]);
|
|
26
|
+
const filtered = computed(() => {
|
|
27
|
+
if (store.scene !== 'normal')
|
|
28
|
+
return [];
|
|
29
|
+
const q = applied.value.keyword.trim().toLowerCase(), status = applied.value.status;
|
|
30
|
+
return store.models.filter(m => (!q || (m.name + ' ' + m.alias).toLowerCase().includes(q)) && (!applied.value.provider || m.provider === applied.value.provider) &&
|
|
31
|
+
(!status || status === 'enabled' && m.enabled || status === 'disabled' && !m.enabled || status === 'error' && m.health === 'error' || status === m.publishState))
|
|
32
|
+
.sort((a, b) => sort.value === 'name' ? a.name.localeCompare(b.name, 'zh-CN') : ((sort.value === 'updated' ? b.updatedAt : b.createdAt).localeCompare(sort.value === 'updated' ? a.updatedAt : a.createdAt) || a.id.localeCompare(b.id)));
|
|
33
|
+
});
|
|
34
|
+
const render = (fn) => (_, m) => fn(m);
|
|
35
|
+
const prefs = useColumns('models', [
|
|
36
|
+
{ key: 'name', label: '模型', locked: true }, { key: 'provider', label: '供应商', defaultVisible: true }, { key: 'capabilities', label: '能力', defaultVisible: true },
|
|
37
|
+
{ key: 'scope', label: '授权范围', defaultVisible: true }, { key: 'status', label: '状态', defaultVisible: true }, { key: 'version', label: '生效 / 草稿', defaultVisible: true },
|
|
38
|
+
{ key: 'createdBy', label: '创建人' }, { key: 'createdAt', label: '创建时间' }, { key: 'createdDept', label: '创建部门' }, { key: 'updatedBy', label: '修改人' }, { key: 'updatedAt', label: '修改时间' }, { key: 'actions', label: '操作', locked: true },
|
|
39
|
+
]);
|
|
40
|
+
const table = useTable({ pageParam: { current: 1, pageSize: 10, total: 0 }, columns: [
|
|
41
|
+
{ key: 'name', title: '模型', dataIndex: 'name', width: 215, render: render(m => h('div', { class: 'model-name-cell' }, [h('button', { class: 'text-button model-link', onClick: () => emit('action', 'detail', m) }, m.name), h('span', { class: 'mono muted' }, m.alias)])) },
|
|
42
|
+
{ key: 'provider', title: '供应商', dataIndex: 'provider', width: 145 },
|
|
43
|
+
{ key: 'capabilities', title: '能力', width: 155, render: render(m => h('div', { class: 'capabilities' }, m.capabilities.map(c => h(Tag, { bordered: false }, () => c)))) },
|
|
44
|
+
{ key: 'scope', title: '授权范围', width: 130, render: render(m => h('button', { class: 'text-button scope-link', onClick: () => emit('action', session.can('model:grant', 'platform') ? 'grant' : 'detail', m) }, m.grants.length ? m.grants.length + ' 个租户 · ' + m.projects.length + ' 个项目' : '暂未授权')) },
|
|
45
|
+
{ key: 'status', title: '状态', width: 130, render: render(m => h(ModelStatus, { model: m })) },
|
|
46
|
+
{ key: 'version', title: '生效 / 草稿', width: 140, render: render(m => h('div', { class: 'model-name-cell' }, [h('span', m.liveVersion ? '生效 v' + m.liveVersion : '尚未发布'), h('span', { class: 'muted' }, m.liveVersion === m.version ? '无待发布变更' : 'v' + m.version + ' · ' + ({ draft: '待发布', review: '评审中', failed: '发布失败', published: '已发布' }[m.publishState]))])) },
|
|
47
|
+
{ key: 'createdBy', title: '创建人', dataIndex: 'createdBy', width: 105 }, { key: 'createdAt', title: '创建时间', dataIndex: 'createdAt', width: 180, render: (v) => formatDate(String(v)) },
|
|
48
|
+
{ key: 'createdDept', title: '创建部门', dataIndex: 'createdDept', width: 140 }, { key: 'updatedBy', title: '修改人', dataIndex: 'updatedBy', width: 105 },
|
|
49
|
+
{ key: 'updatedAt', title: '修改时间', dataIndex: 'updatedAt', width: 180, render: (v) => formatDate(String(v)) },
|
|
50
|
+
{ key: 'actions', title: '操作', fixed: 'right', width: 120, render: render(m => h(RowActions, { model: m, onAction: (a, x) => emit('action', a, x) })) },
|
|
51
|
+
] });
|
|
52
|
+
const deleteTargets = ref([]);
|
|
53
|
+
const selection = useListSelection(table.dataSource, computed(() => JSON.stringify([applied.value, sort.value, session.key, store.scene, table.pageParam.current, table.pageParam.pageSize])), computed(() => session.can('model:delete', 'platform')), m => m.name);
|
|
54
|
+
function batchDelete() { deleteTargets.value = selection.selected.value.map(m => ({ id: m.id, name: m.name, recordVersion: m.recordVersion })); }
|
|
55
|
+
function deleted() { deleteTargets.value = []; selection.clear(); }
|
|
56
|
+
const catalog = new Map(table.columns.value.map(c => [c.key, c]));
|
|
57
|
+
watch(prefs.keys, keys => { table.columns.value = keys.map(k => catalog.get(k)).filter(Boolean); }, { immediate: true });
|
|
58
|
+
watch([filtered, () => table.pageParam.current, () => table.pageParam.pageSize], () => {
|
|
59
|
+
const size = table.pageParam.pageSize || 10, max = Math.max(1, Math.ceil(filtered.value.length / size));
|
|
60
|
+
if ((table.pageParam.current || 1) > max)
|
|
61
|
+
table.setPageParam({ current: max });
|
|
62
|
+
const start = ((table.pageParam.current || 1) - 1) * size;
|
|
63
|
+
table.dataSource.value = filtered.value.slice(start, start + size);
|
|
64
|
+
table.setPageParam({ total: filtered.value.length });
|
|
65
|
+
}, { immediate: true });
|
|
66
|
+
async function refresh() { selection.clear(); loading.value = true; await new Promise(r => setTimeout(r, 300)); loading.value = false; }
|
|
67
|
+
function search() { applied.value = { keyword: filters.formData.keyword || '', provider: filters.formData.provider || '', status: filters.formData.status || '' }; table.setPageParam({ current: 1 }); }
|
|
68
|
+
function reset() { filters.setFormData({ keyword: '', provider: '', status: '' }); search(); }
|
|
69
|
+
function retry() { store.scene = 'normal'; refresh(); }
|
|
70
|
+
onMounted(refresh);
|
|
71
|
+
return { computed, onMounted, ref, watch, h, Button, Empty, Result, Tag, Select, ReloadOutlined, ProForm, ProTable, useForm, useTable, providers, useModels, useSession, formatDate, useColumns, ColumnSettings, useListSelection, ListBatchBar, ListDeleteDialog, ModelStatus, RowActions, emit, store, session, loading, sort, applied, filters, filtered, render, prefs, table, deleteTargets, selection, batchDelete, deleted, catalog, refresh, search, reset, retry };
|
|
72
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/ModelTester.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<template data-component="Drawer" data-bind-open="(true)" title="模型连接测试" data-bind-size="(640)" data-on-close="(close)"><div class="detail-heading"><div><h2>{{ (model.name) }}</h2><p class="mono muted">{{ (model.alias) }} · v{{ (model.version) }}</p></div><template data-component="Tag">模拟测试</template></div><template data-component="Alert" type="info" show-icon="" title="本次测试仅演示交互,不会调用真实模型。" description="可切换成功与失败场景,观察结果和后续操作。"></template><section class="drawer-section"><h2>模拟结果</h2><template data-component="RadioGroup" data-model-value="(outcome)" data-bind-disabled="(running)" data-bind-options="([{ label: '连接成功', value: 'success' }, { label: '连接超时', value: 'failure' }])"></template></section><section class="drawer-section"><template data-component="Steps" data-bind-current="(result === 'success' ? 3 : stage)" data-bind-status="(result === 'failure' ? 'error' : 'process')" data-bind-items="(stages)" size="small"></template></section><div data-if="(running)" class="test-wait" role="status"><template data-component="LoadingOutlined" spin=""></template><h2>正在验证模型接入</h2><p>正在模拟{{ (stages[stage]?.title) }}…</p></div><div data-else-if="(result)" class="test-result" data-bind-class="(result)" role="status"><template data-component="CheckCircleOutlined" data-if="(result === 'success')"></template><template data-component="CloseCircleOutlined" data-else=""></template><h2>{{ (result === 'success' ? '模型连接测试通过' : '模型连接超时') }}</h2><p>{{ (result === 'success' ? '配置与声明能力已通过模拟检查。' : '请检查服务地址、凭据引用及供应商服务状态。') }}</p><p data-if="(result === 'success')" class="muted">模拟响应耗时:480 ms · 此数值不代表真实性能</p><p data-else="" class="mono muted">DEMO_CONNECTION_TIMEOUT · 模拟错误</p></div><div data-else="" class="test-wait"><p class="muted">开始测试后,这里将显示各项检查结果。</p></div><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)"></template><template data-component="Alert" data-if="(result === 'success')" type="info" show-icon="" title="测试通过后,请前往“配置发布”提交评审。" description="本地测试不代表真实协议兼容或发布成功;正式验证需要分别覆盖工具调用、结构化输出、流式、usage 和错误语义。"></template><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-on-click="(close)">{{ (running ? '取消测试并关闭' : '关闭') }}</template><template data-component="Button" type="primary" data-bind-loading="(running)" data-bind-disabled="(!session.can('model:test', 'platform'))" data-on-click="(run)">{{ (result ? '重新测试' : '开始测试') }}</template></div></template></template>
|
package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { computed, onBeforeUnmount, ref } from '../../runtime/state.js';
|
|
2
|
+
import { Alert, Button, Drawer, RadioGroup, Steps, Tag, Space, message } from "../../runtime/widgets.js";
|
|
3
|
+
import { CheckCircleOutlined, CloseCircleOutlined, LoadingOutlined } from "../../runtime/icons.js";
|
|
4
|
+
import { useModels } from "./store.js";
|
|
5
|
+
import { useSession } from "../shared/session.js";
|
|
6
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
7
|
+
export default createComponent({ name: 'ModelTester', propKeys: ["model"], template: new URL('./ModelTester.html', import.meta.url).href, setup(__props, __emit) {
|
|
8
|
+
const props = __props;
|
|
9
|
+
const emit = __emit;
|
|
10
|
+
const store = useModels(), running = ref(false), stage = ref(0), outcome = ref(props.model.health === 'error' ? 'failure' : 'success');
|
|
11
|
+
const session = useSession(), error = ref('');
|
|
12
|
+
const result = ref(null);
|
|
13
|
+
let timer;
|
|
14
|
+
const stages = computed(() => [{ title: '检查配置' }, { title: '验证连接' }, { title: props.model.kind === 'embedding' ? '向量能力' : '声明能力' }]);
|
|
15
|
+
function run() {
|
|
16
|
+
if (!session.can('model:test', 'platform') || running.value)
|
|
17
|
+
return;
|
|
18
|
+
running.value = true;
|
|
19
|
+
stage.value = 0;
|
|
20
|
+
result.value = null;
|
|
21
|
+
const version = props.model.version, id = props.model.id, chosen = outcome.value;
|
|
22
|
+
timer = setInterval(() => {
|
|
23
|
+
if (stage.value < 2)
|
|
24
|
+
stage.value++;
|
|
25
|
+
else {
|
|
26
|
+
clearInterval(timer);
|
|
27
|
+
timer = undefined;
|
|
28
|
+
running.value = false;
|
|
29
|
+
try {
|
|
30
|
+
store.test(id, version, chosen === 'success');
|
|
31
|
+
result.value = chosen;
|
|
32
|
+
error.value = '';
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
result.value = null;
|
|
36
|
+
error.value = e.message;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}, 450);
|
|
40
|
+
}
|
|
41
|
+
function close() { if (timer)
|
|
42
|
+
clearInterval(timer); timer = undefined; emit('close'); }
|
|
43
|
+
onBeforeUnmount(() => { if (timer)
|
|
44
|
+
clearInterval(timer); });
|
|
45
|
+
return { computed, onBeforeUnmount, ref, Alert, Button, Drawer, RadioGroup, Steps, Tag, Space, message, CheckCircleOutlined, CloseCircleOutlined, LoadingOutlined, useModels, useSession, props, emit, store, running, stage, outcome, session, error, result, timer, stages, run, close };
|
|
46
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/ModelsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<div class="page-heading"><div><h1>模型管理</h1><p>平台统一接入,按租户、项目与 Agent 分配使用授权。</p></div><template data-component="Button" type="primary" data-bind-disabled="(!session.can('model:edit', 'platform'))" data-on-click="(create)"><template data-component="PlusOutlined"></template>接入模型</template></div><template data-component="Alert" data-if="(!session.readable('model:view', 'platform'))" class="page-alert" type="info" show-icon="" title="当前展示本租户已获授权的模型" description="接入配置由平台维护;使用授权不包含编辑或转授权权限。"></template><template data-component="Alert" data-if="(store.persistenceError)" class="page-alert" type="warning" show-icon="" title="浏览器暂时无法保存演示数据,请保留当前输入后重试。"></template><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="(tabs)" class="model-tabs"></template><template data-component="ModelTable" data-if="(tab === 'list')" data-on-action="(action)" data-on-create="(create)"></template><template data-component="UsagePanel" data-else-if="(tab === 'usage')"></template><template data-component="AuditPanel" data-else-if="(session.can('model:audit', 'platform'))"></template><template data-component="ModelEditor" data-if="(overlay === 'edit')" data-bind-model="(selected)" data-on-close="(close)" data-on-saved="(saved)"></template><template data-component="ModelDetail" data-if="(overlay === 'detail' && selected)" data-bind-model="(selected)" data-on-close="(close)" data-on-action="(action)"></template><template data-component="ModelTester" data-if="(overlay === 'test' && selected)" data-bind-model="(selected)" data-on-close="(close)"></template><template data-component="ModelGrant" data-if="(overlay === 'grant' && selected)" data-bind-model="(selected)" data-on-close="(close)"></template><template data-component="ModelRelease" data-if="(overlay === 'release' && selected)" data-bind-model="(selected)" data-on-close="(close)"></template><template data-component="ModelReferences" data-if="((overlay === 'references' || overlay === 'delete') && selected)" data-bind-model="(selected)" data-bind-deleting="(overlay === 'delete')" data-on-close="(close)"></template><template data-component="Drawer" data-if="(overlay === 'detail' && !selected)" data-bind-open="(true)" title="模型访问" data-bind-size="(600)" data-on-close="(close)"><template data-component="Result" status="403" title="无法访问此模型" sub-title="记录不存在、已被删除或不在当前授权范围。"><template data-slot="extra"><template data-component="Button" data-on-click="(close)">返回列表</template></template></template></template>
|
package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { confirmAction } from "../shell/confirmation.js";
|
|
2
|
+
import { computed, ref, watch } from '../../runtime/state.js';
|
|
3
|
+
import { useRoute, useRouter } from "../../runtime/router.js";
|
|
4
|
+
import { Alert, Button, Tabs, Result, Drawer, message } from "../../runtime/widgets.js";
|
|
5
|
+
import { PlusOutlined } from "../../runtime/icons.js";
|
|
6
|
+
import { useModels } from "./store.js";
|
|
7
|
+
import { useSession } from "../shared/session.js";
|
|
8
|
+
import ModelTable from "./ModelTable.js";
|
|
9
|
+
import ModelEditor from "./ModelEditor.js";
|
|
10
|
+
import ModelDetail from "./ModelDetail.js";
|
|
11
|
+
import ModelTester from "./ModelTester.js";
|
|
12
|
+
import ModelGrant from "./ModelGrant.js";
|
|
13
|
+
import ModelRelease from "./ModelRelease.js";
|
|
14
|
+
import ModelReferences from "./ModelReferences.js";
|
|
15
|
+
import UsagePanel from "./UsagePanel.js";
|
|
16
|
+
import AuditPanel from "./AuditPanel.js";
|
|
17
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
18
|
+
export default createComponent({ name: 'ModelsPage', propKeys: [], template: new URL('./ModelsPage.html', import.meta.url).href, setup(__props, __emit) {
|
|
19
|
+
const store = useModels(), session = useSession(), route = useRoute(), router = useRouter(), tab = ref('list'), selectedId = ref(null);
|
|
20
|
+
const overlay = ref(null), selected = computed(() => store.models.find(m => m.id === selectedId.value));
|
|
21
|
+
const tabs = computed(() => [{ key: 'list', label: '模型列表' }, { key: 'usage', label: '用量概览' }, ...(session.can('model:audit', 'platform') ? [{ key: 'audit', label: '操作记录' }] : [])]);
|
|
22
|
+
function close() { overlay.value = null; selectedId.value = null; if (route.query.model)
|
|
23
|
+
router.replace('/models'); }
|
|
24
|
+
watch(() => session.actorId, () => { close(); tab.value = 'list'; });
|
|
25
|
+
watch(() => route.query.model, id => { if (typeof id === 'string') {
|
|
26
|
+
selectedId.value = id;
|
|
27
|
+
overlay.value = 'detail';
|
|
28
|
+
} }, { immediate: true });
|
|
29
|
+
function create() { if (session.can('model:edit', 'platform')) {
|
|
30
|
+
selectedId.value = null;
|
|
31
|
+
overlay.value = 'edit';
|
|
32
|
+
} }
|
|
33
|
+
function action(name, model) {
|
|
34
|
+
selectedId.value = model.id;
|
|
35
|
+
if (name === 'toggle') {
|
|
36
|
+
confirmAction({ title: model.enabled ? '停用' + model.name : '启用' + model.name, content: model.enabled ? '停用后阻止新调用。当前生效版本与历史记录保留;在途任务策略仍待运行契约验证。' : '启用已发布的配置。草稿保存或测试成功不能替代发布。', okText: model.enabled ? '确认停用' : '确认启用', cancelText: '取消', okButtonProps: { danger: model.enabled }, onOk: () => { try {
|
|
37
|
+
store.toggle(model.id, model.recordVersion);
|
|
38
|
+
message.success('状态已更新(演示)');
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
message.error(e.message);
|
|
42
|
+
return Promise.reject(e);
|
|
43
|
+
} } });
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
overlay.value = name;
|
|
47
|
+
if (name === 'detail')
|
|
48
|
+
router.replace({ path: '/models', query: { model: model.id } });
|
|
49
|
+
}
|
|
50
|
+
function saved(id) { selectedId.value = id; overlay.value = 'detail'; message.success('草稿已保存,当前生效版本保持不变'); }
|
|
51
|
+
return { confirmAction, computed, ref, watch, useRoute, useRouter, Alert, Button, Tabs, Result, Drawer, message, PlusOutlined, useModels, useSession, ModelTable, ModelEditor, ModelDetail, ModelTester, ModelGrant, ModelRelease, ModelReferences, UsagePanel, AuditPanel, store, session, route, router, tab, selectedId, overlay, selected, tabs, close, create, action, saved };
|
|
52
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/RowActions.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<div class="row-actions"><template data-component="Button" type="text" class="link-button" data-bind-disabled="(!session.can('model:test', 'platform') || model.publishState === 'review')" data-bind-aria-label="('测试' + model.name)" data-on-click="(emit('action', 'test', model))">测试</template><template data-component="ListMore" data-bind-name="(model.name)" data-bind-items="(items)" data-on-action="(emit('action', $event, model))"></template></div>
|
package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { computed } from '../../runtime/state.js';
|
|
2
|
+
import { Button } from "../../runtime/widgets.js";
|
|
3
|
+
import ListMore from "../shared/ListMore.js";
|
|
4
|
+
import { useSession } from "../shared/session.js";
|
|
5
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
6
|
+
export default createComponent({ name: 'RowActions', propKeys: ["model"], template: new URL('./RowActions.html', import.meta.url).href, setup(__props, __emit) {
|
|
7
|
+
const props = __props, emit = __emit, session = useSession();
|
|
8
|
+
const items = computed(() => [
|
|
9
|
+
{ key: 'detail', label: '查看详情' },
|
|
10
|
+
{ key: 'edit', label: '编辑配置', disabled: !session.can('model:edit', 'platform') || props.model.publishState === 'review' },
|
|
11
|
+
{ key: 'release', label: props.model.publishState === 'review' ? '查看发布申请' : '配置发布', disabled: !session.readable('model:view', 'platform') },
|
|
12
|
+
{ key: 'grant', label: '使用授权', disabled: !session.can('model:grant', 'platform') },
|
|
13
|
+
{ key: 'references', label: '资源引用', disabled: !session.readable('model:view', 'platform') },
|
|
14
|
+
{ type: 'divider' },
|
|
15
|
+
{ key: 'toggle', label: props.model.enabled ? '停用模型' : '启用模型', disabled: !session.can('model:status', 'platform') },
|
|
16
|
+
{ key: 'delete', label: '删除模型', danger: true, disabled: !session.can('model:delete', 'platform') },
|
|
17
|
+
]);
|
|
18
|
+
return { computed, Button, ListMore, useSession, props, emit, session, items };
|
|
19
|
+
} });
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<!-- 来源:src/models/UsagePanel.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
|
|
2
|
+
<section class="panel usage-panel"><div class="section-heading"><h2>模型用量</h2><div class="usage-filters"><template data-component="Select" data-model-value="(period)" aria-label="用量周期" data-bind-options="([{ label: '最近 7 天', value: 7 }, { label: '最近 30 天', value: 30 }])"></template><template data-component="Select" data-model-value="(project)" aria-label="用量项目" data-bind-options="([{ label: '全部项目', value: 'all' }, ...projects.map(p => ({ label: p, value: p }))])"></template></div></div><template data-component="Alert" type="info" show-icon="" title="演示用量与价格,仅用于确认展示口径;不代表真实账单。"></template><div class="usage-metrics"><div><span>Token 总量</span><strong>{{ (fmtNumber(totals.tokens)) }}</strong><small>输入 + 输出</small></div><div><span>模型调用</span><strong>{{ (fmtNumber(totals.requests)) }}</strong><small>次 · 所选周期</small></div><div><span>估算费用</span><strong>{{ (money(totals.cost)) }}</strong><small>人民币 · 按演示单价计算</small></div></div><template data-component="ProTable" data-bind-table="(table)" data-bind-table-container="(false)" data-bind-control="(false)" row-key="id" data-bind-scroll="({ x: 780 })" data-bind-pagination="({ showTotal: (t) => `共 ${t} 条`, hideOnSinglePage: false })"></template><p class="muted">估算公式:输入 Token × 输入单价 + 输出 Token × 输出单价;单价以每百万 Token 计。</p></section>
|
package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { computed, ref, watch } from '../../runtime/state.js';
|
|
2
|
+
import { h } from '../../runtime/dom.js';
|
|
3
|
+
import { Alert, Select } from "../../runtime/widgets.js";
|
|
4
|
+
import { ProTable, useTable } from "../../runtime/widgets.js";
|
|
5
|
+
import { fmtNumber } from "./data.js";
|
|
6
|
+
import { useModels } from "./store.js";
|
|
7
|
+
import { createComponent } from '../../runtime/dom.js';
|
|
8
|
+
export default createComponent({ name: 'UsagePanel', propKeys: [], template: new URL('./UsagePanel.html', import.meta.url).href, setup(__props, __emit) {
|
|
9
|
+
const store = useModels(), period = ref(7), project = ref('all');
|
|
10
|
+
const projects = computed(() => [...new Set(store.models.flatMap(m => m.projects))]);
|
|
11
|
+
const rows = computed(() => store.models.map(m => {
|
|
12
|
+
const i = Number(m.id.replace('demo-', '')) - 1;
|
|
13
|
+
const included = project.value === 'all' || m.projects.includes(project.value);
|
|
14
|
+
const factor = (period.value === 7 ? 1 : 4) * (project.value === 'all' ? Math.max(1, m.projects.length) : 1);
|
|
15
|
+
const requests = m.id.startsWith('demo-') && m.projects.length && included ? (680 + (5 - i) * 147) * factor : 0;
|
|
16
|
+
const input = requests * 1120, output = m.kind === 'embedding' ? 0 : requests * 360;
|
|
17
|
+
return { id: m.id, name: m.name, requests, input, output, cost: (input * m.inputPrice + output * m.outputPrice) / 1000000 };
|
|
18
|
+
}).filter(r => project.value === 'all' || r.requests > 0));
|
|
19
|
+
const totals = computed(() => rows.value.reduce((a, x) => ({ tokens: a.tokens + x.input + x.output, requests: a.requests + x.requests, cost: a.cost + x.cost }), { tokens: 0, requests: 0, cost: 0 }));
|
|
20
|
+
const money = (n) => `¥${n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
21
|
+
const table = useTable({ columns: [
|
|
22
|
+
{ title: '模型', dataIndex: 'name', width: 210 },
|
|
23
|
+
{ title: '调用次数', dataIndex: 'requests', align: 'right', render: (text) => fmtNumber(Number(text)) },
|
|
24
|
+
{ title: '输入 Token', dataIndex: 'input', align: 'right', render: (text) => fmtNumber(Number(text)) },
|
|
25
|
+
{ title: '输出 Token', dataIndex: 'output', align: 'right', render: (text) => fmtNumber(Number(text)) },
|
|
26
|
+
{ title: '估算费用(元)', dataIndex: 'cost', align: 'right', width: 180, render: (text) => h('strong', money(Number(text))) },
|
|
27
|
+
] });
|
|
28
|
+
watch(rows, () => { table.dataSource.value = rows.value; table.setPageParam({ total: rows.value.length }); }, { immediate: true });
|
|
29
|
+
return { computed, ref, watch, h, Alert, Select, ProTable, useTable, fmtNumber, useModels, store, period, project, projects, rows, totals, money, table };
|
|
30
|
+
} });
|