@aws/nx-plugin 1.0.0-rc.73 → 1.0.0-rc.75

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.
Files changed (39) hide show
  1. package/LICENSE-THIRD-PARTY +495 -1188
  2. package/README.md +7 -89
  3. package/migrations.json +11 -1
  4. package/package.json +1 -1
  5. package/src/internal/test-matrix/generator.js +15 -0
  6. package/src/internal/test-matrix/generator.js.map +1 -1
  7. package/src/license/dependency-check/collectors/python-collector.js +9 -3
  8. package/src/license/dependency-check/collectors/python-collector.js.map +1 -1
  9. package/src/migrations/latest/py-agent-session-id-middleware-extraction/metadata.json +3 -0
  10. package/src/migrations/latest/py-agent-session-id-middleware-extraction/migration.d.ts +2 -0
  11. package/src/migrations/latest/py-agent-session-id-middleware-extraction/migration.js +118 -0
  12. package/src/migrations/latest/py-agent-session-id-middleware-extraction/migration.js.map +1 -0
  13. package/src/migrations/latest/ts-agent-session-id-middleware-extraction/metadata.json +3 -0
  14. package/src/migrations/latest/ts-agent-session-id-middleware-extraction/migration.d.ts +2 -0
  15. package/src/migrations/latest/ts-agent-session-id-middleware-extraction/migration.js +124 -0
  16. package/src/migrations/latest/ts-agent-session-id-middleware-extraction/migration.js.map +1 -0
  17. package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +3 -18
  18. package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +2 -13
  19. package/src/py/agent/files/langchain/a2a/main.py.template +4 -15
  20. package/src/py/agent/files/langchain/ag-ui/main.py.template +2 -13
  21. package/src/py/agent/files/langchain/common/middleware/__init__.py.template +0 -0
  22. package/src/py/agent/files/langchain/common/middleware/session_id_middleware.py.template +17 -0
  23. package/src/py/agent/files/langchain/http/main.py.template +2 -14
  24. package/src/py/agent/files/strands/a2a/main.py.template +4 -15
  25. package/src/py/agent/files/strands/ag-ui/main.py.template +2 -13
  26. package/src/py/agent/files/strands/common/middleware/__init__.py.template +0 -0
  27. package/src/py/agent/files/strands/common/middleware/session_id_middleware.py.template +17 -0
  28. package/src/py/agent/files/strands/http/main.py.template +2 -17
  29. package/src/sdk/agentcore-harness.d.ts +6 -0
  30. package/src/sdk/agentcore-harness.js +7 -0
  31. package/src/sdk/agentcore-harness.js.map +1 -0
  32. package/src/sdk/smithy.d.ts +6 -0
  33. package/src/sdk/smithy.js +7 -0
  34. package/src/sdk/smithy.js.map +1 -0
  35. package/src/ts/agent/files/a2a/index.ts.template +4 -11
  36. package/src/ts/agent/files/ag-ui/index.ts.template +2 -12
  37. package/src/ts/agent/files/common-express/middleware/session-id-middleware.ts.template +16 -0
  38. package/src/ts/agent/generator.js +8 -0
  39. package/src/ts/agent/generator.js.map +1 -1
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ import { readFileSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { getProjects, joinPathFragments } from "@nx/devkit";
7
+ import { TS_AGENT_GENERATOR_INFO } from "../../../ts/agent/generator.js";
8
+ import { addDestructuredImport, applyGritQL, captureGritQLVariable, matchGritQL } from "../../../utils/ast.js";
9
+ import { formatFilesInSubtree } from "../../../utils/format.js";
10
+ /**
11
+ * Extract the inline session-id Express middleware - previously duplicated
12
+ * verbatim in every ts#agent AG-UI/A2A `index.ts` - into a shared
13
+ * `middleware/session-id-middleware.ts` module sitting beside `index.ts`,
14
+ * mirroring how `agent.ts`/`session.ts` are already shared siblings.
15
+ *
16
+ * HTTP is untouched: its one procedure is a tRPC subscription served over
17
+ * WebSocket, which bypasses Express entirely, so it never had this middleware
18
+ * to begin with (see `enterSessionContext` in its `router.ts` instead).
19
+ *
20
+ * AG-UI and A2A wire the same logic up differently - AG-UI binds it to a
21
+ * named `sessionIdMiddleware` const before use, while A2A inlines it directly
22
+ * at the `app.use` call site - so each gets its own old-shape pattern below,
23
+ * even though both resolve to the same shared middleware content.
24
+ *
25
+ * Guardrails:
26
+ * - Pattern-match before writing: skip files that have diverged from the
27
+ * generated shape and report them via `nextSteps`, rather than clobbering
28
+ * the user's changes.
29
+ * - Idempotent: re-running is a no-op once migrated.
30
+ */ const EXPRESS_IMPORT_OLD = "import express, { type Request, type Response, type NextFunction } from 'express';";
31
+ const EXPRESS_IMPORT_NEW = "import express from 'express';";
32
+ const RANDOM_UUID_IMPORT = "import { randomUUID } from 'node:crypto';";
33
+ const SESSION_ID_HEADER_LINE = "const SESSION_ID_HEADER = 'x-amzn-bedrock-agentcore-runtime-session-id';";
34
+ // The leading comment sits directly above both shapes below. GritQL can only
35
+ // match it as its own comment node - folding it into the same backtick
36
+ // snippet as the statement that follows fails to parse as one construct - so
37
+ // it's matched/deleted as a separate step from the statement/expression.
38
+ const MIDDLEWARE_LEADING_COMMENT = '// Bind the inbound session (or a fresh UUID) for downstream MCP / A2A calls.';
39
+ // AG-UI binds the middleware to a named const, used later via `app.use(sessionIdMiddleware)`.
40
+ const AGUI_MIDDLEWARE_DEFINITION_OLD = `const sessionIdMiddleware = (req: Request, _res: Response, next: NextFunction) => {
41
+ const header = req.headers[SESSION_ID_HEADER];
42
+ const sessionId = (Array.isArray(header) ? header[0] : header) ?? randomUUID();
43
+ runWithSessionId(sessionId, () => next());
44
+ };`;
45
+ // A2A inlines the same logic directly at the `app.use` call site instead.
46
+ const A2A_MIDDLEWARE_USE_OLD = `app.use((req: Request, _res: Response, next: NextFunction) => {
47
+ const header = req.headers[SESSION_ID_HEADER];
48
+ const sessionId = (Array.isArray(header) ? header[0] : header) ?? randomUUID();
49
+ runWithSessionId(sessionId, () => next());
50
+ });`;
51
+ const A2A_MIDDLEWARE_USE_NEW = 'app.use(sessionIdMiddleware);';
52
+ // Captures the agent-connection package specifier so the new middleware
53
+ // module targets the same one. Generic over `$names` since a connection
54
+ // generator may have merged its own import into this same statement.
55
+ const RUNWITHSESSIONID_IMPORT_CAPTURE = "`import { $names } from '$mod';` where { $names <: contains `runWithSessionId` }";
56
+ // Removes `runWithSessionId` from the named import, preserving any other
57
+ // merged specifiers (or the whole statement if it was the only one).
58
+ // Decomposed via `import_clause(name=named_imports($imports))` since a naive
59
+ // `$rest`-based rewrite silently fails once other specifiers are involved.
60
+ const REMOVE_RUNWITHSESSIONID_IMPORT_PATTERN = `\`import $clause from '$mod';\` as $import where {
61
+ $clause <: import_clause(name=named_imports($imports)),
62
+ $imports <: contains \`runWithSessionId\`,
63
+ if ($imports <: [\`runWithSessionId\`]) { $import => . } else { $imports <: some import_specifier(name=\`runWithSessionId\`) => . }
64
+ }`;
65
+ // Both protocols' `common-express/` dir vends byte-identical middleware
66
+ // content; read as the single source of truth rather than hand-duplicating
67
+ // it here.
68
+ const SESSION_ID_MIDDLEWARE_TEMPLATE = readFileSync(join(import.meta.dirname, '../../../ts/agent/files/common-express/middleware/session-id-middleware.ts.template'), 'utf-8');
69
+ const sessionIdMiddlewareContent = (agentConnectionImport)=>SESSION_ID_MIDDLEWARE_TEMPLATE.replace('<%- agentConnectionImport %>', agentConnectionImport);
70
+ const findAgentComponents = (components)=>(components ?? []).filter((component)=>component.generator === TS_AGENT_GENERATOR_INFO.id && (component.protocol === 'ag-ui' || component.protocol === 'a2a'));
71
+ const migrateIndex = async (tree, indexPath, protocol, nextSteps)=>{
72
+ if (!tree.exists(indexPath)) return;
73
+ const contents = tree.read(indexPath, 'utf-8') ?? '';
74
+ if (!contents.includes(SESSION_ID_HEADER_LINE)) return;
75
+ const middlewarePattern = protocol === 'ag-ui' ? AGUI_MIDDLEWARE_DEFINITION_OLD : A2A_MIDDLEWARE_USE_OLD;
76
+ const diverged = ()=>{
77
+ nextSteps.push(`${indexPath}: diverged from the generated ts#agent ${protocol} shape - left untouched. Manually move the inline session-id middleware into a sibling \`middleware/session-id-middleware.ts\` module and import \`sessionIdMiddleware\` from there (see the ts#agent generator's template).`);
78
+ };
79
+ const ready = await matchGritQL(tree, indexPath, `\`${EXPRESS_IMPORT_OLD}\``) && await matchGritQL(tree, indexPath, `\`${RANDOM_UUID_IMPORT}\``) && await matchGritQL(tree, indexPath, `\`${SESSION_ID_HEADER_LINE}\``) && await matchGritQL(tree, indexPath, `\`${MIDDLEWARE_LEADING_COMMENT}\``) && await matchGritQL(tree, indexPath, `\`${middlewarePattern}\``) && await matchGritQL(tree, indexPath, RUNWITHSESSIONID_IMPORT_CAPTURE);
80
+ if (!ready) {
81
+ diverged();
82
+ return;
83
+ }
84
+ const mod = await captureGritQLVariable(tree, indexPath, RUNWITHSESSIONID_IMPORT_CAPTURE, 'mod');
85
+ if (!mod) {
86
+ diverged();
87
+ return;
88
+ }
89
+ const dir = indexPath.split('/').slice(0, -1).join('/');
90
+ const middlewarePath = joinPathFragments(dir, 'middleware', 'session-id-middleware.ts');
91
+ if (!tree.exists(middlewarePath)) {
92
+ tree.write(middlewarePath, sessionIdMiddlewareContent(mod));
93
+ }
94
+ await applyGritQL(tree, indexPath, `\`${EXPRESS_IMPORT_OLD}\` => \`${EXPRESS_IMPORT_NEW}\``);
95
+ await applyGritQL(tree, indexPath, `\`${RANDOM_UUID_IMPORT}\` => .`);
96
+ await applyGritQL(tree, indexPath, `\`${SESSION_ID_HEADER_LINE}\` => .`);
97
+ await applyGritQL(tree, indexPath, REMOVE_RUNWITHSESSIONID_IMPORT_PATTERN);
98
+ await applyGritQL(tree, indexPath, `\`${MIDDLEWARE_LEADING_COMMENT}\` => .`);
99
+ if (protocol === 'ag-ui') {
100
+ await applyGritQL(tree, indexPath, `\`${AGUI_MIDDLEWARE_DEFINITION_OLD}\` => .`);
101
+ } else {
102
+ await applyGritQL(tree, indexPath, `\`${A2A_MIDDLEWARE_USE_OLD}\` => \`${A2A_MIDDLEWARE_USE_NEW}\``);
103
+ }
104
+ await addDestructuredImport(tree, indexPath, [
105
+ 'sessionIdMiddleware'
106
+ ], './middleware/session-id-middleware.js');
107
+ };
108
+ export default async function migration(tree) {
109
+ const nextSteps = [];
110
+ for (const project of getProjects(tree).values()){
111
+ const components = findAgentComponents(project.metadata?.components);
112
+ for (const component of components){
113
+ if (!component.path) continue;
114
+ const indexPath = joinPathFragments(project.root, component.path, 'index.ts');
115
+ await migrateIndex(tree, indexPath, component.protocol, nextSteps);
116
+ }
117
+ }
118
+ await formatFilesInSubtree(tree);
119
+ return {
120
+ nextSteps
121
+ };
122
+ }
123
+
124
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../packages/nx-plugin/src/migrations/latest/ts-agent-session-id-middleware-extraction/migration.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport {\n getProjects,\n joinPathFragments,\n type MigrationReturnObject,\n type Tree,\n} from '@nx/devkit';\nimport { TS_AGENT_GENERATOR_INFO } from '../../../ts/agent/generator';\nimport {\n addDestructuredImport,\n applyGritQL,\n captureGritQLVariable,\n matchGritQL,\n} from '../../../utils/ast';\nimport { formatFilesInSubtree } from '../../../utils/format';\nimport type { ComponentMetadata } from '../../../utils/nx';\n\n/**\n * Extract the inline session-id Express middleware - previously duplicated\n * verbatim in every ts#agent AG-UI/A2A `index.ts` - into a shared\n * `middleware/session-id-middleware.ts` module sitting beside `index.ts`,\n * mirroring how `agent.ts`/`session.ts` are already shared siblings.\n *\n * HTTP is untouched: its one procedure is a tRPC subscription served over\n * WebSocket, which bypasses Express entirely, so it never had this middleware\n * to begin with (see `enterSessionContext` in its `router.ts` instead).\n *\n * AG-UI and A2A wire the same logic up differently - AG-UI binds it to a\n * named `sessionIdMiddleware` const before use, while A2A inlines it directly\n * at the `app.use` call site - so each gets its own old-shape pattern below,\n * even though both resolve to the same shared middleware content.\n *\n * Guardrails:\n * - Pattern-match before writing: skip files that have diverged from the\n * generated shape and report them via `nextSteps`, rather than clobbering\n * the user's changes.\n * - Idempotent: re-running is a no-op once migrated.\n */\n\nconst EXPRESS_IMPORT_OLD =\n \"import express, { type Request, type Response, type NextFunction } from 'express';\";\nconst EXPRESS_IMPORT_NEW = \"import express from 'express';\";\n\nconst RANDOM_UUID_IMPORT = \"import { randomUUID } from 'node:crypto';\";\n\nconst SESSION_ID_HEADER_LINE =\n \"const SESSION_ID_HEADER = 'x-amzn-bedrock-agentcore-runtime-session-id';\";\n\n// The leading comment sits directly above both shapes below. GritQL can only\n// match it as its own comment node - folding it into the same backtick\n// snippet as the statement that follows fails to parse as one construct - so\n// it's matched/deleted as a separate step from the statement/expression.\nconst MIDDLEWARE_LEADING_COMMENT =\n '// Bind the inbound session (or a fresh UUID) for downstream MCP / A2A calls.';\n\n// AG-UI binds the middleware to a named const, used later via `app.use(sessionIdMiddleware)`.\nconst AGUI_MIDDLEWARE_DEFINITION_OLD = `const sessionIdMiddleware = (req: Request, _res: Response, next: NextFunction) => {\n const header = req.headers[SESSION_ID_HEADER];\n const sessionId = (Array.isArray(header) ? header[0] : header) ?? randomUUID();\n runWithSessionId(sessionId, () => next());\n};`;\n\n// A2A inlines the same logic directly at the `app.use` call site instead.\nconst A2A_MIDDLEWARE_USE_OLD = `app.use((req: Request, _res: Response, next: NextFunction) => {\n const header = req.headers[SESSION_ID_HEADER];\n const sessionId = (Array.isArray(header) ? header[0] : header) ?? randomUUID();\n runWithSessionId(sessionId, () => next());\n });`;\nconst A2A_MIDDLEWARE_USE_NEW = 'app.use(sessionIdMiddleware);';\n\n// Captures the agent-connection package specifier so the new middleware\n// module targets the same one. Generic over `$names` since a connection\n// generator may have merged its own import into this same statement.\nconst RUNWITHSESSIONID_IMPORT_CAPTURE =\n \"`import { $names } from '$mod';` where { $names <: contains `runWithSessionId` }\";\n\n// Removes `runWithSessionId` from the named import, preserving any other\n// merged specifiers (or the whole statement if it was the only one).\n// Decomposed via `import_clause(name=named_imports($imports))` since a naive\n// `$rest`-based rewrite silently fails once other specifiers are involved.\nconst REMOVE_RUNWITHSESSIONID_IMPORT_PATTERN = `\\`import $clause from '$mod';\\` as $import where {\n $clause <: import_clause(name=named_imports($imports)),\n $imports <: contains \\`runWithSessionId\\`,\n if ($imports <: [\\`runWithSessionId\\`]) { $import => . } else { $imports <: some import_specifier(name=\\`runWithSessionId\\`) => . }\n}`;\n\n// Both protocols' `common-express/` dir vends byte-identical middleware\n// content; read as the single source of truth rather than hand-duplicating\n// it here.\nconst SESSION_ID_MIDDLEWARE_TEMPLATE = readFileSync(\n join(\n import.meta.dirname,\n '../../../ts/agent/files/common-express/middleware/session-id-middleware.ts.template',\n ),\n 'utf-8',\n);\n\nconst sessionIdMiddlewareContent = (agentConnectionImport: string): string =>\n SESSION_ID_MIDDLEWARE_TEMPLATE.replace(\n '<%- agentConnectionImport %>',\n agentConnectionImport,\n );\n\nconst findAgentComponents = (\n components: ComponentMetadata[] | undefined,\n): ComponentMetadata[] =>\n (components ?? []).filter(\n (component) =>\n component.generator === TS_AGENT_GENERATOR_INFO.id &&\n (component.protocol === 'ag-ui' || component.protocol === 'a2a'),\n );\n\nconst migrateIndex = async (\n tree: Tree,\n indexPath: string,\n protocol: 'ag-ui' | 'a2a',\n nextSteps: string[],\n): Promise<void> => {\n if (!tree.exists(indexPath)) return;\n\n const contents = tree.read(indexPath, 'utf-8') ?? '';\n if (!contents.includes(SESSION_ID_HEADER_LINE)) return;\n\n const middlewarePattern =\n protocol === 'ag-ui'\n ? AGUI_MIDDLEWARE_DEFINITION_OLD\n : A2A_MIDDLEWARE_USE_OLD;\n\n const diverged = () => {\n nextSteps.push(\n `${indexPath}: diverged from the generated ts#agent ${protocol} shape - left untouched. Manually move the inline session-id middleware into a sibling \\`middleware/session-id-middleware.ts\\` module and import \\`sessionIdMiddleware\\` from there (see the ts#agent generator's template).`,\n );\n };\n\n const ready =\n (await matchGritQL(tree, indexPath, `\\`${EXPRESS_IMPORT_OLD}\\``)) &&\n (await matchGritQL(tree, indexPath, `\\`${RANDOM_UUID_IMPORT}\\``)) &&\n (await matchGritQL(tree, indexPath, `\\`${SESSION_ID_HEADER_LINE}\\``)) &&\n (await matchGritQL(tree, indexPath, `\\`${MIDDLEWARE_LEADING_COMMENT}\\``)) &&\n (await matchGritQL(tree, indexPath, `\\`${middlewarePattern}\\``)) &&\n (await matchGritQL(tree, indexPath, RUNWITHSESSIONID_IMPORT_CAPTURE));\n\n if (!ready) {\n diverged();\n return;\n }\n\n const mod = await captureGritQLVariable(\n tree,\n indexPath,\n RUNWITHSESSIONID_IMPORT_CAPTURE,\n 'mod',\n );\n if (!mod) {\n diverged();\n return;\n }\n\n const dir = indexPath.split('/').slice(0, -1).join('/');\n const middlewarePath = joinPathFragments(\n dir,\n 'middleware',\n 'session-id-middleware.ts',\n );\n\n if (!tree.exists(middlewarePath)) {\n tree.write(middlewarePath, sessionIdMiddlewareContent(mod));\n }\n\n await applyGritQL(\n tree,\n indexPath,\n `\\`${EXPRESS_IMPORT_OLD}\\` => \\`${EXPRESS_IMPORT_NEW}\\``,\n );\n await applyGritQL(tree, indexPath, `\\`${RANDOM_UUID_IMPORT}\\` => .`);\n await applyGritQL(tree, indexPath, `\\`${SESSION_ID_HEADER_LINE}\\` => .`);\n await applyGritQL(tree, indexPath, REMOVE_RUNWITHSESSIONID_IMPORT_PATTERN);\n await applyGritQL(tree, indexPath, `\\`${MIDDLEWARE_LEADING_COMMENT}\\` => .`);\n\n if (protocol === 'ag-ui') {\n await applyGritQL(\n tree,\n indexPath,\n `\\`${AGUI_MIDDLEWARE_DEFINITION_OLD}\\` => .`,\n );\n } else {\n await applyGritQL(\n tree,\n indexPath,\n `\\`${A2A_MIDDLEWARE_USE_OLD}\\` => \\`${A2A_MIDDLEWARE_USE_NEW}\\``,\n );\n }\n\n await addDestructuredImport(\n tree,\n indexPath,\n ['sessionIdMiddleware'],\n './middleware/session-id-middleware.js',\n );\n};\n\nexport default async function migration(\n tree: Tree,\n): Promise<MigrationReturnObject> {\n const nextSteps: string[] = [];\n\n for (const project of getProjects(tree).values()) {\n const components = findAgentComponents(\n (project.metadata as { components?: ComponentMetadata[] })?.components,\n );\n\n for (const component of components) {\n if (!component.path) continue;\n\n const indexPath = joinPathFragments(\n project.root,\n component.path,\n 'index.ts',\n );\n\n await migrateIndex(\n tree,\n indexPath,\n component.protocol as 'ag-ui' | 'a2a',\n nextSteps,\n );\n }\n }\n\n await formatFilesInSubtree(tree);\n\n return { nextSteps };\n}\n"],"names":["readFileSync","join","getProjects","joinPathFragments","TS_AGENT_GENERATOR_INFO","addDestructuredImport","applyGritQL","captureGritQLVariable","matchGritQL","formatFilesInSubtree","EXPRESS_IMPORT_OLD","EXPRESS_IMPORT_NEW","RANDOM_UUID_IMPORT","SESSION_ID_HEADER_LINE","MIDDLEWARE_LEADING_COMMENT","AGUI_MIDDLEWARE_DEFINITION_OLD","A2A_MIDDLEWARE_USE_OLD","A2A_MIDDLEWARE_USE_NEW","RUNWITHSESSIONID_IMPORT_CAPTURE","REMOVE_RUNWITHSESSIONID_IMPORT_PATTERN","SESSION_ID_MIDDLEWARE_TEMPLATE","dirname","sessionIdMiddlewareContent","agentConnectionImport","replace","findAgentComponents","components","filter","component","generator","id","protocol","migrateIndex","tree","indexPath","nextSteps","exists","contents","read","includes","middlewarePattern","diverged","push","ready","mod","dir","split","slice","middlewarePath","write","migration","project","values","metadata","path","root"],"mappings":"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"}
@@ -693,18 +693,12 @@ Refer to tools as your 'spellbook'.
693
693
  `;
694
694
 
695
695
  exports[`py#agent generator > should match snapshot for generated files > agent-main.py 1`] = `
