provekit 0.1.0__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.
- provekit/__init__.py +0 -0
- provekit/cli.py +256 -0
- provekit/config.py +77 -0
- provekit/database.py +132 -0
- provekit/main.py +115 -0
- provekit/migrations/env.py +40 -0
- provekit/migrations/script.py.mako +22 -0
- provekit/migrations/versions/323eb73d463c_user_email_verified.py +32 -0
- provekit/migrations/versions/49e8ab812556_baseline_schema.py +241 -0
- provekit/migrations/versions/819ed5ff183e_workspace_ingest_key.py +35 -0
- provekit/migrations/versions/a1b2c3d4e5f6_user_token_version.py +27 -0
- provekit/models.py +191 -0
- provekit/observability.py +154 -0
- provekit/routers/__init__.py +0 -0
- provekit/routers/auth.py +150 -0
- provekit/routers/connections.py +270 -0
- provekit/routers/deployments.py +161 -0
- provekit/routers/flows.py +188 -0
- provekit/routers/library.py +265 -0
- provekit/routers/prompts.py +72 -0
- provekit/routers/run.py +203 -0
- provekit/routers/runtime.py +103 -0
- provekit/routers/traces.py +65 -0
- provekit/routers/usage.py +42 -0
- provekit/services/__init__.py +0 -0
- provekit/services/assertions.py +135 -0
- provekit/services/auth.py +131 -0
- provekit/services/deploy.py +63 -0
- provekit/services/dispatch.py +313 -0
- provekit/services/email.py +38 -0
- provekit/services/flow.py +299 -0
- provekit/services/limits.py +109 -0
- provekit/services/masking.py +45 -0
- provekit/services/netguard.py +69 -0
- provekit/services/otel.py +146 -0
- provekit/services/promptfoo.py +92 -0
- provekit/services/providers/__init__.py +0 -0
- provekit/services/providers/a2a_client.py +110 -0
- provekit/services/providers/agent_http.py +55 -0
- provekit/services/providers/llm.py +364 -0
- provekit/services/providers/mcp_client.py +289 -0
- provekit/services/runstore.py +93 -0
- provekit/services/sealing.py +106 -0
- provekit/services/templates.py +69 -0
- provekit/services/testfile.py +122 -0
- provekit/services/tooling.py +194 -0
- provekit/services/workspace.py +91 -0
- provekit/templates/flows/_manifest.json +2594 -0
- provekit/templates/flows/banking-action-items.yaml +43 -0
- provekit/templates/flows/banking-answer.yaml +43 -0
- provekit/templates/flows/banking-classify-intent.yaml +43 -0
- provekit/templates/flows/banking-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/banking-extract-to-json.yaml +43 -0
- provekit/templates/flows/banking-faq-match-answer.yaml +60 -0
- provekit/templates/flows/banking-keyword-extract.yaml +43 -0
- provekit/templates/flows/banking-language-route.yaml +103 -0
- provekit/templates/flows/banking-moderation-gate.yaml +73 -0
- provekit/templates/flows/banking-redact-summarize.yaml +59 -0
- provekit/templates/flows/banking-score-gate.yaml +73 -0
- provekit/templates/flows/banking-sentiment-route.yaml +73 -0
- provekit/templates/flows/banking-severity-tiers.yaml +103 -0
- provekit/templates/flows/banking-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/banking-tag-enrich.yaml +43 -0
- provekit/templates/flows/banking-tone-rewrite.yaml +43 -0
- provekit/templates/flows/banking-translate-reply.yaml +58 -0
- provekit/templates/flows/banking-triage-route.yaml +73 -0
- provekit/templates/flows/community-forum-action-items.yaml +43 -0
- provekit/templates/flows/community-forum-answer.yaml +43 -0
- provekit/templates/flows/community-forum-classify-intent.yaml +43 -0
- provekit/templates/flows/community-forum-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/community-forum-extract-to-json.yaml +43 -0
- provekit/templates/flows/community-forum-faq-match-answer.yaml +60 -0
- provekit/templates/flows/community-forum-keyword-extract.yaml +43 -0
- provekit/templates/flows/community-forum-language-route.yaml +103 -0
- provekit/templates/flows/community-forum-moderation-gate.yaml +73 -0
- provekit/templates/flows/community-forum-redact-summarize.yaml +59 -0
- provekit/templates/flows/community-forum-score-gate.yaml +73 -0
- provekit/templates/flows/community-forum-sentiment-route.yaml +73 -0
- provekit/templates/flows/community-forum-severity-tiers.yaml +103 -0
- provekit/templates/flows/community-forum-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/community-forum-tag-enrich.yaml +43 -0
- provekit/templates/flows/community-forum-tone-rewrite.yaml +43 -0
- provekit/templates/flows/community-forum-translate-reply.yaml +58 -0
- provekit/templates/flows/community-forum-triage-route.yaml +73 -0
- provekit/templates/flows/content-moderation-action-items.yaml +43 -0
- provekit/templates/flows/content-moderation-answer.yaml +43 -0
- provekit/templates/flows/content-moderation-classify-intent.yaml +43 -0
- provekit/templates/flows/content-moderation-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/content-moderation-extract-to-json.yaml +43 -0
- provekit/templates/flows/content-moderation-faq-match-answer.yaml +60 -0
- provekit/templates/flows/content-moderation-keyword-extract.yaml +43 -0
- provekit/templates/flows/content-moderation-language-route.yaml +103 -0
- provekit/templates/flows/content-moderation-moderation-gate.yaml +73 -0
- provekit/templates/flows/content-moderation-redact-summarize.yaml +59 -0
- provekit/templates/flows/content-moderation-score-gate.yaml +73 -0
- provekit/templates/flows/content-moderation-sentiment-route.yaml +73 -0
- provekit/templates/flows/content-moderation-severity-tiers.yaml +103 -0
- provekit/templates/flows/content-moderation-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/content-moderation-tag-enrich.yaml +43 -0
- provekit/templates/flows/content-moderation-tone-rewrite.yaml +43 -0
- provekit/templates/flows/content-moderation-translate-reply.yaml +58 -0
- provekit/templates/flows/content-moderation-triage-route.yaml +73 -0
- provekit/templates/flows/customer-support-action-items.yaml +43 -0
- provekit/templates/flows/customer-support-answer.yaml +43 -0
- provekit/templates/flows/customer-support-classify-intent.yaml +43 -0
- provekit/templates/flows/customer-support-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/customer-support-extract-to-json.yaml +43 -0
- provekit/templates/flows/customer-support-faq-match-answer.yaml +60 -0
- provekit/templates/flows/customer-support-keyword-extract.yaml +43 -0
- provekit/templates/flows/customer-support-language-route.yaml +103 -0
- provekit/templates/flows/customer-support-moderation-gate.yaml +73 -0
- provekit/templates/flows/customer-support-redact-summarize.yaml +59 -0
- provekit/templates/flows/customer-support-score-gate.yaml +73 -0
- provekit/templates/flows/customer-support-sentiment-route.yaml +73 -0
- provekit/templates/flows/customer-support-severity-tiers.yaml +103 -0
- provekit/templates/flows/customer-support-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/customer-support-tag-enrich.yaml +43 -0
- provekit/templates/flows/customer-support-tone-rewrite.yaml +43 -0
- provekit/templates/flows/customer-support-translate-reply.yaml +58 -0
- provekit/templates/flows/customer-support-triage-route.yaml +73 -0
- provekit/templates/flows/developer-tooling-action-items.yaml +43 -0
- provekit/templates/flows/developer-tooling-answer.yaml +43 -0
- provekit/templates/flows/developer-tooling-classify-intent.yaml +43 -0
- provekit/templates/flows/developer-tooling-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/developer-tooling-extract-to-json.yaml +43 -0
- provekit/templates/flows/developer-tooling-faq-match-answer.yaml +60 -0
- provekit/templates/flows/developer-tooling-keyword-extract.yaml +43 -0
- provekit/templates/flows/developer-tooling-language-route.yaml +103 -0
- provekit/templates/flows/developer-tooling-moderation-gate.yaml +73 -0
- provekit/templates/flows/developer-tooling-redact-summarize.yaml +59 -0
- provekit/templates/flows/developer-tooling-score-gate.yaml +73 -0
- provekit/templates/flows/developer-tooling-sentiment-route.yaml +73 -0
- provekit/templates/flows/developer-tooling-severity-tiers.yaml +103 -0
- provekit/templates/flows/developer-tooling-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/developer-tooling-tag-enrich.yaml +43 -0
- provekit/templates/flows/developer-tooling-tone-rewrite.yaml +43 -0
- provekit/templates/flows/developer-tooling-translate-reply.yaml +58 -0
- provekit/templates/flows/developer-tooling-triage-route.yaml +73 -0
- provekit/templates/flows/devrel-action-items.yaml +43 -0
- provekit/templates/flows/devrel-answer.yaml +43 -0
- provekit/templates/flows/devrel-classify-intent.yaml +43 -0
- provekit/templates/flows/devrel-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/devrel-extract-to-json.yaml +43 -0
- provekit/templates/flows/devrel-faq-match-answer.yaml +60 -0
- provekit/templates/flows/devrel-keyword-extract.yaml +43 -0
- provekit/templates/flows/devrel-language-route.yaml +103 -0
- provekit/templates/flows/devrel-moderation-gate.yaml +73 -0
- provekit/templates/flows/devrel-redact-summarize.yaml +59 -0
- provekit/templates/flows/devrel-score-gate.yaml +73 -0
- provekit/templates/flows/devrel-sentiment-route.yaml +73 -0
- provekit/templates/flows/devrel-severity-tiers.yaml +103 -0
- provekit/templates/flows/devrel-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/devrel-tag-enrich.yaml +43 -0
- provekit/templates/flows/devrel-tone-rewrite.yaml +43 -0
- provekit/templates/flows/devrel-translate-reply.yaml +58 -0
- provekit/templates/flows/devrel-triage-route.yaml +73 -0
- provekit/templates/flows/e-commerce-action-items.yaml +43 -0
- provekit/templates/flows/e-commerce-answer.yaml +43 -0
- provekit/templates/flows/e-commerce-classify-intent.yaml +43 -0
- provekit/templates/flows/e-commerce-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/e-commerce-extract-to-json.yaml +43 -0
- provekit/templates/flows/e-commerce-faq-match-answer.yaml +60 -0
- provekit/templates/flows/e-commerce-keyword-extract.yaml +43 -0
- provekit/templates/flows/e-commerce-language-route.yaml +103 -0
- provekit/templates/flows/e-commerce-moderation-gate.yaml +73 -0
- provekit/templates/flows/e-commerce-redact-summarize.yaml +59 -0
- provekit/templates/flows/e-commerce-score-gate.yaml +73 -0
- provekit/templates/flows/e-commerce-sentiment-route.yaml +73 -0
- provekit/templates/flows/e-commerce-severity-tiers.yaml +103 -0
- provekit/templates/flows/e-commerce-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/e-commerce-tag-enrich.yaml +43 -0
- provekit/templates/flows/e-commerce-tone-rewrite.yaml +43 -0
- provekit/templates/flows/e-commerce-translate-reply.yaml +58 -0
- provekit/templates/flows/e-commerce-triage-route.yaml +73 -0
- provekit/templates/flows/education-action-items.yaml +43 -0
- provekit/templates/flows/education-answer.yaml +43 -0
- provekit/templates/flows/education-classify-intent.yaml +43 -0
- provekit/templates/flows/education-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/education-extract-to-json.yaml +43 -0
- provekit/templates/flows/education-faq-match-answer.yaml +60 -0
- provekit/templates/flows/education-keyword-extract.yaml +43 -0
- provekit/templates/flows/education-language-route.yaml +103 -0
- provekit/templates/flows/education-moderation-gate.yaml +73 -0
- provekit/templates/flows/education-redact-summarize.yaml +59 -0
- provekit/templates/flows/education-score-gate.yaml +73 -0
- provekit/templates/flows/education-sentiment-route.yaml +73 -0
- provekit/templates/flows/education-severity-tiers.yaml +103 -0
- provekit/templates/flows/education-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/education-tag-enrich.yaml +43 -0
- provekit/templates/flows/education-tone-rewrite.yaml +43 -0
- provekit/templates/flows/education-translate-reply.yaml +58 -0
- provekit/templates/flows/education-triage-route.yaml +73 -0
- provekit/templates/flows/finance-action-items.yaml +43 -0
- provekit/templates/flows/finance-answer.yaml +43 -0
- provekit/templates/flows/finance-classify-intent.yaml +43 -0
- provekit/templates/flows/finance-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/finance-extract-to-json.yaml +43 -0
- provekit/templates/flows/finance-faq-match-answer.yaml +60 -0
- provekit/templates/flows/finance-keyword-extract.yaml +43 -0
- provekit/templates/flows/finance-language-route.yaml +103 -0
- provekit/templates/flows/finance-moderation-gate.yaml +73 -0
- provekit/templates/flows/finance-redact-summarize.yaml +59 -0
- provekit/templates/flows/finance-score-gate.yaml +73 -0
- provekit/templates/flows/finance-sentiment-route.yaml +73 -0
- provekit/templates/flows/finance-severity-tiers.yaml +103 -0
- provekit/templates/flows/finance-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/finance-tag-enrich.yaml +43 -0
- provekit/templates/flows/finance-tone-rewrite.yaml +43 -0
- provekit/templates/flows/finance-translate-reply.yaml +58 -0
- provekit/templates/flows/finance-triage-route.yaml +73 -0
- provekit/templates/flows/food-delivery-action-items.yaml +43 -0
- provekit/templates/flows/food-delivery-answer.yaml +43 -0
- provekit/templates/flows/food-delivery-classify-intent.yaml +43 -0
- provekit/templates/flows/food-delivery-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/food-delivery-extract-to-json.yaml +43 -0
- provekit/templates/flows/food-delivery-faq-match-answer.yaml +60 -0
- provekit/templates/flows/food-delivery-keyword-extract.yaml +43 -0
- provekit/templates/flows/food-delivery-language-route.yaml +103 -0
- provekit/templates/flows/food-delivery-moderation-gate.yaml +73 -0
- provekit/templates/flows/food-delivery-redact-summarize.yaml +59 -0
- provekit/templates/flows/food-delivery-score-gate.yaml +73 -0
- provekit/templates/flows/food-delivery-sentiment-route.yaml +73 -0
- provekit/templates/flows/food-delivery-severity-tiers.yaml +103 -0
- provekit/templates/flows/food-delivery-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/food-delivery-tag-enrich.yaml +43 -0
- provekit/templates/flows/food-delivery-tone-rewrite.yaml +43 -0
- provekit/templates/flows/food-delivery-translate-reply.yaml +58 -0
- provekit/templates/flows/food-delivery-triage-route.yaml +73 -0
- provekit/templates/flows/gaming-support-action-items.yaml +43 -0
- provekit/templates/flows/gaming-support-answer.yaml +43 -0
- provekit/templates/flows/gaming-support-classify-intent.yaml +43 -0
- provekit/templates/flows/gaming-support-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/gaming-support-extract-to-json.yaml +43 -0
- provekit/templates/flows/gaming-support-faq-match-answer.yaml +60 -0
- provekit/templates/flows/gaming-support-keyword-extract.yaml +43 -0
- provekit/templates/flows/gaming-support-language-route.yaml +103 -0
- provekit/templates/flows/gaming-support-moderation-gate.yaml +73 -0
- provekit/templates/flows/gaming-support-redact-summarize.yaml +59 -0
- provekit/templates/flows/gaming-support-score-gate.yaml +73 -0
- provekit/templates/flows/gaming-support-sentiment-route.yaml +73 -0
- provekit/templates/flows/gaming-support-severity-tiers.yaml +103 -0
- provekit/templates/flows/gaming-support-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/gaming-support-tag-enrich.yaml +43 -0
- provekit/templates/flows/gaming-support-tone-rewrite.yaml +43 -0
- provekit/templates/flows/gaming-support-translate-reply.yaml +58 -0
- provekit/templates/flows/gaming-support-triage-route.yaml +73 -0
- provekit/templates/flows/healthcare-intake-action-items.yaml +43 -0
- provekit/templates/flows/healthcare-intake-answer.yaml +43 -0
- provekit/templates/flows/healthcare-intake-classify-intent.yaml +43 -0
- provekit/templates/flows/healthcare-intake-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/healthcare-intake-extract-to-json.yaml +43 -0
- provekit/templates/flows/healthcare-intake-faq-match-answer.yaml +60 -0
- provekit/templates/flows/healthcare-intake-keyword-extract.yaml +43 -0
- provekit/templates/flows/healthcare-intake-language-route.yaml +103 -0
- provekit/templates/flows/healthcare-intake-moderation-gate.yaml +73 -0
- provekit/templates/flows/healthcare-intake-redact-summarize.yaml +59 -0
- provekit/templates/flows/healthcare-intake-score-gate.yaml +73 -0
- provekit/templates/flows/healthcare-intake-sentiment-route.yaml +73 -0
- provekit/templates/flows/healthcare-intake-severity-tiers.yaml +103 -0
- provekit/templates/flows/healthcare-intake-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/healthcare-intake-tag-enrich.yaml +43 -0
- provekit/templates/flows/healthcare-intake-tone-rewrite.yaml +43 -0
- provekit/templates/flows/healthcare-intake-translate-reply.yaml +58 -0
- provekit/templates/flows/healthcare-intake-triage-route.yaml +73 -0
- provekit/templates/flows/hr-action-items.yaml +43 -0
- provekit/templates/flows/hr-answer.yaml +43 -0
- provekit/templates/flows/hr-classify-intent.yaml +43 -0
- provekit/templates/flows/hr-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/hr-extract-to-json.yaml +43 -0
- provekit/templates/flows/hr-faq-match-answer.yaml +60 -0
- provekit/templates/flows/hr-keyword-extract.yaml +43 -0
- provekit/templates/flows/hr-language-route.yaml +103 -0
- provekit/templates/flows/hr-moderation-gate.yaml +73 -0
- provekit/templates/flows/hr-redact-summarize.yaml +59 -0
- provekit/templates/flows/hr-score-gate.yaml +73 -0
- provekit/templates/flows/hr-sentiment-route.yaml +73 -0
- provekit/templates/flows/hr-severity-tiers.yaml +103 -0
- provekit/templates/flows/hr-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/hr-tag-enrich.yaml +43 -0
- provekit/templates/flows/hr-tone-rewrite.yaml +43 -0
- provekit/templates/flows/hr-translate-reply.yaml +58 -0
- provekit/templates/flows/hr-triage-route.yaml +73 -0
- provekit/templates/flows/insurance-action-items.yaml +43 -0
- provekit/templates/flows/insurance-answer.yaml +43 -0
- provekit/templates/flows/insurance-classify-intent.yaml +43 -0
- provekit/templates/flows/insurance-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/insurance-extract-to-json.yaml +43 -0
- provekit/templates/flows/insurance-faq-match-answer.yaml +60 -0
- provekit/templates/flows/insurance-keyword-extract.yaml +43 -0
- provekit/templates/flows/insurance-language-route.yaml +103 -0
- provekit/templates/flows/insurance-moderation-gate.yaml +73 -0
- provekit/templates/flows/insurance-redact-summarize.yaml +59 -0
- provekit/templates/flows/insurance-score-gate.yaml +73 -0
- provekit/templates/flows/insurance-sentiment-route.yaml +73 -0
- provekit/templates/flows/insurance-severity-tiers.yaml +103 -0
- provekit/templates/flows/insurance-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/insurance-tag-enrich.yaml +43 -0
- provekit/templates/flows/insurance-tone-rewrite.yaml +43 -0
- provekit/templates/flows/insurance-translate-reply.yaml +58 -0
- provekit/templates/flows/insurance-triage-route.yaml +73 -0
- provekit/templates/flows/it-helpdesk-action-items.yaml +43 -0
- provekit/templates/flows/it-helpdesk-answer.yaml +43 -0
- provekit/templates/flows/it-helpdesk-classify-intent.yaml +43 -0
- provekit/templates/flows/it-helpdesk-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/it-helpdesk-extract-to-json.yaml +43 -0
- provekit/templates/flows/it-helpdesk-faq-match-answer.yaml +60 -0
- provekit/templates/flows/it-helpdesk-keyword-extract.yaml +43 -0
- provekit/templates/flows/it-helpdesk-language-route.yaml +103 -0
- provekit/templates/flows/it-helpdesk-moderation-gate.yaml +73 -0
- provekit/templates/flows/it-helpdesk-redact-summarize.yaml +59 -0
- provekit/templates/flows/it-helpdesk-score-gate.yaml +73 -0
- provekit/templates/flows/it-helpdesk-sentiment-route.yaml +73 -0
- provekit/templates/flows/it-helpdesk-severity-tiers.yaml +103 -0
- provekit/templates/flows/it-helpdesk-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/it-helpdesk-tag-enrich.yaml +43 -0
- provekit/templates/flows/it-helpdesk-tone-rewrite.yaml +43 -0
- provekit/templates/flows/it-helpdesk-translate-reply.yaml +58 -0
- provekit/templates/flows/it-helpdesk-triage-route.yaml +73 -0
- provekit/templates/flows/legal-intake-action-items.yaml +43 -0
- provekit/templates/flows/legal-intake-answer.yaml +43 -0
- provekit/templates/flows/legal-intake-classify-intent.yaml +43 -0
- provekit/templates/flows/legal-intake-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/legal-intake-extract-to-json.yaml +43 -0
- provekit/templates/flows/legal-intake-faq-match-answer.yaml +60 -0
- provekit/templates/flows/legal-intake-keyword-extract.yaml +43 -0
- provekit/templates/flows/legal-intake-language-route.yaml +103 -0
- provekit/templates/flows/legal-intake-moderation-gate.yaml +73 -0
- provekit/templates/flows/legal-intake-redact-summarize.yaml +59 -0
- provekit/templates/flows/legal-intake-score-gate.yaml +73 -0
- provekit/templates/flows/legal-intake-sentiment-route.yaml +73 -0
- provekit/templates/flows/legal-intake-severity-tiers.yaml +103 -0
- provekit/templates/flows/legal-intake-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/legal-intake-tag-enrich.yaml +43 -0
- provekit/templates/flows/legal-intake-tone-rewrite.yaml +43 -0
- provekit/templates/flows/legal-intake-translate-reply.yaml +58 -0
- provekit/templates/flows/legal-intake-triage-route.yaml +73 -0
- provekit/templates/flows/logistics-action-items.yaml +43 -0
- provekit/templates/flows/logistics-answer.yaml +43 -0
- provekit/templates/flows/logistics-classify-intent.yaml +43 -0
- provekit/templates/flows/logistics-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/logistics-extract-to-json.yaml +43 -0
- provekit/templates/flows/logistics-faq-match-answer.yaml +60 -0
- provekit/templates/flows/logistics-keyword-extract.yaml +43 -0
- provekit/templates/flows/logistics-language-route.yaml +103 -0
- provekit/templates/flows/logistics-moderation-gate.yaml +73 -0
- provekit/templates/flows/logistics-redact-summarize.yaml +59 -0
- provekit/templates/flows/logistics-score-gate.yaml +73 -0
- provekit/templates/flows/logistics-sentiment-route.yaml +73 -0
- provekit/templates/flows/logistics-severity-tiers.yaml +103 -0
- provekit/templates/flows/logistics-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/logistics-tag-enrich.yaml +43 -0
- provekit/templates/flows/logistics-tone-rewrite.yaml +43 -0
- provekit/templates/flows/logistics-translate-reply.yaml +58 -0
- provekit/templates/flows/logistics-triage-route.yaml +73 -0
- provekit/templates/flows/marketing-action-items.yaml +43 -0
- provekit/templates/flows/marketing-answer.yaml +43 -0
- provekit/templates/flows/marketing-classify-intent.yaml +43 -0
- provekit/templates/flows/marketing-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/marketing-extract-to-json.yaml +43 -0
- provekit/templates/flows/marketing-faq-match-answer.yaml +60 -0
- provekit/templates/flows/marketing-keyword-extract.yaml +43 -0
- provekit/templates/flows/marketing-language-route.yaml +103 -0
- provekit/templates/flows/marketing-moderation-gate.yaml +73 -0
- provekit/templates/flows/marketing-redact-summarize.yaml +59 -0
- provekit/templates/flows/marketing-score-gate.yaml +73 -0
- provekit/templates/flows/marketing-sentiment-route.yaml +73 -0
- provekit/templates/flows/marketing-severity-tiers.yaml +103 -0
- provekit/templates/flows/marketing-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/marketing-tag-enrich.yaml +43 -0
- provekit/templates/flows/marketing-tone-rewrite.yaml +43 -0
- provekit/templates/flows/marketing-translate-reply.yaml +58 -0
- provekit/templates/flows/marketing-triage-route.yaml +73 -0
- provekit/templates/flows/nonprofit-action-items.yaml +43 -0
- provekit/templates/flows/nonprofit-answer.yaml +43 -0
- provekit/templates/flows/nonprofit-classify-intent.yaml +43 -0
- provekit/templates/flows/nonprofit-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/nonprofit-extract-to-json.yaml +43 -0
- provekit/templates/flows/nonprofit-faq-match-answer.yaml +60 -0
- provekit/templates/flows/nonprofit-keyword-extract.yaml +43 -0
- provekit/templates/flows/nonprofit-language-route.yaml +103 -0
- provekit/templates/flows/nonprofit-moderation-gate.yaml +73 -0
- provekit/templates/flows/nonprofit-redact-summarize.yaml +59 -0
- provekit/templates/flows/nonprofit-score-gate.yaml +73 -0
- provekit/templates/flows/nonprofit-sentiment-route.yaml +73 -0
- provekit/templates/flows/nonprofit-severity-tiers.yaml +103 -0
- provekit/templates/flows/nonprofit-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/nonprofit-tag-enrich.yaml +43 -0
- provekit/templates/flows/nonprofit-tone-rewrite.yaml +43 -0
- provekit/templates/flows/nonprofit-translate-reply.yaml +58 -0
- provekit/templates/flows/nonprofit-triage-route.yaml +73 -0
- provekit/templates/flows/real-estate-action-items.yaml +43 -0
- provekit/templates/flows/real-estate-answer.yaml +43 -0
- provekit/templates/flows/real-estate-classify-intent.yaml +43 -0
- provekit/templates/flows/real-estate-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/real-estate-extract-to-json.yaml +43 -0
- provekit/templates/flows/real-estate-faq-match-answer.yaml +60 -0
- provekit/templates/flows/real-estate-keyword-extract.yaml +43 -0
- provekit/templates/flows/real-estate-language-route.yaml +103 -0
- provekit/templates/flows/real-estate-moderation-gate.yaml +73 -0
- provekit/templates/flows/real-estate-redact-summarize.yaml +59 -0
- provekit/templates/flows/real-estate-score-gate.yaml +73 -0
- provekit/templates/flows/real-estate-sentiment-route.yaml +73 -0
- provekit/templates/flows/real-estate-severity-tiers.yaml +103 -0
- provekit/templates/flows/real-estate-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/real-estate-tag-enrich.yaml +43 -0
- provekit/templates/flows/real-estate-tone-rewrite.yaml +43 -0
- provekit/templates/flows/real-estate-translate-reply.yaml +58 -0
- provekit/templates/flows/real-estate-triage-route.yaml +73 -0
- provekit/templates/flows/recruiting-action-items.yaml +43 -0
- provekit/templates/flows/recruiting-answer.yaml +43 -0
- provekit/templates/flows/recruiting-classify-intent.yaml +43 -0
- provekit/templates/flows/recruiting-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/recruiting-extract-to-json.yaml +43 -0
- provekit/templates/flows/recruiting-faq-match-answer.yaml +60 -0
- provekit/templates/flows/recruiting-keyword-extract.yaml +43 -0
- provekit/templates/flows/recruiting-language-route.yaml +103 -0
- provekit/templates/flows/recruiting-moderation-gate.yaml +73 -0
- provekit/templates/flows/recruiting-redact-summarize.yaml +59 -0
- provekit/templates/flows/recruiting-score-gate.yaml +73 -0
- provekit/templates/flows/recruiting-sentiment-route.yaml +73 -0
- provekit/templates/flows/recruiting-severity-tiers.yaml +103 -0
- provekit/templates/flows/recruiting-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/recruiting-tag-enrich.yaml +43 -0
- provekit/templates/flows/recruiting-tone-rewrite.yaml +43 -0
- provekit/templates/flows/recruiting-translate-reply.yaml +58 -0
- provekit/templates/flows/recruiting-triage-route.yaml +73 -0
- provekit/templates/flows/research-action-items.yaml +43 -0
- provekit/templates/flows/research-answer.yaml +43 -0
- provekit/templates/flows/research-classify-intent.yaml +43 -0
- provekit/templates/flows/research-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/research-extract-to-json.yaml +43 -0
- provekit/templates/flows/research-faq-match-answer.yaml +60 -0
- provekit/templates/flows/research-keyword-extract.yaml +43 -0
- provekit/templates/flows/research-language-route.yaml +103 -0
- provekit/templates/flows/research-moderation-gate.yaml +73 -0
- provekit/templates/flows/research-redact-summarize.yaml +59 -0
- provekit/templates/flows/research-score-gate.yaml +73 -0
- provekit/templates/flows/research-sentiment-route.yaml +73 -0
- provekit/templates/flows/research-severity-tiers.yaml +103 -0
- provekit/templates/flows/research-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/research-tag-enrich.yaml +43 -0
- provekit/templates/flows/research-tone-rewrite.yaml +43 -0
- provekit/templates/flows/research-translate-reply.yaml +58 -0
- provekit/templates/flows/research-triage-route.yaml +73 -0
- provekit/templates/flows/sales-lead-action-items.yaml +43 -0
- provekit/templates/flows/sales-lead-answer.yaml +43 -0
- provekit/templates/flows/sales-lead-classify-intent.yaml +43 -0
- provekit/templates/flows/sales-lead-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/sales-lead-extract-to-json.yaml +43 -0
- provekit/templates/flows/sales-lead-faq-match-answer.yaml +60 -0
- provekit/templates/flows/sales-lead-keyword-extract.yaml +43 -0
- provekit/templates/flows/sales-lead-language-route.yaml +103 -0
- provekit/templates/flows/sales-lead-moderation-gate.yaml +73 -0
- provekit/templates/flows/sales-lead-redact-summarize.yaml +59 -0
- provekit/templates/flows/sales-lead-score-gate.yaml +73 -0
- provekit/templates/flows/sales-lead-sentiment-route.yaml +73 -0
- provekit/templates/flows/sales-lead-severity-tiers.yaml +103 -0
- provekit/templates/flows/sales-lead-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/sales-lead-tag-enrich.yaml +43 -0
- provekit/templates/flows/sales-lead-tone-rewrite.yaml +43 -0
- provekit/templates/flows/sales-lead-translate-reply.yaml +58 -0
- provekit/templates/flows/sales-lead-triage-route.yaml +73 -0
- provekit/templates/flows/travel-action-items.yaml +43 -0
- provekit/templates/flows/travel-answer.yaml +43 -0
- provekit/templates/flows/travel-classify-intent.yaml +43 -0
- provekit/templates/flows/travel-draft-critique-revise.yaml +75 -0
- provekit/templates/flows/travel-extract-to-json.yaml +43 -0
- provekit/templates/flows/travel-faq-match-answer.yaml +60 -0
- provekit/templates/flows/travel-keyword-extract.yaml +43 -0
- provekit/templates/flows/travel-language-route.yaml +103 -0
- provekit/templates/flows/travel-moderation-gate.yaml +73 -0
- provekit/templates/flows/travel-redact-summarize.yaml +59 -0
- provekit/templates/flows/travel-score-gate.yaml +73 -0
- provekit/templates/flows/travel-sentiment-route.yaml +73 -0
- provekit/templates/flows/travel-severity-tiers.yaml +103 -0
- provekit/templates/flows/travel-summarize-then-decide.yaml +88 -0
- provekit/templates/flows/travel-tag-enrich.yaml +43 -0
- provekit/templates/flows/travel-tone-rewrite.yaml +43 -0
- provekit/templates/flows/travel-translate-reply.yaml +58 -0
- provekit/templates/flows/travel-triage-route.yaml +73 -0
- provekit-0.1.0.dist-info/METADATA +86 -0
- provekit-0.1.0.dist-info/RECORD +485 -0
- provekit-0.1.0.dist-info/WHEEL +5 -0
- provekit-0.1.0.dist-info/entry_points.txt +2 -0
- provekit-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Give the model under test a set of MCP tools it can actually call.
|
|
2
|
+
|
|
3
|
+
A prompt request may attach MCP connections:
|
|
4
|
+
|
|
5
|
+
"tools": [{"connection_id": 7, "tools": ["check_inventory"], "execute": true}]
|
|
6
|
+
|
|
7
|
+
Each attachment is resolved to the tools that server advertises (all of them unless
|
|
8
|
+
`tools` narrows it), translated into the shape the target provider expects, and — when the
|
|
9
|
+
model picks one — executed back through the same MCP connection. `execute: false` records
|
|
10
|
+
the call and stops instead, so a routing decision can be asserted without firing the real
|
|
11
|
+
side effect.
|
|
12
|
+
|
|
13
|
+
The model sees a sanitized name (providers require ^[A-Za-z0-9_-]{1,64}$, MCP does not);
|
|
14
|
+
events and assertions always report the server's real tool name, so `tool_called` reads the
|
|
15
|
+
way a user wrote it.
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import json
|
|
20
|
+
import re
|
|
21
|
+
from dataclasses import dataclass
|
|
22
|
+
|
|
23
|
+
from ..models import Connection
|
|
24
|
+
from .providers import mcp_client
|
|
25
|
+
|
|
26
|
+
# Provider-legal function names. MCP tool names are unconstrained, so they're mapped.
|
|
27
|
+
_NAME_OK = re.compile(r"[^A-Za-z0-9_-]")
|
|
28
|
+
MAX_TOOL_ROUNDS = 25 # ceiling on a request's max_tool_rounds: a loop is a cost/latency risk
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class Tool:
|
|
33
|
+
"""One MCP tool, ready to advertise to a model and to invoke."""
|
|
34
|
+
api_name: str # what the model is told (sanitized, unique across attachments)
|
|
35
|
+
name: str # the server's real tool name — what events/assertions report
|
|
36
|
+
description: str
|
|
37
|
+
input_schema: dict
|
|
38
|
+
connection_id: int | None
|
|
39
|
+
cfg: dict # the resolved MCP connection config (authoritative for secrets)
|
|
40
|
+
execute: bool # False → capture the call and stop, never invoke
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _conn(db, cid, workspace_id=None) -> Connection | None:
|
|
44
|
+
"""Same tenancy rule as dispatch._conn: never resolve another workspace's connection."""
|
|
45
|
+
if not cid:
|
|
46
|
+
return None
|
|
47
|
+
c = db.get(Connection, cid)
|
|
48
|
+
if c and workspace_id is not None and c.workspace_id != workspace_id:
|
|
49
|
+
return None
|
|
50
|
+
return c
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _api_name(name: str, taken: set[str]) -> str:
|
|
54
|
+
base = _NAME_OK.sub("_", name or "tool")[:64] or "tool"
|
|
55
|
+
out, n = base, 2
|
|
56
|
+
while out in taken: # two servers exposing the same tool name must stay distinguishable
|
|
57
|
+
suffix = f"_{n}"
|
|
58
|
+
out, n = base[:64 - len(suffix)] + suffix, n + 1
|
|
59
|
+
return out
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
class _Attach:
|
|
64
|
+
"""One resolved attachment, before its server has been asked what it offers."""
|
|
65
|
+
name: str
|
|
66
|
+
connection_id: int
|
|
67
|
+
cfg: dict
|
|
68
|
+
allow: set[str] | None # None → every tool the server offers; a set → exactly those
|
|
69
|
+
execute: bool
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def plan(db, spec, workspace_id=None) -> list[_Attach]:
|
|
73
|
+
"""Resolve `tools` attachments against the database. Touches no network, so it is safe
|
|
74
|
+
to call on the event loop; `discover` does the talking."""
|
|
75
|
+
out = []
|
|
76
|
+
for att in spec or []:
|
|
77
|
+
if not isinstance(att, dict):
|
|
78
|
+
continue
|
|
79
|
+
cid = att.get("connection_id")
|
|
80
|
+
conn = _conn(db, cid, workspace_id)
|
|
81
|
+
if not conn:
|
|
82
|
+
raise ValueError(f"tools: MCP connection {cid!r} not found")
|
|
83
|
+
if conn.kind != "mcp":
|
|
84
|
+
raise ValueError(f"tools: connection {conn.name!r} is a {conn.kind} connection, not mcp")
|
|
85
|
+
# Omitting `tools` exposes everything; an explicit list means exactly that list —
|
|
86
|
+
# including an empty one. Treating [] as "all" made unticking the last tool in the
|
|
87
|
+
# UI silently hand the model every tool instead of none.
|
|
88
|
+
raw = att.get("tools")
|
|
89
|
+
out.append(_Attach(name=conn.name, connection_id=conn.id, cfg=conn.config or {},
|
|
90
|
+
allow=None if raw is None else {str(t) for t in raw},
|
|
91
|
+
execute=att.get("execute", True) is not False))
|
|
92
|
+
return out
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def discover(plans: list[_Attach]) -> list[Tool]:
|
|
96
|
+
"""Ask each MCP server what it offers. Blocking (HTTP, or spawning a stdio server), so
|
|
97
|
+
callers on the event loop must offload this to a thread.
|
|
98
|
+
|
|
99
|
+
An unreachable server fails the run up front rather than halfway through a model turn.
|
|
100
|
+
"""
|
|
101
|
+
tools: list[Tool] = []
|
|
102
|
+
taken: set[str] = set()
|
|
103
|
+
for att in plans:
|
|
104
|
+
try:
|
|
105
|
+
discovered = _session(att.cfg).list_tools()
|
|
106
|
+
except Exception as exc:
|
|
107
|
+
raise ValueError(f"tools: MCP connection {att.name!r} discovery failed: {exc}")
|
|
108
|
+
for t in discovered:
|
|
109
|
+
if att.allow is not None and t["name"] not in att.allow:
|
|
110
|
+
continue
|
|
111
|
+
api = _api_name(t["name"], taken)
|
|
112
|
+
taken.add(api)
|
|
113
|
+
tools.append(Tool(api_name=api, name=t["name"], description=t.get("description", ""),
|
|
114
|
+
input_schema=t.get("input_schema") or {},
|
|
115
|
+
connection_id=att.connection_id, cfg=att.cfg, execute=att.execute))
|
|
116
|
+
return tools
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def resolve(db, spec, workspace_id=None) -> list[Tool]:
|
|
120
|
+
"""plan + discover, for synchronous callers (the CLI, tests)."""
|
|
121
|
+
return discover(plan(db, spec, workspace_id))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _session(cfg: dict) -> mcp_client.MCPSession:
|
|
125
|
+
"""An MCP session from a stored connection. The connection is authoritative for both
|
|
126
|
+
destination and credentials — a caller never supplies a url or secret here."""
|
|
127
|
+
if cfg.get("command"):
|
|
128
|
+
return mcp_client.MCPSession(command=cfg["command"], args=cfg.get("args"),
|
|
129
|
+
env=cfg.get("env"), spec=cfg.get("spec", "auto"))
|
|
130
|
+
if not cfg.get("url"):
|
|
131
|
+
raise ValueError("MCP connection has no url or command")
|
|
132
|
+
return mcp_client.MCPSession(cfg["url"], headers=cfg.get("headers"),
|
|
133
|
+
spec=cfg.get("spec", "auto"), oauth=cfg.get("oauth"))
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _render(out) -> str:
|
|
137
|
+
if isinstance(out, str):
|
|
138
|
+
return out
|
|
139
|
+
try:
|
|
140
|
+
return json.dumps(out)
|
|
141
|
+
except (TypeError, ValueError):
|
|
142
|
+
return str(out)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class Runner:
|
|
146
|
+
"""Holds one open MCP session per connection for the life of a run.
|
|
147
|
+
|
|
148
|
+
Building a session is expensive — it re-runs the initialize handshake, spawns a fresh
|
|
149
|
+
subprocess for stdio, and re-fetches an OAuth token — so a session per tool call would
|
|
150
|
+
pay all of that on every round. Blocking, like everything else here: callers on the
|
|
151
|
+
event loop must offload `call` to a thread, and `close` runs at the end of the run.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
def __init__(self) -> None:
|
|
155
|
+
self._open: dict[int | None, mcp_client.MCPSession] = {}
|
|
156
|
+
|
|
157
|
+
def call(self, tool: Tool, args: dict) -> str:
|
|
158
|
+
sess = self._open.get(tool.connection_id)
|
|
159
|
+
if sess is None:
|
|
160
|
+
sess = self._open[tool.connection_id] = _session(tool.cfg).open()
|
|
161
|
+
return _render(sess.call_tool(tool.name, args or {}))
|
|
162
|
+
|
|
163
|
+
def close(self) -> None:
|
|
164
|
+
for sess in self._open.values():
|
|
165
|
+
try:
|
|
166
|
+
sess.close()
|
|
167
|
+
except Exception: # never let transport teardown mask the run's own outcome
|
|
168
|
+
pass
|
|
169
|
+
self._open.clear()
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def call(tool: Tool, args: dict) -> str:
|
|
173
|
+
"""Invoke one tool on a throwaway session — for one-shot callers (CLI, tests)."""
|
|
174
|
+
with _session(tool.cfg).session() as sess:
|
|
175
|
+
return _render(sess.call_tool(tool.name, args or {}))
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
# ---- provider tool-definition schemas -------------------------------------------------
|
|
179
|
+
def _schema(t: Tool) -> dict:
|
|
180
|
+
# Providers reject a bare {} — an object schema with no properties is the empty case.
|
|
181
|
+
return t.input_schema or {"type": "object", "properties": {}}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def for_provider(tools: list[Tool], provider: str) -> list[dict] | None:
|
|
185
|
+
if not tools:
|
|
186
|
+
return None
|
|
187
|
+
if provider == "anthropic":
|
|
188
|
+
return [{"name": t.api_name, "description": t.description, "input_schema": _schema(t)}
|
|
189
|
+
for t in tools]
|
|
190
|
+
if provider == "openai-responses":
|
|
191
|
+
return [{"type": "function", "name": t.api_name, "description": t.description,
|
|
192
|
+
"parameters": _schema(t)} for t in tools]
|
|
193
|
+
return [{"type": "function", "function": {"name": t.api_name, "description": t.description,
|
|
194
|
+
"parameters": _schema(t)}} for t in tools]
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Workspace resolution + per-workspace seeding.
|
|
2
|
+
|
|
3
|
+
Each user gets a default workspace on first use; its example connections, prompts, and
|
|
4
|
+
demo flows are seeded then (not globally at startup). current_workspace is the dependency
|
|
5
|
+
every tenant-scoped router uses to isolate data.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
|
|
11
|
+
from fastapi import Depends
|
|
12
|
+
from sqlalchemy.orm import Session
|
|
13
|
+
|
|
14
|
+
from ..config import get_settings
|
|
15
|
+
from ..database import get_db
|
|
16
|
+
from ..models import Connection, Flow, Prompt, Workspace, WorkspaceMember
|
|
17
|
+
from .auth import get_current_user
|
|
18
|
+
|
|
19
|
+
log = logging.getLogger("provekit.workspace")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_or_create_default_workspace(db: Session, user) -> Workspace:
|
|
23
|
+
w = (db.query(Workspace)
|
|
24
|
+
.join(WorkspaceMember, WorkspaceMember.workspace_id == Workspace.id)
|
|
25
|
+
.filter(WorkspaceMember.user_id == user.id)
|
|
26
|
+
.order_by(Workspace.id).first())
|
|
27
|
+
if w:
|
|
28
|
+
return w
|
|
29
|
+
w = Workspace(name="My workspace", owner_user_id=user.id)
|
|
30
|
+
db.add(w); db.commit(); db.refresh(w)
|
|
31
|
+
db.add(WorkspaceMember(workspace_id=w.id, user_id=user.id, role="owner")); db.commit()
|
|
32
|
+
seed_workspace(db, w.id)
|
|
33
|
+
return w
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def current_workspace(user=Depends(get_current_user), db: Session = Depends(get_db)) -> Workspace:
|
|
37
|
+
return get_or_create_default_workspace(db, user)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# ---- seeding (per workspace) ----
|
|
41
|
+
def _seed_connections(db: Session, ws: int) -> None:
|
|
42
|
+
s = get_settings()
|
|
43
|
+
rows = [Connection(workspace_id=ws, name="Demo Assistant (mock)", kind="llm",
|
|
44
|
+
config={"provider": "mock", "base_url": "", "api_key": "", "models": ["demo-mock"]})]
|
|
45
|
+
if s.seed_examples:
|
|
46
|
+
# Never distribute the operator's own OpenAI key to tenant workspaces in hosted
|
|
47
|
+
# mode — every signup would otherwise get a connection billed to the operator.
|
|
48
|
+
# Hosted tenants get an empty key to fill in with their own.
|
|
49
|
+
seeded_openai_key = "" if s.hosted else s.openai_api_key
|
|
50
|
+
rows += [
|
|
51
|
+
Connection(workspace_id=ws, name="OpenAI", kind="llm", config={
|
|
52
|
+
"provider": "openai", "base_url": "", "api_key": seeded_openai_key,
|
|
53
|
+
"models": ["gpt-4o-mini", "gpt-4o", "gpt-4.1-mini"]}),
|
|
54
|
+
Connection(workspace_id=ws, name="Anthropic", kind="llm", config={
|
|
55
|
+
"provider": "anthropic", "base_url": "", "api_key": "",
|
|
56
|
+
"models": ["claude-sonnet-4-5", "claude-haiku-4-5-20251001"]}),
|
|
57
|
+
]
|
|
58
|
+
db.add_all(rows); db.commit()
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _seed_prompts(db: Session, ws: int) -> None:
|
|
62
|
+
db.add_all([
|
|
63
|
+
Prompt(workspace_id=ws, key="assistant.system", name="Helpful assistant",
|
|
64
|
+
description="A general system prompt.",
|
|
65
|
+
content="You are a helpful, concise assistant. Answer clearly and cite sources when relevant."),
|
|
66
|
+
Prompt(workspace_id=ws, key="extract.json", name="JSON extractor",
|
|
67
|
+
description="Extract structured fields as JSON.",
|
|
68
|
+
content="Extract the requested fields from the input. Return ONLY valid JSON, no prose. Use null when a field is not present."),
|
|
69
|
+
])
|
|
70
|
+
db.commit()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _seed_flows(db: Session, ws: int) -> None:
|
|
74
|
+
demo = db.query(Connection).filter(Connection.workspace_id == ws, Connection.name == "Demo Assistant (mock)").first()
|
|
75
|
+
did = demo.id if demo else None
|
|
76
|
+
db.add(Flow(workspace_id=ws, name="Demo · Ask the agent",
|
|
77
|
+
description="Keyless demo — ask a question, the mock agent streams an answer.",
|
|
78
|
+
nodes=[
|
|
79
|
+
{"id": "input", "type": "input", "position": {"x": 60, "y": 160}, "data": {"title": "Question"}, "config": {"sample": {"question": "What is an AI agent?"}}},
|
|
80
|
+
{"id": "ask", "type": "prompt", "position": {"x": 360, "y": 160}, "data": {"title": "Ask agent"}, "config": {"connection_id": did, "model": "demo-mock", "system": "You are a helpful assistant.", "user": "{{input.question}}"}},
|
|
81
|
+
{"id": "out", "type": "output", "position": {"x": 680, "y": 160}, "data": {"title": "Answer"}, "config": {"value": "{{ask.text}}"}},
|
|
82
|
+
],
|
|
83
|
+
edges=[{"id": "d1", "source": "input", "target": "ask"}, {"id": "d2", "source": "ask", "target": "out"}]))
|
|
84
|
+
db.commit()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def seed_workspace(db: Session, ws: int) -> None:
|
|
88
|
+
_seed_connections(db, ws)
|
|
89
|
+
_seed_prompts(db, ws)
|
|
90
|
+
_seed_flows(db, ws)
|
|
91
|
+
log.info("seeded workspace %s", ws)
|