Skip to content

Commit

Permalink
feat: Add langgraph orchestration (#447)
Browse files Browse the repository at this point in the history
Langgraph is introduced in langchain v0.2.0. The legacy langchain agent
(implemented in the `langchain-tools` orchestration) is deprecated in
langchain v0.2.0 and will soon be removed in the newer version of
langchain.

This PR adds a new orchestration - langgraph
  • Loading branch information
Yuan325 authored Jul 30, 2024
1 parent d0a3c63 commit 8cefed0
Show file tree
Hide file tree
Showing 13 changed files with 1,212 additions and 3 deletions.
1 change: 1 addition & 0 deletions .github/sync-repo-settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ branchProtectionRules:
- "retrieval-service-alloydb-pr (retrieval-app-testing)"
- "retrieval-service-cloudsql-pg-pr (retrieval-app-testing)"
- "llm-demo-langchain-tools-pr (retrieval-app-testing)"
- "llm-demo-langgraph-pr (retrieval-app-testing)"
- "llm-demo-vertexai-fc-pr (retrieval-app-testing)"
# Set team access
permissionRules:
Expand Down
2 changes: 2 additions & 0 deletions llm_demo/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ async def decline_flight(request: Request):
"""Handler for LangChain chat requests"""
# Note in the history, that the ticket was not booked
# This is helpful in case of reloads so there doesn't seem to be a break in communication.
orchestrator = request.app.state.orchestrator
response = await orchestrator.user_session_decline_ticket(request.session["uuid"])
request.session["history"].append(
{"type": "ai", "data": {"content": "Please confirm if you would like to book."}}
)
Expand Down
80 changes: 80 additions & 0 deletions llm_demo/langgraph.int.tests.cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright 2024 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

steps:
- id: "Deploy to Cloud Run"
name: "gcr.io/cloud-builders/gcloud:latest"
dir: llm_demo
script: |
#!/usr/bin/env bash
gcloud run deploy ${_SERVICE} \
--source . \
--region ${_REGION} \
--no-allow-unauthenticated \
--update-env-vars ORCHESTRATION_TYPE=${_ORCHESTRATION_TYPE}
- id: "Test Frontend"
name: "gcr.io/cloud-builders/gcloud:latest"
entrypoint: /bin/bash
env: # Set env var expected by app
args:
- "-c"
- |
export URL=$(gcloud run services describe ${_SERVICE} --region ${_REGION} --format 'value(status.url)')
export ID_TOKEN=$(gcloud auth print-identity-token --audiences $$URL)
export ORCHESTRATION_TYPE=${_ORCHESTRATION_TYPE}
# Test `/` route
curl -c cookies.txt -si --fail --show-error -H "Authorization: Bearer $$ID_TOKEN" $$URL
# Test `/chat` route should fail
msg=$(curl -si --show-error \
-X POST \
-H "Authorization: Bearer $$ID_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"prompt":"How can you help me?"}' \
$$URL/chat)
if grep -q "400" <<< "$msg"; then
echo "Chat Handler Test: PASSED"
else
echo "Chat Handler Test: FAILED"
echo $msg && exit 1
fi
# Test `/chat` route
curl -b cookies.txt -si --fail --show-error \
-X POST \
-H "Authorization: Bearer $$ID_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"prompt":"How can you help me?"}' \
$$URL/chat
- id: "Delete image and service"
name: "gcr.io/cloud-builders/gcloud"
script: |
#!/usr/bin/env bash
gcloud artifacts docker images delete $_GCR_HOSTNAME/$PROJECT_ID/cloud-run-source-deploy/$_SERVICE --quiet
gcloud run services delete ${_SERVICE} --region ${_REGION} --quiet
serviceAccount: "projects/$PROJECT_ID/serviceAccounts/548341735270-compute@developer.gserviceaccount.com" # Necessary for ID token creation
options:
automapSubstitutions: true
logging: CLOUD_LOGGING_ONLY # Necessary for custom service account
dynamic_substitutions: true

substitutions:
_GCR_HOSTNAME: ${_REGION}-docker.pkg.dev
_SERVICE: demo-service-${BUILD_ID}
_REGION: us-central1
_ORCHESTRATION_TYPE: langgraph
3 changes: 2 additions & 1 deletion llm_demo/orchestrator/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from . import langchain_tools, vertexai_function_calling
from . import langchain_tools, langgraph, vertexai_function_calling
from .orchestrator import BaseOrchestrator, createOrchestrator

__ALL__ = [
"BaseOrchestrator",
"createOrchestrator",
"langchain_tools",
"vertexai_function_calling",
"langgraph",
]
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import os
import uuid
from datetime import datetime
from typing import Any, Dict, List
from typing import Any, Dict, List, Optional

from aiohttp import ClientSession, TCPConnector
from fastapi import HTTPException
Expand Down Expand Up @@ -127,6 +127,13 @@ async def user_session_insert_ticket(self, uuid: str, params: str) -> Any:
response = await user_session.insert_ticket(params)
return response

async def user_session_decline_ticket(self, uuid: str) -> Optional[dict[str, Any]]:
"""
Used if there's a process to be done after user decline ticket.
Return None is nothing is needed to be done.
"""
return None

async def check_and_add_confirmations(self, response: Dict[str, Any]):
for step in response.get("intermediate_steps") or []:
if len(step) > 0:
Expand Down
17 changes: 17 additions & 0 deletions llm_demo/orchestrator/langgraph/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from .langgraph_orchestrator import LangGraphOrchestrator

__ALL__ = ["LangGraphOrchestrator"]
Loading

0 comments on commit 8cefed0

Please sign in to comment.