Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"fastapi",
"deploy-langserve-to-aws",
"rag-qa-bot-llama3",
"rag-qa-bot-with-web"
"rag-qa-bot-with-web",
"simpleaichat-example"
]
}
2 changes: 2 additions & 0 deletions examples/simpleaichat-example/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
OPENAI_API_KEY=<replace-with-your-openai-api-key>
CHAT_API_URL=https://api.openai.com/v1/chat/completions
37 changes: 37 additions & 0 deletions examples/simpleaichat-example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# vscode
.vscode/

# dependencies
node_modules
.pnp
.pnp.js

# testing
coverage

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# turbo
.turbo

# vercel
.vercel

# compilation result
**/dist/

# pluto
.pluto/**/state/
.pluto/*.test.*/
7 changes: 7 additions & 0 deletions examples/simpleaichat-example/.pluto/pluto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
current: aws
language: python
stacks:
- configs: {}
name: aws
platformType: AWS
provisionType: Pulumi
3 changes: 3 additions & 0 deletions examples/simpleaichat-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# A Pluto Application

https://asciinema.org/a/PjekPNsKI0vv0u2Q0RaYeTWsC
104 changes: 104 additions & 0 deletions examples/simpleaichat-example/app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import os
import json

from simpleaichat import AIChat
from simpleaichat.utils import wikipedia_search, wikipedia_search_lookup

from pluto_client import Router, HttpRequest, HttpResponse, Bucket


router = Router("router")
sessions = Bucket("sessions")

basic_args = {
"console": False,
"api_key": os.environ.get("OPENAI_API_KEY"),
"api_url": os.environ.get("CHAT_API_URL"),
}


def chat_handler(req: HttpRequest) -> HttpResponse:
"""Chat in a session with the AI using simpleaichat."""
session_id = req.query.get("session_id")
query = req.query.get("query")
if session_id is None or query is None:
return HttpResponse(
status_code=400,
body=json.dumps({"error": "session_id and query are required."}),
)

ai = AIChat(**basic_args)

# Load the session from bucket if it exists
ai_chat_sess_id = None
output_path = f"/tmp/${session_id}.json"
try:
sessions.get(session_id, output_path)
ai.load_session(input_path=output_path, **basic_args)
with open(output_path, "r") as f:
ai_chat_sess_id = json.load(f)["id"]
except Exception:
ai_chat_sess_id = ai.default_session.id
pass

response = ai(query, id=ai_chat_sess_id)

# Save the session to the bucket
ai.save_session(
output_path=output_path,
format="json",
minify=True,
id=ai_chat_sess_id,
)
sessions.put(session_id, output_path)

return HttpResponse(status_code=200, body=json.dumps(response))


def qa_handler(req: HttpRequest) -> HttpResponse:
"""Ask a question to the AI using simpleaichat."""
query = req.query.get("query")
if query is None:
return HttpResponse(
status_code=400,
body=json.dumps({"error": "query is required."}),
)

ai = AIChat(**basic_args)
response = ai(query)
return HttpResponse(status_code=200, body=json.dumps(response))


# This uses the Wikipedia Search API.
# Results from it are nondeterministic, your mileage will vary.
def search(query):
"""Search the internet."""
wiki_matches = wikipedia_search(query, n=3)
return {"context": ", ".join(wiki_matches), "titles": wiki_matches}


def lookup(query):
"""Lookup more information about a topic."""
page = wikipedia_search_lookup(query, sentences=3)
return page


def wikipedia_handler(req: HttpRequest) -> HttpResponse:
"""Get information from Wikipedia using simpleaichat."""
query = req.query.get("query")
if query is None:
return HttpResponse(
status_code=400,
body=json.dumps({"error": "query is required."}),
)

params = {"temperature": 0.0, "max_tokens": 100}
ai = AIChat(params=params, **basic_args)
response = ai(query, tools=[search, lookup])
return HttpResponse(status_code=200, body=json.dumps(response))


