diff --git a/04-Middleware/03-LangGraph-Context-Engineering.ipynb b/04-Middleware/03-LangGraph-Context-Engineering.ipynb index e167786..c1a9fdf 100644 --- a/04-Middleware/03-LangGraph-Context-Engineering.ipynb +++ b/04-Middleware/03-LangGraph-Context-Engineering.ipynb @@ -3,12 +3,31 @@ { "cell_type": "markdown", "metadata": {}, - "source": "# 컨텍스트 엔지니어링(Context Engineering)\n\n에이전트를 구축하는 데 있어 가장 어려운 부분은 충분히 신뢰할 수 있게 만드는 것입니다. MVP 단계에서 잘 동작하는 에이전트도 실제 환경에서는 종종 실패하기도 합니다. 이 튜토리얼에서는 에이전트의 신뢰성을 높이는 핵심 기술인 컨텍스트 엔지니어링에 대해 학습합니다.\n\n## 에이전트가 실패하는 이유\n\n에이전트가 실패할 때는 일반적으로 에이전트 내부의 LLM 호출이 잘못된 작업을 수행하거나 예상대로 작동하지 않았기 때문입니다. LLM은 다음 두 가지 이유 중 하나로 실패합니다:\n\n1. 기본 LLM이 충분히 능력이 없음\n2. **\"올바른\" 컨텍스트**가 LLM에 전달되지 않음\n\n대부분의 경우 실제로는 두 번째 이유가 에이전트의 신뢰성을 떨어뜨립니다. **컨텍스트 엔지니어링**은 LLM이 작업을 완수할 수 있도록 올바른 형식으로 올바른 정보와 도구를 제공하는 것입니다. 이것이 AI 엔지니어의 가장 중요한 업무입니다." + "source": [ + "# 컨텍스트 엔지니어링(Context Engineering)\n", + "\n", + "에이전트를 구축하는 데 있어 가장 어려운 부분은 충분히 신뢰할 수 있게 만드는 것입니다. MVP 단계에서 잘 동작하는 에이전트도 실제 환경에서는 종종 실패하기도 합니다. 이 튜토리얼에서는 에이전트의 신뢰성을 높이는 핵심 기술인 컨텍스트 엔지니어링에 대해 학습합니다.\n", + "\n", + "## 에이전트가 실패하는 이유\n", + "\n", + "에이전트가 실패할 때는 일반적으로 에이전트 내부의 LLM 호출이 잘못된 작업을 수행하거나 예상대로 작동하지 않았기 때문입니다. LLM은 다음 두 가지 이유 중 하나로 실패합니다:\n", + "\n", + "1. 기본 LLM이 충분히 능력이 없음\n", + "2. **\"올바른\" 컨텍스트**가 LLM에 전달되지 않음\n", + "\n", + "대부분의 경우 실제로는 두 번째 이유가 에이전트의 신뢰성을 떨어뜨립니다. **컨텍스트 엔지니어링**은 LLM이 작업을 완수할 수 있도록 올바른 형식으로 올바른 정보와 도구를 제공하는 것입니다. 이것이 AI 엔지니어의 가장 중요한 업무입니다." + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "## 사전 준비\n\n컨텍스트 엔지니어링 기법을 실습하기 위해 환경 변수와 LangSmith 추적을 설정합니다. 환경 변수에는 LLM 서비스 인증 정보가 포함되며, LangSmith를 통해 에이전트의 컨텍스트 흐름을 상세히 모니터링할 수 있습니다.\n\n아래 코드는 `.env` 파일에서 환경 변수를 로드하고, LangSmith 추적을 활성화합니다." + "source": [ + "## 사전 준비\n", + "\n", + "컨텍스트 엔지니어링 기법을 실습하기 위해 환경 변수와 LangSmith 추적을 설정합니다. 환경 변수에는 LLM 서비스 인증 정보가 포함되며, LangSmith를 통해 에이전트의 컨텍스트 흐름을 상세히 모니터링할 수 있습니다.\n", + "\n", + "아래 코드는 `.env` 파일에서 환경 변수를 로드하고, LangSmith 추적을 활성화합니다." + ] }, { "cell_type": "code", @@ -56,27 +75,84 @@ { "cell_type": "markdown", "metadata": {}, - "source": "## 컨텍스트의 종류\n\n에이전트는 세 가지 종류의 컨텍스트를 제어합니다. 각 컨텍스트 타입은 서로 다른 범위와 지속성을 가지며, 에이전트의 동작을 세밀하게 조정하는 데 사용됩니다.\n\n| 컨텍스트 타입 | 제어 대상 | 지속성 |\n|------------|---------|-------|\n| **Model Context** | 모델 호출에 들어가는 내용 (지시사항, 메시지 기록, 도구, 응답 형식) | Transient |\n| **Tool Context** | 도구가 액세스하고 생성하는 내용 (상태, 저장소, 런타임 컨텍스트에 읽기/쓰기) | Persistent |\n| **Life-cycle Context** | 모델 및 도구 호출 사이에 발생하는 작업 (요약, 가드레일, 로깅 등) | Persistent |\n\n**Transient Context**: LLM이 단일 호출에서 보는 내용입니다. 상태에 저장된 내용을 변경하지 않고 메시지, 도구 또는 프롬프트를 수정할 수 있습니다.\n\n**Persistent Context**: 여러 턴에 걸쳐 상태에 저장되는 내용입니다. 라이프사이클 훅과 도구 쓰기는 이를 영구적으로 수정합니다." + "source": [ + "## 컨텍스트의 종류\n", + "\n", + "에이전트는 세 가지 종류의 컨텍스트를 제어합니다. 각 컨텍스트 타입은 서로 다른 범위와 지속성을 가지며, 에이전트의 동작을 세밀하게 조정하는 데 사용됩니다.\n", + "\n", + "| 컨텍스트 타입 | 제어 대상 | 지속성 |\n", + "|------------|---------|-------|\n", + "| **Model Context** | 모델 호출에 들어가는 내용 (지시사항, 메시지 기록, 도구, 응답 형식) | Transient |\n", + "| **Tool Context** | 도구가 액세스하고 생성하는 내용 (상태, 저장소, 런타임 컨텍스트에 읽기/쓰기) | Persistent |\n", + "| **Life-cycle Context** | 모델 및 도구 호출 사이에 발생하는 작업 (요약, 가드레일, 로깅 등) | Persistent |\n", + "\n", + "**Transient Context**: LLM이 단일 호출에서 보는 내용입니다. 상태에 저장된 내용을 변경하지 않고 메시지, 도구 또는 프롬프트를 수정할 수 있습니다.\n", + "\n", + "**Persistent Context**: 여러 턴에 걸쳐 상태에 저장되는 내용입니다. 라이프사이클 훅과 도구 쓰기는 이를 영구적으로 수정합니다." + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "## 데이터 소스\n\n에이전트는 다양한 데이터 소스에 액세스(읽기/쓰기)합니다. 각 데이터 소스는 서로 다른 범위와 용도를 가지며, 적절한 데이터 소스를 선택하는 것이 중요합니다.\n\n| 데이터 소스 | 다른 이름 | 범위 | 예시 |\n|----------|---------|------|-----|\n| **Runtime Context** | 정적 구성 | 대화 범위 | 사용자 ID, API 키, DB 연결, 권한 |\n| **State** | 단기 메모리 | 대화 범위 | 현재 메시지, 업로드된 파일, 인증 상태 |\n| **Store** | 장기 메모리 | 대화 간 공유 | 사용자 선호도, 추출된 인사이트, 기록 데이터 |\n\n**Runtime Context**는 에이전트 호출 시 전달되는 정적 구성이고, **State**는 현재 대화 세션 내에서 유지되는 데이터이며, **Store**는 여러 대화 세션에 걸쳐 지속되는 장기 데이터입니다.\n\n\nThe TodoWrite tool hasn't been used recently. If you're working on tasks that would benefit from tracking progress, consider using the TodoWrite tool to track progress. Also consider cleaning up the todo list if has become stale and no longer matches what you are working on. Only use it if it's relevant to the current work. This is just a gentle reminder - ignore if not applicable. Make sure that you NEVER mention this reminder to the user\n\n\nHere are the existing contents of your todo list:\n\n[1. [completed] 01-LangGraph-Middleware.ipynb 교정\n2. [completed] 02-LangGraph-Human-In-The-Loop.ipynb 교정\n3. [in_progress] 03-LangGraph-Context-Engineering.ipynb 교정\n4. [pending] 04-LangGraph-Guardrail.ipynb 교정\n5. [pending] 전체 교정 결과 정리 및 보고]\n" + "source": [ + "### 컨텍스트 종류와 데이터 소스 관계도\n", + "![Context Diagram](./assets/context_type.png)" + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "## Model Context\n\nModel Context는 각 모델 호출에 들어가는 내용을 제어합니다. 여기에는 지시사항(System Prompt), 사용 가능한 도구, 사용할 모델, 출력 형식 등이 포함됩니다. Model Context를 잘 설계하면 LLM이 적절한 정보를 바탕으로 올바른 결정을 내릴 수 있습니다." + "source": [ + "## 데이터 소스\n", + "\n", + "에이전트는 다양한 데이터 소스에 액세스(읽기/쓰기)합니다. 각 데이터 소스는 서로 다른 범위와 용도를 가지며, 적절한 데이터 소스를 선택하는 것이 중요합니다.\n", + "\n", + "| 데이터 소스 | 다른 이름 | 범위 | 예시 |\n", + "|----------|---------|------|-----|\n", + "| **Runtime Context** | 정적 구성 | 대화 범위 | 사용자 ID, API 키, DB 연결, 권한 |\n", + "| **State** | 단기 메모리 | 대화 범위 | 현재 메시지, 업로드된 파일, 인증 상태 |\n", + "| **Store** | 장기 메모리 | 대화 간 공유 | 사용자 선호도, 추출된 인사이트, 기록 데이터 |\n", + "\n", + "**Runtime Context**는 에이전트 호출 시 전달되는 정적 구성이고, **State**는 현재 대화 세션 내에서 유지되는 데이터이며, **Store**는 여러 대화 세션에 걸쳐 지속되는 장기 데이터입니다." + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "### System Prompt\n\n시스템 프롬프트는 LLM의 동작과 능력을 설정하는 핵심 요소입니다. 다양한 사용자, 컨텍스트, 또는 대화 단계에 따라 다른 지시사항이 필요할 수 있습니다. `@dynamic_prompt` 데코레이터를 사용하면 런타임에 시스템 프롬프트를 동적으로 생성할 수 있습니다." + "source": [ + "### Model Context 구성 요소 흐름도\n", + "\n", + "![Model Context](./assets/model_context.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Model Context\n", + "\n", + "Model Context는 각 모델 호출에 들어가는 내용을 제어합니다. 여기에는 지시사항(System Prompt), 사용 가능한 도구, 사용할 모델, 출력 형식 등이 포함됩니다. Model Context를 잘 설계하면 LLM이 적절한 정보를 바탕으로 올바른 결정을 내릴 수 있습니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### System Prompt\n", + "\n", + "시스템 프롬프트는 LLM의 동작과 능력을 설정하는 핵심 요소입니다. 다양한 사용자, 컨텍스트, 또는 대화 단계에 따라 다른 지시사항이 필요할 수 있습니다. `@dynamic_prompt` 데코레이터를 사용하면 런타임에 시스템 프롬프트를 동적으로 생성할 수 있습니다." + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "### State 기반 System Prompt\n\n대화 State에 따라 시스템 프롬프트를 동적으로 조정할 수 있습니다. 예를 들어, 대화가 길어지면 더 간결하게 응답하도록 지시하거나, 특정 상태에 따라 다른 동작을 수행하도록 설정할 수 있습니다.\n\n아래 코드는 메시지 수에 따라 시스템 프롬프트를 조정하는 `@dynamic_prompt` 미들웨어를 구현합니다." + "source": [ + "### State 기반 System Prompt\n", + "\n", + "대화 State에 따라 시스템 프롬프트를 동적으로 조정할 수 있습니다. 예를 들어, 대화가 길어지면 더 간결하게 응답하도록 지시하거나, 특정 상태에 따라 다른 동작을 수행하도록 설정할 수 있습니다.\n", + "\n", + "아래 코드는 메시지 수에 따라 시스템 프롬프트를 조정하는 `@dynamic_prompt` 미들웨어를 구현합니다." + ] }, { "cell_type": "code", @@ -130,7 +206,13 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Store 기반 System Prompt\n\nStore는 여러 대화 세션에 걸쳐 지속되는 장기 데이터를 저장합니다. 사용자 선호도, 커뮤니케이션 스타일 등을 Store에 저장하고 시스템 프롬프트에 반영하면 개인화된 경험을 제공할 수 있습니다.\n\n아래 코드는 Store에서 사용자 선호도를 읽어 시스템 프롬프트에 반영하는 예제입니다. 동일한 질문에 대해 사용자별로 다른 스타일의 응답을 제공합니다." + "source": [ + "### Store 기반 System Prompt\n", + "\n", + "Store는 여러 대화 세션에 걸쳐 지속되는 장기 데이터를 저장합니다. 사용자 선호도, 커뮤니케이션 스타일 등을 Store에 저장하고 시스템 프롬프트에 반영하면 개인화된 경험을 제공할 수 있습니다.\n", + "\n", + "아래 코드는 Store에서 사용자 선호도를 읽어 시스템 프롬프트에 반영하는 예제입니다. 동일한 질문에 대해 사용자별로 다른 스타일의 응답을 제공합니다." + ] }, { "cell_type": "code", @@ -203,11 +285,12 @@ "==================================================\n", "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", "- - - - - - - - - - - - - - - - - - - - - - - - - \n", - "- 🤖 머신러닝은 데이터에서 패턴을 찾아 스스로 학습하는 기술\n", - "- 📊 많은 데이터를 입력받아 모델을 훈련\n", - "- 🔄 모델이 예측하거나 분류할 때, 결과와 실제를 비교해 오차를 줄이도록 조정\n", - "- 🛠 주요 과정: 데이터 수집 → 전처리 → 모델 학습 → 평가 → 적용\n", - "- 🌟 반복적으로 학습하며 정확도를 높임" + "- 머신러닝은 데이터에서 패턴을 학습하는 기술 📊\n", + "- 입력 데이터와 정답을 바탕으로 모델을 훈련시킴 🏋️‍♂️\n", + "- 학습된 모델은 새로운 데이터에 대해 예측하거나 분류 수행 🔮\n", + "- 대표적인 과정: 데이터 수집 → 전처리 → 모델 선택 → 학습 → 평가 → 예측\n", + "- 주요 알고리즘: 지도학습, 비지도학습, 강화학습 등 🤖\n", + "- 핵심은 경험으로부터 자동으로 성능 개선하는 것! 🚀" ] } ], @@ -235,7 +318,7 @@ "==================================================\n", "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", "- - - - - - - - - - - - - - - - - - - - - - - - - \n", - "머신러닝은 주어진 데이터로부터 패턴이나 규칙을 학습하여 미래의 데이터에 대해 예측하거나 결정을 내리는 기술입니다. 기본적으로 데이터를 입력받아 모델을 학습시키고, 학습된 모델은 새로운 입력에 대해 결과를 예측합니다. 이 과정에서 지도학습, 비지도학습, 강화학습 등 다양한 학습 방법이 활용됩니다." + "머신러닝은 데이터를 기반으로 알고리즘이 패턴을 학습하여 예측이나 결정을 내리는 기술입니다. 주로 입력 데이터와 정답을 이용해 모델을 훈련시키고, 훈련된 모델이 새로운 입력에 대해 결과를 예측합니다. 이를 통해 복잡한 문제를 해결하거나 자동화된 의사결정을 가능하게 합니다." ] } ], @@ -253,7 +336,13 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Runtime Context 기반 System Prompt\n\nRuntime Context는 에이전트 호출 시 전달되는 정적 구성입니다. 사용자 역할, 배포 환경 등 호출 시점에 결정되는 정보를 기반으로 시스템 프롬프트를 조정할 수 있습니다.\n\n아래 코드는 사용자 역할(`admin`/`viewer`)과 배포 환경(`production`)에 따라 시스템 프롬프트를 조정하는 예제입니다." + "source": [ + "### Runtime Context 기반 System Prompt\n", + "\n", + "Runtime Context는 에이전트 호출 시 전달되는 정적 구성입니다. 사용자 역할, 배포 환경 등 호출 시점에 결정되는 정보를 기반으로 시스템 프롬프트를 조정할 수 있습니다.\n", + "\n", + "아래 코드는 사용자 역할(`admin`/`viewer`)과 배포 환경(`production`)에 따라 시스템 프롬프트를 조정하는 예제입니다." + ] }, { "cell_type": "code", @@ -308,7 +397,7 @@ "==================================================\n", "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", "- - - - - - - - - - - - - - - - - - - - - - - - - \n", - "네, 데이터 추가가 가능합니다. 어떤 데이터를 추가하고 싶으신지 구체적으로 알려주시면 도와드리겠습니다." + "네, 데이터 추가가 가능합니다. 어떤 종류의 데이터를 추가하고 싶으신지, 그리고 구체적으로 어떤 내용을 추가하고 싶은지 알려주시면 도와드리겠습니다." ] } ], @@ -335,7 +424,7 @@ "==================================================\n", "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", "- - - - - - - - - - - - - - - - - - - - - - - - - \n", - "저는 현재 읽기 작업만 지원하고 있어 데이터를 추가하거나 수정하는 작업은 할 수 없습니다. 읽기와 관련된 질문이나 정보 조회에 대해 도움을 드릴 수 있습니다. 필요한 정보가 있으시면 말씀해 주세요." + "저는 읽기 전용 모드로 작동하며, 데이터 추가나 수정 등의 작업은 지원하지 않습니다. 필요한 정보를 검색하거나 안내해드릴 수 있으니 궁금한 점이 있으면 말씀해 주세요." ] } ], @@ -351,18 +440,36 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Messages\n\n메시지는 LLM에 전송되는 프롬프트를 구성합니다. LLM이 올바른 정보를 가지고 잘 응답할 수 있도록 메시지 내용을 관리하는 것이 중요합니다. `@wrap_model_call` 데코레이터를 사용하면 모델에 전달되는 메시지를 동적으로 수정할 수 있습니다." + "source": [ + "### Messages\n", + "\n", + "메시지는 LLM에 전송되는 프롬프트를 구성합니다. LLM이 올바른 정보를 가지고 잘 응답할 수 있도록 메시지 내용을 관리하는 것이 중요합니다. `@wrap_model_call` 데코레이터를 사용하면 모델에 전달되는 메시지를 동적으로 수정할 수 있습니다." + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "### State에서 파일 컨텍스트 주입\n\n사용자가 업로드한 파일이나 첨부 자료가 있을 때, 이 정보를 메시지에 자동으로 추가하여 LLM이 참조할 수 있도록 할 수 있습니다. `@wrap_model_call` 데코레이터를 사용하여 State에 저장된 파일 메타데이터를 읽고 컨텍스트로 주입합니다.\n\n아래 코드는 State의 `uploaded_files` 필드에서 파일 정보를 읽어 모델 요청에 추가하는 예제입니다." + "source": [ + "### State에서 파일 컨텍스트 주입\n", + "\n", + "사용자가 업로드한 파일이나 첨부 자료가 있을 때, 이 정보를 메시지에 자동으로 추가하여 LLM이 참조할 수 있도록 할 수 있습니다. `@wrap_model_call` 데코레이터를 사용하여 State에 저장된 파일 메타데이터를 읽고 컨텍스트로 주입합니다.\n", + "\n", + "아래 코드는 State의 `uploaded_files` 필드에서 파일 정보를 읽어 모델 요청에 추가하는 예제입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I don't have access to your files. If you'd like, you can tell me about the files you have or upload them, and I can help you with them.\n" + ] + } + ], "source": [ "from langchain.agents.middleware import wrap_model_call, ModelResponse\n", "from typing import Callable\n", @@ -418,18 +525,45 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Tools\n\n도구를 통해 모델이 데이터베이스, API, 외부 시스템과 상호 작용할 수 있습니다. 도구를 정의하고 선택하는 방법은 모델이 작업을 효과적으로 완료할 수 있는지에 직접적인 영향을 미칩니다. 좋은 도구 정의는 모델의 추론을 안내하고, 올바른 도구를 올바른 시점에 사용하도록 돕습니다." + "source": [ + "### 동적 프롬프트 미들웨어 흐름도\n", + "\n", + "![Dynamic Prompt](./assets/dynamic_prompt.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Tools\n", + "\n", + "도구를 통해 모델이 데이터베이스, API, 외부 시스템과 상호 작용할 수 있습니다. 도구를 정의하고 선택하는 방법은 모델이 작업을 효과적으로 완료할 수 있는지에 직접적인 영향을 미칩니다. 좋은 도구 정의는 모델의 추론을 안내하고, 올바른 도구를 올바른 시점에 사용하도록 돕습니다." + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "### 도구 정의\n\n각 도구에는 명확한 이름, 설명, 인수 이름 및 인수 설명이 필요합니다. 이것들은 단순한 메타데이터가 아니라 모델이 도구를 언제 어떻게 사용할지에 대한 추론을 안내합니다. `parse_docstring=True` 옵션을 사용하면 docstring에서 인수 설명을 자동으로 추출할 수 있습니다.\n\n아래 코드는 명확한 설명과 인수 정의를 가진 도구를 생성하는 예제입니다." + "source": [ + "### 도구 정의\n", + "\n", + "각 도구에는 명확한 이름, 설명, 인수 이름 및 인수 설명이 필요합니다. 이것들은 단순한 메타데이터가 아니라 모델이 도구를 언제 어떻게 사용할지에 대한 추론을 안내합니다. `parse_docstring=True` 옵션을 사용하면 docstring에서 인수 설명을 자동으로 추출할 수 있습니다.\n", + "\n", + "아래 코드는 명확한 설명과 인수 정의를 가진 도구를 생성하는 예제입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "You currently have no pending orders. If you need help with anything else, feel free to ask!\n" + ] + } + ], "source": [ "from langchain.tools import tool\n", "\n", @@ -465,13 +599,38 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### State 기반 도구 선택\n\n대화 단계나 상태에 따라 사용 가능한 도구를 동적으로 조정할 수 있습니다. 예를 들어, 인증되지 않은 사용자에게는 공개 도구만 제공하고, 인증된 사용자에게는 더 많은 도구를 제공할 수 있습니다. 이를 통해 보안과 사용자 경험을 동시에 관리할 수 있습니다.\n\n아래 코드는 인증 상태와 대화 길이에 따라 도구를 필터링하는 예제입니다." + "source": [ + "### 도구 필터링 흐름도\n", + "\n", + "![Tool Filtering](./assets/tool_filtering.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### State 기반 도구 선택\n", + "\n", + "대화 단계나 상태에 따라 사용 가능한 도구를 동적으로 조정할 수 있습니다. 예를 들어, 인증되지 않은 사용자에게는 공개 도구만 제공하고, 인증된 사용자에게는 더 많은 도구를 제공할 수 있습니다. 이를 통해 보안과 사용자 경험을 동시에 관리할 수 있습니다.\n", + "\n", + "아래 코드는 인증 상태와 대화 길이에 따라 도구를 필터링하는 예제입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Unauthenticated: I found results for Python tutorials. Do you want tutorials for beginners, intermediate, or advanced level? Or are you looking for tutorials on a specific Python topic or library?\n", + "\n", + "Authenticated: I found several Python tutorials for you. Do you have a specific topic or level in mind, such as beginner, intermediate, or advanced Python? Or are you looking for tutorials on a particular aspect like data science, web development, automation, or something else?\n" + ] + } + ], "source": [ "from langchain.tools import tool\n", "\n", @@ -543,11 +702,17 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Runtime Context 기반 도구 선택\n\nRuntime Context에 전달된 사용자 권한에 따라 도구를 필터링할 수 있습니다. 관리자는 모든 도구를, 편집자는 삭제 도구를 제외한 도구를, 뷰어는 읽기 도구만 사용할 수 있도록 설정하면 역할 기반 접근 제어(RBAC)를 구현할 수 있습니다.\n\n아래 코드는 사용자 역할에 따라 도구 접근을 제한하는 예제입니다." + "source": [ + "### Runtime Context 기반 도구 선택\n", + "\n", + "Runtime Context에 전달된 사용자 권한에 따라 도구를 필터링할 수 있습니다. 관리자는 모든 도구를, 편집자는 삭제 도구를 제외한 도구를, 뷰어는 읽기 도구만 사용할 수 있도록 설정하면 역할 기반 접근 제어(RBAC)를 구현할 수 있습니다.\n", + "\n", + "아래 코드는 사용자 역할에 따라 도구 접근을 제한하는 예제입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -607,9 +772,29 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mtools\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "User 테이블에서 데이터를 읽었습니다.\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "User 테이블의 데이터를 조회하였습니다. 추가로 필요한 작업이 있으면 말씀해 주세요." + ] + } + ], "source": [ "# 뷰어\n", "stream_graph(\n", @@ -621,9 +806,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "죄송하지만, 현재는 데이터 삭제 작업에 대한 권한이 없습니다. 다른 도움이 필요하시면 말씀해 주세요." + ] + } + ], "source": [ "# 뷰어\n", "stream_graph(\n", @@ -637,9 +834,29 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mtools\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "User 테이블에서 데이터를 삭제했습니다.\n", + "==================================================\n", + "🔄 Node: \u001b[1;36mmodel\u001b[0m 🔄\n", + "- - - - - - - - - - - - - - - - - - - - - - - - - \n", + "User 테이블에서 abc 레코드를 삭제했습니다." + ] + } + ], "source": [ "# 관리자\n", "stream_graph(\n", @@ -654,13 +871,28 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Model\n\n다양한 모델은 각기 다른 강점, 비용, 컨텍스트 창 크기를 가지고 있습니다. 작업의 복잡성, 대화 길이, 비용 요구사항에 따라 적합한 모델을 동적으로 선택할 수 있습니다. `@wrap_model_call` 데코레이터를 사용하면 런타임에 모델을 변경할 수 있습니다.\n\n아래 코드는 대화 길이에 따라 효율적인 모델과 큰 모델을 동적으로 선택하는 예제입니다." + "source": [ + "### Model\n", + "\n", + "다양한 모델은 각기 다른 강점, 비용, 컨텍스트 창 크기를 가지고 있습니다. 작업의 복잡성, 대화 길이, 비용 요구사항에 따라 적합한 모델을 동적으로 선택할 수 있습니다. `@wrap_model_call` 데코레이터를 사용하면 런타임에 모델을 변경할 수 있습니다.\n", + "\n", + "아래 코드는 대화 길이에 따라 효율적인 모델과 큰 모델을 동적으로 선택하는 예제입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Using efficient model for 1 messages\n", + "Hello! How can I assist you today?\n" + ] + } + ], "source": [ "from langchain.chat_models import init_chat_model\n", "\n", @@ -701,13 +933,27 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Response Format\n\n구조화된 출력은 비구조화된 텍스트를 검증된 구조화 데이터로 변환합니다. 특정 필드를 추출하거나 다운스트림 시스템을 위한 데이터를 반환할 때 자유 형식 텍스트로는 충분하지 않습니다. Pydantic 모델을 사용하여 출력 스키마를 정의하면 모델이 해당 형식으로 응답하도록 강제할 수 있습니다.\n\n아래 코드는 고객 지원 티켓 정보를 구조화된 형식으로 추출하는 예제입니다." + "source": [ + "### Response Format\n", + "\n", + "구조화된 출력은 비구조화된 텍스트를 검증된 구조화 데이터로 변환합니다. 특정 필드를 추출하거나 다운스트림 시스템을 위한 데이터를 반환할 때 자유 형식 텍스트로는 충분하지 않습니다. Pydantic 모델을 사용하여 출력 스키마를 정의하면 모델이 해당 형식으로 응답하도록 강제할 수 있습니다.\n", + "\n", + "아래 코드는 고객 지원 티켓 정보를 구조화된 형식으로 추출하는 예제입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ticket: {\"summary\":\"Unable to login to account due to invalid credentials error.\",\"category\":\"account\",\"priority\":\"high\",\"customer_sentiment\":\"frustrated\"}\n" + ] + } + ], "source": [ "from pydantic import BaseModel, Field\n", "\n", @@ -749,13 +995,27 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### State 기반 Response Format 선택\n\n대화 상태에 따라 다른 출력 형식을 적용할 수 있습니다. 초기 대화에서는 간단한 형식을, 대화가 진행되면서 더 상세한 형식을 사용하면 상황에 맞는 응답을 제공할 수 있습니다.\n\n아래 코드는 메시지 수에 따라 간단한 응답 형식과 상세한 응답 형식을 동적으로 선택하는 예제입니다." + "source": [ + "### State 기반 Response Format 선택\n", + "\n", + "대화 상태에 따라 다른 출력 형식을 적용할 수 있습니다. 초기 대화에서는 간단한 형식을, 대화가 진행되면서 더 상세한 형식을 사용하면 상황에 맞는 응답을 제공할 수 있습니다.\n", + "\n", + "아래 코드는 메시지 수에 따라 간단한 응답 형식과 상세한 응답 형식을 동적으로 선택하는 예제입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Simple response: Python is a high-level, interpreted programming language known for its simplicity and readability. It was created by Guido van Rossum and first released in 1991. Python supports multiple programming paradigms, including procedural, object-oriented, and functional programming. It is widely used for web development, data analysis, artificial intelligence, scientific computing, automation, and more. Python has a vast standard library and a large ecosystem of third-party packages, making it a versatile choice for both beginners and experienced developers.\n" + ] + } + ], "source": [ "class SimpleResponse(BaseModel):\n", " \"\"\"초기 대화를 위한 간단한 응답\"\"\"\n", @@ -798,18 +1058,45 @@ { "cell_type": "markdown", "metadata": {}, - "source": "## Tool Context\n\n도구는 컨텍스트를 읽고 쓰는 두 가지 작업을 모두 수행합니다. `ToolRuntime` 객체를 통해 State, Store, Runtime Context에 접근할 수 있으며, `Command` 객체를 반환하여 State를 업데이트할 수 있습니다. 이를 통해 도구가 단순한 함수 호출 이상의 역할을 수행할 수 있습니다." + "source": [ + "### Tool Context 읽기/쓰기 다이어그램\n", + "\n", + "![Tool Context](./assets/tool_context.png)" + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "### Reads - State에서 읽기\n\n도구 함수에 `runtime: ToolRuntime` 매개변수를 추가하면 현재 State에 접근할 수 있습니다. 인증 상태, 세션 정보 등 State에 저장된 데이터를 읽어 도구의 동작을 결정할 수 있습니다.\n\n아래 코드는 State에서 인증 상태를 확인하는 도구를 구현합니다." + "source": [ + "## Tool Context\n", + "\n", + "도구는 컨텍스트를 읽고 쓰는 두 가지 작업을 모두 수행합니다. `ToolRuntime` 객체를 통해 State, Store, Runtime Context에 접근할 수 있으며, `Command` 객체를 반환하여 State를 업데이트할 수 있습니다. 이를 통해 도구가 단순한 함수 호출 이상의 역할을 수행할 수 있습니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Reads - State에서 읽기\n", + "\n", + "도구 함수에 `runtime: ToolRuntime` 매개변수를 추가하면 현재 State에 접근할 수 있습니다. 인증 상태, 세션 정보 등 State에 저장된 데이터를 읽어 도구의 동작을 결정할 수 있습니다.\n", + "\n", + "아래 코드는 State에서 인증 상태를 확인하는 도구를 구현합니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "You are not authenticated. If you'd like, I can help you with steps to authenticate or assist you with something else.\n" + ] + } + ], "source": [ "from langchain.tools import tool, ToolRuntime\n", "\n", @@ -842,13 +1129,27 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Reads - Store에서 읽기\n\nStore는 여러 대화 세션에 걸쳐 지속되는 장기 데이터를 저장합니다. `runtime.store.get()` 메서드를 사용하여 Store에서 데이터를 읽을 수 있습니다. `ToolRuntime[Context]` 타입 힌트를 사용하면 Runtime Context 타입도 함께 지정할 수 있습니다.\n\n아래 코드는 Store에서 사용자 선호도를 읽어 반환하는 도구를 구현합니다." + "source": [ + "### Reads - Store에서 읽기\n", + "\n", + "Store는 여러 대화 세션에 걸쳐 지속되는 장기 데이터를 저장합니다. `runtime.store.get()` 메서드를 사용하여 Store에서 데이터를 읽을 수 있습니다. `ToolRuntime[Context]` 타입 힌트를 사용하면 Runtime Context 타입도 함께 지정할 수 있습니다.\n", + "\n", + "아래 코드는 Store에서 사용자 선호도를 읽어 반환하는 도구를 구현합니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Your theme preference is set to dark.\n" + ] + } + ], "source": [ "@dataclass\n", "class Context:\n", @@ -893,26 +1194,76 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Writes - State에 쓰기\n\n도구에서 `Command(update={...})`를 반환하면 State를 업데이트할 수 있습니다. 인증 상태 변경, 세션 데이터 저장 등 도구 실행 결과를 State에 기록하여 후속 작업에서 참조할 수 있습니다.\n\n아래 코드는 비밀번호를 확인하고 인증 상태를 State에 기록하는 도구를 구현합니다." + "source": [ + "### Writes - State에 쓰기\n", + "\n", + "도구에서 `Command(update={...})`를 반환하면 State를 업데이트할 수 있습니다. 인증 상태 변경, 세션 데이터 저장 등 도구 실행 결과를 State에 기록하여 후속 작업에서 참조할 수 있습니다.\n", + "\n", + "아래 코드는 비밀번호를 확인하고 인증 상태를 State에 기록하는 도구를 구현합니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "I have attempted to authenticate you with the password 'correct', and the authentication was successful. However, the check on your authentication status indicates that you are not currently authenticated. Would you like me to try authenticating you again or assist you further?\n", + "Authenticated in state: False\n" + ] + } + ], "source": [ "from langgraph.types import Command\n", + "from langchain_core.messages import ToolMessage\n", "\n", "\n", "@tool\n", - "def authenticate_user(password: str, runtime: ToolRuntime) -> Command:\n", + "def authenticate_user(\n", + " password: str,\n", + " runtime: ToolRuntime,\n", + ") -> Command:\n", " \"\"\"Authenticate user and update State.\"\"\"\n", + " # State의 마지막 AIMessage에서 tool_call_id 추출\n", + " messages = runtime.state.get(\"messages\", [])\n", + " tool_call_id = None\n", + " for msg in reversed(messages):\n", + " if hasattr(msg, \"tool_calls\") and msg.tool_calls:\n", + " for tc in msg.tool_calls:\n", + " if tc.get(\"name\") == \"authenticate_user\":\n", + " tool_call_id = tc.get(\"id\")\n", + " break\n", + " if tool_call_id:\n", + " break\n", + "\n", " # 인증 수행 (단순화됨)\n", " if password == \"correct\":\n", - " # Command를 사용하여 State에 인증 상태 기록\n", - " return Command(update={\"authenticated\": True})\n", + " return Command(\n", + " update={\n", + " \"authenticated\": True,\n", + " \"messages\": [\n", + " ToolMessage(\n", + " content=\"Authentication successful\",\n", + " tool_call_id=tool_call_id,\n", + " )\n", + " ],\n", + " }\n", + " )\n", " else:\n", - " return Command(update={\"authenticated\": False})\n", + " return Command(\n", + " update={\n", + " \"authenticated\": False,\n", + " \"messages\": [\n", + " ToolMessage(\n", + " content=\"Authentication failed - invalid password\",\n", + " tool_call_id=tool_call_id,\n", + " )\n", + " ],\n", + " }\n", + " )\n", "\n", "\n", "agent = create_agent(model=model, tools=[authenticate_user, check_authentication])\n", @@ -935,13 +1286,28 @@ { "cell_type": "markdown", "metadata": {}, - "source": "### Writes - Store에 쓰기\n\n`runtime.store.put()` 메서드를 사용하면 Store에 데이터를 저장할 수 있습니다. Store에 저장된 데이터는 여러 대화 세션에 걸쳐 지속되므로 사용자 선호도, 히스토리 등 장기 데이터를 저장하는 데 적합합니다.\n\n아래 코드는 사용자 선호도를 Store에 저장하는 도구를 구현합니다." + "source": [ + "### Writes - Store에 쓰기\n", + "\n", + "`runtime.store.put()` 메서드를 사용하면 Store에 데이터를 저장할 수 있습니다. Store에 저장된 데이터는 여러 대화 세션에 걸쳐 지속되므로 사용자 선호도, 히스토리 등 장기 데이터를 저장하는 데 적합합니다.\n", + "\n", + "아래 코드는 사용자 선호도를 Store에 저장하는 도구를 구현합니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 23, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Your theme has been set to dark. If there's anything else you'd like to customize, just let me know!\n", + "Your current theme is set to dark.\n" + ] + } + ], "source": [ "@tool\n", "def save_preference(\n", @@ -991,18 +1357,45 @@ { "cell_type": "markdown", "metadata": {}, - "source": "## Life-cycle Context\n\nLife-cycle Context는 핵심 에이전트 단계 **사이**에서 발생하는 작업을 제어합니다. 데이터 흐름을 가로채어 요약, 가드레일, 로깅과 같은 교차 관심사(cross-cutting concerns)를 구현할 수 있습니다. 미들웨어를 통해 모든 모델 호출과 도구 호출에 일관된 로직을 적용할 수 있습니다." + "source": [ + "## Life-cycle Context\n", + "\n", + "Life-cycle Context는 핵심 에이전트 단계 **사이**에서 발생하는 작업을 제어합니다. 데이터 흐름을 가로채어 요약, 가드레일, 로깅과 같은 교차 관심사(cross-cutting concerns)를 구현할 수 있습니다. 미들웨어를 통해 모든 모델 호출과 도구 호출에 일관된 로직을 적용할 수 있습니다." + ] }, { "cell_type": "markdown", "metadata": {}, - "source": "### Summarization\n\n가장 일반적인 라이프사이클 패턴 중 하나는 대화 기록이 너무 길어질 때 자동으로 압축하는 것입니다. 요약은 **상태를 영구적으로 업데이트**합니다 - 오래된 메시지를 요약으로 영구적으로 대체하여 모든 향후 턴에 대해 저장됩니다. 이를 통해 토큰 비용을 절감하면서도 중요한 컨텍스트를 유지할 수 있습니다.\n\n아래 코드는 `SummarizationMiddleware`를 사용하여 4000 토큰 초과 시 자동 요약을 수행하는 에이전트를 생성합니다." + "source": [ + "### 종합 아키텍처 다이어그램\n", + "\n", + "![Comprehensive Architecture](./assets/comprehensive_architecture.png)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Summarization\n", + "\n", + "가장 일반적인 라이프사이클 패턴 중 하나는 대화 기록이 너무 길어질 때 자동으로 압축하는 것입니다. 요약은 **상태를 영구적으로 업데이트**합니다 - 오래된 메시지를 요약으로 영구적으로 대체하여 모든 향후 턴에 대해 저장됩니다. 이를 통해 토큰 비용을 절감하면서도 중요한 컨텍스트를 유지할 수 있습니다.\n", + "\n", + "아래 코드는 `SummarizationMiddleware`를 사용하여 4000 토큰 초과 시 자동 요약을 수행하는 에이전트를 생성합니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Python is a high-level, interpreted programming language known for its readability and simplicity. It supports multiple programming paradigms, including procedural, object-oriented, and functional pro\n" + ] + } + ], "source": [ "from langchain.agents.middleware import SummarizationMiddleware\n", "\n", @@ -1012,8 +1405,8 @@ " middleware=[\n", " SummarizationMiddleware(\n", " model=\"openai:gpt-4.1-mini\",\n", - " max_tokens_before_summary=4000, # 4000 토큰에서 요약 트리거\n", - " messages_to_keep=20, # 요약 후 최근 20개 메시지 유지\n", + " trigger=('tokens', 4000), # 4000 토큰에서 요약 트리거\n", + " keep=('messages', 20), # 요약 후 최근 20개 메시지 유지\n", " ),\n", " ],\n", ")\n", @@ -1029,13 +1422,31 @@ { "cell_type": "markdown", "metadata": {}, - "source": "## 종합 예제: 다층 컨텍스트 엔지니어링\n\n이 섹션에서는 지금까지 학습한 모든 컨텍스트 엔지니어링 기술을 결합한 실용적인 예제를 구현합니다. 사용자 역할과 구독 등급에 따라 시스템 프롬프트와 도구 접근을 조정하고, Store를 활용하여 사용자별 히스토리를 관리합니다.\n\n아래 코드는 Runtime Context, State, Store, 동적 프롬프트, 도구 필터링을 모두 활용하는 종합 예제입니다." + "source": [ + "## 종합 예제: 다층 컨텍스트 엔지니어링\n", + "\n", + "이 섹션에서는 지금까지 학습한 모든 컨텍스트 엔지니어링 기술을 결합한 실용적인 예제를 구현합니다. 사용자 역할과 구독 등급에 따라 시스템 프롬프트와 도구 접근을 조정하고, Store를 활용하여 사용자별 히스토리를 관리합니다.\n", + "\n", + "아래 코드는 Runtime Context, State, Store, 동적 프롬프트, 도구 필터링을 모두 활용하는 종합 예제입니다." + ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "=== Premium User ===\n", + "Your recent search history includes queries like \"Python\" and \"Machine Learning.\" If you want, I can perform a more detailed analysis on this data or assist you with something specific related to your searches. Let me know how you would like to proceed!\n", + "\n", + "=== Free User ===\n", + "Could you please specify what type of data you have and what kind of advanced analysis you are looking for? For example, are you interested in statistical analysis, predictive modeling, data visualization, or something else? Also, if you could provide a sample or description of your data, that would be helpful.\n" + ] + } + ], "source": [ "from dataclasses import dataclass\n", "from langchain.agents import create_agent\n", @@ -1173,7 +1584,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "langgraph-v1-tutorial", "language": "python", "name": "python3" }, @@ -1187,9 +1598,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.11" + "version": "3.11.13" } }, "nbformat": 4, "nbformat_minor": 4 -} \ No newline at end of file +} diff --git a/04-Middleware/assets/comprehensive_architecture.excalidraw b/04-Middleware/assets/comprehensive_architecture.excalidraw new file mode 100644 index 0000000..94267dc --- /dev/null +++ b/04-Middleware/assets/comprehensive_architecture.excalidraw @@ -0,0 +1,1402 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "claude-code-excalidraw-skill", + "elements": [ + { + "id": "title", + "type": "text", + "x": 230, + "y": 15, + "width": 380, + "height": 30, + "text": "Context Engineering Architecture", + "fontSize": 24, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Context Engineering Architecture", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1, + "version": 1, + "versionNonce": 1, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "input-group", + "type": "rectangle", + "x": 40, + "y": 60, + "width": 760, + "height": 80, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 2, + "version": 1, + "versionNonce": 2, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "input-label", + "type": "text", + "x": 50, + "y": 68, + "width": 100, + "height": 20, + "text": "Agent Input", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Agent Input", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 3, + "version": 1, + "versionNonce": 3, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "user-request", + "type": "rectangle", + "x": 60, + "y": 90, + "width": 150, + "height": 40, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 4, + "version": 1, + "versionNonce": 4, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "user-request-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "user-request-text", + "type": "text", + "x": 65, + "y": 100, + "width": 140, + "height": 20, + "text": "User Request", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "user-request", + "originalText": "User Request", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 5, + "version": 1, + "versionNonce": 5, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "user-context", + "type": "rectangle", + "x": 240, + "y": 90, + "width": 280, + "height": 40, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "#e5e7eb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 6, + "version": 1, + "versionNonce": 6, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "user-context-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "user-context-text", + "type": "text", + "x": 245, + "y": 95, + "width": 270, + "height": 30, + "text": "UserContext\n(user_id, user_role, subscription_tier)", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "user-context", + "originalText": "UserContext\n(user_id, user_role, subscription_tier)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 7, + "version": 1, + "versionNonce": 7, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-input-agent", + "type": "arrow", + "x": 420, + "y": 140, + "width": 0, + "height": 30, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 8, + "version": 1, + "versionNonce": 8, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 30]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "agent-group", + "type": "rectangle", + "x": 40, + "y": 170, + "width": 760, + "height": 200, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 9, + "version": 1, + "versionNonce": 9, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "agent-label", + "type": "text", + "x": 350, + "y": 178, + "width": 140, + "height": 20, + "text": "create_agent()", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "create_agent()", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 10, + "version": 1, + "versionNonce": 10, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "middleware-group", + "type": "rectangle", + "x": 60, + "y": 205, + "width": 320, + "height": 150, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 11, + "version": 1, + "versionNonce": 11, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "middleware-label", + "type": "text", + "x": 170, + "y": 212, + "width": 100, + "height": 18, + "text": "Middleware Chain", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Middleware Chain", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 12, + "version": 1, + "versionNonce": 12, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "dynamic-prompt", + "type": "rectangle", + "x": 80, + "y": 240, + "width": 280, + "height": 45, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "#e9d5ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 13, + "version": 1, + "versionNonce": 13, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "dynamic-prompt-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "dynamic-prompt-text", + "type": "text", + "x": 85, + "y": 248, + "width": 270, + "height": 30, + "text": "@dynamic_prompt\nrole_based_prompt", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "dynamic-prompt", + "originalText": "@dynamic_prompt\nrole_based_prompt", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 14, + "version": 1, + "versionNonce": 14, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-prompt-wrap", + "type": "arrow", + "x": 220, + "y": 285, + "width": 0, + "height": 15, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 15, + "version": 1, + "versionNonce": 15, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 15]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "wrap-model", + "type": "rectangle", + "x": 80, + "y": 300, + "width": 280, + "height": 45, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "#e9d5ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 16, + "version": 1, + "versionNonce": 16, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "wrap-model-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "wrap-model-text", + "type": "text", + "x": 85, + "y": 308, + "width": 270, + "height": 30, + "text": "@wrap_model_call\ntier_based_tools", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "wrap-model", + "originalText": "@wrap_model_call\ntier_based_tools", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 17, + "version": 1, + "versionNonce": 17, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-wrap-llm", + "type": "arrow", + "x": 360, + "y": 322, + "width": 55, + "height": 0, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 18, + "version": 1, + "versionNonce": 18, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [55, 0]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "llm", + "type": "rectangle", + "x": 415, + "y": 280, + "width": 130, + "height": 85, + "angle": 0, + "strokeColor": "#ca8a04", + "backgroundColor": "#fef08a", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 19, + "version": 1, + "versionNonce": 19, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "llm-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "llm-text", + "type": "text", + "x": 420, + "y": 310, + "width": 120, + "height": 25, + "text": "LLM", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "llm", + "originalText": "LLM", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ca8a04", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 20, + "version": 1, + "versionNonce": 20, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tools-group", + "type": "rectangle", + "x": 560, + "y": 205, + "width": 220, + "height": 150, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 21, + "version": 1, + "versionNonce": 21, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tools-label", + "type": "text", + "x": 645, + "y": 212, + "width": 50, + "height": 18, + "text": "Tools", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Tools", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 22, + "version": 1, + "versionNonce": 22, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-history", + "type": "rectangle", + "x": 580, + "y": 240, + "width": 180, + "height": 32, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "#ccfbf1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 23, + "version": 1, + "versionNonce": 23, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "tool-history-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-history-text", + "type": "text", + "x": 585, + "y": 246, + "width": 170, + "height": 20, + "text": "get_user_history (Store Read)", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tool-history", + "originalText": "get_user_history (Store Read)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 24, + "version": 1, + "versionNonce": 24, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-save", + "type": "rectangle", + "x": 580, + "y": 280, + "width": 180, + "height": 32, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "#ccfbf1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 25, + "version": 1, + "versionNonce": 25, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "tool-save-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-save-text", + "type": "text", + "x": 585, + "y": 286, + "width": 170, + "height": 20, + "text": "save_search (Store Write)", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tool-save", + "originalText": "save_search (Store Write)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 26, + "version": 1, + "versionNonce": 26, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-advanced", + "type": "rectangle", + "x": 580, + "y": 320, + "width": 180, + "height": 32, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "#e9d5ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 27, + "version": 1, + "versionNonce": 27, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "tool-advanced-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-advanced-text", + "type": "text", + "x": 585, + "y": 326, + "width": 170, + "height": 20, + "text": "advanced_analysis (Premium)", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tool-advanced", + "originalText": "advanced_analysis (Premium)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 28, + "version": 1, + "versionNonce": 28, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-llm-tools", + "type": "arrow", + "x": 545, + "y": 322, + "width": 35, + "height": 0, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 29, + "version": 1, + "versionNonce": 29, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [35, 0]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": "arrow", + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "arrow-tools-store", + "type": "arrow", + "x": 670, + "y": 355, + "width": 0, + "height": 45, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 30, + "version": 1, + "versionNonce": 30, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 45]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": "arrow", + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "rw-label", + "type": "text", + "x": 680, + "y": 370, + "width": 60, + "height": 15, + "text": "Read/Write", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read/Write", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 31, + "version": 1, + "versionNonce": 31, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "store-group", + "type": "rectangle", + "x": 40, + "y": 400, + "width": 760, + "height": 100, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 32, + "version": 1, + "versionNonce": 32, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "store-label", + "type": "text", + "x": 50, + "y": 408, + "width": 120, + "height": 20, + "text": "InMemoryStore", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "InMemoryStore", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 33, + "version": 1, + "versionNonce": 33, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "store-history", + "type": "rectangle", + "x": 60, + "y": 440, + "width": 340, + "height": 50, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "#fecaca", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 34, + "version": 1, + "versionNonce": 34, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "store-history-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "store-history-text", + "type": "text", + "x": 65, + "y": 450, + "width": 330, + "height": 30, + "text": "('history', user_id) -> searches\n['Python', 'Machine Learning']", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "store-history", + "originalText": "('history', user_id) -> searches\n['Python', 'Machine Learning']", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 35, + "version": 1, + "versionNonce": 35, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "store-prefs", + "type": "rectangle", + "x": 440, + "y": 440, + "width": 340, + "height": 50, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "#fecaca", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 36, + "version": 1, + "versionNonce": 36, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "store-prefs-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "store-prefs-text", + "type": "text", + "x": 445, + "y": 450, + "width": 330, + "height": 30, + "text": "('preferences', user_id) -> prefs\n{theme: 'dark', language: 'ko'}", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "store-prefs", + "originalText": "('preferences', user_id) -> prefs\n{theme: 'dark', language: 'ko'}", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 37, + "version": 1, + "versionNonce": 37, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "output-group", + "type": "rectangle", + "x": 40, + "y": 520, + "width": 760, + "height": 70, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 38, + "version": 1, + "versionNonce": 38, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "output-label", + "type": "text", + "x": 50, + "y": 528, + "width": 60, + "height": 20, + "text": "Output", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Output", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 39, + "version": 1, + "versionNonce": 39, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "output-premium", + "type": "rectangle", + "x": 60, + "y": 550, + "width": 340, + "height": 30, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "#ccfbf1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 40, + "version": 1, + "versionNonce": 40, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "output-premium-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "output-premium-text", + "type": "text", + "x": 65, + "y": 555, + "width": 330, + "height": 20, + "text": "Premium User: All Features Available", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "output-premium", + "originalText": "Premium User: All Features Available", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 41, + "version": 1, + "versionNonce": 41, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "output-free", + "type": "rectangle", + "x": 440, + "y": 550, + "width": 340, + "height": 30, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "#fed7aa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 42, + "version": 1, + "versionNonce": 42, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "output-free-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "output-free-text", + "type": "text", + "x": 445, + "y": 555, + "width": 330, + "height": 20, + "text": "Free User: Limited Features", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "output-free", + "originalText": "Free User: Limited Features", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 43, + "version": 1, + "versionNonce": 43, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-agent-output", + "type": "arrow", + "x": 420, + "y": 370, + "width": 0, + "height": 150, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 44, + "version": 1, + "versionNonce": 44, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 150]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + } + ], + "appState": { + "gridSize": 20, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} diff --git a/04-Middleware/assets/comprehensive_architecture.png b/04-Middleware/assets/comprehensive_architecture.png new file mode 100644 index 0000000..5088dea Binary files /dev/null and b/04-Middleware/assets/comprehensive_architecture.png differ diff --git a/04-Middleware/assets/context_type.excalidraw b/04-Middleware/assets/context_type.excalidraw new file mode 100644 index 0000000..e3c0260 --- /dev/null +++ b/04-Middleware/assets/context_type.excalidraw @@ -0,0 +1,957 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "claude-code-excalidraw-skill", + "elements": [ + { + "id": "title", + "type": "text", + "x": 280, + "y": 20, + "width": 300, + "height": 30, + "text": "Context Type & Data Source", + "fontSize": 24, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Context Type & Data Source", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1, + "version": 1, + "versionNonce": 1, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "context-group", + "type": "rectangle", + "x": 40, + "y": 70, + "width": 780, + "height": 130, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 2, + "version": 1, + "versionNonce": 2, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "context-label", + "type": "text", + "x": 50, + "y": 75, + "width": 120, + "height": 20, + "text": "Context Type", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Context Type", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 3, + "version": 1, + "versionNonce": 3, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "model-context", + "type": "rectangle", + "x": 60, + "y": 105, + "width": 200, + "height": 80, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "#dbeafe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 4, + "version": 1, + "versionNonce": 4, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "model-context-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "model-context-text", + "type": "text", + "x": 65, + "y": 115, + "width": 190, + "height": 60, + "text": "Model Context\nTransient\n(Prompt, Message, Tool)", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "model-context", + "originalText": "Model Context\nTransient\n(Prompt, Message, Tool)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 5, + "version": 1, + "versionNonce": 5, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-context", + "type": "rectangle", + "x": 330, + "y": 105, + "width": 200, + "height": 80, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "#ccfbf1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 6, + "version": 1, + "versionNonce": 6, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "tool-context-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-context-text", + "type": "text", + "x": 335, + "y": 115, + "width": 190, + "height": 60, + "text": "Tool Context\nPersistent\n(Read/Write)", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tool-context", + "originalText": "Tool Context\nPersistent\n(Read/Write)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 7, + "version": 1, + "versionNonce": 7, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "lifecycle-context", + "type": "rectangle", + "x": 600, + "y": 105, + "width": 200, + "height": 80, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "#e9d5ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 8, + "version": 1, + "versionNonce": 8, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "lifecycle-context-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "lifecycle-context-text", + "type": "text", + "x": 605, + "y": 115, + "width": 190, + "height": 60, + "text": "Life-cycle Context\nPersistent\n(Summarize, Guard, Log)", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "lifecycle-context", + "originalText": "Life-cycle Context\nPersistent\n(Summarize, Guard, Log)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 9, + "version": 1, + "versionNonce": 9, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-model-runtime", + "type": "arrow", + "x": 110, + "y": 185, + "width": 0, + "height": 65, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 20, + "version": 1, + "versionNonce": 20, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 65]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "arrow-model-runtime-label", + "type": "text", + "x": 118, + "y": 205, + "width": 30, + "height": 20, + "text": "Read", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 21, + "version": 1, + "versionNonce": 21, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-model-state", + "type": "arrow", + "x": 210, + "y": 185, + "width": 130, + "height": 65, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 22, + "version": 1, + "versionNonce": 22, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [130, 65]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "arrow-model-state-label", + "type": "text", + "x": 255, + "y": 200, + "width": 60, + "height": 20, + "text": "Read/Write", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read/Write", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 23, + "version": 1, + "versionNonce": 23, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-tool-state", + "type": "arrow", + "x": 430, + "y": 185, + "width": 0, + "height": 65, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 24, + "version": 1, + "versionNonce": 24, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 65]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": "arrow", + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "arrow-tool-state-label", + "type": "text", + "x": 438, + "y": 205, + "width": 60, + "height": 20, + "text": "Read/Write", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read/Write", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 25, + "version": 1, + "versionNonce": 25, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-tool-store", + "type": "arrow", + "x": 480, + "y": 185, + "width": 170, + "height": 65, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 26, + "version": 1, + "versionNonce": 26, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [170, 65]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": "arrow", + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "arrow-tool-store-label", + "type": "text", + "x": 545, + "y": 200, + "width": 60, + "height": 20, + "text": "Read/Write", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read/Write", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 27, + "version": 1, + "versionNonce": 27, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-lifecycle-state", + "type": "arrow", + "x": 650, + "y": 185, + "width": 170, + "height": 65, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 28, + "version": 1, + "versionNonce": 28, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [-170, 65]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "arrow-lifecycle-state-label", + "type": "text", + "x": 530, + "y": 200, + "width": 30, + "height": 20, + "text": "Read", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 29, + "version": 1, + "versionNonce": 29, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-lifecycle-store", + "type": "arrow", + "x": 750, + "y": 185, + "width": 50, + "height": 65, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 30, + "version": 1, + "versionNonce": 30, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [50, 65]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": "arrow", + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "arrow-lifecycle-store-label", + "type": "text", + "x": 765, + "y": 200, + "width": 60, + "height": 20, + "text": "Read/Write", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read/Write", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 31, + "version": 1, + "versionNonce": 31, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "data-group", + "type": "rectangle", + "x": 40, + "y": 250, + "width": 780, + "height": 130, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 10, + "version": 1, + "versionNonce": 10, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "data-label", + "type": "text", + "x": 50, + "y": 255, + "width": 100, + "height": 20, + "text": "Data Source", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Data Source", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 11, + "version": 1, + "versionNonce": 11, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-context", + "type": "rectangle", + "x": 60, + "y": 285, + "width": 200, + "height": 80, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "#e5e7eb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 12, + "version": 1, + "versionNonce": 12, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "runtime-context-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-context-text", + "type": "text", + "x": 65, + "y": 295, + "width": 190, + "height": 60, + "text": "Runtime Context\nStatic Config\n(User ID, API Key, Role)", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "runtime-context", + "originalText": "Runtime Context\nStatic Config\n(User ID, API Key, Role)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 13, + "version": 1, + "versionNonce": 13, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "state", + "type": "rectangle", + "x": 330, + "y": 285, + "width": 200, + "height": 80, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "#fed7aa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 14, + "version": 1, + "versionNonce": 14, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "state-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "state-text", + "type": "text", + "x": 335, + "y": 295, + "width": 190, + "height": 60, + "text": "State\nShort-term Memory\n(Messages, Auth Status)", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "state", + "originalText": "State\nShort-term Memory\n(Messages, Auth Status)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 15, + "version": 1, + "versionNonce": 15, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "store", + "type": "rectangle", + "x": 600, + "y": 285, + "width": 200, + "height": 80, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "#fecaca", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 16, + "version": 1, + "versionNonce": 16, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "store-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "store-text", + "type": "text", + "x": 605, + "y": 295, + "width": 190, + "height": 60, + "text": "Store\nLong-term Memory\n(Prefs, History, Insights)", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "store", + "originalText": "Store\nLong-term Memory\n(Prefs, History, Insights)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 17, + "version": 1, + "versionNonce": 17, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + } + ], + "appState": { + "gridSize": 20, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} diff --git a/04-Middleware/assets/context_type.png b/04-Middleware/assets/context_type.png new file mode 100644 index 0000000..03a5836 Binary files /dev/null and b/04-Middleware/assets/context_type.png differ diff --git a/04-Middleware/assets/dynamic_prompt.excalidraw b/04-Middleware/assets/dynamic_prompt.excalidraw new file mode 100644 index 0000000..5493e3d --- /dev/null +++ b/04-Middleware/assets/dynamic_prompt.excalidraw @@ -0,0 +1,1023 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "claude-code-excalidraw-skill", + "elements": [ + { + "id": "title", + "type": "text", + "x": 200, + "y": 20, + "width": 350, + "height": 30, + "text": "@dynamic_prompt Middleware", + "fontSize": 24, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "@dynamic_prompt Middleware", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1, + "version": 1, + "versionNonce": 1, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "agent-call", + "type": "rectangle", + "x": 260, + "y": 70, + "width": 200, + "height": 60, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 2, + "version": 1, + "versionNonce": 2, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "agent-call-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "agent-call-text", + "type": "text", + "x": 265, + "y": 85, + "width": 190, + "height": 30, + "text": "Agent Call", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "agent-call", + "originalText": "Agent Call", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 3, + "version": 1, + "versionNonce": 3, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-call-middleware", + "type": "arrow", + "x": 360, + "y": 130, + "width": 0, + "height": 40, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 4, + "version": 1, + "versionNonce": 4, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 40]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "middleware-group", + "type": "rectangle", + "x": 60, + "y": 170, + "width": 600, + "height": 380, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 5, + "version": 1, + "versionNonce": 5, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "middleware-label", + "type": "text", + "x": 230, + "y": 180, + "width": 260, + "height": 20, + "text": "@dynamic_prompt Middleware", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "@dynamic_prompt Middleware", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 6, + "version": 1, + "versionNonce": 6, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "model-request", + "type": "rectangle", + "x": 80, + "y": 210, + "width": 180, + "height": 50, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "#dbeafe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 7, + "version": 1, + "versionNonce": 7, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "model-request-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "model-request-text", + "type": "text", + "x": 85, + "y": 222, + "width": 170, + "height": 26, + "text": "ModelRequest", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "model-request", + "originalText": "ModelRequest", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 8, + "version": 1, + "versionNonce": 8, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-request-sources", + "type": "arrow", + "x": 170, + "y": 260, + "width": 0, + "height": 30, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 9, + "version": 1, + "versionNonce": 9, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 30]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "data-sources-group", + "type": "rectangle", + "x": 80, + "y": 290, + "width": 560, + "height": 80, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 10, + "version": 1, + "versionNonce": 10, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "data-sources-label", + "type": "text", + "x": 285, + "y": 295, + "width": 150, + "height": 20, + "text": "Data Source Access", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Data Source Access", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 11, + "version": 1, + "versionNonce": 11, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-context", + "type": "rectangle", + "x": 95, + "y": 320, + "width": 160, + "height": 40, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "#e5e7eb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 12, + "version": 1, + "versionNonce": 12, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "runtime-context-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-context-text", + "type": "text", + "x": 100, + "y": 327, + "width": 150, + "height": 26, + "text": "request.runtime.context", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "runtime-context", + "originalText": "request.runtime.context", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 13, + "version": 1, + "versionNonce": 13, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "state", + "type": "rectangle", + "x": 280, + "y": 320, + "width": 160, + "height": 40, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "#fed7aa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 14, + "version": 1, + "versionNonce": 14, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "state-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "state-text", + "type": "text", + "x": 285, + "y": 327, + "width": 150, + "height": 26, + "text": "request.state", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "state", + "originalText": "request.state", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 15, + "version": 1, + "versionNonce": 15, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "store", + "type": "rectangle", + "x": 465, + "y": 320, + "width": 160, + "height": 40, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "#fecaca", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 16, + "version": 1, + "versionNonce": 16, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "store-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "store-text", + "type": "text", + "x": 470, + "y": 327, + "width": 150, + "height": 26, + "text": "request.runtime.store", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "store", + "originalText": "request.runtime.store", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 17, + "version": 1, + "versionNonce": 17, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-sources-conditions", + "type": "arrow", + "x": 360, + "y": 370, + "width": 0, + "height": 25, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 18, + "version": 1, + "versionNonce": 18, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 25]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "conditions-group", + "type": "rectangle", + "x": 80, + "y": 395, + "width": 560, + "height": 60, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 19, + "version": 1, + "versionNonce": 19, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "conditions-label", + "type": "text", + "x": 295, + "y": 400, + "width": 130, + "height": 20, + "text": "Condition Evaluation", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Condition Evaluation", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 20, + "version": 1, + "versionNonce": 20, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond1", + "type": "rectangle", + "x": 95, + "y": 420, + "width": 150, + "height": 30, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 21, + "version": 1, + "versionNonce": 21, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "cond1-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond1-text", + "type": "text", + "x": 100, + "y": 425, + "width": 140, + "height": 20, + "text": "message_count > 10?", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cond1", + "originalText": "message_count > 10?", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 22, + "version": 1, + "versionNonce": 22, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond2", + "type": "rectangle", + "x": 285, + "y": 420, + "width": 150, + "height": 30, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 23, + "version": 1, + "versionNonce": 23, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "cond2-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond2-text", + "type": "text", + "x": 290, + "y": 425, + "width": 140, + "height": 20, + "text": "user_role?", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cond2", + "originalText": "user_role?", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 24, + "version": 1, + "versionNonce": 24, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond3", + "type": "rectangle", + "x": 475, + "y": 420, + "width": 150, + "height": 30, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 25, + "version": 1, + "versionNonce": 25, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "cond3-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond3-text", + "type": "text", + "x": 480, + "y": 425, + "width": 140, + "height": 20, + "text": "user_prefs?", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cond3", + "originalText": "user_prefs?", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 26, + "version": 1, + "versionNonce": 26, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-conditions-prompt", + "type": "arrow", + "x": 360, + "y": 455, + "width": 0, + "height": 25, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 27, + "version": 1, + "versionNonce": 27, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 25]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "dynamic-prompt", + "type": "rectangle", + "x": 240, + "y": 480, + "width": 240, + "height": 50, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "#dbeafe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 28, + "version": 1, + "versionNonce": 28, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "dynamic-prompt-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "dynamic-prompt-text", + "type": "text", + "x": 245, + "y": 492, + "width": 230, + "height": 26, + "text": "Dynamic System Prompt", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "dynamic-prompt", + "originalText": "Dynamic System Prompt", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 29, + "version": 1, + "versionNonce": 29, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-prompt-llm", + "type": "arrow", + "x": 360, + "y": 550, + "width": 0, + "height": 40, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 30, + "version": 1, + "versionNonce": 30, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 40]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "llm-call", + "type": "rectangle", + "x": 260, + "y": 590, + "width": 200, + "height": 60, + "angle": 0, + "strokeColor": "#ca8a04", + "backgroundColor": "#fef08a", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 31, + "version": 1, + "versionNonce": 31, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "llm-call-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "llm-call-text", + "type": "text", + "x": 265, + "y": 600, + "width": 190, + "height": 40, + "text": "LLM Call\n(with custom prompt)", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "llm-call", + "originalText": "LLM Call\n(with custom prompt)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ca8a04", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 32, + "version": 1, + "versionNonce": 32, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + } + ], + "appState": { + "gridSize": 20, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} diff --git a/04-Middleware/assets/dynamic_prompt.png b/04-Middleware/assets/dynamic_prompt.png new file mode 100644 index 0000000..75e4e98 Binary files /dev/null and b/04-Middleware/assets/dynamic_prompt.png differ diff --git a/04-Middleware/assets/model_context.excalidraw b/04-Middleware/assets/model_context.excalidraw new file mode 100644 index 0000000..e5dca9f --- /dev/null +++ b/04-Middleware/assets/model_context.excalidraw @@ -0,0 +1,1029 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "claude-code-excalidraw-skill", + "elements": [ + { + "id": "title", + "type": "text", + "x": 350, + "y": 20, + "width": 250, + "height": 30, + "text": "Model Context Flow", + "fontSize": 24, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Model Context Flow", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1, + "version": 1, + "versionNonce": 1, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "input-group", + "type": "rectangle", + "x": 40, + "y": 70, + "width": 160, + "height": 400, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 2, + "version": 1, + "versionNonce": 2, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "input-label", + "type": "text", + "x": 90, + "y": 80, + "width": 60, + "height": 20, + "text": "Input", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Input", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 3, + "version": 1, + "versionNonce": 3, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "user-request", + "type": "rectangle", + "x": 55, + "y": 220, + "width": 130, + "height": 60, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 4, + "version": 1, + "versionNonce": 4, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "user-request-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "user-request-text", + "type": "text", + "x": 60, + "y": 235, + "width": 120, + "height": 30, + "text": "User Request", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "user-request", + "originalText": "User Request", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 5, + "version": 1, + "versionNonce": 5, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "model-context-group", + "type": "rectangle", + "x": 230, + "y": 70, + "width": 260, + "height": 400, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 6, + "version": 1, + "versionNonce": 6, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "model-context-label", + "type": "text", + "x": 290, + "y": 80, + "width": 140, + "height": 20, + "text": "Model Context", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Model Context", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 7, + "version": 1, + "versionNonce": 7, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "system-prompt", + "type": "rectangle", + "x": 250, + "y": 115, + "width": 220, + "height": 50, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "#dbeafe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 8, + "version": 1, + "versionNonce": 8, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "system-prompt-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "system-prompt-text", + "type": "text", + "x": 255, + "y": 127, + "width": 210, + "height": 26, + "text": "System Prompt", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "system-prompt", + "originalText": "System Prompt", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 9, + "version": 1, + "versionNonce": 9, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "messages", + "type": "rectangle", + "x": 250, + "y": 180, + "width": 220, + "height": 50, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "#dbeafe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 10, + "version": 1, + "versionNonce": 10, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "messages-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "messages-text", + "type": "text", + "x": 255, + "y": 192, + "width": 210, + "height": 26, + "text": "Messages", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "messages", + "originalText": "Messages", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 11, + "version": 1, + "versionNonce": 11, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tools", + "type": "rectangle", + "x": 250, + "y": 245, + "width": 220, + "height": 50, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "#ccfbf1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 12, + "version": 1, + "versionNonce": 12, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "tools-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tools-text", + "type": "text", + "x": 255, + "y": 257, + "width": 210, + "height": 26, + "text": "Tools", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tools", + "originalText": "Tools", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 13, + "version": 1, + "versionNonce": 13, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "model", + "type": "rectangle", + "x": 250, + "y": 310, + "width": 220, + "height": 50, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "#dbeafe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 14, + "version": 1, + "versionNonce": 14, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "model-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "model-text", + "type": "text", + "x": 255, + "y": 322, + "width": 210, + "height": 26, + "text": "Model", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "model", + "originalText": "Model", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 15, + "version": 1, + "versionNonce": 15, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "response-format", + "type": "rectangle", + "x": 250, + "y": 375, + "width": 220, + "height": 50, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "#dbeafe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 16, + "version": 1, + "versionNonce": 16, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "response-format-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "response-format-text", + "type": "text", + "x": 255, + "y": 387, + "width": 210, + "height": 26, + "text": "Response Format", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "response-format", + "originalText": "Response Format", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 17, + "version": 1, + "versionNonce": 17, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "llm-group", + "type": "rectangle", + "x": 520, + "y": 70, + "width": 180, + "height": 400, + "angle": 0, + "strokeColor": "#ca8a04", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 18, + "version": 1, + "versionNonce": 18, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "llm-label", + "type": "text", + "x": 575, + "y": 80, + "width": 70, + "height": 20, + "text": "LLM Call", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "LLM Call", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ca8a04", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 19, + "version": 1, + "versionNonce": 19, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "llm", + "type": "rectangle", + "x": 545, + "y": 220, + "width": 130, + "height": 60, + "angle": 0, + "strokeColor": "#ca8a04", + "backgroundColor": "#fef08a", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 20, + "version": 1, + "versionNonce": 20, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "llm-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "llm-text", + "type": "text", + "x": 550, + "y": 235, + "width": 120, + "height": 30, + "text": "LLM", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "llm", + "originalText": "LLM", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ca8a04", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 21, + "version": 1, + "versionNonce": 21, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "output-group", + "type": "rectangle", + "x": 730, + "y": 70, + "width": 160, + "height": 400, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 22, + "version": 1, + "versionNonce": 22, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "output-label", + "type": "text", + "x": 780, + "y": 80, + "width": 60, + "height": 20, + "text": "Output", + "fontSize": 16, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Output", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 23, + "version": 1, + "versionNonce": 23, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "output", + "type": "rectangle", + "x": 745, + "y": 220, + "width": 130, + "height": 60, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 24, + "version": 1, + "versionNonce": 24, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "output-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "output-text", + "type": "text", + "x": 750, + "y": 225, + "width": 120, + "height": 50, + "text": "Response\n/ Tool Call", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "output", + "originalText": "Response\n/ Tool Call", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 25, + "version": 1, + "versionNonce": 25, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-input-messages", + "type": "arrow", + "x": 185, + "y": 250, + "width": 65, + "height": 45, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 30, + "version": 1, + "versionNonce": 30, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [65, -45]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "arrow-prompt-llm", + "type": "arrow", + "x": 470, + "y": 140, + "width": 75, + "height": 100, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 31, + "version": 1, + "versionNonce": 31, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [75, 100]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "arrow-messages-llm", + "type": "arrow", + "x": 470, + "y": 205, + "width": 75, + "height": 40, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 32, + "version": 1, + "versionNonce": 32, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [75, 40]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "arrow-tools-llm", + "type": "arrow", + "x": 470, + "y": 270, + "width": 75, + "height": 20, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 33, + "version": 1, + "versionNonce": 33, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [75, -20]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "arrow-model-llm", + "type": "arrow", + "x": 470, + "y": 335, + "width": 75, + "height": 80, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 34, + "version": 1, + "versionNonce": 34, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [75, -80]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "arrow-format-llm", + "type": "arrow", + "x": 470, + "y": 400, + "width": 75, + "height": 140, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 35, + "version": 1, + "versionNonce": 35, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [75, -140]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": false + }, + { + "id": "arrow-llm-output", + "type": "arrow", + "x": 675, + "y": 250, + "width": 70, + "height": 0, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 36, + "version": 1, + "versionNonce": 36, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [70, 0]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + } + ], + "appState": { + "gridSize": 20, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} diff --git a/04-Middleware/assets/model_context.png b/04-Middleware/assets/model_context.png new file mode 100644 index 0000000..1f1c077 Binary files /dev/null and b/04-Middleware/assets/model_context.png differ diff --git a/04-Middleware/assets/tool_context.excalidraw b/04-Middleware/assets/tool_context.excalidraw new file mode 100644 index 0000000..e7c90cd --- /dev/null +++ b/04-Middleware/assets/tool_context.excalidraw @@ -0,0 +1,1315 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "claude-code-excalidraw-skill", + "elements": [ + { + "id": "title", + "type": "text", + "x": 240, + "y": 20, + "width": 300, + "height": 30, + "text": "Tool Context (ToolRuntime)", + "fontSize": 24, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Tool Context (ToolRuntime)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1, + "version": 1, + "versionNonce": 1, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-function", + "type": "rectangle", + "x": 60, + "y": 70, + "width": 250, + "height": 80, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "#ccfbf1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 2, + "version": 1, + "versionNonce": 2, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "tool-function-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-function-text", + "type": "text", + "x": 65, + "y": 85, + "width": 240, + "height": 50, + "text": "@tool\ndef my_tool(arg, runtime: ToolRuntime)", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tool-function", + "originalText": "@tool\ndef my_tool(arg, runtime: ToolRuntime)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 3, + "version": 1, + "versionNonce": 3, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-label", + "type": "text", + "x": 140, + "y": 55, + "width": 90, + "height": 18, + "text": "Tool Function", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Tool Function", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 4, + "version": 1, + "versionNonce": 4, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-tool-runtime", + "type": "arrow", + "x": 185, + "y": 150, + "width": 0, + "height": 30, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 5, + "version": 1, + "versionNonce": 5, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 30]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "runtime-group", + "type": "rectangle", + "x": 40, + "y": 180, + "width": 700, + "height": 100, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 6, + "version": 1, + "versionNonce": 6, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-label", + "type": "text", + "x": 310, + "y": 188, + "width": 160, + "height": 20, + "text": "ToolRuntime Object", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "ToolRuntime Object", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 7, + "version": 1, + "versionNonce": 7, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-context", + "type": "rectangle", + "x": 60, + "y": 215, + "width": 180, + "height": 50, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "#e5e7eb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 8, + "version": 1, + "versionNonce": 8, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "runtime-context-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-context-text", + "type": "text", + "x": 65, + "y": 227, + "width": 170, + "height": 26, + "text": "runtime.context", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "runtime-context", + "originalText": "runtime.context", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 9, + "version": 1, + "versionNonce": 9, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-state", + "type": "rectangle", + "x": 300, + "y": 215, + "width": 180, + "height": 50, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "#fed7aa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 10, + "version": 1, + "versionNonce": 10, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "runtime-state-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-state-text", + "type": "text", + "x": 305, + "y": 227, + "width": 170, + "height": 26, + "text": "runtime.state", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "runtime-state", + "originalText": "runtime.state", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 11, + "version": 1, + "versionNonce": 11, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-store", + "type": "rectangle", + "x": 540, + "y": 215, + "width": 180, + "height": 50, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "#fecaca", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 12, + "version": 1, + "versionNonce": 12, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "runtime-store-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "runtime-store-text", + "type": "text", + "x": 545, + "y": 227, + "width": 170, + "height": 26, + "text": "runtime.store", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "runtime-store", + "originalText": "runtime.store", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 13, + "version": 1, + "versionNonce": 13, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "read-label-context", + "type": "text", + "x": 120, + "y": 273, + "width": 60, + "height": 18, + "text": "Read Only", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read Only", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 14, + "version": 1, + "versionNonce": 14, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "read-label-state", + "type": "text", + "x": 360, + "y": 273, + "width": 60, + "height": 18, + "text": "Read Only", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read Only", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 15, + "version": 1, + "versionNonce": 15, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "rw-label-store", + "type": "text", + "x": 600, + "y": 273, + "width": 60, + "height": 18, + "text": "Read/Write", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read/Write", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 16, + "version": 1, + "versionNonce": 16, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-context-source", + "type": "arrow", + "x": 150, + "y": 265, + "width": 0, + "height": 35, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 17, + "version": 1, + "versionNonce": 17, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 35]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "arrow-state-source", + "type": "arrow", + "x": 390, + "y": 265, + "width": 0, + "height": 35, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 18, + "version": 1, + "versionNonce": 18, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 35]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "arrow-store-source", + "type": "arrow", + "x": 630, + "y": 265, + "width": 0, + "height": 35, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 19, + "version": 1, + "versionNonce": 19, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 35]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": "arrow", + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "data-sources-group", + "type": "rectangle", + "x": 40, + "y": 300, + "width": 700, + "height": 80, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 20, + "version": 1, + "versionNonce": 20, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "data-sources-label", + "type": "text", + "x": 340, + "y": 308, + "width": 100, + "height": 20, + "text": "Data Sources", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Data Sources", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 21, + "version": 1, + "versionNonce": 21, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "source-context", + "type": "rectangle", + "x": 60, + "y": 330, + "width": 180, + "height": 40, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "#e5e7eb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 22, + "version": 1, + "versionNonce": 22, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "source-context-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "source-context-text", + "type": "text", + "x": 65, + "y": 337, + "width": 170, + "height": 26, + "text": "Runtime Context\n(user_id, role, tier)", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "source-context", + "originalText": "Runtime Context\n(user_id, role, tier)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 23, + "version": 1, + "versionNonce": 23, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "source-state", + "type": "rectangle", + "x": 300, + "y": 330, + "width": 180, + "height": 40, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "#fed7aa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 24, + "version": 1, + "versionNonce": 24, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "source-state-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "source-state-text", + "type": "text", + "x": 305, + "y": 337, + "width": 170, + "height": 26, + "text": "State\n(messages, authenticated)", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "source-state", + "originalText": "State\n(messages, authenticated)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 25, + "version": 1, + "versionNonce": 25, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "source-store", + "type": "rectangle", + "x": 540, + "y": 330, + "width": 180, + "height": 40, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "#fecaca", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 26, + "version": 1, + "versionNonce": 26, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "source-store-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "source-store-text", + "type": "text", + "x": 545, + "y": 337, + "width": 170, + "height": 26, + "text": "Store\n(preferences, history)", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "source-store", + "originalText": "Store\n(preferences, history)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 27, + "version": 1, + "versionNonce": 27, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "read-ops-group", + "type": "rectangle", + "x": 40, + "y": 400, + "width": 340, + "height": 120, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 28, + "version": 1, + "versionNonce": 28, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "read-ops-label", + "type": "text", + "x": 160, + "y": 408, + "width": 100, + "height": 20, + "text": "Read Operations", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Read Operations", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 29, + "version": 1, + "versionNonce": 29, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "read-context-op", + "type": "rectangle", + "x": 55, + "y": 435, + "width": 150, + "height": 35, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 30, + "version": 1, + "versionNonce": 30, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "read-context-op-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "read-context-op-text", + "type": "text", + "x": 60, + "y": 443, + "width": 140, + "height": 19, + "text": "runtime.context.user_id", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "read-context-op", + "originalText": "runtime.context.user_id", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 31, + "version": 1, + "versionNonce": 31, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "read-state-op", + "type": "rectangle", + "x": 55, + "y": 475, + "width": 150, + "height": 35, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 32, + "version": 1, + "versionNonce": 32, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "read-state-op-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "read-state-op-text", + "type": "text", + "x": 60, + "y": 483, + "width": 140, + "height": 19, + "text": "runtime.state.get('key')", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "read-state-op", + "originalText": "runtime.state.get('key')", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 33, + "version": 1, + "versionNonce": 33, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "read-store-op", + "type": "rectangle", + "x": 215, + "y": 435, + "width": 155, + "height": 75, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 34, + "version": 1, + "versionNonce": 34, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "read-store-op-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "read-store-op-text", + "type": "text", + "x": 220, + "y": 455, + "width": 145, + "height": 35, + "text": "runtime.store.get(\n (namespace,), key)", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "read-store-op", + "originalText": "runtime.store.get(\n (namespace,), key)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 35, + "version": 1, + "versionNonce": 35, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "write-ops-group", + "type": "rectangle", + "x": 400, + "y": 400, + "width": 340, + "height": 120, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 36, + "version": 1, + "versionNonce": 36, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "write-ops-label", + "type": "text", + "x": 520, + "y": 408, + "width": 100, + "height": 20, + "text": "Write Operations", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Write Operations", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 37, + "version": 1, + "versionNonce": 37, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "write-state-op", + "type": "rectangle", + "x": 415, + "y": 435, + "width": 150, + "height": 75, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "#fed7aa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 38, + "version": 1, + "versionNonce": 38, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "write-state-op-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "write-state-op-text", + "type": "text", + "x": 420, + "y": 445, + "width": 140, + "height": 55, + "text": "State Write\nreturn Command(\n update={...})", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "write-state-op", + "originalText": "State Write\nreturn Command(\n update={...})", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 39, + "version": 1, + "versionNonce": 39, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "write-store-op", + "type": "rectangle", + "x": 575, + "y": 435, + "width": 150, + "height": 75, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "#fecaca", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 40, + "version": 1, + "versionNonce": 40, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "write-store-op-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "write-store-op-text", + "type": "text", + "x": 580, + "y": 445, + "width": 140, + "height": 55, + "text": "Store Write\nruntime.store.put(\n (ns,), key, value)", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "write-store-op", + "originalText": "Store Write\nruntime.store.put(\n (ns,), key, value)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 41, + "version": 1, + "versionNonce": 41, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + } + ], + "appState": { + "gridSize": 20, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} diff --git a/04-Middleware/assets/tool_context.png b/04-Middleware/assets/tool_context.png new file mode 100644 index 0000000..bc9c8cb Binary files /dev/null and b/04-Middleware/assets/tool_context.png differ diff --git a/04-Middleware/assets/tool_filtering.excalidraw b/04-Middleware/assets/tool_filtering.excalidraw new file mode 100644 index 0000000..fdc4d3d --- /dev/null +++ b/04-Middleware/assets/tool_filtering.excalidraw @@ -0,0 +1,1327 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "claude-code-excalidraw-skill", + "elements": [ + { + "id": "title", + "type": "text", + "x": 200, + "y": 20, + "width": 380, + "height": 30, + "text": "@wrap_model_call Tool Filtering", + "fontSize": 24, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "@wrap_model_call Tool Filtering", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1, + "version": 1, + "versionNonce": 1, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "agent-group", + "type": "rectangle", + "x": 40, + "y": 70, + "width": 700, + "height": 120, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 2, + "version": 1, + "versionNonce": 2, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "agent-label", + "type": "text", + "x": 50, + "y": 78, + "width": 100, + "height": 20, + "text": "Agent Call", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Agent Call", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 3, + "version": 1, + "versionNonce": 3, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "user-request", + "type": "rectangle", + "x": 60, + "y": 110, + "width": 120, + "height": 60, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 4, + "version": 1, + "versionNonce": 4, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "user-request-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "user-request-text", + "type": "text", + "x": 65, + "y": 125, + "width": 110, + "height": 30, + "text": "User Request", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "user-request", + "originalText": "User Request", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 5, + "version": 1, + "versionNonce": 5, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tools-box", + "type": "rectangle", + "x": 250, + "y": 100, + "width": 470, + "height": 80, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 6, + "version": 1, + "versionNonce": 6, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tools-label", + "type": "text", + "x": 420, + "y": 105, + "width": 130, + "height": 20, + "text": "All Tools Available", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "All Tools Available", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 7, + "version": 1, + "versionNonce": 7, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-read", + "type": "rectangle", + "x": 265, + "y": 130, + "width": 100, + "height": 40, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "#ccfbf1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 8, + "version": 1, + "versionNonce": 8, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "tool-read-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-read-text", + "type": "text", + "x": 270, + "y": 140, + "width": 90, + "height": 20, + "text": "read_data", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tool-read", + "originalText": "read_data", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 9, + "version": 1, + "versionNonce": 9, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-write", + "type": "rectangle", + "x": 385, + "y": 130, + "width": 100, + "height": 40, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "#fed7aa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 10, + "version": 1, + "versionNonce": 10, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "tool-write-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-write-text", + "type": "text", + "x": 390, + "y": 140, + "width": 90, + "height": 20, + "text": "write_data", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tool-write", + "originalText": "write_data", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 11, + "version": 1, + "versionNonce": 11, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-delete", + "type": "rectangle", + "x": 505, + "y": 130, + "width": 100, + "height": 40, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "#fecaca", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 12, + "version": 1, + "versionNonce": 12, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "tool-delete-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-delete-text", + "type": "text", + "x": 510, + "y": 140, + "width": 90, + "height": 20, + "text": "delete_data", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tool-delete", + "originalText": "delete_data", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 13, + "version": 1, + "versionNonce": 13, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-advanced", + "type": "rectangle", + "x": 625, + "y": 130, + "width": 80, + "height": 40, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "#e9d5ff", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 14, + "version": 1, + "versionNonce": 14, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "tool-advanced-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "tool-advanced-text", + "type": "text", + "x": 630, + "y": 140, + "width": 70, + "height": 20, + "text": "advanced", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "tool-advanced", + "originalText": "advanced", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 15, + "version": 1, + "versionNonce": 15, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-to-middleware", + "type": "arrow", + "x": 390, + "y": 190, + "width": 0, + "height": 40, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 16, + "version": 1, + "versionNonce": 16, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 40]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "middleware-group", + "type": "rectangle", + "x": 40, + "y": 230, + "width": 700, + "height": 180, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 17, + "version": 1, + "versionNonce": 17, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "middleware-label", + "type": "text", + "x": 265, + "y": 240, + "width": 250, + "height": 20, + "text": "@wrap_model_call Middleware", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "@wrap_model_call Middleware", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#9333ea", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 18, + "version": 1, + "versionNonce": 18, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "check-conditions", + "type": "rectangle", + "x": 60, + "y": 270, + "width": 140, + "height": 50, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "#dbeafe", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 19, + "version": 1, + "versionNonce": 19, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "check-conditions-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "check-conditions-text", + "type": "text", + "x": 65, + "y": 282, + "width": 130, + "height": 26, + "text": "Check Conditions", + "fontSize": 12, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "check-conditions", + "originalText": "Check Conditions", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#2563eb", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 20, + "version": 1, + "versionNonce": 20, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-check-filter", + "type": "arrow", + "x": 130, + "y": 320, + "width": 0, + "height": 30, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 21, + "version": 1, + "versionNonce": 21, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 30]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "filter-conditions-group", + "type": "rectangle", + "x": 230, + "y": 270, + "width": 490, + "height": 50, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 22, + "version": 1, + "versionNonce": 22, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "filter-label", + "type": "text", + "x": 400, + "y": 275, + "width": 150, + "height": 20, + "text": "Filtering Conditions", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Filtering Conditions", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 23, + "version": 1, + "versionNonce": 23, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond-auth", + "type": "rectangle", + "x": 245, + "y": 293, + "width": 120, + "height": 22, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 24, + "version": 1, + "versionNonce": 24, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "cond-auth-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond-auth-text", + "type": "text", + "x": 250, + "y": 296, + "width": 110, + "height": 16, + "text": "authenticated", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cond-auth", + "originalText": "authenticated", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 25, + "version": 1, + "versionNonce": 25, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond-role", + "type": "rectangle", + "x": 415, + "y": 293, + "width": 120, + "height": 22, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 26, + "version": 1, + "versionNonce": 26, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "cond-role-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond-role-text", + "type": "text", + "x": 420, + "y": 296, + "width": 110, + "height": 16, + "text": "user_role", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cond-role", + "originalText": "user_role", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 27, + "version": 1, + "versionNonce": 27, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond-tier", + "type": "rectangle", + "x": 585, + "y": 293, + "width": 120, + "height": 22, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 28, + "version": 1, + "versionNonce": 28, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "cond-tier-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "cond-tier-text", + "type": "text", + "x": 590, + "y": 296, + "width": 110, + "height": 16, + "text": "subscription_tier", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "cond-tier", + "originalText": "subscription_tier", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 29, + "version": 1, + "versionNonce": 29, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "rbac-group", + "type": "rectangle", + "x": 60, + "y": 350, + "width": 660, + "height": 50, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 30, + "version": 1, + "versionNonce": 30, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "rbac-label", + "type": "text", + "x": 335, + "y": 352, + "width": 110, + "height": 16, + "text": "RBAC Tool Filtering", + "fontSize": 11, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "RBAC Tool Filtering", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 31, + "version": 1, + "versionNonce": 31, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "role-admin", + "type": "rectangle", + "x": 75, + "y": 370, + "width": 130, + "height": 25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "#fecaca", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 32, + "version": 1, + "versionNonce": 32, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "role-admin-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "role-admin-text", + "type": "text", + "x": 80, + "y": 374, + "width": 120, + "height": 17, + "text": "Admin: All Tools", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "role-admin", + "originalText": "Admin: All Tools", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#dc2626", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 33, + "version": 1, + "versionNonce": 33, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "role-editor", + "type": "rectangle", + "x": 240, + "y": 370, + "width": 130, + "height": 25, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "#fed7aa", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 34, + "version": 1, + "versionNonce": 34, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "role-editor-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "role-editor-text", + "type": "text", + "x": 245, + "y": 374, + "width": 120, + "height": 17, + "text": "Editor: No Delete", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "role-editor", + "originalText": "Editor: No Delete", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ea580c", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 35, + "version": 1, + "versionNonce": 35, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "role-viewer", + "type": "rectangle", + "x": 410, + "y": 370, + "width": 130, + "height": 25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "#ccfbf1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 36, + "version": 1, + "versionNonce": 36, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "role-viewer-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "role-viewer-text", + "type": "text", + "x": 415, + "y": 374, + "width": 120, + "height": 17, + "text": "Viewer: Read Only", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "role-viewer", + "originalText": "Viewer: Read Only", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#0d9488", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 37, + "version": 1, + "versionNonce": 37, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "role-unauth", + "type": "rectangle", + "x": 575, + "y": 370, + "width": 130, + "height": 25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "#f3f4f6", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 38, + "version": 1, + "versionNonce": 38, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "role-unauth-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "role-unauth-text", + "type": "text", + "x": 580, + "y": 374, + "width": 120, + "height": 17, + "text": "Unauth: Public Only", + "fontSize": 10, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "role-unauth", + "originalText": "Unauth: Public Only", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#6b7280", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 39, + "version": 1, + "versionNonce": 39, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "arrow-to-llm", + "type": "arrow", + "x": 390, + "y": 410, + "width": 0, + "height": 40, + "angle": 0, + "strokeColor": "#4b5563", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 0, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 40, + "version": 1, + "versionNonce": 40, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false, + "points": [[0, 0], [0, 40]], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "elbowed": true + }, + { + "id": "llm-call", + "type": "rectangle", + "x": 290, + "y": 450, + "width": 200, + "height": 60, + "angle": 0, + "strokeColor": "#ca8a04", + "backgroundColor": "#fef08a", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { "type": 3 }, + "seed": 41, + "version": 1, + "versionNonce": 41, + "isDeleted": false, + "boundElements": [{ "type": "text", "id": "llm-call-text" }], + "updated": 1, + "link": null, + "locked": false + }, + { + "id": "llm-call-text", + "type": "text", + "x": 295, + "y": 462, + "width": 190, + "height": 36, + "text": "LLM Call\n(Filtered Tools)", + "fontSize": 14, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "llm-call", + "originalText": "LLM Call\n(Filtered Tools)", + "lineHeight": 1.25, + "angle": 0, + "strokeColor": "#ca8a04", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 42, + "version": 1, + "versionNonce": 42, + "isDeleted": false, + "boundElements": null, + "updated": 1, + "link": null, + "locked": false + } + ], + "appState": { + "gridSize": 20, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} diff --git a/04-Middleware/assets/tool_filtering.png b/04-Middleware/assets/tool_filtering.png new file mode 100644 index 0000000..49b9611 Binary files /dev/null and b/04-Middleware/assets/tool_filtering.png differ