696
- "import uuid
697
-
698
- import uvicorn
696
+ "import uvicorn
699
697
  from bedrock_agentcore.runtime.models import PingStatus
700
- from fastapi import Request
701
- from proj_agent_connection import session_id_context
702
698
  from pydantic import BaseModel, Field
703
- from starlette.middleware.base import BaseHTTPMiddleware
704
699
 
705
700
  from .init import JsonStreamingResponse, app
706
-
707
- SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
701
+ from .middleware.session_id_middleware import SessionIdMiddleware
708
702
 
709
703
 
710
704
  class InvokeInput(BaseModel):
@@ -745,16 +739,7 @@ async def invoke(input: InvokeInput) -> JsonStreamingResponse:
745
739
  return JsonStreamingResponse(handle_invoke(input))
746
740
 
747
741
 
748
- class _SessionIdMiddleware(BaseHTTPMiddleware):
749
- """Bind the inbound session (or a fresh UUID) to async context."""
750
-
751
- async def dispatch(self, request: Request, call_next):
752
- session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
753
- with session_id_context(session_id):
754
- return await call_next(request)
755
-
756
-
757
- app.add_middleware(_SessionIdMiddleware)
742
+ app.add_middleware(SessionIdMiddleware)
758
743
 
759
744
 
760
745
  @app.get("/ping")
