@atmem/architect 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONSTITUTION.md +144 -0
- package/LICENSE +202 -0
- package/NOTICE +6 -0
- package/README.md +31 -2
- package/agent-skills/discovery/SKILL.md +48 -0
- package/agent-skills/discovery/topics.json +139 -0
- package/agent-skills/generation-capabilities.json +760 -0
- package/agent-skills/service-lifecycle.json +21 -0
- package/agent-skills/specialists/architecture/SKILL.md +15 -0
- package/agent-skills/specialists/aws/SKILL.md +17 -0
- package/agent-skills/specialists/azure/SKILL.md +7 -0
- package/agent-skills/specialists/composition/SKILL.md +17 -0
- package/agent-skills/specialists/devops/SKILL.md +10 -0
- package/agent-skills/specialists/finops/SKILL.md +7 -0
- package/agent-skills/specialists/gcp/SKILL.md +7 -0
- package/agent-skills/specialists/ibm/SKILL.md +7 -0
- package/agent-skills/specialists/manifest.json +13 -0
- package/agent-skills/specialists/pulumi/SKILL.md +7 -0
- package/agent-skills/specialists/security/SKILL.md +7 -0
- package/agent-skills/specialists/terraform/SKILL.md +14 -0
- package/agent-skills/upstream/aws/LICENSE +175 -0
- package/agent-skills/upstream/aws/SKILL.md +125 -0
- package/agent-skills/upstream/azure/LICENSE +21 -0
- package/agent-skills/upstream/azure/SKILL.md +387 -0
- package/agent-skills/upstream/gcp/LICENSE +202 -0
- package/agent-skills/upstream/gcp/SKILL.md +159 -0
- package/agent-skills/upstream/manifest.json +57 -0
- package/agent-skills/upstream/pulumi/LICENSE +201 -0
- package/agent-skills/upstream/pulumi/SKILL.md +501 -0
- package/agent-skills/upstream/terraform/LICENSE +373 -0
- package/agent-skills/upstream/terraform/SKILL.md +316 -0
- package/agent-skills/workflows/workflows.json +601 -0
- package/cli/architect.mjs +3 -0
- package/cli/runtime.mjs +115 -0
- package/dist/assets/html2canvas.esm-QH1iLAAe.js +22 -0
- package/dist/assets/index-BTLHaa3J.css +1 -0
- package/dist/assets/index-CQ2C1gKF.js +21338 -0
- package/dist/assets/index.es-DTyqIdaO.js +18 -0
- package/dist/assets/purify.es-CAi2OJFm.js +3 -0
- package/dist/assets/visual-export-Ox0j5xj5.js +173 -0
- package/dist/favicon.svg +2 -0
- package/dist/fonts/DM-Sans-OFL.txt +93 -0
- package/dist/fonts/Manrope-OFL.txt +93 -0
- package/dist/fonts/NotoSans-Regular.ttf +0 -0
- package/dist/fonts/OFL.txt +94 -0
- package/dist/fonts/dm-sans-latin-wght-normal.woff2 +0 -0
- package/dist/fonts/manrope-latin-wght-normal.woff2 +0 -0
- package/dist/index.html +4 -0
- package/dist/licenses/atmem-APACHE-2.0.txt +202 -0
- package/dist/licenses/aws-architect-LICENSE.txt +17 -0
- package/dist/licenses/aws-mcp-LICENSE.txt +175 -0
- package/dist/licenses/aws-mcp-NOTICE.txt +1 -0
- package/dist/licenses/cloud-emulation-notices.txt +36619 -0
- package/dist/licenses/dependency-notices.txt +6379 -0
- package/dist/licenses/emulation-notices.txt +717 -0
- package/dist/licenses/github-copilot-sdk-LICENSE.txt +21 -0
- package/dist/licenses/memory-dependency-notices.txt +3319 -0
- package/dist/licenses/openarchflow-LICENSE.txt +21 -0
- package/dist/licenses/python-dependency-notices.txt +11951 -0
- package/docs/upstream-lock.json +26 -0
- package/knowledge/engineering-practices.json +536 -0
- package/package.json +30 -4
- package/packaging/uv-release-lock.json +54 -0
- package/public/licenses/atmem-APACHE-2.0.txt +202 -0
- package/public/licenses/aws-architect-LICENSE.txt +17 -0
- package/public/licenses/aws-mcp-LICENSE.txt +175 -0
- package/public/licenses/aws-mcp-NOTICE.txt +1 -0
- package/public/licenses/cloud-emulation-notices.txt +36619 -0
- package/public/licenses/dependency-notices.txt +6379 -0
- package/public/licenses/emulation-notices.txt +717 -0
- package/public/licenses/github-copilot-sdk-LICENSE.txt +21 -0
- package/public/licenses/memory-dependency-notices.txt +3319 -0
- package/public/licenses/openarchflow-LICENSE.txt +21 -0
- package/public/licenses/python-dependency-notices.txt +11951 -0
- package/scripts/terraform-render.mjs +8 -0
- package/server/__init__.py +0 -0
- package/server/abstraction.py +28 -0
- package/server/agent_runtime.py +153 -0
- package/server/app.py +257 -0
- package/server/architect.py +112 -0
- package/server/architecture_activity.py +67 -0
- package/server/attachments.py +101 -0
- package/server/cloud-emulation-requirements.txt +29 -0
- package/server/codex_app_server.py +219 -0
- package/server/codex_engineering_backend.py +266 -0
- package/server/codex_worker_policy.py +193 -0
- package/server/contracts.py +315 -0
- package/server/copilot_worker.py +16 -0
- package/server/dependency_mirror.py +54 -0
- package/server/design_patch.py +43 -0
- package/server/emulation-requirements.txt +8 -0
- package/server/emulation_adapters.py +20 -0
- package/server/emulation_routes.py +98 -0
- package/server/emulation_worker.py +351 -0
- package/server/engineering_artifacts.py +221 -0
- package/server/engineering_assets/application-runtime.json +4372 -0
- package/server/engineering_assets/architecture_work.schema.json +79 -0
- package/server/engineering_assets/materialize_runtime.py +62 -0
- package/server/engineering_assets/prepare_tools.py +96 -0
- package/server/engineering_assets/sql_validation.py +59 -0
- package/server/engineering_contexts.py +120 -0
- package/server/engineering_delivery.py +210 -0
- package/server/engineering_finalization.py +210 -0
- package/server/engineering_handoff.py +172 -0
- package/server/engineering_jobs.py +206 -0
- package/server/engineering_knowledge.py +75 -0
- package/server/engineering_reconciliation.py +159 -0
- package/server/engineering_routes.py +483 -0
- package/server/engineering_sessions.py +273 -0
- package/server/engineering_tools.py +166 -0
- package/server/generation_lint.py +18 -0
- package/server/local_providers.py +185 -0
- package/server/local_validation.py +236 -0
- package/server/memory-requirements.lock +181 -0
- package/server/memory-requirements.txt +6 -0
- package/server/memory_context.py +58 -0
- package/server/memory_routes.py +141 -0
- package/server/memory_service.py +306 -0
- package/server/memory_worker.py +129 -0
- package/server/openai_voice.py +80 -0
- package/server/orca_handoff.py +90 -0
- package/server/packaged_app.py +9 -0
- package/server/pricing.py +190 -0
- package/server/process_control_observation.py +31 -0
- package/server/prompts.py +136 -0
- package/server/public_faq_emulation_worker.py +44 -0
- package/server/requirements.lock +1618 -0
- package/server/requirements.txt +68 -0
- package/server/runtime_dependency_locks.py +27 -0
- package/server/runtime_evidence.py +93 -0
- package/server/settings.py +14 -0
- package/server/skills.py +103 -0
- package/server/storage_emulation_worker.py +160 -0
- package/server/structured_emulation_worker.py +48 -0
- package/server/terraform_routes.py +118 -0
- package/server/upstream/__init__.py +0 -0
- package/server/upstream/agent/__init__.py +1 -0
- package/server/upstream/agent/aws_architect.py +600 -0
- package/server/upstream/agent/config/__init__.py +1 -0
- package/server/upstream/agent/config/agent_config.py +82 -0
- package/server/upstream/agent/config/prompts.py +138 -0
- package/server/upstream/agent/rate_limiter.py +62 -0
- package/server/upstream/utils/__init__.py +1 -0
- package/server/upstream/utils/file_writer.py +43 -0
- package/server/validation_applicability.py +85 -0
- package/server/validation_jobs.py +252 -0
- package/server/validation_workers.py +48 -0
- package/server/voice_routes.py +91 -0
- package/server/voice_worker.py +26 -0
- package/server/windows_snapshot.py +119 -0
- package/specs/028-convergence-evaluation/evidence/20261110-ibm-invoice-native/registry-structured/qualification.json +72 -0
- package/specs/028-convergence-evaluation/evidence/20261110-invoice-runtime/durable-current/receipt.json +61 -0
- package/specs/029-general-purpose-engine/evidence/20261111-runtime-dependencies/sdk/receipt.json +22 -0
- package/src/ArchitectureActivity.jsx +54 -0
- package/src/ArchitectureWorkPanel.jsx +39 -0
- package/src/ArtifactChecks.jsx +49 -0
- package/src/BlockRequirements.jsx +13 -0
- package/src/BrainActivity.jsx +11 -0
- package/src/ChatMessage.jsx +29 -0
- package/src/ChatResizeHandle.jsx +6 -0
- package/src/CodePreview.jsx +8 -0
- package/src/ComponentReview.jsx +31 -0
- package/src/DeliveryViews.jsx +59 -0
- package/src/EmulationPanel.jsx +44 -0
- package/src/EngagementViews.jsx +387 -0
- package/src/EngineeringPanel.jsx +151 -0
- package/src/FileTree.jsx +7 -0
- package/src/FinalChecklist.jsx +15 -0
- package/src/HelpNote.jsx +3 -0
- package/src/ImplementationDelivery.jsx +91 -0
- package/src/JourneyViews.jsx +403 -0
- package/src/LocationChoices.jsx +12 -0
- package/src/MemoryPanel.jsx +58 -0
- package/src/OpenAIVoicePanel.jsx +66 -0
- package/src/OutputsView.jsx +71 -0
- package/src/ProjectChecks.jsx +44 -0
- package/src/TerraformView.jsx +57 -0
- package/src/WorkbenchDialogs.jsx +532 -0
- package/src/activity-presentation.mjs +28 -0
- package/src/ai-qualification-scenarios.mjs +31 -0
- package/src/approval-application-files.mjs +32 -0
- package/src/approval-applications.mjs +82 -0
- package/src/approval-spec-kit.mjs +30 -0
- package/src/architecture-activity.css +28 -0
- package/src/architecture-activity.mjs +63 -0
- package/src/architecture-work.mjs +176 -0
- package/src/artifact-work.mjs +103 -0
- package/src/async-documents.mjs +191 -0
- package/src/atflow.css +1140 -0
- package/src/atforma.css +748 -0
- package/src/atmem-tokens.css +79 -0
- package/src/aws-preflight.mjs +60 -0
- package/src/aws-public-faq.mjs +102 -0
- package/src/aws-validation-scenarios.mjs +10 -0
- package/src/aws-validation.mjs +48 -0
- package/src/azure-plan-mocks.mjs +25 -0
- package/src/azure-structured.mjs +133 -0
- package/src/bedrock-summary.mjs +152 -0
- package/src/bounded-rag.mjs +60 -0
- package/src/brand.css +9 -0
- package/src/canvas-view.mjs +28 -0
- package/src/capability-composition.mjs +44 -0
- package/src/chat-attachments.mjs +13 -0
- package/src/cloud-provider-locks.mjs +9 -0
- package/src/cloud-storage-scenarios.mjs +2 -0
- package/src/component-review.mjs +55 -0
- package/src/composition-spec-kit.mjs +30 -0
- package/src/consultation-context.mjs +15 -0
- package/src/consultation.mjs +52 -0
- package/src/container-contracts.mjs +5 -0
- package/src/container-inspection.mjs +75 -0
- package/src/container-runtime.mjs +30 -0
- package/src/container-security-inspection.mjs +49 -0
- package/src/container-terraform.mjs +109 -0
- package/src/conversation.mjs +18 -0
- package/src/core.mjs +863 -0
- package/src/cross-cloud-storage.mjs +100 -0
- package/src/delivery-capabilities.mjs +25 -0
- package/src/delivery.mjs +58 -0
- package/src/deployment-ownership.mjs +10 -0
- package/src/deployment-region.mjs +11 -0
- package/src/derive.mjs +31 -0
- package/src/design-build-flow.mjs +10 -0
- package/src/diagram-attention.mjs +24 -0
- package/src/discovery.mjs +359 -0
- package/src/document.mjs +170 -0
- package/src/emulation-feedback.mjs +61 -0
- package/src/emulation-guidance.mjs +37 -0
- package/src/engagement.mjs +274 -0
- package/src/engineering-client.mjs +73 -0
- package/src/engineering-defaults.mjs +17 -0
- package/src/engineering.css +31 -0
- package/src/enterprise-application.mjs +76 -0
- package/src/enterprise-aws-host-infrastructure.mjs +62 -0
- package/src/enterprise-aws-host-tests.mjs +15 -0
- package/src/enterprise-aws-infrastructure-tests.mjs +38 -0
- package/src/enterprise-aws-infrastructure.mjs +138 -0
- package/src/enterprise-google-infrastructure.mjs +84 -0
- package/src/enterprise-google-tests.mjs +25 -0
- package/src/estimate.mjs +190 -0
- package/src/existing-references.mjs +18 -0
- package/src/external-identities.mjs +17 -0
- package/src/faq-lambda-build.mjs +28 -0
- package/src/final-package.mjs +34 -0
- package/src/gcp-structured.mjs +104 -0
- package/src/generation-provider.mjs +7 -0
- package/src/generation-quality.mjs +69 -0
- package/src/handoff.mjs +141 -0
- package/src/ibm-registry.mjs +12 -0
- package/src/ibm-structured.mjs +103 -0
- package/src/identifiers.mjs +15 -0
- package/src/implementation-map.mjs +14 -0
- package/src/implementation-outcome.mjs +8 -0
- package/src/incomplete-terraform.mjs +9 -0
- package/src/integrations.ts +137 -0
- package/src/interface-contracts.mjs +30 -0
- package/src/invoice-application.mjs +66 -0
- package/src/invoice-aws-operations.mjs +136 -0
- package/src/invoice-aws.mjs +143 -0
- package/src/invoice-azure-operations.mjs +147 -0
- package/src/invoice-azure.mjs +134 -0
- package/src/invoice-builder.mjs +35 -0
- package/src/invoice-dependencies.mjs +43 -0
- package/src/invoice-gcp-operations.mjs +178 -0
- package/src/invoice-gcp.mjs +104 -0
- package/src/invoice-ibm-operations.mjs +278 -0
- package/src/invoice-ibm.mjs +142 -0
- package/src/invoice-operations.mjs +143 -0
- package/src/invoice-plan.mjs +45 -0
- package/src/invoice-region.mjs +6 -0
- package/src/invoice-spec-kit.mjs +61 -0
- package/src/invoice-state.mjs +7 -0
- package/src/invoice-terraform.mjs +29 -0
- package/src/invoice-tests.mjs +122 -0
- package/src/journey-workspace.css +106 -0
- package/src/journey.mjs +97 -0
- package/src/levels.mjs +145 -0
- package/src/local-agent.mjs +184 -0
- package/src/main.jsx +2481 -0
- package/src/model-policy-preflight.mjs +34 -0
- package/src/openai-voice.mjs +102 -0
- package/src/output-bundle.mjs +13 -0
- package/src/ownership-inspection.mjs +28 -0
- package/src/pack.mjs +201 -0
- package/src/pricing.mjs +85 -0
- package/src/production-state.mjs +8 -0
- package/src/project-copy.mjs +10 -0
- package/src/project-file.mjs +160 -0
- package/src/project-links.mjs +3 -0
- package/src/protected-state.mjs +43 -0
- package/src/public-faq-builder.mjs +19 -0
- package/src/public-faq-clouds.mjs +251 -0
- package/src/public-faq.mjs +122 -0
- package/src/pulumi.mjs +123 -0
- package/src/python-container.mjs +25 -0
- package/src/python-runtime.mjs +50 -0
- package/src/rag-handler.mjs +43 -0
- package/src/rag-web-assets.mjs +52 -0
- package/src/rag-web.mjs +68 -0
- package/src/records.mjs +177 -0
- package/src/resources.mjs +163 -0
- package/src/review.mjs +252 -0
- package/src/runtime/EnterpriseDocument.java +89 -0
- package/src/runtime/approved_http_destination.py +72 -0
- package/src/runtime/aws-lambda-qualification-lock.json +7 -0
- package/src/runtime/aws-python-lock.json +82 -0
- package/src/runtime/aws-web-python-lock.json +887 -0
- package/src/runtime/aws_json_model.py +42 -0
- package/src/runtime/azure-python-lock.json +863 -0
- package/src/runtime/azure-sources.json +8 -0
- package/src/runtime/azure-test-lock.json +23 -0
- package/src/runtime/azure_acceptance.py +192 -0
- package/src/runtime/azure_structured.py +153 -0
- package/src/runtime/bounded_rag.py +126 -0
- package/src/runtime/catalog_admin.py +70 -0
- package/src/runtime/cloud-sql-proxy-lock.json +8 -0
- package/src/runtime/cloud-sql-proxy-security-review.json +30 -0
- package/src/runtime/connector_cli.py +50 -0
- package/src/runtime/connector_sync.py +70 -0
- package/src/runtime/durable-python-lock.json +247 -0
- package/src/runtime/durable_workflow.py +325 -0
- package/src/runtime/enterprise-application-manifest.json +110 -0
- package/src/runtime/enterprise-application-sources.json +266 -0
- package/src/runtime/enterprise-auth-python-lock.json +592 -0
- package/src/runtime/enterprise-aws-host-bootstrap-source.json +1 -0
- package/src/runtime/enterprise-aws-host-probe-source.json +1 -0
- package/src/runtime/enterprise-aws-task-template.json +235 -0
- package/src/runtime/enterprise-document-lock.json +18 -0
- package/src/runtime/enterprise-document.Dockerfile +15 -0
- package/src/runtime/enterprise-runtime-aws-python-lock.json +1115 -0
- package/src/runtime/enterprise-runtime-azure-python-lock.json +1106 -0
- package/src/runtime/enterprise-runtime-gcp-python-lock.json +1060 -0
- package/src/runtime/enterprise-runtime-ibm-python-lock.json +1096 -0
- package/src/runtime/enterprise-runtime-python-lock.json +1058 -0
- package/src/runtime/enterprise-runtime.Dockerfile +15 -0
- package/src/runtime/enterprise-web-app.js +1 -0
- package/src/runtime/enterprise-web-entry.js +105 -0
- package/src/runtime/enterprise-web-lock.json +29 -0
- package/src/runtime/enterprise-web-notices.txt +229 -0
- package/src/runtime/enterprise-web.css +4 -0
- package/src/runtime/enterprise-web.html +8 -0
- package/src/runtime/enterprise_audit.py +91 -0
- package/src/runtime/enterprise_audit_schema.sql +25 -0
- package/src/runtime/enterprise_auth_schema.sql +67 -0
- package/src/runtime/enterprise_auth_store.py +241 -0
- package/src/runtime/enterprise_aws_host_bootstrap.py +120 -0
- package/src/runtime/enterprise_aws_host_probe.py +105 -0
- package/src/runtime/enterprise_aws_hosts.py +136 -0
- package/src/runtime/enterprise_aws_jobs.py +300 -0
- package/src/runtime/enterprise_aws_objects.py +93 -0
- package/src/runtime/enterprise_aws_transfer.py +83 -0
- package/src/runtime/enterprise_azure_batch_api.py +128 -0
- package/src/runtime/enterprise_azure_host.py +599 -0
- package/src/runtime/enterprise_azure_jobs.py +294 -0
- package/src/runtime/enterprise_azure_objects.py +234 -0
- package/src/runtime/enterprise_azure_pool.py +161 -0
- package/src/runtime/enterprise_azure_transfer.py +122 -0
- package/src/runtime/enterprise_configuration.py +136 -0
- package/src/runtime/enterprise_document.py +116 -0
- package/src/runtime/enterprise_document_cli.py +32 -0
- package/src/runtime/enterprise_document_contract.py +54 -0
- package/src/runtime/enterprise_document_job.py +109 -0
- package/src/runtime/enterprise_document_jobs.py +122 -0
- package/src/runtime/enterprise_document_jobs_schema.sql +23 -0
- package/src/runtime/enterprise_extraction_cache.py +186 -0
- package/src/runtime/enterprise_extraction_schema.sql +17 -0
- package/src/runtime/enterprise_google_jobs.py +275 -0
- package/src/runtime/enterprise_google_transfer.py +85 -0
- package/src/runtime/enterprise_http.py +212 -0
- package/src/runtime/enterprise_identity.py +52 -0
- package/src/runtime/enterprise_knowledge.py +152 -0
- package/src/runtime/enterprise_models.py +94 -0
- package/src/runtime/enterprise_native.py +181 -0
- package/src/runtime/enterprise_oauth.py +132 -0
- package/src/runtime/enterprise_operator.py +160 -0
- package/src/runtime/enterprise_parser_service.py +136 -0
- package/src/runtime/enterprise_parser_transport.py +68 -0
- package/src/runtime/enterprise_queries.py +255 -0
- package/src/runtime/enterprise_queries_schema.sql +27 -0
- package/src/runtime/enterprise_query_service.py +111 -0
- package/src/runtime/enterprise_secrets.py +110 -0
- package/src/runtime/enterprise_sessions.py +95 -0
- package/src/runtime/enterprise_sources.py +260 -0
- package/src/runtime/enterprise_web.py +39 -0
- package/src/runtime/enterprise_worker.py +68 -0
- package/src/runtime/export_contract_acceptance.py +18 -0
- package/src/runtime/faq-output-contract.json +40 -0
- package/src/runtime/faq-web-app.js +41 -0
- package/src/runtime/faq-web.css +1 -0
- package/src/runtime/faq-web.html +6 -0
- package/src/runtime/gcp-sources.json +9 -0
- package/src/runtime/gcp_acceptance.py +110 -0
- package/src/runtime/gcp_structured.py +150 -0
- package/src/runtime/http_acceptance.py +39 -0
- package/src/runtime/iap-web-app.js +36 -0
- package/src/runtime/iap-web-source.json +1 -0
- package/src/runtime/ibm-python-lock.json +856 -0
- package/src/runtime/ibm-sources.json +9 -0
- package/src/runtime/ibm_acceptance.py +133 -0
- package/src/runtime/ibm_structured.py +113 -0
- package/src/runtime/invoice-azapi-provider-lock.json +7 -0
- package/src/runtime/invoice-ibm-provider-lock.json +7 -0
- package/src/runtime/invoice-parser-lock.json +1199 -0
- package/src/runtime/invoice-parser-python-lock.json +56 -0
- package/src/runtime/invoice-parser.Dockerfile +190 -0
- package/src/runtime/invoice-sources.json +58 -0
- package/src/runtime/invoice-test-sources.json +24 -0
- package/src/runtime/invoice-web.css +2 -0
- package/src/runtime/invoice-web.html +12 -0
- package/src/runtime/invoice-web.js +112 -0
- package/src/runtime/invoice_configuration.py +17 -0
- package/src/runtime/invoice_document.py +95 -0
- package/src/runtime/invoice_extraction.py +96 -0
- package/src/runtime/invoice_http.py +129 -0
- package/src/runtime/invoice_identity.py +5 -0
- package/src/runtime/invoice_maintenance.py +40 -0
- package/src/runtime/invoice_native.py +77 -0
- package/src/runtime/invoice_object_store.py +153 -0
- package/src/runtime/invoice_operations.py +108 -0
- package/src/runtime/invoice_operator.py +79 -0
- package/src/runtime/invoice_operator_core.py +39 -0
- package/src/runtime/invoice_operator_job.py +147 -0
- package/src/runtime/invoice_parser_cli.py +17 -0
- package/src/runtime/invoice_parser_identity.py +39 -0
- package/src/runtime/invoice_parser_service.py +89 -0
- package/src/runtime/invoice_parser_transport.py +89 -0
- package/src/runtime/invoice_processing.py +24 -0
- package/src/runtime/invoice_retention.py +16 -0
- package/src/runtime/invoice_runtime_secrets.py +43 -0
- package/src/runtime/invoice_stage.py +80 -0
- package/src/runtime/invoice_web.py +39 -0
- package/src/runtime/invoice_worker.py +50 -0
- package/src/runtime/lambda_faq.py +5 -0
- package/src/runtime/parser-requirements.lock +4 -0
- package/src/runtime/policy_review.py +18 -0
- package/src/runtime/postgres-qualification-lock.json +21 -0
- package/src/runtime/public-faq-sources.json +22 -0
- package/src/runtime/public_catalog_admin.py +122 -0
- package/src/runtime/public_catalog_store.py +125 -0
- package/src/runtime/public_faq.py +144 -0
- package/src/runtime/public_faq_app.py +49 -0
- package/src/runtime/python-container-lock.json +18 -0
- package/src/runtime/rag-sources.json +10 -0
- package/src/runtime/rag_acceptance.py +60 -0
- package/src/runtime/rag_aws_adapter.py +95 -0
- package/src/runtime/rds-ca-source.json +9 -0
- package/src/runtime/rds-global-ca.pem +2888 -0
- package/src/runtime/state-contract-check-source.json +4 -0
- package/src/runtime/state_contract_check.py +338 -0
- package/src/runtime/structured-source.json +1 -0
- package/src/runtime/structured-web-app.js +71 -0
- package/src/runtime/structured-web-source.json +1 -0
- package/src/runtime/structured_http.py +105 -0
- package/src/runtime/structured_output.py +48 -0
- package/src/runtime/web-python-lock.json +802 -0
- package/src/runtime/web_user_admin.py +44 -0
- package/src/runtime/workflow_application.py +62 -0
- package/src/runtime/workflow_bindings.py +128 -0
- package/src/runtime/workflow_configuration.py +40 -0
- package/src/runtime/workflow_connection.py +105 -0
- package/src/runtime/workflow_contract.py +54 -0
- package/src/runtime/workflow_database.py +94 -0
- package/src/runtime/workflow_errors.py +6 -0
- package/src/runtime/workflow_http.py +178 -0
- package/src/runtime/workflow_identity.py +69 -0
- package/src/runtime/workflow_payload.py +118 -0
- package/src/runtime/workflow_process_stage.py +88 -0
- package/src/runtime/workflow_profile.py +91 -0
- package/src/runtime/workflow_review.py +106 -0
- package/src/runtime/workflow_role_bootstrap.py +104 -0
- package/src/runtime/workflow_schema.sql +72 -0
- package/src/runtime/workflow_worker.py +142 -0
- package/src/runtime-settings.mjs +15 -0
- package/src/s3-access.mjs +14 -0
- package/src/source-contracts.mjs +17 -0
- package/src/spec-kit.mjs +186 -0
- package/src/state-custody.mjs +32 -0
- package/src/state-inspection.mjs +45 -0
- package/src/state-spec-kit.mjs +13 -0
- package/src/storage-tests.mjs +25 -0
- package/src/structured-api.mjs +133 -0
- package/src/structured-contract.mjs +19 -0
- package/src/structured-operation-policy.mjs +2 -0
- package/src/structured-web.mjs +17 -0
- package/src/style.css +1 -0
- package/src/system-description.mjs +26 -0
- package/src/terraform-admission.mjs +66 -0
- package/src/terraform-composition.mjs +83 -0
- package/src/terraform-expressions.mjs +46 -0
- package/src/terraform-validation-coverage.mjs +11 -0
- package/src/terraform.mjs +128 -0
- package/src/text-statistics.mjs +51 -0
- package/src/upstream/openarchflow/format-payload.ts +26 -0
- package/src/upstream/openarchflow/import/mermaid.ts +205 -0
- package/src/upstream/openarchflow/import/sql-ddl.ts +109 -0
- package/src/upstream/openarchflow/layout.ts +54 -0
- package/src/upstream/openarchflow/providers/aws.ts +196 -0
- package/src/upstream/openarchflow/providers/azure.ts +126 -0
- package/src/upstream/openarchflow/providers/cloudnative.ts +71 -0
- package/src/upstream/openarchflow/providers/generic.ts +227 -0
- package/src/upstream/openarchflow/providers/integration.ts +22 -0
- package/src/upstream/openarchflow/providers/types.ts +2 -0
- package/src/upstream/openarchflow/templates.ts +937 -0
- package/src/upstream-catalog.mjs +10 -0
- package/src/useChatScroll.jsx +37 -0
- package/src/useEmulation.jsx +36 -0
- package/src/useEngineeringStatus.mjs +17 -0
- package/src/validation-receipt.mjs +10 -0
- package/src/visual-export.mjs +92 -0
- package/src/voice-conversation.mjs +117 -0
- package/src/work-intake.mjs +24 -0
- package/src/workflow-runtime-inventory.mjs +3 -0
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
# AtForma modification: package-relative file writer import. MIT-0 upstream preserved.
|
|
2
|
+
import logging
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
import uuid
|
|
6
|
+
import time
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Dict, Any, List, Optional
|
|
9
|
+
from io import StringIO
|
|
10
|
+
from contextlib import contextmanager
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from strands import Agent
|
|
13
|
+
from strands.models import BedrockModel
|
|
14
|
+
from strands.session.file_session_manager import FileSessionManager
|
|
15
|
+
from strands.tools.mcp import MCPClient
|
|
16
|
+
from .config.prompts import SYSTEM_INSTRUCTIONS
|
|
17
|
+
from .config.agent_config import BEDROCK_MODEL_ID, RATE_LIMIT_MAX_REQUESTS, RATE_LIMIT_TIME_WINDOW, MAX_TOKENS, THINKING_CONFIG, ANTHROPIC_BETA
|
|
18
|
+
from ..utils.file_writer import write_file
|
|
19
|
+
from .rate_limiter import RateLimiter
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
logger = logging.getLogger(__name__) #module level logger
|
|
24
|
+
|
|
25
|
+
# Configure Strands logging
|
|
26
|
+
logging.getLogger("strands.tools.registry").setLevel(logging.ERROR) # VD : log tool registration
|
|
27
|
+
logging.getLogger("strands.models").setLevel(logging.ERROR) #VD : log model invocation
|
|
28
|
+
logging.getLogger("strands.event_loop").setLevel(logging.ERROR) # VD : log event loop , how the agent is thinking
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class MCPServerConfig:
|
|
32
|
+
"""Configuration for MCP servers"""
|
|
33
|
+
name: str
|
|
34
|
+
client_type: str
|
|
35
|
+
url: Optional[str] = None
|
|
36
|
+
command: Optional[str] = None
|
|
37
|
+
args: Optional[List[str]] = None
|
|
38
|
+
env: Optional[Dict[str, str]] = None
|
|
39
|
+
remote: bool = False
|
|
40
|
+
|
|
41
|
+
class LogCapture:
|
|
42
|
+
"""Simplified log capture utility with streaming support"""
|
|
43
|
+
def __init__(self, stream_callback=None):
|
|
44
|
+
self.log_stream = StringIO()
|
|
45
|
+
self.stream_callback = stream_callback
|
|
46
|
+
self.handler = logging.StreamHandler(self.log_stream)
|
|
47
|
+
self.handler.setLevel(logging.DEBUG)
|
|
48
|
+
|
|
49
|
+
# Custom formatter to preserve full message
|
|
50
|
+
class FullMessageFormatter(logging.Formatter):
|
|
51
|
+
def format(self, record):
|
|
52
|
+
msg = str(record.getMessage())
|
|
53
|
+
return f"{self.formatTime(record)} - {record.levelname}: {msg}"
|
|
54
|
+
|
|
55
|
+
formatter = FullMessageFormatter()
|
|
56
|
+
self.handler.setFormatter(formatter)
|
|
57
|
+
|
|
58
|
+
# Override emit to stream logs in real-time
|
|
59
|
+
original_emit = self.handler.emit
|
|
60
|
+
def streaming_emit(record):
|
|
61
|
+
original_emit(record)
|
|
62
|
+
if self.stream_callback:
|
|
63
|
+
self.stream_callback(self.handler.format(record))
|
|
64
|
+
self.handler.emit = streaming_emit
|
|
65
|
+
|
|
66
|
+
@contextmanager
|
|
67
|
+
def capture(self):
|
|
68
|
+
"""Context manager for filtered stdout/stderr capture"""
|
|
69
|
+
# Capture stdout/stderr
|
|
70
|
+
original_stdout = sys.stdout
|
|
71
|
+
original_stderr = sys.stderr
|
|
72
|
+
|
|
73
|
+
class FilteredTeeStream:
|
|
74
|
+
def __init__(self, original, capture_stream, filter_func=None):
|
|
75
|
+
self.original = original
|
|
76
|
+
self.capture_stream = capture_stream
|
|
77
|
+
self.filter_func = filter_func
|
|
78
|
+
|
|
79
|
+
def write(self, text):
|
|
80
|
+
self.original.write(text)
|
|
81
|
+
if self.filter_func is None or self.filter_func(text):
|
|
82
|
+
self.capture_stream.write(text)
|
|
83
|
+
|
|
84
|
+
def flush(self):
|
|
85
|
+
self.original.flush()
|
|
86
|
+
self.capture_stream.flush()
|
|
87
|
+
|
|
88
|
+
# Filter function for stdout - only capture lines starting with "Tool"
|
|
89
|
+
def stdout_filter(text):
|
|
90
|
+
return text.strip().startswith("Tool")
|
|
91
|
+
|
|
92
|
+
sys.stdout = FilteredTeeStream(original_stdout, self.log_stream, stdout_filter)
|
|
93
|
+
sys.stderr = FilteredTeeStream(original_stderr, self.log_stream) # Capture all stderr
|
|
94
|
+
|
|
95
|
+
self.log_stream.seek(0)
|
|
96
|
+
self.log_stream.truncate(0)
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
yield self
|
|
100
|
+
finally:
|
|
101
|
+
sys.stdout = original_stdout
|
|
102
|
+
sys.stderr = original_stderr
|
|
103
|
+
|
|
104
|
+
def get_logs(self) -> str:
|
|
105
|
+
return self.log_stream.getvalue()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class MCPClientManager:
|
|
110
|
+
"""Manages MCP client connections and tools"""
|
|
111
|
+
|
|
112
|
+
def __init__(self):
|
|
113
|
+
self.clients = {}
|
|
114
|
+
self.config = self._get_default_config()
|
|
115
|
+
self.server_processes = []
|
|
116
|
+
self.clients_activated = False
|
|
117
|
+
# Cache connection status and tools during initialization for UI display
|
|
118
|
+
self.connection_status = {} # server_name -> status string
|
|
119
|
+
self.server_tools = {} # server_name -> list of tools
|
|
120
|
+
|
|
121
|
+
def _get_default_config(self) -> List[MCPServerConfig]:
|
|
122
|
+
"""Default MCP server configurations"""
|
|
123
|
+
return [
|
|
124
|
+
MCPServerConfig(
|
|
125
|
+
name="AWS Knowledge",
|
|
126
|
+
client_type="http",
|
|
127
|
+
url="https://knowledge-mcp.global.api.aws",
|
|
128
|
+
remote=True
|
|
129
|
+
),
|
|
130
|
+
MCPServerConfig(
|
|
131
|
+
name="AWS Pricing",
|
|
132
|
+
client_type="stdio",
|
|
133
|
+
command="uvx",
|
|
134
|
+
args=["awslabs.aws-pricing-mcp-server@latest"],
|
|
135
|
+
remote=True
|
|
136
|
+
),
|
|
137
|
+
MCPServerConfig(
|
|
138
|
+
name="AWS Diagram",
|
|
139
|
+
client_type="stdio",
|
|
140
|
+
command="uvx",
|
|
141
|
+
args=["awslabs.aws-diagram-mcp-server@latest"],
|
|
142
|
+
env={"FASTMCP_LOG_LEVEL": "ERROR", "AWS_REGION": "us-east-1"},
|
|
143
|
+
remote=True
|
|
144
|
+
),
|
|
145
|
+
# MCPServerConfig(
|
|
146
|
+
# name="Local Diagram Samples",
|
|
147
|
+
# client_type="stdio",
|
|
148
|
+
# command="python",
|
|
149
|
+
# args=["local_mcp_servers/sample_diagrams/server.py"],
|
|
150
|
+
# remote=False
|
|
151
|
+
# ),
|
|
152
|
+
# MCPServerConfig(
|
|
153
|
+
# name="Local WAR Samples",
|
|
154
|
+
# client_type="stdio",
|
|
155
|
+
# command="python",
|
|
156
|
+
# args=["local_mcp_servers/war_assessment/server.py"],
|
|
157
|
+
# remote=False
|
|
158
|
+
# )
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
def initialize_clients(self) -> Dict[str, Any]:
|
|
162
|
+
"""Initialize all MCP clients"""
|
|
163
|
+
from mcp.client.streamable_http import streamablehttp_client
|
|
164
|
+
from mcp import stdio_client, StdioServerParameters
|
|
165
|
+
import subprocess
|
|
166
|
+
import time
|
|
167
|
+
|
|
168
|
+
self._start_local_servers()
|
|
169
|
+
|
|
170
|
+
for config in self.config:
|
|
171
|
+
try:
|
|
172
|
+
if config.client_type == "http":
|
|
173
|
+
client = MCPClient(lambda url=config.url: streamablehttp_client(url))
|
|
174
|
+
elif config.client_type == "stdio":
|
|
175
|
+
client = MCPClient(lambda cfg=config: stdio_client(
|
|
176
|
+
StdioServerParameters(
|
|
177
|
+
command=cfg.command,
|
|
178
|
+
args=cfg.args,
|
|
179
|
+
env=cfg.env or {}
|
|
180
|
+
)
|
|
181
|
+
))
|
|
182
|
+
else:
|
|
183
|
+
logger.error(f"Unknown client type: {config.client_type}")
|
|
184
|
+
continue
|
|
185
|
+
|
|
186
|
+
if self._validate_connectivity(client, config.name):
|
|
187
|
+
self.clients[config.name] = client
|
|
188
|
+
else:
|
|
189
|
+
# Status already cached in _validate_connectivity
|
|
190
|
+
pass
|
|
191
|
+
|
|
192
|
+
except Exception as e:
|
|
193
|
+
# Cache initialization failure status
|
|
194
|
+
self.connection_status[config.name] = "🔴 Disconnected"
|
|
195
|
+
self.server_tools[config.name] = []
|
|
196
|
+
logger.error(f"{config.name} MCP client failed: {e}")
|
|
197
|
+
|
|
198
|
+
logger.info(f"MCP Status: {len(self.clients)}/{len(self.config)} servers connected")
|
|
199
|
+
|
|
200
|
+
# Log detailed connection status for each server
|
|
201
|
+
for config in self.config:
|
|
202
|
+
if config.name in self.clients:
|
|
203
|
+
logger.info(f"✅ MCP Server '{config.name}': Connected successfully")
|
|
204
|
+
else:
|
|
205
|
+
logger.error(f"❌ MCP Server '{config.name}': Failed to connect")
|
|
206
|
+
|
|
207
|
+
return self.clients
|
|
208
|
+
|
|
209
|
+
def _start_local_servers(self):
|
|
210
|
+
"""Start local MCP servers as background processes"""
|
|
211
|
+
import subprocess
|
|
212
|
+
import time
|
|
213
|
+
|
|
214
|
+
self.server_processes = []
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def _validate_connectivity(self, client, name: str) -> bool:
|
|
218
|
+
"""Validate MCP client connectivity and cache status + tools for UI"""
|
|
219
|
+
try:
|
|
220
|
+
with client:
|
|
221
|
+
tools = client.list_tools_sync()
|
|
222
|
+
# Cache successful connection status and tools
|
|
223
|
+
self.connection_status[name] = "🟢 Connected"
|
|
224
|
+
self.server_tools[name] = tools
|
|
225
|
+
logger.info(f"{name} server: Connected")
|
|
226
|
+
return True
|
|
227
|
+
except Exception as e:
|
|
228
|
+
# Cache failed connection status
|
|
229
|
+
self.connection_status[name] = "🟡 Error"
|
|
230
|
+
self.server_tools[name] = []
|
|
231
|
+
logger.error(f"{name} server: Connection failed - {e}")
|
|
232
|
+
return False
|
|
233
|
+
|
|
234
|
+
def load_tools(self) -> List[Any]:
|
|
235
|
+
"""Load tools from all connected MCP clients"""
|
|
236
|
+
tools = []
|
|
237
|
+
logger.info(f"Starting tool loading from {len(self.clients)} connected clients...")
|
|
238
|
+
|
|
239
|
+
for name, client in self.clients.items():
|
|
240
|
+
try:
|
|
241
|
+
logger.info(f"Loading tools from {name} server...")
|
|
242
|
+
logger.info(f"Client type: {type(client)}")
|
|
243
|
+
|
|
244
|
+
with client:
|
|
245
|
+
client_tools = client.list_tools_sync()
|
|
246
|
+
logger.info(f"Raw tools from {name}: {len(client_tools)} tools")
|
|
247
|
+
|
|
248
|
+
tools.extend(client_tools)
|
|
249
|
+
logger.info(f"✅ {name} server: {len(client_tools)} tools loaded")
|
|
250
|
+
except AttributeError as e:
|
|
251
|
+
logger.error(f"❌ {name} server: Method not found - {e}")
|
|
252
|
+
except Exception as e:
|
|
253
|
+
logger.error(f"❌ {name} server tools failed: {e}")
|
|
254
|
+
|
|
255
|
+
logger.info(f"Tools Status: {len(tools)} total tools loaded")
|
|
256
|
+
return tools
|
|
257
|
+
|
|
258
|
+
@contextmanager
|
|
259
|
+
def active_clients(self):
|
|
260
|
+
"""Context manager for active MCP clients"""
|
|
261
|
+
if not self.clients_activated:
|
|
262
|
+
entered_clients = []
|
|
263
|
+
try:
|
|
264
|
+
for name, client in self.clients.items():
|
|
265
|
+
try:
|
|
266
|
+
client.__enter__()
|
|
267
|
+
entered_clients.append(client)
|
|
268
|
+
logger.info(f"Activated MCP client: {name}")
|
|
269
|
+
except Exception as e:
|
|
270
|
+
logger.error(f"Failed to activate {name} client: {e}")
|
|
271
|
+
|
|
272
|
+
self.clients_activated = True
|
|
273
|
+
yield self.clients
|
|
274
|
+
|
|
275
|
+
except Exception:
|
|
276
|
+
for client in entered_clients:
|
|
277
|
+
try:
|
|
278
|
+
client.__exit__(None, None, None)
|
|
279
|
+
except Exception as e:
|
|
280
|
+
logger.error(f"Error deactivating client: {e}")
|
|
281
|
+
self.clients_activated = False
|
|
282
|
+
raise
|
|
283
|
+
else:
|
|
284
|
+
yield self.clients
|
|
285
|
+
|
|
286
|
+
def cleanup_servers(self):
|
|
287
|
+
"""Cleanup local server processes"""
|
|
288
|
+
for process in self.server_processes:
|
|
289
|
+
try:
|
|
290
|
+
process.terminate()
|
|
291
|
+
process.wait(timeout=5)
|
|
292
|
+
except:
|
|
293
|
+
try:
|
|
294
|
+
process.kill()
|
|
295
|
+
except:
|
|
296
|
+
pass
|
|
297
|
+
|
|
298
|
+
class SystemPromptLoader:
|
|
299
|
+
"""Handles system prompt loading and configuration with Bedrock caching"""
|
|
300
|
+
|
|
301
|
+
@staticmethod
|
|
302
|
+
def load_prompt() -> Dict[str, Any]:
|
|
303
|
+
"""Load system prompt with cache configuration"""
|
|
304
|
+
try:
|
|
305
|
+
output_path = Path.cwd() / "generated-diagrams"
|
|
306
|
+
prompt = SYSTEM_INSTRUCTIONS + f"\n\nIMPORTANT: All generated files must be saved to: {output_path}"
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
"system_prompt": prompt,
|
|
310
|
+
"cache_config": {
|
|
311
|
+
"cache_control": {"type": "ephemeral"},
|
|
312
|
+
"cache_ttl": 3600
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
except Exception as e:
|
|
317
|
+
logger.error(f"Error loading context: {e}")
|
|
318
|
+
output_path = Path.cwd() / "generated-diagrams"
|
|
319
|
+
return {
|
|
320
|
+
"system_prompt": f"You are an AWS architect assistant. Save all files to: {output_path}",
|
|
321
|
+
"cache_config": {"cache_control": {"type": "ephemeral"}}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
class AWSArchitectAgent:
|
|
325
|
+
"""AWS Solution Architecture Agent using composition with Strands Agent
|
|
326
|
+
|
|
327
|
+
Key Changes Made:
|
|
328
|
+
- Removed inheritance - AWSArchitectAgent no longer extends Agent
|
|
329
|
+
- Added composition - Uses self.agent = Agent(...) with MCP tools
|
|
330
|
+
- Simplified initialization - Tools passed directly to Agent constructor
|
|
331
|
+
- Removed complex tool wrapping - GuidelineEnforcer class eliminated
|
|
332
|
+
- Cleaner process_message - Delegates to self.agent(message)
|
|
333
|
+
|
|
334
|
+
Benefits:
|
|
335
|
+
- Simpler architecture - No complex inheritance or tool registration
|
|
336
|
+
- Direct MCP integration - Tools work natively with Strands Agent
|
|
337
|
+
- Reduced complexity - Eliminated 150+ lines of tool wrapping code
|
|
338
|
+
- Better maintainability - Clear separation of concerns
|
|
339
|
+
"""
|
|
340
|
+
|
|
341
|
+
def __init__(self):
|
|
342
|
+
self.mcp_manager = MCPClientManager()
|
|
343
|
+
self.agent = None # Strands Agent instance (composition)
|
|
344
|
+
self.mcp_tools = [] # Store loaded MCP tools
|
|
345
|
+
self.initialized = False
|
|
346
|
+
self.session_id = None # Expose session ID
|
|
347
|
+
# Rate limiter for LLM API calls - prevents exceeding service limits
|
|
348
|
+
self.rate_limiter = RateLimiter(
|
|
349
|
+
max_requests=RATE_LIMIT_MAX_REQUESTS,
|
|
350
|
+
time_window=RATE_LIMIT_TIME_WINDOW
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
def initialize(self) -> None:
|
|
354
|
+
"""Initialize the agent with MCP tools"""
|
|
355
|
+
try:
|
|
356
|
+
# Initialize MCP clients
|
|
357
|
+
clients = self.mcp_manager.initialize_clients()
|
|
358
|
+
if not clients:
|
|
359
|
+
raise RuntimeError("Failed to initialize any MCP clients")
|
|
360
|
+
|
|
361
|
+
# Load MCP tools directly from servers
|
|
362
|
+
mcp_tools = self.mcp_manager.load_tools()
|
|
363
|
+
|
|
364
|
+
# Add native file writing tool for deterministic output handling
|
|
365
|
+
# This ensures files can be saved regardless of MCP server status
|
|
366
|
+
native_tools = [write_file]
|
|
367
|
+
all_tools = mcp_tools + native_tools
|
|
368
|
+
|
|
369
|
+
if not all_tools:
|
|
370
|
+
raise RuntimeError("No tools available")
|
|
371
|
+
|
|
372
|
+
logger.info(f"Loaded {len(mcp_tools)} MCP tools + {len(native_tools)} native tools")
|
|
373
|
+
|
|
374
|
+
# Load system prompt
|
|
375
|
+
prompt_data = SystemPromptLoader.load_prompt()
|
|
376
|
+
|
|
377
|
+
# Create session manager with random session ID
|
|
378
|
+
# sessions_dir = Path(__file__).parent / "sessions"
|
|
379
|
+
# sessions_dir.mkdir(exist_ok=True)
|
|
380
|
+
# self.session_id = str(uuid.uuid4())
|
|
381
|
+
# session_manager = FileSessionManager(
|
|
382
|
+
# session_id=self.session_id,
|
|
383
|
+
# storage_dir=str(sessions_dir)
|
|
384
|
+
# )
|
|
385
|
+
|
|
386
|
+
# Create Bedrock model instance with max_tokens configuration
|
|
387
|
+
bedrock_model = BedrockModel(
|
|
388
|
+
model_id=BEDROCK_MODEL_ID,
|
|
389
|
+
max_tokens=MAX_TOKENS,
|
|
390
|
+
additional_request_fields={"thinking": THINKING_CONFIG,
|
|
391
|
+
"anthropic_beta":ANTHROPIC_BETA
|
|
392
|
+
}
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
# Create Strands Agent with configured Bedrock model
|
|
396
|
+
self.agent = Agent(
|
|
397
|
+
name="aws-architect",
|
|
398
|
+
system_prompt=prompt_data["system_prompt"],
|
|
399
|
+
model=bedrock_model,
|
|
400
|
+
tools=all_tools,
|
|
401
|
+
trace_attributes={
|
|
402
|
+
# "session.id": self.session_id,
|
|
403
|
+
}
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
self.initialized = True
|
|
407
|
+
logger.info("Agent initialized successfully with MCP tools")
|
|
408
|
+
|
|
409
|
+
except Exception as e:
|
|
410
|
+
logger.error(f"Failed to initialize agent: {e}")
|
|
411
|
+
raise
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def process_message(self, message: str, log_callback=None) -> Dict[str, Any]:
|
|
417
|
+
"""Process user message and return response with logs
|
|
418
|
+
|
|
419
|
+
Uses composition pattern - delegates to self.agent(message)
|
|
420
|
+
"""
|
|
421
|
+
if not self.initialized or not self.agent:
|
|
422
|
+
return {"error": "Agent not initialized", "logs": "", "phase": "Error"}
|
|
423
|
+
|
|
424
|
+
if not message or not message.strip():
|
|
425
|
+
return {"error": "Empty message provided", "logs": "", "phase": "Error"}
|
|
426
|
+
|
|
427
|
+
with LogCapture(stream_callback=log_callback).capture() as log_capture:
|
|
428
|
+
try:
|
|
429
|
+
logger.info(f"Processing user request: {message[:100]}...")
|
|
430
|
+
|
|
431
|
+
# Use MCP client context manager for active connections
|
|
432
|
+
with self.mcp_manager.active_clients():
|
|
433
|
+
# Delegate to Strands Agent with retry logic for Bedrock throttling
|
|
434
|
+
result = self._call_agent_with_retry(message.strip())
|
|
435
|
+
|
|
436
|
+
phase = self._detect_current_phase(result.message, message)
|
|
437
|
+
logger.info(f"Completed processing - Phase: {phase}")
|
|
438
|
+
|
|
439
|
+
return {"result": result.message, "logs": log_capture.get_logs(), "phase": phase}
|
|
440
|
+
|
|
441
|
+
except Exception as e:
|
|
442
|
+
logger.error(f"Agent processing failed: {e}")
|
|
443
|
+
return {
|
|
444
|
+
"error": f"Failed to process message: {str(e)}",
|
|
445
|
+
"logs": log_capture.get_logs(),
|
|
446
|
+
"phase": "Error"
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
def _call_agent_with_retry(self, message: str, max_retries: int = 3):
|
|
450
|
+
"""
|
|
451
|
+
Call agent with rate limiting and exponential backoff retry for Bedrock throttling
|
|
452
|
+
|
|
453
|
+
Implements two-layer protection:
|
|
454
|
+
1. Proactive rate limiting to prevent exceeding 5 requests/minute
|
|
455
|
+
2. Reactive retry with exponential backoff for any throttling errors
|
|
456
|
+
|
|
457
|
+
Args:
|
|
458
|
+
message: User message to process
|
|
459
|
+
max_retries: Maximum number of retry attempts (default: 3)
|
|
460
|
+
|
|
461
|
+
Returns:
|
|
462
|
+
Agent response result
|
|
463
|
+
|
|
464
|
+
Raises:
|
|
465
|
+
Exception: Re-raises non-throttling exceptions or after max retries
|
|
466
|
+
"""
|
|
467
|
+
for attempt in range(max_retries):
|
|
468
|
+
try:
|
|
469
|
+
# Proactive rate limiting - wait if needed to stay under 5/min limit
|
|
470
|
+
self.rate_limiter.wait_if_needed()
|
|
471
|
+
|
|
472
|
+
# Make LLM API call through Strands Agent
|
|
473
|
+
return self.agent(message)
|
|
474
|
+
except Exception as e:
|
|
475
|
+
# Reactive handling - Check for Bedrock throttling errors
|
|
476
|
+
if "throttlingException" in str(e) or "Too many requests" in str(e):
|
|
477
|
+
if attempt < max_retries - 1:
|
|
478
|
+
# Exponential backoff: 2, 4, 8 seconds
|
|
479
|
+
wait_time = (2 ** attempt) * 2
|
|
480
|
+
logger.warning(f"Bedrock throttling detected, retrying in {wait_time}s (attempt {attempt + 1}/{max_retries})")
|
|
481
|
+
time.sleep(wait_time)
|
|
482
|
+
continue
|
|
483
|
+
# Re-raise non-throttling exceptions or after max retries
|
|
484
|
+
raise e
|
|
485
|
+
|
|
486
|
+
def get_tool_info(self) -> List[Dict[str, str]]:
|
|
487
|
+
"""Get tool information for UI display using cached data from initialization"""
|
|
488
|
+
if not self.initialized:
|
|
489
|
+
return []
|
|
490
|
+
|
|
491
|
+
tool_info = []
|
|
492
|
+
|
|
493
|
+
# Use cached connection status and tools from initialization
|
|
494
|
+
for config in self.mcp_manager.config:
|
|
495
|
+
status = self.mcp_manager.connection_status.get(config.name, "🔴")
|
|
496
|
+
# Extract only the emoji from status
|
|
497
|
+
if "🟢" in status:
|
|
498
|
+
status = "🟢"
|
|
499
|
+
elif "🔴" in status:
|
|
500
|
+
status = "🔴"
|
|
501
|
+
tools = self.mcp_manager.server_tools.get(config.name, [])
|
|
502
|
+
|
|
503
|
+
if tools:
|
|
504
|
+
# Add entry for each tool
|
|
505
|
+
for tool in tools:
|
|
506
|
+
tool_info.append({
|
|
507
|
+
"MCP Server": config.name,
|
|
508
|
+
"Status": status,
|
|
509
|
+
"Tool Name": getattr(tool, 'tool_name', str(tool))
|
|
510
|
+
})
|
|
511
|
+
else:
|
|
512
|
+
# Add single entry showing no tools available
|
|
513
|
+
tool_info.append({
|
|
514
|
+
"MCP Server": config.name,
|
|
515
|
+
"Status": status,
|
|
516
|
+
"Tool Name": "No tools available"
|
|
517
|
+
})
|
|
518
|
+
|
|
519
|
+
return tool_info
|
|
520
|
+
|
|
521
|
+
def get_model_info(self) -> str:
|
|
522
|
+
"""Get current model ID from the initialized agent"""
|
|
523
|
+
if not self.initialized or not self.agent:
|
|
524
|
+
return "Agent not initialized"
|
|
525
|
+
|
|
526
|
+
# Try to get model from agent instance, fallback to config
|
|
527
|
+
return getattr(self.agent, 'model', BEDROCK_MODEL_ID)
|
|
528
|
+
|
|
529
|
+
def get_model_info(self) -> str:
|
|
530
|
+
"""Get current model ID for UI display"""
|
|
531
|
+
return BEDROCK_MODEL_ID
|
|
532
|
+
|
|
533
|
+
def _detect_current_phase(self, response_message, user_message: str) -> str:
|
|
534
|
+
"""
|
|
535
|
+
Detect current phase using LLM-based intelligent classification
|
|
536
|
+
Replaces keyword-based detection with context-aware analysis
|
|
537
|
+
Added by: Vikrant
|
|
538
|
+
"""
|
|
539
|
+
try:
|
|
540
|
+
# Create phase classification prompt - Vikrant
|
|
541
|
+
phase_prompt = f"""
|
|
542
|
+
Analyze this conversation exchange and determine the current AWS architecture workflow phase.
|
|
543
|
+
|
|
544
|
+
User Request: {user_message}
|
|
545
|
+
Assistant Response: {str(response_message)[:500]}...
|
|
546
|
+
|
|
547
|
+
Available Phases:
|
|
548
|
+
1. Discovery Phase - Gathering business requirements, understanding needs, asking clarifying questions
|
|
549
|
+
2. AWS Solution Architecture - Designing architecture, creating diagrams, selecting AWS services
|
|
550
|
+
3. Cost Analysis - Calculating costs, pricing estimates, budget analysis
|
|
551
|
+
4. AWS Well Architected Review - Reviewing against AWS best practices, assessing pillars
|
|
552
|
+
|
|
553
|
+
Based on the content and intent, which phase is this conversation currently in?
|
|
554
|
+
Respond with ONLY the exact phase name from the list above.
|
|
555
|
+
"""
|
|
556
|
+
|
|
557
|
+
# Use LLM to intelligently classify phase - Vikrant
|
|
558
|
+
phase_result = self.agent(phase_prompt.strip())
|
|
559
|
+
detected_phase = self._parse_phase_from_response(str(phase_result.message))
|
|
560
|
+
|
|
561
|
+
logger.info(f"LLM detected phase: {detected_phase}")
|
|
562
|
+
return detected_phase
|
|
563
|
+
|
|
564
|
+
except Exception as e:
|
|
565
|
+
# Fallback to Discovery Phase on any error - Vikrant
|
|
566
|
+
logger.warning(f"Phase detection failed, defaulting to Discovery: {e}")
|
|
567
|
+
return "Discovery Phase"
|
|
568
|
+
|
|
569
|
+
def _parse_phase_from_response(self, response: str) -> str:
|
|
570
|
+
"""
|
|
571
|
+
Parse phase name from LLM response with fuzzy matching
|
|
572
|
+
Added by: Vikrant
|
|
573
|
+
"""
|
|
574
|
+
response_lower = response.lower().strip()
|
|
575
|
+
|
|
576
|
+
# Define valid phases - Vikrant
|
|
577
|
+
valid_phases = [
|
|
578
|
+
"Discovery Phase",
|
|
579
|
+
"AWS Solution Architecture",
|
|
580
|
+
"Cost Analysis",
|
|
581
|
+
"AWS Well Architected Review"
|
|
582
|
+
]
|
|
583
|
+
|
|
584
|
+
# Direct match check - Vikrant
|
|
585
|
+
for phase in valid_phases:
|
|
586
|
+
if phase.lower() in response_lower:
|
|
587
|
+
return phase
|
|
588
|
+
|
|
589
|
+
# Fuzzy matching for common variations - Vikrant
|
|
590
|
+
if any(word in response_lower for word in ["discovery", "requirement", "gathering"]):
|
|
591
|
+
return "Discovery Phase"
|
|
592
|
+
elif any(word in response_lower for word in ["architecture", "design", "diagram"]):
|
|
593
|
+
return "AWS Solution Architecture"
|
|
594
|
+
elif any(word in response_lower for word in ["cost", "pricing", "budget"]):
|
|
595
|
+
return "Cost Analysis"
|
|
596
|
+
elif any(word in response_lower for word in ["well-architected", "review", "pillar"]):
|
|
597
|
+
return "AWS Well Architected Review"
|
|
598
|
+
|
|
599
|
+
# Default fallback - Vikrant
|
|
600
|
+
return "Discovery Phase"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Configuration module
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""AWS configuration settings"""
|
|
2
|
+
|
|
3
|
+
# ============================================================================
|
|
4
|
+
# AWS Configuration
|
|
5
|
+
# ============================================================================
|
|
6
|
+
|
|
7
|
+
# AWS Region Configuration
|
|
8
|
+
AWS_REGION = "us-east-1"
|
|
9
|
+
|
|
10
|
+
# ============================================================================
|
|
11
|
+
# Bedrock Model Configuration
|
|
12
|
+
# ============================================================================
|
|
13
|
+
|
|
14
|
+
# Bedrock Model with cross-region inference
|
|
15
|
+
|
|
16
|
+
#BEDROCK_MODEL_ID = "global.anthropic.claude-sonnet-4-6" # Global Claude Sonnet 4.6
|
|
17
|
+
BEDROCK_MODEL_ID = "global.anthropic.claude-sonnet-4-5-20250929-v1:0" # Global Claude Sonnet 4.5
|
|
18
|
+
#BEDROCK_MODEL_ID = "global.anthropic.claude-sonnet-4-20250514-v1:0" # Global Claude Sonnet 4
|
|
19
|
+
#BEDROCK_MODEL_ID = "us.anthropic.claude-3-7-sonnet-20250219-v1:0" # US Anthropic Claude 3.7 Sonnet
|
|
20
|
+
|
|
21
|
+
# Model Parameters
|
|
22
|
+
MAX_TOKENS = 10000
|
|
23
|
+
ANTHROPIC_BETA = ["context-1m-2025-08-07"] # Claude Sonnet 4's 1M context window
|
|
24
|
+
|
|
25
|
+
# Thinking configuration for Claude models
|
|
26
|
+
THINKING_CONFIG = {
|
|
27
|
+
"type": "enabled",
|
|
28
|
+
"budget_tokens": 4000
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# ============================================================================
|
|
32
|
+
# Agent Configuration
|
|
33
|
+
# ============================================================================
|
|
34
|
+
|
|
35
|
+
AGENT_NAME = "aws-architect"
|
|
36
|
+
MAX_RETRIES = 3
|
|
37
|
+
SERVER_CLEANUP_TIMEOUT = 5 # seconds
|
|
38
|
+
|
|
39
|
+
# ============================================================================
|
|
40
|
+
# Rate Limiter Configuration
|
|
41
|
+
# ============================================================================
|
|
42
|
+
|
|
43
|
+
RATE_LIMIT_MAX_REQUESTS = 5 # Maximum LLM requests per time window
|
|
44
|
+
RATE_LIMIT_TIME_WINDOW = 60 # Time window in seconds (1 minute)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# ============================================================================
|
|
49
|
+
# MCP Server Configuration
|
|
50
|
+
# ============================================================================
|
|
51
|
+
|
|
52
|
+
# Environment variables for MCP servers
|
|
53
|
+
MCP_ENV_VARS = {
|
|
54
|
+
"AWS_REGION": AWS_REGION,
|
|
55
|
+
"BEDROCK_MODEL_ID": BEDROCK_MODEL_ID,
|
|
56
|
+
"FASTMCP_LOG_LEVEL": "ERROR"
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# MCP Server Definitions
|
|
60
|
+
MCP_SERVERS = [
|
|
61
|
+
{
|
|
62
|
+
"name": "AWS Knowledge",
|
|
63
|
+
"client_type": "http",
|
|
64
|
+
"url": "https://knowledge-mcp.global.api.aws",
|
|
65
|
+
"remote": True
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "AWS Pricing",
|
|
69
|
+
"client_type": "stdio",
|
|
70
|
+
"command": "uvx",
|
|
71
|
+
"args": ["awslabs.aws-pricing-mcp-server@latest"],
|
|
72
|
+
"remote": True
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "AWS Diagram",
|
|
76
|
+
"client_type": "stdio",
|
|
77
|
+
"command": "uvx",
|
|
78
|
+
"args": ["awslabs.aws-diagram-mcp-server@latest"],
|
|
79
|
+
"env": {"FASTMCP_LOG_LEVEL": "ERROR", "AWS_REGION": AWS_REGION},
|
|
80
|
+
"remote": True
|
|
81
|
+
}
|
|
82
|
+
]
|