@bluefly/openstandardagents 0.4.0 → 0.4.2
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/CHANGELOG.md +137 -0
- package/DEMO.md +212 -0
- package/README.md +77 -17
- package/dist/adapters/drupal/generator.d.ts +149 -0
- package/dist/adapters/drupal/generator.d.ts.map +1 -0
- package/dist/adapters/drupal/generator.js +1760 -0
- package/dist/adapters/drupal/generator.js.map +1 -0
- package/dist/adapters/drupal/index.d.ts +2 -0
- package/dist/adapters/drupal/index.d.ts.map +1 -1
- package/dist/adapters/drupal/index.js +3 -0
- package/dist/adapters/drupal/index.js.map +1 -1
- package/dist/adapters/npm/adapter.js +2 -2
- package/dist/adapters/npm/converter.js +3 -3
- package/dist/cli/banner.d.ts +21 -0
- package/dist/cli/banner.d.ts.map +1 -0
- package/dist/cli/banner.js +128 -0
- package/dist/cli/banner.js.map +1 -0
- package/dist/cli/commands/dev.command.d.ts +20 -0
- package/dist/cli/commands/dev.command.d.ts.map +1 -0
- package/dist/cli/commands/dev.command.js +78 -0
- package/dist/cli/commands/dev.command.js.map +1 -0
- package/dist/cli/commands/estimate.command.d.ts +12 -0
- package/dist/cli/commands/estimate.command.d.ts.map +1 -0
- package/dist/cli/commands/estimate.command.js +226 -0
- package/dist/cli/commands/estimate.command.js.map +1 -0
- package/dist/cli/commands/export-enhanced.command.d.ts +7 -0
- package/dist/cli/commands/export-enhanced.command.d.ts.map +1 -0
- package/dist/cli/commands/{export-v2.command.js → export-enhanced.command.js} +3 -3
- package/dist/cli/commands/export-enhanced.command.js.map +1 -0
- package/dist/cli/commands/export.command.d.ts.map +1 -1
- package/dist/cli/commands/export.command.js +82 -4
- package/dist/cli/commands/export.command.js.map +1 -1
- package/dist/cli/commands/init.command.d.ts.map +1 -1
- package/dist/cli/commands/init.command.js +2 -0
- package/dist/cli/commands/init.command.js.map +1 -1
- package/dist/cli/commands/test.command.d.ts +1 -0
- package/dist/cli/commands/test.command.d.ts.map +1 -1
- package/dist/cli/commands/test.command.js +172 -105
- package/dist/cli/commands/test.command.js.map +1 -1
- package/dist/cli/commands/types/wizard-config.types.d.ts +59 -0
- package/dist/cli/commands/types/wizard-config.types.d.ts.map +1 -0
- package/dist/cli/commands/types/wizard-config.types.js +34 -0
- package/dist/cli/commands/types/wizard-config.types.js.map +1 -0
- package/dist/cli/commands/upgrade.command.d.ts +9 -0
- package/dist/cli/commands/upgrade.command.d.ts.map +1 -0
- package/dist/cli/commands/upgrade.command.js +167 -0
- package/dist/cli/commands/upgrade.command.js.map +1 -0
- package/dist/cli/commands/wizard-api-first.command.d.ts +18 -0
- package/dist/cli/commands/wizard-api-first.command.d.ts.map +1 -0
- package/dist/cli/commands/wizard-api-first.command.js +854 -0
- package/dist/cli/commands/wizard-api-first.command.js.map +1 -0
- package/dist/cli/commands/wizard-interactive.command.d.ts +25 -0
- package/dist/cli/commands/wizard-interactive.command.d.ts.map +1 -0
- package/dist/cli/commands/wizard-interactive.command.js +1875 -0
- package/dist/cli/commands/wizard-interactive.command.js.map +1 -0
- package/dist/cli/commands/workspace.command.js +1 -1
- package/dist/cli/commands/workspace.command.js.map +1 -1
- package/dist/cli/index.js +9 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/schema-driven/index.d.ts +27 -0
- package/dist/cli/schema-driven/index.d.ts.map +1 -0
- package/dist/cli/schema-driven/index.js +34 -0
- package/dist/cli/schema-driven/index.js.map +1 -0
- package/dist/cli/schema-driven/schema-loader.d.ts +115 -0
- package/dist/cli/schema-driven/schema-loader.d.ts.map +1 -0
- package/dist/cli/schema-driven/schema-loader.js +270 -0
- package/dist/cli/schema-driven/schema-loader.js.map +1 -0
- package/dist/cli/schema-driven/ui-generator.d.ts +88 -0
- package/dist/cli/schema-driven/ui-generator.d.ts.map +1 -0
- package/dist/cli/schema-driven/ui-generator.js +326 -0
- package/dist/cli/schema-driven/ui-generator.js.map +1 -0
- package/dist/cli/wizard/interactive-wizard.d.ts +26 -0
- package/dist/cli/wizard/interactive-wizard.d.ts.map +1 -0
- package/dist/cli/wizard/interactive-wizard.js +296 -0
- package/dist/cli/wizard/interactive-wizard.js.map +1 -0
- package/dist/cli/wizard/template-catalog.d.ts +32 -0
- package/dist/cli/wizard/template-catalog.d.ts.map +1 -0
- package/dist/cli/wizard/template-catalog.js +99 -0
- package/dist/cli/wizard/template-catalog.js.map +1 -0
- package/dist/cli/wizard/use-cases.d.ts +37 -0
- package/dist/cli/wizard/use-cases.d.ts.map +1 -0
- package/dist/cli/wizard/use-cases.js +157 -0
- package/dist/cli/wizard/use-cases.js.map +1 -0
- package/dist/di-container.d.ts.map +1 -1
- package/dist/di-container.js +2 -0
- package/dist/di-container.js.map +1 -1
- package/dist/package.json +33 -11
- package/dist/runtime/agent-runner.d.ts +46 -0
- package/dist/runtime/agent-runner.d.ts.map +1 -0
- package/dist/runtime/agent-runner.js +346 -0
- package/dist/runtime/agent-runner.js.map +1 -0
- package/dist/sdks/kagent/crd-generator.d.ts +4 -0
- package/dist/sdks/kagent/crd-generator.d.ts.map +1 -1
- package/dist/sdks/kagent/crd-generator.js +83 -2
- package/dist/sdks/kagent/crd-generator.js.map +1 -1
- package/dist/sdks/kagent/k8s-resources-generator.d.ts +73 -0
- package/dist/sdks/kagent/k8s-resources-generator.d.ts.map +1 -0
- package/dist/sdks/kagent/k8s-resources-generator.js +286 -0
- package/dist/sdks/kagent/k8s-resources-generator.js.map +1 -0
- package/dist/sdks/kagent/types.d.ts +79 -0
- package/dist/sdks/kagent/types.d.ts.map +1 -1
- package/dist/sdks/shared/validation.d.ts +2 -2
- package/dist/services/cost-estimation/optimization-patterns.d.ts +23 -0
- package/dist/services/cost-estimation/optimization-patterns.d.ts.map +1 -0
- package/dist/services/cost-estimation/optimization-patterns.js +147 -0
- package/dist/services/cost-estimation/optimization-patterns.js.map +1 -0
- package/dist/services/cost-estimation/pricing.d.ts +29 -0
- package/dist/services/cost-estimation/pricing.d.ts.map +1 -0
- package/dist/services/cost-estimation/pricing.js +225 -0
- package/dist/services/cost-estimation/pricing.js.map +1 -0
- package/dist/services/cost-estimation/scenario-estimator.d.ts +59 -0
- package/dist/services/cost-estimation/scenario-estimator.d.ts.map +1 -0
- package/dist/services/cost-estimation/scenario-estimator.js +145 -0
- package/dist/services/cost-estimation/scenario-estimator.js.map +1 -0
- package/dist/services/cost-estimation/token-counter.service.d.ts +51 -0
- package/dist/services/cost-estimation/token-counter.service.d.ts.map +1 -0
- package/dist/services/cost-estimation/token-counter.service.js +125 -0
- package/dist/services/cost-estimation/token-counter.service.js.map +1 -0
- package/dist/services/dev-server/dev-server.service.d.ts +121 -0
- package/dist/services/dev-server/dev-server.service.d.ts.map +1 -0
- package/dist/services/dev-server/dev-server.service.js +290 -0
- package/dist/services/dev-server/dev-server.service.js.map +1 -0
- package/dist/services/dev-server/file-watcher.d.ts +101 -0
- package/dist/services/dev-server/file-watcher.d.ts.map +1 -0
- package/dist/services/dev-server/file-watcher.js +190 -0
- package/dist/services/dev-server/file-watcher.js.map +1 -0
- package/dist/services/dev-server/live-validator.d.ts +157 -0
- package/dist/services/dev-server/live-validator.d.ts.map +1 -0
- package/dist/services/dev-server/live-validator.js +301 -0
- package/dist/services/dev-server/live-validator.js.map +1 -0
- package/dist/services/dev-server/websocket-server.d.ts +137 -0
- package/dist/services/dev-server/websocket-server.d.ts.map +1 -0
- package/dist/services/dev-server/websocket-server.js +229 -0
- package/dist/services/dev-server/websocket-server.js.map +1 -0
- package/dist/services/export/anthropic/anthropic-exporter.d.ts +70 -0
- package/dist/services/export/anthropic/anthropic-exporter.d.ts.map +1 -0
- package/dist/services/export/anthropic/anthropic-exporter.js +576 -0
- package/dist/services/export/anthropic/anthropic-exporter.js.map +1 -0
- package/dist/services/export/anthropic/api-generator.d.ts +39 -0
- package/dist/services/export/anthropic/api-generator.d.ts.map +1 -0
- package/dist/services/export/anthropic/api-generator.js +395 -0
- package/dist/services/export/anthropic/api-generator.js.map +1 -0
- package/dist/services/export/anthropic/index.d.ts +18 -0
- package/dist/services/export/anthropic/index.d.ts.map +1 -0
- package/dist/services/export/anthropic/index.js +16 -0
- package/dist/services/export/anthropic/index.js.map +1 -0
- package/dist/services/export/anthropic/tools-generator.d.ts +35 -0
- package/dist/services/export/anthropic/tools-generator.d.ts.map +1 -0
- package/dist/services/export/anthropic/tools-generator.js +260 -0
- package/dist/services/export/anthropic/tools-generator.js.map +1 -0
- package/dist/services/export/langchain/api-generator.d.ts +17 -0
- package/dist/services/export/langchain/api-generator.d.ts.map +1 -0
- package/dist/services/export/langchain/api-generator.js +375 -0
- package/dist/services/export/langchain/api-generator.js.map +1 -0
- package/dist/services/export/langchain/callbacks-generator.d.ts +63 -0
- package/dist/services/export/langchain/callbacks-generator.d.ts.map +1 -0
- package/dist/services/export/langchain/callbacks-generator.js +408 -0
- package/dist/services/export/langchain/callbacks-generator.js.map +1 -0
- package/dist/services/export/langchain/error-handling-generator.d.ts +76 -0
- package/dist/services/export/langchain/error-handling-generator.d.ts.map +1 -0
- package/dist/services/export/langchain/error-handling-generator.js +522 -0
- package/dist/services/export/langchain/error-handling-generator.js.map +1 -0
- package/dist/services/export/langchain/index.d.ts +17 -0
- package/dist/services/export/langchain/index.d.ts.map +1 -0
- package/dist/services/export/langchain/index.js +13 -0
- package/dist/services/export/langchain/index.js.map +1 -0
- package/dist/services/export/langchain/langchain-exporter.d.ts +174 -0
- package/dist/services/export/langchain/langchain-exporter.d.ts.map +1 -0
- package/dist/services/export/langchain/langchain-exporter.js +953 -0
- package/dist/services/export/langchain/langchain-exporter.js.map +1 -0
- package/dist/services/export/langchain/langgraph-generator.d.ts +86 -0
- package/dist/services/export/langchain/langgraph-generator.d.ts.map +1 -0
- package/dist/services/export/langchain/langgraph-generator.js +473 -0
- package/dist/services/export/langchain/langgraph-generator.js.map +1 -0
- package/dist/services/export/langchain/langserve-generator.d.ts +95 -0
- package/dist/services/export/langchain/langserve-generator.d.ts.map +1 -0
- package/dist/services/export/langchain/langserve-generator.js +807 -0
- package/dist/services/export/langchain/langserve-generator.js.map +1 -0
- package/dist/services/export/langchain/memory-generator.d.ts +71 -0
- package/dist/services/export/langchain/memory-generator.d.ts.map +1 -0
- package/dist/services/export/langchain/memory-generator.js +1182 -0
- package/dist/services/export/langchain/memory-generator.js.map +1 -0
- package/dist/services/export/langchain/openapi-generator.d.ts +20 -0
- package/dist/services/export/langchain/openapi-generator.d.ts.map +1 -0
- package/dist/services/export/langchain/openapi-generator.js +364 -0
- package/dist/services/export/langchain/openapi-generator.js.map +1 -0
- package/dist/services/export/langchain/plan-execute-generator.d.ts +60 -0
- package/dist/services/export/langchain/plan-execute-generator.d.ts.map +1 -0
- package/dist/services/export/langchain/plan-execute-generator.js +679 -0
- package/dist/services/export/langchain/plan-execute-generator.js.map +1 -0
- package/dist/services/export/langchain/streaming-generator.d.ts +66 -0
- package/dist/services/export/langchain/streaming-generator.d.ts.map +1 -0
- package/dist/services/export/langchain/streaming-generator.js +749 -0
- package/dist/services/export/langchain/streaming-generator.js.map +1 -0
- package/dist/services/export/langchain/tools-generator.d.ts +67 -0
- package/dist/services/export/langchain/tools-generator.d.ts.map +1 -0
- package/dist/services/export/langchain/tools-generator.js +543 -0
- package/dist/services/export/langchain/tools-generator.js.map +1 -0
- package/dist/services/export/npm/express-generator.d.ts +23 -0
- package/dist/services/export/npm/express-generator.d.ts.map +1 -0
- package/dist/services/export/npm/express-generator.js +296 -0
- package/dist/services/export/npm/express-generator.js.map +1 -0
- package/dist/services/export/npm/index.d.ts +13 -0
- package/dist/services/export/npm/index.d.ts.map +1 -0
- package/dist/services/export/npm/index.js +11 -0
- package/dist/services/export/npm/index.js.map +1 -0
- package/dist/services/export/npm/npm-exporter.d.ts +142 -0
- package/dist/services/export/npm/npm-exporter.d.ts.map +1 -0
- package/dist/services/export/npm/npm-exporter.js +480 -0
- package/dist/services/export/npm/npm-exporter.js.map +1 -0
- package/dist/services/export/npm/openapi-generator.d.ts +19 -0
- package/dist/services/export/npm/openapi-generator.d.ts.map +1 -0
- package/dist/services/export/npm/openapi-generator.js +428 -0
- package/dist/services/export/npm/openapi-generator.js.map +1 -0
- package/dist/services/export/npm/package-json-generator.d.ts +31 -0
- package/dist/services/export/npm/package-json-generator.d.ts.map +1 -0
- package/dist/services/export/npm/package-json-generator.js +153 -0
- package/dist/services/export/npm/package-json-generator.js.map +1 -0
- package/dist/services/export/npm/typescript-generator.d.ts +69 -0
- package/dist/services/export/npm/typescript-generator.d.ts.map +1 -0
- package/dist/services/export/npm/typescript-generator.js +437 -0
- package/dist/services/export/npm/typescript-generator.js.map +1 -0
- package/dist/services/export/testing/index.d.ts +8 -0
- package/dist/services/export/testing/index.d.ts.map +1 -0
- package/dist/services/export/testing/index.js +7 -0
- package/dist/services/export/testing/index.js.map +1 -0
- package/dist/services/export/testing/test-generator.d.ts +178 -0
- package/dist/services/export/testing/test-generator.d.ts.map +1 -0
- package/dist/services/export/testing/test-generator.js +2542 -0
- package/dist/services/export/testing/test-generator.js.map +1 -0
- package/dist/services/test-runner/mock-llm.service.d.ts +77 -0
- package/dist/services/test-runner/mock-llm.service.d.ts.map +1 -0
- package/dist/services/test-runner/mock-llm.service.js +173 -0
- package/dist/services/test-runner/mock-llm.service.js.map +1 -0
- package/dist/services/test-runner/scenarios.d.ts +36 -0
- package/dist/services/test-runner/scenarios.d.ts.map +1 -0
- package/dist/services/test-runner/scenarios.js +196 -0
- package/dist/services/test-runner/scenarios.js.map +1 -0
- package/dist/services/test-runner/test-runner.service.d.ts +19 -1
- package/dist/services/test-runner/test-runner.service.d.ts.map +1 -1
- package/dist/services/test-runner/test-runner.service.js +72 -6
- package/dist/services/test-runner/test-runner.service.js.map +1 -1
- package/dist/services/validation/best-practices-validator.d.ts +84 -0
- package/dist/services/validation/best-practices-validator.d.ts.map +1 -0
- package/dist/services/validation/best-practices-validator.js +499 -0
- package/dist/services/validation/best-practices-validator.js.map +1 -0
- package/dist/services/validation/cost-estimator.d.ts +69 -0
- package/dist/services/validation/cost-estimator.d.ts.map +1 -0
- package/dist/services/validation/cost-estimator.js +221 -0
- package/dist/services/validation/cost-estimator.js.map +1 -0
- package/dist/services/validation/enhanced-validator.d.ts +78 -0
- package/dist/services/validation/enhanced-validator.d.ts.map +1 -0
- package/dist/services/validation/enhanced-validator.js +212 -0
- package/dist/services/validation/enhanced-validator.js.map +1 -0
- package/dist/services/validation/index.d.ts +13 -0
- package/dist/services/validation/index.d.ts.map +1 -0
- package/dist/services/validation/index.js +9 -0
- package/dist/services/validation/index.js.map +1 -0
- package/dist/services/validation/security-validator.d.ts +81 -0
- package/dist/services/validation/security-validator.d.ts.map +1 -0
- package/dist/services/validation/security-validator.js +328 -0
- package/dist/services/validation/security-validator.js.map +1 -0
- package/dist/services/wizard/prompts.d.ts +71 -0
- package/dist/services/wizard/prompts.d.ts.map +1 -0
- package/dist/services/wizard/prompts.js +322 -0
- package/dist/services/wizard/prompts.js.map +1 -0
- package/dist/services/wizard/wizard.service.d.ts +60 -0
- package/dist/services/wizard/wizard.service.d.ts.map +1 -0
- package/dist/services/wizard/wizard.service.js +261 -0
- package/dist/services/wizard/wizard.service.js.map +1 -0
- package/dist/types/personality.zod.d.ts +23 -23
- package/dist/utils/version.d.ts +1 -1
- package/dist/utils/version.js +1 -1
- package/dist/version-management/core/version-manager.test.js.map +1 -1
- package/dist/version.d.ts +62 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +73 -0
- package/dist/version.js.map +1 -0
- package/examples/a2a/agent-handoff.ossa.yaml +1 -1
- package/examples/a2a/service-discovery.ossa.yaml +1 -1
- package/examples/adapters/drupal-eca-mapping.yaml +1 -1
- package/examples/adapters/drupal-eca-task.yaml +1 -1
- package/examples/adapters/drupal-flowdrop-mapping.yaml +1 -1
- package/examples/adapters/drupal-maestro-mapping.yaml +1 -1
- package/examples/adapters/mistral-agent.yaml +1 -1
- package/examples/adapters/symfony-messenger-task.yaml +1 -1
- package/examples/adapters/symfony-messenger-workflow.yaml +1 -1
- package/examples/adk-integration/code-review-workflow.yml +1 -1
- package/examples/adk-integration/customer-support.yml +1 -1
- package/examples/adk-integration/data-pipeline.yml +1 -1
- package/examples/advanced/reasoning-agent.yaml +1 -1
- package/examples/advanced/workflows/hybrid-model-strategy.yaml +1 -1
- package/examples/agent-manifests/critics/critic-agent.yaml +1 -1
- package/examples/agent-manifests/governors/governor-agent.yaml +1 -1
- package/examples/agent-manifests/integrators/integrator-agent.yaml +1 -1
- package/examples/agent-manifests/judges/judge-agent.yaml +1 -1
- package/examples/agent-manifests/monitors/monitor-agent.yaml +1 -1
- package/examples/agent-manifests/orchestrators/orchestrator-agent.yaml +1 -1
- package/examples/agent-manifests/sample-compliant-agent.yaml +1 -1
- package/examples/agent-manifests/workers/worker-agent.yaml +1 -1
- package/examples/agents/01-customer-support-bot/.env.example +32 -0
- package/examples/agents/01-customer-support-bot/Dockerfile +30 -0
- package/examples/agents/01-customer-support-bot/README.md +295 -0
- package/examples/agents/01-customer-support-bot/agent.ossa.yaml +172 -0
- package/examples/agents/01-customer-support-bot/docker-compose.yml +55 -0
- package/examples/agents/01-customer-support-bot/openapi.yaml +238 -0
- package/examples/agents/01-customer-support-bot/package.json +48 -0
- package/examples/agents/02-code-review-agent/README.md +72 -0
- package/examples/agents/02-code-review-agent/agent.ossa.yaml +239 -0
- package/examples/agents/02-code-review-agent/docker-compose.yml +22 -0
- package/examples/agents/02-code-review-agent/openapi.yaml +150 -0
- package/examples/agents/03-data-analysis-agent/README.md +51 -0
- package/examples/agents/03-data-analysis-agent/agent.ossa.yaml +97 -0
- package/examples/agents/03-data-analysis-agent/openapi.yaml +74 -0
- package/examples/agents/04-content-moderator/README.md +55 -0
- package/examples/agents/04-content-moderator/agent.ossa.yaml +131 -0
- package/examples/agents/04-content-moderator/openapi.yaml +50 -0
- package/examples/agents/05-sales-assistant/README.md +37 -0
- package/examples/agents/05-sales-assistant/agent.ossa.yaml +146 -0
- package/examples/agents/05-sales-assistant/openapi.yaml +59 -0
- package/examples/agents/06-devops-agent/README.md +39 -0
- package/examples/agents/06-devops-agent/agent.ossa.yaml +141 -0
- package/examples/agents/06-devops-agent/openapi.yaml +51 -0
- package/examples/agents/07-research-assistant/README.md +31 -0
- package/examples/agents/07-research-assistant/agent.ossa.yaml +119 -0
- package/examples/agents/07-research-assistant/openapi.yaml +56 -0
- package/examples/agents/08-email-triage-agent/README.md +33 -0
- package/examples/agents/08-email-triage-agent/agent.ossa.yaml +133 -0
- package/examples/agents/08-email-triage-agent/openapi.yaml +41 -0
- package/examples/agents/09-security-scanner/README.md +49 -0
- package/examples/agents/09-security-scanner/agent.ossa.yaml +174 -0
- package/examples/agents/09-security-scanner/openapi.yaml +46 -0
- package/examples/agents/10-meeting-assistant/README.md +53 -0
- package/examples/agents/10-meeting-assistant/agent.ossa.yaml +211 -0
- package/examples/agents/10-meeting-assistant/docker-compose.yml +27 -0
- package/examples/agents/10-meeting-assistant/openapi.yaml +131 -0
- package/examples/agents/COMPLETION_REPORT.txt +272 -0
- package/examples/agents/INDEX.md +296 -0
- package/examples/agents/README.md +452 -0
- package/examples/agents/SUMMARY.md +362 -0
- package/examples/agents/TEST_RESULTS.md +458 -0
- package/examples/agents/architecture-healer-enterprise.yaml +1 -1
- package/examples/agents/dependency-healer-npm.yaml +1 -1
- package/examples/agents/spec-healer-openapi.yaml +1 -1
- package/examples/agents/wiki-healer-production.yaml +1 -1
- package/examples/agents-md/code-agent.ossa.json +1 -1
- package/examples/agents-md/monorepo-agent.ossa.yaml +1 -1
- package/examples/anthropic/claude-assistant.ossa.json +1 -1
- package/examples/autogen/multi-agent.ossa.json +1 -1
- package/examples/autonomous-evolution/self-evolving-agent.ossa.yaml +1 -1
- package/examples/build-once-use-everywhere/agent.ossa.yaml +1 -1
- package/examples/claude-code/code-reviewer.ossa.yaml +1 -1
- package/examples/claude-code/ossa-validator.ossa.yaml +1 -1
- package/examples/common_npm/agent-router.ossa.yaml +2 -2
- package/examples/contracts/data-consumer.ossa.yaml +1 -1
- package/examples/contracts/data-producer-v2.ossa.yaml +1 -1
- package/examples/contracts/data-producer.ossa.yaml +1 -1
- package/examples/crewai/research-team.ossa.json +1 -1
- package/examples/cursor/code-review-agent.ossa.json +1 -1
- package/examples/drupal/QUICKSTART.md +439 -0
- package/examples/drupal/ai_agents_ossa-module/.agents/example-agent/agent.ossa.yaml +1 -1
- package/examples/drupal/content-moderator.ossa.yaml +107 -0
- package/examples/drupal/gitlab-ml-recommender.ossa.yaml +2 -2
- package/examples/economics/marketplace-agent.ossa.json +1 -1
- package/examples/export/langchain/production-agent-with-memory/README.md +373 -0
- package/examples/export/langchain/production-agent-with-memory/agent.ossa.yaml +97 -0
- package/examples/export/langchain/production-agent-with-streaming/README.md +617 -0
- package/examples/export/langchain/production-agent-with-streaming/agent.ossa.yaml +100 -0
- package/examples/export/langchain/production-agent-with-streaming/client-example.py +263 -0
- package/examples/export/langchain/production-agent-with-tools/README.md +296 -0
- package/examples/export/langchain/production-agent-with-tools/agent.ossa.yaml +216 -0
- package/examples/export/langchain-export-example.ts +246 -0
- package/examples/export/langserve-export-example.ts +246 -0
- package/examples/export/test-generation-example.ts +457 -0
- package/examples/extensions/agents-md-advanced.yml +1 -1
- package/examples/extensions/agents-md-basic.yml +1 -1
- package/examples/extensions/agents-md-sync.yml +1 -1
- package/examples/extensions/agents-md-v1.yml +1 -1
- package/examples/extensions/drupal-v1.yml +1 -1
- package/examples/extensions/encryption-multi-provider.yaml +4 -4
- package/examples/extensions/kagent-v1.yml +1 -1
- package/examples/extensions/knowledge-sources.yaml +1 -1
- package/examples/extensions/mcp-full-featured.yaml +1 -1
- package/examples/genetics/breeding-agent.ossa.json +1 -1
- package/examples/getting-started/01-minimal-agent.ossa.yaml +1 -1
- package/examples/getting-started/02-agent-with-tools.ossa.yaml +1 -1
- package/examples/getting-started/03-agent-with-safety.ossa.yaml +1 -1
- package/examples/getting-started/04-agent-with-messaging.ossa.yaml +1 -1
- package/examples/getting-started/05-workflow-composition.ossa.yaml +1 -1
- package/examples/getting-started/hello-world-complete.ossa.yaml +1 -1
- package/examples/integration-patterns/agent-to-agent-orchestration.ossa.yaml +1 -1
- package/examples/kagent/compliance-validator.ossa.yaml +1 -1
- package/examples/kagent/cost-optimizer.ossa.yaml +1 -1
- package/examples/kagent/documentation-agent.ossa.yaml +1 -1
- package/examples/kagent/k8s-troubleshooter-v1.ossa.yaml +2 -2
- package/examples/kagent/k8s-troubleshooter.ossa.yaml +1 -1
- package/examples/kagent/security-scanner.ossa.yaml +1 -1
- package/examples/langchain/chain-agent.ossa.json +1 -1
- package/examples/langflow/workflow-agent.ossa.json +1 -1
- package/examples/langgraph/state-machine-agent.ossa.json +1 -1
- package/examples/lifecycle/mentoring-agent.ossa.json +1 -1
- package/examples/llamaindex/rag-agent.ossa.json +1 -1
- package/examples/mcp/database-mcp.ossa.yaml +1 -1
- package/examples/mcp/filesystem-mcp.ossa.yaml +1 -1
- package/examples/messaging/dependency-healer.ossa.yaml +1 -1
- package/examples/messaging/incident-responder.ossa.yaml +1 -1
- package/examples/messaging/routing-rules.ossa.yaml +1 -1
- package/examples/messaging/security-scanner.ossa.yaml +1 -1
- package/examples/migration-guides/from-langchain-to-ossa.yaml +4 -4
- package/examples/migrations/langchain/01-python-react-agent-after.ossa.yaml +1 -1
- package/examples/migrations/langchain/02-typescript-conversational-after.ossa.yaml +1 -1
- package/examples/migrations/langchain/03-sequential-chain-after.ossa.yaml +1 -1
- package/examples/migrations/langchain/04-config-based-after.ossa.yaml +1 -1
- package/examples/migrations/swarm-to-ossa/after-handoffs.ossa.yaml +6 -6
- package/examples/migrations/swarm-to-ossa/after-triage-agent.ossa.yaml +3 -3
- package/examples/multi-agent/conditional-router.ossa.yaml +1 -1
- package/examples/multi-agent/parallel-execution.ossa.yaml +1 -1
- package/examples/multi-agent/sequential-pipeline.ossa.yaml +1 -1
- package/examples/multi-agent-research-workflow.ossa.yaml +133 -0
- package/examples/multi-platform/single-manifest/agent.ossa.yaml +1 -1
- package/examples/npm-export-example.ts +150 -0
- package/examples/observability/activity-stream-full.yaml +1 -1
- package/examples/openai/basic-agent.ossa.yaml +1 -1
- package/examples/openai/multi-tool-agent.ossa.json +1 -1
- package/examples/openai/swarm-agent.ossa.json +1 -1
- package/examples/ossa-templates/01-code-assistant.ossa.yaml +1 -1
- package/examples/ossa-templates/02-security-scanner.ossa.yaml +1 -1
- package/examples/ossa-templates/03-ci-pipeline.ossa.yaml +1 -1
- package/examples/ossa-templates/04-code-reviewer.ossa.yaml +1 -1
- package/examples/ossa-templates/05-doc-generator.ossa.yaml +1 -1
- package/examples/ossa-templates/06-compliance-validator.ossa.yaml +1 -1
- package/examples/ossa-templates/07-workflow-orchestrator.ossa.yaml +1 -1
- package/examples/ossa-templates/08-content-writer.ossa.yaml +1 -1
- package/examples/ossa-templates/09-test-generator.ossa.yaml +1 -1
- package/examples/ossa-templates/10-data-transformer.ossa.yaml +1 -1
- package/examples/ossa-templates/11-react-performance-expert.ossa.yaml +1 -1
- package/examples/ossa-templates/12-typescript-type-safety-expert.ossa.yaml +1 -1
- package/examples/ossa-templates/13-accessibility-champion.ossa.yaml +1 -1
- package/examples/ossa-templates/14-security-hardening-agent.ossa.yaml +1 -1
- package/examples/production/document-analyzer-openai.yml +1 -1
- package/examples/production-ready/01-customer-support-bot/.env.example +32 -0
- package/examples/production-ready/01-customer-support-bot/Dockerfile +30 -0
- package/examples/production-ready/01-customer-support-bot/README.md +295 -0
- package/examples/production-ready/01-customer-support-bot/agent.ossa.yaml +172 -0
- package/examples/production-ready/01-customer-support-bot/docker-compose.yml +55 -0
- package/examples/production-ready/01-customer-support-bot/openapi.yaml +238 -0
- package/examples/production-ready/01-customer-support-bot/package.json +48 -0
- package/examples/production-ready/02-code-review-agent/README.md +72 -0
- package/examples/production-ready/02-code-review-agent/agent.ossa.yaml +239 -0
- package/examples/production-ready/02-code-review-agent/docker-compose.yml +22 -0
- package/examples/production-ready/02-code-review-agent/openapi.yaml +150 -0
- package/examples/production-ready/03-data-analysis-agent/README.md +51 -0
- package/examples/production-ready/03-data-analysis-agent/agent.ossa.yaml +97 -0
- package/examples/production-ready/03-data-analysis-agent/openapi.yaml +74 -0
- package/examples/production-ready/04-content-moderator/README.md +55 -0
- package/examples/production-ready/04-content-moderator/agent.ossa.yaml +131 -0
- package/examples/production-ready/04-content-moderator/openapi.yaml +50 -0
- package/examples/production-ready/05-sales-assistant/README.md +37 -0
- package/examples/production-ready/05-sales-assistant/agent.ossa.yaml +146 -0
- package/examples/production-ready/05-sales-assistant/openapi.yaml +59 -0
- package/examples/production-ready/06-devops-agent/README.md +39 -0
- package/examples/production-ready/06-devops-agent/agent.ossa.yaml +141 -0
- package/examples/production-ready/06-devops-agent/openapi.yaml +51 -0
- package/examples/production-ready/07-research-assistant/README.md +31 -0
- package/examples/production-ready/07-research-assistant/agent.ossa.yaml +119 -0
- package/examples/production-ready/07-research-assistant/openapi.yaml +56 -0
- package/examples/production-ready/08-email-triage-agent/README.md +33 -0
- package/examples/production-ready/08-email-triage-agent/agent.ossa.yaml +133 -0
- package/examples/production-ready/08-email-triage-agent/openapi.yaml +41 -0
- package/examples/production-ready/09-security-scanner/README.md +49 -0
- package/examples/production-ready/09-security-scanner/agent.ossa.yaml +174 -0
- package/examples/production-ready/09-security-scanner/openapi.yaml +46 -0
- package/examples/production-ready/10-meeting-assistant/README.md +53 -0
- package/examples/production-ready/10-meeting-assistant/agent.ossa.yaml +211 -0
- package/examples/production-ready/10-meeting-assistant/docker-compose.yml +27 -0
- package/examples/production-ready/10-meeting-assistant/openapi.yaml +131 -0
- package/examples/production-ready/COMPLETION_REPORT.txt +272 -0
- package/examples/production-ready/INDEX.md +296 -0
- package/examples/production-ready/README.md +452 -0
- package/examples/production-ready/SUMMARY.md +362 -0
- package/examples/production-ready/TEST_RESULTS.md +458 -0
- package/examples/quickstart/support-agent.ossa.yaml +1 -1
- package/examples/real-world/gitlab-cicd-optimizer.ossa.yaml +1 -1
- package/examples/real-world/rag-documentation-assistant.ossa.yaml +1 -1
- package/examples/registry/agents/code-reviewer/agent.yaml +1 -1
- package/examples/registry/agents/security-scanner/agent.yaml +1 -1
- package/examples/runtime-adapters/bedrock-claude-example.ossa.yaml +1 -1
- package/examples/schema/reusable-components.yaml +1 -1
- package/examples/showcase/ci-pipeline.ossa.yaml +1 -1
- package/examples/showcase/code-assistant.ossa.yaml +1 -1
- package/examples/showcase/code-reviewer.ossa.yaml +1 -1
- package/examples/showcase/compliance-validator.ossa.yaml +1 -1
- package/examples/showcase/content-writer.ossa.yaml +1 -1
- package/examples/showcase/data-transformer.ossa.yaml +1 -1
- package/examples/showcase/doc-generator.ossa.yaml +1 -1
- package/examples/showcase/security-scanner.ossa.yaml +1 -1
- package/examples/showcase/test-generator.ossa.yaml +1 -1
- package/examples/showcase/workflow-orchestrator.ossa.yaml +1 -1
- package/examples/skills-example.ossa.yaml +140 -0
- package/examples/swarm/pso-optimizer.ossa.json +1 -1
- package/examples/tasks/batch-email-sender.yaml +1 -1
- package/examples/tasks/data-transform.yaml +1 -1
- package/examples/tasks/publish-content.yaml +1 -1
- package/examples/templates/ossa-compliance.yaml +1 -1
- package/examples/unified/security-scanner.ossa.yaml +1 -1
- package/examples/v0.3.6-features/genetics-breeding-advanced.ossa.yaml +1 -1
- package/examples/v0.3.6-features/genetics-breeding-simple.ossa.yaml +1 -1
- package/examples/v0.3.6-features/genetics-fitness-scoring.ossa.yaml +1 -1
- package/examples/vercel/edge-agent.ossa.json +1 -1
- package/examples/workflows/batch-email-campaign.yaml +1 -1
- package/examples/workflows/content-review-publish.yaml +1 -1
- package/examples/workflows/simple-etl.yaml +1 -1
- package/openapi/cli/openapi.yaml +221 -5
- package/package.json +31 -9
- package/dist/cli/commands/export-v2.command.d.ts +0 -7
- package/dist/cli/commands/export-v2.command.d.ts.map +0 -1
- package/dist/cli/commands/export-v2.command.js.map +0 -1
|
@@ -0,0 +1,749 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangChain Streaming Generator (Production Quality - v0.4.1)
|
|
3
|
+
*
|
|
4
|
+
* Generates production-ready streaming support for LangChain agents
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Server-Sent Events (SSE) for real-time responses
|
|
8
|
+
* - WebSocket bidirectional streaming
|
|
9
|
+
* - LangChain callbacks for actual streaming
|
|
10
|
+
* - a2a (agent-to-agent) streaming integration
|
|
11
|
+
* - Token-by-token streaming
|
|
12
|
+
* - Error handling and reconnection logic
|
|
13
|
+
*
|
|
14
|
+
* SOLID: Single Responsibility - Streaming code generation
|
|
15
|
+
* DRY: Reusable streaming templates
|
|
16
|
+
*/
|
|
17
|
+
export class StreamingGenerator {
|
|
18
|
+
/**
|
|
19
|
+
* Generate streaming.py module with SSE, WebSocket, and a2a support
|
|
20
|
+
*/
|
|
21
|
+
generate(manifest, config = {}) {
|
|
22
|
+
const sseEnabled = config.sse?.enabled !== false;
|
|
23
|
+
const websocketEnabled = config.websocket?.enabled !== false;
|
|
24
|
+
const a2aEnabled = config.a2a?.enabled === true;
|
|
25
|
+
const imports = this.generateImports(sseEnabled, websocketEnabled, a2aEnabled);
|
|
26
|
+
const callbacks = this.generateCallbacks(config);
|
|
27
|
+
const sseCode = sseEnabled ? this.generateSSE() : '';
|
|
28
|
+
const websocketCode = websocketEnabled ? this.generateWebSocket() : '';
|
|
29
|
+
const a2aCode = a2aEnabled ? this.generateA2A(config.a2a?.mesh_url) : '';
|
|
30
|
+
return `"""
|
|
31
|
+
LangChain Streaming Support (Production Quality)
|
|
32
|
+
|
|
33
|
+
Features:
|
|
34
|
+
- Server-Sent Events (SSE) for real-time responses
|
|
35
|
+
- WebSocket bidirectional streaming
|
|
36
|
+
- LangChain callbacks for token-by-token streaming
|
|
37
|
+
- Agent-to-agent (a2a) streaming integration
|
|
38
|
+
- Comprehensive error handling
|
|
39
|
+
- Reconnection logic
|
|
40
|
+
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
${imports}
|
|
44
|
+
|
|
45
|
+
${callbacks}
|
|
46
|
+
|
|
47
|
+
${sseCode}
|
|
48
|
+
|
|
49
|
+
${websocketCode}
|
|
50
|
+
|
|
51
|
+
${a2aCode}
|
|
52
|
+
|
|
53
|
+
def get_streaming_config() -> Dict[str, Any]:
|
|
54
|
+
"""
|
|
55
|
+
Get streaming configuration
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Dictionary with streaming settings
|
|
59
|
+
"""
|
|
60
|
+
return {
|
|
61
|
+
"sse_enabled": ${sseEnabled ? 'True' : 'False'},
|
|
62
|
+
"websocket_enabled": ${websocketEnabled ? 'True' : 'False'},
|
|
63
|
+
"a2a_enabled": ${a2aEnabled ? 'True' : 'False'},
|
|
64
|
+
}
|
|
65
|
+
`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Generate imports based on enabled features
|
|
69
|
+
*/
|
|
70
|
+
generateImports(sse, websocket, a2a) {
|
|
71
|
+
const baseImports = `from typing import Any, Dict, AsyncIterator, Optional
|
|
72
|
+
from langchain.callbacks.base import BaseCallbackHandler
|
|
73
|
+
from langchain.schema import LLMResult
|
|
74
|
+
import asyncio
|
|
75
|
+
import json
|
|
76
|
+
import logging
|
|
77
|
+
|
|
78
|
+
logger = logging.getLogger(__name__)`;
|
|
79
|
+
const sseImports = sse ? `
|
|
80
|
+
from fastapi.responses import StreamingResponse
|
|
81
|
+
from starlette.responses import EventSourceResponse` : '';
|
|
82
|
+
const websocketImports = websocket ? `
|
|
83
|
+
from fastapi import WebSocket, WebSocketDisconnect
|
|
84
|
+
from websockets.exceptions import ConnectionClosed` : '';
|
|
85
|
+
const a2aImports = a2a ? `
|
|
86
|
+
import httpx
|
|
87
|
+
from datetime import datetime` : '';
|
|
88
|
+
return `${baseImports}${sseImports}${websocketImports}${a2aImports}`;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Generate LangChain streaming callbacks with cost tracking integration
|
|
92
|
+
*/
|
|
93
|
+
generateCallbacks(config) {
|
|
94
|
+
return `
|
|
95
|
+
# Import cost tracking from callbacks module
|
|
96
|
+
try:
|
|
97
|
+
from callbacks import CostTrackingHandler
|
|
98
|
+
COST_TRACKING_AVAILABLE = True
|
|
99
|
+
except ImportError:
|
|
100
|
+
COST_TRACKING_AVAILABLE = False
|
|
101
|
+
logger.warning("callbacks module not available, cost tracking disabled in streaming")
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class StreamingCallbackHandler(BaseCallbackHandler):
|
|
105
|
+
"""
|
|
106
|
+
Custom callback handler for LangChain streaming with cost tracking
|
|
107
|
+
|
|
108
|
+
Captures tokens as they're generated and sends them through
|
|
109
|
+
the configured streaming channel (SSE, WebSocket, or a2a)
|
|
110
|
+
with real-time cost tracking per token
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
def __init__(self, queue: asyncio.Queue, cost_tracker: Optional[Any] = None):
|
|
114
|
+
"""
|
|
115
|
+
Initialize callback handler
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
queue: Async queue for streaming tokens
|
|
119
|
+
cost_tracker: Optional CostTrackingHandler for real-time cost tracking
|
|
120
|
+
"""
|
|
121
|
+
self.queue = queue
|
|
122
|
+
self.tokens = []
|
|
123
|
+
self.cost_tracker = cost_tracker
|
|
124
|
+
self.token_count = 0
|
|
125
|
+
|
|
126
|
+
def on_llm_start(
|
|
127
|
+
self, serialized: Dict[str, Any], prompts: list[str], **kwargs: Any
|
|
128
|
+
) -> None:
|
|
129
|
+
"""Called when LLM starts generating"""
|
|
130
|
+
logger.info("LLM generation started")
|
|
131
|
+
|
|
132
|
+
# Capture model name for cost tracking
|
|
133
|
+
if self.cost_tracker:
|
|
134
|
+
self.cost_tracker.model_name = serialized.get("name", "unknown")
|
|
135
|
+
|
|
136
|
+
asyncio.create_task(self.queue.put({
|
|
137
|
+
"type": "llm_start",
|
|
138
|
+
"prompts": prompts,
|
|
139
|
+
"model": serialized.get("name", "unknown"),
|
|
140
|
+
}))
|
|
141
|
+
|
|
142
|
+
def on_llm_new_token(self, token: str, **kwargs: Any) -> None:
|
|
143
|
+
"""Called when LLM generates a new token"""
|
|
144
|
+
logger.debug(f"New token: {token}")
|
|
145
|
+
self.tokens.append(token)
|
|
146
|
+
self.token_count += 1
|
|
147
|
+
|
|
148
|
+
# Get current cost if tracker available
|
|
149
|
+
current_cost = 0.0
|
|
150
|
+
if self.cost_tracker:
|
|
151
|
+
current_cost = self.cost_tracker.total_cost
|
|
152
|
+
|
|
153
|
+
asyncio.create_task(self.queue.put({
|
|
154
|
+
"type": "token",
|
|
155
|
+
"token": token,
|
|
156
|
+
"token_count": self.token_count,
|
|
157
|
+
"cost": current_cost,
|
|
158
|
+
}))
|
|
159
|
+
|
|
160
|
+
def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None:
|
|
161
|
+
"""Called when LLM finishes generating"""
|
|
162
|
+
logger.info("LLM generation completed")
|
|
163
|
+
|
|
164
|
+
# Track final token usage if cost tracker available
|
|
165
|
+
cost_summary = {}
|
|
166
|
+
if self.cost_tracker and response.llm_output:
|
|
167
|
+
token_usage = response.llm_output.get("token_usage", {})
|
|
168
|
+
prompt_tokens = token_usage.get("prompt_tokens", 0)
|
|
169
|
+
completion_tokens = token_usage.get("completion_tokens", 0)
|
|
170
|
+
|
|
171
|
+
# Update cost tracker
|
|
172
|
+
self.cost_tracker.prompt_tokens += prompt_tokens
|
|
173
|
+
self.cost_tracker.completion_tokens += completion_tokens
|
|
174
|
+
self.cost_tracker.total_tokens += (prompt_tokens + completion_tokens)
|
|
175
|
+
|
|
176
|
+
# Calculate final cost
|
|
177
|
+
model_key = self.cost_tracker._normalize_model_name(
|
|
178
|
+
self.cost_tracker.model_name or ""
|
|
179
|
+
)
|
|
180
|
+
pricing = self.cost_tracker.PRICING.get(model_key, {"input": 0, "output": 0})
|
|
181
|
+
input_cost = (prompt_tokens / 1_000_000) * pricing["input"]
|
|
182
|
+
output_cost = (completion_tokens / 1_000_000) * pricing["output"]
|
|
183
|
+
self.cost_tracker.total_cost += input_cost + output_cost
|
|
184
|
+
|
|
185
|
+
cost_summary = self.cost_tracker.get_summary()
|
|
186
|
+
|
|
187
|
+
asyncio.create_task(self.queue.put({
|
|
188
|
+
"type": "llm_end",
|
|
189
|
+
"full_response": "".join(self.tokens),
|
|
190
|
+
"tokens": len(self.tokens),
|
|
191
|
+
"cost_summary": cost_summary,
|
|
192
|
+
}))
|
|
193
|
+
|
|
194
|
+
def on_llm_error(self, error: Exception, **kwargs: Any) -> None:
|
|
195
|
+
"""Called when LLM encounters an error"""
|
|
196
|
+
logger.error(f"LLM error: {str(error)}", exc_info=True)
|
|
197
|
+
asyncio.create_task(self.queue.put({
|
|
198
|
+
"type": "error",
|
|
199
|
+
"error": str(error),
|
|
200
|
+
"error_type": type(error).__name__,
|
|
201
|
+
}))
|
|
202
|
+
|
|
203
|
+
def on_tool_start(
|
|
204
|
+
self, serialized: Dict[str, Any], input_str: str, **kwargs: Any
|
|
205
|
+
) -> None:
|
|
206
|
+
"""Called when tool execution starts"""
|
|
207
|
+
tool_name = serialized.get("name", "unknown")
|
|
208
|
+
logger.info(f"Tool '{tool_name}' started")
|
|
209
|
+
asyncio.create_task(self.queue.put({
|
|
210
|
+
"type": "tool_start",
|
|
211
|
+
"tool": tool_name,
|
|
212
|
+
"input": input_str,
|
|
213
|
+
}))
|
|
214
|
+
|
|
215
|
+
def on_tool_end(self, output: str, **kwargs: Any) -> None:
|
|
216
|
+
"""Called when tool execution ends"""
|
|
217
|
+
logger.info("Tool execution completed")
|
|
218
|
+
asyncio.create_task(self.queue.put({
|
|
219
|
+
"type": "tool_end",
|
|
220
|
+
"output": output,
|
|
221
|
+
}))
|
|
222
|
+
|
|
223
|
+
def on_tool_error(self, error: Exception, **kwargs: Any) -> None:
|
|
224
|
+
"""Called when tool encounters an error"""
|
|
225
|
+
logger.error(f"Tool error: {str(error)}", exc_info=True)
|
|
226
|
+
asyncio.create_task(self.queue.put({
|
|
227
|
+
"type": "tool_error",
|
|
228
|
+
"error": str(error),
|
|
229
|
+
"error_type": type(error).__name__,
|
|
230
|
+
}))
|
|
231
|
+
`;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Generate SSE (Server-Sent Events) implementation with cost tracking
|
|
235
|
+
*/
|
|
236
|
+
generateSSE() {
|
|
237
|
+
return `
|
|
238
|
+
|
|
239
|
+
# Server-Sent Events (SSE) Implementation
|
|
240
|
+
|
|
241
|
+
async def stream_sse(
|
|
242
|
+
message: str,
|
|
243
|
+
agent: Any,
|
|
244
|
+
session_id: str = "default",
|
|
245
|
+
cost_tracker: Optional[Any] = None
|
|
246
|
+
) -> AsyncIterator[str]:
|
|
247
|
+
"""
|
|
248
|
+
Stream agent responses via Server-Sent Events with cost tracking
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
message: User message
|
|
252
|
+
agent: LangChain agent instance
|
|
253
|
+
session_id: Session identifier
|
|
254
|
+
cost_tracker: Optional CostTrackingHandler for real-time cost tracking
|
|
255
|
+
|
|
256
|
+
Yields:
|
|
257
|
+
SSE formatted strings with agent response tokens and cost information
|
|
258
|
+
"""
|
|
259
|
+
queue: asyncio.Queue = asyncio.Queue()
|
|
260
|
+
callback_handler = StreamingCallbackHandler(queue, cost_tracker=cost_tracker)
|
|
261
|
+
|
|
262
|
+
try:
|
|
263
|
+
logger.info(f"Starting SSE stream for session: {session_id}")
|
|
264
|
+
|
|
265
|
+
# Send initial connection event
|
|
266
|
+
yield f"data: {json.dumps({'type': 'connected', 'session_id': session_id})}\\n\\n"
|
|
267
|
+
|
|
268
|
+
# Run agent with streaming callback in background
|
|
269
|
+
async def run_agent():
|
|
270
|
+
try:
|
|
271
|
+
result = await agent.arun(
|
|
272
|
+
message,
|
|
273
|
+
callbacks=[callback_handler]
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
# Get final cost summary
|
|
277
|
+
final_cost = {}
|
|
278
|
+
if cost_tracker:
|
|
279
|
+
final_cost = cost_tracker.get_summary()
|
|
280
|
+
|
|
281
|
+
await queue.put({
|
|
282
|
+
"type": "done",
|
|
283
|
+
"result": result,
|
|
284
|
+
"cost_summary": final_cost
|
|
285
|
+
})
|
|
286
|
+
except Exception as e:
|
|
287
|
+
logger.error(f"Agent error: {str(e)}", exc_info=True)
|
|
288
|
+
await queue.put({"type": "error", "error": str(e)})
|
|
289
|
+
|
|
290
|
+
# Start agent execution
|
|
291
|
+
agent_task = asyncio.create_task(run_agent())
|
|
292
|
+
|
|
293
|
+
# Stream events as they come
|
|
294
|
+
while True:
|
|
295
|
+
try:
|
|
296
|
+
# Wait for event with timeout for heartbeat
|
|
297
|
+
event = await asyncio.wait_for(queue.get(), timeout=30.0)
|
|
298
|
+
|
|
299
|
+
# Format as SSE
|
|
300
|
+
yield f"data: {json.dumps(event)}\\n\\n"
|
|
301
|
+
|
|
302
|
+
# End stream on completion or error
|
|
303
|
+
if event["type"] in ["done", "error"]:
|
|
304
|
+
break
|
|
305
|
+
|
|
306
|
+
except asyncio.TimeoutError:
|
|
307
|
+
# Send heartbeat to keep connection alive
|
|
308
|
+
yield f": heartbeat\\n\\n"
|
|
309
|
+
continue
|
|
310
|
+
|
|
311
|
+
# Wait for agent task to complete
|
|
312
|
+
await agent_task
|
|
313
|
+
|
|
314
|
+
logger.info(f"SSE stream completed for session: {session_id}")
|
|
315
|
+
|
|
316
|
+
except asyncio.CancelledError:
|
|
317
|
+
logger.info(f"SSE stream cancelled for session: {session_id}")
|
|
318
|
+
yield f"data: {json.dumps({'type': 'cancelled'})}\\n\\n"
|
|
319
|
+
raise
|
|
320
|
+
except Exception as e:
|
|
321
|
+
logger.error(f"SSE streaming error: {str(e)}", exc_info=True)
|
|
322
|
+
yield f"data: {json.dumps({'type': 'error', 'error': str(e)})}\\n\\n"
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def create_sse_endpoint(agent: Any):
|
|
326
|
+
"""
|
|
327
|
+
Create FastAPI endpoint for SSE streaming with cost tracking
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
agent: LangChain agent instance
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
FastAPI endpoint function
|
|
334
|
+
"""
|
|
335
|
+
async def sse_chat(message: str, session_id: str = "default"):
|
|
336
|
+
"""SSE chat endpoint with real-time cost tracking"""
|
|
337
|
+
# Create cost tracker for this session
|
|
338
|
+
cost_tracker = None
|
|
339
|
+
if COST_TRACKING_AVAILABLE:
|
|
340
|
+
from callbacks import CostTrackingHandler
|
|
341
|
+
cost_tracker = CostTrackingHandler()
|
|
342
|
+
|
|
343
|
+
return StreamingResponse(
|
|
344
|
+
stream_sse(message, agent, session_id, cost_tracker),
|
|
345
|
+
media_type="text/event-stream",
|
|
346
|
+
headers={
|
|
347
|
+
"Cache-Control": "no-cache",
|
|
348
|
+
"Connection": "keep-alive",
|
|
349
|
+
"X-Accel-Buffering": "no", # Disable nginx buffering
|
|
350
|
+
"Access-Control-Allow-Origin": "*",
|
|
351
|
+
}
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
return sse_chat
|
|
355
|
+
`;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Generate WebSocket implementation with cost tracking and backpressure handling
|
|
359
|
+
*/
|
|
360
|
+
generateWebSocket() {
|
|
361
|
+
return `
|
|
362
|
+
|
|
363
|
+
# WebSocket Implementation
|
|
364
|
+
|
|
365
|
+
class ConnectionManager:
|
|
366
|
+
"""
|
|
367
|
+
Manages WebSocket connections for multiple sessions with backpressure handling
|
|
368
|
+
"""
|
|
369
|
+
|
|
370
|
+
def __init__(self):
|
|
371
|
+
"""Initialize connection manager"""
|
|
372
|
+
self.active_connections: Dict[str, WebSocket] = {}
|
|
373
|
+
self.session_queues: Dict[str, asyncio.Queue] = {}
|
|
374
|
+
self.session_tasks: Dict[str, asyncio.Task] = {}
|
|
375
|
+
self.cost_trackers: Dict[str, Any] = {}
|
|
376
|
+
self.max_queue_size = 1000 # Prevent memory issues
|
|
377
|
+
|
|
378
|
+
async def connect(self, websocket: WebSocket, session_id: str):
|
|
379
|
+
"""
|
|
380
|
+
Connect a new WebSocket client
|
|
381
|
+
|
|
382
|
+
Args:
|
|
383
|
+
websocket: WebSocket connection
|
|
384
|
+
session_id: Session identifier
|
|
385
|
+
"""
|
|
386
|
+
await websocket.accept()
|
|
387
|
+
self.active_connections[session_id] = websocket
|
|
388
|
+
self.session_queues[session_id] = asyncio.Queue(maxsize=self.max_queue_size)
|
|
389
|
+
|
|
390
|
+
# Create cost tracker for session
|
|
391
|
+
if COST_TRACKING_AVAILABLE:
|
|
392
|
+
from callbacks import CostTrackingHandler
|
|
393
|
+
self.cost_trackers[session_id] = CostTrackingHandler()
|
|
394
|
+
|
|
395
|
+
logger.info(f"WebSocket connected: {session_id}")
|
|
396
|
+
|
|
397
|
+
# Send welcome message
|
|
398
|
+
await websocket.send_json({
|
|
399
|
+
"type": "connected",
|
|
400
|
+
"session_id": session_id,
|
|
401
|
+
"message": "WebSocket connection established"
|
|
402
|
+
})
|
|
403
|
+
|
|
404
|
+
def disconnect(self, session_id: str):
|
|
405
|
+
"""
|
|
406
|
+
Disconnect a WebSocket client
|
|
407
|
+
|
|
408
|
+
Args:
|
|
409
|
+
session_id: Session identifier
|
|
410
|
+
"""
|
|
411
|
+
# Cancel running tasks
|
|
412
|
+
if session_id in self.session_tasks:
|
|
413
|
+
self.session_tasks[session_id].cancel()
|
|
414
|
+
del self.session_tasks[session_id]
|
|
415
|
+
|
|
416
|
+
if session_id in self.active_connections:
|
|
417
|
+
del self.active_connections[session_id]
|
|
418
|
+
if session_id in self.session_queues:
|
|
419
|
+
del self.session_queues[session_id]
|
|
420
|
+
if session_id in self.cost_trackers:
|
|
421
|
+
del self.cost_trackers[session_id]
|
|
422
|
+
|
|
423
|
+
logger.info(f"WebSocket disconnected: {session_id}")
|
|
424
|
+
|
|
425
|
+
async def send_message(self, session_id: str, message: Dict[str, Any]):
|
|
426
|
+
"""
|
|
427
|
+
Send message to specific session with backpressure handling
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
session_id: Session identifier
|
|
431
|
+
message: Message dictionary
|
|
432
|
+
"""
|
|
433
|
+
if session_id in self.active_connections:
|
|
434
|
+
try:
|
|
435
|
+
# Add timeout to prevent blocking
|
|
436
|
+
await asyncio.wait_for(
|
|
437
|
+
self.active_connections[session_id].send_json(message),
|
|
438
|
+
timeout=5.0
|
|
439
|
+
)
|
|
440
|
+
except asyncio.TimeoutError:
|
|
441
|
+
logger.warning(f"WebSocket send timeout for session: {session_id}")
|
|
442
|
+
self.disconnect(session_id)
|
|
443
|
+
except Exception as e:
|
|
444
|
+
logger.error(f"Error sending WebSocket message: {str(e)}")
|
|
445
|
+
self.disconnect(session_id)
|
|
446
|
+
|
|
447
|
+
async def broadcast(self, message: Dict[str, Any]):
|
|
448
|
+
"""
|
|
449
|
+
Broadcast message to all connected clients
|
|
450
|
+
|
|
451
|
+
Args:
|
|
452
|
+
message: Message dictionary
|
|
453
|
+
"""
|
|
454
|
+
disconnected = []
|
|
455
|
+
for session_id in list(self.active_connections.keys()):
|
|
456
|
+
try:
|
|
457
|
+
await self.send_message(session_id, message)
|
|
458
|
+
except Exception:
|
|
459
|
+
disconnected.append(session_id)
|
|
460
|
+
|
|
461
|
+
# Clean up disconnected sessions
|
|
462
|
+
for session_id in disconnected:
|
|
463
|
+
self.disconnect(session_id)
|
|
464
|
+
|
|
465
|
+
def get_cost_tracker(self, session_id: str) -> Optional[Any]:
|
|
466
|
+
"""Get cost tracker for session"""
|
|
467
|
+
return self.cost_trackers.get(session_id)
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
# Global connection manager
|
|
471
|
+
manager = ConnectionManager()
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
async def stream_websocket(
|
|
475
|
+
websocket: WebSocket,
|
|
476
|
+
agent: Any,
|
|
477
|
+
session_id: str = "default"
|
|
478
|
+
):
|
|
479
|
+
"""
|
|
480
|
+
Stream agent responses via WebSocket with cost tracking and cancellation support
|
|
481
|
+
|
|
482
|
+
Args:
|
|
483
|
+
websocket: WebSocket connection
|
|
484
|
+
agent: LangChain agent instance
|
|
485
|
+
session_id: Session identifier
|
|
486
|
+
"""
|
|
487
|
+
await manager.connect(websocket, session_id)
|
|
488
|
+
current_task = None
|
|
489
|
+
|
|
490
|
+
try:
|
|
491
|
+
while True:
|
|
492
|
+
# Receive message from client
|
|
493
|
+
data = await websocket.receive_json()
|
|
494
|
+
message_type = data.get("type", "message")
|
|
495
|
+
|
|
496
|
+
# Handle cancellation request
|
|
497
|
+
if message_type == "cancel":
|
|
498
|
+
if current_task and not current_task.done():
|
|
499
|
+
current_task.cancel()
|
|
500
|
+
await websocket.send_json({
|
|
501
|
+
"type": "cancelled",
|
|
502
|
+
"message": "Stream cancelled by user"
|
|
503
|
+
})
|
|
504
|
+
continue
|
|
505
|
+
|
|
506
|
+
message = data.get("message", "")
|
|
507
|
+
|
|
508
|
+
if not message:
|
|
509
|
+
await websocket.send_json({
|
|
510
|
+
"type": "error",
|
|
511
|
+
"error": "Empty message"
|
|
512
|
+
})
|
|
513
|
+
continue
|
|
514
|
+
|
|
515
|
+
logger.info(f"WebSocket message received: {session_id}")
|
|
516
|
+
|
|
517
|
+
# Cancel previous task if still running
|
|
518
|
+
if current_task and not current_task.done():
|
|
519
|
+
current_task.cancel()
|
|
520
|
+
|
|
521
|
+
# Get queue and cost tracker
|
|
522
|
+
queue = manager.session_queues[session_id]
|
|
523
|
+
cost_tracker = manager.get_cost_tracker(session_id)
|
|
524
|
+
callback_handler = StreamingCallbackHandler(queue, cost_tracker=cost_tracker)
|
|
525
|
+
|
|
526
|
+
# Run agent with streaming callback
|
|
527
|
+
async def run_agent():
|
|
528
|
+
try:
|
|
529
|
+
result = await agent.arun(
|
|
530
|
+
message,
|
|
531
|
+
callbacks=[callback_handler]
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
# Get final cost summary
|
|
535
|
+
final_cost = {}
|
|
536
|
+
if cost_tracker:
|
|
537
|
+
final_cost = cost_tracker.get_summary()
|
|
538
|
+
|
|
539
|
+
await queue.put({
|
|
540
|
+
"type": "done",
|
|
541
|
+
"result": result,
|
|
542
|
+
"cost_summary": final_cost
|
|
543
|
+
})
|
|
544
|
+
except asyncio.CancelledError:
|
|
545
|
+
await queue.put({"type": "cancelled"})
|
|
546
|
+
raise
|
|
547
|
+
except Exception as e:
|
|
548
|
+
logger.error(f"Agent error: {str(e)}", exc_info=True)
|
|
549
|
+
await queue.put({"type": "error", "error": str(e)})
|
|
550
|
+
|
|
551
|
+
# Start agent execution
|
|
552
|
+
agent_task = asyncio.create_task(run_agent())
|
|
553
|
+
manager.session_tasks[session_id] = agent_task
|
|
554
|
+
|
|
555
|
+
# Stream events as they come
|
|
556
|
+
async def stream_events():
|
|
557
|
+
try:
|
|
558
|
+
while True:
|
|
559
|
+
event = await queue.get()
|
|
560
|
+
await manager.send_message(session_id, event)
|
|
561
|
+
|
|
562
|
+
if event["type"] in ["done", "error", "cancelled"]:
|
|
563
|
+
break
|
|
564
|
+
except asyncio.CancelledError:
|
|
565
|
+
logger.info(f"Event streaming cancelled for: {session_id}")
|
|
566
|
+
raise
|
|
567
|
+
|
|
568
|
+
# Wait for both tasks
|
|
569
|
+
current_task = asyncio.create_task(stream_events())
|
|
570
|
+
await asyncio.gather(agent_task, current_task, return_exceptions=True)
|
|
571
|
+
|
|
572
|
+
except WebSocketDisconnect:
|
|
573
|
+
logger.info(f"WebSocket client disconnected: {session_id}")
|
|
574
|
+
manager.disconnect(session_id)
|
|
575
|
+
except Exception as e:
|
|
576
|
+
logger.error(f"WebSocket error: {str(e)}", exc_info=True)
|
|
577
|
+
manager.disconnect(session_id)
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
def create_websocket_endpoint(agent: Any):
|
|
581
|
+
"""
|
|
582
|
+
Create FastAPI endpoint for WebSocket streaming with cancellation support
|
|
583
|
+
|
|
584
|
+
Args:
|
|
585
|
+
agent: LangChain agent instance
|
|
586
|
+
|
|
587
|
+
Returns:
|
|
588
|
+
FastAPI endpoint function
|
|
589
|
+
"""
|
|
590
|
+
async def websocket_chat(websocket: WebSocket, session_id: str = "default"):
|
|
591
|
+
"""WebSocket chat endpoint with real-time cost tracking and cancellation"""
|
|
592
|
+
await stream_websocket(websocket, agent, session_id)
|
|
593
|
+
|
|
594
|
+
return websocket_chat
|
|
595
|
+
`;
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Generate a2a (agent-to-agent) streaming implementation
|
|
599
|
+
*/
|
|
600
|
+
generateA2A(meshUrl) {
|
|
601
|
+
const url = meshUrl || 'http://localhost:8080';
|
|
602
|
+
return `
|
|
603
|
+
|
|
604
|
+
# Agent-to-Agent (a2a) Streaming Implementation
|
|
605
|
+
|
|
606
|
+
class A2AStreamingClient:
|
|
607
|
+
"""
|
|
608
|
+
Client for streaming agent responses to Agent Mesh
|
|
609
|
+
"""
|
|
610
|
+
|
|
611
|
+
def __init__(self, mesh_url: str = "${url}"):
|
|
612
|
+
"""
|
|
613
|
+
Initialize a2a streaming client
|
|
614
|
+
|
|
615
|
+
Args:
|
|
616
|
+
mesh_url: Agent Mesh URL
|
|
617
|
+
"""
|
|
618
|
+
self.mesh_url = mesh_url
|
|
619
|
+
self.client = httpx.AsyncClient(timeout=30.0)
|
|
620
|
+
|
|
621
|
+
async def stream_to_mesh(
|
|
622
|
+
self,
|
|
623
|
+
agent_id: str,
|
|
624
|
+
message: str,
|
|
625
|
+
queue: asyncio.Queue,
|
|
626
|
+
target_agent: Optional[str] = None
|
|
627
|
+
):
|
|
628
|
+
"""
|
|
629
|
+
Stream agent response to Agent Mesh
|
|
630
|
+
|
|
631
|
+
Args:
|
|
632
|
+
agent_id: Source agent identifier
|
|
633
|
+
message: Message content
|
|
634
|
+
queue: Queue with streaming events
|
|
635
|
+
target_agent: Optional target agent for routing
|
|
636
|
+
"""
|
|
637
|
+
try:
|
|
638
|
+
endpoint = f"{self.mesh_url}/agents/{agent_id}/stream"
|
|
639
|
+
|
|
640
|
+
# Collect streaming events
|
|
641
|
+
events = []
|
|
642
|
+
full_response = ""
|
|
643
|
+
|
|
644
|
+
while True:
|
|
645
|
+
event = await queue.get()
|
|
646
|
+
events.append(event)
|
|
647
|
+
|
|
648
|
+
# Accumulate tokens
|
|
649
|
+
if event["type"] == "token":
|
|
650
|
+
full_response += event["token"]
|
|
651
|
+
|
|
652
|
+
# Send to mesh on completion
|
|
653
|
+
if event["type"] == "done":
|
|
654
|
+
payload = {
|
|
655
|
+
"agent_id": agent_id,
|
|
656
|
+
"message": message,
|
|
657
|
+
"response": full_response,
|
|
658
|
+
"target_agent": target_agent,
|
|
659
|
+
"timestamp": datetime.utcnow().isoformat(),
|
|
660
|
+
"streaming_events": events,
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
response = await self.client.post(endpoint, json=payload)
|
|
664
|
+
response.raise_for_status()
|
|
665
|
+
|
|
666
|
+
logger.info(f"Streamed response to Agent Mesh: {agent_id}")
|
|
667
|
+
break
|
|
668
|
+
|
|
669
|
+
# Stop on error
|
|
670
|
+
if event["type"] == "error":
|
|
671
|
+
logger.error(f"Streaming error: {event['error']}")
|
|
672
|
+
break
|
|
673
|
+
|
|
674
|
+
except Exception as e:
|
|
675
|
+
logger.error(f"a2a streaming error: {str(e)}", exc_info=True)
|
|
676
|
+
|
|
677
|
+
async def close(self):
|
|
678
|
+
"""Close HTTP client"""
|
|
679
|
+
await self.client.aclose()
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
async def stream_a2a(
|
|
683
|
+
agent_id: str,
|
|
684
|
+
message: str,
|
|
685
|
+
agent: Any,
|
|
686
|
+
mesh_url: str = "${url}",
|
|
687
|
+
target_agent: Optional[str] = None
|
|
688
|
+
) -> Dict[str, Any]:
|
|
689
|
+
"""
|
|
690
|
+
Stream agent response with a2a integration
|
|
691
|
+
|
|
692
|
+
Args:
|
|
693
|
+
agent_id: Agent identifier
|
|
694
|
+
message: User message
|
|
695
|
+
agent: LangChain agent instance
|
|
696
|
+
mesh_url: Agent Mesh URL
|
|
697
|
+
target_agent: Optional target agent
|
|
698
|
+
|
|
699
|
+
Returns:
|
|
700
|
+
Agent response with streaming metadata
|
|
701
|
+
"""
|
|
702
|
+
queue: asyncio.Queue = asyncio.Queue()
|
|
703
|
+
callback_handler = StreamingCallbackHandler(queue)
|
|
704
|
+
a2a_client = A2AStreamingClient(mesh_url)
|
|
705
|
+
|
|
706
|
+
try:
|
|
707
|
+
logger.info(f"Starting a2a stream for agent: {agent_id}")
|
|
708
|
+
|
|
709
|
+
# Run agent with streaming callback
|
|
710
|
+
async def run_agent():
|
|
711
|
+
try:
|
|
712
|
+
result = await agent.arun(
|
|
713
|
+
message,
|
|
714
|
+
callbacks=[callback_handler]
|
|
715
|
+
)
|
|
716
|
+
await queue.put({"type": "done", "result": result})
|
|
717
|
+
except Exception as e:
|
|
718
|
+
logger.error(f"Agent error: {str(e)}", exc_info=True)
|
|
719
|
+
await queue.put({"type": "error", "error": str(e)})
|
|
720
|
+
|
|
721
|
+
# Start agent execution and a2a streaming
|
|
722
|
+
agent_task = asyncio.create_task(run_agent())
|
|
723
|
+
mesh_task = asyncio.create_task(
|
|
724
|
+
a2a_client.stream_to_mesh(agent_id, message, queue, target_agent)
|
|
725
|
+
)
|
|
726
|
+
|
|
727
|
+
# Wait for both tasks
|
|
728
|
+
await asyncio.gather(agent_task, mesh_task)
|
|
729
|
+
|
|
730
|
+
logger.info(f"a2a stream completed for agent: {agent_id}")
|
|
731
|
+
|
|
732
|
+
return {
|
|
733
|
+
"success": True,
|
|
734
|
+
"agent_id": agent_id,
|
|
735
|
+
"streamed_to_mesh": True,
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
except Exception as e:
|
|
739
|
+
logger.error(f"a2a streaming error: {str(e)}", exc_info=True)
|
|
740
|
+
return {
|
|
741
|
+
"success": False,
|
|
742
|
+
"error": str(e),
|
|
743
|
+
}
|
|
744
|
+
finally:
|
|
745
|
+
await a2a_client.close()
|
|
746
|
+
`;
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
//# sourceMappingURL=streaming-generator.js.map
|