<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael Flanagan</title>
    <description>The latest articles on DEV Community by Michael Flanagan (@michael_flanagan_red).</description>
    <link>https://dev.to/michael_flanagan_red</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2107491%2Fb94154fe-db9b-4204-9d61-897d2d93f01d.jpg</url>
      <title>DEV Community: Michael Flanagan</title>
      <link>https://dev.to/michael_flanagan_red</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/michael_flanagan_red"/>
    <language>en</language>
    <item>
      <title>Bedrock Knowledge Bases with S3 Vectors: A [Preview] CDK Quickstart</title>
      <dc:creator>Michael Flanagan</dc:creator>
      <pubDate>Tue, 26 Aug 2025 22:10:25 +0000</pubDate>
      <link>https://dev.to/michael_flanagan_red/bedrock-knowledge-bases-with-s3-vectors-a-preview-cdk-quickstart-1d8p</link>
      <guid>https://dev.to/michael_flanagan_red/bedrock-knowledge-bases-with-s3-vectors-a-preview-cdk-quickstart-1d8p</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I've been hanging out in the AWS ecosystem for a while, and one of the things I've enjoyed is how Bedrock Knowledge Bases give you a relatively turnkey way to stand up RAG pipelines without duct taping half a dozen services together. The catch has always been vector storage. Until now, your out-of-the-box choices were either OpenSearch (simple but pricey) or Aurora Serverless (flexible but configuration-heavy, even if it scales to zero).&lt;/p&gt;

&lt;p&gt;In July '25, AWS dropped something new into preview: Amazon S3 Vectors. It's a native vector store designed to be dirt cheap (AWS claims up to 90% lower cost than other options) at the expense of some performance. Latencies are higher, but for many workloads, and especially experimentation or pre-production it should be "good enough." Right now S3 Vectors show up as an option when you create new Knowledge Bases in the console… there isn't an official L2 CDK construct yet.&lt;/p&gt;

&lt;p&gt;Repository Link: &lt;a href="https://github.com/MikeORed/building-bedrock-knowledge-base-s3-vectors-aws-cdk" rel="noopener noreferrer"&gt;Building Bedrock Knowledge Base w/S3 Vectors&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Purpose
&lt;/h2&gt;

&lt;p&gt;That's where this CDK construct comes in. I've put together a relatively simple but configurable stack that wires up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An ingestion S3 bucket&lt;/li&gt;
&lt;li&gt;A Bedrock Knowledge Base&lt;/li&gt;
&lt;li&gt;An S3 Vectors bucket and index&lt;/li&gt;
&lt;li&gt;The appropriate IAM scaffolding&lt;/li&gt;
&lt;li&gt;A Lambda-based cleanup finalizer (so your teardown doesn't fail on dangling vector stores).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not fully L2 yet, because most of the S3 Vectors pieces are so fresh they still require &lt;code&gt;AwsCustomResource&lt;/code&gt; with &lt;code&gt;installLatestAwsSdk: true&lt;/code&gt;, and cleanup had to be loaded into a Lambda because CloudFormation deletes in the wrong order otherwise. Hopefully this all gets abstracted in a future CDK release, but for now this construct should give you a reproducible, low-cost way to deploy Knowledge Bases with S3 Vectors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Value
&lt;/h2&gt;

&lt;p&gt;Who's this for? Pretty much anyone who wants to explore Bedrock KBs without burning cash on infra you don't need yet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hobbyists and students: Can build and test RAG pipelines on your own dime without becoming an Aurora expert or burning a clean 100+ USD monthly on OpenSearch.&lt;/li&gt;
&lt;li&gt;Indie devs and small teams: Can prototype workflows, test integrations, or demo features without a runaway AWS bill.&lt;/li&gt;
&lt;li&gt;Enterprise teams: Can spin up a pre-production configuration for experimentation, then later environments can utilize the more performant OpenSearch, Pinecone, or Aurora without rewriting your app since Bedrock's KB API abstracts the vector store, so swapping later is always on the table without changes to the underlying code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;⚠️ One early caveat: if you expect to move beyond this pattern, it's better to bring your own S3 ingestion bucket. Knowledge Bases are bound to their vector stores, so changing later can be destructive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hit the ground running (Quickstart)
&lt;/h2&gt;

&lt;p&gt;Beyond the usual AWS account + CDK bootstrap, there are two things you need squared away before deploying:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Region: As of preview (July '25), S3 Vectors are only available in: &lt;code&gt;us-east-1&lt;/code&gt;,&lt;code&gt;us-east-2&lt;/code&gt;,&lt;code&gt;us-west-2&lt;/code&gt;,&lt;code&gt;eu-central-1&lt;/code&gt;,&lt;code&gt;ap-southeast-2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Embedding model: You must have access to an embedding model supported by Bedrock KBs. At time of writing, that means:

&lt;ul&gt;
&lt;li&gt;Amazon Titan Text Embedding v2: supports 256, 512, or 1024 dimensions&lt;/li&gt;
&lt;li&gt;Amazon Titan Text Embedding v1: requires 1536 dimensions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you try another model, ingestion will fail because the dimensions won't line up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy the Construct
&lt;/h3&gt;

&lt;p&gt;Once you've cloned the repo and reviewed the props you might want to tweak (prefixes, parsing model, deletion behavior, etc.), you can go ahead and synth/deploy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install   # or yarn/pnpm
cdk synth      # optional, to review the generated CloudFormation
# however, on first pass it'd good to get a view on what you're generating!
cdk deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On success you'll get stack outputs that look like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;KnowledgeBaseId&lt;/li&gt;
&lt;li&gt;KnowledgeBaseArn&lt;/li&gt;
&lt;li&gt;IngestionBucketName (upload docs here; defaults to docs/)&lt;/li&gt;
&lt;li&gt;VectorBucketName / VectorIndexName&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Add Documents
&lt;/h3&gt;

&lt;p&gt;Now drop some content into the ingestion bucket. By default, that means s3:///docs/.&lt;/p&gt;

&lt;p&gt;For my first test, I uploaded a handful of short Wikipedia pages about sauces (pipian, mole, béchamel) just to have something fun to query against.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kick Off an Ingestion Job
&lt;/h3&gt;

&lt;p&gt;Next, tell Bedrock to ingest what you just uploaded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws bedrock-agent start-ingestion-job \
  --knowledge-base-id $KB_ID \
  --data-source-id $DS_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then poll until you see it complete:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws bedrock-agent get-ingestion-job \
  --knowledge-base-id $KB_ID \
  --data-source-id $DS_ID \
  --ingestion-job-id $JOB_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also check the status in the AWS Console under Bedrock -&amp;gt; Knowledge Bases -&amp;gt; Ingestion Jobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try a Simple Retrieval
&lt;/h3&gt;

&lt;p&gt;Once the job is complete, you can run a retrieval-only query (no LLM wrapping):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws bedrock-agent-runtime retrieve \
  --knowledge-base-id $KB_ID \
  --retrieval-query '{"text":"What is pipian sauce?"}' \
  --retrieval-configuration '{"vectorSearchConfiguration": {"numberOfResults": 3}}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return raw document chunks with their source references.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step Up to RAG (Retrieve-and-Generate)
&lt;/h3&gt;

&lt;p&gt;Now let's try a full RAG cycle with an LLM on top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws bedrock-agent-runtime retrieve-and-generate \
  --input '{"text":"Summarize pipian sauce in two sentences"}' \
  --retrieve-and-generate-configuration "{
    \"type\": \"KNOWLEDGE_BASE\",
    \"knowledgeBaseConfiguration\": {
      \"knowledgeBaseId\": \"$KB_ID\",
      \"modelArn\": \"arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-sonnet-20240229-v1:0\",
      \"retrievalConfiguration\": {
        \"vectorSearchConfiguration\": { \"numberOfResults\": 3 }
      }
    }
  }"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all goes well, you should see a short, generated answer based on your docs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zr3hc95b56133pu39lr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4zr3hc95b56133pu39lr.png" alt="Retrieval and Generation Example, can you tell I've been cooking more?" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;And just like that, you've got a working S3 -&amp;gt; S3 Vectors Knowledge Base on AWS. You can now hook it into workflows, wrap it with agents, or query it from your own code. If you stick around, the next sections cover some caveats and sharp edges that will save you pain down the line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerations &amp;amp; Watchouts (Before You're Committed)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Vector Store Lock-In
&lt;/h3&gt;

&lt;p&gt;Your Knowledge Base is glued to its vector store. You don't get to swap later so if you decide to move to OpenSearch, Pinecone, Aurora Serverless, etc, you're rebuilding and re-ingesting. Because of that, I'd strongly suggest bringing your own S3 ingestion bucket up front. That way if the KB has to go, your docs don't go with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model + Dimension Choice
&lt;/h3&gt;

&lt;p&gt;Same deal with models and dimensions: once you've set it, that's it. Titan v2 is flexible (256/512/1024), Titan v1 is locked at 1536. Change your mind later? You're tearing down the KB and index and starting over. The construct defaults to Titan v2 at 1024 if you don't care enough to pick.&lt;/p&gt;

&lt;h3&gt;
  
  
  Price vs. Performance
&lt;/h3&gt;

&lt;p&gt;S3 Vectors is dirt cheap, and right now they're the cheapest vector store option AWS has, but the latency is slower. Both ingestion and retrieval take longer compared to OpenSearch or Aurora. For tinkering, prototyping, low-intensity apps, it's more than fine. But if you're building something latency-critical, you'll probably outgrow it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S3 Vectors: sub-second retrieval&lt;/li&gt;
&lt;li&gt;OpenSearch Serverless: low tens of ms retrieval&lt;/li&gt;
&lt;li&gt;Aurora pgvector: low tens-of-ms&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Preview Warnings
&lt;/h3&gt;

&lt;p&gt;Don't forget this is still in preview. The APIs aren't final. Permissions are broad, SDK calls may shift, and if you start seeing weird errors about malformed API calls popping up out of nowhere, that's probably AWS changing things under the hood. I'm expecting to have to refactor this construct a bit before general release, so you'd likely need to do the same if you pull it into your ecosystem.&lt;/p&gt;




&lt;p&gt;With all that in mind, you should be good to get off to the races! If you want the deeper details of why the construct is wired the way it is, hang around for the deep dive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deep Dive (Why the Construct Is Wired the Way It Is)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Custom Resources and Fresh APIs
&lt;/h3&gt;

&lt;p&gt;The first thing you'll notice when you crack open the code: a bunch of &lt;code&gt;AwsCustomResource&lt;/code&gt; blocks with &lt;code&gt;installLatestAwsSdk: true&lt;/code&gt;. This is because S3 Vectors is so new the APIs aren't in the default Lambda runtime SDK yet. This is a preview-only issue, and it'll go away once S3 Vectors land in the managed SDK.&lt;/p&gt;