# Define routes for the ApiGateway
router.get("/chat", chat_handler)
router.get("/qa", qa_handler)
router.get("/wikipedia", wikipedia_handler)
76 changes: 76 additions & 0 deletions examples/simpleaichat-example/demo.cast
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{"version": 2, "width": 161, "height": 34, "timestamp": 1716350814, "env": {"SHELL": "/bin/bash", "TERM": "xterm"}}
[1.674221, "o", "\u001b]0;admin@egumomng-0-006000117109:~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u0007"]
[1.675091, "o", "\r\r\n\u001b[1;37m[\u001b[m\u001b[1;32madmin\u001b[m\u001b[1;33m@\u001b[m\u001b[1;35megumomng-0-006000117109\u001b[m \u001b[4m~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u001b[m\u001b[1;37m]\u001b[m\u001b[1;36m\u001b[m\r\r\n$"]
[2.234862, "o", "p"]
[2.404695, "o", "l"]
[2.554805, "o", "u"]
[2.679612, "o", "t"]
[2.737914, "o", "o"]
[2.869536, "o", " "]
[3.020949, "o", "d"]
[3.161149, "o", "e"]
[3.259531, "o", "p"]
[3.400547, "o", "l"]
[3.534976, "o", "o"]
[3.686663, "o", "y"]
[4.207589, "o", "\r\n"]
[4.534471, "o", "\u001b[34mInfo: \u001b[39m Generating reference architecture...\r\n"]
[6.541664, "o", "Bundling dependencies, this may take a while...\r\n"]
[7.792584, "o", "╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\r\n║ Architecture Entities ║\r\n╟───────────────────────────────────────────────────────────┬──────────┬─────────────────────────┬─────────────╢\r\n║ ID │ Name │ Resource Type │ Entity Type ║\r\n╟───────────────────────────────────────────────────────────┼──────────┼─────────────────────────┼─────────────╢\r\n║ simpleaichat_example_aws__plutolang_pluto_Router_router │ router │ @plutolang/pluto.Router │ Resource ║\r\n║ simpleaichat_example_aws__plutolang_pluto_Bucket_sessions │ sessions │ @plutolang/pluto.Bucket │ Resource ║\r\n╟───────────────────────────────────────────────────────────┼──────────┼─────────────────────────┼─────────────╢\r\n║ router_0_get_1_fn │ - │ - │ Closure ║\r\n║ router_1_get_1_fn │ - │ - │ Closure ║\r\n║ router_2_get_1_fn │ - │ - │ Closure ║\r\n╚═══════════════════════════════════════════════════════════╧══════════╧═════════════════════════╧═════════════╝\r\n\r\n"]
[7.796776, "o", "╔═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗\r\n║ Entity Relationships ║\r\n╟─────────────────────────────────────────────────────────┬───────────────────────────────────────────────────────────┬───────────────────┬───────────╢\r\n║ Source Entity ID │ Target Entity ID │ Relationship Type │ Operation ║\r\n╟─────────────────────────────────────────────────────────┼───────────────────────────────────────────────────────────┼───────────────────┼───────────╢\r\n║ simpleaichat_example_aws__plutolang_pluto_Router_router │ router_0_get_1_fn │ Create │ get ║\r\n║ simpleaichat_example_aws__plutolang_pluto_Router_router │ router_1_get_1_fn │ Create │ get ║\r\n║ simpleaichat_example_aws__plutolang_pluto_Router_router │ router_2_get_1_fn │ Create │ get ║\r\n║ router_0_get_1_fn │ simpleaichat_example_aws__plutolang_pluto_Bucket_sessions │ MethodCall │ get ║\r\n║ router_0_get_1_fn │ simpleaichat_example_aws__plutolang_pluto_Bucket_sessions │ MethodCall │ put ║\r\n╚═════════════════════════════════════════════════════════╧═══════════════════════════════════════════════════════════╧═══════════════════╧═══════════╝\r\n\r\n"]
[7.803189, "o", "\u001b[32m?\u001b[39m \u001b[1mDoes this reference architecture satisfy the design of your application?\u001b[22m\u001b[2m (Y/n)\u001b[22m\u001b[82G"]
[8.930925, "o", "\u001b[2K\u001b[G"]
[8.931244, "o", "\u001b[32m?\u001b[39m \u001b[1mDoes this reference architecture satisfy the design of your application?\u001b[22m\u001b[2m (Y/n)\u001b[22m Y\u001b[83G"]
[9.744059, "o", "\u001b[2K\u001b[G"]
[9.744415, "o", "\u001b[32m?\u001b[39m \u001b[1mDoes this reference architecture satisfy the design of your application?\u001b[22m \u001b[36myes\u001b[39m\u001b[79G"]
[9.745027, "o", "\r\n"]
[9.745142, "o", "\u001b[?25h"]
[9.746067, "o", "\u001b[34mInfo: \u001b[39m Generating the IaC Code and computing modules...\r\n"]
[10.362047, "o", "\u001b[34mInfo: \u001b[39m Applying...\r\n"]
[13.079646, "o", " "]
[14.17864, "o", "\b \b"]
[30.307129, "o", " "]
[31.606592, "o", "\b \b"]
[35.546415, "o", "\u001b[34mInfo: \u001b[39m Successfully applied!\r\n"]
[35.546554, "o", "\u001b[34mInfo: \u001b[39m Here are the resource outputs:\r\n"]
[35.546715, "o", "\u001b[34mInfo: \u001b[39m simpleaichat_example_aws__plutolang_pluto_Router_router: https://jinr43521d.execute-api.us-east-1.amazonaws.com/dev\r\n"]
[35.568094, "o", "\u001b]0;admin@egumomng-0-006000117109:~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u0007"]
[35.569003, "o", "\r\r\n\u001b[1;37m[\u001b[m\u001b[1;32madmin\u001b[m\u001b[1;33m@\u001b[m\u001b[1;35megumomng-0-006000117109\u001b[m \u001b[4m~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u001b[m\u001b[1;37m]\u001b[m\u001b[1;36m\u001b[m\r\r\n$"]
[43.017747, "o", "export SESSION_ID=$(uuidgen)"]
[43.376681, "o", "\r\n"]
[43.382193, "o", "\u001b]0;admin@egumomng-0-006000117109:~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u0007"]
[43.38283, "o", "\r\r\n\u001b[1;37m[\u001b[m\u001b[1;32madmin\u001b[m\u001b[1;33m@\u001b[m\u001b[1;35megumomng-0-006000117109\u001b[m \u001b[4m~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u001b[m\u001b[1;37m]\u001b[m\u001b[1;36m\u001b[m\r\r\n$"]
[50.637717, "o", "curl -G https://jinr43521d.execute-api.us-east-1.amazonaws.com/dev/chat \\\r\n"]
[50.63796, "o", "> --data-urlencode 'query=Where is the capital of France?' \\\r\n> "]
[50.638034, "o", "--data-urlencode \"session_id=$SESSION_ID\""]
[50.857375, "o", "\r\n"]
[81.785015, "o", "{\"message\":\"Service Unavailable\"}"]
[81.78753, "o", "\u001b]0;admin@egumomng-0-006000117109:~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u0007"]
[81.789196, "o", "\r\r\n\u001b[1;37m[\u001b[m\u001b[1;32madmin\u001b[m\u001b[1;33m@\u001b[m\u001b[1;35megumomng-0-006000117109\u001b[m \u001b[4m~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u001b[m\u001b[1;37m]\u001b[m\u001b[1;36m\u001b[m\r\r\n$"]
[89.915906, "o", "curl -G https://jinr43521d.execute-api.us-east-1.amazonaws.com/dev/chat --data-urlencode 'query=Where is the capital of France?' --data-urlencode \"session_id=$SE\rESSION_ID\""]
[90.184803, "o", "\r\n"]
[93.775745, "o", "\"The capital of France is Paris. It is known for its iconic landmarks such as the Eiffel Tower, Louvre Museum, and Notre-Dame Cathedral.\""]
[93.779151, "o", "\u001b]0;admin@egumomng-0-006000117109:~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u0007"]
[93.779972, "o", "\r\r\n\u001b[1;37m[\u001b[m\u001b[1;32madmin\u001b[m\u001b[1;33m@\u001b[m\u001b[1;35megumomng-0-006000117109\u001b[m \u001b[4m~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u001b[m\u001b[1;37m]\u001b[m\u001b[1;36m\u001b[m\r\r\n$"]
[95.637691, "o", "curl -G https://jinr43521d.execute-api.us-east-1.amazonaws.com/dev/chat \\\r\n"]
[95.637872, "o", "> "]
[95.637934, "o", "--data-urlencode 'query=What is the most famous food there?' \\\r\n> "]
[95.637979, "o", "--data-urlencode \"session_id=$SESSION_ID\""]
[95.789189, "o", "\r\n"]
[100.97087, "o", "\"One of the most famous foods in Paris, France is the croissant. This buttery and flaky pastry is a staple of French cuisine and is often enjoyed for breakfast or as a snack. Paris is also known for its delicious pastries, cheeses, and fine dining restaurants.\""]
[100.973826, "o", "\u001b]0;admin@egumomng-0-006000117109:~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u0007"]
[100.974475, "o", "\r\r\n\u001b[1;37m[\u001b[m\u001b[1;32madmin\u001b[m\u001b[1;33m@\u001b[m\u001b[1;35megumomng-0-006000117109\u001b[m \u001b[4m~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u001b[m\u001b[1;37m]\u001b[m\u001b[1;36m\u001b[m\r\r\n$"]
[103.311176, "o", "curl -G https://jinr43521d.execute-api.us-east-1.amazonaws.com/dev/qa \\\r\n"]
[103.311418, "o", "> "]
[103.311466, "o", "--data-urlencode 'query=Where is the capital of France?'"]
[103.488492, "o", "\r\n"]
[122.230673, "o", "\"The capital of France is Paris. It is known for its iconic landmarks such as the Eiffel Tower, Louvre Museum, and Notre-Dame Cathedral.\""]
[122.233672, "o", "\u001b]0;admin@egumomng-0-006000117109:~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u0007"]
[122.234284, "o", "\r\r\n\u001b[1;37m[\u001b[m\u001b[1;32madmin\u001b[m\u001b[1;33m@\u001b[m\u001b[1;35megumomng-0-006000117109\u001b[m \u001b[4m~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u001b[m\u001b[1;37m]\u001b[m\u001b[1;36m\u001b[m\r\r\n$"]
[124.843955, "o", "curl -G https://jinr43521d.execute-api.us-east-1.amazonaws.com/dev/wikipedia \\\r\n"]
[124.844165, "o", "> --data-urlencode 'query=San Francisco tourist attractions'"]
[125.022787, "o", "\r\n"]
[145.950725, "o", "{\"context\": \"Tourist attractions in the United States, Fisherman's Wharf, San Francisco, Lombard Street (San Francisco)\", \"titles\": [\"Tourist attractions in the United States\", \"Fisherman's Wharf, San Francisco\", \"Lombard Street (San Francisco)\"], \"tool\": \"search\", \"response\": \"San Francisco is a city known for its diverse attractions. Some popular tourist spots include Fisherman's Wharf, where you can enjoy seafood restaurants, shops, and beautiful views of the bay. Lombard Street, famous for its steep, winding section, offers a unique driving experience and great photo opportunities. These are just a couple of the many attractions that San Francisco has to offer.\"}"]
[145.953329, "o", "\u001b]0;admin@egumomng-0-006000117109:~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u0007"]
[145.954033, "o", "\r\r\n\u001b[1;37m[\u001b[m\u001b[1;32madmin\u001b[m\u001b[1;33m@\u001b[m\u001b[1;35megumomng-0-006000117109\u001b[m \u001b[4m~/zhengshoujian.zsj/pluto-lang/pluto/examples/simpleaichat-example\u001b[m\u001b[1;37m]\u001b[m\u001b[1;36m\u001b[m\r\r\n$"]
[149.867429, "o", "exit\r\n"]
20 changes: 20 additions & 0 deletions examples/simpleaichat-example/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "simpleaichat-example",
"private": true,
"version": "0.0.0",
"scripts": {
"test:dev": "pluto test --sim",
"test:prod": "pluto test",
"deploy": "pluto deploy",
"destroy": "pluto destroy"
},
"dependencies": {},
"devDependencies": {
"@types/node": "^20",
"typescript": "^5.2.2",
"@plutolang/base": "workspace:*",
"@plutolang/pluto-infra": "workspace:*",
"@pulumi/pulumi": "^3.88.0"
},
"main": "dist/index.js"
}
2 changes: 2 additions & 0 deletions examples/simpleaichat-example/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pluto_client
simpleaichat
24 changes: 19 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.