@aws/nx-plugin-mcp 1.0.0-rc.60 → 1.0.0-rc.62
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/bin/aws-nx-mcp.js +1 -1
- package/docs/get_started/quick-start.mdx +14 -3
- package/docs/get_started/tutorials/dungeon-game/1.mdx +153 -62
- package/docs/get_started/tutorials/dungeon-game/4.mdx +2 -2
- package/docs/guides/py-agent.mdx +2 -2
- package/docs/guides/react-website.mdx +5 -5
- package/docs/snippets/prerequisites.mdx +2 -0
- package/docs/snippets/required-prerequisites.mdx +0 -2
- package/package.json +1 -1
package/bin/aws-nx-mcp.js
CHANGED
|
@@ -53897,7 +53897,7 @@ ${PACKAGE_MANAGERS.map((pm) => buildNxCommand("<options>", pm)).join(" - \n")}
|
|
|
53897
53897
|
- Carefully examine the files that have been generated and always refer back to the generator guide when working in a generated project
|
|
53898
53898
|
- Generate all projects into the \`packages/\` directory
|
|
53899
53899
|
- After making changes to your projects, fix linting issues, then run a full build
|
|
53900
|
-
- When it's time to start testing a project, suggest to the user that infrastructure is deployed to AWS. For websites, if a runtime-config.json is needed, use the load
|
|
53900
|
+
- When it's time to start testing a project, suggest to the user that infrastructure is deployed to AWS. For websites, if a runtime-config.json is needed, use the load-runtime-config target after a deployment to point a local website at a sandbox stack.
|
|
53901
53901
|
|
|
53902
53902
|
## Batching Generators
|
|
53903
53903
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Quick Start Guide
|
|
3
|
-
description: A quick start on how to use @aws/nx-plugin.
|
|
3
|
+
description: "A quick start on how to use @aws/nx-plugin."
|
|
4
4
|
---
|
|
5
5
|
import { Steps } from '@astrojs/starlight/components';
|
|
6
6
|
import Link from '@components/link.astro';
|
|
@@ -11,6 +11,7 @@ import InstallCommand from '@components/install-command.astro';
|
|
|
11
11
|
import RunGenerator from '@components/run-generator.astro';
|
|
12
12
|
import NxCommands from '@components/nx-commands.astro';
|
|
13
13
|
import Infrastructure from '@components/infrastructure.astro';
|
|
14
|
+
import EmbeddedGraph from '@components/embedded-graph.astro';
|
|
14
15
|
|
|
15
16
|
This guide walks you through the basics of installing and using `@aws/nx-plugin` to rapidly build projects on AWS.
|
|
16
17
|
|
|
@@ -51,7 +52,17 @@ cd my-project
|
|
|
51
52
|
|
|
52
53
|
## Step 2: Use Generators to Scaffold your Project
|
|
53
54
|
|
|
54
|
-
We'll add a tRPC API, React Website, Cognito Authentication, and CDK or Terraform Infrastructure in this quick-start guide. Depending on the type of project you're building, you can choose any combination of generators to quickly bootstrap your project. Check out the
|
|
55
|
+
We'll add a tRPC API, React Website, Cognito Authentication, and CDK or Terraform Infrastructure in this quick-start guide. Depending on the type of project you're building, you can choose any combination of generators to quickly bootstrap your project. Check out the __Generators__ in the navigation bar to the left to see the full list of options, or try the <Link path="get_started/graph-builder">graph builder</Link> to construct your workspace visually.
|
|
56
|
+
|
|
57
|
+
As a shortcut, you can use the button below to copy the commands to scaffold the full application.
|
|
58
|
+
|
|
59
|
+
<EmbeddedGraph preset="quick-start" workspace="my-project" iac="cdk" orientation="horizontal" skipWorkspace />
|
|
60
|
+
|
|
61
|
+
:::tip[Build with AI]
|
|
62
|
+
The <Link path="get_started/building-with-ai">Nx Plugin for AWS MCP Server</Link> is already configured in your workspace, so you can ask your favourite AI coding agent like Kiro or Claude to build these projects for you instead of typing the CLI commands yourself.
|
|
63
|
+
:::
|
|
64
|
+
|
|
65
|
+
Otherwise, follow the steps below to run each generator yourself.
|
|
55
66
|
|
|
56
67
|
### Add a tRPC API
|
|
57
68
|
|
|
@@ -252,7 +263,7 @@ This command will first run `terraform plan` to show you what changes will be ma
|
|
|
252
263
|
<Steps>
|
|
253
264
|
1. Fetch the `runtime-config.json` file:
|
|
254
265
|
|
|
255
|
-
<NxCommands commands={['
|
|
266
|
+
<NxCommands commands={['load-runtime-config demo-website']} />
|
|
256
267
|
|
|
257
268
|
2. Start the local website server
|
|
258
269
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Set up a monorepo
|
|
3
|
-
description: A walkthrough of how to build an agentic AI-powered dungeon adventure game using the @aws/nx-plugin.
|
|
3
|
+
description: "A walkthrough of how to build an agentic AI-powered dungeon adventure game using the @aws/nx-plugin."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
import { Aside, Code, FileTree, Steps, Tabs, TabItem } from '@astrojs/starlight/components';
|
|
@@ -12,6 +12,7 @@ import NxCommands from '@components/nx-commands.astro';
|
|
|
12
12
|
import InstallCommand from '@components/install-command.astro';
|
|
13
13
|
import CreateNxWorkspaceCommand from '@components/create-nx-workspace-command.astro';
|
|
14
14
|
import PackageManagerShortCommand from '@components/package-manager-short-command.astro';
|
|
15
|
+
import EmbeddedGraph from '@components/embedded-graph.astro';
|
|
15
16
|
import E2EDiff from '@components/e2e-diff.astro';
|
|
16
17
|
|
|
17
18
|
import dungeonAdventureArchitecturePng from '@assets/dungeon-game-architecture.png'
|
|
@@ -50,11 +51,24 @@ This will set up a NX monorepo within the `dungeon-adventure` directory. When yo
|
|
|
50
51
|
- aws-nx-plugin.config.mts configuraton for the Nx Plugin for AWS
|
|
51
52
|
</FileTree>
|
|
52
53
|
|
|
53
|
-
We can now start creating our different sub-projects using the `@aws/nx-plugin`.
|
|
54
|
-
|
|
55
54
|
<Aside type="tip" title="Commit Often">It is best practice to ensure all your unstaged files are committed in Git before running any generators. This allows you to see what has changed after running your generator via `git diff`.</Aside>
|
|
56
55
|
|
|
57
|
-
## Task 2:
|
|
56
|
+
## Task 2: Scaffold the Dungeon Adventure Game
|
|
57
|
+
|
|
58
|
+
With the workspace in place, we scaffold the game's sub-projects — the Game API, Story Agent, Inventory MCP server, game database, and website — along with the connections that wire them together. There are two ways to do this:
|
|
59
|
+
|
|
60
|
+
- **Quick** — copy the commands straight from the diagram below and run them. The fastest way to reach the same starting point.
|
|
61
|
+
- **Step By Step** — expand the section below to run each generator yourself and examine exactly what each one produces.
|
|
62
|
+
|
|
63
|
+
The diagram below _is_ the Dungeon Adventure workspace: every project, component, and connection you'll build in this module. Hit **Copy commands** to take the whole series, then run them from within the `dungeon-adventure` directory you created in Task 1.
|
|
64
|
+
|
|
65
|
+
<EmbeddedGraph preset="dungeon-adventure" workspace="dungeon-adventure" iac="cdk" skipWorkspace />
|
|
66
|
+
|
|
67
|
+
<Drawer title="Step By Step" trigger="Step By Step: run each generator yourself and see what it produces">
|
|
68
|
+
|
|
69
|
+
Rather than copying the commands all at once, you can run each generator individually. This is the best way to understand what each generator adds to your workspace. Run each generator in turn, from within the `dungeon-adventure` directory you created in Task 1.
|
|
70
|
+
|
|
71
|
+
##### Create a Game API
|
|
58
72
|
|
|
59
73
|
First, let's create our Game API. To do this, create a tRPC API called `GameApi` using these steps:
|
|
60
74
|
|
|
@@ -69,7 +83,9 @@ The root `package.json` is now configured with a `type` of `module`, which means
|
|
|
69
83
|
For more details on working with TypeScript projects, refer to the <Link path="guides/typescript-project">ts#project generator guide</Link>.
|
|
70
84
|
</Aside>
|
|
71
85
|
|
|
72
|
-
<
|
|
86
|
+
<details>
|
|
87
|
+
<summary>Examine the generated `ts#api` files in detail</summary>
|
|
88
|
+
|
|
73
89
|
Below is a list of all files which have been generated by the `ts#api` generator. We are going to examine some of the key files highlighted in the file tree:
|
|
74
90
|
<FileTree>
|
|
75
91
|
- packages/
|
|
@@ -364,20 +380,22 @@ export class GameApi<
|
|
|
364
380
|
|
|
365
381
|
This is the CDK construct that defines our `GameApi`. It provides a `defaultIntegrations` method which automatically creates a Lambda function for each procedure in our tRPC API, pointing to the bundled API implementation. This means that at `cdk synth` time, bundling does not occur (opposed to using [NodeJsFunction](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs.NodejsFunction.html)) as we have already bundled it as part of the backend project's build target.
|
|
366
382
|
|
|
367
|
-
</
|
|
383
|
+
</details>
|
|
368
384
|
|
|
369
|
-
|
|
385
|
+
##### Create the Story Agent
|
|
370
386
|
|
|
371
|
-
Now let's create our Story
|
|
387
|
+
Now let's create our Story Agent.
|
|
372
388
|
|
|
373
|
-
|
|
389
|
+
###### Story agent: Python project
|
|
374
390
|
|
|
375
391
|
To create a Python project:
|
|
376
392
|
|
|
377
393
|
<RunGenerator generator="py#project" requiredParameters={{name:"story"}} noInteractive />
|
|
378
394
|
|
|
379
395
|
You will see some new files appear in your file tree.
|
|
380
|
-
<
|
|
396
|
+
<details>
|
|
397
|
+
<summary>Examine the generated `py#project` files in detail</summary>
|
|
398
|
+
|
|
381
399
|
The `py#project` generates these files:
|
|
382
400
|
|
|
383
401
|
<FileTree>
|
|
@@ -396,9 +414,9 @@ The `py#project` generates these files:
|
|
|
396
414
|
|
|
397
415
|
This has configured a Python project and [UV Workspace](https://docs.astral.sh/uv/concepts/projects/workspaces/) with shared virtual environment.
|
|
398
416
|
|
|
399
|
-
</
|
|
417
|
+
</details>
|
|
400
418
|
|
|
401
|
-
|
|
419
|
+
###### Story agent
|
|
402
420
|
|
|
403
421
|
To add a Strands agent to the project with the `py#agent` generator:
|
|
404
422
|
|
|
@@ -409,7 +427,9 @@ We choose `--protocol=ag-ui` so the agent speaks the [Agent-User Interaction pro
|
|
|
409
427
|
:::
|
|
410
428
|
|
|
411
429
|
You will see some new files appear in your file tree.
|
|
412
|
-
<
|
|
430
|
+
<details>
|
|
431
|
+
<summary>Examine the generated `py#agent` files in detail</summary>
|
|
432
|
+
|
|
413
433
|
The `py#agent` generates these files:
|
|
414
434
|
|
|
415
435
|
<FileTree>
|
|
@@ -417,7 +437,6 @@ The `py#agent` generates these files:
|
|
|
417
437
|
- story/
|
|
418
438
|
- dungeon_adventure_story/ python module
|
|
419
439
|
- agent/
|
|
420
|
-
- init.py sets up the FastAPI app and middleware
|
|
421
440
|
- main.py entrypoint for your agent in Bedrock AgentCore Runtime
|
|
422
441
|
- agent.py defines an example agent and tools
|
|
423
442
|
- Dockerfile defines the docker image for deployment to AgentCore Runtime
|
|
@@ -462,10 +481,15 @@ This creates an example Strands agent and defines a subtraction tool.
|
|
|
462
481
|
# agent/main.py
|
|
463
482
|
import logging
|
|
464
483
|
import uuid
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
from
|
|
468
|
-
from
|
|
484
|
+
from contextlib import asynccontextmanager
|
|
485
|
+
|
|
486
|
+
from ag_ui.core import EventType, RunAgentInput, RunErrorEvent
|
|
487
|
+
from ag_ui.encoder import EventEncoder
|
|
488
|
+
from ag_ui_strands import StrandsAgent
|
|
489
|
+
from dungeon_adventure_agent_connection import get_current_session_id, session_id_context
|
|
490
|
+
from fastapi import FastAPI, Request
|
|
491
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
492
|
+
from fastapi.responses import StreamingResponse
|
|
469
493
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
470
494
|
|
|
471
495
|
from .agent import get_agent
|
|
@@ -474,15 +498,16 @@ logging.basicConfig(level=logging.INFO)
|
|
|
474
498
|
|
|
475
499
|
SESSION_ID_HEADER = "x-amzn-bedrock-agentcore-runtime-session-id"
|
|
476
500
|
|
|
477
|
-
# Create AG-UI agent wrapper
|
|
478
|
-
_agent_ctx = get_agent()
|
|
479
|
-
_agent = _agent_ctx.__enter__()
|
|
480
501
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
502
|
+
@asynccontextmanager
|
|
503
|
+
async def lifespan(app: FastAPI):
|
|
504
|
+
with get_agent() as agent:
|
|
505
|
+
app.state.agui_agent = StrandsAgent(
|
|
506
|
+
agent=agent,
|
|
507
|
+
name="StoryAgent",
|
|
508
|
+
description="A Strands Agent exposed via the AG-UI protocol.",
|
|
509
|
+
)
|
|
510
|
+
yield
|
|
486
511
|
|
|
487
512
|
|
|
488
513
|
class _SessionIdMiddleware(BaseHTTPMiddleware):
|
|
@@ -494,12 +519,58 @@ class _SessionIdMiddleware(BaseHTTPMiddleware):
|
|
|
494
519
|
return await call_next(request)
|
|
495
520
|
|
|
496
521
|
|
|
497
|
-
|
|
498
|
-
app
|
|
522
|
+
app = FastAPI(title="AWS Strands - StoryAgent", lifespan=lifespan)
|
|
523
|
+
app.add_middleware(
|
|
524
|
+
CORSMiddleware,
|
|
525
|
+
allow_origins=["*"],
|
|
526
|
+
allow_credentials=True,
|
|
527
|
+
allow_methods=["*"],
|
|
528
|
+
allow_headers=["*"],
|
|
529
|
+
)
|
|
499
530
|
app.add_middleware(_SessionIdMiddleware)
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
@app.post("/invocations")
|
|
534
|
+
async def invocations(request: Request):
|
|
535
|
+
# Validate the body manually since AgentCore may omit Content-Type.
|
|
536
|
+
encoder = EventEncoder(accept=request.headers.get("accept") or "")
|
|
537
|
+
raw = await request.body()
|
|
538
|
+
try:
|
|
539
|
+
input_data = RunAgentInput.model_validate_json(raw)
|
|
540
|
+
except Exception as exc:
|
|
541
|
+
message = f"Invalid RunAgentInput: {str(exc)[:200]}"
|
|
542
|
+
|
|
543
|
+
async def _bad():
|
|
544
|
+
yield encoder.encode(RunErrorEvent(type=EventType.RUN_ERROR, message=message, code="BAD_REQUEST"))
|
|
545
|
+
|
|
546
|
+
return StreamingResponse(_bad(), media_type=encoder.get_content_type())
|
|
547
|
+
|
|
548
|
+
session_id = request.headers.get(SESSION_ID_HEADER) or get_current_session_id()
|
|
549
|
+
|
|
550
|
+
async def event_generator():
|
|
551
|
+
# Re-bind the session: the streaming body runs outside the middleware.
|
|
552
|
+
with session_id_context(session_id or str(uuid.uuid4())):
|
|
553
|
+
async for event in request.app.state.agui_agent.run(input_data):
|
|
554
|
+
try:
|
|
555
|
+
yield encoder.encode(event)
|
|
556
|
+
except Exception as e:
|
|
557
|
+
error_event = RunErrorEvent(
|
|
558
|
+
type=EventType.RUN_ERROR,
|
|
559
|
+
message=f"Encoding error: {e}",
|
|
560
|
+
code="ENCODING_ERROR",
|
|
561
|
+
)
|
|
562
|
+
yield encoder.encode(error_event)
|
|
563
|
+
break
|
|
564
|
+
|
|
565
|
+
return StreamingResponse(event_generator(), media_type=encoder.get_content_type())
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
@app.get("/ping")
|
|
569
|
+
async def ping():
|
|
570
|
+
return {"status": "healthy"}
|
|
500
571
|
```
|
|
501
572
|
|
|
502
|
-
This is the entrypoint for the agent. Because we selected `--protocol=ag-ui`, the generator wraps our Strands `Agent` with `StrandsAgent` from [`ag_ui_strands`](https://docs.copilotkit.ai/aws-strands/integration) and mounts it on a FastAPI app that speaks the [AG-UI protocol](https://docs.copilotkit.ai/aws-strands/protocol) — this is what CopilotKit will talk to from the React website. The `_SessionIdMiddleware` binds the inbound AgentCore runtime session ID onto a `ContextVar` so any downstream MCP/A2A client we wire up later (e.g. the Inventory MCP server in <Link path="get_started/tutorials/dungeon-game/2">Module 2</Link>) automatically forwards it on its outbound calls. In <Link path="get_started/tutorials/dungeon-game/3">Module 3</Link> we'll also add a `session_manager_provider` so each thread id gets its own `S3SessionManager` and conversation history persists across turns.
|
|
573
|
+
This is the entrypoint for the agent. Because we selected `--protocol=ag-ui`, the generator wraps our Strands `Agent` with `StrandsAgent` from [`ag_ui_strands`](https://docs.copilotkit.ai/aws-strands/integration) and mounts it on a FastAPI app that speaks the [AG-UI protocol](https://docs.copilotkit.ai/aws-strands/protocol) — this is what CopilotKit will talk to from the React website. The agent is built inside a `lifespan` handler — not at import time — so container startup, not module import, owns construction, and each AgentCore session gets its own container. The `_SessionIdMiddleware` binds the inbound AgentCore runtime session ID onto a `ContextVar` so any downstream MCP/A2A client we wire up later (e.g. the Inventory MCP server in <Link path="get_started/tutorials/dungeon-game/2">Module 2</Link>) automatically forwards it on its outbound calls. In <Link path="get_started/tutorials/dungeon-game/3">Module 3</Link> we'll also add a `session_manager_provider` so each thread id gets its own `S3SessionManager` and conversation history persists across turns.
|
|
503
574
|
|
|
504
575
|
```ts
|
|
505
576
|
// common/constructs/src/app/agents/story-agent.ts
|
|
@@ -561,11 +632,11 @@ This configures a CDK `AgentRuntimeArtifact` which uploads your agent Docker ima
|
|
|
561
632
|
|
|
562
633
|
You may notice an extra `Dockerfile`, that references the Docker image from the `story` project, allowing us to co-locate the Dockerfile and agent source code.
|
|
563
634
|
|
|
564
|
-
</
|
|
635
|
+
</details>
|
|
565
636
|
|
|
566
|
-
|
|
637
|
+
##### Set up the Inventory tools
|
|
567
638
|
|
|
568
|
-
|
|
639
|
+
###### Inventory: TypeScript project
|
|
569
640
|
|
|
570
641
|
Let us create an MCP server to provide tools for our Story Agent to manage a player's inventory.
|
|
571
642
|
|
|
@@ -575,7 +646,9 @@ First, we create a TypeScript project:
|
|
|
575
646
|
|
|
576
647
|
This will create an empty TypeScript project.
|
|
577
648
|
|
|
578
|
-
<
|
|
649
|
+
<details>
|
|
650
|
+
<summary>Examine the generated `ts#project` files in detail</summary>
|
|
651
|
+
|
|
579
652
|
The `ts#project` generator generates these files.
|
|
580
653
|
|
|
581
654
|
<FileTree>
|
|
@@ -591,16 +664,18 @@ The `ts#project` generator generates these files.
|
|
|
591
664
|
- tsconfig.base.json updated to configure an alias for other projects to reference this
|
|
592
665
|
</FileTree>
|
|
593
666
|
|
|
594
|
-
</
|
|
667
|
+
</details>
|
|
595
668
|
|
|
596
|
-
|
|
669
|
+
###### Inventory: MCP server
|
|
597
670
|
|
|
598
671
|
Next, we'll add an MCP server to our TypeScript project:
|
|
599
672
|
|
|
600
673
|
<RunGenerator generator="ts#mcp-server" requiredParameters={{project:"inventory"}} noInteractive />
|
|
601
674
|
|
|
602
675
|
This will add an MCP server.
|
|
603
|
-
<
|
|
676
|
+
<details>
|
|
677
|
+
<summary>Examine the generated `ts#mcp-server` files in detail</summary>
|
|
678
|
+
|
|
604
679
|
The `ts#mcp-server` generator generates these files.
|
|
605
680
|
|
|
606
681
|
<FileTree>
|
|
@@ -623,9 +698,9 @@ The `ts#mcp-server` generator generates these files.
|
|
|
623
698
|
- inventory-mcp-server.ts construct for deploying your inventory MCP server to AgentCore Runtime
|
|
624
699
|
</FileTree>
|
|
625
700
|
|
|
626
|
-
</
|
|
701
|
+
</details>
|
|
627
702
|
|
|
628
|
-
|
|
703
|
+
##### Create the game database
|
|
629
704
|
|
|
630
705
|
Our game state — saved games and each player's inventory — lives in [Amazon DynamoDB](https://aws.amazon.com/dynamodb/). Create a DynamoDB project called `DungeonDb` with the `ts#dynamodb` generator:
|
|
631
706
|
|
|
@@ -636,7 +711,9 @@ The `ts#dynamodb` generator vends a `dev` target that runs [DynamoDB Local](http
|
|
|
636
711
|
:::
|
|
637
712
|
|
|
638
713
|
You will see some new files appear in your file tree.
|
|
639
|
-
<
|
|
714
|
+
<details>
|
|
715
|
+
<summary>Examine the generated `ts#dynamodb` files in detail</summary>
|
|
716
|
+
|
|
640
717
|
The `ts#dynamodb` generator generates these files.
|
|
641
718
|
|
|
642
719
|
<FileTree>
|
|
@@ -669,13 +746,13 @@ The generated `src/client.ts` exports `getDynamoDBClient()` and `resolveTableNam
|
|
|
669
746
|
|
|
670
747
|
For more details, refer to the <Link path="guides/ts-dynamodb">ts#dynamodb generator guide</Link>.
|
|
671
748
|
|
|
672
|
-
</
|
|
749
|
+
</details>
|
|
673
750
|
|
|
674
|
-
|
|
751
|
+
##### Create the User Interface (UI)
|
|
675
752
|
|
|
676
|
-
|
|
753
|
+
Next, we will create the UI which will allow you to interact with the game.
|
|
677
754
|
|
|
678
|
-
|
|
755
|
+
###### Game UI: Website
|
|
679
756
|
|
|
680
757
|
To create the UI, create a website called `GameUI` using these steps:
|
|
681
758
|
|
|
@@ -687,7 +764,9 @@ We select `--ux=shadcn` so the generated website uses [shadcn/ui](https://ui.sha
|
|
|
687
764
|
|
|
688
765
|
You will see some new files appear in your file tree.
|
|
689
766
|
|
|
690
|
-
<
|
|
767
|
+
<details>
|
|
768
|
+
<summary>Examine the generated `ts#website` files in detail</summary>
|
|
769
|
+
|
|
691
770
|
The `ts#website` generates these files. Let us examine some of the key files highlighted in the file tree:
|
|
692
771
|
|
|
693
772
|
<FileTree>
|
|
@@ -802,9 +881,9 @@ function RouteComponent() {
|
|
|
802
881
|
|
|
803
882
|
A component will be rendered when navigating to the `/` route. `@tanstack/react-router` will manage the `Route` for you whenever you create/move this file (as long as the dev server is running).
|
|
804
883
|
|
|
805
|
-
</
|
|
884
|
+
</details>
|
|
806
885
|
|
|
807
|
-
|
|
886
|
+
###### Game UI: Auth
|
|
808
887
|
|
|
809
888
|
Let us configure our Game UI to require authenticated access via Amazon Cognito using these steps:
|
|
810
889
|
|
|
@@ -812,7 +891,9 @@ Let us configure our Game UI to require authenticated access via Amazon Cognito
|
|
|
812
891
|
|
|
813
892
|
You will see some new files appear/change in your file tree.
|
|
814
893
|
|
|
815
|
-
<
|
|
894
|
+
<details>
|
|
895
|
+
<summary>Examine the generated `ts#website#auth` files in detail</summary>
|
|
896
|
+
|
|
816
897
|
The `ts#website#auth` generator updates/generates these files. Let us examine some of the key files highlighted in the file tree:
|
|
817
898
|
|
|
818
899
|
<FileTree>
|
|
@@ -884,9 +965,9 @@ root &&
|
|
|
884
965
|
|
|
885
966
|
The `RuntimeConfigProvider` and `CognitoAuth` components have been added to the `main.tsx` file via an AST transform. This allows the `CognitoAuth` component to authenticate with Amazon Cognito by fetching the `runtime-config.json` which contains the required cognito connection configuration in order to make the backend calls to the correct destination.
|
|
886
967
|
|
|
887
|
-
</
|
|
968
|
+
</details>
|
|
888
969
|
|
|
889
|
-
|
|
970
|
+
###### Game UI: Connect to Game API
|
|
890
971
|
|
|
891
972
|
Let us configure our Game UI to connect to our previously created Game API.
|
|
892
973
|
|
|
@@ -894,7 +975,9 @@ Let us configure our Game UI to connect to our previously created Game API.
|
|
|
894
975
|
|
|
895
976
|
You will see some new files have appear/change in your file tree.
|
|
896
977
|
|
|
897
|
-
<
|
|
978
|
+
<details>
|
|
979
|
+
<summary>Examine the UI → tRPC connection files</summary>
|
|
980
|
+
|
|
898
981
|
The `connection` generator generates/updates these files. Let us examine some of the key files highlighted in the file tree:
|
|
899
982
|
|
|
900
983
|
<FileTree>
|
|
@@ -973,15 +1056,17 @@ root &&
|
|
|
973
1056
|
|
|
974
1057
|
The `main.tsx` file has been updated via an AST transform to inject the tRPC providers.
|
|
975
1058
|
|
|
976
|
-
</
|
|
1059
|
+
</details>
|
|
977
1060
|
|
|
978
|
-
|
|
1061
|
+
###### Story Agent: Connect to Inventory MCP Server
|
|
979
1062
|
|
|
980
1063
|
Let us connect our Story Agent to the Inventory MCP server so the agent can discover and invoke the MCP server's tools.
|
|
981
1064
|
|
|
982
1065
|
<RunGenerator generator="connection" requiredParameters={{sourceProject:"story", targetProject:"inventory"}} noInteractive />
|
|
983
1066
|
|
|
984
|
-
<
|
|
1067
|
+
<details>
|
|
1068
|
+
<summary>Examine the Story Agent → Inventory MCP connection files</summary>
|
|
1069
|
+
|
|
985
1070
|
The `connection` generator generates/updates these files:
|
|
986
1071
|
|
|
987
1072
|
<FileTree>
|
|
@@ -1011,15 +1096,17 @@ The generator:
|
|
|
1011
1096
|
- Updates the `dev` target to automatically start the MCP server when running locally
|
|
1012
1097
|
|
|
1013
1098
|
For more details, refer to the <Link path="guides/connection/py-agent-mcp">Python Agent to MCP connection guide</Link>.
|
|
1014
|
-
</
|
|
1099
|
+
</details>
|
|
1015
1100
|
|
|
1016
|
-
|
|
1101
|
+
###### Game UI: Connect to Story Agent
|
|
1017
1102
|
|
|
1018
1103
|
Let us connect our Game UI to the Story Agent. Since the agent speaks AG-UI, the `connection` generator wires up [CopilotKit](https://docs.copilotkit.ai/): a themed chat component and an `@ag-ui/client` `HttpAgent` ready to render.
|
|
1019
1104
|
|
|
1020
1105
|
<RunGenerator generator="connection" requiredParameters={{sourceProject:"@dungeon-adventure/game-ui", targetProject:"story"}} noInteractive />
|
|
1021
1106
|
|
|
1022
|
-
<
|
|
1107
|
+
<details>
|
|
1108
|
+
<summary>Examine the UI → Story Agent connection files</summary>
|
|
1109
|
+
|
|
1023
1110
|
The `connection` generator generates/updates these files:
|
|
1024
1111
|
|
|
1025
1112
|
<FileTree>
|
|
@@ -1043,9 +1130,9 @@ The generator:
|
|
|
1043
1130
|
- Reads the agent's runtime ARN from Runtime Configuration, builds the AgentCore invocation URL, and attaches the Cognito bearer token plus the AgentCore session id header.
|
|
1044
1131
|
|
|
1045
1132
|
For more details, refer to the <Link path="guides/connection/react-agui">React to AG-UI connection guide</Link>.
|
|
1046
|
-
</
|
|
1133
|
+
</details>
|
|
1047
1134
|
|
|
1048
|
-
|
|
1135
|
+
###### Connect the Game API and Inventory MCP server to the database
|
|
1049
1136
|
|
|
1050
1137
|
Both the Game API and the Inventory MCP server read and write our DynamoDB table, so let us connect them to the `DungeonDb` project. The `connection` generator detects that the target is a `ts#dynamodb` project and wires each source project's `dev` target to start DynamoDB Local automatically.
|
|
1051
1138
|
|
|
@@ -1057,7 +1144,7 @@ Both the Game API and the Inventory MCP server read and write our DynamoDB table
|
|
|
1057
1144
|
Because the Story Agent's `agent-dev` already depends on the Inventory MCP server's `mcp-server-dev` (via the `story → inventory` connection above), and both the Game API and MCP server now depend on `dungeon-db:dev`, running any one project's `dev` target starts every dependency it needs in the right order.
|
|
1058
1145
|
</Aside>
|
|
1059
1146
|
|
|
1060
|
-
|
|
1147
|
+
###### Game UI: Infrastructure
|
|
1061
1148
|
|
|
1062
1149
|
Let us create the final sub-project for the CDK infrastructure.
|
|
1063
1150
|
|
|
@@ -1065,7 +1152,9 @@ Let us create the final sub-project for the CDK infrastructure.
|
|
|
1065
1152
|
|
|
1066
1153
|
You will see some new files have appear/change in your file tree.
|
|
1067
1154
|
|
|
1068
|
-
<
|
|
1155
|
+
<details>
|
|
1156
|
+
<summary>Examine the generated `ts#infra` files in detail</summary>
|
|
1157
|
+
|
|
1069
1158
|
The `ts#infra` generator generates/updates these. Let us examine some of the key files highlighted in the file tree:
|
|
1070
1159
|
|
|
1071
1160
|
<FileTree>
|
|
@@ -1131,9 +1220,11 @@ export class ApplicationStack extends Stack {
|
|
|
1131
1220
|
|
|
1132
1221
|
Let us instantiate our CDK constructs to build our dungeon adventure game.
|
|
1133
1222
|
|
|
1223
|
+
</details>
|
|
1224
|
+
|
|
1134
1225
|
</Drawer>
|
|
1135
1226
|
|
|
1136
|
-
## Task
|
|
1227
|
+
## Task 3: Update our infrastructure
|
|
1137
1228
|
|
|
1138
1229
|
Let's update `packages/infra/src/stacks/application-stack.ts` to instantiate some of our generated constructs:
|
|
1139
1230
|
|
|
@@ -1143,7 +1234,7 @@ Let's update `packages/infra/src/stacks/application-stack.ts` to instantiate som
|
|
|
1143
1234
|
We supply default integrations for our Game API. By default, each operation in our API is mapped to an individual Lambda function to handle that operation.
|
|
1144
1235
|
:::
|
|
1145
1236
|
|
|
1146
|
-
## Task
|
|
1237
|
+
## Task 4: Build the code
|
|
1147
1238
|
|
|
1148
1239
|
<Drawer title="Nx commands" trigger="Now it's time for us to build our code for the first time">
|
|
1149
1240
|
|
|
@@ -146,11 +146,11 @@ You've seen two ends of the spectrum: everything local (`dev`) and everything de
|
|
|
146
146
|
|
|
147
147
|
The key is the `RUNTIME_CONFIG_APP_ID` environment variable. When a project runs **without** `LOCAL_DEV=true`, the runtime config lookups fetch their configuration from AWS AppConfig using this application id — the `RuntimeConfigApplicationId` value from your CDK outputs.
|
|
148
148
|
|
|
149
|
-
Each website has a `load
|
|
149
|
+
Each website has a `load-runtime-config` target that downloads the deployed `runtime-config.json` (Cognito pool, API endpoints, agent ARN) into the local dev server. Some useful combinations:
|
|
150
150
|
|
|
151
151
|
- **Local website → deployed backend.** Pull the deployed config once, then run the plain `serve` target so the UI talks to the deployed API and agent:
|
|
152
152
|
|
|
153
|
-
<NxCommands commands={["
|
|
153
|
+
<NxCommands commands={["load-runtime-config game-ui"]} />
|
|
154
154
|
<NxCommands commands={["serve game-ui"]} />
|
|
155
155
|
|
|
156
156
|
- **Local API → real DynamoDB table.** Run the plain `serve` target with `RUNTIME_CONFIG_APP_ID` set to the deployed application id:
|
package/docs/guides/py-agent.mdx
CHANGED
|
@@ -383,8 +383,8 @@ Most users will not need to modify this file; edit `agent.py` to change tools or
|
|
|
383
383
|
|
|
384
384
|
The generated `main.py` exposes a single POST endpoint that streams [AG-UI](https://docs.ag-ui.com/) events over Server-Sent Events (SSE), as well as `/ping` for the AgentCore runtime health check. The wiring depends on the framework:
|
|
385
385
|
|
|
386
|
-
- **Strands**: wraps your `Agent` in an `ag_ui_strands.StrandsAgent` and
|
|
387
|
-
- **LangChain**: wraps the compiled graph in an `ag_ui_langgraph.LangGraphAgent` and
|
|
386
|
+
- **Strands**: wraps your `Agent` in an `ag_ui_strands.StrandsAgent`, built inside a FastAPI `lifespan` handler (so construction happens at container/session startup rather than import time), and served from a hand-rolled FastAPI `/invocations` loop.
|
|
387
|
+
- **LangChain**: wraps the compiled graph in an `ag_ui_langgraph.LangGraphAgent`, built the same way inside `lifespan`, and served from a hand-rolled FastAPI `/invocations` loop.
|
|
388
388
|
|
|
389
389
|
Most users will not need to modify this file — edit `agent.py` to change tools or the system prompt.
|
|
390
390
|
|
|
@@ -326,19 +326,19 @@ For details on how runtime configuration is stored in AWS AppConfig and how serv
|
|
|
326
326
|
|
|
327
327
|
When running the [local development server](#local-development-server), you will need a `runtime-config.json` file in your `public` directory in order for your local website to know the backend URLs, identity configuration, etc.
|
|
328
328
|
|
|
329
|
-
Your website project is configured with a `load
|
|
329
|
+
Your website project is configured with a `load-runtime-config` target which you can use to pull down the `runtime-config.json` file from a deployed application:
|
|
330
330
|
|
|
331
|
-
<NxCommands commands={['
|
|
331
|
+
<NxCommands commands={['load-runtime-config <my-website>']} />
|
|
332
332
|
|
|
333
333
|
:::note[Custom Stage Names]
|
|
334
334
|
<Infrastructure>
|
|
335
335
|
<Fragment slot="cdk">
|
|
336
|
-
If you change the prefix for your stage names in your infrastructure project's `src/main.ts`, you will need to update the `load
|
|
336
|
+
If you change the prefix for your stage names in your infrastructure project's `src/main.ts`, you will need to update the `load-runtime-config` target in your website's `project.json` file accordingly.
|
|
337
337
|
|
|
338
|
-
Additionally it's worth noting that the `load
|
|
338
|
+
Additionally it's worth noting that the `load-runtime-config` target assumes a single stage of your application is deployed to the environment you have AWS credentials for. You will need to adjust the command if you deploy multiple stages to the same account and region.
|
|
339
339
|
</Fragment>
|
|
340
340
|
<Fragment slot="terraform">
|
|
341
|
-
For Terraform projects, the `load
|
|
341
|
+
For Terraform projects, the `load-runtime-config` target copies the `runtime-config.json` file that was created after your most recent local `terraform apply`.
|
|
342
342
|
</Fragment>
|
|
343
343
|
</Infrastructure>
|
|
344
344
|
:::
|
|
@@ -10,6 +10,8 @@ import Snippet from '@components/snippet.astro';
|
|
|
10
10
|
|
|
11
11
|
### Recommended
|
|
12
12
|
|
|
13
|
+
- [PNPM >= 11](https://pnpm.io/installation#using-npm) (you can also use [Yarn >= 4](https://yarnpkg.com/getting-started/install), [Bun >= 1](https://bun.sh/docs/installation), or [NPM >= 10](https://nodejs.org/en/learn/getting-started/an-introduction-to-the-npm-package-manager) if you prefer)
|
|
14
|
+
- verify by running `pnpm --version`, `yarn --version`, `bun --version` or `npm --version`
|
|
13
15
|
- [AWS Credentials](https://docs.aws.amazon.com/sdkref/latest/guide/access.html) configured to your target AWS account are required to deploy your application (as well as for some local development workflows).
|
|
14
16
|
- [Docker](https://www.docker.com/) or [Finch >= 1.6.0](https://runfinch.com/) is required for some generators. For Docker, [multi-platform builds](https://docs.docker.com/build/building/multi-platform/) must be set up; Finch supports [multi-platform builds](https://runfinch.com/docs/getting-started/building-images/#building-a-multi-architecture-container-image) out of the box.
|
|
15
17
|
- [Terraform >= 1.12](https://developer.hashicorp.com/terraform/install) is required if you choose to use this for infrastructure as code instead of CDK
|
|
@@ -4,8 +4,6 @@ title: Required Prerequisites
|
|
|
4
4
|
- [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
|
5
5
|
- [Node >= 22](https://nodejs.org/en/download) (We recommend using something like [NVM](https://github.com/nvm-sh/nvm) to manage your node versions)
|
|
6
6
|
- verify by running `node --version`
|
|
7
|
-
- [PNPM >= 11](https://pnpm.io/installation#using-npm) (you can also use [Yarn >= 4](https://yarnpkg.com/getting-started/install), [Bun >= 1](https://bun.sh/docs/installation), or [NPM >= 10](https://nodejs.org/en/learn/getting-started/an-introduction-to-the-npm-package-manager) if you prefer)
|
|
8
|
-
- verify by running `pnpm --version`, `yarn --version`, `bun --version` or `npm --version`
|
|
9
7
|
- [UV >= 0.5.29](https://docs.astral.sh/uv/getting-started/installation/)
|
|
10
8
|
1. install Python 3.14 by running: `uv python install 3.14.0`
|
|
11
9
|
2. verify with `uv python list --only-installed`
|