&lt;p&gt;Small aside: running &lt;code&gt;installLatestAwsSdk&lt;/code&gt; also plays funny with how roles get wired in. Instead of relying on CDK to attach roles cleanly, I had to drop in a couple of explicit inline policies to make sure those Lambdas could actually talk to the services. It's not pretty, but it keeps things working until AWS smooths this out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cleanup Lambda
&lt;/h3&gt;

&lt;p&gt;Normal S3 buckets can't be deleted if they still have objects, and S3 Vector buckets/inxexes are no different. CloudFormation doesn't know that - it just tries to rip things out in reverse order and fails. To fix this, the construct wires in custom resources to delete the index before the bucket, and adds a cleanup Lambda to handle the Bedrock bits (DataSource + Knowledge Base) in the right sequence. On &lt;code&gt;cdk destroy&lt;/code&gt;, the two work together so teardown finishes cleanly instead of leaving you with dangling vector stores or broken stacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Broad Permissions for Now
&lt;/h3&gt;

&lt;p&gt;You'll also see some wide-open IAM statements, especially around &lt;code&gt;s3vectors:*&lt;/code&gt;. That's because the preview only supports &lt;code&gt;*&lt;/code&gt; scoping for data-plane actions. I would not reasonably be able to trust ARN targeting yet as the feature persists through preview. Expect this to tighten up after general release, but in the meantime it's "better working than broken."&lt;/p&gt;

&lt;h3&gt;
  
  
  Parsing Options
&lt;/h3&gt;

&lt;p&gt;By default, ingestion just chunks and indexes your docs. But I wired in optional foundation model parsing: run the content through Claude Sonnet (or another model) with a customizable prompt before vectorization. This is off by default because it can rack up costs fast depending on the model. If you flip it on, make sure the model is enabled in your account/region and double-check permissions + spend expectations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preview Caveat
&lt;/h3&gt;

