Skip to content

Commit 6eb7102

Browse files
authored
Add Treasure Hunt (#262)
* Add Treasure Hunt * Update README.md Signed-off-by: Atulpriya Sharma <[email protected]> * Update requirements.txt Signed-off-by: Atulpriya Sharma <[email protected]> * Updated code for randomizing names * Adding a dockerfile * Adding GPTScript logo * Updated debug flag with env variable. Signed-off-by: Atulpriya Sharma <[email protected]> * Added debug env variable Signed-off-by: Atulpriya Sharma <[email protected]> * Added link to gptscript logo. Signed-off-by: Atulpriya Sharma <[email protected]> * Updating debug flag to True. Signed-off-by: Atulpriya Sharma <[email protected]> * Updating Debug flag to false Signed-off-by: Atulpriya Sharma <[email protected]> --------- Signed-off-by: Atulpriya Sharma <[email protected]>
1 parent 22f30ad commit 6eb7102

File tree

10 files changed

+296
-0
lines changed

10 files changed

+296
-0
lines changed

examples/treasure-hunt/Dockerfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Use the official Python image as the base image
2+
FROM python:3.9-slim
3+
4+
# Set the working directory
5+
WORKDIR /app
6+
7+
# Copy the requirements file
8+
COPY requirements.txt .
9+
10+
# Install the Python dependencies
11+
RUN pip install --no-cache-dir -r requirements.txt
12+
13+
# Copy the Flask app code
14+
COPY . .
15+
16+
# Expose the port
17+
EXPOSE 5000
18+
19+
# Set the environment variable
20+
ENV FLASK_APP=app.py
21+
ENV FLASK_DEBUG=False # Set this to True/False to enable/disable debugging.
22+
23+
# Run app
24+
CMD ["flask", "run", "--host=0.0.0.0"]

examples/treasure-hunt/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Treasure Hunt
2+
3+
## Overview
4+
5+
This Flask application leverages GPTScript to generate clues for a real world treasure hunt game. The user needs to provide a list of locations within a city and the application will generate fun and interesting clues for them.
6+
7+
## Installation
8+
9+
### Prerequisites
10+
11+
- Python 3.8 or later
12+
- Node.js and npm
13+
- Flask
14+
- Other Python and Node.js dependencies listed in `requirements.txt` and `package.json` respectively.
15+
16+
### Steps
17+
18+
1. Clone the repository:
19+
20+
``` bash
21+
git clone https://github.com/gptscript-ai/gptscript.git
22+
```
23+
24+
2. Navigate to the `examples/treasure-hunt` directory and install the dependencies:
25+
26+
Python:
27+
28+
```bash
29+
pip install -r requirements.txt
30+
```
31+
32+
Node:
33+
34+
```bash
35+
npm install
36+
```
37+
38+
3. Setup `OPENAI_API_KEY` (Eg: `export OPENAI_API_KEY="yourapikey123456"`). You can get your [API key here](https://platform.openai.com/api-keys).
39+
40+
4. Run the Flask application using `flask run` or `python app.py`
41+
42+
## Usage
43+
44+
1. Open your web browser and navigate to `http://127.0.0.1:5000/`.
45+
2. Use the interface to provide a comma-separated list of locations within a city. For eg: Statue of Liberty, Hudson Yards, Central Park, Grand Central Station.
46+
3. The application will generate fun and witty clues for all these locations.

examples/treasure-hunt/app.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from gptscript.command import stream_exec_file
2+
from flask import Flask, render_template, request, jsonify
3+
import os
4+
import uuid
5+
6+
app = Flask(__name__)
7+
8+
# Setting the base directory
9+
base_dir = os.path.dirname(os.path.abspath(__file__))
10+
app.config['PWD'] = base_dir
11+
SCRIPT_PATH = os.path.join(base_dir, 'treasure-hunt.gpt')
12+
13+
def print_output(out, err):
14+
# Error stream has the debug info that is useful to see
15+
for line in err:
16+
print(line)
17+
for line in out:
18+
print(line)
19+
20+
@app.route('/')
21+
def index():
22+
return render_template('index.html')
23+
24+
@app.route('/get-clues', methods=['POST'])
25+
def get_clues():
26+
try:
27+
code = request.json['code']
28+
29+
# Generate a unique request ID
30+
request_id = str(uuid.uuid4())
31+
32+
# Generate an output file name based on the request ID
33+
output_file_name = f"{request_id}_treasure-hunt.md"
34+
output_file_path = os.path.join(app.config['PWD'], output_file_name)
35+
36+
# Execute the script to generate the clues
37+
out, err, wait = stream_exec_file(SCRIPT_PATH, "--locations " + code + " --outputfile "+output_file_name)
38+
print_output(out, err)
39+
wait()
40+
41+
# Read the output file
42+
with open(output_file_path, 'r') as output_file:
43+
summary = output_file.read()
44+
45+
# Return clues
46+
return summary
47+
except Exception as e:
48+
return jsonify({'error': str(e)}), 500
49+
50+
if __name__ == '__main__':
51+
app.run(debug=os.environ.get('FLASK_DEBUG', True), host='0.0.0.0')

examples/treasure-hunt/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"dependencies": {
3+
"marked": "^12.0.1"
4+
}
5+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Flask==2.0.1
2+
gptscript==0.4.1
3+
Werkzeug==2.2.2
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* style.css */
2+
body {
3+
background-color: #f5f5f5;
4+
font-family: 'Roboto', sans-serif;
5+
display: flex;
6+
justify-content: center;
7+
align-items: center;
8+
min-height: 100vh;
9+
}
10+
11+
.container {
12+
max-width: 500px;
13+
width: 60%;
14+
padding: 0 10px;
15+
}
16+
17+
.input, .button {
18+
border-radius: 0 !important;
19+
}
20+
21+
.box {
22+
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
23+
border-radius: 0;
24+
padding: 30px;
25+
}
26+
27+
.markdown-body {
28+
box-sizing: border-box;
29+
background-color: #f5f5f5;
30+
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
31+
border-radius: 0;
32+
padding: 30px;
33+
}
34+
35+
.gpt-logo {
36+
height: 100%;
37+
width: 100%;
38+
display: flex;
39+
align-items: center;
40+
justify-content: center;
41+
}
42+
43+
.gpt-logo img {
44+
width: 15%;
45+
height: 15%;
46+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// app.js
2+
new Vue({
3+
el: '#app',
4+
data: {
5+
code: '',
6+
showClues: false,
7+
cluesMarkdown: '',
8+
renderedMarkdown: '',
9+
isLoading: false
10+
},
11+
methods: {
12+
getClues() {
13+
this.isLoading = true;
14+
axios.post('/get-clues', { code: this.code })
15+
.then(response => {
16+
this.cluesMarkdown = response.data;
17+
this.renderedMarkdown = marked.parse(this.cluesMarkdown)
18+
this.showClues = true;
19+
})
20+
.catch(error => {
21+
if (error.response && error.response.data && error.response.data.error) {
22+
alert('Error: ' + error.response.data.error);
23+
} else {
24+
alert('An unexpected error occurred. Please try again later.');
25+
}
26+
})
27+
.finally(() => {
28+
this.isLoading = false;
29+
});
30+
}
31+
}
32+
});
33+
34+
// Initialize the marked library
35+
marked.setOptions({
36+
renderer: new marked.Renderer(),
37+
highlight: function(code, language) {
38+
const hljs = require('highlight.js');
39+
const validLanguage = hljs.getLanguage(language) ? language : 'plaintext';
40+
return hljs.highlight(validLanguage, code).value;
41+
},
42+
pedantic: false,
43+
gfm: true,
44+
breaks: false,
45+
sanitize: false,
46+
smartLists: true,
47+
smartypants: false,
48+
xhtml: false
49+
});
50+
Loading
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<!-- index.html -->
2+
<!DOCTYPE html>
3+
<html>
4+
<head>
5+
<title>Treasure Hunt</title>
6+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css">
7+
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
8+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.1.0/github-markdown.min.css">
9+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
10+
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
11+
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
12+
</head>
13+
<body>
14+
<div id="app" class="container is-fluid">
15+
<section class="hero is-primary is-medium is-bold" style="background-image: linear-gradient(to right, #140aa2, #b91b0d);">
16+
<div class="hero-body">
17+
<h1 class="title">Treasure Hunt</h1>
18+
<h2 class="subtitle">How about a real treasure hunt experience? Enter locations for which you want the clues and get hunting!</h2>
19+
</div>
20+
</section>
21+
22+
<div class="box">
23+
<div class="field">
24+
<label class="label">Locations</label>
25+
<div class="control">
26+
<input class="input is-focused" type="text" placeholder="Central Park, Hudson Yards, Times Square..." v-model="code">
27+
</div>
28+
</div>
29+
<button class="button is-primary is-medium" style="background-color: #140aa2;" @click="getClues" :disabled="isLoading">
30+
<span v-if="isLoading" class="icon is-medium">
31+
<i class="fas fa-spinner fa-spin"></i>
32+
</span>
33+
<span v-else>Get Clues</span>
34+
</button>
35+
</div>
36+
37+
<div class="box markdown-body" v-if="showClues" v-html="renderedMarkdown"></div>
38+
<div class="gpt-logo"><a href="https://gptscript.ai" target="_blank"><img src="{{url_for('static', filename='made-with-gptscript.png')}}"/></a></div>
39+
</div>
40+
41+
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
42+
<script defer src="https://use.fontawesome.com/releases/v5.15.4/js/all.js"></script>
43+
</body>
44+
</html>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
tools: sys.find, sys.read, sys.write, search
2+
args: locations: List of locations
3+
args: outputfile: Name of the output file.
4+
5+
You are an expert in generating treasure hunt clues. You have to create a list of clues for an amazing race-type game in which people go on a scavenger hunt across a city, hopping from one spot to the other.
6+
7+
Do the following things in order without showing, using, or writing the location provided by the user:
8+
9+
1. Generate a clue in the format "Your next location is a/the..." without including the location's name or address. Try to use interesting trivia, facts, historical information, noteworthy personalities, or events that took place at that location.
10+
2. For the first clue, start with "Your journey starts with/Your first location is..."
11+
3. Be witty or funny when you give a clue, and ensure it has at least three hints for every location to help the user.
12+
4. The clue should also lead the user to the next location, with fun trivia, suggested modes of transport, and the distance.
13+
5. For the last clue, mention that it's the final one and that the user will find their final reward here.
14+
6. Do not show, write, or display the name of the specific location or the word "clue" anywhere in the output.
15+
7. Create a new md file named $(outputfile) with all the clues in order of the locations provided, along with a short welcome note to the player welcoming them to the city. Mention the name of the city where these locations are before listing the clues.
16+
8. Beautify the md file neatly with logical line breaks, paragraphs, bold, and italics. For each clue, use a bold subheading with a witty one-liner related to that clue without mentioning the location.
17+
18+
19+
---
20+
name: search
21+
description: Searches the internet for content
22+
args: query: The query to search for
23+
tools: sys.http.html2text?
24+
25+
1. For each of the location in $(locations), open Google Maps at the URL: "https://www.google.com/maps/search/?api=1&query=${locations}".
26+
2. Find the shortest route between the locations provided based on the order of places provided.
27+
3. Return the best mode of transport to reach from one location to another for each location in the order provided.

0 commit comments

Comments
 (0)