procesio-cli 0.1.1__py3-none-any.whl
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.
- procesio_cli/__init__.py +18 -0
- procesio_cli/_cli.py +71 -0
- procesio_cli/agents/__init__.py +0 -0
- procesio_cli/agents/_lib/__init__.py +0 -0
- procesio_cli/agents/_lib/actiondef.py +24 -0
- procesio_cli/agents/_lib/errors.py +40 -0
- procesio_cli/agents/_lib/reversibility.py +236 -0
- procesio_cli/agents/_lib/toolrunner.py +141 -0
- procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-PLAYBOOK.md +62 -0
- procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-PROCESIO-INTEROP.md +76 -0
- procesio_cli/agents/connector-builder/CONNECTOR-BUILDER-TROUBLESHOOTING.md +60 -0
- procesio_cli/agents/connector-builder/README.md +51 -0
- procesio_cli/agents/connector-builder/agent.yaml +61 -0
- procesio_cli/agents/connector-builder/context.py +19 -0
- procesio_cli/agents/connector-builder/handlers/__init__.py +1 -0
- procesio_cli/agents/connector-builder/handlers/checklist.py +71 -0
- procesio_cli/agents/connector-builder/handlers/guidance.py +37 -0
- procesio_cli/agents/connector-builder/handlers/nextstep.py +221 -0
- procesio_cli/agents/connector-builder/handlers/status.py +35 -0
- procesio_cli/agents/connector-builder/knowledge.py +47 -0
- procesio_cli/agents/connector-builder/main.py +93 -0
- procesio_cli/agents/connector-builder/tests/conftest.py +95 -0
- procesio_cli/agents/connector-builder/tests/test_cba_agent.py +148 -0
- procesio_cli/agents/orchestrator/__init__.py +0 -0
- procesio_cli/agents/orchestrator/bootstraplib.py +166 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/00-INDEX.md +60 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/01-PROCESSES.md +230 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/02-FORMS.md +287 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/03-INTEGRATIONS.md +384 -0
- procesio_cli/agents/procesio/IMPLEMENTATION-PATTERNS/04-DATABASE.md +293 -0
- procesio_cli/agents/procesio/PROCESIO-API-RELIABILITY-DOCTRINE.md +113 -0
- procesio_cli/agents/procesio/PROCESIO-BEST-PRACTICES.md +316 -0
- procesio_cli/agents/procesio/PROCESIO-BUILD-AND-TEST-PLAYBOOK.md +217 -0
- procesio_cli/agents/procesio/PROCESIO-DATASTORE.md +72 -0
- procesio_cli/agents/procesio/PROCESIO-ENVIRONMENTS.md +62 -0
- procesio_cli/agents/procesio/PROCESIO-SCHEDULING.md +47 -0
- procesio_cli/agents/procesio/PROCESIO-VISUAL-ORGANIZATION.md +175 -0
- procesio_cli/agents/procesio/README.md +97 -0
- procesio_cli/agents/procesio/__init__.py +0 -0
- procesio_cli/agents/procesio/agent.yaml +73 -0
- procesio_cli/agents/procesio/audit.py +226 -0
- procesio_cli/agents/procesio/checklist.py +135 -0
- procesio_cli/agents/procesio/context.py +19 -0
- procesio_cli/agents/procesio/handlers/__init__.py +0 -0
- procesio_cli/agents/procesio/handlers/audit.py +39 -0
- procesio_cli/agents/procesio/handlers/checklist.py +34 -0
- procesio_cli/agents/procesio/handlers/guidance.py +36 -0
- procesio_cli/agents/procesio/handlers/status.py +33 -0
- procesio_cli/agents/procesio/handlers/verify.py +39 -0
- procesio_cli/agents/procesio/knowledge.py +115 -0
- procesio_cli/agents/procesio/main.py +89 -0
- procesio_cli/agents/procesio/tests/__init__.py +0 -0
- procesio_cli/agents/procesio/tests/conftest.py +62 -0
- procesio_cli/agents/procesio/tests/test_audit.py +91 -0
- procesio_cli/agents/procesio/tests/test_checklist.py +28 -0
- procesio_cli/agents/procesio/tests/test_guidance.py +78 -0
- procesio_cli/agents/procesio/tests/test_manifest_sync.py +48 -0
- procesio_cli/agents/procesio/tests/test_verify.py +134 -0
- procesio_cli/agents/procesio/tests/test_workspace_scope.py +97 -0
- procesio_cli/agents/procesio/verifylib.py +222 -0
- procesio_cli/dashboard/README.md +117 -0
- procesio_cli/dashboard/__init__.py +18 -0
- procesio_cli/dashboard/serve.py +98 -0
- procesio_cli/dashboard/server/__init__.py +1 -0
- procesio_cli/dashboard/server/config_schemas.py +92 -0
- procesio_cli/dashboard/server/google.py +103 -0
- procesio_cli/dashboard/server/handler.py +160 -0
- procesio_cli/dashboard/server/inventory.py +213 -0
- procesio_cli/dashboard/server/jobs.py +118 -0
- procesio_cli/dashboard/server/llmtest.py +181 -0
- procesio_cli/dashboard/server/procesio_env.py +94 -0
- procesio_cli/dashboard/server/routes.py +74 -0
- procesio_cli/dashboard/server/runner.py +150 -0
- procesio_cli/dashboard/server/security.py +29 -0
- procesio_cli/dashboard/server/setup.py +211 -0
- procesio_cli/dashboard/server/validate.py +152 -0
- procesio_cli/dashboard/tests/conftest.py +16 -0
- procesio_cli/dashboard/tests/test_dashboard.py +225 -0
- procesio_cli/dashboard/tests/test_procesio_env.py +159 -0
- procesio_cli/dashboard/web/actions.js +274 -0
- procesio_cli/dashboard/web/api.js +79 -0
- procesio_cli/dashboard/web/app.js +385 -0
- procesio_cli/dashboard/web/copilot.js +72 -0
- procesio_cli/dashboard/web/google.js +121 -0
- procesio_cli/dashboard/web/index.html +67 -0
- procesio_cli/dashboard/web/procesio_env.js +187 -0
- procesio_cli/dashboard/web/styles.css +207 -0
- procesio_cli/registry.py +370 -0
- procesio_cli/scripts/build-router.py +249 -0
- procesio_cli/scripts/build-tool-skill.py +202 -0
- procesio_cli/scripts/check-requirements.py +131 -0
- procesio_cli/scripts/check-skill-governance.py +174 -0
- procesio_cli/scripts/evaluate-skill-routing.py +217 -0
- procesio_cli/scripts/evaluate-skills.py +316 -0
- procesio_cli/scripts/get-skill.py +122 -0
- procesio_cli/scripts/list-skills.py +68 -0
- procesio_cli/scripts/list-tools.py +73 -0
- procesio_cli/scripts/run-agent.py +59 -0
- procesio_cli/scripts/run-tool.py +123 -0
- procesio_cli/scripts/secret_scan.py +584 -0
- procesio_cli/scripts/set-credential.py +126 -0
- procesio_cli/scripts/validate-skills.py +530 -0
- procesio_cli/skills/PORTFOLIO.md +134 -0
- procesio_cli/skills/__init__.py +6 -0
- procesio_cli/skills/agent-skill-engineer/SKILL.md +226 -0
- procesio_cli/skills/agent-skill-engineer/evals/evals.json +422 -0
- procesio_cli/skills/agent-skill-engineer/references/authoring-standard.md +178 -0
- procesio_cli/skills/agent-skill-engineer/references/decision-framework.md +107 -0
- procesio_cli/skills/agent-skill-engineer/references/domain-evidence-protocol.md +248 -0
- procesio_cli/skills/agent-skill-engineer/references/evaluation-standard.md +191 -0
- procesio_cli/skills/agent-skill-engineer/references/expert-lenses.md +167 -0
- procesio_cli/skills/agent-skill-engineer/references/field-gate-standard.md +231 -0
- procesio_cli/skills/agent-skill-engineer/references/optimization-protocol.md +233 -0
- procesio_cli/skills/agent-skill-engineer/references/optimizer-contract.md +268 -0
- procesio_cli/skills/agent-skill-engineer/references/portability-standard.md +99 -0
- procesio_cli/skills/agent-skill-engineer/references/research-basis.md +128 -0
- procesio_cli/skills/agent-skill-engineer/references/review-standard.md +143 -0
- procesio_cli/skills/agent-skill-engineer/scripts/audit_skill.py +959 -0
- procesio_cli/skills/agent-skill-engineer/scripts/optimize_skill.py +891 -0
- procesio_cli/skills/agent-skill-engineer/scripts/scaffold_skill.py +397 -0
- procesio_cli/skills/evals/baseline-catalog.json +14 -0
- procesio_cli/skills/evals/baseline-routing-v2.json +38 -0
- procesio_cli/skills/evals/baseline.json +37 -0
- procesio_cli/skills/evals/behavioral.json +367 -0
- procesio_cli/skills/evals/field-boundary-development-v1.json +126 -0
- procesio_cli/skills/evals/field-closeout-correction-development-v1.json +23 -0
- procesio_cli/skills/evals/field-closeout-development-v1.json +89 -0
- procesio_cli/skills/evals/portfolio-pressure-training-v1.json +83 -0
- procesio_cli/skills/evals/routing.json +363 -0
- procesio_cli/skills/evals/validation-baseline.json +4 -0
- procesio_cli/skills/procesio-cli/SKILL.md +134 -0
- procesio_cli/skills/procesio-cli/evals/evals.json +111 -0
- procesio_cli/skills/procesio-cli/evals/workflows.json +16 -0
- procesio_cli/skills/procesio-cli/references/connector-lifecycle.md +47 -0
- procesio_cli/skills/procesio-cli/references/credentials-admin.md +113 -0
- procesio_cli/skills/procesio-cli/references/data-verification.md +71 -0
- procesio_cli/skills/procesio-cli/references/documents-files.md +44 -0
- procesio_cli/skills/procesio-cli/references/form-e2e.md +57 -0
- procesio_cli/skills/procesio-cli/references/operation-contract.md +138 -0
- procesio_cli/skills/procesio-cli/references/process-debugging.md +65 -0
- procesio_cli/skills/procesio-cli/references/process-lifecycle.md +88 -0
- procesio_cli/skills/procesio-cli/references/schedules-webhooks.md +58 -0
- procesio_cli/skills/procesio-cli/references/transport-environments.md +53 -0
- procesio_cli/skills/procesio-cli-maintainer/SKILL.md +84 -0
- procesio_cli/skills/procesio-cli-maintainer/evals/evals.json +116 -0
- procesio_cli/skills/procesio-cli-maintainer/references/change-contract.md +34 -0
- procesio_cli/skills/procesio-cli-maintainer/references/mcp-compatibility.md +13 -0
- procesio_cli/skills/procesio-cli-maintainer/references/skill-authoring.md +51 -0
- procesio_cli/skills/procesio-platform-advisor/SKILL.md +82 -0
- procesio_cli/skills/procesio-platform-advisor/evals/evals.json +116 -0
- procesio_cli/skills/procesio-platform-advisor/references/capability-map.md +22 -0
- procesio_cli/skills/procesio-platform-advisor/references/fit-framework.md +35 -0
- procesio_cli/skills/procesio-platform-advisor/references/freshness-policy.md +25 -0
- procesio_cli/skills/procesio-platform-advisor/references/sizing-method.md +70 -0
- procesio_cli/skills/procesio-platform-advisor/scripts/estimate_capacity.py +99 -0
- procesio_cli/skills/procesio-setup/SKILL.md +180 -0
- procesio_cli/skills/sql-server-optimizer/SKILL.md +86 -0
- procesio_cli/skills/sql-server-optimizer/evals/evals.json +116 -0
- procesio_cli/skills/sql-server-optimizer/references/db-context.md +44 -0
- procesio_cli/skills/sql-server-optimizer/references/generic-mode.md +32 -0
- procesio_cli/skills/sql-server-optimizer/references/procesio-mode.md +40 -0
- procesio_cli/skills/sql-server-optimizer/references/sql-rules.md +43 -0
- procesio_cli/skills/sql-server-optimizer/scripts/export-indexes.sql +178 -0
- procesio_cli/skills/sql-server-optimizer/scripts/export-procs-and-functions.sql +118 -0
- procesio_cli/skills/sql-server-optimizer/scripts/export-tables.sql +367 -0
- procesio_cli/skills/tests/__init__.py +0 -0
- procesio_cli/skills/tests/test_agent_skill_engineer.py +240 -0
- procesio_cli/skills/tests/test_auth_failure_stop.py +25 -0
- procesio_cli/skills/tests/test_capacity_estimator.py +85 -0
- procesio_cli/skills/tests/test_field_boundary_learning.py +100 -0
- procesio_cli/skills/tests/test_field_closeout_learning.py +123 -0
- procesio_cli/skills/tests/test_field_gate_standard.py +76 -0
- procesio_cli/skills/tests/test_operational_playbooks.py +51 -0
- procesio_cli/skills/tests/test_portfolio_pressure_training.py +35 -0
- procesio_cli/skills/tests/test_process_lifecycle_single_run.py +25 -0
- procesio_cli/skills/tests/test_skill_evaluator.py +67 -0
- procesio_cli/skills/tests/test_skill_optimizer.py +473 -0
- procesio_cli/skills/tests/test_skill_portfolio_review.py +70 -0
- procesio_cli/skills/tests/test_skill_release_binding.py +204 -0
- procesio_cli/skills/tests/test_skill_routing.py +74 -0
- procesio_cli/skills/tests/test_skill_scaffold_v2.py +116 -0
- procesio_cli/skills/tests/test_validate_skills.py +115 -0
- procesio_cli/tools/__init__.py +0 -0
- procesio_cli/tools/_lib/README.md +119 -0
- procesio_cli/tools/_lib/__init__.py +0 -0
- procesio_cli/tools/_lib/accounting.py +120 -0
- procesio_cli/tools/_lib/contacts.py +544 -0
- procesio_cli/tools/_lib/creds.py +83 -0
- procesio_cli/tools/_lib/creds_backends.py +578 -0
- procesio_cli/tools/_lib/dbprofiles.py +147 -0
- procesio_cli/tools/_lib/dbquery.py +286 -0
- procesio_cli/tools/_lib/dbschema.py +225 -0
- procesio_cli/tools/_lib/io.py +54 -0
- procesio_cli/tools/_lib/manifest.py +297 -0
- procesio_cli/tools/_lib/skill_release.py +127 -0
- procesio_cli/tools/_lib/skill_resources.py +118 -0
- procesio_cli/tools/_lib/userdata.py +228 -0
- procesio_cli/tools/_lib/webserialize/__init__.py +16 -0
- procesio_cli/tools/_lib/webserialize/admin.py +61 -0
- procesio_cli/tools/_lib/webserialize/client.py +264 -0
- procesio_cli/tools/_lib/webserialize/config.py +96 -0
- procesio_cli/tools/_lib/webserialize/errors.py +27 -0
- procesio_cli/tools/_lib/webserialize/framing.py +45 -0
- procesio_cli/tools/_lib/webserialize/registry.py +47 -0
- procesio_cli/tools/_lib/webserialize/runtime.py +61 -0
- procesio_cli/tools/_lib/webserialize/server.py +510 -0
- procesio_cli/tools/_lib/websession.py +194 -0
- procesio_cli/tools/connector-builder/CONNECTOR-BUILDER-API-NOTES.md +91 -0
- procesio_cli/tools/connector-builder/README.md +101 -0
- procesio_cli/tools/connector-builder/SKILL.md +248 -0
- procesio_cli/tools/connector-builder/__init__.py +7 -0
- procesio_cli/tools/connector-builder/actiondef.py +24 -0
- procesio_cli/tools/connector-builder/client.py +251 -0
- procesio_cli/tools/connector-builder/errors.py +44 -0
- procesio_cli/tools/connector-builder/gen_manifest.py +142 -0
- procesio_cli/tools/connector-builder/handlers/__init__.py +1 -0
- procesio_cli/tools/connector-builder/handlers/admin.py +182 -0
- procesio_cli/tools/connector-builder/handlers/auth.py +74 -0
- procesio_cli/tools/connector-builder/handlers/builds.py +396 -0
- procesio_cli/tools/connector-builder/handlers/common.py +104 -0
- procesio_cli/tools/connector-builder/handlers/files.py +111 -0
- procesio_cli/tools/connector-builder/handlers/raw.py +38 -0
- procesio_cli/tools/connector-builder/handlers/telemetry.py +39 -0
- procesio_cli/tools/connector-builder/main.py +94 -0
- procesio_cli/tools/connector-builder/tests/conftest.py +146 -0
- procesio_cli/tools/connector-builder/tests/test_cb_client.py +86 -0
- procesio_cli/tools/connector-builder/tests/test_cb_dispatch.py +105 -0
- procesio_cli/tools/connector-builder/tests/test_cb_manifest_sync.py +76 -0
- procesio_cli/tools/connector-builder/tests/test_cb_wait.py +123 -0
- procesio_cli/tools/connector-builder/tool.yaml +671 -0
- procesio_cli/tools/framework-map/.gitattributes +2 -0
- procesio_cli/tools/framework-map/README.md +98 -0
- procesio_cli/tools/framework-map/SKILL.md +30 -0
- procesio_cli/tools/framework-map/app.js +188 -0
- procesio_cli/tools/framework-map/fm_builder.py +476 -0
- procesio_cli/tools/framework-map/fm_catalog.py +19 -0
- procesio_cli/tools/framework-map/fm_ro_catalog.py +94 -0
- procesio_cli/tools/framework-map/fm_strings.py +101 -0
- procesio_cli/tools/framework-map/main.py +95 -0
- procesio_cli/tools/framework-map/styles.css +214 -0
- procesio_cli/tools/framework-map/tests/conftest.py +33 -0
- procesio_cli/tools/framework-map/tests/test_fm_build.py +126 -0
- procesio_cli/tools/framework-map/tests/test_fm_manifest_sync.py +63 -0
- procesio_cli/tools/framework-map/tests/test_fm_store_tree.py +75 -0
- procesio_cli/tools/framework-map/tool.yaml +61 -0
- procesio_cli/tools/mysql/MOVED-TO-CENTRAL.md +29 -0
- procesio_cli/tools/mysql/README.md +196 -0
- procesio_cli/tools/mysql/SKILL.md +37 -0
- procesio_cli/tools/mysql/__init__.py +0 -0
- procesio_cli/tools/mysql/connection.py +191 -0
- procesio_cli/tools/mysql/main.py +487 -0
- procesio_cli/tools/mysql/profiles.template.json +1 -0
- procesio_cli/tools/mysql/schema.py +434 -0
- procesio_cli/tools/mysql/tests/__init__.py +0 -0
- procesio_cli/tools/mysql/tests/conftest.py +21 -0
- procesio_cli/tools/mysql/tests/test_manifest_sync.py +68 -0
- procesio_cli/tools/mysql/tests/test_mysql.py +201 -0
- procesio_cli/tools/mysql/tests/test_mysql_schema.py +337 -0
- procesio_cli/tools/mysql/tool.yaml +112 -0
- procesio_cli/tools/procesio/DTO-SUBTOOLS-NOTE.md +360 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/00-INDEX.md +67 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/01-ANATOMY.md +209 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/02-CODE-INJECTION.md +309 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/03-DOM-CONTRACT.md +370 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/04-INTERACTION-RECIPES.md +600 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/05-STEPPER-AND-MOTION.md +426 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/06-PROCESS-INTEGRATION.md +347 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/07-DEPLOY-WORKFLOW.md +294 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/08-PITFALLS.md +569 -0
- procesio_cli/tools/procesio/FORM-DEV-GUIDE/09-NAVIGATION-AND-HOSTING.md +308 -0
- procesio_cli/tools/procesio/PHASE4-E2E-NOTES.md +594 -0
- procesio_cli/tools/procesio/PROCESIO-API-CORRECTIONS.md +295 -0
- procesio_cli/tools/procesio/PROCESIO-API-NOTES.md +6976 -0
- procesio_cli/tools/procesio/PROCESIO-AUTH-NOTES.md +226 -0
- procesio_cli/tools/procesio/PROCESIO-CARD-BUILD-NOTES.md +183 -0
- procesio_cli/tools/procesio/PROCESIO-CONNECTORS-NOTES.md +141 -0
- procesio_cli/tools/procesio/PROCESIO-CUSTOM-ACTION-NOTES.md +179 -0
- procesio_cli/tools/procesio/PROCESIO-DOCS-FIX-REPORT.md +123 -0
- procesio_cli/tools/procesio/PROCESIO-ENVIRONMENTS-NOTES.md +94 -0
- procesio_cli/tools/procesio/PROCESIO-FE-VALIDATION-NOTES.md +107 -0
- procesio_cli/tools/procesio/PROCESIO-FOREACH-NOTES.md +199 -0
- procesio_cli/tools/procesio/PROCESIO-FORM-API-HANG-NOTE.md +101 -0
- procesio_cli/tools/procesio/PROCESIO-FORM-SUBMISSION-NOTES.md +172 -0
- procesio_cli/tools/procesio/PROCESIO-HTML-TO-DOCX-NOTES.md +110 -0
- procesio_cli/tools/procesio/PROCESIO-INSTANCE-HISTORY-NOTES.md +242 -0
- procesio_cli/tools/procesio/PROCESIO-METERING-NOTES.md +201 -0
- procesio_cli/tools/procesio/PROCESIO-NODE-CODE-NOTES.md +279 -0
- procesio_cli/tools/procesio/PROCESIO-NODE-MODULE-WHITELIST.md +113 -0
- procesio_cli/tools/procesio/PROCESIO-PYTHON-ACTION-NOTES.md +165 -0
- procesio_cli/tools/procesio/PROCESIO-QUERY-STORE-NOTES.md +826 -0
- procesio_cli/tools/procesio/PROCESIO-RECONCILIATION-PATTERNS.md +104 -0
- procesio_cli/tools/procesio/PROCESIO-RESOURCE-MODEL-NOTES.md +1100 -0
- procesio_cli/tools/procesio/PROCESIO-SEND-EMAIL-CRED-OPTIONALITY.md +45 -0
- procesio_cli/tools/procesio/PROCESIO-SEND-EMAIL-NOTES.md +252 -0
- procesio_cli/tools/procesio/PROCESIO-SQL-ACTIONS-NOTES.md +284 -0
- procesio_cli/tools/procesio/PROCESIO-USAGE-GUIDE.md +219 -0
- procesio_cli/tools/procesio/README.md +341 -0
- procesio_cli/tools/procesio/SCHEDULE-INPUT-SECURITY-NOTES.md +63 -0
- procesio_cli/tools/procesio/SKILL.md +694 -0
- procesio_cli/tools/procesio/__init__.py +1 -0
- procesio_cli/tools/procesio/actiondef.py +27 -0
- procesio_cli/tools/procesio/assets/html2docx/html2docx.js +2155 -0
- procesio_cli/tools/procesio/auth.py +354 -0
- procesio_cli/tools/procesio/autogen.py +121 -0
- procesio_cli/tools/procesio/client.py +355 -0
- procesio_cli/tools/procesio/config.py +96 -0
- procesio_cli/tools/procesio/data/endpoints.json +2901 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/01-authentication.md +180 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/02-conventions.md +116 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/ANONYMOUS-SURFACE.md +51 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/README.md +104 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/SYMBOL-INDEX.md +444 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/03-auth-users-workspaces.md +731 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/04-processes.md +913 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/05-actions.md +605 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/06-files.md +237 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/07-forms-documents.md +985 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/08-credentials.md +532 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/09-datastore-datatypes.md +830 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/10-custom-urls.md +319 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/11-subscriptions-resources-analytics.md +455 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/12-webhooks-notifications-misc.md +519 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/13-realtime-signalr.md +153 -0
- procesio_cli/tools/procesio/docs_info/API-DOCUMENTATION/endpoints/99-internal-and-other-services.md +52 -0
- procesio_cli/tools/procesio/docs_info/FormBuilder mock.ts +5725 -0
- procesio_cli/tools/procesio/docs_info/Procesio Platform Actions.json +30219 -0
- procesio_cli/tools/procesio/docs_info/form-config-enums.ts +92 -0
- procesio_cli/tools/procesio/docs_info/form-theme.ts +1603 -0
- procesio_cli/tools/procesio/docs_info/process-validation-reference-1.md +2739 -0
- procesio_cli/tools/procesio/dto/__init__.py +13 -0
- procesio_cli/tools/procesio/dto/credential/builder.py +179 -0
- procesio_cli/tools/procesio/dto/credential/config.schema.json +19 -0
- procesio_cli/tools/procesio/dto/credential/description.md +193 -0
- procesio_cli/tools/procesio/dto/credential/fixtures/rest.config.json +11 -0
- procesio_cli/tools/procesio/dto/credential/fixtures/rest.dto.json +28 -0
- procesio_cli/tools/procesio/dto/credential/fixtures/rest.template.json +44 -0
- procesio_cli/tools/procesio/dto/credential/template.dto.json +16 -0
- procesio_cli/tools/procesio/dto/data/_refresh.py +147 -0
- procesio_cli/tools/procesio/dto/data/action_catalog.json +30825 -0
- procesio_cli/tools/procesio/dto/data/action_families.json +55 -0
- procesio_cli/tools/procesio/dto/data/platform_types.json +182 -0
- procesio_cli/tools/procesio/dto/datatype/builder.py +223 -0
- procesio_cli/tools/procesio/dto/datatype/config.schema.json +47 -0
- procesio_cli/tools/procesio/dto/datatype/description.md +85 -0
- procesio_cli/tools/procesio/dto/datatype/fixtures/customer.config.json +41 -0
- procesio_cli/tools/procesio/dto/datatype/fixtures/customer.dto.json +164 -0
- procesio_cli/tools/procesio/dto/datatype/template.dto.json +37 -0
- procesio_cli/tools/procesio/dto/document/builder.py +193 -0
- procesio_cli/tools/procesio/dto/document/config.schema.json +33 -0
- procesio_cli/tools/procesio/dto/document/description.md +124 -0
- procesio_cli/tools/procesio/dto/document/fixtures/invoice.config.json +16 -0
- procesio_cli/tools/procesio/dto/document/fixtures/invoice.dto.json +32 -0
- procesio_cli/tools/procesio/dto/document/template.dto.json +14 -0
- procesio_cli/tools/procesio/dto/form/FORM-STYLING-NOTES.md +142 -0
- procesio_cli/tools/procesio/dto/form/GOLDEN-DRIFT-NOTES.md +72 -0
- procesio_cli/tools/procesio/dto/form/RUN-PROCESS-RESULT-NOTES.md +80 -0
- procesio_cli/tools/procesio/dto/form/addelement.py +277 -0
- procesio_cli/tools/procesio/dto/form/builder.py +1009 -0
- procesio_cli/tools/procesio/dto/form/capture_goldens.py +106 -0
- procesio_cli/tools/procesio/dto/form/code_cipher.py +67 -0
- procesio_cli/tools/procesio/dto/form/config.schema.json +76 -0
- procesio_cli/tools/procesio/dto/form/data_shell.json +1 -0
- procesio_cli/tools/procesio/dto/form/description.md +346 -0
- procesio_cli/tools/procesio/dto/form/elements/approval.json +259 -0
- procesio_cli/tools/procesio/dto/form/elements/assignee.json +137 -0
- procesio_cli/tools/procesio/dto/form/elements/button.json +125 -0
- procesio_cli/tools/procesio/dto/form/elements/chart.json +341 -0
- procesio_cli/tools/procesio/dto/form/elements/chat.json +199 -0
- procesio_cli/tools/procesio/dto/form/elements/checkbox.json +153 -0
- procesio_cli/tools/procesio/dto/form/elements/column.json +77 -0
- procesio_cli/tools/procesio/dto/form/elements/columns.json +78 -0
- procesio_cli/tools/procesio/dto/form/elements/datetime-input.json +304 -0
- procesio_cli/tools/procesio/dto/form/elements/divider.json +54 -0
- procesio_cli/tools/procesio/dto/form/elements/dropdown.json +130 -0
- procesio_cli/tools/procesio/dto/form/elements/dynamic-table-row.json +253 -0
- procesio_cli/tools/procesio/dto/form/elements/file-upload.json +196 -0
- procesio_cli/tools/procesio/dto/form/elements/file-viewer.json +169 -0
- procesio_cli/tools/procesio/dto/form/elements/heading.json +79 -0
- procesio_cli/tools/procesio/dto/form/elements/icon.json +107 -0
- procesio_cli/tools/procesio/dto/form/elements/image.json +174 -0
- procesio_cli/tools/procesio/dto/form/elements/input.json +206 -0
- procesio_cli/tools/procesio/dto/form/elements/list.json +202 -0
- procesio_cli/tools/procesio/dto/form/elements/number-input.json +202 -0
- procesio_cli/tools/procesio/dto/form/elements/paragraph.json +79 -0
- procesio_cli/tools/procesio/dto/form/elements/radiobox.json +174 -0
- procesio_cli/tools/procesio/dto/form/elements/section.json +114 -0
- procesio_cli/tools/procesio/dto/form/elements/select.json +217 -0
- procesio_cli/tools/procesio/dto/form/elements/side-panel.json +146 -0
- procesio_cli/tools/procesio/dto/form/elements/signature-pad.json +141 -0
- procesio_cli/tools/procesio/dto/form/elements/static-table-row.json +84 -0
- procesio_cli/tools/procesio/dto/form/elements/step.json +105 -0
- procesio_cli/tools/procesio/dto/form/elements/stepper.json +126 -0
- procesio_cli/tools/procesio/dto/form/elements/tab.json +77 -0
- procesio_cli/tools/procesio/dto/form/elements/table.json +279 -0
- procesio_cli/tools/procesio/dto/form/elements/tabs.json +114 -0
- procesio_cli/tools/procesio/dto/form/elements/textarea.json +213 -0
- procesio_cli/tools/procesio/dto/form/enum_map.json +68 -0
- procesio_cli/tools/procesio/dto/form/fieldpath.py +284 -0
- procesio_cli/tools/procesio/dto/form/fixtures/reg.config.json +32 -0
- procesio_cli/tools/procesio/dto/form/fixtures/reg.elements.json +638 -0
- procesio_cli/tools/procesio/dto/form/sync_from_mock.py +386 -0
- procesio_cli/tools/procesio/dto/framework.py +125 -0
- procesio_cli/tools/procesio/dto/process/builder.py +1991 -0
- procesio_cli/tools/procesio/dto/process/config.schema.json +159 -0
- procesio_cli/tools/procesio/dto/process/description.md +218 -0
- procesio_cli/tools/procesio/dto/process/fixtures/greet.config.json +32 -0
- procesio_cli/tools/procesio/dto/process/fixtures/greet.dto.json +317 -0
- procesio_cli/tools/procesio/dto/process/naming.py +305 -0
- procesio_cli/tools/procesio/dto/process/normalize.py +74 -0
- procesio_cli/tools/procesio/dto/process/template.dto.json +32 -0
- procesio_cli/tools/procesio/dto/refdata.py +87 -0
- procesio_cli/tools/procesio/dto/registry.py +27 -0
- procesio_cli/tools/procesio/dto/webhook/builder.py +142 -0
- procesio_cli/tools/procesio/dto/webhook/config.schema.json +25 -0
- procesio_cli/tools/procesio/dto/webhook/description.md +92 -0
- procesio_cli/tools/procesio/dto/webhook/fixtures/order.config.json +10 -0
- procesio_cli/tools/procesio/dto/webhook/fixtures/order.dto.json +25 -0
- procesio_cli/tools/procesio/dto/webhook/template.dto.json +14 -0
- procesio_cli/tools/procesio/environments.py +264 -0
- procesio_cli/tools/procesio/errors.py +166 -0
- procesio_cli/tools/procesio/flowmodel/README.md +37 -0
- procesio_cli/tools/procesio/flowmodel/__init__.py +14 -0
- procesio_cli/tools/procesio/flowmodel/digest.py +223 -0
- procesio_cli/tools/procesio/flowmodel/families.py +34 -0
- procesio_cli/tools/procesio/flowmodel/fevalidation.py +1098 -0
- procesio_cli/tools/procesio/flowmodel/formdigest.py +232 -0
- procesio_cli/tools/procesio/flowmodel/inspect.py +78 -0
- procesio_cli/tools/procesio/flowmodel/model.py +82 -0
- procesio_cli/tools/procesio/flowmodel/nodeparam.py +871 -0
- procesio_cli/tools/procesio/flowmodel/reader.py +191 -0
- procesio_cli/tools/procesio/flowmodel/sqlparam.py +410 -0
- procesio_cli/tools/procesio/form_code_keys.py +50 -0
- procesio_cli/tools/procesio/formlint.py +292 -0
- procesio_cli/tools/procesio/gen_manifest.py +118 -0
- procesio_cli/tools/procesio/handlers/__init__.py +1 -0
- procesio_cli/tools/procesio/handlers/auth_actions.py +103 -0
- procesio_cli/tools/procesio/handlers/catalog.py +147 -0
- procesio_cli/tools/procesio/handlers/common.py +90 -0
- procesio_cli/tools/procesio/handlers/customaction_ops.py +146 -0
- procesio_cli/tools/procesio/handlers/datastore_ops.py +482 -0
- procesio_cli/tools/procesio/handlers/datatype_ops.py +275 -0
- procesio_cli/tools/procesio/handlers/dto_actions.py +258 -0
- procesio_cli/tools/procesio/handlers/environment_admin.py +146 -0
- procesio_cli/tools/procesio/handlers/fevalidate.py +236 -0
- procesio_cli/tools/procesio/handlers/files.py +141 -0
- procesio_cli/tools/procesio/handlers/flowgraph.py +229 -0
- procesio_cli/tools/procesio/handlers/flowlint.py +269 -0
- procesio_cli/tools/procesio/handlers/form_chains.py +336 -0
- procesio_cli/tools/procesio/handlers/form_code.py +277 -0
- procesio_cli/tools/procesio/handlers/form_element.py +199 -0
- procesio_cli/tools/procesio/handlers/form_events.py +441 -0
- procesio_cli/tools/procesio/handlers/form_update.py +270 -0
- procesio_cli/tools/procesio/handlers/formprocess.py +211 -0
- procesio_cli/tools/procesio/handlers/generic.py +135 -0
- procesio_cli/tools/procesio/handlers/layout.py +137 -0
- procesio_cli/tools/procesio/handlers/nodeparams.py +1018 -0
- procesio_cli/tools/procesio/handlers/process_layout.py +189 -0
- procesio_cli/tools/procesio/handlers/process_naming.py +213 -0
- procesio_cli/tools/procesio/handlers/processes.py +416 -0
- procesio_cli/tools/procesio/handlers/profile_admin.py +184 -0
- procesio_cli/tools/procesio/handlers/resource_ops.py +447 -0
- procesio_cli/tools/procesio/handlers/schedules.py +320 -0
- procesio_cli/tools/procesio/handlers/sqlactions.py +232 -0
- procesio_cli/tools/procesio/handlers/transport.py +463 -0
- procesio_cli/tools/procesio/handlers/usageguide.py +222 -0
- procesio_cli/tools/procesio/layout/README.md +196 -0
- procesio_cli/tools/procesio/layout/__init__.py +11 -0
- procesio_cli/tools/procesio/layout/adapter.py +736 -0
- procesio_cli/tools/procesio/layout/cycles.py +186 -0
- procesio_cli/tools/procesio/layout/dispatch.py +39 -0
- procesio_cli/tools/procesio/layout/elk/elk_runner.mjs +50 -0
- procesio_cli/tools/procesio/layout/elk/package-lock.json +21 -0
- procesio_cli/tools/procesio/layout/elk/package.json +11 -0
- procesio_cli/tools/procesio/layout/elk_engine.py +568 -0
- procesio_cli/tools/procesio/layout/engine.py +1311 -0
- procesio_cli/tools/procesio/layout/report.py +187 -0
- procesio_cli/tools/procesio/main.py +179 -0
- procesio_cli/tools/procesio/profiles.py +193 -0
- procesio_cli/tools/procesio/reliability.py +193 -0
- procesio_cli/tools/procesio/sqlformat.py +167 -0
- procesio_cli/tools/procesio/swagger.py +51 -0
- procesio_cli/tools/procesio/tests/__init__.py +0 -0
- procesio_cli/tools/procesio/tests/conftest.py +129 -0
- procesio_cli/tools/procesio/tests/test_auth.py +200 -0
- procesio_cli/tools/procesio/tests/test_autogen.py +78 -0
- procesio_cli/tools/procesio/tests/test_builder_attrpath_sqlbind.py +180 -0
- procesio_cli/tools/procesio/tests/test_builder_custom_action_catalog.py +72 -0
- procesio_cli/tools/procesio/tests/test_client.py +114 -0
- procesio_cli/tools/procesio/tests/test_client_reliability.py +139 -0
- procesio_cli/tools/procesio/tests/test_customaction.py +103 -0
- procesio_cli/tools/procesio/tests/test_customaction_test.py +80 -0
- procesio_cli/tools/procesio/tests/test_cycles.py +69 -0
- procesio_cli/tools/procesio/tests/test_datastore.py +378 -0
- procesio_cli/tools/procesio/tests/test_datastore_node.py +94 -0
- procesio_cli/tools/procesio/tests/test_dispatch.py +170 -0
- procesio_cli/tools/procesio/tests/test_document_page_size.py +19 -0
- procesio_cli/tools/procesio/tests/test_dto.py +734 -0
- procesio_cli/tools/procesio/tests/test_edit_dryrun_preview.py +96 -0
- procesio_cli/tools/procesio/tests/test_elk_layout.py +221 -0
- procesio_cli/tools/procesio/tests/test_environments.py +214 -0
- procesio_cli/tools/procesio/tests/test_fevalidate_gate.py +104 -0
- procesio_cli/tools/procesio/tests/test_fevalidation.py +317 -0
- procesio_cli/tools/procesio/tests/test_fieldpath_variables.py +87 -0
- procesio_cli/tools/procesio/tests/test_files.py +72 -0
- procesio_cli/tools/procesio/tests/test_flow_digest.py +202 -0
- procesio_cli/tools/procesio/tests/test_flowlint.py +114 -0
- procesio_cli/tools/procesio/tests/test_flowmodel.py +158 -0
- procesio_cli/tools/procesio/tests/test_form_add_element.py +256 -0
- procesio_cli/tools/procesio/tests/test_form_approval_gaps.py +319 -0
- procesio_cli/tools/procesio/tests/test_form_auto_names.py +60 -0
- procesio_cli/tools/procesio/tests/test_form_chains.py +217 -0
- procesio_cli/tools/procesio/tests/test_form_code_actions.py +188 -0
- procesio_cli/tools/procesio/tests/test_form_code_keys.py +92 -0
- procesio_cli/tools/procesio/tests/test_form_code_style.py +178 -0
- procesio_cli/tools/procesio/tests/test_form_delete_element.py +99 -0
- procesio_cli/tools/procesio/tests/test_form_element_config.py +141 -0
- procesio_cli/tools/procesio/tests/test_form_event_maps.py +135 -0
- procesio_cli/tools/procesio/tests/test_form_event_ops.py +376 -0
- procesio_cli/tools/procesio/tests/test_form_event_replace.py +86 -0
- procesio_cli/tools/procesio/tests/test_form_events.py +92 -0
- procesio_cli/tools/procesio/tests/test_form_parity.py +171 -0
- procesio_cli/tools/procesio/tests/test_form_select_source.py +74 -0
- procesio_cli/tools/procesio/tests/test_form_sync.py +35 -0
- procesio_cli/tools/procesio/tests/test_form_update.py +133 -0
- procesio_cli/tools/procesio/tests/test_formlint.py +155 -0
- procesio_cli/tools/procesio/tests/test_formlint_css_scope.py +38 -0
- procesio_cli/tools/procesio/tests/test_formlint_field_names.py +83 -0
- procesio_cli/tools/procesio/tests/test_guards.py +110 -0
- procesio_cli/tools/procesio/tests/test_hidden_setting_types.py +39 -0
- procesio_cli/tools/procesio/tests/test_html2docx_asset.py +132 -0
- procesio_cli/tools/procesio/tests/test_key_handle_terminology.py +45 -0
- procesio_cli/tools/procesio/tests/test_layout.py +574 -0
- procesio_cli/tools/procesio/tests/test_layout_report.py +88 -0
- procesio_cli/tools/procesio/tests/test_manifest_sync.py +68 -0
- procesio_cli/tools/procesio/tests/test_nodedelete.py +151 -0
- procesio_cli/tools/procesio/tests/test_nodeparam.py +826 -0
- procesio_cli/tools/procesio/tests/test_normalize.py +70 -0
- procesio_cli/tools/procesio/tests/test_payload_docs.py +86 -0
- procesio_cli/tools/procesio/tests/test_process_action_naming.py +170 -0
- procesio_cli/tools/procesio/tests/test_process_call_api_seed.py +46 -0
- procesio_cli/tools/procesio/tests/test_process_ext.py +373 -0
- procesio_cli/tools/procesio/tests/test_process_invariants.py +183 -0
- procesio_cli/tools/procesio/tests/test_process_layout.py +117 -0
- procesio_cli/tools/procesio/tests/test_process_naming.py +188 -0
- procesio_cli/tools/procesio/tests/test_process_query_store.py +172 -0
- procesio_cli/tools/procesio/tests/test_processinfo_variable.py +56 -0
- procesio_cli/tools/procesio/tests/test_profiles.py +127 -0
- procesio_cli/tools/procesio/tests/test_put_projects.py +41 -0
- procesio_cli/tools/procesio/tests/test_reliability.py +107 -0
- procesio_cli/tools/procesio/tests/test_removal_gate.py +95 -0
- procesio_cli/tools/procesio/tests/test_resource_ops.py +173 -0
- procesio_cli/tools/procesio/tests/test_save_validity.py +207 -0
- procesio_cli/tools/procesio/tests/test_schedule_cron_shape.py +111 -0
- procesio_cli/tools/procesio/tests/test_schedules.py +309 -0
- procesio_cli/tools/procesio/tests/test_sqlconvert.py +234 -0
- procesio_cli/tools/procesio/tests/test_sqlformat.py +83 -0
- procesio_cli/tools/procesio/tests/test_sqlparam.py +187 -0
- procesio_cli/tools/procesio/tests/test_superseded_actions.py +54 -0
- procesio_cli/tools/procesio/tests/test_surgical_concurrency.py +156 -0
- procesio_cli/tools/procesio/tests/test_tier4.py +123 -0
- procesio_cli/tools/procesio/tests/test_transport.py +147 -0
- procesio_cli/tools/procesio/tests/test_transport_data_stores.py +168 -0
- procesio_cli/tools/procesio/tests/test_transport_mapper_repair.py +150 -0
- procesio_cli/tools/procesio/tests/test_transport_webhook_strip.py +253 -0
- procesio_cli/tools/procesio/tests/test_usage_guide.py +96 -0
- procesio_cli/tools/procesio/tool.yaml +12486 -0
- procesio_cli/tools/sqlserver/MOVED-TO-CENTRAL.md +29 -0
- procesio_cli/tools/sqlserver/README.md +192 -0
- procesio_cli/tools/sqlserver/SKILL.md +37 -0
- procesio_cli/tools/sqlserver/SQLSERVER-SCHEMA-NOTES.md +284 -0
- procesio_cli/tools/sqlserver/__init__.py +0 -0
- procesio_cli/tools/sqlserver/connection.py +242 -0
- procesio_cli/tools/sqlserver/main.py +521 -0
- procesio_cli/tools/sqlserver/profiles.template.json +1 -0
- procesio_cli/tools/sqlserver/schema.py +600 -0
- procesio_cli/tools/sqlserver/tests/__init__.py +0 -0
- procesio_cli/tools/sqlserver/tests/conftest.py +21 -0
- procesio_cli/tools/sqlserver/tests/test_connection.py +75 -0
- procesio_cli/tools/sqlserver/tests/test_dbprofiles.py +92 -0
- procesio_cli/tools/sqlserver/tests/test_dbquery.py +220 -0
- procesio_cli/tools/sqlserver/tests/test_manifest_sync.py +68 -0
- procesio_cli/tools/sqlserver/tests/test_sqlserver.py +326 -0
- procesio_cli/tools/sqlserver/tests/test_sqlserver_schema.py +488 -0
- procesio_cli/tools/sqlserver/tool.yaml +123 -0
- procesio_cli/tools/web/README.md +381 -0
- procesio_cli/tools/web/SKILL.md +37 -0
- procesio_cli/tools/web/WEB-AUTOMATION-NOTES.md +277 -0
- procesio_cli/tools/web/__init__.py +21 -0
- procesio_cli/tools/web/actiondef.py +24 -0
- procesio_cli/tools/web/api.py +444 -0
- procesio_cli/tools/web/brokered.py +107 -0
- procesio_cli/tools/web/driver.py +839 -0
- procesio_cli/tools/web/drivercontract.py +44 -0
- procesio_cli/tools/web/errors.py +54 -0
- procesio_cli/tools/web/handlers/__init__.py +1 -0
- procesio_cli/tools/web/handlers/archive.py +367 -0
- procesio_cli/tools/web/handlers/browse.py +182 -0
- procesio_cli/tools/web/handlers/contacts.py +74 -0
- procesio_cli/tools/web/handlers/sessmgmt.py +120 -0
- procesio_cli/tools/web/main.py +128 -0
- procesio_cli/tools/web/sessions.py +253 -0
- procesio_cli/tools/web/steps.py +162 -0
- procesio_cli/tools/web/tests/__init__.py +0 -0
- procesio_cli/tools/web/tests/conftest.py +197 -0
- procesio_cli/tools/web/tests/test_api.py +330 -0
- procesio_cli/tools/web/tests/test_archive.py +190 -0
- procesio_cli/tools/web/tests/test_brokered.py +138 -0
- procesio_cli/tools/web/tests/test_dispatch.py +132 -0
- procesio_cli/tools/web/tests/test_errors.py +60 -0
- procesio_cli/tools/web/tests/test_manifest_sync.py +76 -0
- procesio_cli/tools/web/tests/test_page_contacts.py +68 -0
- procesio_cli/tools/web/tests/test_sessions.py +145 -0
- procesio_cli/tools/web/tests/test_steps.py +210 -0
- procesio_cli/tools/web/tool.yaml +184 -0
- procesio_cli/tools/xlsx/README.md +34 -0
- procesio_cli/tools/xlsx/SKILL.md +28 -0
- procesio_cli/tools/xlsx/__init__.py +0 -0
- procesio_cli/tools/xlsx/main.py +129 -0
- procesio_cli/tools/xlsx/reader.py +91 -0
- procesio_cli/tools/xlsx/tests/__init__.py +0 -0
- procesio_cli/tools/xlsx/tests/conftest.py +39 -0
- procesio_cli/tools/xlsx/tests/test_xlsx.py +103 -0
- procesio_cli/tools/xlsx/tool.yaml +30 -0
- procesio_cli/webplatform/aat_mcp/AAT-MCP-NOTES.md +244 -0
- procesio_cli/webplatform/aat_mcp/README.md +78 -0
- procesio_cli/webplatform/aat_mcp/bridge.py +705 -0
- procesio_cli/webplatform/aat_mcp/chat_server.py +194 -0
- procesio_cli/webplatform/aat_mcp/chat_surface.snapshot.json +668 -0
- procesio_cli/webplatform/aat_mcp/chat_surface.yaml +372 -0
- procesio_cli/webplatform/aat_mcp/gate.py +68 -0
- procesio_cli/webplatform/aat_mcp/http_server.py +139 -0
- procesio_cli/webplatform/aat_mcp/protocol.py +175 -0
- procesio_cli/webplatform/aat_mcp/server.py +306 -0
- procesio_cli/webplatform/aat_mcp/tests/conftest.py +8 -0
- procesio_cli/webplatform/aat_mcp/tests/test_aat_mcp.py +255 -0
- procesio_cli/webplatform/aat_mcp/tests/test_chat_surface.py +247 -0
- procesio_cli/webplatform/aat_mcp/tests/test_discovery.py +489 -0
- procesio_cli/webplatform/aat_mcp/tests/test_multiuser.py +86 -0
- procesio_cli/webplatform/aat_mcp/tests/test_progressive_discovery.py +89 -0
- procesio_cli/webplatform/aat_mcp/tests/test_protocol.py +180 -0
- procesio_cli/webplatform/aat_mcp/tests/test_skill_discovery.py +23 -0
- procesio_cli-0.1.1.dist-info/METADATA +467 -0
- procesio_cli-0.1.1.dist-info/RECORD +647 -0
- procesio_cli-0.1.1.dist-info/WHEEL +4 -0
- procesio_cli-0.1.1.dist-info/entry_points.txt +7 -0
- procesio_cli-0.1.1.dist-info/licenses/LICENSE +201 -0
- procesio_cli-0.1.1.dist-info/licenses/NOTICE +5 -0
|
@@ -0,0 +1,734 @@
|
|
|
1
|
+
"""DTO sub-tools: schema validation, pure builders (fixture regression), and the
|
|
2
|
+
generic action wiring. All offline (no network)."""
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import itertools
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
from tools.procesio import main
|
|
11
|
+
from tools.procesio.dto import framework, refdata, registry
|
|
12
|
+
from tools.procesio.dto.datatype import builder as dt
|
|
13
|
+
from tools.procesio.errors import UsageError
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# -- reference data -----------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
def test_primitive_type_ids_and_aliases():
|
|
19
|
+
assert refdata.primitive_type_id("string") == "0317bfee-b2f5-4bde-bfe8-121212121214"
|
|
20
|
+
assert refdata.primitive_type_id("STR") == refdata.primitive_type_id("string")
|
|
21
|
+
assert refdata.primitive_type_id("int") == refdata.primitive_type_id("integer")
|
|
22
|
+
assert refdata.csharp_correspondent("string") == 50
|
|
23
|
+
with pytest.raises(KeyError):
|
|
24
|
+
refdata.primitive_type_id("widget")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# -- schema validation --------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
def test_datatype_schema_accepts_valid():
|
|
30
|
+
framework.validate_config(dt.COMPONENT, {"name": "M", "attributes": [{"name": "a", "type": "string"}]})
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_datatype_schema_rejects_missing_name():
|
|
34
|
+
with pytest.raises(UsageError):
|
|
35
|
+
framework.validate_config(dt.COMPONENT, {"attributes": []})
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_datatype_schema_rejects_unknown_primitive():
|
|
39
|
+
with pytest.raises(UsageError):
|
|
40
|
+
framework.validate_config(dt.COMPONENT, {"name": "M", "attributes": [{"name": "a", "type": "widget"}]})
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_datatype_schema_rejects_attr_with_no_kind():
|
|
44
|
+
with pytest.raises(UsageError):
|
|
45
|
+
framework.validate_config(dt.COMPONENT, {"name": "M", "attributes": [{"name": "a"}]})
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_datatype_schema_rejects_additional_props():
|
|
49
|
+
with pytest.raises(UsageError):
|
|
50
|
+
framework.validate_config(dt.COMPONENT, {"name": "M", "attributes": [], "bogus": 1})
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# -- pure builder + fixture regression ---------------------------------------
|
|
54
|
+
|
|
55
|
+
def _det_ctx():
|
|
56
|
+
counter = itertools.count(1)
|
|
57
|
+
return {"new_id": lambda: f"00000000-0000-0000-0000-{next(counter):012d}",
|
|
58
|
+
"models": {"personmodel": "11111111-1111-1111-1111-111111111111"}}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def test_datatype_builder_matches_golden_fixture():
|
|
62
|
+
fx = dt.DIR / "fixtures"
|
|
63
|
+
cfg = json.loads((fx / "customer.config.json").read_text(encoding="utf-8"))
|
|
64
|
+
want = json.loads((fx / "customer.dto.json").read_text(encoding="utf-8"))
|
|
65
|
+
got = dt.build(cfg, _det_ctx())
|
|
66
|
+
assert got == want
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def test_datatype_builder_primitive_list_nested_modelref():
|
|
70
|
+
cfg = {"name": "M", "attributes": [
|
|
71
|
+
{"name": "s", "type": "string"},
|
|
72
|
+
{"name": "tags", "type": "string", "isList": True},
|
|
73
|
+
{"name": "child", "attributes": [{"name": "x", "type": "integer"}]},
|
|
74
|
+
{"name": "ref", "model": "personmodel"},
|
|
75
|
+
]}
|
|
76
|
+
dto = dt.build(cfg, _det_ctx())
|
|
77
|
+
attrs = dto["Content"]["Attributes"]
|
|
78
|
+
assert dto["Content"]["IsDataModel"] is True
|
|
79
|
+
assert attrs[0]["DataTypeId"] == refdata.primitive_type_id("string")
|
|
80
|
+
assert attrs[0]["IsDataModel"] is False
|
|
81
|
+
assert attrs[1]["IsList"] is True
|
|
82
|
+
assert attrs[2]["IsDataModel"] is True and [a["Name"] for a in attrs[2]["Attributes"]] == ["x"]
|
|
83
|
+
assert attrs[3]["DataTypeId"] == "11111111-1111-1111-1111-111111111111"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# -- credential builder -------------------------------------------------------
|
|
87
|
+
|
|
88
|
+
def test_credential_builder_matches_golden_and_resolves_options():
|
|
89
|
+
from tools.procesio.dto.credential import builder as cb
|
|
90
|
+
fx = cb.DIR / "fixtures"
|
|
91
|
+
cfg = json.loads((fx / "rest.config.json").read_text(encoding="utf-8"))
|
|
92
|
+
template = json.loads((fx / "rest.template.json").read_text(encoding="utf-8"))
|
|
93
|
+
want = json.loads((fx / "rest.dto.json").read_text(encoding="utf-8"))
|
|
94
|
+
got = cb.build(cfg, {"template": template})
|
|
95
|
+
assert got == want
|
|
96
|
+
# option name resolved to value
|
|
97
|
+
vals = {p["id"]: p["value"] for p in got["properties"]}
|
|
98
|
+
assert vals["p-auth"] == "opt-noauth" and vals["p-method"] == "opt-get"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def test_credential_unknown_property_raises():
|
|
102
|
+
from tools.procesio.dto.credential import builder as cb
|
|
103
|
+
template = {"name": "X", "gid": "g", "pid": "p", "properties": [{"id": "i", "label": "URL"}]}
|
|
104
|
+
with pytest.raises(UsageError):
|
|
105
|
+
cb.build({"template": "X", "name": "n", "properties": {"Nope": "1"}}, {"template": template})
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def test_credential_schema_accepts_array_pills_value():
|
|
109
|
+
"""OAuth2 credentials carry a 'Scopes' pills LIST; the credential config schema
|
|
110
|
+
must accept an ARRAY property value. Regression: values were scalar-only, which
|
|
111
|
+
rejected the scopes list and blocked OAuth2 (Google Drive/Mail/etc.) credentials."""
|
|
112
|
+
from tools.procesio.dto import framework
|
|
113
|
+
from tools.procesio.dto.credential import builder as credential
|
|
114
|
+
cfg = {"template": "OAuth2 (REST API) / Google Drive", "name": "google-drive",
|
|
115
|
+
"properties": {"URL": "https://www.googleapis.com",
|
|
116
|
+
"Scopes": ["https://www.googleapis.com/auth/drive",
|
|
117
|
+
"https://www.googleapis.com/auth/drive.readonly"],
|
|
118
|
+
"Method": "GET"}}
|
|
119
|
+
framework.validate_config(credential.COMPONENT, cfg) # must not raise
|
|
120
|
+
# a scalar value still validates (no regression)
|
|
121
|
+
framework.validate_config(credential.COMPONENT,
|
|
122
|
+
{"template": "REST API", "name": "x",
|
|
123
|
+
"properties": {"URL": "https://api.example.com"}})
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# -- document builder ---------------------------------------------------------
|
|
127
|
+
|
|
128
|
+
def test_document_builder_matches_golden():
|
|
129
|
+
from tools.procesio.dto.document import builder as db
|
|
130
|
+
fx = db.DIR / "fixtures"
|
|
131
|
+
cfg = json.loads((fx / "invoice.config.json").read_text(encoding="utf-8"))
|
|
132
|
+
want = json.loads((fx / "invoice.dto.json").read_text(encoding="utf-8"))
|
|
133
|
+
cnt = itertools.count(1)
|
|
134
|
+
got = db.build(cfg, {"new_id": lambda: f"00000000-0000-0000-0000-{next(cnt):012d}"})
|
|
135
|
+
assert got == want
|
|
136
|
+
assert got["placeholderDelimiterStart"] == "<%" and got["documentPageOrientation"] == 0
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def test_document_landscape_and_types():
|
|
140
|
+
from tools.procesio.dto.document import builder as db
|
|
141
|
+
dto = db.build({"name": "D", "body": "x", "orientation": "landscape",
|
|
142
|
+
"variables": [{"name": "n", "type": "integer"}]}, {})
|
|
143
|
+
assert dto["documentPageOrientation"] == 1
|
|
144
|
+
assert dto["variables"][0]["dataType"] == refdata.primitive_type_id("integer")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# -- webhook builder ----------------------------------------------------------
|
|
148
|
+
|
|
149
|
+
def test_webhook_builder_matches_golden():
|
|
150
|
+
from tools.procesio.dto.webhook import builder as wb
|
|
151
|
+
fx = wb.DIR / "fixtures"
|
|
152
|
+
cfg = json.loads((fx / "order.config.json").read_text(encoding="utf-8"))
|
|
153
|
+
want = json.loads((fx / "order.dto.json").read_text(encoding="utf-8"))
|
|
154
|
+
fake_dm = json.loads(want["DataModel"]) if isinstance(want.get("DataModel"), str) else want["DataModel"]
|
|
155
|
+
got = wb.build(cfg, {"new_id": lambda: "00000000-0000-0000-0000-000000000001", "data_model": fake_dm})
|
|
156
|
+
assert got == want
|
|
157
|
+
assert got["Type"] == 1 and got["IsEdited"] is True
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def test_webhook_auto_type_and_custom_response_dto():
|
|
161
|
+
from tools.procesio.dto.webhook import builder as wb
|
|
162
|
+
fake_dm = {"id": "dm", "name": "X", "isDataModel": True, "type": 2, "attributes": []}
|
|
163
|
+
dto = wb.build({"name": "W", "sample": {"a": 1}, "type": "auto",
|
|
164
|
+
"customResponse": {"type": "staticjson", "config": "{\"ok\":1}"}},
|
|
165
|
+
{"new_id": lambda: "id", "data_model": fake_dm})
|
|
166
|
+
assert dto["Type"] == 0 # AUTO requested
|
|
167
|
+
assert dto["CustomResponseConfig"] == {"ConfigType": 1, "Config": "{\"ok\":1}"}
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def test_process_custom_response_binds_variable():
|
|
171
|
+
from tools.procesio.dto.process import builder as pb
|
|
172
|
+
cfg = {"title": "T", "variables": [{"name": "r", "type": "string", "direction": "output"}],
|
|
173
|
+
"actions": [{"id": "g", "action": "Generate GUID"}],
|
|
174
|
+
"customResponse": {"var": "r"}}
|
|
175
|
+
dto = pb.build(cfg, _proc_ctx())
|
|
176
|
+
cr = dto["CustomResponse"]
|
|
177
|
+
assert cr["Value"] == "<%0%>" and cr["Variable"]["variableId"] is not None
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def test_webhook_requires_data_model_in_ctx():
|
|
181
|
+
from tools.procesio.dto.webhook import builder as wb
|
|
182
|
+
with pytest.raises(UsageError):
|
|
183
|
+
wb.build({"name": "W", "sample": {"a": 1}}, {})
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# -- form builder -------------------------------------------------------------
|
|
187
|
+
|
|
188
|
+
def _form_ctx():
|
|
189
|
+
cnt = itertools.count(1)
|
|
190
|
+
return {"new_id": lambda: f"00000000-0000-0000-0000-{next(cnt):012d}"}
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def test_form_builder_elements_match_golden():
|
|
194
|
+
from tools.procesio.dto.form import builder as fb
|
|
195
|
+
fx = fb.DIR / "fixtures"
|
|
196
|
+
cfg = json.loads((fx / "reg.config.json").read_text(encoding="utf-8"))
|
|
197
|
+
want = json.loads((fx / "reg.elements.json").read_text(encoding="utf-8"))
|
|
198
|
+
got = fb.build(cfg, _form_ctx())["Data"]["elements"]
|
|
199
|
+
assert got == want
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def test_form_sections_and_overrides():
|
|
203
|
+
from tools.procesio.dto.form import builder as fb
|
|
204
|
+
cfg = {"name": "F", "elements": [
|
|
205
|
+
{"type": "heading", "label": "H"},
|
|
206
|
+
{"type": "input", "label": "Name", "name": "nm", "required": True},
|
|
207
|
+
{"type": "select", "label": "C", "options": ["a", "b"]},
|
|
208
|
+
{"type": "checkbox", "label": "Sub"},
|
|
209
|
+
{"type": "button", "label": "Go", "submit": True}]}
|
|
210
|
+
dto = fb.build(cfg, _form_ctx())
|
|
211
|
+
els = {e["type"]: e for e in dto["Data"]["elements"]}
|
|
212
|
+
assert els["heading"]["section"] == "header" and els["button"]["section"] == "footer"
|
|
213
|
+
for e in dto["Data"]["elements"]:
|
|
214
|
+
assert e["parentId"] is None # all top-level
|
|
215
|
+
for c in e["configs"]:
|
|
216
|
+
if c["key"] == "visible":
|
|
217
|
+
assert c["value"] is True
|
|
218
|
+
# required propagated; options resolved
|
|
219
|
+
inp = els["input"]["configs"]
|
|
220
|
+
assert next(c["value"] for c in inp if c["key"] == "required") is True
|
|
221
|
+
opts = next(c["value"] for c in els["select"]["configs"] if c["key"] == "sourceValue")
|
|
222
|
+
assert opts == [{"name": "a", "value": "a"}, {"name": "b", "value": "b"}]
|
|
223
|
+
# form Data.code is empty (renders from elements)
|
|
224
|
+
assert dto["Data"]["code"] == "" and dto["Status"] == 1
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def test_form_nested_children_flat_with_parentid():
|
|
228
|
+
from tools.procesio.dto.form import builder as fb
|
|
229
|
+
cfg = {"name": "F", "elements": [
|
|
230
|
+
{"type": "section", "label": "S", "children": [{"type": "input", "label": "X"}]}]}
|
|
231
|
+
dto = fb.build(cfg, _form_ctx())
|
|
232
|
+
els = dto["Data"]["elements"]
|
|
233
|
+
assert [e["type"] for e in els] == ["section", "input"] # FLAT, not nested
|
|
234
|
+
assert all("children" not in e for e in els)
|
|
235
|
+
assert els[1]["parentId"] == els[0]["id"]
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def test_form_table_structure():
|
|
239
|
+
from tools.procesio.dto.form import builder as fb
|
|
240
|
+
dto = fb.build({"name": "F", "elements": [
|
|
241
|
+
{"type": "table", "label": "Items", "columns": [
|
|
242
|
+
{"key": "product", "label": "Product", "cell": {"type": "input", "label": "P"}},
|
|
243
|
+
{"key": "qty", "label": "Qty", "cell": {"type": "number-input", "label": "Q"}}]}]}, _form_ctx())
|
|
244
|
+
els = dto["Data"]["elements"]
|
|
245
|
+
table = next(e for e in els if e["type"] == "table")
|
|
246
|
+
row = next(e for e in els if e["type"] == "static-table-row")
|
|
247
|
+
assert row["parentId"] == table["id"]
|
|
248
|
+
cols = next(c["value"] for c in table["configs"] if c["key"] == "tableColumnsSourceValue")
|
|
249
|
+
assert [c["key"] for c in cols] == ["product", "qty"]
|
|
250
|
+
cells = [e for e in els if e["parentId"] == row["id"]]
|
|
251
|
+
assert len(cells) == 2
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def test_form_events_and_theme():
|
|
255
|
+
from tools.procesio.dto.form import builder as fb
|
|
256
|
+
cfg = {"name": "F", "theme": {"--c-primary": "#abc123"}, "elements": [
|
|
257
|
+
{"type": "button", "label": "Go", "submit": True,
|
|
258
|
+
"events": [{"on": "click", "do": "js", "code": "alert(1)"},
|
|
259
|
+
{"on": "click", "do": "process", "processId": "PID",
|
|
260
|
+
"inputs": [{"to": "v", "from": "p"}]}]}]}
|
|
261
|
+
dto = fb.build(cfg, _form_ctx())
|
|
262
|
+
btn = dto["Data"]["elements"][0]
|
|
263
|
+
ev = next(c["value"] for c in btn["configs"] if c["key"] == "onClickEvents")
|
|
264
|
+
assert ev["events"][0]["action"] == "RUN_JAVASCRIPT"
|
|
265
|
+
assert ev["events"][1]["action"] == "RUN_PROCESS" and ev["events"][1]["config"]["processId"] == "PID"
|
|
266
|
+
prim = next(p["value"] for s in dto["Data"]["theme"] for p in s.get("properties", [])
|
|
267
|
+
if p.get("cssVariable") == "--c-primary")
|
|
268
|
+
assert prim == "#abc123"
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def test_form_assignee_and_event_trigger_kinds():
|
|
272
|
+
from tools.procesio.dto.form import builder as fb
|
|
273
|
+
dto = fb.build({"name": "F", "elements": [
|
|
274
|
+
{"type": "section", "label": "S", "assignee": "USER-1", "children": [{"type": "input", "label": "x"}]},
|
|
275
|
+
{"type": "input", "label": "m", "events": [{"on": "input", "do": "map",
|
|
276
|
+
"mapping": [{"to": "dest", "value": "lit"}]}]}]}, _form_ctx())
|
|
277
|
+
els = dto["Data"]["elements"]
|
|
278
|
+
sec = next(e for e in els if e["type"] == "section")
|
|
279
|
+
assert next(c["value"] for c in sec["configs"] if c["key"] == "assignee") == "USER-1"
|
|
280
|
+
# flat list: find the input that carries the event (not the section's child)
|
|
281
|
+
inp = next(e for e in els if e["type"] == "input"
|
|
282
|
+
and any(c["key"] == "onInputEvents" and c["value"] for c in e["configs"]))
|
|
283
|
+
ev = next(c["value"] for c in inp["configs"] if c["key"] == "onInputEvents")
|
|
284
|
+
assert ev["events"][0]["action"] == "MAP_FORM_DATA"
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def test_form_unknown_control_raises():
|
|
288
|
+
from tools.procesio.dto.form import builder as fb
|
|
289
|
+
with pytest.raises(UsageError):
|
|
290
|
+
fb.build({"name": "F", "elements": [{"type": "no-such-control"}]}, _form_ctx())
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
# -- action wiring ------------------------------------------------------------
|
|
294
|
+
|
|
295
|
+
def test_dto_actions_registered():
|
|
296
|
+
for comp in registry.all_components():
|
|
297
|
+
assert f"{comp}-create" in main.ACTIONS
|
|
298
|
+
assert f"{comp}-edit" in main.ACTIONS
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
# -- process builder ----------------------------------------------------------
|
|
302
|
+
|
|
303
|
+
def _proc_ctx():
|
|
304
|
+
counter = itertools.count(1)
|
|
305
|
+
return {"new_id": lambda: f"00000000-0000-0000-0000-{next(counter):012d}"}
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
def test_process_builder_matches_golden_fixture():
|
|
309
|
+
from tools.procesio.dto.process import builder as pb
|
|
310
|
+
fx = pb.DIR / "fixtures"
|
|
311
|
+
cfg = json.loads((fx / "greet.config.json").read_text(encoding="utf-8"))
|
|
312
|
+
want = json.loads((fx / "greet.dto.json").read_text(encoding="utf-8"))
|
|
313
|
+
assert pb.build(cfg, _proc_ctx()) == want
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def test_process_binding_modes_and_ports():
|
|
317
|
+
from tools.procesio.dto.process import builder as pb
|
|
318
|
+
cfg = {"title": "T", "variables": [{"name": "v", "type": "string"}],
|
|
319
|
+
"actions": [{"id": "c", "action": "Concatenate", "params": {
|
|
320
|
+
"Input String 1": {"var": "v"},
|
|
321
|
+
"Input String 2": "lit",
|
|
322
|
+
"Result": {"var": "v"}}}]}
|
|
323
|
+
dto = pb.build(cfg, _proc_ctx())
|
|
324
|
+
names = [a["ActionName"] for a in dto["Actions"]]
|
|
325
|
+
assert names == ["Start", "Concatenate", "Stop"]
|
|
326
|
+
params = {p["Value"]: p for p in dto["Actions"][1]["Parameters"]}
|
|
327
|
+
assert "lit" in params and params["lit"]["Variable"] == [] # literal
|
|
328
|
+
var_param = next(p for p in dto["Actions"][1]["Parameters"] if p["Variable"])
|
|
329
|
+
assert var_param["Value"] == "<%0%>" # variable binding
|
|
330
|
+
# entry edge (null->Start) + Start->Concat on Start; Concat->Stop on Concat
|
|
331
|
+
assert len(dto["Actions"][0]["Ports"]) == 2
|
|
332
|
+
assert dto["Actions"][2]["Ports"] == []
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def test_process_explicit_edges_and_template_binding():
|
|
336
|
+
from tools.procesio.dto.process import builder as pb
|
|
337
|
+
cfg = {"title": "T", "variables": [{"name": "a", "type": "string"}],
|
|
338
|
+
"actions": [{"id": "c", "action": "Concatenate",
|
|
339
|
+
"params": {"Input String 1": {"template": "x <%0%>", "vars": ["a"]}}}],
|
|
340
|
+
"edges": [["start", "c"], ["c", "stop"]]}
|
|
341
|
+
dto = pb.build(cfg, _proc_ctx())
|
|
342
|
+
p = dto["Actions"][1]["Parameters"][0]
|
|
343
|
+
assert p["Value"] == "x <%0%>" and len(p["Variable"]) == 1
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def test_process_webhook_attachment():
|
|
347
|
+
from tools.procesio.dto.process import builder as pb
|
|
348
|
+
cfg = {"title": "T", "variables": [{"name": "p", "type": "string", "direction": "input"}],
|
|
349
|
+
"actions": [{"id": "g", "action": "Generate GUID"}],
|
|
350
|
+
"webhooks": [{"webhookId": "wh-1", "variables": [{"name": "p", "source": "body"}]}]}
|
|
351
|
+
dto = pb.build(cfg, _proc_ctx())
|
|
352
|
+
assert len(dto["Webhooks"]) == 1
|
|
353
|
+
wh = dto["Webhooks"][0]
|
|
354
|
+
assert wh["WebhookId"] == "wh-1"
|
|
355
|
+
assert wh["WebhookVariables"][0]["VariableType"] == 3 # body
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def test_process_decisional_branches():
|
|
359
|
+
from tools.procesio.dto.process import builder as pb
|
|
360
|
+
cfg = {"title": "T", "variables": [{"name": "n", "type": "integer", "direction": "input"}],
|
|
361
|
+
"actions": [
|
|
362
|
+
{"id": "dec", "action": "Decisional", "branches": [
|
|
363
|
+
{"to": "hi", "when": [{"left": {"var": "n"}, "op": "GREATER_THAN", "right": 5}]},
|
|
364
|
+
{"to": "lo", "default": True}]},
|
|
365
|
+
{"id": "hi", "action": "Generate GUID"},
|
|
366
|
+
{"id": "lo", "action": "Generate GUID"},
|
|
367
|
+
{"id": "s1", "action": "Stop"}, {"id": "s2", "action": "Stop"}],
|
|
368
|
+
"edges": [["start", "dec"], ["hi", "s1"], ["lo", "s2"]]}
|
|
369
|
+
dto = pb.build(cfg, _proc_ctx())
|
|
370
|
+
dec = next(a for a in dto["Actions"] if a["ActionName"] == "Decisional")
|
|
371
|
+
cases = next(p for p in dec["Parameters"] if isinstance(p["Value"], list))
|
|
372
|
+
assert cases["Value"][0]["condition"][0]["operator"] == "GREATER_THAN"
|
|
373
|
+
# two branch ports (case + default), default carries the marker
|
|
374
|
+
assert any(p.get("Data", {}).get("isDefault") == "default" for p in dec["Ports"])
|
|
375
|
+
# user-supplied Stops -> no auto stop duplication
|
|
376
|
+
assert sum(1 for a in dto["Actions"] if a["ActionName"] == "Stop") == 2
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def test_process_error_port_and_join():
|
|
380
|
+
from tools.procesio.dto.process import builder as pb
|
|
381
|
+
cfg = {"title": "T", "variables": [{"name": "m", "type": "string", "direction": "output"}],
|
|
382
|
+
"actions": [
|
|
383
|
+
{"id": "t", "action": "Throw", "onError": "h"},
|
|
384
|
+
{"id": "h", "action": "Generate GUID"},
|
|
385
|
+
{"id": "j", "action": "Join"}],
|
|
386
|
+
"edges": [["start", "t"], ["t", "j"], ["h", "j"], ["j", "stop"]]}
|
|
387
|
+
dto = pb.build(cfg, _proc_ctx())
|
|
388
|
+
th = next(a for a in dto["Actions"] if a["ActionName"] == "Throw")
|
|
389
|
+
assert th["VariableErrorId"] is not None
|
|
390
|
+
assert any(p.get("Type") == 1 and p.get("Data", {}).get("isDefault") == "error" for p in th["Ports"])
|
|
391
|
+
assert any(v.get("IsError") for v in dto["Variables"]) # ErrorDataModel variable
|
|
392
|
+
jn = next(a for a in dto["Actions"] if a["ActionName"] == "Join")
|
|
393
|
+
assert jn["CustomData"]["inputPorts"] == -1 # flow Join accepts many inputs
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def test_process_scripting_global_indexing():
|
|
397
|
+
from tools.procesio.dto.process import builder as pb
|
|
398
|
+
cfg = {"title": "T", "variables": [{"name": "n", "type": "integer", "direction": "input"},
|
|
399
|
+
{"name": "out", "type": "json", "direction": "output"}],
|
|
400
|
+
"actions": [{"id": "js", "action": "Javascript",
|
|
401
|
+
"params": {"Code": {"template": "setOutput(<%0%>+1)", "vars": ["n"]},
|
|
402
|
+
"Output": {"var": "out"}}}]}
|
|
403
|
+
dto = pb.build(cfg, _proc_ctx())
|
|
404
|
+
js = next(a for a in dto["Actions"] if a["ActionName"] == "Javascript")
|
|
405
|
+
# Code uses <%0%> (id 0), Output captured at a distinct global index (<%1%>)
|
|
406
|
+
code = next(p for p in js["Parameters"] if "setOutput" in str(p["Value"]))
|
|
407
|
+
out = next(p for p in js["Parameters"] if p["Value"] == "<%1%>")
|
|
408
|
+
assert code["Variable"][0]["id"] == 0 and out["Variable"][0]["id"] == 1
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def test_process_doc_mapper_destination_shape():
|
|
412
|
+
from tools.procesio.dto.process import builder as pb
|
|
413
|
+
ctx = _proc_ctx()
|
|
414
|
+
ctx["doc_vars"] = {"gd": {"clientname": "DOC-VAR-ID"}}
|
|
415
|
+
cfg = {"title": "T", "variables": [{"name": "c", "type": "string", "direction": "input"}],
|
|
416
|
+
"actions": [{"id": "gd", "action": "Generate Document",
|
|
417
|
+
"params": {"Select Document Template": "DID", "File Name": "f"},
|
|
418
|
+
"docMap": {"clientName": "c"}}]}
|
|
419
|
+
dto = pb.build(cfg, ctx)
|
|
420
|
+
gd = next(a for a in dto["Actions"] if a["ActionTemplateName"] == "Generate Document")
|
|
421
|
+
assert gd["ActionName"] == "Generate f" # auto-named from the File Name literal
|
|
422
|
+
mapper = next(p for p in gd["Parameters"] if isinstance(p["Value"], list) and p["Value"]
|
|
423
|
+
and "destination" in p["Value"][0])
|
|
424
|
+
row = mapper["Value"][0]
|
|
425
|
+
assert row["destination"]["variableId"] == "DOC-VAR-ID"
|
|
426
|
+
assert row["source"]["value"].startswith("<%")
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
def test_process_unknown_action_raises():
|
|
430
|
+
from tools.procesio.dto.process import builder as pb
|
|
431
|
+
with pytest.raises(UsageError):
|
|
432
|
+
pb.build({"title": "T", "actions": [{"id": "x", "action": "NoSuchAction"}]}, _proc_ctx())
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
def test_process_unknown_property_raises():
|
|
436
|
+
from tools.procesio.dto.process import builder as pb
|
|
437
|
+
with pytest.raises(UsageError):
|
|
438
|
+
pb.build({"title": "T", "actions": [{"id": "x", "action": "Generate GUID",
|
|
439
|
+
"params": {"Nope": "1"}}]}, _proc_ctx())
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def test_datatype_create_dry_run_builds_without_network():
|
|
443
|
+
# needs_client path, but --dry-run must not call the network; pass a client
|
|
444
|
+
# whose any network use would raise.
|
|
445
|
+
class Boom:
|
|
446
|
+
def __getattr__(self, _):
|
|
447
|
+
raise AssertionError("dry-run must not touch the network")
|
|
448
|
+
defn = main.ACTIONS["datatype-create"]
|
|
449
|
+
import argparse
|
|
450
|
+
p = argparse.ArgumentParser()
|
|
451
|
+
defn.add_args(p)
|
|
452
|
+
args = p.parse_args(["--config", json.dumps({"name": "M", "attributes": [{"name": "a", "type": "string"}]}),
|
|
453
|
+
"--dry-run"])
|
|
454
|
+
# datatype has no `model` refs here, so prepare_ctx makes no calls.
|
|
455
|
+
out = defn.func(Boom(), args)
|
|
456
|
+
assert out["dry_run"] is True and out["dto"]["Content"]["Name"] == "M"
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
def test_action_config_mirrors_parameters():
|
|
461
|
+
"""Designer reads CustomData.configuration; it must mirror Parameters (literal as-is,
|
|
462
|
+
a variable ref as the raw var id, not <%N%>)."""
|
|
463
|
+
from tools.procesio.dto.process import builder as pb
|
|
464
|
+
cfg = {"title": "T", "variables": [{"name": "v", "type": "string"}],
|
|
465
|
+
"actions": [{"id": "c", "action": "Concatenate", "params": {
|
|
466
|
+
"Input String 1": {"var": "v"}, "Input String 2": "lit", "Result": {"var": "v"}}}]}
|
|
467
|
+
dto = pb.build(cfg, _proc_ctx())
|
|
468
|
+
act = [a for a in dto["Actions"] if a["ActionName"] not in ("Start", "Stop")][0]
|
|
469
|
+
vals = {}
|
|
470
|
+
|
|
471
|
+
def walk(ss):
|
|
472
|
+
for s in ss or []:
|
|
473
|
+
if s.get("label"):
|
|
474
|
+
vals[s["label"]] = s.get("value")
|
|
475
|
+
if isinstance(s.get("value"), list):
|
|
476
|
+
walk(s["value"])
|
|
477
|
+
for t in act["CustomData"]["configuration"]:
|
|
478
|
+
walk(t.get("settings", []))
|
|
479
|
+
assert vals.get("Input String 2") == "lit"
|
|
480
|
+
assert vals.get("Input String 1") == dto["Variables"][0]["Id"] # <%0%> -> var id
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def test_generate_document_docmapper_config_shape():
|
|
484
|
+
"""document-mapper config must be the designer shape [{id, process, document}],
|
|
485
|
+
not the runtime {source/destination} shape (else the designer shows it empty)."""
|
|
486
|
+
from tools.procesio.dto.process import builder as pb
|
|
487
|
+
ctx = _proc_ctx()
|
|
488
|
+
ctx["doc_vars"] = {"g": {"htmlcontent": "DOCVAR"}}
|
|
489
|
+
cfg = {"title": "T", "variables": [{"name": "html", "type": "string"}],
|
|
490
|
+
"actions": [{"id": "g", "action": "Generate Document", "name": "gd",
|
|
491
|
+
"params": {"Save document as": "1"},
|
|
492
|
+
"docMap": {"htmlContent": {"var": "html"}}}]}
|
|
493
|
+
dto = pb.build(cfg, ctx)
|
|
494
|
+
gd = [a for a in dto["Actions"] if a["ActionName"] == "gd"][0]
|
|
495
|
+
found = []
|
|
496
|
+
|
|
497
|
+
def find(ss):
|
|
498
|
+
for s in ss or []:
|
|
499
|
+
if s.get("type") == "document-mapper":
|
|
500
|
+
found.append(s)
|
|
501
|
+
if isinstance(s.get("value"), list):
|
|
502
|
+
find(s["value"])
|
|
503
|
+
for t in gd["CustomData"]["configuration"]:
|
|
504
|
+
find(t.get("settings", []))
|
|
505
|
+
assert found, "no document-mapper setting"
|
|
506
|
+
row = found[0]["value"][0]
|
|
507
|
+
assert {"id", "process", "document"} <= set(row) and row["document"] == "DOCVAR"
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
def test_form_builds_data_model_mirror():
|
|
511
|
+
"""Each form field must get a data-model attribute under the `fields` container so
|
|
512
|
+
triggers resolve and values flow."""
|
|
513
|
+
from tools.procesio.dto.form import builder as fb
|
|
514
|
+
cfg = {"name": "F", "elements": [
|
|
515
|
+
{"type": "input", "label": "Company", "name": "companyName"},
|
|
516
|
+
{"type": "button", "label": "Go", "name": "go"}]}
|
|
517
|
+
dto = fb.build(cfg, _form_ctx())
|
|
518
|
+
dm = dto["Data"]["dataModel"]
|
|
519
|
+
assert dm["id"] != dto["Id"] # data-model root is a SEPARATE id
|
|
520
|
+
fields = next(a for a in dm["attributes"] if a["id"] == fb._FIELDS_NS)
|
|
521
|
+
assert fields["parentDataTypeId"] == dm["id"] # fields container hangs off the root
|
|
522
|
+
names = {f["name"]: f for f in fields["attributes"]}
|
|
523
|
+
assert "companyName" in names
|
|
524
|
+
assert any(at["name"] == "value" for at in names["companyName"]["attributes"])
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
def test_decisional_cases_config_designer_shape():
|
|
529
|
+
"""decisional-case config must carry every field the designer needs to render a
|
|
530
|
+
condition (value/rightOperandAsListRequired/operandsAsListOptional/uid), map a
|
|
531
|
+
variable operand to its id, and coerce a literal operand to a string."""
|
|
532
|
+
from tools.procesio.dto.process import builder as pb
|
|
533
|
+
cases = [{"id": 0, "actionid": "TARGET", "condition": [{
|
|
534
|
+
"id": 0, "operator": "GREATER_THAN", "logicOperator": 1,
|
|
535
|
+
"leftOperator": {"value": "<%0%>", "variable": [{"id": 0, "variableId": "VARID", "attribute": None}]},
|
|
536
|
+
"rightOperator": {"value": 50, "variable": []},
|
|
537
|
+
"auxOperator": {"value": "", "variable": []}}]}]
|
|
538
|
+
out = pb._decisional_cases_config(cases, _proc_ctx())
|
|
539
|
+
case = out[0]
|
|
540
|
+
assert case["target"] == "TARGET" and case["name"] == "Case 1"
|
|
541
|
+
cond = case["condition"][0]
|
|
542
|
+
assert {"value", "rightOperandAsListRequired", "operandsAsListOptional", "uid"} <= set(cond)
|
|
543
|
+
assert cond["leftOperator"]["value"] == "VARID" # <%0%> -> variable id
|
|
544
|
+
assert cond["rightOperator"]["value"] == "50" # literal coerced to string
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
def test_form_field_paths_root_matches_form_handle_variable():
|
|
548
|
+
"""The designer resolves a field path back to its name by walking from the form
|
|
549
|
+
handle variable (Data.variables[0]) into Data.dataModel. So dataModel.id, every
|
|
550
|
+
field-path first segment, AND variables[0].id must be the SAME id; otherwise the
|
|
551
|
+
process<->form maps render as raw guids (input) or blank (output). Regression guard
|
|
552
|
+
for the live bug where a fresh dm_root_id != variables[0].id (65396456...)."""
|
|
553
|
+
from tools.procesio.dto.form import builder as fb
|
|
554
|
+
cfg = {"name": "F", "elements": [
|
|
555
|
+
{"type": "input", "label": "Company", "name": "companyName"},
|
|
556
|
+
{"type": "file-upload", "label": "PDF", "name": "briefFile"},
|
|
557
|
+
{"type": "button", "label": "Go", "name": "go", "events": [
|
|
558
|
+
{"on": "click", "do": "process", "processId": "P", "syncRun": True,
|
|
559
|
+
"inputs": [{"to": "pin", "from": "companyName"}],
|
|
560
|
+
"outputs": [{"to": "pout", "from": "briefFile"}]}]}]}
|
|
561
|
+
dto = fb.build(cfg, _form_ctx())
|
|
562
|
+
data = dto["Data"]
|
|
563
|
+
fv = data["variables"][0]["id"]
|
|
564
|
+
assert data["dataModel"]["id"] == fv # root == form handle variable
|
|
565
|
+
assert fv != dto["Id"] # ...and still != form template id
|
|
566
|
+
# every field path embedded in the button's RUN_PROCESS maps roots at fv
|
|
567
|
+
paths = []
|
|
568
|
+
for el in data["elements"]:
|
|
569
|
+
for c in el.get("configs", []):
|
|
570
|
+
if c.get("key") == "onClickEvents":
|
|
571
|
+
cfgv = c["value"]["events"][0]["config"]
|
|
572
|
+
for row in cfgv["inputMap"] + cfgv["outputMap"]:
|
|
573
|
+
for v in (row["left"], row["right"]):
|
|
574
|
+
if isinstance(v, str) and v.count(".") == 3:
|
|
575
|
+
paths.append(v)
|
|
576
|
+
assert paths, "expected at least one field-path reference in the maps"
|
|
577
|
+
assert all(p.startswith(fv + ".") for p in paths), paths
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
def test_form_datamodel_attr_ids_match_element_config_ids_and_are_private():
|
|
581
|
+
"""The process-designer trigger-map resolves a 'Form variable' to its name only
|
|
582
|
+
when the form's data model matches what the platform generates for a real UI form:
|
|
583
|
+
(1) every fields sub-model attribute id == that element's config id of the same key
|
|
584
|
+
(live evidence: OMS 15/16 match; our old builder 0/11 -> 'Unknown'), and (2) field
|
|
585
|
+
sub-models AND their leaf attrs are isPublic:false (the 100%-consistent property of
|
|
586
|
+
all 163 real forms scanned). Regression guard for both fixes."""
|
|
587
|
+
from tools.procesio.dto.form import builder as fb
|
|
588
|
+
cfg = {"name": "F", "elements": [
|
|
589
|
+
{"type": "input", "label": "Company", "name": "companyName"},
|
|
590
|
+
{"type": "file-upload", "label": "PDF", "name": "briefFile"}]}
|
|
591
|
+
dto = fb.build(cfg, _form_ctx())
|
|
592
|
+
data = dto["Data"]
|
|
593
|
+
elements = {e["id"]: e for e in data["elements"]}
|
|
594
|
+
fields = next(a for a in data["dataModel"]["attributes"] if a["id"] == fb._FIELDS_NS)
|
|
595
|
+
checked = 0
|
|
596
|
+
for sub in fields["attributes"]:
|
|
597
|
+
el = elements.get(sub["id"])
|
|
598
|
+
if not el:
|
|
599
|
+
continue
|
|
600
|
+
assert sub["isPublic"] is False, f"sub-model {sub['name']} must be isPublic:false"
|
|
601
|
+
cfg_ids = {fb._attr_name(c.get("key")): c.get("id") for c in el.get("configs", [])}
|
|
602
|
+
for attr in sub["attributes"]:
|
|
603
|
+
assert attr["isPublic"] is False, f"attr {attr['name']} must be isPublic:false"
|
|
604
|
+
assert attr["id"] == cfg_ids.get(attr["name"]), (
|
|
605
|
+
f"dataModel attr id for {sub['name']}.{attr['name']} "
|
|
606
|
+
f"({attr['id']}) must equal the element config id ({cfg_ids.get(attr['name'])})")
|
|
607
|
+
checked += 1
|
|
608
|
+
assert checked >= 2, "expected to check several attributes"
|
|
609
|
+
# the value-attr path segment equals the element's value config id
|
|
610
|
+
cn = next(e for e in data["elements"]
|
|
611
|
+
if next((c["value"] for c in e["configs"] if c["key"] == "name"), None) == "companyName")
|
|
612
|
+
val_cfg_id = next(c["id"] for c in cn["configs"] if c["key"] == "value")
|
|
613
|
+
# find the field path for companyName in the (rebuilt) ctx via a button map would be
|
|
614
|
+
# indirect; assert directly that the value attr in the data model uses that id
|
|
615
|
+
sub = next(a for a in fields["attributes"] if a["id"] == cn["id"])
|
|
616
|
+
val_attr = next(a for a in sub["attributes"] if a["name"] == "value")
|
|
617
|
+
assert val_attr["id"] == val_cfg_id
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
def test_form_every_field_submodel_has_visible_attr():
|
|
621
|
+
"""The process-designer trigger-map INPUT-side resolver only treats a form field as
|
|
622
|
+
a mappable variable if its data-model sub-model carries a `visible` attribute; a
|
|
623
|
+
field without it renders as 'Unknown' (live-confirmed: briefFile had `visible` and
|
|
624
|
+
resolved on the output side, companyName/country lacked it and showed 'Unknown' on
|
|
625
|
+
the input side). The builder synthesizes `visible` for goldens that omit it (e.g.
|
|
626
|
+
input). Guard that every field sub-model has it."""
|
|
627
|
+
from tools.procesio.dto.form import builder as fb
|
|
628
|
+
cfg = {"name": "F", "elements": [
|
|
629
|
+
{"type": "input", "label": "Company", "name": "companyName"},
|
|
630
|
+
{"type": "input", "label": "Country", "name": "country"},
|
|
631
|
+
{"type": "file-upload", "label": "PDF", "name": "briefFile"}]}
|
|
632
|
+
dto = fb.build(cfg, _form_ctx())
|
|
633
|
+
data = dto["Data"]
|
|
634
|
+
elements = {e["id"]: e for e in data["elements"]}
|
|
635
|
+
fields = next(a for a in data["dataModel"]["attributes"] if a["id"] == fb._FIELDS_NS)
|
|
636
|
+
for sub in fields["attributes"]:
|
|
637
|
+
if sub["id"] not in elements:
|
|
638
|
+
continue
|
|
639
|
+
attr_names = {a["name"] for a in sub["attributes"]}
|
|
640
|
+
assert "visible" in attr_names, f"field {sub['name']} sub-model missing 'visible' attr"
|
|
641
|
+
# and the visible attr id still equals the element's visible config id (invariant)
|
|
642
|
+
el = elements[sub["id"]]
|
|
643
|
+
vis_cfg_id = next((c["id"] for c in el["configs"] if c.get("key") == "visible"), None)
|
|
644
|
+
vis_attr_id = next(a["id"] for a in sub["attributes"] if a["name"] == "visible")
|
|
645
|
+
assert vis_attr_id == vis_cfg_id
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
def test_datatype_create_uses_empty_post_then_attribute_endpoint():
|
|
649
|
+
"""The PROCESIO UI (HAR-verified) creates a model EMPTY (content:null) then adds EVERY
|
|
650
|
+
attribute via POST /api/DataTypes/attribute/{id} — that path compiles them and inlines
|
|
651
|
+
referenced child models. Attributes in the initial POST Content are never compiled
|
|
652
|
+
(documents then render them "Unknown" / "Unable to find attribute"). Guard that the
|
|
653
|
+
create flow replicates the UI exactly. Regression guard for the AAT_SearchHit bug."""
|
|
654
|
+
from tools.procesio.dto.datatype import builder as db
|
|
655
|
+
cnt = itertools.count(1)
|
|
656
|
+
dto = db.build(
|
|
657
|
+
{"name": "Parent", "attributes": [
|
|
658
|
+
{"name": "title", "type": "string"},
|
|
659
|
+
{"name": "items", "model": "ChildModel", "isList": True}]},
|
|
660
|
+
{"new_id": lambda: f"id{next(cnt)}", "models": {"childmodel": "CHILD-ID"}})
|
|
661
|
+
calls = []
|
|
662
|
+
class FakeClient:
|
|
663
|
+
def post(self, path, body=None):
|
|
664
|
+
calls.append((path, body))
|
|
665
|
+
return {"id": "NEW-PARENT-ID"} if path == "/api/DataTypes" else {}
|
|
666
|
+
db._create(FakeClient(), dto, {})
|
|
667
|
+
model_posts = [b for p, b in calls if p == "/api/DataTypes"]
|
|
668
|
+
assert len(model_posts) == 1 # one empty-model create
|
|
669
|
+
assert model_posts[0].get("content") is None and "Content" not in model_posts[0]
|
|
670
|
+
attr_calls = [(p, b) for p, b in calls if p.startswith("/api/DataTypes/attribute/")]
|
|
671
|
+
assert len(attr_calls) == 2 # BOTH attrs via the attribute endpoint
|
|
672
|
+
by_name = {b["name"]: b for _, b in attr_calls}
|
|
673
|
+
assert set(by_name) == {"title", "items"}
|
|
674
|
+
for b in by_name.values():
|
|
675
|
+
assert b["id"] is None and b["parentDataTypeId"] == "NEW-PARENT-ID"
|
|
676
|
+
assert {"displayName", "name", "dataTypeId", "isList", "jsonProperty"} <= set(b)
|
|
677
|
+
assert by_name["items"]["dataTypeId"] == "CHILD-ID" and by_name["items"]["isList"] is True
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
def test_process_ai_decisional_branches():
|
|
681
|
+
"""AI Decisional: string-condition cases -> runtime {id,actionid,condition:str} +
|
|
682
|
+
designer {id,name,target,condition,internalId}; default port carries the marker;
|
|
683
|
+
Model/Endpoint/extra-config pass through; LLM Response is an OUTPUT binding."""
|
|
684
|
+
from tools.procesio.dto.process import builder as pb
|
|
685
|
+
cfg = {"title": "T",
|
|
686
|
+
"variables": [{"name": "animal", "type": "string", "direction": "input"},
|
|
687
|
+
{"name": "res", "type": "json", "direction": "process"}],
|
|
688
|
+
"actions": [
|
|
689
|
+
{"id": "ai", "action": "AI Decisional",
|
|
690
|
+
"params": {"Select AI Configuration": "CRED", "Model": "gpt-4o",
|
|
691
|
+
"Endpoint": "1", "Timeout (seconds)": 60,
|
|
692
|
+
"User Prompt": {"template": "which? <%0%>", "vars": ["animal"]},
|
|
693
|
+
"LLM Response": {"var": "res"},
|
|
694
|
+
"Temperature": 0, "Top P": 1, "Max Output Tokens": 1024,
|
|
695
|
+
"Presence Penalty": 0, "Frequency Penalty": 0, "Seed": "", "Store": False},
|
|
696
|
+
"branches": [
|
|
697
|
+
{"name": "bear", "to": "a", "condition": "Is it a bear?"},
|
|
698
|
+
{"to": "b", "condition": "Is it a fish?"},
|
|
699
|
+
{"to": "d", "default": True}]},
|
|
700
|
+
{"id": "a", "action": "Generate GUID"},
|
|
701
|
+
{"id": "b", "action": "Generate GUID"},
|
|
702
|
+
{"id": "d", "action": "Generate GUID"}],
|
|
703
|
+
"edges": [["start", "ai"], ["a", "stop"], ["b", "stop"], ["d", "stop"]]}
|
|
704
|
+
dto = pb.build(cfg, _proc_ctx())
|
|
705
|
+
ai = next(a for a in dto["Actions"] if a["ActionTemplateName"] == "AI Decisional")
|
|
706
|
+
P = {p["TabPropertyId"]: p for p in ai["Parameters"]}
|
|
707
|
+
cases = P["772aac51-73f5-471d-bf9f-f5099cb30124"]["Value"]
|
|
708
|
+
assert [set(c) for c in cases] == [{"id", "actionid", "condition"}] * 2
|
|
709
|
+
assert [c["condition"] for c in cases] == ["Is it a bear?", "Is it a fish?"]
|
|
710
|
+
assert P["772aac51-73f5-471d-bf9f-f5099cb30112"]["Value"] == "gpt-4o" # Model
|
|
711
|
+
assert P["772aac51-73f5-471d-bf9f-f5099cb30113"]["Value"] == "1" # Endpoint
|
|
712
|
+
assert str(P["772aac51-73f5-471d-bf9f-f5099cb30118"]["Value"]) == "1024" # Max Output Tokens (int/str ok)
|
|
713
|
+
lr = P["772aac51-73f5-471d-bf9f-f5099cb30123"] # LLM Response OUTPUT
|
|
714
|
+
assert lr["Value"].startswith("<%") and lr["Variable"][0]["variableId"]
|
|
715
|
+
dc = next(s for tab in ai["CustomData"]["configuration"]
|
|
716
|
+
for s in tab["settings"] if s.get("type") == "ai-decisional-case")
|
|
717
|
+
assert all(set(c) == {"id", "name", "target", "condition", "internalId"} for c in dc["value"])
|
|
718
|
+
assert dc["value"][0]["name"] == "bear" and dc["value"][1]["name"] == "Is it a fish?"
|
|
719
|
+
assert any(p.get("Data", {}).get("isDefault") == "default" for p in ai["Ports"])
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
def test_ai_decisional_cases_config_designer_shape():
|
|
723
|
+
"""ai-decisional-case: runtime {id,actionid,condition:str} -> designer
|
|
724
|
+
{id,name,target,condition,internalId}; name/internalId from the stashed meta, with
|
|
725
|
+
a 'Case N' name + generated internalId fallback when no meta is present."""
|
|
726
|
+
from tools.procesio.dto.process import builder as pb
|
|
727
|
+
ctx = _proc_ctx()
|
|
728
|
+
ctx["_ai_case_meta"] = {"NODE": [{"id": 0, "name": "bear", "internalId": "IID0"}]}
|
|
729
|
+
cases = [{"id": 0, "actionid": "TARGET", "condition": "Is it a bear?"}]
|
|
730
|
+
assert pb._ai_decisional_cases_config(cases, ctx, "NODE") == [
|
|
731
|
+
{"id": 0, "name": "bear", "target": "TARGET",
|
|
732
|
+
"condition": "Is it a bear?", "internalId": "IID0"}]
|
|
733
|
+
out2 = pb._ai_decisional_cases_config(cases, _proc_ctx(), "OTHER")
|
|
734
|
+
assert out2[0]["name"] == "Case 1" and out2[0]["internalId"]
|