&lt;p&gt;All of the above (the custom resources, cleanup Lambda, broad IAM, parsing options) are wired this way because we're in preview. Expect SDK upgrades, CDK L2 support (for S3 Vectors/indexes and the datasource), and tighter IAM to land over time. Again, I'll be watching and updating over time as viable, but if I miss an update feel free to keep me honest in the repo!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion (Where This Fits, Where It Doesn't)
&lt;/h2&gt;

&lt;p&gt;At the end of the day, I'm putting out this construct to help folk out while full support is pending. It's here to give you the cheapest, cleanest path into experimenting with Bedrock Knowledge Bases while AWS does what they do to produce the release version of S3 Vectors in the SDKs &amp;amp; CDK. If you're a hobbyist, student, or small team, this is your way to get hands-on without torching a cloud budget. If you're an enterprise shop, this is the kind of thing you point at for prototyping, internal demos, and pre-production environments, knowing you'll likely jump to OpenSearch, Pinecone, or Aurora for production once latency and compliance start mattering more.&lt;/p&gt;

&lt;p&gt;More to the point, it's not the right fit if you're building latency-critical apps where sub-100ms is non-negotiable, and you need stable, compliance-ready APIs today (S3 Vectors is still preview).&lt;/p&gt;

&lt;p&gt;But it is the right fit if you want to understand what Bedrock KBs can do, tinker with your own docs, and start building muscle memory around RAG on AWS without burning dollars unnecessarily.&lt;/p&gt;

&lt;p&gt;Feel free to take this for a spin, let me know how it goes. I'll be iterating this repo as the preview evolves, but real-world feedback is always best!&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS Direct Docs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2025/07/amazon-s3-vectors-preview-native-support-storing-querying-vectors/" rel="noopener noreferrer"&gt;Amazon S3 Vectors Preview Announcement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-vectors.html" rel="noopener noreferrer"&gt;Working with S3 Vectors and vector buckets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base.html" rel="noopener noreferrer"&gt;Amazon Bedrock Knowledge Bases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Community / Blog Posts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://blog.serverlessadvocate.com/" rel="noopener noreferrer"&gt;AWS Serverless Advocate Lee Gilmore&lt;/a&gt; - &lt;a href="https://blog.serverlessadvocate.com/amazon-bedrock-knowledge-bases-with-private-data-7685d04ef396" rel="noopener noreferrer"&gt;Amazon Bedrock Knowledge Bases with Private Data&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.ranthebuilder.cloud" rel="noopener noreferrer"&gt;ranthebuilder.cloud&lt;/a&gt; - &lt;a href="https://ranthebuilder.medium.com/amazon-cloudformation-custom-resources-best-practices-with-cdk-and-python-examples-f8344093bf3f?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Amazon CloudFormation Custom Resources Best Practices with CDK and Python Examples&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;That's it! You've got the quickstart, the caveats, the guts, and the guardrails. Give it a whirl, and if you hit something weird (or find a sharper way to solve the cleanup/permissions pain points), toss an issue or PR in the repo. I'd love to keep this one honest as S3 Vectors matures.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cdk</category>
      <category>rag</category>
    </item>
    <item>
      <title>From Scrolls to Scripts: Orchestrating Agents with Chronicles</title>
      <dc:creator>Michael Flanagan</dc:creator>
      <pubDate>Wed, 11 Dec 2024 01:10:19 +0000</pubDate>
      <link>https://dev.to/michael_flanagan_red/from-scrolls-to-scripts-orchestrating-agents-with-chronicles-n1b</link>
      <guid>https://dev.to/michael_flanagan_red/from-scrolls-to-scripts-orchestrating-agents-with-chronicles-n1b</guid>
      <description>&lt;h2&gt;
  
  
  🏰 Embarking on the Next Chapter
&lt;/h2&gt;

&lt;p&gt;In the previous installments of my AI adventure, we laid down the foundational stones of our grand project. We began by exploring the Documents—the core entities like Actors and Locations that populate our creative worlds. Then, we ventured into the realm of Agents, capable helpers designed to perform specific tasks and bring our documents to life.&lt;/p&gt;

&lt;p&gt;However, these Agents, while powerful individually, lack a unifying narrative to coordinate their actions. This brings us to the next exciting phase: introducing Chronicles. Just as a storyteller weaves characters and events into a captivating narrative, Chronicles orchestrate our Agents, guiding them through complex workflows to achieve larger goals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Stop: Time for reality
&lt;/h3&gt;

&lt;p&gt;As I said before, I come bearing gifts this is my repository for this project:&lt;br&gt;
&lt;a href="https://github.com/MikeORed/codex-of-agents" rel="noopener noreferrer"&gt;Codex of Agents&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For some help to specifically get this initial version off the ground feel free to give this first step readme a read:&lt;br&gt;
&lt;a href="https://github.com/MikeORed/codex-of-agents/blob/main/docs/FIRSTSTEPS.md" rel="noopener noreferrer"&gt;First Steps&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Chronicles?
&lt;/h3&gt;

&lt;p&gt;In AI and automation, managing individual tasks is just the beginning. To tackle more intricate challenges, we need a way to coordinate multiple Agents seamlessly. Chronicles serve as scripts that outline each Agent's role, the sequence of actions, and how data flows between them.&lt;/p&gt;

&lt;p&gt;By orchestrating our Agents with Chronicles, we transform individual performances into a harmonious ensemble, where each member knows their part and contributes to the harmony of the whole.&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting the Stage
&lt;/h3&gt;

&lt;p&gt;In this post, we'll dive into the art of orchestrating Agents using Chronicles. We'll focus on a few illustrative examples to keep things clear and manageable. Through these scenarios, we'll see how Agents can be coordinated to perform complex tasks that would be challenging for them to handle individually.&lt;/p&gt;

&lt;p&gt;Looking ahead, there's much more on the horizon. In the next set of paired posts, we'll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🛠️ Building a More Resilient Serverless Architecture:&lt;/strong&gt; We'll delve into designing an infrastructure that can gracefully handle the demands of our growing system, ensuring scalability and robustness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📜 Expanding the Agent Codex:&lt;/strong&gt; We'll work on building out our list of Agents, enriching our system's capabilities and paving the way for more sophisticated workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for now, let's focus on mastering the basics of orchestration with Chronicles. After all, every epic tale begins with a single chapter.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Power of Names in Software Development
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🌟 What's in a Name?&lt;/strong&gt;&lt;br&gt;
When building anything—be it a world for a tabletop game or a piece of software—the words we choose matter. Precise terminology isn't just about semantics; it's about clear communication and shared understanding.&lt;/p&gt;
&lt;h2&gt;
  
  
  Clarity and Communication
&lt;/h2&gt;

&lt;p&gt;In coding, names are more than labels; they're guides that help us navigate complex systems. A well-chosen name illuminates purpose and intent, reducing confusion for anyone reading the code or documentation. Yet, finding the right names is surprisingly tough. It's a balancing act between technical accuracy and engaging descriptiveness.&lt;/p&gt;
&lt;h2&gt;
  
  
  Our Thematic Shift
&lt;/h2&gt;
&lt;h3&gt;
  
  
  ✨ Embracing Storytelling Elements
&lt;/h3&gt;

&lt;p&gt;To address these challenges, we've embraced storytelling elements in our project. Given my love for narratives, I've decided to infuse our work with a bit of fantasy flair. By adopting terms from storytelling, we're not just writing code—we're crafting an experience.&lt;/p&gt;
&lt;h3&gt;
  
  
  Introducing Our Cast
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📜 Scribe:&lt;/strong&gt; The master planner who crafts Chronicles—the blueprints that guide our Agents.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📖 Chronicles:&lt;/strong&gt; Detailed plans outlining the steps our Agents will take to accomplish complex tasks.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🔖 Chapters:&lt;/strong&gt; Individual steps within a Chronicle, each representing a specific action.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧭 Navigator:&lt;/strong&gt; An Agent that adjusts Chronicles in response to changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🤖 Agents:&lt;/strong&gt; Our trusty helpers who carry out the tasks detailed in the Chronicles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🛠️ Implements:&lt;/strong&gt; The tools our Agents use to perform their duties.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By framing our technical components within a storytelling context, we make the system more engaging and relatable. This consistent theme enhances understanding and fosters a stronger connection to the project.&lt;/p&gt;

&lt;p&gt;(Note: The "Navigator" will be introduced in future posts when its role becomes relevant.)&lt;/p&gt;

&lt;p&gt;To prevent confusion, I'll provide clear definitions whenever introducing a new concept going forward!&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding Orchestration in AI Systems
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🔗 The Art of Coordination&lt;/strong&gt;&lt;br&gt;
In the realm of artificial intelligence, individual components can achieve impressive feats on their own. However, as tasks grow in complexity, these components need to work together harmoniously. This is where orchestration comes into play.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Orchestration?
&lt;/h2&gt;

&lt;p&gt;Orchestration is the coordination of multiple Agents to achieve complex objectives that would be challenging for a single entity. It's about managing workflows, handling dependencies, and ensuring that each part of the system knows its role within the bigger picture.&lt;/p&gt;

&lt;p&gt;Think of it as conducting an orchestra: each musician plays their instrument, but it's the conductor who ensures they all perform in harmony. Similarly, in AI systems, orchestration involves planning and overseeing the interactions between various Agents to execute a multifaceted task seamlessly.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Orchestration Matters
&lt;/h3&gt;

&lt;p&gt;While single agents can perform specific tasks efficiently, they often hit limitations when confronted with more intricate challenges. Coordinating multiple agents allows us to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Divide and Conquer:&lt;/strong&gt; Break down complex goals into manageable, discrete tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leverage Specialization:&lt;/strong&gt; Utilize the unique capabilities of different agents, each designed for specific functions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhance Flexibility:&lt;/strong&gt; Adapt to changing requirements by rearranging or swapping agents without disrupting the entire system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improve Reliability:&lt;/strong&gt; Design systems that can handle failures gracefully by redistributing tasks among agents.
In essence, orchestration is essential for building AI systems that are robust, scalable, and capable of tackling real-world problems with agility.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Designing Our Orchestration Strategy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🛠️ Crafting the Plan&lt;/strong&gt;&lt;br&gt;
With orchestration and our storytelling theme in place, let's delve into how we're implementing this strategy in our project.&lt;/p&gt;
&lt;h3&gt;
  
  
  Our Approach
&lt;/h3&gt;

&lt;p&gt;At the heart of our strategy is the separation of planning and execution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📜 Scribe:&lt;/strong&gt; The master planner who composes Chronicles based on our goals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🤖 Agents:&lt;/strong&gt; Specialists who execute tasks specified in the Chronicles, using their Implements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This division maintains a clean architecture where each component has a distinct responsibility, enhancing scalability and maintainability. The Scribe focuses on crafting adaptable high-level plans, while Agents concentrate on efficiently performing their designated tasks, guided by the detailed instructions within each Chapter.&lt;/p&gt;
&lt;h3&gt;
  
  
  Key Features of Chronicles
&lt;/h3&gt;

&lt;p&gt;We're concentrating on the basics to keep things straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chapters:&lt;/strong&gt; Individual steps within a Chronicle, each representing a specific action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies:&lt;/strong&gt; Relationships between Chapters that determine execution order.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By defining clear dependencies, we control the flow of execution, ensuring that Agents perform their tasks in the correct sequence—crucial when certain actions rely on the results of previous steps.&lt;/p&gt;
&lt;h3&gt;
  
  
  Keeping It Simple
&lt;/h3&gt;

&lt;p&gt;Our initial focus is on these core elements to establish a solid foundation. By mastering the fundamentals of orchestrating Agents with Chronicles, we set the stage for introducing more complex features down the line.&lt;/p&gt;
&lt;h3&gt;
  
  
  Looking Ahead
&lt;/h3&gt;

&lt;p&gt;While we're starting with the essentials, there's plenty of room for growth. In future posts, we'll explore advanced capabilities such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parallelism:&lt;/strong&gt; Allowing multiple Chapters to be executed simultaneously when there are no dependencies between them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries and Error Handling:&lt;/strong&gt; Implementing mechanisms to handle failures gracefully and ensure the robustness of our system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Adjustments:&lt;/strong&gt; Introducing the Navigator to adjust Chronicles in response to changes or new information.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By building upon the basics, we'll gradually enhance our system's capabilities without overwhelming complexity.&lt;/p&gt;


&lt;h2&gt;
  
  
  Architecture of Chronicles in Our System
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🧩 Building the Blueprint&lt;/strong&gt;&lt;br&gt;
Let's delve into the architecture that brings our system to life, focusing on how Chronicles are structured and how they interact with our Agents and Implements.&lt;/p&gt;
&lt;h3&gt;
  
  
  Defining the Chronicle Structure
&lt;/h3&gt;

&lt;p&gt;At the core of our system lies the Chronicle, the orchestrated plan that guides our Agents.&lt;/p&gt;
&lt;h4&gt;
  
  
  Components of a Chronicle
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;🔖 Chapters:&lt;/strong&gt; Goal-driven actions assigned to specific Agents. Think of them as individual quests in our grand adventure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧩 Dependencies:&lt;/strong&gt; Define the order and prerequisites for Chapter execution, maintaining logical flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⏳ Status Tracking:&lt;/strong&gt; Both Chronicles and Chapters have statuses to indicate their progress through the workflow.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Data Structures
&lt;/h4&gt;

&lt;p&gt;Here's how we represent Chronicles and Chapters in code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ChronicleStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;created&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inProgress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ChapterStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;created&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inProgress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Chronicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;// Unique identifier&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// Human-readable title&lt;/span&gt;
  &lt;span class="nl"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// Overarching objective&lt;/span&gt;
  &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChronicleStatus&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Current state&lt;/span&gt;
  &lt;span class="nl"&gt;chapters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Chapter&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;    &lt;span class="c1"&gt;// List of Chapters&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Chapter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;             &lt;span class="c1"&gt;// Unique identifier&lt;/span&gt;
  &lt;span class="nl"&gt;targetAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// Responsible Agent&lt;/span&gt;
  &lt;span class="nl"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;           &lt;span class="c1"&gt;// Specific objective&lt;/span&gt;
  &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ChapterStatus&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Current state&lt;/span&gt;
  &lt;span class="nl"&gt;inputContext&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Required data&lt;/span&gt;
  &lt;span class="nl"&gt;outputContext&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Resulting data&lt;/span&gt;
  &lt;span class="nl"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;             &lt;span class="c1"&gt;// Prerequisites&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Integration with Agents and Implements
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📜 Scribe:&lt;/strong&gt; Generates the Chronicle using LLM requests (e.g., AWS Bedrock's Converse API), transforming user goals into detailed plans.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🤖 Agents:&lt;/strong&gt; Execute assigned Chapters, utilizing Implements to perform actions. They update the status and output context accordingly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🛠️ Implements:&lt;/strong&gt; Tools that empower Agents, such as database connectors or API clients, allowing Agents to focus on their tasks without worrying about underlying mechanics.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Integrating with Agents and Implements
&lt;/h3&gt;

&lt;p&gt;Now that we have our Chronicles defined, let's see how they integrate with our Agents and Implements.&lt;/p&gt;

&lt;h4&gt;
  
  
  📜 Scribe
&lt;/h4&gt;

&lt;p&gt;The &lt;strong&gt;Scribe&lt;/strong&gt; plays a pivotal role in our architecture. Using Large Language Model (LLM) requests—specifically AWS Bedrock's Converse API calls—the Scribe generates the orchestrating Chronicles. It takes the user's goals and transforms them into a detailed plan that our Agents can execute.&lt;/p&gt;

&lt;p&gt;Here's how the Scribe operates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input Processing:&lt;/strong&gt; Receives a natural language prompt from the user or other input sources, which may include multiple tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chronicle Generation:&lt;/strong&gt; Crafts a Chronicle with structured Chapters, assigning each to the appropriate Agent and defining goals, contexts, and dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status Initialization:&lt;/strong&gt; Sets the initial status of the Chronicle and its Chapters to &lt;code&gt;created&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preparation for Execution:&lt;/strong&gt; Updates the status to &lt;code&gt;ready&lt;/code&gt; once the Chronicle is fully defined and dependencies are mapped.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🤖 Agents
&lt;/h4&gt;

&lt;p&gt;Agents are the executors of our Chronicles. Each Agent is responsible for one or more Chapters within a Chronicle. When an Agent receives a Chapter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reads the Goal:&lt;/strong&gt; Understands the specific objective of the Chapter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checks Dependencies:&lt;/strong&gt; Ensures all dependencies have been satisfied before proceeding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uses Implements:&lt;/strong&gt; Leverages its tools (Implements) to perform the necessary actions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Updates Status:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Sets the Chapter status to &lt;code&gt;inProgress&lt;/code&gt; at the start of execution.&lt;/li&gt;
&lt;li&gt;Upon completion, updates the status to &lt;code&gt;complete&lt;/code&gt; and records any output in the &lt;code&gt;outputContext&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If an error occurs, updates the status to &lt;code&gt;failed&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Output Sharing:&lt;/strong&gt; The &lt;code&gt;outputContext&lt;/code&gt; can be accessed by dependent Chapters, facilitating data flow between Agents.&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  🛠️ Implements
&lt;/h4&gt;

&lt;p&gt;Implements are the tools that empower our Agents to perform their duties. They provide the capabilities required for executing each Agent's Chapters. Implements can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database Connectors:&lt;/strong&gt; For storing or retrieving data (e.g., DynamoDB operations).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Clients:&lt;/strong&gt; To interact with external services or APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utility Libraries:&lt;/strong&gt; For tasks like data transformation, validation, or formatting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By abstracting functionalities into Implements, we enable Agents to focus on their specific tasks without worrying about the underlying mechanics. This modularity enhances reusability and simplifies maintenance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example Workflow: Simple Chronicle Execution
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🎭 Bringing It All Together&lt;/strong&gt;&lt;br&gt;
Now that we've laid out the architecture and roles within our system, it's time to see how everything works in practice. Let's walk through a simple yet illustrative example that showcases how the Scribe, Agents, and Implements collaborate to achieve a common goal.&lt;/p&gt;
&lt;h3&gt;
  
  
  Scenario Overview
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Goal (from the user's prompt):
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;I need your help to create some new characters and a location for our game world. First, there's Elthien Pettlebloom, an elf ranger who loves the forest. She's an expert archer and is seeking revenge against the orcs who destroyed her village. Next, Thorgar Ironfist, a dwarf warrior. He's a master blacksmith, enjoys hearty ale, and is on a quest to find the legendary Hammer of Durin. Finally, we need the Misty Mountains, a treacherous mountain range filled with ancient mines, hidden dangers, and rumored to house a sleeping dragon.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Agents Involved:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;📜 DocumentRequestHandlingScribe:&lt;/strong&gt; Our Scribe specialized in handling document-related requests and ensuring data integrity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🤖 ActorSubmissionAgent:&lt;/strong&gt; Responsible for processing and submitting Actor documents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🤖 LocationSubmissionAgent:&lt;/strong&gt; Responsible for processing and submitting Location documents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🤖 DocumentRelationshipMappingAgent:&lt;/strong&gt; Handles mapping relationships within our relationship datastore. This Agent prefers to depend on the resolution of submission-related Agents to reduce executions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: For those curious, I use the term Ancestry when referring to the types and origins of our characters—yes, I'm a big fan of Pathfinder 2nd Edition!&lt;/p&gt;
&lt;h4&gt;
  
  
  Our Scenario’s Chronicle
&lt;/h4&gt;

&lt;p&gt;Upon receiving the user's prompt, the &lt;code&gt;DocumentRequestHandlingScribe&lt;/code&gt; processes the input and generates the following Chronicle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;chronicle&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;chapter&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"chapter-001"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;targetAgent&amp;gt;&lt;/span&gt;ActorSubmissionAgent&lt;span class="nt"&gt;&amp;lt;/targetAgent&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencies/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;Process and submit the document for the character Elthien Pettlebloom.&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;context&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Elthien Pettlebloom&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ancestry&amp;gt;&lt;/span&gt;Elf&lt;span class="nt"&gt;&amp;lt;/ancestry&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;class&amp;gt;&lt;/span&gt;Ranger&lt;span class="nt"&gt;&amp;lt;/class&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;traits&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;trait&amp;gt;&lt;/span&gt;Forest lover&lt;span class="nt"&gt;&amp;lt;/trait&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;trait&amp;gt;&lt;/span&gt;Expert archer&lt;span class="nt"&gt;&amp;lt;/trait&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;trait&amp;gt;&lt;/span&gt;Seeking revenge against orcs who destroyed her village&lt;span class="nt"&gt;&amp;lt;/trait&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/traits&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/context&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/chapter&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;chapter&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"chapter-002"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;targetAgent&amp;gt;&lt;/span&gt;ActorSubmissionAgent&lt;span class="nt"&gt;&amp;lt;/targetAgent&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencies/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;Process and submit the document for the character Thorgar Ironfist.&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;context&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Thorgar Ironfist&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ancestry&amp;gt;&lt;/span&gt;Dwarf&lt;span class="nt"&gt;&amp;lt;/ancestry&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;class&amp;gt;&lt;/span&gt;Warrior&lt;span class="nt"&gt;&amp;lt;/class&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;traits&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;trait&amp;gt;&lt;/span&gt;Master blacksmith&lt;span class="nt"&gt;&amp;lt;/trait&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;trait&amp;gt;&lt;/span&gt;Enjoys hearty ale&lt;span class="nt"&gt;&amp;lt;/trait&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;trait&amp;gt;&lt;/span&gt;On a quest to find the legendary Hammer of Durin&lt;span class="nt"&gt;&amp;lt;/trait&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/traits&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/context&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/chapter&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;chapter&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"chapter-003"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;targetAgent&amp;gt;&lt;/span&gt;LocationSubmissionAgent&lt;span class="nt"&gt;&amp;lt;/targetAgent&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencies/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;Process and submit the document for the location Misty Mountains.&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;context&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Misty Mountains&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;A treacherous mountain range filled with ancient mines, hidden dangers, and rumored to house a sleeping dragon.&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/context&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/chapter&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;chapter&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"chapter-004"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;targetAgent&amp;gt;&lt;/span&gt;DocumentRelationshipMappingAgent&lt;span class="nt"&gt;&amp;lt;/targetAgent&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;chapter-001&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;chapter-002&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;chapter-003&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;Map relationships among the submitted characters and location in the relationship datastore.&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;context/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/chapter&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/chronicle&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Execution Flow
&lt;/h4&gt;

&lt;p&gt;Let's step through how this Chronicle is executed within our system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scribe Generates the Chronicle

&lt;ul&gt;
&lt;li&gt;The DocumentRequestHandlingScribe receives the user's prompt.&lt;/li&gt;
&lt;li&gt;Parses the prompt to identify entities (characters and location).&lt;/li&gt;
&lt;li&gt;Constructs the Chronicle with four Chapters, each assigned to the appropriate Agent.&lt;/li&gt;
&lt;li&gt;Sets the status of the Chronicle and all Chapters to "created".&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Scribe Prepares the Chronicle for Execution

&lt;ul&gt;
&lt;li&gt;Updates the status of the Chronicle to "ready".&lt;/li&gt;
&lt;li&gt;Sets the status of Chapters 1 to 3 to "ready" since they have no dependencies.&lt;/li&gt;
&lt;li&gt;Chapter 4 remains at "created" because it depends on the completion of the first three Chapters.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Agents Execute Chapters 1 to 3

&lt;ul&gt;
&lt;li&gt;For each of Chapters 1 to 3:&lt;/li&gt;
&lt;li&gt;The assigned Agent retrieves the Chapter when its status is "ready".&lt;/li&gt;
&lt;li&gt;Updates the Chapter status to "inProgress".&lt;/li&gt;
&lt;li&gt;Agent Execution Pseudocode:
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;executeChapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Chapter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inProgress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Augment the document using the style guide&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;augmentedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;applyStyleGuide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Submit the document to DynamoDB (simulated)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;documentId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;submitToDynamoDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;augmentedData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Update the Chapter's output context with the document ID&lt;/span&gt;
    &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outputContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;documentId&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle error (e.g., log it, retry logic)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;For Chapters 1 and 2 (ActorSubmissionAgent):

&lt;ul&gt;
&lt;li&gt;Processes the character data.&lt;/li&gt;
&lt;li&gt;Augments the data according to the style guide (e.g., ensuring required fields are present).&lt;/li&gt;
&lt;li&gt;Stores the Actor document in DynamoDB.&lt;/li&gt;
&lt;li&gt;Records the document ID in the outputContext.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;For Chapter 3 (LocationSubmissionAgent):

&lt;ul&gt;
&lt;li&gt;Processes the location data.&lt;/li&gt;
&lt;li&gt;Augments the data as per the style guide.&lt;/li&gt;
&lt;li&gt;Stores the Location document in DynamoDB.&lt;/li&gt;
&lt;li&gt;Records the document ID in the outputContext.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Scribe Updates Chapter 4 to Ready

&lt;ul&gt;
&lt;li&gt;Once Chapters 1 to 3 are "complete", the Scribe (or a simple status-checking mechanism within the Scribe Lambda) updates Chapter 4's status to "ready".&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;DocumentRelationshipMappingAgent Executes Chapter 4

&lt;ul&gt;
&lt;li&gt;The DocumentRelationshipMappingAgent retrieves Chapter 4.&lt;/li&gt;
&lt;li&gt;Updates the Chapter status to "inProgress".&lt;/li&gt;
&lt;li&gt;Agent Execution Pseudocode:
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;executeRelationshipMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Chapter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chronicle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Chronicle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inProgress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Gather outputs from dependencies&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dependencyOutputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;depId&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;depChapter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chronicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chapters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;depId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;depChapter&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;outputContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Process relationships&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;relationships&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;mapRelationships&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dependencyOutputs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Optionally store relationships&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;storeRelationships&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;relationships&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle error&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Functionality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collects the document IDs from Chapters 1 to 3.&lt;/li&gt;
&lt;li&gt;Identifies potential relationships between the characters and the location.&lt;/li&gt;
&lt;li&gt;For example, associating Thorgar Ironfist with the Hammer of Durin if it exists in the datastore.&lt;/li&gt;
&lt;li&gt;Updates the relationship datastore accordingly.&lt;/li&gt;
&lt;li&gt;Marks the Chapter as "complete" upon success.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Completion of the Chronicle&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once all Chapters are "complete", the Chronicle's status is updated to "complete".&lt;/li&gt;
&lt;li&gt;The workflow is successfully executed, and the new characters and location are now part of the game world, with relationships mapped.&lt;/li&gt;
&lt;li&gt;Code Snippets&lt;/li&gt;
&lt;li&gt;Here's a simplified version of how this might look within our Scribe Lambda Function:
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Assume event contains the user's prompt  const userPrompt = event.userPrompt;&lt;/span&gt;
  &lt;span class="c1"&gt;// Step 1: Generate the Chronicle  const chronicle = generateChronicle(userPrompt);&lt;/span&gt;
  &lt;span class="c1"&gt;// Step 2: Prepare Chapters 1-3  chronicle.chapters.forEach(chapter =&amp;gt; {&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// Step 3: Execute Chapters 1-3  for (const chapter of chronicle.chapters) {&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;executeChapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chapter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Step 4: Update Chapter 4 to Ready  const chapter4 = chronicle.chapters.find(ch =&amp;gt; ch.id === 'chapter-004');&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chapter4&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;chapter4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;depId&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;depChapter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chronicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chapters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;depId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;depChapter&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;chapter4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;executeRelationshipMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chapter4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;chronicle&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Step 5: Update Chronicle Status  if (chronicle.chapters.every(ch =&amp;gt; ch.status === 'complete')) {&lt;/span&gt;
    &lt;span class="nx"&gt;chronicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;chronicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// Return the final status  return {&lt;/span&gt;
    &lt;span class="nl"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Chronicle execution complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;chronicleStatus&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;chronicle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Notes on Execution
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;All execution occurs within the Scribe Lambda function&lt;/strong&gt;, simplifying our architecture for this example.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status Management:&lt;/strong&gt; We use the status fields to control the flow of execution and handle dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; If any Chapter fails, its status is set to "failed", and appropriate error handling can be implemented (e.g., retries, logging).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Flow:&lt;/strong&gt; The outputContext of Chapters allows us to pass data between Agents, crucial for dependent tasks like relationship mapping.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Implements in Action
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;applyStyleGuide:&lt;/strong&gt; A utility function (Implement) used by Agents to ensure that the data adheres to our predefined style guidelines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;submitToDynamoDB:&lt;/strong&gt; An Implement that abstracts the process of storing documents in DynamoDB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mapRelationships:&lt;/strong&gt; Used by the DocumentRelationshipMappingAgent to establish connections between entities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;storeRelationships:&lt;/strong&gt; An Implement for persisting relationship data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Outcome
&lt;/h4&gt;

&lt;p&gt;By the end of this workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Elthien Pettlebloom and Thorgar Ironfist are added to our game world's database as new characters.&lt;/li&gt;
&lt;li&gt;The Misty Mountains becomes part of our location data.&lt;/li&gt;
&lt;li&gt;Relationships among the characters and location are established, enriching the game's narrative fabric.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This example demonstrates how our system orchestrates multiple Agents to achieve a complex goal, all within a single execution flow. It showcases the power of the Chronicle structure, the coordination of Agents, and the utility of Implements.&lt;/p&gt;

&lt;p&gt;In the next section, we'll reflect on how this workflow highlights the strengths of our orchestration strategy and discuss potential enhancements for future iterations. The journey doesn't end here—there are many more adventures to embark upon as we continue to build and refine our system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Highlighting the Potential of Chronicles
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🌟 Unleashing the Power of Coordination&lt;/strong&gt;&lt;br&gt;
By now, we've seen how Chronicles serve as the orchestrators of our Agents, guiding them through complex tasks with ease. But what makes Chronicles truly shine in our system? Let's delve into the benefits that Chronicles bring to the table and how they set the stage for future enhancements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of Using Chronicles
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Scalability
&lt;/h4&gt;

&lt;p&gt;One of the standout advantages of utilizing Chronicles is the inherent scalability they offer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Effortless Expansion:&lt;/strong&gt; Need to add a new feature or incorporate another Agent? With Chronicles, it's as simple as writing a new Chapter and assigning it to the appropriate Agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel Development:&lt;/strong&gt; Multiple Chronicles can be crafted and executed simultaneously, allowing different teams or Agents to work on various aspects of the project without stepping on each other's toes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Maintainability
&lt;/h4&gt;

&lt;p&gt;A well-structured Chronicle makes maintaining and updating our system a breeze.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clear Structure:&lt;/strong&gt; Each Chapter within a Chronicle is a self-contained unit with a specific goal, making it easier to identify where changes need to be made.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Debugging:&lt;/strong&gt; If something goes awry, the status tracking within Chronicles and Chapters helps pinpoint exactly where the issue occurred, reducing downtime and frustration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Flexibility
&lt;/h4&gt;

&lt;p&gt;Perhaps one of the most exciting aspects is the flexibility that Chronicles introduce.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Adaptive Agents:&lt;/strong&gt; Agents can interpret and execute Chapters based on the context provided, allowing for dynamic responses to varying inputs or situations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easy Reconfiguration:&lt;/strong&gt; Want to change the flow of tasks? Adjusting dependencies or reordering Chapters in a Chronicle allows us to reshape the workflow without extensive rewrites.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setting the Stage for Future Enhancements
&lt;/h3&gt;

&lt;p&gt;Our journey doesn't stop here. Chronicles open up a world of possibilities for more sophisticated workflows and integrations.&lt;/p&gt;

&lt;h4&gt;
  
  
  Complex Workflows
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Intricate Dependencies:&lt;/strong&gt; Future Chronicles can incorporate more complex dependency structures, enabling the modeling of intricate processes that mirror real-world scenarios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditional Logic:&lt;/strong&gt; Introducing conditions within Chapters can allow Agents to make decisions on the fly, further enhancing the system's responsiveness.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Integration with the Agent Codex
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Expanding the Roster:&lt;/strong&gt; As we build out our Agent Codex, we'll introduce new Agents with specialized skills, broadening the system's capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Functionality:&lt;/strong&gt; With a richer set of Agents and Implements, Chronicles can orchestrate more diverse and powerful workflows, from data analytics to real-time decision-making.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;🚀 Charting the Path Forward&lt;/strong&gt;&lt;br&gt;
With the foundational pieces in place, it's time to look ahead at what's on the horizon for our project. The journey of building this system is akin to an epic tale, and the next chapters promise to be just as thrilling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exploring Resilient Serverless Architecture
&lt;/h3&gt;

&lt;p&gt;In the upcoming posts, we'll dive into designing a more robust serverless architecture.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scalability at Scale:&lt;/strong&gt; We'll explore how to ensure our system can handle increased load without breaking a sweat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Management:&lt;/strong&gt; Managing state in a distributed, serverless environment presents unique challenges. We'll tackle these head-on, implementing solutions that keep our system responsive and reliable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Building Out the Agent Codex
&lt;/h3&gt;

&lt;p&gt;Our Agents are the heart of the system, and it's time to expand their ranks.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;New Agents and Implements:&lt;/strong&gt; We'll introduce a host of new Agents, each bringing unique capabilities to the table. From data processors to AI-driven decision-makers, the possibilities are vast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Flexibility:&lt;/strong&gt; With more Agents at our disposal, Chronicles can orchestrate increasingly complex tasks, opening doors to functionalities we haven't yet imagined.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By focusing on these areas, we're setting ourselves up for a future where our system isn't just functional—it's exceptional.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;📝 Wrapping Up Our Journey&lt;/strong&gt;&lt;br&gt;
As we close this chapter, let's reflect on the ground we've covered and look forward to the adventures yet to come.&lt;/p&gt;

&lt;h3&gt;
  
  
  Recap of Key Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Power of Chronicles:&lt;/strong&gt; We've seen how Chronicles serve as the orchestrators, uniting our Agents to achieve complex goals efficiently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thoughtful Naming Matters:&lt;/strong&gt; By embracing storytelling elements, we've made our system more engaging and easier to understand, demonstrating that clarity and creativity can go hand in hand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity in Action:&lt;/strong&gt; Even a simple Chronicle can coordinate multiple Agents to perform tasks that would be challenging to handle individually.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Invitation for Engagement
&lt;/h3&gt;

&lt;p&gt;I encourage you to explore the repository and experiment with the code. Whether you're a seasoned developer or just starting out, there's a place for you in this journey.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Try It Out:&lt;/strong&gt; Clone the repo, run the examples, and see how Chronicles and Agents work together firsthand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Share Your Thoughts:&lt;/strong&gt; Your feedback is invaluable. Feel free to open issues, suggest enhancements, or share your experiences.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Looking Forward
&lt;/h3&gt;

&lt;p&gt;The story doesn't end here—it's just beginning. Stay tuned for our next installment, where we'll dive into advanced orchestration mechanisms and expand our Agent Codex, setting the stage for even more ambitious projects.&lt;/p&gt;




&lt;h2&gt;
  
  
  References (The Big One)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Repository: &lt;a href="https://github.com/MikeORed/codex-of-agents" rel="noopener noreferrer"&gt;Codex of Agents&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>typescript</category>
      <category>learning</category>
    </item>
    <item>
      <title>Building the Backbone: Entities Part 2, Agent</title>
      <dc:creator>Michael Flanagan</dc:creator>
      <pubDate>Tue, 12 Nov 2024 02:04:27 +0000</pubDate>
      <link>https://dev.to/michael_flanagan_red/building-the-backbone-entities-part-2-agent-4kca</link>
      <guid>https://dev.to/michael_flanagan_red/building-the-backbone-entities-part-2-agent-4kca</guid>
      <description>&lt;h2&gt;
  
  
  The Best Way to Start a Story Is from the Beginning
&lt;/h2&gt;

&lt;p&gt;In my previous post, I laid the foundations for our core structure—defining the fundamental entity structure and fleshing out the Document entity that underpins our system. With this groundwork in place, I'm excited to dive into defining the Agent as an entity.&lt;br&gt;
However, I can't jump straight into that just yet. While the concepts of documents and their derived types might make intuitive sense, it's important to cover some basic concepts around Agents (a common shorthand for AI Agent).&lt;br&gt;
Once I've laid out these concepts, I'll be able to define the related entities in this context, the basic actions needed for these entities, and finally present the full picture for this page of our codex.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agents, Their Pieces and Their Wholes
&lt;/h2&gt;

&lt;p&gt;To get started, AWS describes agents as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"An artificial intelligence (AI) agent is a software program that can interact with its environment, collect data, and use the data to perform self-determined tasks to meet predetermined goals." - &lt;a href="https://aws.amazon.com/what-is/ai-agents/" rel="noopener noreferrer"&gt;Link&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As that implies, agents are expected to perform actions much like a "normal human" might, given the same information available to them. The most prolific agents in distribution are the myriad AI chatbots that have emerged in recent years, with several "out-of-the-box" chatbots capable of evaluating files, searching the internet, and more.&lt;br&gt;
Agents reveal much more of their potential when we take things a step further—allowing these programs access to other systems via APIs or similar methods. By providing them with context-specific datasets, we enable agents to achieve their goals significantly more accurately.&lt;br&gt;
To accomplish this our Agents will use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large Language Models (LLM): These will translate my instructions, context, and the options available into a plan of action.&lt;/li&gt;
&lt;li&gt;Tool Use/Function Calling: This enables the agent to execute its plan of action by reaching out to APIs, datasets, or even executing code on its own.&lt;/li&gt;
&lt;li&gt;Agent Orchestration: While individual agents are powerful, orchestrating multiple agents amplifies that power, allowing them to achieve goals that are too intricate for a single agent to handle. Think of orchestration as a collaborative effort where each agent performs specialized roles, enabling them to tackle more complex problems by working in unison. This coordination—whether managing story details in a campaign or automating multifaceted workflows—opens doors to streamlined and sophisticated outcomes that one agent alone couldn't accomplish.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's delve a little deeper.&lt;/p&gt;

&lt;h3&gt;
  
  
  LLMs, Mind in the Model
&lt;/h3&gt;

&lt;p&gt;At the heart of an agent's capabilities lies the Large Language Model (LLM). These models are trained on vast amounts of text data, enabling them to understand and generate human-like language. In my system, the LLM acts as the "brain" of the agent, interpreting instructions, understanding context, and formulating plans.&lt;/p&gt;

&lt;h4&gt;
  
  
  How LLMs Function in the Agent:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Interpreting Instructions: The LLM processes my input—be it a command, a question, or a narrative prompt—and determines the underlying intent.&lt;/li&gt;
&lt;li&gt;Contextual Understanding: By leveraging the context-specific datasets I provide (like campaign notes or world-building documents), the LLM can generate responses that are highly relevant and tailored to the specific scenario.&lt;/li&gt;
&lt;li&gt;Generating a Plan of Action: Based on the instructions and context, the LLM devises a sequence of steps or actions that the agent should take to achieve the desired goal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tools, Body of Work
&lt;/h3&gt;

&lt;p&gt;While the LLM provides the cognitive processing, the agent needs tools to interact with the environment and execute tasks. These tools are like the "hands" and "feet" of the agent, enabling it to perform actions beyond just thinking.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Tools and Functions:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;API Access: Allows the agent to retrieve data from or send commands to external services. For example, fetching the latest game notes from a database or updating a character's status.&lt;/li&gt;
&lt;li&gt;Dataset Interaction: Enables the agent to read from and write to specific datasets, ensuring it has the most up-to-date information and can record new insights.
Code Execution: Grants the agent the ability to run code snippets, automate scripts, or perform computations necessary for its tasks.&lt;/li&gt;
&lt;li&gt;External Integrations: Tools that let the agent interface with other platforms, like sending messages on communication apps or updating documents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By equipping agents with these tools, they can move from planning to action, effectively bridging the gap between decision-making and execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Orchestration, Living in a Society
&lt;/h3&gt;

&lt;p&gt;As tasks grow in complexity, a single agent may not suffice. Orchestration comes into play by coordinating multiple agents, each with specialized roles, to work together harmoniously.&lt;/p&gt;

&lt;h4&gt;
  
  
  Benefits of Agent Orchestration:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Specialization: Agents can focus on what they do best. One might handle data retrieval, another manages analysis, and a third focuses on content generation.&lt;/li&gt;
&lt;li&gt;Parallel Processing: Tasks can be divided among agents to be executed simultaneously, improving efficiency.&lt;/li&gt;
&lt;li&gt;Collaboration: Agents can share results and insights with each other, enhancing the overall capabilities of the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Real-World Application: LLM-as-a-Judge
&lt;/h4&gt;

&lt;p&gt;Imagine a scenario where an Agent acts as a "judge" to evaluate and score the quality of outputs generated by other agents, enabling a systematic and unbiased approach to selecting the best result.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Basic Orchestration: Start with a simple setup where one agent generates content—let’s say a product description. The LLM-as-a-Judge agent then reviews this description against specific criteria, such as clarity or conciseness, and assigns it a score along with constructive feedback. This basic orchestration not only improves content quality but also provides transparent reasoning that can be used for further refinement.&lt;/li&gt;
&lt;li&gt;Multi-Agent Evaluation: Now, consider a more complex situation where multiple agents produce outputs—say, three agents tasked with generating alternative headlines for a marketing campaign. The LLM-as-a-Judge then evaluates each headline, selecting the one that best meets a particular metric, such as engagement potential or brand alignment. In this setup, the judge agent doesn’t just rate outputs but actively decides which submission is the "winner," streamlining decision-making and ensuring a standard of quality.&lt;/li&gt;
&lt;li&gt;Scalable Orchestration for Diverse Outputs: In an even more advanced use case, orchestration could involve multiple "judged" agents working on different aspects of a task. For example, imagine a content creation pipeline where one agent generates text, another designs accompanying visuals, and a third drafts social media captions. The LLM-as-a-Judge evaluates these outputs based on coherence and alignment with campaign goals, selecting the best combination to form a cohesive final piece. This layered orchestration maximizes output quality by coordinating specialized agents and aligning their work with overarching objectives.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://mermaid.live/edit#pako:eNp1kcFqhDAQhl8lzNk9GG8eChbdLoXSwhYKNR6CmdWATiQmC2Xdd292XS09mFMy-eZjkv8CtVEIKTRWDi37zAUJynhcHlCqThOyFyS00hnLsgbJsbhiu93T9CjjyFYynljOy1evGpzZShALK-N8W8c3dfymWwzJtiHZNCR_hpzfoeIsO_8PGidW8PKIHdZuZM84uvXqMX4xt35Yc9YqdH5pIk3Nik1sz8u9Jtmxd-8G7yqIoEfbS63Cx15uFgGuxR4FpGGr8CR95wQIugZUemeOP1RD6qzHCKzxTbsc_KDCuLmWIZ8e0pPsxlBFpcP73-bk7gFGMEj6NmZhrr8ArJ4l" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2Fpako%3AeNp1kcFqhDAQhl8lzNk9GG8eChbdLoXSwhYKNR6CmdWATiQmC2Xdd292XS09mFMy-eZjkv8CtVEIKTRWDi37zAUJynhcHlCqThOyFyS00hnLsgbJsbhiu93T9CjjyFYynljOy1evGpzZShALK-N8W8c3dfymWwzJtiHZNCR_hpzfoeIsO_8PGidW8PKIHdZuZM84uvXqMX4xt35Yc9YqdH5pIk3Nik1sz8u9Jtmxd-8G7yqIoEfbS63Cx15uFgGuxR4FpGGr8CR95wQIugZUemeOP1RD6qzHCKzxTbsc_KDCuLmWIZ8e0pPsxlBFpcP73-bk7gFGMEj6NmZhrr8ArJ4l%3Ftype%3Dpng" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining Agents as Entities
&lt;/h2&gt;

&lt;p&gt;Now that we have a clearer understanding of what our agents need to accomplish and a glimpse into how they operate, let's discuss the actual business entity. We'll be defining our Agent entity through its own instructions and the Tool sub-entities it can access to fulfill these instructions.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Agent
&lt;/h3&gt;

&lt;p&gt;The eponymous star in our &lt;em&gt;Codex of Agents&lt;/em&gt;, the Agent entity is the cornerstone of our system. When one of our agents is invoked, it generates a Plan. During the plan's evaluation, different tools are called, various LLM models are utilized, and potentially other agents are orchestrated to meet the requirements for the agent's execution.&lt;/p&gt;

&lt;h4&gt;
  
  
  Properties:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Capabilities: A list of actions or tools the agent can utilize, defining what it can do within the system.&lt;/li&gt;
&lt;li&gt;Context: Stores any context-specific information the agent needs to function effectively, such as current tasks or relevant data.&lt;/li&gt;
&lt;li&gt;State: Keeps track of the agent's current status or any intermediate data during operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Methods:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;generatePlan(instruction): Uses the LLM to create a plan of action based on the given instruction and context.

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;To Be Continued...&lt;/em&gt;: You may notice the Plan type outlined isn't delved into in this document, nor are these methods around the plan / integrations actually fully defined. We'll get to that a post or two down the road so we can fully delve into Orchestration.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;executePlan(plan): Carries out the steps defined in the plan using available tools.&lt;/li&gt;

&lt;li&gt;interactWithAgent(otherAgent): Facilitates communication and collaboration with other agents when orchestrated.&lt;/li&gt;

&lt;li&gt;updateState(newState): Updates the agent's internal state based on actions taken or new information received.
&lt;h4&gt;
  
  
  Sample Code Snippet:
&lt;/h4&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Entity&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./entity&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Tool&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./tool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DocumentType&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;_DocumentType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@smitty/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AgentProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="nl"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Entity&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AgentProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AgentProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Additional initialization if needed&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;generatePlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Plan&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Utilize LLM to generate a plan based on the instruction and context&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generatePlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;instruction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;executePlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;plan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Plan&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Execute each step in the plan using available tools&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;updateState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;newState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Additional agent-specific methods...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Tools
&lt;/h3&gt;

&lt;p&gt;Tools are standardized components that empower agents to perform specific actions. They follow a consistent structure, making them easily integrable and reusable across different agents.&lt;/p&gt;

&lt;h4&gt;
  
  
  Standard Structure of Tools
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Name: A unique name for the tool, should be somewhat human readable so plans around the tool may be made easier.&lt;/li&gt;
&lt;li&gt;Description: Explains what the tool does, aiding the agent in selecting the appropriate tool for a task.&lt;/li&gt;
&lt;li&gt;Input Schema: Defines the expected input parameters, ensuring the tool is used correctly.&lt;/li&gt;
&lt;li&gt;Parameters (Params): Specific configurations or settings required by the tool, allowing customization for different contexts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design is influenced by guidelines from &lt;a href="https://docs.anthropic.com/en/docs/build-with-claude/tool-use" rel="noopener noreferrer"&gt;Anthropic's Tool Use&lt;/a&gt; and AWS's &lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/tool-use.html" rel="noopener noreferrer"&gt;Bedrock Tool Documentation&lt;/a&gt;, which emphasize the importance of clear interfaces for tool integration.&lt;/p&gt;

&lt;h4&gt;
  
  
  Base Tool Interface
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ToolInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Define the structure of the input required by the tool&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ToolParams&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Define any additional parameters or configurations&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tool&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TInput&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ToolInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TParams&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ToolParams&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TParams&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  DynamoDB Tool
&lt;/h4&gt;

&lt;p&gt;As an example, let's explore a tool that allows agents to interact with DynamoDB to retrieve items based on a given key or composite key.&lt;/p&gt;

&lt;h5&gt;
  
  
  Key Features:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Configurable Parameters: Includes the table name and key schema (key names and types) necessary for querying DynamoDB.&lt;/li&gt;
&lt;li&gt;Input Definition: Specifies the inputs required to perform the operation, such as key values.&lt;/li&gt;
&lt;li&gt;Execution Logic: Implements the execute method to perform the actual DynamoDB query.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  Implementation:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DocumentType&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;_DocumentType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@smitty/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Tool&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./tool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;DynamoDBToolInput&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ToolInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;DynamoDBToolParams&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ToolParams&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;keySchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// Key names and their data types&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GetDynamoDBItemTool&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Tool&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DynamoDBToolInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DynamoDBToolParams&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DynamoDBToolParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;_DocumentType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromEntries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keySchema&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(([&lt;/span&gt;&lt;span class="nx"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;keyType&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
              &lt;span class="nx"&gt;keyName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;keyType&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;])&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keySchema&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GetDynamoDBItem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Retrieves an item from DynamoDB based on the provided key.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;inputSchema&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DynamoDBToolInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Validate input against inputSchema if necessary&lt;/span&gt;

    &lt;span class="c1"&gt;// Use AWS SDK to query DynamoDB&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dynamoDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DynamoDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DocumentClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;TableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dynamoDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Handle error&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When an agent needs to retrieve data from DynamoDB, it can utilize this tool by providing the necessary input, and the tool handles the rest.&lt;/p&gt;

&lt;h5&gt;
  
  
  Example Instantiation:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usersKeySchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getUserTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GetDynamoDBItemTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UsersTable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;keySchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;usersKeySchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;12345&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;getUserTool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error retrieving user:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  AgentHandoff Tool
&lt;/h4&gt;

&lt;p&gt;The AgentHandoffTool embodies the concept of orchestration within our system. It enables an agent to delegate tasks or pass context to another agent seamlessly.&lt;/p&gt;

&lt;h5&gt;
  
  
  Functionality:
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Defines Target Agent(s): Specifies the key or identifier of the agent(s) to hand off to.&lt;/li&gt;
&lt;li&gt;Execution Logic: Through the execute method, the tool facilitates passing the current context and appropriate input to the designated agents.&lt;/li&gt;
&lt;li&gt;Seamless Transition: Allows agents to collaborate by handing off tasks without interrupting the workflow.
##### Implementation:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DocumentType&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;_DocumentType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@smitty/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Tool&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./tool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Agent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./agent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AgentRepository&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./agentRepository&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AgentHandoffInput&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ToolInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AgentHandoffParams&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ToolParams&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;targetAgentIds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;// IDs of the agents to hand off to&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentHandoffTool&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Tool&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AgentHandoffInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AgentHandoffParams&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AgentHandoffParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;_DocumentType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;context&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AgentHandoff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hands off the current task and context to specified agent(s).&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;inputSchema&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AgentHandoffInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Validate input against inputSchema if necessary&lt;/span&gt;

    &lt;span class="c1"&gt;// Logic to pass context and input to target agents&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agentId&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;targetAgentIds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetAgent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;AgentRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAgentById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;agentId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;targetAgent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;targetAgent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;receiveHandoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Handle agent not found scenario&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Agent with ID &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;agentId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; not found.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Handoff Complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Example Instantiation:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agentHandoffTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AgentHandoffTool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;targetAgentIds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;agent-abc123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;agent-def456&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handoffInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;sessionId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;session-789&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Process user feedback&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;agentHandoffTool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handoffInput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Phew! That was a bit dive into our agents and tools. Like characters in a story finding their roles, it's good to see our entities finding their parts in this project. We've set a solid foundation, and I can't wait to see how these agents will interact and evolve as we continue this journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;In our next installment, we'll embark on the adventure of defining Plans—the blueprints that guide our agents' actions. We'll explore how these plans function, how they're crafted, and how they orchestrate the harmony between agents and tools. Plus, we'll start following along with the code for this project. &lt;/p&gt;

&lt;p&gt;Stay tuned; the plot is just getting interesting!&lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful References
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Evidently AI's LLM-as-a-Judge Guide:&lt;/strong&gt; &lt;a href="https://www.evidentlyai.com/llm-guide/llm-as-a-judge" rel="noopener noreferrer"&gt;LLM-as-a-Judge&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;AWS AI Agents Overview:&lt;/strong&gt; &lt;a href="https://aws.amazon.com/what-is/ai-agents/" rel="noopener noreferrer"&gt;AWS AI Agents&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Anthropic Tool Use:&lt;/strong&gt; &lt;a href="https://docs.anthropic.com/en/docs/build-with-claude/tool-use" rel="noopener noreferrer"&gt;Tool Use with Anthropic's Models&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Bedrock Tool Use:&lt;/strong&gt; &lt;a href="https://docs.aws.amazon.com/bedrock/latest/userguide/tool-use.html" rel="noopener noreferrer"&gt;Tool Use with AWS Bedrock&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>typescript</category>
      <category>learning</category>
    </item>
    <item>
      <title>Building the Backbone: Entities Part 1, Document</title>
      <dc:creator>Michael Flanagan</dc:creator>
      <pubDate>Sat, 02 Nov 2024 23:11:54 +0000</pubDate>
      <link>https://dev.to/michael_flanagan_red/building-the-backbone-entities-part-1-document-2n9f</link>
      <guid>https://dev.to/michael_flanagan_red/building-the-backbone-entities-part-1-document-2n9f</guid>
      <description>&lt;h2&gt;
  
  
  🏗️ Laying the Foundation: Embracing Worldbuilding and Game Mastery
&lt;/h2&gt;

&lt;p&gt;In my previous post, I embarked on an AI journey to tackle the complexities of managing creative projects, particularly in the realm of tabletop games, cooking, and note management. I'm excited to say that the direction for implementing this document management framework will be in the realm of the fantastical, specifically in the realm of world building and game mastery.&lt;/p&gt;

&lt;p&gt;Today, I'm excited to dive deeper into the technical side, focusing on defining the core &lt;code&gt;Document&lt;/code&gt; type that will serve as the backbone of this system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why go down this path?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a game master and worldbuilder, I deal with an ever-growing web of characters, locations, lore, and countless other elements that make up the worlds I enjoy with my friends. However, managing all this information can be overwhelming, and details can easily get lost or be obfuscated unless you're an ace power user of your tool of choice.&lt;/p&gt;

&lt;p&gt;In short, I wanted to create a system that not only organizes this data efficiently but also allows for scalability, flexibility as my worlds expand, and lets my players and friends have an easier time reviewing and relating to the world they're playing in.&lt;/p&gt;

&lt;p&gt;To start, by implementing a robust &lt;code&gt;Document&lt;/code&gt; type that extends from a generic Entity base class, I can ensure that all pieces of content in my system are treated uniformly, allowing for consistent handling of metadata, relationships, and domain events. This design choice aligns with a few of the principles from Clean Architecture and Domain-Driven Design, providing a strong foundation for future growth.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7dsiqp0nbphotom21yv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl7dsiqp0nbphotom21yv.png" alt="The Tree of Entities!" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Understanding the Core: &lt;code&gt;Entity&lt;/code&gt; and &lt;code&gt;Document&lt;/code&gt; Classes
&lt;/h2&gt;

&lt;p&gt;At the heart of my system lies the Entity base class. This generic class provides the foundational properties and methods common to all entities in the system. By extending Entity, the &lt;code&gt;Document&lt;/code&gt; class inherits these essential features and adds document-specific properties and behaviors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entity Base Class&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Purpose: Provides unique identification, domain event handling, and common functionalities for all entities.&lt;/li&gt;
&lt;li&gt;Properties:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_id&lt;/code&gt;: Unique identifier (UUID).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_created&lt;/code&gt;: Timestamp of creation.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_updated&lt;/code&gt;: Timestamp of the last update.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;props&lt;/code&gt;: Properties specific to the derived class.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Methods:

&lt;ul&gt;
&lt;li&gt;Domain event handling (&lt;code&gt;addDomainEvent&lt;/code&gt;, &lt;code&gt;clearDomainEvents&lt;/code&gt;, etc.).&lt;/li&gt;
&lt;li&gt;Validation and timestamp management.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export abstract class Entity&amp;lt;T&amp;gt; {
  private readonly _id: string;
  private readonly _created: string;
  private _updated: string;
  protected props: T;
  private _domainEvents: DomainEvent[] = [];

  constructor(props: T, id?: string, created?: string, updated?: string) {
    this._id = id ? id : uuid();
    this._created = created ? created : new Date().toISOString();
    this._updated = updated ? updated : new Date().toISOString();
    this.props = {
      ...props,
      id: this._id,
      created: this._created,
      updated: this._updated,
    };
  }

  // Domain event methods, getters, and setters...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Document Class (Extends Entity)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Purpose: Serves as the base class for all document types in the system.&lt;/li&gt;
&lt;li&gt;Additional Properties (within &lt;code&gt;props&lt;/code&gt;):

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;title&lt;/code&gt;: The document's title.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content&lt;/code&gt;: Main body of the document.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;metadata&lt;/code&gt;: Collection of key-value pairs for additional context.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Methods:

&lt;ul&gt;
&lt;li&gt;Document-specific behaviors and utilities.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface DocumentProps {
  title: string;
  content: string;
  metadata: Map&amp;lt;string, any&amp;gt;;
  relationships: Relationship[];
  // Other properties as needed
}

class Document extends Entity&amp;lt;DocumentProps&amp;gt; {
  constructor(props: DocumentProps) {
    super(props);
    // Additional initialization if needed
  }

  // Document-specific methods...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔍 Defining Actors and Locations as Specialized Documents
&lt;/h2&gt;

&lt;p&gt;In these early days, I need to determine the key entities required to get this project moving, knowing that there will be more to add as the project evolves. And in this context, two are relatively obvious: Actor and Location. By inheriting from Document, they gain all the base functionality and can add their own specific properties and methods, and give a good view into how the framework will need to adapt as more complex relationships eventually get made.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actor Class (Extends Document)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Purpose: Represents a person or creature within the game world.&lt;/li&gt;
&lt;li&gt;Additional Properties (within props):

&lt;ul&gt;
&lt;li&gt;name: { full name, given name, etc.}&lt;/li&gt;
&lt;li&gt;ancestry: the ancestral origins of the actor, could be Human, Orc, Dragon, etc.&lt;/li&gt;
&lt;li&gt;relationships: Connections to other entities.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface ActorProps extends DocumentProps {
  name: ActorName,
  ancestry: ActorAncestry,
}

class Actor extends Document {
  constructor(props: ActorProps) {
    super(props);
    // Additional initialization if needed
  }

  // Actor-specific methods...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Location Class (Extends Document)&lt;/p&gt;

&lt;p&gt;Purpose: Represents a place within the game world.&lt;br&gt;
Additional Properties (within props):&lt;br&gt;
geography: Details about terrain, climate, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface LocationProps extends DocumentProps {
  geography: string;
}

class Location extends Document {
  constructor(props: LocationProps) {
    super(props);
    // Additional initialization if needed
  }

  // Location-specific methods...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔗 Class Relationships
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://mermaid.live/edit#pako:eNqFU8FOwzAM_ZUoJxDbD1RcJroDEkOIcaNoshKvjdQmVepOTGP_jpc2WxhF9JDG71nxe45zkMpplJlUNXRdbqD00BRW8Le0ZGgv7r_mc5E71TdoaWBiNHALRc5PEU9OARlnCzuwoUQ89jBgp-9uTd7YUmyMngCVRyCcYvpWXzFvovWu7RIkdw0Yu9yxqPcPsdGXMM0CrZPEGzytORKYusvE40NQkCTcZmLnotjjT3vnFiQGI_ZyJW40wv2o8TesnKVzywOxglY0LIttQwK_Yh363FWmZZM-CZNqk2rD3aVSAxB0CvykP5WHtGdoUFheromFVdiR3wsYN5O143ik5SP2v4KxSSU6nti2upSQM9mg57vSPNXh6EJShaxSZrzVuIW-pkIW9sip0JNb762SGfkeZ9K7vqxiMAzY-ChktoW6YxS1YY-r8dmcfsdvyiQKww" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2Fpako%3AeNqFU8FOwzAM_ZUoJxDbD1RcJroDEkOIcaNoshKvjdQmVepOTGP_jpc2WxhF9JDG71nxe45zkMpplJlUNXRdbqD00BRW8Le0ZGgv7r_mc5E71TdoaWBiNHALRc5PEU9OARlnCzuwoUQ89jBgp-9uTd7YUmyMngCVRyCcYvpWXzFvovWu7RIkdw0Yu9yxqPcPsdGXMM0CrZPEGzytORKYusvE40NQkCTcZmLnotjjT3vnFiQGI_ZyJW40wv2o8TesnKVzywOxglY0LIttQwK_Yh363FWmZZM-CZNqk2rD3aVSAxB0CvykP5WHtGdoUFheromFVdiR3wsYN5O143ik5SP2v4KxSSU6nti2upSQM9mg57vSPNXh6EJShaxSZrzVuIW-pkIW9sip0JNb762SGfkeZ9K7vqxiMAzY-ChktoW6YxS1YY-r8dmcfsdvyiQKww%3Ftype%3Dpng" width="559" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ✏️ Why This Implementation?
&lt;/h2&gt;

&lt;p&gt;Choosing this structure offers several advantages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uniform Handling of Entities:&lt;/strong&gt; By having all classes extend from &lt;code&gt;Entity&lt;/code&gt;, we ensure that core functionalities like identity management and domain event handling are consistent across the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extensibility:&lt;/strong&gt; New document types can be added easily by extending &lt;code&gt;Document&lt;/code&gt;. This makes the system flexible and adaptable to future needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Separation of Concerns:&lt;/strong&gt; &lt;code&gt;Entity&lt;/code&gt; handles generic entity behavior, &lt;code&gt;Document&lt;/code&gt; handles document-specific behavior, and domain-specific classes like &lt;code&gt;Actor&lt;/code&gt; and &lt;code&gt;Location&lt;/code&gt; add their unique attributes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alignment with Clean Architecture:&lt;/strong&gt; This design promotes a clear separation between domain models and other layers, enhancing maintainability and scalability.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Planning for Agents as Future Entities
&lt;/h2&gt;

&lt;p&gt;Although agents are not yet part of the user-facing interface, I'm designing the system so that agents can be treated as entities in the future. By extending Entity, agents can be managed similarly to other entities, allowing for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User Customization: Users could fine-tune agents to suit their needs.&lt;/li&gt;
&lt;li&gt;Unified Management: Consistent handling of entities simplifies the system architecture.&lt;/li&gt;
&lt;li&gt;Future-proofing: Preparing for agents as entities now avoids significant refactoring later.
&lt;em&gt;🤖 Note: In our next post ("Entities Part 2, Agents"), I'll delve deeper into how agents fit into this architecture.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔄 Delving into the Code: Understanding Entity
&lt;/h2&gt;

&lt;p&gt;The Entity class is crucial to the system's architecture. Here's a closer look at its implementation:&lt;/p&gt;

&lt;p&gt;Generics: Using generics () allows Entity to be flexible with the properties (props) it holds.&lt;/p&gt;

&lt;p&gt;Domain Events: Entity includes methods to manage domain events, which are important for maintaining consistency and handling side effects in a decoupled manner.&lt;/p&gt;

&lt;p&gt;Validation: The class includes a validate method to ensure that the properties meet the defined schema.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public addDomainEvent(eventDetails: ICreateDomainEvent): void {
  if (eventDetails.eventSchema) {
    validate(eventDetails.eventSchema, eventDetails.event);
  }

  const event: DomainEvent = {
    source: eventDetails.source,
    eventName: eventDetails.eventName,
    event: eventDetails.event,
    eventVersion: eventDetails.eventVersion,
    eventDateTime: this.getISOString(),
  };

  this._domainEvents.push(event);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🚀 Moving Forward
&lt;/h2&gt;

&lt;p&gt;With the core &lt;code&gt;Document&lt;/code&gt; type and its relationship to &lt;code&gt;Entity&lt;/code&gt; established, some of the steps ahead include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Develop the Agent entity:&lt;/strong&gt; To fulfill the goals of this project, I want semi-to-full automation in the form of Agentic Orchestration. While I could simply develop agentic interactions as a service layer, I'd like to take it a step further and consider Agents as manageable business entities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Review our Bounded Contexts:&lt;/strong&gt; After our two primary entity sets are established, we'll review our decisions how they fit into the architectural strategies we've settled on, what complications there may be, and how to further set the structure of the solution going forward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing Repositories:&lt;/strong&gt; Setting up data access layers to persist and retrieve entities.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;🔍 It might seem like I’m overlooking “User” as an entity, but for now, I’m designing this system for a single user to simplify development and focus on core functionalities before expanding to a multi-user environment. While references to users owning documents or entities may appear, I’ll only revisit this concept later when preparing the UX, expanding to multi-user functionality, and needing to address authorization.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Defining &lt;code&gt;Document&lt;/code&gt; as an extension of &lt;code&gt;Entity&lt;/code&gt; is more than a structural decision—it’s the cornerstone of a system that can grow as needed when more content types are required. This approach balances consistency, ease of expansion, and will be used similarly to have Agents and their component entities also extend &lt;code&gt;Entity&lt;/code&gt;, making it a solid foundation for what’s to come.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Next
&lt;/h3&gt;

&lt;p&gt;In the upcoming "Entities Part 2, Agents," I'll explore how Agents fit into this architecture, what sub entities may be needed based on the technology we'll be leveraging, and a few exciting concepts found in AWS Bedrock and Generally that'll inform those decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Join the Conversation
&lt;/h3&gt;

&lt;p&gt;I’m curious to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do you prioritize which entities are essential when designing a system?&lt;/li&gt;
&lt;li&gt;What role do you envision agents playing in business operations and creative projects?&lt;/li&gt;
&lt;li&gt;Imagine a tool that could enrich content dynamically with the most relevant context—how would it fit into your workflow?&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;"Programs must be written for people to read, and only incidentally for machines to execute." -Harold Abelson and Gerald Jay Sussman&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Helpful References
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Clean Architecture by Robert C. Martin&lt;/strong&gt; - A comprehensive guide on structuring systems for maintainability and scalability.&lt;br&gt;
&lt;strong&gt;Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans&lt;/strong&gt; - An in-depth look at managing complex software projects through domain modeling.&lt;br&gt;
&lt;strong&gt;Implementing Domain-Driven Design by Vaughn Vernon&lt;/strong&gt; - Practical examples and patterns for applying DDD principles.&lt;br&gt;
&lt;strong&gt;&lt;a href="//serverlessadvocate.com"&gt;The Serverless Advocate aka Lee Gilmore&lt;/a&gt;&lt;/strong&gt; -Insights and best practices on serverless architectures and event-driven design, whose own examples are the basis of the base entity orchestration seen here.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>learning</category>
      <category>eventdriven</category>
      <category>architecture</category>
    </item>
    <item>
      <title>My AI Adventure Begins</title>
      <dc:creator>Michael Flanagan</dc:creator>
      <pubDate>Fri, 01 Nov 2024 14:45:35 +0000</pubDate>
      <link>https://dev.to/michael_flanagan_red/my-ai-adventure-begins-4gcm</link>
      <guid>https://dev.to/michael_flanagan_red/my-ai-adventure-begins-4gcm</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Starting an AI Journey
&lt;/h2&gt;

&lt;p&gt;AI is everywhere these days—🤖 LLMs, 🕵️‍♂️ agents, and beyond. I'm adding my own contribution to that 🌊 wave by starting this project blog. On the flip side, this project is an opportunity to embark on a learning journey—exploring how AI can help solve my personal challenges, from managing ✨ creative projects to organizing everyday 📋 information.&lt;/p&gt;

&lt;p&gt;The biggest challenge is figuring out which problems in my life these solutions might address. To that end, I turned to my 🎨 hobbies and discovered a common theme across all of them—something that I could leverage the AI 💥 to help solve.&lt;/p&gt;

&lt;p&gt;Whether it’s recording 📚 learnings from books and blogs, managing and sharing 🍲 recipes, or organizing 📖 narratives and notes for the tabletop games I run with friends, they all share a common need. Each requires a way to submit data with minimal structure, tag it contextually, and easily review, ✏️ edit, and aggregate that data.&lt;/p&gt;

&lt;p&gt;This intersection of ⚙️ technology and everyday creativity is what excites me most. In the coming posts, I’ll explore how 🤖 LLMs and automated agents can help manage and elevate these processes, turning abstract capabilities into practical 🛠️ solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚔️ Challenges in Managing Creative Complexity
&lt;/h2&gt;

&lt;p&gt;Running 🎲 tabletop games is a complex endeavor, especially when managing multiple games across different settings, each with its own set of evolving narratives, affected entities, and ongoing events. There are so many moving parts—characters with rich backstories, interlinked events, places with history—that the potential for losing or misplacing important details is high. Even with a solid ✍️ note-keeping system, it can feel overwhelming, and critical information can easily fall through the cracks.&lt;/p&gt;

&lt;p&gt;This complexity, though challenging, is precisely what excites me and presents a significant opportunity for leveraging 🤖 AI. The more dynamic and intertwined these games get, the more potential there is for automated processes to streamline note-taking, identify 🔗 connections, and keep track of the myriad of details that otherwise could be lost or forgotten. Imagine having an 🤖 AI agent that not only keeps track of every NPC's motivations but also suggests new story twists based on past events. Each time I submit a new event, I get a glimpse into how it might affect planning and play workflows down the road.&lt;/p&gt;

&lt;p&gt;While the primary focus is on narrative 🎲 tabletop games, the approach I'm building should be extensible to almost any agent-driven 🤖 LLM content management platform. Beyond games, I anticipate using this system for managing project and meeting notes, providing structure and context to different types of content, making the platform adaptable for broader use cases.&lt;/p&gt;

&lt;p&gt;And, in a fun twist of going full 🔄 ouroboros, I’ll likely use this very platform to manage the project's own organization as it evolves.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Making the Vision a Reality
&lt;/h2&gt;

&lt;p&gt;The project has several key components that I'll dive into as we move forward. Each of these components plays a crucial role in building a system that can help manage creative and narrative-driven tasks effectively:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;☁️ Serverless Architecture and AWS Services:&lt;/strong&gt; Leveraging AWS for infrastructure and deployment is at the heart of this project. A "serverless first" approach means we can minimize maintenance, easily scale, and tap into the rich ecosystem that AWS offers. This provides the stable, reliable backbone needed for all other components to work effectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🤖 AI-Powered Agents:&lt;/strong&gt; These agents are the core of the project. An AI agent, in this context, is a software program capable of interacting with its environment, collecting data, and using it to perform tasks aimed at achieving specific goals (AWS definition). While these agents hold great promise for managing complex tasks—such as tracking characters, plot twists, and evolving narratives—I remain skeptical about relying on them for key functions until their reliability is fully validated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🐝 Agent Orchestration / Swarms:&lt;/strong&gt; Beyond single agents, orchestration is a powerful concept. By coordinating multiple agents working towards a common goal, we can tackle larger, more dynamic problems in a distributed way. This approach is like having a "swarm" of helpers, each specializing in a different aspect of the narrative or data management, making the system more resilient and effective.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ Tool Use / Function Calling Framework:&lt;/strong&gt; Agents should not just provide information; they need to act meaningfully within the system. This means being able to call external tools, invoke APIs, and interact with various parts of the platform to achieve their goals. This function-calling framework will enhance the practical utility of 🤖 AI agents by allowing them to be proactive contributors, not just passive assistants.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗️ Laying the Foundation
&lt;/h2&gt;

&lt;p&gt;To get things moving, I'm starting by laying the groundwork—defining the entities and their basic actions. These entities will be the core building blocks, each with its own purpose and properties, and establishing those will give me a foundation to build on. The initial focus will also be on getting basic entity actions in place, creating the essential CRUD operations that will let me interact with and manipulate these entities in meaningful ways.&lt;/p&gt;

&lt;p&gt;Initially, I'll be working with agents sequentially. This means one action at a time—no complex handoffs, no many-to-many agent relationships, and no intricate graph-like dependencies. I want to understand the flow deeply before trying to orchestrate more complex behaviors. There's something valuable about that simplicity: it forces you to consider every step, every action, and how one thing leads into the next.&lt;/p&gt;

&lt;p&gt;It's worth mentioning that there are already frameworks designed to make this kind of orchestration much easier. &lt;a href="https://www.langchain.com/langchain" rel="noopener noreferrer"&gt;Langchain&lt;/a&gt; and &lt;a href="https://www.langchain.com/langgraph" rel="noopener noreferrer"&gt;Langgraph&lt;/a&gt; come to mind, both of which are fantastic for streamlining agent interactions and orchestration. Recently, I also came across an educational framework from OpenAI around swarm orchestration that was a big inspiration for kicking off this project (&lt;a href="https://github.com/openai/swarm" rel="noopener noreferrer"&gt;OpenAI Swarm&lt;/a&gt;). But, to be honest, I want to be in the weeds. I want to feel the mistakes and learn from them firsthand. With 🤖 AI tooling becoming more commonplace, I think the "under the hood" knowledge might become harder to acquire if we always rely on ready-made solutions. So, I’m diving in headfirst, hoping that my path will be full of lessons—mistakes and all—that will make this journey interesting and engaging.&lt;/p&gt;

&lt;h2&gt;
  
  
  📅 What to Expect Moving Forward
&lt;/h2&gt;

&lt;p&gt;In the upcoming posts, I'll dive deeper into specific components of the project, explore the challenges I encounter, and share the lessons I learn along the way. This series is going to be an evolving journey, and I’d love for you to follow along as things progress. Feel free to comment with your own experiences or share your thoughts on how these ideas might apply to your projects. I want to invite you to be part of this exploration—engage, provide feedback, and share your thoughts. Let's make this an engaging, shared experience!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The world reveals itself to those who travel by foot" - Werner Herzog&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>aws</category>
      <category>ai</category>
      <category>typescript</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
