@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,617 @@
|
|
|
1
|
+
# Production Agent with Streaming Support
|
|
2
|
+
|
|
3
|
+
This example demonstrates a production-quality LangChain agent with comprehensive streaming support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Server-Sent Events (SSE)**: Real-time one-way streaming from server to client
|
|
8
|
+
- **WebSocket**: Bidirectional communication for interactive streaming with cancellation support
|
|
9
|
+
- **Agent-to-Agent (a2a)**: Integration with Agent Mesh for multi-agent streaming
|
|
10
|
+
- **Token-by-Token**: Real LangChain streaming callbacks for progressive responses
|
|
11
|
+
- **Tool Streaming**: Real-time updates during tool execution
|
|
12
|
+
- **Cost Tracking**: Real-time per-token cost tracking integrated with streaming callbacks
|
|
13
|
+
- **Backpressure Handling**: Prevents memory issues with queue size limits and timeouts
|
|
14
|
+
- **Stream Cancellation**: Cancel long-running agent executions via WebSocket
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
### 1. Export the Agent
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Export to LangChain with streaming enabled
|
|
22
|
+
ossa export agent.ossa.yaml --target langchain --output ./agent
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The exporter will automatically generate `streaming.py` with all streaming implementations.
|
|
26
|
+
|
|
27
|
+
### 2. Install Dependencies
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cd agent
|
|
31
|
+
pip install -r requirements.txt
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Dependencies include:
|
|
35
|
+
- `fastapi` - Web framework
|
|
36
|
+
- `uvicorn` - ASGI server
|
|
37
|
+
- `sse-starlette` - Server-Sent Events support
|
|
38
|
+
- `websockets` - WebSocket support
|
|
39
|
+
- `langchain` - Agent framework
|
|
40
|
+
|
|
41
|
+
### 3. Configure Environment
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
cp .env.example .env
|
|
45
|
+
# Edit .env with your API keys and configuration
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Required environment variables:
|
|
49
|
+
```env
|
|
50
|
+
OPENAI_API_KEY=sk-...
|
|
51
|
+
REDIS_HOST=localhost
|
|
52
|
+
REDIS_PORT=6379
|
|
53
|
+
AGENT_MESH_URL=http://localhost:8080 # Optional: for a2a streaming
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 4. Start the Server
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
uvicorn server:app --host 0.0.0.0 --port 8000 --reload
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Usage Examples
|
|
63
|
+
|
|
64
|
+
### Server-Sent Events (SSE)
|
|
65
|
+
|
|
66
|
+
SSE is perfect for one-way streaming from server to client (like chat completions).
|
|
67
|
+
|
|
68
|
+
**JavaScript Client:**
|
|
69
|
+
|
|
70
|
+
```javascript
|
|
71
|
+
const eventSource = new EventSource(
|
|
72
|
+
'http://localhost:8000/chat/stream?message=Hello&session_id=user123'
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
eventSource.onmessage = (event) => {
|
|
76
|
+
const data = JSON.parse(event.data);
|
|
77
|
+
|
|
78
|
+
switch (data.type) {
|
|
79
|
+
case 'connected':
|
|
80
|
+
console.log(`Connected: ${data.session_id}`);
|
|
81
|
+
break;
|
|
82
|
+
|
|
83
|
+
case 'llm_start':
|
|
84
|
+
console.log(`LLM generation started: ${data.model}`);
|
|
85
|
+
break;
|
|
86
|
+
|
|
87
|
+
case 'token':
|
|
88
|
+
// Append token to UI in real-time with cost tracking
|
|
89
|
+
process.stdout.write(data.token);
|
|
90
|
+
console.log(`\nTokens: ${data.token_count}, Cost: $${data.cost.toFixed(6)}`);
|
|
91
|
+
break;
|
|
92
|
+
|
|
93
|
+
case 'tool_start':
|
|
94
|
+
console.log(`\nTool started: ${data.tool}`);
|
|
95
|
+
break;
|
|
96
|
+
|
|
97
|
+
case 'tool_end':
|
|
98
|
+
console.log(`Tool completed: ${data.output}`);
|
|
99
|
+
break;
|
|
100
|
+
|
|
101
|
+
case 'llm_end':
|
|
102
|
+
console.log(`\n\nLLM Complete: ${data.full_response}`);
|
|
103
|
+
console.log(`Total tokens: ${data.tokens}`);
|
|
104
|
+
if (data.cost_summary) {
|
|
105
|
+
console.log(`Cost: $${data.cost_summary.total_cost.toFixed(6)}`);
|
|
106
|
+
}
|
|
107
|
+
break;
|
|
108
|
+
|
|
109
|
+
case 'done':
|
|
110
|
+
console.log(`\n\nComplete: ${data.result}`);
|
|
111
|
+
if (data.cost_summary) {
|
|
112
|
+
console.log(`Final Cost: $${data.cost_summary.total_cost.toFixed(6)}`);
|
|
113
|
+
console.log(`Tokens: ${data.cost_summary.total_tokens}`);
|
|
114
|
+
}
|
|
115
|
+
eventSource.close();
|
|
116
|
+
break;
|
|
117
|
+
|
|
118
|
+
case 'error':
|
|
119
|
+
console.error('Error:', data.error);
|
|
120
|
+
eventSource.close();
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
eventSource.onerror = (error) => {
|
|
126
|
+
console.error('SSE Error:', error);
|
|
127
|
+
eventSource.close();
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Python Client:**
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import httpx
|
|
135
|
+
import json
|
|
136
|
+
|
|
137
|
+
async def stream_chat_sse(message: str):
|
|
138
|
+
async with httpx.AsyncClient() as client:
|
|
139
|
+
async with client.stream(
|
|
140
|
+
'GET',
|
|
141
|
+
'http://localhost:8000/chat/stream',
|
|
142
|
+
params={'message': message, 'session_id': 'user123'}
|
|
143
|
+
) as response:
|
|
144
|
+
async for line in response.aiter_lines():
|
|
145
|
+
if line.startswith('data: '):
|
|
146
|
+
data = json.loads(line[6:])
|
|
147
|
+
|
|
148
|
+
if data['type'] == 'token':
|
|
149
|
+
print(data['token'], end='', flush=True)
|
|
150
|
+
elif data['type'] == 'done':
|
|
151
|
+
print(f"\n\nComplete: {data['result']}")
|
|
152
|
+
break
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### WebSocket Streaming
|
|
156
|
+
|
|
157
|
+
WebSocket enables bidirectional communication for interactive conversations.
|
|
158
|
+
|
|
159
|
+
**JavaScript Client:**
|
|
160
|
+
|
|
161
|
+
```javascript
|
|
162
|
+
const ws = new WebSocket('ws://localhost:8000/ws?session_id=user123');
|
|
163
|
+
|
|
164
|
+
ws.onopen = () => {
|
|
165
|
+
console.log('WebSocket connected');
|
|
166
|
+
|
|
167
|
+
// Send message
|
|
168
|
+
ws.send(JSON.stringify({
|
|
169
|
+
type: 'message',
|
|
170
|
+
message: 'Hello, how can you help me?'
|
|
171
|
+
}));
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
ws.onmessage = (event) => {
|
|
175
|
+
const data = JSON.parse(event.data);
|
|
176
|
+
|
|
177
|
+
switch (data.type) {
|
|
178
|
+
case 'connected':
|
|
179
|
+
console.log(`Session established: ${data.session_id}`);
|
|
180
|
+
break;
|
|
181
|
+
|
|
182
|
+
case 'token':
|
|
183
|
+
// Real-time token with cost tracking
|
|
184
|
+
process.stdout.write(data.token);
|
|
185
|
+
if (data.cost && data.token_count % 10 === 0) {
|
|
186
|
+
console.log(`\n[${data.token_count} tokens, $${data.cost.toFixed(6)}]`);
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
|
|
190
|
+
case 'tool_start':
|
|
191
|
+
console.log(`\nExecuting tool: ${data.tool}`);
|
|
192
|
+
break;
|
|
193
|
+
|
|
194
|
+
case 'done':
|
|
195
|
+
console.log(`\n\nComplete: ${data.result}`);
|
|
196
|
+
if (data.cost_summary) {
|
|
197
|
+
console.log(`\nCost Summary:`);
|
|
198
|
+
console.log(` Total Tokens: ${data.cost_summary.total_tokens}`);
|
|
199
|
+
console.log(` Total Cost: $${data.cost_summary.total_cost.toFixed(6)}`);
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
|
|
203
|
+
case 'cancelled':
|
|
204
|
+
console.log('Stream cancelled by request');
|
|
205
|
+
break;
|
|
206
|
+
|
|
207
|
+
case 'error':
|
|
208
|
+
console.error('Error:', data.error);
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// Cancel stream button
|
|
214
|
+
document.getElementById('cancelButton').onclick = () => {
|
|
215
|
+
ws.send(JSON.stringify({ type: 'cancel' }));
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
ws.onerror = (error) => {
|
|
219
|
+
console.error('WebSocket error:', error);
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
ws.onclose = () => {
|
|
223
|
+
console.log('WebSocket disconnected');
|
|
224
|
+
};
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Python Client:**
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
import asyncio
|
|
231
|
+
import websockets
|
|
232
|
+
import json
|
|
233
|
+
|
|
234
|
+
async def chat_websocket():
|
|
235
|
+
uri = "ws://localhost:8000/ws?session_id=user123"
|
|
236
|
+
|
|
237
|
+
async with websockets.connect(uri) as websocket:
|
|
238
|
+
# Send message
|
|
239
|
+
await websocket.send(json.dumps({
|
|
240
|
+
"message": "Hello, how can you help me?"
|
|
241
|
+
}))
|
|
242
|
+
|
|
243
|
+
# Receive streaming response
|
|
244
|
+
while True:
|
|
245
|
+
response = await websocket.recv()
|
|
246
|
+
data = json.loads(response)
|
|
247
|
+
|
|
248
|
+
if data['type'] == 'token':
|
|
249
|
+
print(data['token'], end='', flush=True)
|
|
250
|
+
elif data['type'] == 'done':
|
|
251
|
+
print(f"\n\nComplete: {data['result']}")
|
|
252
|
+
break
|
|
253
|
+
elif data['type'] == 'error':
|
|
254
|
+
print(f"Error: {data['error']}")
|
|
255
|
+
break
|
|
256
|
+
|
|
257
|
+
asyncio.run(chat_websocket())
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Agent-to-Agent (a2a) Streaming
|
|
261
|
+
|
|
262
|
+
The a2a implementation automatically streams responses to the Agent Mesh for multi-agent coordination.
|
|
263
|
+
|
|
264
|
+
**Python Usage:**
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
from streaming import stream_a2a
|
|
268
|
+
from agent import create_agent
|
|
269
|
+
|
|
270
|
+
async def main():
|
|
271
|
+
agent = create_agent()
|
|
272
|
+
|
|
273
|
+
result = await stream_a2a(
|
|
274
|
+
agent_id="production-streaming-agent",
|
|
275
|
+
message="Analyze this data",
|
|
276
|
+
agent=agent,
|
|
277
|
+
mesh_url="http://localhost:8080",
|
|
278
|
+
target_agent="data-analyzer" # Optional: route to specific agent
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
print(f"Streamed to mesh: {result['success']}")
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
The a2a client will:
|
|
285
|
+
1. Collect all streaming events (tokens, tool calls)
|
|
286
|
+
2. Accumulate the full response
|
|
287
|
+
3. Post to Agent Mesh with complete metadata
|
|
288
|
+
4. Include streaming events for replay/analysis
|
|
289
|
+
|
|
290
|
+
## Event Types
|
|
291
|
+
|
|
292
|
+
All streaming implementations emit these event types:
|
|
293
|
+
|
|
294
|
+
| Event Type | Description | Fields |
|
|
295
|
+
|------------|-------------|--------|
|
|
296
|
+
| `connected` | Connection established | `session_id`, `message` |
|
|
297
|
+
| `llm_start` | LLM generation started | `prompts`, `model` |
|
|
298
|
+
| `token` | New token generated | `token`, `token_count`, `cost` |
|
|
299
|
+
| `llm_end` | LLM generation completed | `full_response`, `tokens`, `cost_summary` |
|
|
300
|
+
| `tool_start` | Tool execution started | `tool`, `input` |
|
|
301
|
+
| `tool_end` | Tool execution completed | `output` |
|
|
302
|
+
| `tool_error` | Tool execution failed | `error`, `error_type` |
|
|
303
|
+
| `error` | LLM error occurred | `error`, `error_type` |
|
|
304
|
+
| `cancelled` | Stream cancelled by user | - |
|
|
305
|
+
| `done` | Complete response ready | `result`, `cost_summary` |
|
|
306
|
+
|
|
307
|
+
### Cost Summary Object
|
|
308
|
+
|
|
309
|
+
```json
|
|
310
|
+
{
|
|
311
|
+
"total_tokens": 150,
|
|
312
|
+
"prompt_tokens": 50,
|
|
313
|
+
"completion_tokens": 100,
|
|
314
|
+
"total_cost": 0.000450,
|
|
315
|
+
"model": "gpt-4"
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Customization
|
|
320
|
+
|
|
321
|
+
### Disable Specific Streaming Methods
|
|
322
|
+
|
|
323
|
+
```yaml
|
|
324
|
+
# In agent.ossa.yaml
|
|
325
|
+
spec:
|
|
326
|
+
streaming:
|
|
327
|
+
sse:
|
|
328
|
+
enabled: false # Disable SSE
|
|
329
|
+
websocket:
|
|
330
|
+
enabled: true # Keep WebSocket
|
|
331
|
+
a2a:
|
|
332
|
+
enabled: false # Disable a2a
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Custom Endpoints
|
|
336
|
+
|
|
337
|
+
```yaml
|
|
338
|
+
spec:
|
|
339
|
+
streaming:
|
|
340
|
+
sse:
|
|
341
|
+
enabled: true
|
|
342
|
+
endpoint: /api/stream # Custom SSE endpoint
|
|
343
|
+
|
|
344
|
+
websocket:
|
|
345
|
+
enabled: true
|
|
346
|
+
endpoint: /chat # Custom WebSocket endpoint
|
|
347
|
+
port: 9000 # Custom port
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### Selective Callbacks
|
|
351
|
+
|
|
352
|
+
```yaml
|
|
353
|
+
spec:
|
|
354
|
+
streaming:
|
|
355
|
+
callbacks:
|
|
356
|
+
on_llm_start: true
|
|
357
|
+
on_llm_new_token: true # Token-by-token streaming
|
|
358
|
+
on_llm_end: true
|
|
359
|
+
on_tool_start: false # Disable tool start events
|
|
360
|
+
on_tool_end: false # Disable tool end events
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Advanced Features
|
|
364
|
+
|
|
365
|
+
### Real-Time Cost Tracking
|
|
366
|
+
|
|
367
|
+
Every streaming event includes cost information:
|
|
368
|
+
|
|
369
|
+
```python
|
|
370
|
+
# In streaming.py
|
|
371
|
+
class StreamingCallbackHandler(BaseCallbackHandler):
|
|
372
|
+
def on_llm_new_token(self, token: str, **kwargs):
|
|
373
|
+
# Track cost per token
|
|
374
|
+
current_cost = self.cost_tracker.total_cost if self.cost_tracker else 0.0
|
|
375
|
+
|
|
376
|
+
await self.queue.put({
|
|
377
|
+
"type": "token",
|
|
378
|
+
"token": token,
|
|
379
|
+
"token_count": self.token_count,
|
|
380
|
+
"cost": current_cost # Real-time cost
|
|
381
|
+
})
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**Client-Side Cost Display:**
|
|
385
|
+
|
|
386
|
+
```javascript
|
|
387
|
+
let totalCost = 0;
|
|
388
|
+
|
|
389
|
+
eventSource.onmessage = (event) => {
|
|
390
|
+
const data = JSON.parse(event.data);
|
|
391
|
+
|
|
392
|
+
if (data.type === 'token') {
|
|
393
|
+
totalCost = data.cost;
|
|
394
|
+
document.getElementById('cost').textContent = `$${totalCost.toFixed(6)}`;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Stream Cancellation (WebSocket Only)
|
|
400
|
+
|
|
401
|
+
Cancel long-running agent executions:
|
|
402
|
+
|
|
403
|
+
```javascript
|
|
404
|
+
// Client sends cancel request
|
|
405
|
+
ws.send(JSON.stringify({ type: 'cancel' }));
|
|
406
|
+
|
|
407
|
+
// Server cancels agent task and responds
|
|
408
|
+
ws.onmessage = (event) => {
|
|
409
|
+
const data = JSON.parse(event.data);
|
|
410
|
+
|
|
411
|
+
if (data.type === 'cancelled') {
|
|
412
|
+
console.log('Stream cancelled successfully');
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**Python Implementation:**
|
|
418
|
+
|
|
419
|
+
```python
|
|
420
|
+
# In streaming.py - ConnectionManager
|
|
421
|
+
async def stream_websocket(websocket, agent, session_id):
|
|
422
|
+
current_task = None
|
|
423
|
+
|
|
424
|
+
while True:
|
|
425
|
+
data = await websocket.receive_json()
|
|
426
|
+
|
|
427
|
+
# Handle cancellation
|
|
428
|
+
if data.get("type") == "cancel":
|
|
429
|
+
if current_task and not current_task.done():
|
|
430
|
+
current_task.cancel()
|
|
431
|
+
await websocket.send_json({
|
|
432
|
+
"type": "cancelled",
|
|
433
|
+
"message": "Stream cancelled by user"
|
|
434
|
+
})
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Backpressure Handling
|
|
438
|
+
|
|
439
|
+
Prevents memory issues with queue size limits:
|
|
440
|
+
|
|
441
|
+
```python
|
|
442
|
+
# In streaming.py
|
|
443
|
+
class ConnectionManager:
|
|
444
|
+
def __init__(self):
|
|
445
|
+
self.max_queue_size = 1000 # Prevent memory issues
|
|
446
|
+
|
|
447
|
+
async def connect(self, websocket, session_id):
|
|
448
|
+
self.session_queues[session_id] = asyncio.Queue(
|
|
449
|
+
maxsize=self.max_queue_size
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
async def send_message(self, session_id, message):
|
|
453
|
+
# Add timeout to prevent blocking
|
|
454
|
+
await asyncio.wait_for(
|
|
455
|
+
self.active_connections[session_id].send_json(message),
|
|
456
|
+
timeout=5.0
|
|
457
|
+
)
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Connection Timeout & Heartbeat
|
|
461
|
+
|
|
462
|
+
SSE streams include heartbeat to keep connections alive:
|
|
463
|
+
|
|
464
|
+
```python
|
|
465
|
+
# In streaming.py
|
|
466
|
+
async def stream_sse(...):
|
|
467
|
+
while True:
|
|
468
|
+
try:
|
|
469
|
+
# Wait with timeout for heartbeat
|
|
470
|
+
event = await asyncio.wait_for(queue.get(), timeout=30.0)
|
|
471
|
+
yield f"data: {json.dumps(event)}\n\n"
|
|
472
|
+
|
|
473
|
+
except asyncio.TimeoutError:
|
|
474
|
+
# Send heartbeat
|
|
475
|
+
yield ": heartbeat\n\n"
|
|
476
|
+
continue
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
## Architecture
|
|
480
|
+
|
|
481
|
+
### LangChain Streaming Callbacks with Cost Integration
|
|
482
|
+
|
|
483
|
+
The `StreamingCallbackHandler` class hooks into LangChain's callback system with cost tracking:
|
|
484
|
+
|
|
485
|
+
```python
|
|
486
|
+
class StreamingCallbackHandler(BaseCallbackHandler):
|
|
487
|
+
def __init__(self, queue: asyncio.Queue, cost_tracker: Optional[Any] = None):
|
|
488
|
+
self.queue = queue
|
|
489
|
+
self.cost_tracker = cost_tracker
|
|
490
|
+
self.token_count = 0
|
|
491
|
+
|
|
492
|
+
def on_llm_new_token(self, token: str, **kwargs):
|
|
493
|
+
# Called for EACH token generated
|
|
494
|
+
self.token_count += 1
|
|
495
|
+
|
|
496
|
+
# Get current cost
|
|
497
|
+
current_cost = self.cost_tracker.total_cost if self.cost_tracker else 0.0
|
|
498
|
+
|
|
499
|
+
asyncio.create_task(self.queue.put({
|
|
500
|
+
"type": "token",
|
|
501
|
+
"token": token,
|
|
502
|
+
"token_count": self.token_count,
|
|
503
|
+
"cost": current_cost, # Real-time cost tracking
|
|
504
|
+
}))
|
|
505
|
+
|
|
506
|
+
def on_llm_end(self, response: LLMResult, **kwargs):
|
|
507
|
+
# Calculate final cost from token usage
|
|
508
|
+
if self.cost_tracker and response.llm_output:
|
|
509
|
+
token_usage = response.llm_output.get("token_usage", {})
|
|
510
|
+
# Update tracker with actual usage
|
|
511
|
+
self.cost_tracker.prompt_tokens += token_usage.get("prompt_tokens", 0)
|
|
512
|
+
self.cost_tracker.completion_tokens += token_usage.get("completion_tokens", 0)
|
|
513
|
+
# Calculate cost based on model pricing
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
This provides **real token-by-token streaming with per-token cost tracking** (not word-splitting simulation).
|
|
517
|
+
|
|
518
|
+
### Connection Management
|
|
519
|
+
|
|
520
|
+
WebSocket connections are managed by `ConnectionManager`:
|
|
521
|
+
|
|
522
|
+
```python
|
|
523
|
+
manager = ConnectionManager()
|
|
524
|
+
|
|
525
|
+
# Multiple concurrent sessions
|
|
526
|
+
await manager.connect(websocket, "user123")
|
|
527
|
+
await manager.connect(websocket2, "user456")
|
|
528
|
+
|
|
529
|
+
# Broadcast or send to specific session
|
|
530
|
+
await manager.send_message("user123", event)
|
|
531
|
+
await manager.broadcast(event)
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Error Handling
|
|
535
|
+
|
|
536
|
+
All streaming implementations include:
|
|
537
|
+
- Try/catch blocks around agent execution
|
|
538
|
+
- Automatic cleanup on errors
|
|
539
|
+
- Error events sent to clients
|
|
540
|
+
- Graceful disconnection handling
|
|
541
|
+
|
|
542
|
+
## Performance
|
|
543
|
+
|
|
544
|
+
### SSE
|
|
545
|
+
- **Latency**: ~10-50ms per token
|
|
546
|
+
- **Connections**: 100+ concurrent
|
|
547
|
+
- **Best for**: One-way streaming, mobile clients
|
|
548
|
+
|
|
549
|
+
### WebSocket
|
|
550
|
+
- **Latency**: ~5-20ms per token
|
|
551
|
+
- **Connections**: 1000+ concurrent
|
|
552
|
+
- **Best for**: Interactive chat, bidirectional
|
|
553
|
+
|
|
554
|
+
### a2a
|
|
555
|
+
- **Latency**: Depends on mesh
|
|
556
|
+
- **Connections**: Agent-to-agent only
|
|
557
|
+
- **Best for**: Multi-agent orchestration
|
|
558
|
+
|
|
559
|
+
## Troubleshooting
|
|
560
|
+
|
|
561
|
+
### SSE Connection Drops
|
|
562
|
+
|
|
563
|
+
If SSE connections drop frequently:
|
|
564
|
+
|
|
565
|
+
```python
|
|
566
|
+
# Add keep-alive pings
|
|
567
|
+
yield ":\n\n" # Comment-only SSE event (keep-alive)
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### WebSocket Reconnection
|
|
571
|
+
|
|
572
|
+
```javascript
|
|
573
|
+
let reconnectAttempts = 0;
|
|
574
|
+
const maxReconnect = 5;
|
|
575
|
+
|
|
576
|
+
function connectWebSocket() {
|
|
577
|
+
const ws = new WebSocket('ws://localhost:8000/ws?session_id=user123');
|
|
578
|
+
|
|
579
|
+
ws.onclose = () => {
|
|
580
|
+
if (reconnectAttempts < maxReconnect) {
|
|
581
|
+
reconnectAttempts++;
|
|
582
|
+
setTimeout(connectWebSocket, 1000 * reconnectAttempts);
|
|
583
|
+
}
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
### Memory Leaks
|
|
589
|
+
|
|
590
|
+
Ensure proper cleanup:
|
|
591
|
+
|
|
592
|
+
```python
|
|
593
|
+
# Always close connections
|
|
594
|
+
try:
|
|
595
|
+
await stream_websocket(websocket, agent, session_id)
|
|
596
|
+
finally:
|
|
597
|
+
manager.disconnect(session_id)
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
## Production Considerations
|
|
601
|
+
|
|
602
|
+
1. **Rate Limiting**: Use `api.rate_limit` in manifest
|
|
603
|
+
2. **CORS**: Configure `api.cors.origins` for web clients
|
|
604
|
+
3. **Authentication**: Add auth middleware in `server.py`
|
|
605
|
+
4. **Monitoring**: Log all streaming events for debugging
|
|
606
|
+
5. **Scaling**: Use Redis for session state across instances
|
|
607
|
+
|
|
608
|
+
## Next Steps
|
|
609
|
+
|
|
610
|
+
- [LangChain Streaming Docs](https://python.langchain.com/docs/modules/callbacks/)
|
|
611
|
+
- [FastAPI WebSocket Guide](https://fastapi.tiangolo.com/advanced/websockets/)
|
|
612
|
+
- [SSE Specification](https://html.spec.whatwg.org/multipage/server-sent-events.html)
|
|
613
|
+
- [Agent Mesh Documentation](https://github.com/blueflyio/agent-mesh)
|
|
614
|
+
|
|
615
|
+
## License
|
|
616
|
+
|
|
617
|
+
MIT - See LICENSE file for details
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
ossaVersion: 0.4.1
|
|
2
|
+
kind: Agent
|
|
3
|
+
metadata:
|
|
4
|
+
name: production-streaming-agent
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
description: Production-quality agent with full streaming support (SSE, WebSocket, a2a)
|
|
7
|
+
author: OSSA Team
|
|
8
|
+
license: MIT
|
|
9
|
+
tags:
|
|
10
|
+
- streaming
|
|
11
|
+
- production
|
|
12
|
+
- sse
|
|
13
|
+
- websocket
|
|
14
|
+
- a2a
|
|
15
|
+
|
|
16
|
+
spec:
|
|
17
|
+
role: |
|
|
18
|
+
You are a production streaming agent that demonstrates real-time response streaming.
|
|
19
|
+
|
|
20
|
+
Capabilities:
|
|
21
|
+
- Server-Sent Events (SSE) for one-way streaming
|
|
22
|
+
- WebSocket bidirectional communication
|
|
23
|
+
- Agent-to-agent (a2a) streaming integration
|
|
24
|
+
- Token-by-token streaming responses
|
|
25
|
+
- Real-time tool execution updates
|
|
26
|
+
|
|
27
|
+
llm:
|
|
28
|
+
provider: openai
|
|
29
|
+
model: gpt-4-turbo-preview
|
|
30
|
+
temperature: 0.7
|
|
31
|
+
max_tokens: 2000
|
|
32
|
+
|
|
33
|
+
tools:
|
|
34
|
+
- name: search_web
|
|
35
|
+
type: function
|
|
36
|
+
description: Search the web for information
|
|
37
|
+
input_schema:
|
|
38
|
+
type: object
|
|
39
|
+
properties:
|
|
40
|
+
query:
|
|
41
|
+
type: string
|
|
42
|
+
description: Search query
|
|
43
|
+
required:
|
|
44
|
+
- query
|
|
45
|
+
|
|
46
|
+
- name: analyze_data
|
|
47
|
+
type: function
|
|
48
|
+
description: Analyze data and return insights
|
|
49
|
+
input_schema:
|
|
50
|
+
type: object
|
|
51
|
+
properties:
|
|
52
|
+
data:
|
|
53
|
+
type: string
|
|
54
|
+
description: Data to analyze
|
|
55
|
+
required:
|
|
56
|
+
- data
|
|
57
|
+
|
|
58
|
+
memory:
|
|
59
|
+
type: redis
|
|
60
|
+
config:
|
|
61
|
+
host: ${REDIS_HOST:localhost}
|
|
62
|
+
port: ${REDIS_PORT:6379}
|
|
63
|
+
db: 0
|
|
64
|
+
session_ttl: 3600
|
|
65
|
+
|
|
66
|
+
streaming:
|
|
67
|
+
# Server-Sent Events (SSE) Configuration
|
|
68
|
+
sse:
|
|
69
|
+
enabled: true
|
|
70
|
+
endpoint: /chat/stream
|
|
71
|
+
|
|
72
|
+
# WebSocket Configuration
|
|
73
|
+
websocket:
|
|
74
|
+
enabled: true
|
|
75
|
+
endpoint: /ws
|
|
76
|
+
port: 8000
|
|
77
|
+
|
|
78
|
+
# Agent-to-Agent (a2a) Streaming
|
|
79
|
+
a2a:
|
|
80
|
+
enabled: true
|
|
81
|
+
mesh_url: ${AGENT_MESH_URL:http://localhost:8080}
|
|
82
|
+
|
|
83
|
+
# LangChain Callbacks
|
|
84
|
+
callbacks:
|
|
85
|
+
on_llm_start: true
|
|
86
|
+
on_llm_new_token: true
|
|
87
|
+
on_llm_end: true
|
|
88
|
+
on_tool_start: true
|
|
89
|
+
on_tool_end: true
|
|
90
|
+
|
|
91
|
+
api:
|
|
92
|
+
port: 8000
|
|
93
|
+
cors:
|
|
94
|
+
enabled: true
|
|
95
|
+
origins:
|
|
96
|
+
- http://localhost:3000
|
|
97
|
+
- http://localhost:8080
|
|
98
|
+
rate_limit:
|
|
99
|
+
enabled: true
|
|
100
|
+
requests_per_minute: 60
|