@@ -618,14 +618,12 @@ from fastapi import FastAPI, Request
618
618
  from fastapi.middleware.cors import CORSMiddleware
619
619
  from fastapi.responses import JSONResponse, StreamingResponse
620
620
  from proj_agent_connection import get_current_session_id, session_id_context
621
- from starlette.middleware.base import BaseHTTPMiddleware
622
621
 
623
622
  from .agent import get_agent
623
+ from .middleware.session_id_middleware import SESSION_ID_HEADER, SessionIdMiddleware
624
624
 
625
625
  logging.basicConfig(level=logging.INFO)
626
626
 
627
- SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
628
-
629
627
 
630
628
  @asynccontextmanager
631
629
  async def lifespan(app: FastAPI):
@@ -638,15 +636,6 @@ async def lifespan(app: FastAPI):
638
636
  yield
639
637
 
640
638
 
641
- class _SessionIdMiddleware(BaseHTTPMiddleware):
642
- """Bind the session ID for this request so downstream MCP / A2A clients forward it on outbound calls."""
643
-
644
- async def dispatch(self, request: Request, call_next):
645
- session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
646
- with session_id_context(session_id):
647
- return await call_next(request)
648
-
649
-
650
639
  app = FastAPI(title="SnapshotAgent", lifespan=lifespan)
