agentic-qe 3.3.5 → 3.4.1
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/.claude/helpers/statusline-v3.cjs +47 -0
- package/.claude/skills/qcsd-ideation-swarm/SKILL.md +7 -4
- package/CHANGELOG.md +23 -0
- package/README.md +69 -0
- package/package.json +1 -1
- package/v3/CHANGELOG.md +91 -0
- package/v3/README.md +117 -0
- package/v3/assets/skills/qcsd-ideation-swarm/SKILL.md +7 -4
- package/v3/dist/adapters/a2a/agent-cards/generator.d.ts +153 -0
- package/v3/dist/adapters/a2a/agent-cards/generator.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/agent-cards/generator.js +478 -0
- package/v3/dist/adapters/a2a/agent-cards/generator.js.map +1 -0
- package/v3/dist/adapters/a2a/agent-cards/schema.d.ts +274 -0
- package/v3/dist/adapters/a2a/agent-cards/schema.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/agent-cards/schema.js +135 -0
- package/v3/dist/adapters/a2a/agent-cards/schema.js.map +1 -0
- package/v3/dist/adapters/a2a/agent-cards/validator.d.ts +514 -0
- package/v3/dist/adapters/a2a/agent-cards/validator.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/agent-cards/validator.js +555 -0
- package/v3/dist/adapters/a2a/agent-cards/validator.js.map +1 -0
- package/v3/dist/adapters/a2a/auth/index.d.ts +23 -0
- package/v3/dist/adapters/a2a/auth/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/auth/index.js +85 -0
- package/v3/dist/adapters/a2a/auth/index.js.map +1 -0
- package/v3/dist/adapters/a2a/auth/jwt-utils.d.ts +215 -0
- package/v3/dist/adapters/a2a/auth/jwt-utils.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/auth/jwt-utils.js +314 -0
- package/v3/dist/adapters/a2a/auth/jwt-utils.js.map +1 -0
- package/v3/dist/adapters/a2a/auth/middleware.d.ts +173 -0
- package/v3/dist/adapters/a2a/auth/middleware.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/auth/middleware.js +300 -0
- package/v3/dist/adapters/a2a/auth/middleware.js.map +1 -0
- package/v3/dist/adapters/a2a/auth/oauth-provider.d.ts +308 -0
- package/v3/dist/adapters/a2a/auth/oauth-provider.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/auth/oauth-provider.js +573 -0
- package/v3/dist/adapters/a2a/auth/oauth-provider.js.map +1 -0
- package/v3/dist/adapters/a2a/auth/routes.d.ts +244 -0
- package/v3/dist/adapters/a2a/auth/routes.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/auth/routes.js +496 -0
- package/v3/dist/adapters/a2a/auth/routes.js.map +1 -0
- package/v3/dist/adapters/a2a/auth/scopes.d.ts +219 -0
- package/v3/dist/adapters/a2a/auth/scopes.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/auth/scopes.js +292 -0
- package/v3/dist/adapters/a2a/auth/scopes.js.map +1 -0
- package/v3/dist/adapters/a2a/auth/token-store.d.ts +278 -0
- package/v3/dist/adapters/a2a/auth/token-store.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/auth/token-store.js +453 -0
- package/v3/dist/adapters/a2a/auth/token-store.js.map +1 -0
- package/v3/dist/adapters/a2a/discovery/agent-health.d.ts +226 -0
- package/v3/dist/adapters/a2a/discovery/agent-health.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/discovery/agent-health.js +426 -0
- package/v3/dist/adapters/a2a/discovery/agent-health.js.map +1 -0
- package/v3/dist/adapters/a2a/discovery/discovery-service.d.ts +296 -0
- package/v3/dist/adapters/a2a/discovery/discovery-service.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/discovery/discovery-service.js +520 -0
- package/v3/dist/adapters/a2a/discovery/discovery-service.js.map +1 -0
- package/v3/dist/adapters/a2a/discovery/file-watcher.d.ts +166 -0
- package/v3/dist/adapters/a2a/discovery/file-watcher.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/discovery/file-watcher.js +385 -0
- package/v3/dist/adapters/a2a/discovery/file-watcher.js.map +1 -0
- package/v3/dist/adapters/a2a/discovery/hot-reload-service.d.ts +226 -0
- package/v3/dist/adapters/a2a/discovery/hot-reload-service.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/discovery/hot-reload-service.js +433 -0
- package/v3/dist/adapters/a2a/discovery/hot-reload-service.js.map +1 -0
- package/v3/dist/adapters/a2a/discovery/index.d.ts +18 -0
- package/v3/dist/adapters/a2a/discovery/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/discovery/index.js +54 -0
- package/v3/dist/adapters/a2a/discovery/index.js.map +1 -0
- package/v3/dist/adapters/a2a/discovery/metrics.d.ts +200 -0
- package/v3/dist/adapters/a2a/discovery/metrics.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/discovery/metrics.js +371 -0
- package/v3/dist/adapters/a2a/discovery/metrics.js.map +1 -0
- package/v3/dist/adapters/a2a/discovery/routes.d.ts +184 -0
- package/v3/dist/adapters/a2a/discovery/routes.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/discovery/routes.js +453 -0
- package/v3/dist/adapters/a2a/discovery/routes.js.map +1 -0
- package/v3/dist/adapters/a2a/index.d.ts +18 -0
- package/v3/dist/adapters/a2a/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/index.js +139 -0
- package/v3/dist/adapters/a2a/index.js.map +1 -0
- package/v3/dist/adapters/a2a/jsonrpc/envelope.d.ts +312 -0
- package/v3/dist/adapters/a2a/jsonrpc/envelope.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/jsonrpc/envelope.js +554 -0
- package/v3/dist/adapters/a2a/jsonrpc/envelope.js.map +1 -0
- package/v3/dist/adapters/a2a/jsonrpc/errors.d.ts +244 -0
- package/v3/dist/adapters/a2a/jsonrpc/errors.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/jsonrpc/errors.js +365 -0
- package/v3/dist/adapters/a2a/jsonrpc/errors.js.map +1 -0
- package/v3/dist/adapters/a2a/jsonrpc/index.d.ts +14 -0
- package/v3/dist/adapters/a2a/jsonrpc/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/jsonrpc/index.js +59 -0
- package/v3/dist/adapters/a2a/jsonrpc/index.js.map +1 -0
- package/v3/dist/adapters/a2a/jsonrpc/methods.d.ts +400 -0
- package/v3/dist/adapters/a2a/jsonrpc/methods.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/jsonrpc/methods.js +249 -0
- package/v3/dist/adapters/a2a/jsonrpc/methods.js.map +1 -0
- package/v3/dist/adapters/a2a/notifications/index.d.ts +60 -0
- package/v3/dist/adapters/a2a/notifications/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/notifications/index.js +99 -0
- package/v3/dist/adapters/a2a/notifications/index.js.map +1 -0
- package/v3/dist/adapters/a2a/notifications/retry-queue.d.ts +225 -0
- package/v3/dist/adapters/a2a/notifications/retry-queue.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/notifications/retry-queue.js +449 -0
- package/v3/dist/adapters/a2a/notifications/retry-queue.js.map +1 -0
- package/v3/dist/adapters/a2a/notifications/signature.d.ts +133 -0
- package/v3/dist/adapters/a2a/notifications/signature.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/notifications/signature.js +244 -0
- package/v3/dist/adapters/a2a/notifications/signature.js.map +1 -0
- package/v3/dist/adapters/a2a/notifications/subscription-store.d.ts +243 -0
- package/v3/dist/adapters/a2a/notifications/subscription-store.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/notifications/subscription-store.js +486 -0
- package/v3/dist/adapters/a2a/notifications/subscription-store.js.map +1 -0
- package/v3/dist/adapters/a2a/notifications/webhook-service.d.ts +257 -0
- package/v3/dist/adapters/a2a/notifications/webhook-service.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/notifications/webhook-service.js +542 -0
- package/v3/dist/adapters/a2a/notifications/webhook-service.js.map +1 -0
- package/v3/dist/adapters/a2a/tasks/index.d.ts +16 -0
- package/v3/dist/adapters/a2a/tasks/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/tasks/index.js +33 -0
- package/v3/dist/adapters/a2a/tasks/index.js.map +1 -0
- package/v3/dist/adapters/a2a/tasks/task-manager.d.ts +306 -0
- package/v3/dist/adapters/a2a/tasks/task-manager.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/tasks/task-manager.js +562 -0
- package/v3/dist/adapters/a2a/tasks/task-manager.js.map +1 -0
- package/v3/dist/adapters/a2a/tasks/task-router.d.ts +270 -0
- package/v3/dist/adapters/a2a/tasks/task-router.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/tasks/task-router.js +574 -0
- package/v3/dist/adapters/a2a/tasks/task-router.js.map +1 -0
- package/v3/dist/adapters/a2a/tasks/task-store.d.ts +251 -0
- package/v3/dist/adapters/a2a/tasks/task-store.d.ts.map +1 -0
- package/v3/dist/adapters/a2a/tasks/task-store.js +468 -0
- package/v3/dist/adapters/a2a/tasks/task-store.js.map +1 -0
- package/v3/dist/adapters/a2ui/accessibility/aria-attributes.d.ts +294 -0
- package/v3/dist/adapters/a2ui/accessibility/aria-attributes.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/accessibility/aria-attributes.js +447 -0
- package/v3/dist/adapters/a2ui/accessibility/aria-attributes.js.map +1 -0
- package/v3/dist/adapters/a2ui/accessibility/index.d.ts +83 -0
- package/v3/dist/adapters/a2ui/accessibility/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/accessibility/index.js +155 -0
- package/v3/dist/adapters/a2ui/accessibility/index.js.map +1 -0
- package/v3/dist/adapters/a2ui/accessibility/keyboard-nav.d.ts +177 -0
- package/v3/dist/adapters/a2ui/accessibility/keyboard-nav.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/accessibility/keyboard-nav.js +638 -0
- package/v3/dist/adapters/a2ui/accessibility/keyboard-nav.js.map +1 -0
- package/v3/dist/adapters/a2ui/accessibility/wcag-validator.d.ts +186 -0
- package/v3/dist/adapters/a2ui/accessibility/wcag-validator.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/accessibility/wcag-validator.js +816 -0
- package/v3/dist/adapters/a2ui/accessibility/wcag-validator.js.map +1 -0
- package/v3/dist/adapters/a2ui/catalog/component-schemas.d.ts +227 -0
- package/v3/dist/adapters/a2ui/catalog/component-schemas.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/catalog/component-schemas.js +1090 -0
- package/v3/dist/adapters/a2ui/catalog/component-schemas.js.map +1 -0
- package/v3/dist/adapters/a2ui/catalog/index.d.ts +55 -0
- package/v3/dist/adapters/a2ui/catalog/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/catalog/index.js +100 -0
- package/v3/dist/adapters/a2ui/catalog/index.js.map +1 -0
- package/v3/dist/adapters/a2ui/catalog/qe-catalog.d.ts +456 -0
- package/v3/dist/adapters/a2ui/catalog/qe-catalog.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/catalog/qe-catalog.js +413 -0
- package/v3/dist/adapters/a2ui/catalog/qe-catalog.js.map +1 -0
- package/v3/dist/adapters/a2ui/catalog/standard-catalog.d.ts +581 -0
- package/v3/dist/adapters/a2ui/catalog/standard-catalog.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/catalog/standard-catalog.js +409 -0
- package/v3/dist/adapters/a2ui/catalog/standard-catalog.js.map +1 -0
- package/v3/dist/adapters/a2ui/data/bound-value.d.ts +252 -0
- package/v3/dist/adapters/a2ui/data/bound-value.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/data/bound-value.js +403 -0
- package/v3/dist/adapters/a2ui/data/bound-value.js.map +1 -0
- package/v3/dist/adapters/a2ui/data/index.d.ts +14 -0
- package/v3/dist/adapters/a2ui/data/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/data/index.js +41 -0
- package/v3/dist/adapters/a2ui/data/index.js.map +1 -0
- package/v3/dist/adapters/a2ui/data/json-pointer-resolver.d.ts +187 -0
- package/v3/dist/adapters/a2ui/data/json-pointer-resolver.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/data/json-pointer-resolver.js +425 -0
- package/v3/dist/adapters/a2ui/data/json-pointer-resolver.js.map +1 -0
- package/v3/dist/adapters/a2ui/data/reactive-store.d.ts +241 -0
- package/v3/dist/adapters/a2ui/data/reactive-store.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/data/reactive-store.js +461 -0
- package/v3/dist/adapters/a2ui/data/reactive-store.js.map +1 -0
- package/v3/dist/adapters/a2ui/index.d.ts +17 -0
- package/v3/dist/adapters/a2ui/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/index.js +119 -0
- package/v3/dist/adapters/a2ui/index.js.map +1 -0
- package/v3/dist/adapters/a2ui/integration/agui-sync.d.ts +259 -0
- package/v3/dist/adapters/a2ui/integration/agui-sync.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/integration/agui-sync.js +559 -0
- package/v3/dist/adapters/a2ui/integration/agui-sync.js.map +1 -0
- package/v3/dist/adapters/a2ui/integration/index.d.ts +11 -0
- package/v3/dist/adapters/a2ui/integration/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/integration/index.js +23 -0
- package/v3/dist/adapters/a2ui/integration/index.js.map +1 -0
- package/v3/dist/adapters/a2ui/integration/surface-state-bridge.d.ts +209 -0
- package/v3/dist/adapters/a2ui/integration/surface-state-bridge.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/integration/surface-state-bridge.js +545 -0
- package/v3/dist/adapters/a2ui/integration/surface-state-bridge.js.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/component-builder.d.ts +227 -0
- package/v3/dist/adapters/a2ui/renderer/component-builder.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/component-builder.js +488 -0
- package/v3/dist/adapters/a2ui/renderer/component-builder.js.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/index.d.ts +16 -0
- package/v3/dist/adapters/a2ui/renderer/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/index.js +50 -0
- package/v3/dist/adapters/a2ui/renderer/index.js.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/message-types.d.ts +299 -0
- package/v3/dist/adapters/a2ui/renderer/message-types.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/message-types.js +187 -0
- package/v3/dist/adapters/a2ui/renderer/message-types.js.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/surface-generator.d.ts +210 -0
- package/v3/dist/adapters/a2ui/renderer/surface-generator.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/surface-generator.js +586 -0
- package/v3/dist/adapters/a2ui/renderer/surface-generator.js.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/templates/accessibility-surface.d.ts +149 -0
- package/v3/dist/adapters/a2ui/renderer/templates/accessibility-surface.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/templates/accessibility-surface.js +414 -0
- package/v3/dist/adapters/a2ui/renderer/templates/accessibility-surface.js.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/templates/coverage-surface.d.ts +95 -0
- package/v3/dist/adapters/a2ui/renderer/templates/coverage-surface.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/templates/coverage-surface.js +231 -0
- package/v3/dist/adapters/a2ui/renderer/templates/coverage-surface.js.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/templates/index.d.ts +12 -0
- package/v3/dist/adapters/a2ui/renderer/templates/index.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/templates/index.js +16 -0
- package/v3/dist/adapters/a2ui/renderer/templates/index.js.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/templates/security-surface.d.ts +121 -0
- package/v3/dist/adapters/a2ui/renderer/templates/security-surface.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/templates/security-surface.js +367 -0
- package/v3/dist/adapters/a2ui/renderer/templates/security-surface.js.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/templates/test-results-surface.d.ts +104 -0
- package/v3/dist/adapters/a2ui/renderer/templates/test-results-surface.d.ts.map +1 -0
- package/v3/dist/adapters/a2ui/renderer/templates/test-results-surface.js +294 -0
- package/v3/dist/adapters/a2ui/renderer/templates/test-results-surface.js.map +1 -0
- package/v3/dist/adapters/ag-ui/backpressure-handler.d.ts +201 -0
- package/v3/dist/adapters/ag-ui/backpressure-handler.d.ts.map +1 -0
- package/v3/dist/adapters/ag-ui/backpressure-handler.js +399 -0
- package/v3/dist/adapters/ag-ui/backpressure-handler.js.map +1 -0
- package/v3/dist/adapters/ag-ui/event-adapter.d.ts +360 -0
- package/v3/dist/adapters/ag-ui/event-adapter.d.ts.map +1 -0
- package/v3/dist/adapters/ag-ui/event-adapter.js +1083 -0
- package/v3/dist/adapters/ag-ui/event-adapter.js.map +1 -0
- package/v3/dist/adapters/ag-ui/event-batcher.d.ts +242 -0
- package/v3/dist/adapters/ag-ui/event-batcher.d.ts.map +1 -0
- package/v3/dist/adapters/ag-ui/event-batcher.js +444 -0
- package/v3/dist/adapters/ag-ui/event-batcher.js.map +1 -0
- package/v3/dist/adapters/ag-ui/event-types.d.ts +450 -0
- package/v3/dist/adapters/ag-ui/event-types.d.ts.map +1 -0
- package/v3/dist/adapters/ag-ui/event-types.js +173 -0
- package/v3/dist/adapters/ag-ui/event-types.js.map +1 -0
- package/v3/dist/adapters/ag-ui/index.d.ts +17 -0
- package/v3/dist/adapters/ag-ui/index.d.ts.map +1 -0
- package/v3/dist/adapters/ag-ui/index.js +47 -0
- package/v3/dist/adapters/ag-ui/index.js.map +1 -0
- package/v3/dist/adapters/ag-ui/json-patch-utils.d.ts +136 -0
- package/v3/dist/adapters/ag-ui/json-patch-utils.d.ts.map +1 -0
- package/v3/dist/adapters/ag-ui/json-patch-utils.js +574 -0
- package/v3/dist/adapters/ag-ui/json-patch-utils.js.map +1 -0
- package/v3/dist/adapters/ag-ui/json-patch.d.ts +241 -0
- package/v3/dist/adapters/ag-ui/json-patch.d.ts.map +1 -0
- package/v3/dist/adapters/ag-ui/json-patch.js +726 -0
- package/v3/dist/adapters/ag-ui/json-patch.js.map +1 -0
- package/v3/dist/adapters/ag-ui/state-delta-cache.d.ts +218 -0
- package/v3/dist/adapters/ag-ui/state-delta-cache.d.ts.map +1 -0
- package/v3/dist/adapters/ag-ui/state-delta-cache.js +422 -0
- package/v3/dist/adapters/ag-ui/state-delta-cache.js.map +1 -0
- package/v3/dist/adapters/ag-ui/state-manager.d.ts +249 -0
- package/v3/dist/adapters/ag-ui/state-manager.d.ts.map +1 -0
- package/v3/dist/adapters/ag-ui/state-manager.js +511 -0
- package/v3/dist/adapters/ag-ui/state-manager.js.map +1 -0
- package/v3/dist/adapters/ag-ui/stream-controller.d.ts +195 -0
- package/v3/dist/adapters/ag-ui/stream-controller.d.ts.map +1 -0
- package/v3/dist/adapters/ag-ui/stream-controller.js +481 -0
- package/v3/dist/adapters/ag-ui/stream-controller.js.map +1 -0
- package/v3/dist/adapters/index.d.ts +4 -0
- package/v3/dist/adapters/index.d.ts.map +1 -1
- package/v3/dist/adapters/index.js +89 -0
- package/v3/dist/adapters/index.js.map +1 -1
- package/v3/dist/cli/bundle.js +7412 -3749
- package/v3/dist/init/init-wizard.d.ts.map +1 -1
- package/v3/dist/init/init-wizard.js +16 -1
- package/v3/dist/init/init-wizard.js.map +1 -1
- package/v3/dist/init/migration/config-migrator.d.ts.map +1 -1
- package/v3/dist/init/migration/config-migrator.js +15 -1
- package/v3/dist/init/migration/config-migrator.js.map +1 -1
- package/v3/dist/init/self-configurator.d.ts +7 -0
- package/v3/dist/init/self-configurator.d.ts.map +1 -1
- package/v3/dist/init/self-configurator.js +23 -27
- package/v3/dist/init/self-configurator.js.map +1 -1
- package/v3/dist/kernel/plugin-loader.d.ts.map +1 -1
- package/v3/dist/kernel/plugin-loader.js +6 -1
- package/v3/dist/kernel/plugin-loader.js.map +1 -1
- package/v3/dist/kernel/unified-memory.d.ts +97 -0
- package/v3/dist/kernel/unified-memory.d.ts.map +1 -1
- package/v3/dist/kernel/unified-memory.js +204 -0
- package/v3/dist/kernel/unified-memory.js.map +1 -1
- package/v3/dist/mcp/bundle.js +121759 -105597
- package/v3/dist/mcp/entry.d.ts +5 -0
- package/v3/dist/mcp/entry.d.ts.map +1 -1
- package/v3/dist/mcp/entry.js +36 -0
- package/v3/dist/mcp/entry.js.map +1 -1
- package/v3/dist/mcp/http-server.d.ts +95 -0
- package/v3/dist/mcp/http-server.d.ts.map +1 -0
- package/v3/dist/mcp/http-server.js +833 -0
- package/v3/dist/mcp/http-server.js.map +1 -0
- package/v3/dist/mcp/protocol-server.d.ts +6 -0
- package/v3/dist/mcp/protocol-server.d.ts.map +1 -1
- package/v3/dist/mcp/protocol-server.js +40 -0
- package/v3/dist/mcp/protocol-server.js.map +1 -1
- package/v3/dist/mcp/transport/index.d.ts +25 -3
- package/v3/dist/mcp/transport/index.d.ts.map +1 -1
- package/v3/dist/mcp/transport/index.js +22 -4
- package/v3/dist/mcp/transport/index.js.map +1 -1
- package/v3/dist/mcp/transport/sse/connection-manager.d.ts +84 -0
- package/v3/dist/mcp/transport/sse/connection-manager.d.ts.map +1 -0
- package/v3/dist/mcp/transport/sse/connection-manager.js +271 -0
- package/v3/dist/mcp/transport/sse/connection-manager.js.map +1 -0
- package/v3/dist/mcp/transport/sse/index.d.ts +10 -0
- package/v3/dist/mcp/transport/sse/index.d.ts.map +1 -0
- package/v3/dist/mcp/transport/sse/index.js +15 -0
- package/v3/dist/mcp/transport/sse/index.js.map +1 -0
- package/v3/dist/mcp/transport/sse/sse-transport.d.ts +56 -0
- package/v3/dist/mcp/transport/sse/sse-transport.d.ts.map +1 -0
- package/v3/dist/mcp/transport/sse/sse-transport.js +381 -0
- package/v3/dist/mcp/transport/sse/sse-transport.js.map +1 -0
- package/v3/dist/mcp/transport/sse/types.d.ts +237 -0
- package/v3/dist/mcp/transport/sse/types.d.ts.map +1 -0
- package/v3/dist/mcp/transport/sse/types.js +37 -0
- package/v3/dist/mcp/transport/sse/types.js.map +1 -0
- package/v3/dist/mcp/transport/websocket/connection-manager.d.ts +143 -0
- package/v3/dist/mcp/transport/websocket/connection-manager.d.ts.map +1 -0
- package/v3/dist/mcp/transport/websocket/connection-manager.js +522 -0
- package/v3/dist/mcp/transport/websocket/connection-manager.js.map +1 -0
- package/v3/dist/mcp/transport/websocket/index.d.ts +10 -0
- package/v3/dist/mcp/transport/websocket/index.d.ts.map +1 -0
- package/v3/dist/mcp/transport/websocket/index.js +19 -0
- package/v3/dist/mcp/transport/websocket/index.js.map +1 -0
- package/v3/dist/mcp/transport/websocket/types.d.ts +354 -0
- package/v3/dist/mcp/transport/websocket/types.d.ts.map +1 -0
- package/v3/dist/mcp/transport/websocket/types.js +49 -0
- package/v3/dist/mcp/transport/websocket/types.js.map +1 -0
- package/v3/dist/mcp/transport/websocket/websocket-transport.d.ts +77 -0
- package/v3/dist/mcp/transport/websocket/websocket-transport.d.ts.map +1 -0
- package/v3/dist/mcp/transport/websocket/websocket-transport.js +622 -0
- package/v3/dist/mcp/transport/websocket/websocket-transport.js.map +1 -0
- package/v3/dist/memory/crdt/convergence-tracker.d.ts +59 -0
- package/v3/dist/memory/crdt/convergence-tracker.d.ts.map +1 -0
- package/v3/dist/memory/crdt/convergence-tracker.js +325 -0
- package/v3/dist/memory/crdt/convergence-tracker.js.map +1 -0
- package/v3/dist/memory/crdt/crdt-store.d.ts +55 -0
- package/v3/dist/memory/crdt/crdt-store.d.ts.map +1 -0
- package/v3/dist/memory/crdt/crdt-store.js +582 -0
- package/v3/dist/memory/crdt/crdt-store.js.map +1 -0
- package/v3/dist/memory/crdt/g-counter.d.ts +47 -0
- package/v3/dist/memory/crdt/g-counter.d.ts.map +1 -0
- package/v3/dist/memory/crdt/g-counter.js +134 -0
- package/v3/dist/memory/crdt/g-counter.js.map +1 -0
- package/v3/dist/memory/crdt/index.d.ts +52 -0
- package/v3/dist/memory/crdt/index.d.ts.map +1 -0
- package/v3/dist/memory/crdt/index.js +66 -0
- package/v3/dist/memory/crdt/index.js.map +1 -0
- package/v3/dist/memory/crdt/lww-register.d.ts +40 -0
- package/v3/dist/memory/crdt/lww-register.d.ts.map +1 -0
- package/v3/dist/memory/crdt/lww-register.js +133 -0
- package/v3/dist/memory/crdt/lww-register.js.map +1 -0
- package/v3/dist/memory/crdt/or-set.d.ts +62 -0
- package/v3/dist/memory/crdt/or-set.d.ts.map +1 -0
- package/v3/dist/memory/crdt/or-set.js +336 -0
- package/v3/dist/memory/crdt/or-set.js.map +1 -0
- package/v3/dist/memory/crdt/pn-counter.d.ts +53 -0
- package/v3/dist/memory/crdt/pn-counter.d.ts.map +1 -0
- package/v3/dist/memory/crdt/pn-counter.js +147 -0
- package/v3/dist/memory/crdt/pn-counter.js.map +1 -0
- package/v3/dist/memory/crdt/types.d.ts +397 -0
- package/v3/dist/memory/crdt/types.d.ts.map +1 -0
- package/v3/dist/memory/crdt/types.js +12 -0
- package/v3/dist/memory/crdt/types.js.map +1 -0
- package/v3/dist/memory/index.d.ts +5 -2
- package/v3/dist/memory/index.d.ts.map +1 -1
- package/v3/dist/memory/index.js +5 -2
- package/v3/dist/memory/index.js.map +1 -1
- package/v3/dist/performance/benchmarks.d.ts +215 -0
- package/v3/dist/performance/benchmarks.d.ts.map +1 -0
- package/v3/dist/performance/benchmarks.js +516 -0
- package/v3/dist/performance/benchmarks.js.map +1 -0
- package/v3/dist/performance/ci-gates.d.ts +149 -0
- package/v3/dist/performance/ci-gates.d.ts.map +1 -0
- package/v3/dist/performance/ci-gates.js +425 -0
- package/v3/dist/performance/ci-gates.js.map +1 -0
- package/v3/dist/performance/index.d.ts +18 -0
- package/v3/dist/performance/index.d.ts.map +1 -0
- package/v3/dist/performance/index.js +26 -0
- package/v3/dist/performance/index.js.map +1 -0
- package/v3/dist/performance/optimizer.d.ts +323 -0
- package/v3/dist/performance/optimizer.d.ts.map +1 -0
- package/v3/dist/performance/optimizer.js +592 -0
- package/v3/dist/performance/optimizer.js.map +1 -0
- package/v3/dist/performance/profiler.d.ts +195 -0
- package/v3/dist/performance/profiler.d.ts.map +1 -0
- package/v3/dist/performance/profiler.js +369 -0
- package/v3/dist/performance/profiler.js.map +1 -0
- package/v3/dist/performance/run-gates.d.ts +23 -0
- package/v3/dist/performance/run-gates.d.ts.map +1 -0
- package/v3/dist/performance/run-gates.js +122 -0
- package/v3/dist/performance/run-gates.js.map +1 -0
- package/v3/dist/testing/index.d.ts +6 -0
- package/v3/dist/testing/index.d.ts.map +1 -0
- package/v3/dist/testing/index.js +7 -0
- package/v3/dist/testing/index.js.map +1 -0
- package/v3/dist/testing/load/agent-load-tester.d.ts +221 -0
- package/v3/dist/testing/load/agent-load-tester.d.ts.map +1 -0
- package/v3/dist/testing/load/agent-load-tester.js +566 -0
- package/v3/dist/testing/load/agent-load-tester.js.map +1 -0
- package/v3/dist/testing/load/bottleneck-analyzer.d.ts +150 -0
- package/v3/dist/testing/load/bottleneck-analyzer.d.ts.map +1 -0
- package/v3/dist/testing/load/bottleneck-analyzer.js +442 -0
- package/v3/dist/testing/load/bottleneck-analyzer.js.map +1 -0
- package/v3/dist/testing/load/index.d.ts +17 -0
- package/v3/dist/testing/load/index.d.ts.map +1 -0
- package/v3/dist/testing/load/index.js +23 -0
- package/v3/dist/testing/load/index.js.map +1 -0
- package/v3/dist/testing/load/metrics-collector.d.ts +275 -0
- package/v3/dist/testing/load/metrics-collector.d.ts.map +1 -0
- package/v3/dist/testing/load/metrics-collector.js +475 -0
- package/v3/dist/testing/load/metrics-collector.js.map +1 -0
- package/v3/package.json +5 -1
|
@@ -0,0 +1,833 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - HTTP Server
|
|
3
|
+
* Express server for AG-UI SSE/WebSocket, A2A discovery, and A2UI surfaces
|
|
4
|
+
*
|
|
5
|
+
* This server runs alongside the stdio MCP server to provide:
|
|
6
|
+
* - AG-UI Protocol: SSE streaming at /agent/stream (default, unidirectional)
|
|
7
|
+
* - AG-UI Protocol: WebSocket streaming at /agent/ws (bidirectional, <100ms latency)
|
|
8
|
+
* - A2A Protocol: Agent discovery at /.well-known/agent.json
|
|
9
|
+
* - A2A Protocol: Task submission at /a2a/tasks
|
|
10
|
+
*
|
|
11
|
+
* @module mcp/http-server
|
|
12
|
+
*/
|
|
13
|
+
import { createServer } from 'http';
|
|
14
|
+
import { join, dirname } from 'path';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
// AG-UI imports
|
|
17
|
+
import { createEventAdapter, } from '../adapters/ag-ui/index.js';
|
|
18
|
+
// A2A imports
|
|
19
|
+
import { createDiscoveryService, getDiscoveryRouteDefinitions, } from '../adapters/a2a/discovery/index.js';
|
|
20
|
+
import { createTaskManager, createTaskStore, } from '../adapters/a2a/tasks/index.js';
|
|
21
|
+
// Push Notifications imports
|
|
22
|
+
import { createWebhookService, createSubscriptionStore, } from '../adapters/a2a/notifications/index.js';
|
|
23
|
+
import { createAgentCardGenerator, } from '../adapters/index.js';
|
|
24
|
+
// SSE Transport
|
|
25
|
+
import { createSSETransport, } from './transport/sse/index.js';
|
|
26
|
+
// WebSocket Transport
|
|
27
|
+
import { createWebSocketTransport, } from './transport/websocket/index.js';
|
|
28
|
+
import { AGUIEventType } from './transport/sse/types.js';
|
|
29
|
+
// Memory for CRDT
|
|
30
|
+
import { getUnifiedMemory } from '../kernel/unified-memory.js';
|
|
31
|
+
class SimpleRouter {
|
|
32
|
+
routes = [];
|
|
33
|
+
add(method, path, handler) {
|
|
34
|
+
// Convert Express-style path params to regex
|
|
35
|
+
const paramNames = [];
|
|
36
|
+
const patternStr = path.replace(/:([^/]+)/g, (_, name) => {
|
|
37
|
+
paramNames.push(name);
|
|
38
|
+
return '([^/]+)';
|
|
39
|
+
});
|
|
40
|
+
const pattern = new RegExp(`^${patternStr}$`);
|
|
41
|
+
this.routes.push({ method: method.toUpperCase(), pattern, paramNames, handler });
|
|
42
|
+
}
|
|
43
|
+
match(method, path) {
|
|
44
|
+
for (const route of this.routes) {
|
|
45
|
+
if (route.method !== method.toUpperCase() && route.method !== 'ALL') {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const match = path.match(route.pattern);
|
|
49
|
+
if (match) {
|
|
50
|
+
const params = {};
|
|
51
|
+
route.paramNames.forEach((name, i) => {
|
|
52
|
+
params[name] = match[i + 1];
|
|
53
|
+
});
|
|
54
|
+
return { handler: route.handler, params };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// HTTP Server Implementation
|
|
62
|
+
// ============================================================================
|
|
63
|
+
class HTTPServerImpl {
|
|
64
|
+
eventAdapter;
|
|
65
|
+
discoveryService;
|
|
66
|
+
taskManager;
|
|
67
|
+
taskStore;
|
|
68
|
+
sseTransport;
|
|
69
|
+
webSocketTransport;
|
|
70
|
+
enableWebSocket;
|
|
71
|
+
router;
|
|
72
|
+
agentMarkdownDir;
|
|
73
|
+
skipAgentCardLoading;
|
|
74
|
+
skipCRDTInit;
|
|
75
|
+
server = null;
|
|
76
|
+
running = false;
|
|
77
|
+
agentCardsLoaded = false;
|
|
78
|
+
enableCors;
|
|
79
|
+
// OAuth 2.0 (ADR-054)
|
|
80
|
+
jwtVerifier;
|
|
81
|
+
enableOAuth;
|
|
82
|
+
authMiddleware;
|
|
83
|
+
// Push Notifications (ADR-054)
|
|
84
|
+
webhookService;
|
|
85
|
+
subscriptionStore;
|
|
86
|
+
enablePushNotifications;
|
|
87
|
+
// Hot Reload (ADR-054)
|
|
88
|
+
hotReloadService;
|
|
89
|
+
healthChecker;
|
|
90
|
+
enableHotReload;
|
|
91
|
+
constructor(config = {}) {
|
|
92
|
+
// Initialize components with defaults
|
|
93
|
+
this.eventAdapter = config.eventAdapter ?? createEventAdapter();
|
|
94
|
+
this.enableCors = config.enableCors ?? true;
|
|
95
|
+
this.skipAgentCardLoading = config.skipAgentCardLoading ?? false;
|
|
96
|
+
this.skipCRDTInit = config.skipCRDTInit ?? false;
|
|
97
|
+
this.enableWebSocket = config.enableWebSocket ?? true;
|
|
98
|
+
// Resolve agent markdown directory
|
|
99
|
+
const currentDir = dirname(fileURLToPath(import.meta.url));
|
|
100
|
+
this.agentMarkdownDir = config.agentMarkdownDir ?? join(currentDir, '../../assets/agents/v3');
|
|
101
|
+
// Initialize task store and manager
|
|
102
|
+
this.taskStore = createTaskStore();
|
|
103
|
+
this.taskManager = config.taskManager ?? createTaskManager({
|
|
104
|
+
storeConfig: {},
|
|
105
|
+
});
|
|
106
|
+
// Initialize agent card generator and discovery service
|
|
107
|
+
const baseUrl = 'http://localhost:' + (process.env.AQE_HTTP_PORT || '3000');
|
|
108
|
+
const agentCardGenerator = config.agentCardGenerator ?? createAgentCardGenerator({
|
|
109
|
+
baseUrl,
|
|
110
|
+
});
|
|
111
|
+
this.discoveryService = config.discoveryService ?? createDiscoveryService({
|
|
112
|
+
generator: agentCardGenerator,
|
|
113
|
+
baseUrl,
|
|
114
|
+
});
|
|
115
|
+
// Initialize SSE transport (default, unidirectional)
|
|
116
|
+
this.sseTransport = config.sseTransport ?? createSSETransport();
|
|
117
|
+
// CRITICAL: Wire the SSE agent handler to process requests
|
|
118
|
+
this.sseTransport.setAgentHandler(this.handleAgentRequest.bind(this));
|
|
119
|
+
// Initialize WebSocket transport (optional, bidirectional <100ms latency)
|
|
120
|
+
if (this.enableWebSocket) {
|
|
121
|
+
this.webSocketTransport = config.webSocketTransport ?? createWebSocketTransport(config.webSocketConfig);
|
|
122
|
+
// Wire the WebSocket agent handler (same handler as SSE)
|
|
123
|
+
this.webSocketTransport.setAgentHandler(this.handleAgentRequest.bind(this));
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.webSocketTransport = null;
|
|
127
|
+
}
|
|
128
|
+
// ========================================
|
|
129
|
+
// OAuth 2.0 Initialization (ADR-054)
|
|
130
|
+
// ========================================
|
|
131
|
+
this.jwtVerifier = config.jwtVerifier;
|
|
132
|
+
this.enableOAuth = config.enableOAuth ?? false;
|
|
133
|
+
if (this.jwtVerifier && this.enableOAuth) {
|
|
134
|
+
// Create auth middleware that returns true if auth passes
|
|
135
|
+
this.authMiddleware = async (req, res) => {
|
|
136
|
+
const authHeader = req.headers.authorization;
|
|
137
|
+
if (!authHeader?.startsWith('Bearer ')) {
|
|
138
|
+
res.setHeader('WWW-Authenticate', 'Bearer');
|
|
139
|
+
this.sendError(res, 401, 'Authentication required');
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
const token = authHeader.substring(7);
|
|
143
|
+
try {
|
|
144
|
+
const claims = await this.jwtVerifier.verify(token);
|
|
145
|
+
req.user = claims;
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
res.setHeader('WWW-Authenticate', 'Bearer error="invalid_token"');
|
|
150
|
+
this.sendError(res, 401, 'Invalid or expired token');
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
// ========================================
|
|
156
|
+
// Push Notifications Initialization (ADR-054)
|
|
157
|
+
// ========================================
|
|
158
|
+
this.subscriptionStore = config.subscriptionStore ?? createSubscriptionStore();
|
|
159
|
+
this.webhookService = config.webhookService ?? createWebhookService();
|
|
160
|
+
this.enablePushNotifications = config.enablePushNotifications ?? true;
|
|
161
|
+
// Wire task events to webhook notifications
|
|
162
|
+
if (this.enablePushNotifications && this.webhookService) {
|
|
163
|
+
this.taskManager.on('stateChange', (event) => {
|
|
164
|
+
this.webhookService.notifyStateChange(event.taskId, event.newStatus, event.previousStatus).catch((err) => console.error('[AQE] Webhook delivery failed:', err));
|
|
165
|
+
});
|
|
166
|
+
this.taskManager.on('artifactAdded', (event) => {
|
|
167
|
+
this.webhookService.notifyArtifactCreated(event.taskId, {
|
|
168
|
+
id: event.artifact.id ?? 'unknown',
|
|
169
|
+
name: event.artifact.name ?? 'artifact',
|
|
170
|
+
}).catch((err) => console.error('[AQE] Artifact webhook delivery failed:', err));
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// ========================================
|
|
174
|
+
// Hot Reload Initialization (ADR-054)
|
|
175
|
+
// ========================================
|
|
176
|
+
this.enableHotReload = config.enableHotReload ?? false;
|
|
177
|
+
this.healthChecker = config.healthChecker;
|
|
178
|
+
this.hotReloadService = config.hotReloadService;
|
|
179
|
+
// Setup router
|
|
180
|
+
this.router = new SimpleRouter();
|
|
181
|
+
this.setupRoutes();
|
|
182
|
+
}
|
|
183
|
+
// ============================================================================
|
|
184
|
+
// SSE Agent Handler - THE CRITICAL INTEGRATION POINT
|
|
185
|
+
// ============================================================================
|
|
186
|
+
/**
|
|
187
|
+
* Handle AG-UI agent requests via SSE
|
|
188
|
+
* This is the main integration point between AG-UI protocol and A2A task system
|
|
189
|
+
*/
|
|
190
|
+
async handleAgentRequest(request, emit, signal) {
|
|
191
|
+
// Extract message content from request
|
|
192
|
+
const messageContent = request.messages?.map(m => m.content).join('\n') || '';
|
|
193
|
+
if (!messageContent) {
|
|
194
|
+
emit({
|
|
195
|
+
type: AGUIEventType.RUN_ERROR,
|
|
196
|
+
runId: request.runId || 'unknown',
|
|
197
|
+
message: 'No message content provided',
|
|
198
|
+
code: 'INVALID_REQUEST',
|
|
199
|
+
});
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
// Create A2A task from AG-UI request
|
|
203
|
+
const task = this.taskManager.createTask({
|
|
204
|
+
role: 'user',
|
|
205
|
+
parts: [{ type: 'text', text: messageContent }],
|
|
206
|
+
}, { contextId: request.threadId });
|
|
207
|
+
// Emit STEP_STARTED for task creation
|
|
208
|
+
emit({
|
|
209
|
+
type: AGUIEventType.STEP_STARTED,
|
|
210
|
+
stepId: task.id,
|
|
211
|
+
name: 'Task Processing',
|
|
212
|
+
runId: request.runId,
|
|
213
|
+
});
|
|
214
|
+
// Subscribe to task events and forward to SSE
|
|
215
|
+
const taskEventHandler = (event) => {
|
|
216
|
+
if (event.taskId !== task.id || signal.aborted)
|
|
217
|
+
return;
|
|
218
|
+
// Emit appropriate AG-UI events based on task state changes
|
|
219
|
+
if (event.newStatus === 'working') {
|
|
220
|
+
emit({
|
|
221
|
+
type: AGUIEventType.TEXT_MESSAGE_START,
|
|
222
|
+
messageId: `msg-${task.id}`,
|
|
223
|
+
role: 'assistant',
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
else if (event.newStatus === 'completed') {
|
|
227
|
+
emit({
|
|
228
|
+
type: AGUIEventType.TEXT_MESSAGE_CONTENT,
|
|
229
|
+
messageId: `msg-${task.id}`,
|
|
230
|
+
delta: 'Task completed successfully',
|
|
231
|
+
});
|
|
232
|
+
emit({
|
|
233
|
+
type: AGUIEventType.TEXT_MESSAGE_END,
|
|
234
|
+
messageId: `msg-${task.id}`,
|
|
235
|
+
});
|
|
236
|
+
emit({
|
|
237
|
+
type: AGUIEventType.STEP_FINISHED,
|
|
238
|
+
stepId: task.id,
|
|
239
|
+
result: event.task,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
else if (event.newStatus === 'failed') {
|
|
243
|
+
emit({
|
|
244
|
+
type: AGUIEventType.STEP_FINISHED,
|
|
245
|
+
stepId: task.id,
|
|
246
|
+
result: { error: 'Task failed' },
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
const artifactHandler = (event) => {
|
|
251
|
+
if (event.taskId !== task.id || signal.aborted)
|
|
252
|
+
return;
|
|
253
|
+
// Emit artifact as text message content
|
|
254
|
+
const textParts = event.artifact?.parts?.filter(p => p.type === 'text') || [];
|
|
255
|
+
for (const part of textParts) {
|
|
256
|
+
if (part.text) {
|
|
257
|
+
emit({
|
|
258
|
+
type: AGUIEventType.TEXT_MESSAGE_CONTENT,
|
|
259
|
+
messageId: `msg-${task.id}`,
|
|
260
|
+
delta: part.text,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
this.taskManager.on('stateChange', taskEventHandler);
|
|
266
|
+
this.taskManager.on('artifactAdded', artifactHandler);
|
|
267
|
+
// Handle abort signal
|
|
268
|
+
signal.addEventListener('abort', () => {
|
|
269
|
+
this.taskManager.off('stateChange', taskEventHandler);
|
|
270
|
+
this.taskManager.off('artifactAdded', artifactHandler);
|
|
271
|
+
try {
|
|
272
|
+
this.taskManager.cancelTask(task.id);
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
// Task may already be in terminal state
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
// Start task processing
|
|
279
|
+
try {
|
|
280
|
+
this.taskManager.startTask(task.id);
|
|
281
|
+
// Simulate task completion for now (in production, this would delegate to actual handlers)
|
|
282
|
+
// TODO: Wire to actual MCP tool handlers
|
|
283
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
284
|
+
if (!signal.aborted) {
|
|
285
|
+
this.taskManager.completeTask(task.id, [
|
|
286
|
+
this.taskManager.createTextArtifact(`result-${task.id}`, 'Result', `Processed: ${messageContent}`),
|
|
287
|
+
]);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
if (!signal.aborted) {
|
|
292
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
293
|
+
this.taskManager.failTask(task.id, {
|
|
294
|
+
code: 'PROCESSING_ERROR',
|
|
295
|
+
message: errorMessage,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
finally {
|
|
300
|
+
// Cleanup listeners
|
|
301
|
+
this.taskManager.off('stateChange', taskEventHandler);
|
|
302
|
+
this.taskManager.off('artifactAdded', artifactHandler);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
// ============================================================================
|
|
306
|
+
// Route Setup
|
|
307
|
+
// ============================================================================
|
|
308
|
+
setupRoutes() {
|
|
309
|
+
// Get discovery route definitions
|
|
310
|
+
const discoveryRoutes = getDiscoveryRouteDefinitions({
|
|
311
|
+
discoveryService: this.discoveryService,
|
|
312
|
+
});
|
|
313
|
+
// Register discovery routes
|
|
314
|
+
for (const route of discoveryRoutes) {
|
|
315
|
+
const handler = this.createHandlerFromDefinition(route);
|
|
316
|
+
this.router.add(route.method, route.path, handler);
|
|
317
|
+
}
|
|
318
|
+
// A2A Task routes
|
|
319
|
+
this.router.add('POST', '/a2a/tasks', this.handleTaskSubmit.bind(this));
|
|
320
|
+
this.router.add('GET', '/a2a/tasks/:taskId', this.handleTaskGet.bind(this));
|
|
321
|
+
this.router.add('POST', '/a2a/tasks/:taskId/cancel', this.handleTaskCancel.bind(this));
|
|
322
|
+
this.router.add('GET', '/a2a/tasks/:taskId/subscribe', this.handleTaskSubscribe.bind(this));
|
|
323
|
+
this.router.add('GET', '/a2a/tasks', this.handleTaskList.bind(this));
|
|
324
|
+
// Push Notification routes (ADR-054)
|
|
325
|
+
if (this.enablePushNotifications) {
|
|
326
|
+
this.router.add('POST', '/a2a/tasks/:taskId/pushNotification', this.handlePushNotificationSet.bind(this));
|
|
327
|
+
this.router.add('GET', '/a2a/tasks/:taskId/pushNotification', this.handlePushNotificationGet.bind(this));
|
|
328
|
+
this.router.add('DELETE', '/a2a/tasks/:taskId/pushNotification', this.handlePushNotificationDelete.bind(this));
|
|
329
|
+
}
|
|
330
|
+
// AG-UI SSE streaming endpoint
|
|
331
|
+
this.router.add('POST', '/agent/stream', this.handleAgentStream.bind(this));
|
|
332
|
+
this.router.add('OPTIONS', '/agent/stream', this.handleCorsPreFlight.bind(this));
|
|
333
|
+
// Health check
|
|
334
|
+
this.router.add('GET', '/health', this.handleHealth.bind(this));
|
|
335
|
+
}
|
|
336
|
+
createHandlerFromDefinition(route) {
|
|
337
|
+
return async (req, res) => {
|
|
338
|
+
// Create Express-compatible request/response wrappers
|
|
339
|
+
const httpReq = this.wrapRequest(req);
|
|
340
|
+
const httpRes = this.wrapResponse(res);
|
|
341
|
+
// Execute all handlers in sequence
|
|
342
|
+
for (const handler of route.handlers) {
|
|
343
|
+
await handler(httpReq, httpRes);
|
|
344
|
+
if (res.writableEnded)
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
// ============================================================================
|
|
350
|
+
// Request/Response Wrappers
|
|
351
|
+
// ============================================================================
|
|
352
|
+
wrapRequest(req) {
|
|
353
|
+
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
|
|
354
|
+
const query = {};
|
|
355
|
+
url.searchParams.forEach((value, key) => {
|
|
356
|
+
const existing = query[key];
|
|
357
|
+
if (existing) {
|
|
358
|
+
if (Array.isArray(existing)) {
|
|
359
|
+
existing.push(value);
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
query[key] = [existing, value];
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
else {
|
|
366
|
+
query[key] = value;
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
return {
|
|
370
|
+
params: req.params || {},
|
|
371
|
+
query,
|
|
372
|
+
headers: req.headers,
|
|
373
|
+
header: (name) => {
|
|
374
|
+
const value = req.headers[name.toLowerCase()];
|
|
375
|
+
return Array.isArray(value) ? value[0] : value;
|
|
376
|
+
},
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
wrapResponse(res) {
|
|
380
|
+
return {
|
|
381
|
+
status: (code) => {
|
|
382
|
+
res.statusCode = code;
|
|
383
|
+
return this.wrapResponse(res);
|
|
384
|
+
},
|
|
385
|
+
json: (body) => {
|
|
386
|
+
res.setHeader('Content-Type', 'application/json');
|
|
387
|
+
res.end(JSON.stringify(body));
|
|
388
|
+
},
|
|
389
|
+
setHeader: (name, value) => {
|
|
390
|
+
res.setHeader(name, value);
|
|
391
|
+
},
|
|
392
|
+
end: () => {
|
|
393
|
+
res.end();
|
|
394
|
+
},
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
// ============================================================================
|
|
398
|
+
// Task Handlers
|
|
399
|
+
// ============================================================================
|
|
400
|
+
async handleTaskSubmit(req, res) {
|
|
401
|
+
try {
|
|
402
|
+
const body = await this.parseBody(req);
|
|
403
|
+
const { message, contextId } = body;
|
|
404
|
+
if (!message) {
|
|
405
|
+
this.sendError(res, 400, 'Missing required field: message');
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
// TaskManager.createTask expects (A2AMessage, CreateTaskOptions?)
|
|
409
|
+
const task = this.taskManager.createTask(message, { contextId });
|
|
410
|
+
this.setCorsHeaders(res);
|
|
411
|
+
res.setHeader('Content-Type', 'application/json');
|
|
412
|
+
res.statusCode = 201;
|
|
413
|
+
res.end(JSON.stringify({ task }));
|
|
414
|
+
}
|
|
415
|
+
catch (error) {
|
|
416
|
+
const message = error instanceof Error ? error.message : 'Failed to submit task';
|
|
417
|
+
this.sendError(res, 500, message);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async handleTaskGet(req, res) {
|
|
421
|
+
try {
|
|
422
|
+
const taskId = req.params?.taskId;
|
|
423
|
+
if (!taskId) {
|
|
424
|
+
this.sendError(res, 400, 'Missing task ID');
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
const task = await this.taskStore.get(taskId);
|
|
428
|
+
if (!task) {
|
|
429
|
+
this.sendError(res, 404, 'Task not found');
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
this.setCorsHeaders(res);
|
|
433
|
+
res.setHeader('Content-Type', 'application/json');
|
|
434
|
+
res.end(JSON.stringify({ task }));
|
|
435
|
+
}
|
|
436
|
+
catch (error) {
|
|
437
|
+
const message = error instanceof Error ? error.message : 'Failed to get task';
|
|
438
|
+
this.sendError(res, 500, message);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
async handleTaskCancel(req, res) {
|
|
442
|
+
try {
|
|
443
|
+
const taskId = req.params?.taskId;
|
|
444
|
+
if (!taskId) {
|
|
445
|
+
this.sendError(res, 400, 'Missing task ID');
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
await this.taskManager.cancelTask(taskId);
|
|
449
|
+
this.setCorsHeaders(res);
|
|
450
|
+
res.setHeader('Content-Type', 'application/json');
|
|
451
|
+
res.end(JSON.stringify({ success: true }));
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
const message = error instanceof Error ? error.message : 'Failed to cancel task';
|
|
455
|
+
this.sendError(res, 500, message);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
async handleTaskSubscribe(req, res) {
|
|
459
|
+
const taskId = req.params?.taskId;
|
|
460
|
+
if (!taskId) {
|
|
461
|
+
this.sendError(res, 400, 'Missing task ID');
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
const task = await this.taskStore.get(taskId);
|
|
465
|
+
if (!task) {
|
|
466
|
+
this.sendError(res, 404, 'Task not found');
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
// Set SSE headers
|
|
470
|
+
this.setCorsHeaders(res);
|
|
471
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
472
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
473
|
+
res.setHeader('Connection', 'keep-alive');
|
|
474
|
+
res.setHeader('X-Accel-Buffering', 'no');
|
|
475
|
+
res.flushHeaders();
|
|
476
|
+
// Send initial state
|
|
477
|
+
res.write(`data: ${JSON.stringify({ type: 'task_state', task })}\n\n`);
|
|
478
|
+
// Subscribe to task events using EventEmitter
|
|
479
|
+
const onStateChange = (event) => {
|
|
480
|
+
const e = event;
|
|
481
|
+
if (e.taskId === taskId && !res.writableEnded) {
|
|
482
|
+
res.write(`data: ${JSON.stringify(event)}\n\n`);
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
const onArtifact = (event) => {
|
|
486
|
+
const e = event;
|
|
487
|
+
if (e.taskId === taskId && !res.writableEnded) {
|
|
488
|
+
res.write(`data: ${JSON.stringify(event)}\n\n`);
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
this.taskManager.on('stateChange', onStateChange);
|
|
492
|
+
this.taskManager.on('artifactAdded', onArtifact);
|
|
493
|
+
// Handle client disconnect
|
|
494
|
+
req.on('close', () => {
|
|
495
|
+
this.taskManager.off('stateChange', onStateChange);
|
|
496
|
+
this.taskManager.off('artifactAdded', onArtifact);
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
async handleTaskList(req, res) {
|
|
500
|
+
try {
|
|
501
|
+
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
|
|
502
|
+
const status = url.searchParams.get('status') || undefined;
|
|
503
|
+
const limit = parseInt(url.searchParams.get('limit') || '50', 10);
|
|
504
|
+
const result = await this.taskStore.query({ status: status, limit });
|
|
505
|
+
this.setCorsHeaders(res);
|
|
506
|
+
res.setHeader('Content-Type', 'application/json');
|
|
507
|
+
res.end(JSON.stringify(result));
|
|
508
|
+
}
|
|
509
|
+
catch (error) {
|
|
510
|
+
const message = error instanceof Error ? error.message : 'Failed to list tasks';
|
|
511
|
+
this.sendError(res, 500, message);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
// ============================================================================
|
|
515
|
+
// Push Notification Handlers (ADR-054)
|
|
516
|
+
// ============================================================================
|
|
517
|
+
async handlePushNotificationSet(req, res) {
|
|
518
|
+
try {
|
|
519
|
+
const taskId = req.params?.taskId;
|
|
520
|
+
if (!taskId) {
|
|
521
|
+
this.sendError(res, 400, 'Missing task ID');
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
const body = await this.parseBody(req);
|
|
525
|
+
const { url, token, events } = body;
|
|
526
|
+
if (!url) {
|
|
527
|
+
this.sendError(res, 400, 'Missing required field: url');
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
// Validate URL
|
|
531
|
+
try {
|
|
532
|
+
new URL(url);
|
|
533
|
+
}
|
|
534
|
+
catch {
|
|
535
|
+
this.sendError(res, 400, 'Invalid webhook URL');
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
// Create subscription
|
|
539
|
+
if (this.subscriptionStore) {
|
|
540
|
+
const webhookEvents = events || ['task.completed', 'task.failed'];
|
|
541
|
+
this.subscriptionStore.create(taskId, {
|
|
542
|
+
url,
|
|
543
|
+
secret: token || '',
|
|
544
|
+
events: webhookEvents,
|
|
545
|
+
timeout: 30000,
|
|
546
|
+
maxRetries: 5,
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
this.setCorsHeaders(res);
|
|
550
|
+
res.setHeader('Content-Type', 'application/json');
|
|
551
|
+
res.statusCode = 200;
|
|
552
|
+
res.end(JSON.stringify({ success: true }));
|
|
553
|
+
}
|
|
554
|
+
catch (error) {
|
|
555
|
+
const message = error instanceof Error ? error.message : 'Failed to set push notification';
|
|
556
|
+
this.sendError(res, 500, message);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
async handlePushNotificationGet(req, res) {
|
|
560
|
+
try {
|
|
561
|
+
const taskId = req.params?.taskId;
|
|
562
|
+
if (!taskId) {
|
|
563
|
+
this.sendError(res, 400, 'Missing task ID');
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
const subscriptions = this.subscriptionStore?.listByTask(taskId) || [];
|
|
567
|
+
if (subscriptions.length === 0) {
|
|
568
|
+
this.sendError(res, 404, 'No push notification configured for this task');
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
const subscription = subscriptions[0];
|
|
572
|
+
this.setCorsHeaders(res);
|
|
573
|
+
res.setHeader('Content-Type', 'application/json');
|
|
574
|
+
res.end(JSON.stringify({
|
|
575
|
+
url: subscription.webhookConfig.url,
|
|
576
|
+
events: subscription.webhookConfig.events,
|
|
577
|
+
}));
|
|
578
|
+
}
|
|
579
|
+
catch (error) {
|
|
580
|
+
const message = error instanceof Error ? error.message : 'Failed to get push notification';
|
|
581
|
+
this.sendError(res, 500, message);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
async handlePushNotificationDelete(req, res) {
|
|
585
|
+
try {
|
|
586
|
+
const taskId = req.params?.taskId;
|
|
587
|
+
if (!taskId) {
|
|
588
|
+
this.sendError(res, 400, 'Missing task ID');
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
// Remove all subscriptions for this task
|
|
592
|
+
const subscriptions = this.subscriptionStore?.listByTask(taskId) || [];
|
|
593
|
+
for (const sub of subscriptions) {
|
|
594
|
+
this.subscriptionStore?.delete(sub.id);
|
|
595
|
+
}
|
|
596
|
+
this.setCorsHeaders(res);
|
|
597
|
+
res.statusCode = 204;
|
|
598
|
+
res.end();
|
|
599
|
+
}
|
|
600
|
+
catch (error) {
|
|
601
|
+
const message = error instanceof Error ? error.message : 'Failed to delete push notification';
|
|
602
|
+
this.sendError(res, 500, message);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
// ============================================================================
|
|
606
|
+
// AG-UI Handler
|
|
607
|
+
// ============================================================================
|
|
608
|
+
async handleAgentStream(req, res) {
|
|
609
|
+
// Delegate to SSE transport (which now has the handler wired)
|
|
610
|
+
await this.sseTransport.handleRequest(req, res);
|
|
611
|
+
}
|
|
612
|
+
// ============================================================================
|
|
613
|
+
// Utility Handlers
|
|
614
|
+
// ============================================================================
|
|
615
|
+
handleCorsPreFlight(_req, res) {
|
|
616
|
+
this.setCorsHeaders(res);
|
|
617
|
+
res.statusCode = 204;
|
|
618
|
+
res.end();
|
|
619
|
+
}
|
|
620
|
+
handleHealth(_req, res) {
|
|
621
|
+
this.setCorsHeaders(res);
|
|
622
|
+
res.setHeader('Content-Type', 'application/json');
|
|
623
|
+
res.end(JSON.stringify({
|
|
624
|
+
status: 'ok',
|
|
625
|
+
version: '3.0.0',
|
|
626
|
+
protocols: ['ag-ui', 'a2a', 'a2ui'],
|
|
627
|
+
agentCardsLoaded: this.agentCardsLoaded,
|
|
628
|
+
agentCount: this.discoveryService.getAgentCount(),
|
|
629
|
+
timestamp: new Date().toISOString(),
|
|
630
|
+
}));
|
|
631
|
+
}
|
|
632
|
+
// ============================================================================
|
|
633
|
+
// Helpers
|
|
634
|
+
// ============================================================================
|
|
635
|
+
async parseBody(req) {
|
|
636
|
+
return new Promise((resolve, reject) => {
|
|
637
|
+
const chunks = [];
|
|
638
|
+
let size = 0;
|
|
639
|
+
const maxSize = 1024 * 1024; // 1MB
|
|
640
|
+
req.on('data', (chunk) => {
|
|
641
|
+
size += chunk.length;
|
|
642
|
+
if (size > maxSize) {
|
|
643
|
+
reject(new Error('Request body too large'));
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
chunks.push(chunk);
|
|
647
|
+
});
|
|
648
|
+
req.on('end', () => {
|
|
649
|
+
try {
|
|
650
|
+
const body = Buffer.concat(chunks).toString('utf-8');
|
|
651
|
+
if (!body) {
|
|
652
|
+
resolve({});
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
resolve(JSON.parse(body));
|
|
656
|
+
}
|
|
657
|
+
catch (error) {
|
|
658
|
+
reject(new Error('Invalid JSON in request body'));
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
req.on('error', reject);
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
setCorsHeaders(res) {
|
|
665
|
+
if (this.enableCors) {
|
|
666
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
667
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
|
|
668
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
|
|
669
|
+
res.setHeader('Access-Control-Max-Age', '86400');
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
sendError(res, code, message) {
|
|
673
|
+
this.setCorsHeaders(res);
|
|
674
|
+
res.setHeader('Content-Type', 'application/json');
|
|
675
|
+
res.statusCode = code;
|
|
676
|
+
res.end(JSON.stringify({ error: { code, message } }));
|
|
677
|
+
}
|
|
678
|
+
// ============================================================================
|
|
679
|
+
// Server Lifecycle
|
|
680
|
+
// ============================================================================
|
|
681
|
+
async start(port) {
|
|
682
|
+
if (this.running) {
|
|
683
|
+
throw new Error('Server already running');
|
|
684
|
+
}
|
|
685
|
+
// CRITICAL: Initialize CRDT for distributed state
|
|
686
|
+
if (!this.skipCRDTInit) {
|
|
687
|
+
try {
|
|
688
|
+
const memory = getUnifiedMemory();
|
|
689
|
+
if (!memory.isCRDTInitialized()) {
|
|
690
|
+
memory.initializeCRDT(`aqe-http-${process.pid}-${Date.now()}`);
|
|
691
|
+
console.error('[AQE] CRDT store initialized');
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
catch (error) {
|
|
695
|
+
console.error('[AQE] WARNING: Failed to initialize CRDT:', error);
|
|
696
|
+
// Non-fatal, continue without CRDT
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
// CRITICAL: Load agent cards before accepting connections
|
|
700
|
+
if (!this.skipAgentCardLoading) {
|
|
701
|
+
try {
|
|
702
|
+
await this.discoveryService.loadCards(this.agentMarkdownDir);
|
|
703
|
+
this.agentCardsLoaded = true;
|
|
704
|
+
console.error(`[AQE] Loaded ${this.discoveryService.getAgentCount()} agent cards`);
|
|
705
|
+
}
|
|
706
|
+
catch (error) {
|
|
707
|
+
console.error('[AQE] WARNING: Failed to load agent cards:', error);
|
|
708
|
+
// Non-fatal, discovery will return empty results
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
return new Promise(async (resolve, reject) => {
|
|
712
|
+
this.server = createServer((req, res) => {
|
|
713
|
+
this.handleHttpRequest(req, res).catch((error) => {
|
|
714
|
+
console.error('[HTTP] Request error:', error);
|
|
715
|
+
this.sendError(res, 500, 'Internal server error');
|
|
716
|
+
});
|
|
717
|
+
});
|
|
718
|
+
this.server.on('error', (error) => {
|
|
719
|
+
reject(error);
|
|
720
|
+
});
|
|
721
|
+
// Attach WebSocket transport for bidirectional streaming
|
|
722
|
+
if (this.webSocketTransport && this.enableWebSocket) {
|
|
723
|
+
try {
|
|
724
|
+
await this.webSocketTransport.attach(this.server, '/agent/ws');
|
|
725
|
+
console.error('[AQE] WebSocket transport attached at /agent/ws');
|
|
726
|
+
}
|
|
727
|
+
catch (error) {
|
|
728
|
+
console.error('[AQE] WARNING: Failed to attach WebSocket transport:', error);
|
|
729
|
+
// Non-fatal, SSE is still available as fallback
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
// Start hot reload watcher if enabled (ADR-054)
|
|
733
|
+
if (this.enableHotReload && this.hotReloadService) {
|
|
734
|
+
this.hotReloadService.start().then(() => {
|
|
735
|
+
console.error('[AQE] Hot reload enabled for agent cards');
|
|
736
|
+
}).catch(err => {
|
|
737
|
+
console.error('[AQE] WARNING: Failed to start hot reload:', err);
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
this.server.listen(port, () => {
|
|
741
|
+
this.running = true;
|
|
742
|
+
console.error(`[AQE] HTTP server started on port ${port}`);
|
|
743
|
+
console.error(`[AQE] Endpoints ready:`);
|
|
744
|
+
console.error(`[AQE] GET /.well-known/agent.json - Platform discovery (${this.discoveryService.getAgentCount()} agents)`);
|
|
745
|
+
console.error(`[AQE] POST /agent/stream - AG-UI SSE streaming (default)`);
|
|
746
|
+
if (this.webSocketTransport) {
|
|
747
|
+
console.error(`[AQE] WS /agent/ws - AG-UI WebSocket streaming (<100ms latency)`);
|
|
748
|
+
}
|
|
749
|
+
console.error(`[AQE] POST /a2a/tasks - A2A task submission`);
|
|
750
|
+
if (this.enablePushNotifications) {
|
|
751
|
+
console.error(`[AQE] POST /a2a/tasks/:id/pushNotification - Push notification subscription`);
|
|
752
|
+
}
|
|
753
|
+
if (this.enableOAuth) {
|
|
754
|
+
console.error(`[AQE] OAuth 2.0 protection enabled`);
|
|
755
|
+
}
|
|
756
|
+
if (this.enableHotReload) {
|
|
757
|
+
console.error(`[AQE] Hot reload enabled for agent cards`);
|
|
758
|
+
}
|
|
759
|
+
console.error(`[AQE] GET /health - Health check`);
|
|
760
|
+
resolve();
|
|
761
|
+
});
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
async handleHttpRequest(req, res) {
|
|
765
|
+
const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
|
|
766
|
+
const path = url.pathname;
|
|
767
|
+
const method = req.method || 'GET';
|
|
768
|
+
// Try to match route
|
|
769
|
+
const match = this.router.match(method, path);
|
|
770
|
+
if (match) {
|
|
771
|
+
// Attach params to request
|
|
772
|
+
req.params = match.params;
|
|
773
|
+
await match.handler(req, res);
|
|
774
|
+
}
|
|
775
|
+
else {
|
|
776
|
+
// 404 Not Found
|
|
777
|
+
this.sendError(res, 404, 'Not found');
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
async stop() {
|
|
781
|
+
if (!this.running || !this.server) {
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
return new Promise((resolve) => {
|
|
785
|
+
this.server.close(() => {
|
|
786
|
+
this.running = false;
|
|
787
|
+
this.server = null;
|
|
788
|
+
console.error('[AQE] HTTP server stopped');
|
|
789
|
+
resolve();
|
|
790
|
+
});
|
|
791
|
+
// Close SSE transport
|
|
792
|
+
this.sseTransport.dispose();
|
|
793
|
+
// Close WebSocket transport
|
|
794
|
+
if (this.webSocketTransport) {
|
|
795
|
+
this.webSocketTransport.dispose();
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
// ============================================================================
|
|
800
|
+
// Accessors
|
|
801
|
+
// ============================================================================
|
|
802
|
+
getEventAdapter() {
|
|
803
|
+
return this.eventAdapter;
|
|
804
|
+
}
|
|
805
|
+
getDiscoveryService() {
|
|
806
|
+
return this.discoveryService;
|
|
807
|
+
}
|
|
808
|
+
getTaskManager() {
|
|
809
|
+
return this.taskManager;
|
|
810
|
+
}
|
|
811
|
+
getServer() {
|
|
812
|
+
return this.server;
|
|
813
|
+
}
|
|
814
|
+
getWebSocketTransport() {
|
|
815
|
+
return this.webSocketTransport;
|
|
816
|
+
}
|
|
817
|
+
isRunning() {
|
|
818
|
+
return this.running;
|
|
819
|
+
}
|
|
820
|
+
hasLoadedAgentCards() {
|
|
821
|
+
return this.agentCardsLoaded;
|
|
822
|
+
}
|
|
823
|
+
isWebSocketEnabled() {
|
|
824
|
+
return this.enableWebSocket && this.webSocketTransport !== null;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
// ============================================================================
|
|
828
|
+
// Factory Function
|
|
829
|
+
// ============================================================================
|
|
830
|
+
export function createHTTPServer(config) {
|
|
831
|
+
return new HTTPServerImpl(config);
|
|
832
|
+
}
|
|
833
|
+
//# sourceMappingURL=http-server.js.map
|