651
640
  # Allow browser-based AG-UI clients (e.g. a connected React website) to call
652
641
  # this agent cross-origin, including the CORS preflight.
@@ -657,7 +646,7 @@ app.add_middleware(
657
646
  allow_methods=["*"],
658
647
  allow_headers=["*"],
659
648
  )
660
- app.add_middleware(_SessionIdMiddleware)
649
+ app.add_middleware(SessionIdMiddleware)
661
650
 
662
651
 
663
652
  @app.post("/invocations")
@@ -1,6 +1,5 @@
1
1
  import logging
2
2
  import os
3
- import uuid
4
3
  from contextlib import asynccontextmanager
5
4
 
6
5
  from a2a.server.agent_execution import AgentExecutor, RequestContext
@@ -10,18 +9,17 @@ from a2a.server.request_handlers import DefaultRequestHandler
10
9
  from a2a.server.tasks import InMemoryTaskStore, TaskUpdater
11
10
  from a2a.types import AgentCapabilities, AgentCard, Part, TextPart
12
11
  from a2a.utils import new_task
13
- from fastapi import FastAPI, Request
14
- from starlette.middleware.base import BaseHTTPMiddleware
12
+ from fastapi import FastAPI
15
13
 
16
- from <%- agentConnectionModuleName %> import get_current_session_id, session_id_context
14
+ from <%- agentConnectionModuleName %> import get_current_session_id
17
15
 
18
16
  from .agent import get_agent
17
+ from .middleware.session_id_middleware import SessionIdMiddleware
19
18
 
20
19
  logging.basicConfig(level=logging.INFO)
21
20
 
22
21
  PORT = int(os.environ.get("PORT", "9000"))
23
22
  RUNTIME_URL = os.environ.get("AGENTCORE_RUNTIME_URL", f"http://localhost:{PORT}/")
24
- SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
25
23
  DEFAULT_MODES = ["text/plain"]
26
24
 
27
25
 
@@ -73,17 +71,8 @@ _agent_card = AgentCard(
73
71
  a2a_app = A2AStarletteApplication(agent_card=_agent_card, http_handler=_handler).build()
74
72
 
75
73
 
76
- class _SessionIdMiddleware(BaseHTTPMiddleware):
77
- """Bind the inbound session (or a fresh UUID) to async context."""
78
-
79
- async def dispatch(self, request: Request, call_next):
80
- session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
81
- with session_id_context(session_id):
82
- return await call_next(request)
83
-
84
-
85
74
  app = FastAPI(title="<%= agentNameClassName %>", lifespan=lifespan)
86
- app.add_middleware(_SessionIdMiddleware)
75
+ app.add_middleware(SessionIdMiddleware)
87
76
 
88
77
 
89
78
  @app.get("/ping")
@@ -10,14 +10,12 @@ from fastapi import FastAPI, Request
10
10
  from fastapi.middleware.cors import CORSMiddleware
11
11
  from fastapi.responses import JSONResponse, StreamingResponse
12
12
  from <%- agentConnectionModuleName %> import get_current_session_id, session_id_context
13
- from starlette.middleware.base import BaseHTTPMiddleware
14
13
 
15
14
  from .agent import get_agent
15
+ from .middleware.session_id_middleware import SESSION_ID_HEADER, SessionIdMiddleware
16
16
 
17
17
  logging.basicConfig(level=logging.INFO)
18
18
 
19
- SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
20
-
21
19
 
22
20
  @asynccontextmanager
23
21
  async def lifespan(app: FastAPI):
@@ -30,15 +28,6 @@ async def lifespan(app: FastAPI):
30
28
  yield
31
29
 
32
30
 
33
- class _SessionIdMiddleware(BaseHTTPMiddleware):
34
- """Bind the session ID for this request so downstream MCP / A2A clients forward it on outbound calls."""
35
-
36
- async def dispatch(self, request: Request, call_next):
37
- session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
38
- with session_id_context(session_id):
39
- return await call_next(request)
40
-
41
-
42
31
  app = FastAPI(title="<%= agentNameClassName %>", lifespan=lifespan)
43
32
  # Allow browser-based AG-UI clients (e.g. a connected React website) to call
44
33
  # this agent cross-origin, including the CORS preflight.
@@ -49,7 +38,7 @@ app.add_middleware(
49
38
  allow_methods=["*"],
50
39
  allow_headers=["*"],
51
40
  )
52
- app.add_middleware(_SessionIdMiddleware)
41
+ app.add_middleware(SessionIdMiddleware)
53
42
 
54
43
 
55
44
  @app.post("/invocations")
@@ -0,0 +1,17 @@
1
+ import uuid
2
+
3
+ from fastapi import Request
4
+ from starlette.middleware.base import BaseHTTPMiddleware
5
+
6
+ from <%- agentConnectionModuleName %> import session_id_context
7
+
8
+ SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
9
+
10
+
11
+ class SessionIdMiddleware(BaseHTTPMiddleware):
12
+ """Bind the session ID for this request so downstream MCP / A2A clients forward it on outbound calls."""
13
+
14
+ async def dispatch(self, request: Request, call_next):
15
+ session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
16
+ with session_id_context(session_id):
17
+ return await call_next(request)
@@ -2,14 +2,11 @@ import uuid
2
2
 
3
3
  import uvicorn
4
4
  from bedrock_agentcore.runtime.models import PingStatus
5
- from fastapi import Request
6
5
  from pydantic import BaseModel, Field
7
- from starlette.middleware.base import BaseHTTPMiddleware
8
6
  from <%- agentConnectionModuleName %> import get_current_session_id, session_id_context
9
7
 
10
8
  from .init import JsonStreamingResponse, app
11
-
12
- SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
9
+ from .middleware.session_id_middleware import SessionIdMiddleware
13
10
 
14
11
 
15
12
  class InvokeInput(BaseModel):
@@ -59,16 +56,7 @@ async def invoke(input: InvokeInput) -> JsonStreamingResponse:
59
56
  return JsonStreamingResponse(handle_invoke(input, session_id))
60
57
 
61
58
 
62
- class _SessionIdMiddleware(BaseHTTPMiddleware):
63
- """Bind the inbound session (or a fresh UUID) to async context."""
64
-
65
- async def dispatch(self, request: Request, call_next):
66
- session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
67
- with session_id_context(session_id):
68
- return await call_next(request)
69
-
70
-
71
- app.add_middleware(_SessionIdMiddleware)
59
+ app.add_middleware(SessionIdMiddleware)
72
60
 
73
61
 
74
62
  @app.get("/ping")
@@ -1,23 +1,21 @@
1
1
  import logging
2
2
  import os
3
- import uuid
4
3
  from contextlib import asynccontextmanager
5
4
  from types import SimpleNamespace
6
5
  from typing import cast
7
6
 
8
- from fastapi import FastAPI, Request
9
- from starlette.middleware.base import BaseHTTPMiddleware
7
+ from fastapi import FastAPI
10
8
  from strands import Agent
11
9
  from strands.multiagent.a2a import A2AServer
12
- from <%- agentConnectionModuleName %> import session_id_context, with_session_id
10
+ from <%- agentConnectionModuleName %> import with_session_id
13
11
 
14
12
  from .agent import get_agent
13
+ from .middleware.session_id_middleware import SessionIdMiddleware
15
14
 
16
15
  logging.basicConfig(level=logging.INFO)
17
16
 
18
17
  PORT = int(os.environ.get("PORT", "9000"))
19
18
  RUNTIME_URL = os.environ.get("AGENTCORE_RUNTIME_URL", f"http://localhost:{PORT}/")
20
- SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
21
19
  AGENT_NAME = "<%= agentNameClassName %>"
22
20
  AGENT_DESCRIPTION = "A Strands Agent exposed via the Agent-to-Agent (A2A) protocol."
23
21
 
@@ -41,17 +39,8 @@ async def lifespan(app: FastAPI):
41
39
  yield
42
40
 
43
41
 
44
- class _SessionIdMiddleware(BaseHTTPMiddleware):
45
- """Bind the inbound session (or a fresh UUID) to async context."""
46
-
47
- async def dispatch(self, request: Request, call_next):
48
- session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
49
- with session_id_context(session_id):
50
- return await call_next(request)
51
-
52
-
53
42
  app = FastAPI(lifespan=lifespan)
54
- app.add_middleware(_SessionIdMiddleware)
43
+ app.add_middleware(SessionIdMiddleware)
55
44
 
56
45
 
57
46
  @app.get("/ping")
@@ -9,15 +9,13 @@ from fastapi import FastAPI, Request
9
9
  from fastapi.middleware.cors import CORSMiddleware
10
10
  from fastapi.responses import StreamingResponse
11
11
  from <%- agentConnectionModuleName %> import get_current_session_id, session_id_context
12
- from starlette.middleware.base import BaseHTTPMiddleware
13
12
 
14
13
  from .agent import get_agent
14
+ from .middleware.session_id_middleware import SESSION_ID_HEADER, SessionIdMiddleware
15
15
  from .session import get_session_manager
16
16
 
17
17
  logging.basicConfig(level=logging.INFO)
18
18
 
19
- SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
20
-
21
19
 
22
20
  @asynccontextmanager
23
21
  async def lifespan(app: FastAPI):
@@ -33,15 +31,6 @@ async def lifespan(app: FastAPI):
33
31
  yield
34
32
 
35
33
 
36
- class _SessionIdMiddleware(BaseHTTPMiddleware):
37
- """Bind the session ID for this request so downstream MCP / A2A clients forward it on outbound calls."""
38
-
39
- async def dispatch(self, request: Request, call_next):
40
- session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
41
- with session_id_context(session_id):
42
- return await call_next(request)
43
-
44
-
45
34
  app = FastAPI(title="AWS Strands - <%= agentNameClassName %>", lifespan=lifespan)
46
35
  app.add_middleware(
47
36
  CORSMiddleware,
@@ -50,7 +39,7 @@ app.add_middleware(
50
39
  allow_methods=["*"],
51
40
  allow_headers=["*"],
52
41
  )
53
- app.add_middleware(_SessionIdMiddleware)
42
+ app.add_middleware(SessionIdMiddleware)
54
43
 
55
44
 
56
45
  @app.post("/invocations")
@@ -0,0 +1,17 @@
1
+ import uuid
2
+
3
+ from fastapi import Request
4
+ from starlette.middleware.base import BaseHTTPMiddleware
5
+
6
+ from <%- agentConnectionModuleName %> import session_id_context
7
+
8
+ SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
9
+
10
+
11
+ class SessionIdMiddleware(BaseHTTPMiddleware):
12
+ """Bind the session ID for this request so downstream MCP / A2A clients forward it on outbound calls."""
13
+
14
+ async def dispatch(self, request: Request, call_next):
15
+ session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
16
+ with session_id_context(session_id):
17
+ return await call_next(request)
@@ -1,15 +1,9 @@
1
- import uuid
2
-
3
1
  import uvicorn
4
2
  from bedrock_agentcore.runtime.models import PingStatus
5
- from fastapi import Request
6
3
  from pydantic import BaseModel, Field
7
- from starlette.middleware.base import BaseHTTPMiddleware
8
- from <%- agentConnectionModuleName %> import session_id_context
9
4
 
10
5
  from .init import JsonStreamingResponse, app
11
-
12
- SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
6
+ from .middleware.session_id_middleware import SessionIdMiddleware
13
7
 
14
8
 
15
9
  class InvokeInput(BaseModel):
@@ -41,16 +35,7 @@ async def invoke(input: InvokeInput) -> JsonStreamingResponse:
41
35
  return JsonStreamingResponse(handle_invoke(input))
42
36
 
43
37
 
44
- class _SessionIdMiddleware(BaseHTTPMiddleware):
45
- """Bind the inbound session (or a fresh UUID) to async context."""
46
-
47
- async def dispatch(self, request: Request, call_next):
48
- session_id = request.headers.get(SESSION_ID_HEADER) or str(uuid.uuid4())
49
- with session_id_context(session_id):
50
- return await call_next(request)
51
-
52
-
53
- app.add_middleware(_SessionIdMiddleware)
38
+ app.add_middleware(SessionIdMiddleware)
54
39
 
55
40
 
56
41
  @app.get("/ping")
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ export { agentcoreHarnessGenerator } from '../agentcore-harness/generator';
6
+ export type { AgentcoreHarnessGeneratorSchema } from '../agentcore-harness/schema';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ // AgentCore Harness Generator
5
+ export { agentcoreHarnessGenerator } from "../agentcore-harness/generator.js";
6
+
7
+ //# sourceMappingURL=agentcore-harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../packages/nx-plugin/src/sdk/agentcore-harness.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// AgentCore Harness Generator\nexport { agentcoreHarnessGenerator } from '../agentcore-harness/generator';\nexport type { AgentcoreHarnessGeneratorSchema } from '../agentcore-harness/schema';\n"],"names":["agentcoreHarnessGenerator"],"mappings":"AAAA;;;CAGC,GAED,8BAA8B;AAC9B,SAASA,yBAAyB,QAAQ,oCAAiC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */
5
+ export { smithyProjectGenerator } from '../smithy/project/generator';
6
+ export type { SmithyProjectGeneratorSchema } from '../smithy/project/schema';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ * SPDX-License-Identifier: Apache-2.0
4
+ */ // Smithy Project Generator
5
+ export { smithyProjectGenerator } from "../smithy/project/generator.js";
6
+
7
+ //# sourceMappingURL=smithy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../packages/nx-plugin/src/sdk/smithy.ts"],"sourcesContent":["/**\n * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// Smithy Project Generator\nexport { smithyProjectGenerator } from '../smithy/project/generator';\nexport type { SmithyProjectGeneratorSchema } from '../smithy/project/schema';\n"],"names":["smithyProjectGenerator"],"mappings":"AAAA;;;CAGC,GAED,2BAA2B;AAC3B,SAASA,sBAAsB,QAAQ,iCAA8B"}
@@ -1,14 +1,12 @@
1
1
  import { A2AExpressServer } from '@strands-agents/sdk/a2a/express';
2
- import express, { type Request, type Response, type NextFunction } from 'express';
3
- import { randomUUID } from 'node:crypto';
4
- import { runWithSessionId, withSessionId } from '<%- agentConnectionImport %>';
2
+ import express from 'express';
3
+ import { withSessionId } from '<%- agentConnectionImport %>';
5
4
  import { getAgent } from './agent<% if (esm) { %>.js<% } %>';
5
+ import { sessionIdMiddleware } from './middleware/session-id-middleware<% if (esm) { %>.js<% } %>';
6
6
 
7
7
  const PORT = parseInt(process.env.PORT || '9000');
8
8
  const HOST = '0.0.0.0';
9
9
 
10
- const SESSION_ID_HEADER = 'x-amzn-bedrock-agentcore-runtime-session-id';
11
-
12
10
  void (async () => {
13
11
  const httpUrl =
14
12
  process.env.AGENTCORE_RUNTIME_URL ?? `http://localhost:${PORT}/`;
@@ -25,12 +23,7 @@ void (async () => {
25
23
 
26
24
  const app = express();
27
25
  app.get('/ping', (_req, res) => res.status(200).json({ status: 'Healthy' }));
28
- // Bind the inbound session (or a fresh UUID) for downstream MCP / A2A calls.
29
- app.use((req: Request, _res: Response, next: NextFunction) => {
30
- const header = req.headers[SESSION_ID_HEADER];
31
- const sessionId = (Array.isArray(header) ? header[0] : header) ?? randomUUID();
32
- runWithSessionId(sessionId, () => next());
33
- });
26
+ app.use(sessionIdMiddleware);
34
27
  app.use(server.createMiddleware());
35
28
  app.listen(PORT, HOST, () => {
36
29
  console.log(`A2A server listening on ${HOST}:${PORT}`);
@@ -4,29 +4,19 @@ import {
4
4
  addPing,
5
5
  addCapabilities,
6
6
  } from '@ag-ui/aws-strands/server';
7
- import express, { type Request, type Response, type NextFunction } from 'express';
7
+ import express from 'express';
8
8
  import cors from 'cors';
9
- import { randomUUID } from 'node:crypto';
10
9
  import {
11
10
  ModelErrorLoggingPlugin,
12
11
  ToolErrorLoggingPlugin,
13
- runWithSessionId,
14
12
  } from '<%- agentConnectionImport %>';
15
13
  import { getAgent } from './agent<% if (esm) { %>.js<% } %>';
16
14
  import { getSessionManager } from './session<% if (esm) { %>.js<% } %>';
15
+ import { sessionIdMiddleware } from './middleware/session-id-middleware<% if (esm) { %>.js<% } %>';
17
16
 
18
17
  const PORT = parseInt(process.env.PORT || '8080');
19
18
  const HOST = '0.0.0.0';
20
19
 
21
- const SESSION_ID_HEADER = 'x-amzn-bedrock-agentcore-runtime-session-id';
22
-
23
- // Bind the inbound session (or a fresh UUID) for downstream MCP / A2A calls.
24
- const sessionIdMiddleware = (req: Request, _res: Response, next: NextFunction) => {
25
- const header = req.headers[SESSION_ID_HEADER];
26
- const sessionId = (Array.isArray(header) ? header[0] : header) ?? randomUUID();
27
- runWithSessionId(sessionId, () => next());
28
- };
29
-
30
20
  void (async () => {
31
21
  const agent = await getAgent();
32
22
 
@@ -0,0 +1,16 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import type { NextFunction, Request, Response } from 'express';
3
+ import { runWithSessionId } from '<%- agentConnectionImport %>';
4
+
5
+ export const SESSION_ID_HEADER = 'x-amzn-bedrock-agentcore-runtime-session-id';
6
+
7
+ // Bind the inbound session (or a fresh UUID) for downstream MCP / A2A calls.
8
+ export const sessionIdMiddleware = (
9
+ req: Request,
10
+ _res: Response,
11
+ next: NextFunction,
12
+ ) => {
13
+ const header = req.headers[SESSION_ID_HEADER];
14
+ const sessionId = (Array.isArray(header) ? header[0] : header) ?? randomUUID();
15
+ runWithSessionId(sessionId, () => next());
16
+ };