├── promptscript ├── __init__.py ├── ai │ ├── __init__.py │ ├── listen.py │ ├── draw.py │ └── chat.py ├── utils │ ├── __init__.py │ ├── debug_level.py │ ├── numbers.py │ ├── is_valid_file.py │ ├── file.py │ └── config.py ├── __main__.py ├── cli.py ├── executor.py └── interpreter.py ├── test ├── files │ ├── .env.prompt │ ├── read.prompt │ ├── yield.prompt │ ├── parameters.prompt │ ├── show.prompt │ ├── environment.prompt │ ├── conditionals.prompt │ └── loops.prompt └── commands │ ├── test_show.py │ ├── test_assignment.py │ ├── _test_command_base.py │ └── test_math.py ├── docs ├── 404.rst ├── _build │ ├── html │ │ ├── _sources │ │ │ ├── 404.rst.txt │ │ │ ├── basic │ │ │ │ ├── conditionals.rst.txt │ │ │ │ ├── chaining.rst.txt │ │ │ │ ├── show.rst.txt │ │ │ │ ├── loops.rst.txt │ │ │ │ ├── files.rst.txt │ │ │ │ ├── index.rst.txt │ │ │ │ └── load.rst.txt │ │ │ ├── install.rst.txt │ │ │ ├── ai │ │ │ │ ├── listen.rst.txt │ │ │ │ ├── draw.rst.txt │ │ │ │ ├── index.rst.txt │ │ │ │ └── chat.rst.txt │ │ │ ├── running │ │ │ │ ├── index.rst.txt │ │ │ │ ├── cli.rst.txt │ │ │ │ └── python.rst.txt │ │ │ ├── index.rst.txt │ │ │ └── about.rst.txt │ │ ├── objects.inv │ │ ├── _static │ │ │ ├── file.png │ │ │ ├── plus.png │ │ │ ├── favicon.ico │ │ │ ├── minus.png │ │ │ ├── docsearch_config.js │ │ │ ├── alabaster-docsearch-custom.css │ │ │ ├── rtd-docsearch-custom.css │ │ │ ├── language_data.js │ │ │ ├── documentation_options.js │ │ │ ├── pydata-docsearch-custom.css │ │ │ ├── print.css │ │ │ ├── design-tabs.js │ │ │ ├── furo-docsearch-custom.css │ │ │ ├── tabs.css │ │ │ ├── shibuya.js │ │ │ ├── tabs.js │ │ │ ├── doctools.js │ │ │ ├── sphinx_highlight.js │ │ │ └── pygments.css │ │ ├── .buildinfo │ │ ├── _sphinx_design_static │ │ │ └── design-tabs.js │ │ ├── genindex.html │ │ ├── 404.html │ │ ├── install.html │ │ ├── basic │ │ │ ├── chaining.html │ │ │ ├── conditionals.html │ │ │ ├── show.html │ │ │ └── loops.html │ │ └── ai │ │ │ └── listen.html │ └── doctrees │ │ ├── 404.doctree │ │ ├── about.doctree │ │ ├── ai │ │ ├── chat.doctree │ │ ├── draw.doctree │ │ ├── index.doctree │ │ └── listen.doctree │ │ ├── index.doctree │ │ ├── install.doctree │ │ ├── basic │ │ ├── files.doctree │ │ ├── index.doctree │ │ ├── load.doctree │ │ ├── loops.doctree │ │ ├── show.doctree │ │ ├── chaining.doctree │ │ └── conditionals.doctree │ │ ├── environment.pickle │ │ └── running │ │ ├── cli.doctree │ │ ├── index.doctree │ │ └── python.doctree ├── _static │ └── favicon.ico ├── config.env ├── basic │ ├── conditionals.rst │ ├── chaining.rst │ ├── show.rst │ ├── loops.rst │ ├── files.rst │ ├── index.rst │ └── load.rst ├── install.rst ├── Makefile ├── promptscript_lexer.py ├── ai │ ├── listen.rst │ ├── draw.rst │ ├── index.rst │ └── chat.rst ├── running │ ├── index.rst │ ├── cli.rst │ └── python.rst ├── make.bat ├── index.rst ├── conf.py └── about.rst ├── .gitignore ├── requirements.txt ├── .github └── workflows │ └── python-publish.yml ├── LICENSE ├── setup.py └── README.md /promptscript/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /promptscript/ai/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /promptscript/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/files/.env.prompt: -------------------------------------------------------------------------------- 1 | x = 5 2 | y = "hello" -------------------------------------------------------------------------------- /docs/404.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | :layout: 404 3 | 4 | 404 5 | === -------------------------------------------------------------------------------- /docs/_build/html/_sources/404.rst.txt: -------------------------------------------------------------------------------- 1 | :orphan: 2 | :layout: 404 3 | 4 | 404 5 | === -------------------------------------------------------------------------------- /test/files/read.prompt: -------------------------------------------------------------------------------- 1 | text = 'Hello, World!' 2 | save text, "file.txt" 3 | show read "file.txt" 4 | -------------------------------------------------------------------------------- /test/files/yield.prompt: -------------------------------------------------------------------------------- 1 | show "starting yield testing" 2 | 3 | x = 5 4 | y = 3 5 | 6 | yield "x", x -------------------------------------------------------------------------------- /docs/_static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_static/favicon.ico -------------------------------------------------------------------------------- /test/files/parameters.prompt: -------------------------------------------------------------------------------- 1 | # Run this file, passing in 'x' and 'y' as parameters 2 | show "{}, {}!".format(x, y) -------------------------------------------------------------------------------- /test/files/show.prompt: -------------------------------------------------------------------------------- 1 | SHOW "init" 2 | x = 5 3 | SHOW "Here " + str(x) 4 | x = x + 1 5 | SHOW "New x " + str(x) -------------------------------------------------------------------------------- /docs/_build/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/html/objects.inv -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | __pycache__/ 3 | *.egg-info 4 | *.pyc 5 | 6 | .DS_Store 7 | .cli_history 8 | .promptscript_cli_history -------------------------------------------------------------------------------- /test/files/environment.prompt: -------------------------------------------------------------------------------- 1 | SHOW "environment init" 2 | SHOW LOAD "x" 3 | environment_y = LOAD "y" 4 | SHOW environment_y -------------------------------------------------------------------------------- /docs/_build/doctrees/404.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/404.doctree -------------------------------------------------------------------------------- /docs/_build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/html/_static/file.png -------------------------------------------------------------------------------- /docs/_build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/_build/doctrees/about.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/about.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/ai/chat.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/ai/chat.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/ai/draw.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/ai/draw.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/install.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/install.doctree -------------------------------------------------------------------------------- /docs/_build/html/_static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/html/_static/favicon.ico -------------------------------------------------------------------------------- /docs/_build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/_build/doctrees/ai/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/ai/index.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/ai/listen.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/ai/listen.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/basic/files.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/basic/files.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/basic/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/basic/index.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/basic/load.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/basic/load.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/basic/loops.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/basic/loops.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/basic/show.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/basic/show.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/_build/doctrees/running/cli.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/running/cli.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/basic/chaining.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/basic/chaining.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/running/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/running/index.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/running/python.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/running/python.doctree -------------------------------------------------------------------------------- /docs/_build/doctrees/basic/conditionals.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zainmfjavaid/PromptScript/HEAD/docs/_build/doctrees/basic/conditionals.doctree -------------------------------------------------------------------------------- /docs/config.env: -------------------------------------------------------------------------------- 1 | USE_DOCSEARCH=true 2 | DOCSEARCH_APP_ID=MY0HAVZAE7 3 | DOCSEARCH_API_KEY=bb77df2e061d7f2f69e8523351fcf42c 4 | DOCSEARCH_INDEX_NAME=promptscript -------------------------------------------------------------------------------- /test/files/conditionals.prompt: -------------------------------------------------------------------------------- 1 | x = 5 2 | 3 | IF x > 5: 4 | SHOW "x is greater than 5" 5 | ELIF x < 5: 6 | SHOW "x is less than 5" 7 | ELSE: 8 | SHOW "x is equal to 5" -------------------------------------------------------------------------------- /docs/_build/html/_static/docsearch_config.js: -------------------------------------------------------------------------------- 1 | docsearch({ 2 | container: "#docsearch", 3 | appId: "MY0HAVZAE7", 4 | apiKey: "bb77df2e061d7f2f69e8523351fcf42c", 5 | indexName: "promptscript", 6 | }); -------------------------------------------------------------------------------- /docs/_build/html/_static/alabaster-docsearch-custom.css: -------------------------------------------------------------------------------- 1 | .DocSearch-Button { 2 | margin: 0; 3 | border-radius: 0; 4 | width: 100%; 5 | border: 1px solid var(--color-sidebar-background-border); 6 | } 7 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | openai==1.35.1 2 | Pygments==2.8.1 3 | shibuya==2024.6.23 4 | sphinx-tabs==3.4.5 5 | sphinx_design==0.5.0 6 | twine==5.1.1 7 | anthropic==0.30.0 8 | sphinx-docsearch==0.0.7 9 | python-dotenv==1.0.1 -------------------------------------------------------------------------------- /promptscript/utils/debug_level.py: -------------------------------------------------------------------------------- 1 | from dataclasses import dataclass 2 | 3 | 4 | @dataclass 5 | class DebugLevel: 6 | DEBUG: int = 100 7 | INFO: int = 200 8 | WARNING: int = 300 9 | ERROR: int = 400 -------------------------------------------------------------------------------- /test/commands/test_show.py: -------------------------------------------------------------------------------- 1 | from _test_command_base import run_command 2 | 3 | 4 | assert run_command('SHOW "Hello, World!"').stdout.strip('\n') == 'Hello, World!' 5 | assert run_command('SHOW 5').stdout.strip('\n') == '5' -------------------------------------------------------------------------------- /docs/_build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: 412644a37ee35add8406e35d93237323 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /docs/_build/html/_static/rtd-docsearch-custom.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --docsearch-primary-color: #2980b9; 3 | } 4 | 5 | input[type="search"] { 6 | border: none; 7 | box-shadow: none; 8 | font-size: unset; 9 | } 10 | 11 | .DocSearch-Button { 12 | width: 90%; 13 | } 14 | -------------------------------------------------------------------------------- /test/commands/test_assignment.py: -------------------------------------------------------------------------------- 1 | from _test_command_base import run_environment_command 2 | 3 | 4 | assert run_environment_command('x = 5')['x'] == 5 5 | assert run_environment_command('x = "Hello, World!"')['x'] == 'Hello, World!' 6 | assert run_environment_command('x = 0.01')['x'] == 0.01 -------------------------------------------------------------------------------- /promptscript/__main__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from promptscript.cli import run_cli 3 | from promptscript.executor import FileExecutor 4 | 5 | def main(): 6 | if len(sys.argv) == 1: 7 | run_cli() 8 | else: 9 | FileExecutor().run(sys.argv[1], **dict(arg.split('=') for arg in sys.argv[2:])) 10 | 11 | if __name__ == '__main__': 12 | main() -------------------------------------------------------------------------------- /promptscript/utils/numbers.py: -------------------------------------------------------------------------------- 1 | def is_number(string: str) -> bool: 2 | is_dot = False 3 | for character in string: 4 | if character == '.': 5 | if is_dot: 6 | return False 7 | else: 8 | is_dot = True 9 | elif not character.isdigit(): 10 | return False 11 | return True -------------------------------------------------------------------------------- /test/files/loops.prompt: -------------------------------------------------------------------------------- 1 | for i in range(5): 2 | show i 3 | 4 | 5 | show "done with first for loop, starting second" 6 | 7 | for j in range(1, 10): 8 | show j 9 | 10 | show "done with second for loop, starting third" 11 | 12 | for k in range(1, len("four")): 13 | show k 14 | 15 | show "done with for loops, starting while loop" 16 | 17 | x = 5 18 | while x != 0: 19 | show x 20 | x -= 1 -------------------------------------------------------------------------------- /docs/_build/html/_static/language_data.js: -------------------------------------------------------------------------------- 1 | /* 2 | * language_data.js 3 | * ~~~~~~~~~~~~~~~~ 4 | * 5 | * This script contains the language-specific data used by searchtools.js, 6 | * namely the list of stopwords, stemmer, scorer and splitter. 7 | * 8 | * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. 9 | * :license: BSD, see LICENSE for details. 10 | * 11 | */ 12 | 13 | var stopwords = ; 14 | 15 | -------------------------------------------------------------------------------- /promptscript/utils/is_valid_file.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | ### Valid extensions for promptscript 4 | # .../file.prompt 5 | # OR 6 | # .../file 7 | ### 8 | 9 | def is_promptscript_file(file_path: str) -> bool: 10 | path_components = file_path.split('/') 11 | file_name = (path_components[0] if len(path_components) == 1 else path_components[-1]) 12 | 13 | if (file_name.endswith('.prompt') or '.' not in file_name) and os.path.exists(file_path): 14 | return True 15 | return False -------------------------------------------------------------------------------- /docs/_build/html/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '0.3.0', 4 | LANGUAGE: 'en', 5 | COLLAPSE_INDEX: false, 6 | BUILDER: 'html', 7 | FILE_SUFFIX: '.html', 8 | LINK_SUFFIX: '.html', 9 | HAS_SOURCE: true, 10 | SOURCELINK_SUFFIX: '.txt', 11 | NAVIGATION_WITH_KEYS: false, 12 | SHOW_SEARCH_SUMMARY: true, 13 | ENABLE_SEARCH_SHORTCUTS: true, 14 | }; -------------------------------------------------------------------------------- /docs/_build/html/_static/pydata-docsearch-custom.css: -------------------------------------------------------------------------------- 1 | .DocSearch-Container { 2 | z-index: 1050; 3 | } 4 | 5 | .search-button__wrapper.show .search-button__overlay, 6 | .search-button__wrapper.show .search-button__search-container { 7 | display: none; 8 | } 9 | 10 | .DocSearch-Hits mark { 11 | padding: 0; 12 | } 13 | 14 | kbd:not(.compound) { 15 | padding: 0rem 0rem; 16 | } 17 | 18 | kbd.DocSearch-Commands-Key { 19 | border: 0; 20 | box-shadow: var(--docsearch-key-shadow); 21 | margin: 1px 5px 1px 0px; 22 | padding: inherit; 23 | } 24 | -------------------------------------------------------------------------------- /docs/basic/conditionals.rst: -------------------------------------------------------------------------------- 1 | :description: How to write conditionals in PromptScript 2 | 3 | Conditionals 4 | ============ 5 | 6 | .. rst-class:: lead 7 | 8 | Using conditionals in PromptScript. 9 | 10 | ---- 11 | 12 | Conditionals in PromptScript function the same as in python: 13 | 14 | .. code-block:: promptscript 15 | :linenos: 16 | 17 | number = 8 18 | guess = 5 19 | 20 | if guess > number: 21 | show "your guess is too high." 22 | elif guess < number: 23 | show "your guess is too low." 24 | else: 25 | show "you guessed correctly!" -------------------------------------------------------------------------------- /docs/_build/html/_sources/basic/conditionals.rst.txt: -------------------------------------------------------------------------------- 1 | :description: How to write conditionals in PromptScript 2 | 3 | Conditionals 4 | ============ 5 | 6 | .. rst-class:: lead 7 | 8 | Using conditionals in PromptScript. 9 | 10 | ---- 11 | 12 | Conditionals in PromptScript function the same as in python: 13 | 14 | .. code-block:: promptscript 15 | :linenos: 16 | 17 | number = 8 18 | guess = 5 19 | 20 | if guess > number: 21 | show "your guess is too high." 22 | elif guess < number: 23 | show "your guess is too low." 24 | else: 25 | show "you guessed correctly!" -------------------------------------------------------------------------------- /docs/install.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | .. rst-class:: lead 5 | 6 | Install the PromptScript language and Python package. 7 | 8 | ---- 9 | 10 | pip install 11 | ----------- 12 | 13 | .. parsed-literal:: 14 | 15 | $ pip install promptscript==\ |release| 16 | 17 | Verifying 18 | --------- 19 | 20 | To make sure PromptScript was installed correctly, you can run: 21 | 22 | .. code-block:: shell 23 | 24 | promptscript 25 | 26 | Or: 27 | 28 | .. code-block:: shell 29 | 30 | python -m promptscript 31 | 32 | If the installation was successful, running these commands should bring up the PromptScript CLI. -------------------------------------------------------------------------------- /docs/_build/html/_sources/install.rst.txt: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | .. rst-class:: lead 5 | 6 | Install the PromptScript language and Python package. 7 | 8 | ---- 9 | 10 | pip install 11 | ----------- 12 | 13 | .. parsed-literal:: 14 | 15 | $ pip install promptscript==\ |release| 16 | 17 | Verifying 18 | --------- 19 | 20 | To make sure PromptScript was installed correctly, you can run: 21 | 22 | .. code-block:: shell 23 | 24 | promptscript 25 | 26 | Or: 27 | 28 | .. code-block:: shell 29 | 30 | python -m promptscript 31 | 32 | If the installation was successful, running these commands should bring up the PromptScript CLI. -------------------------------------------------------------------------------- /docs/basic/chaining.rst: -------------------------------------------------------------------------------- 1 | :description: How to read chain together commands in PromptScript? 2 | 3 | Chaining 4 | ======== 5 | 6 | .. rst-class:: lead 7 | 8 | Chaning multiple PromptScript commands together. 9 | 10 | ---- 11 | 12 | .. _chaining: 13 | 14 | To pass the output of one process as the parameter of another, surround it in square brackets (``[]``). Example: 15 | 16 | .. code-block:: promptscript 17 | 18 | save [chat "", "", ""], "file.txt" 19 | 20 | .. note:: Chaining isn't required for passing the output of one process into a method that only takes one parameter 21 | (e.g. ``show``). It's still recommended for readability. -------------------------------------------------------------------------------- /docs/_build/html/_sources/basic/chaining.rst.txt: -------------------------------------------------------------------------------- 1 | :description: How to read chain together commands in PromptScript? 2 | 3 | Chaining 4 | ======== 5 | 6 | .. rst-class:: lead 7 | 8 | Chaning multiple PromptScript commands together. 9 | 10 | ---- 11 | 12 | .. _chaining: 13 | 14 | To pass the output of one process as the parameter of another, surround it in square brackets (``[]``). Example: 15 | 16 | .. code-block:: promptscript 17 | 18 | save [chat "", "", ""], "file.txt" 19 | 20 | .. note:: Chaining isn't required for passing the output of one process into a method that only takes one parameter 21 | (e.g. ``show``). It's still recommended for readability. -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/promptscript_lexer.py: -------------------------------------------------------------------------------- 1 | from pygments.lexer import RegexLexer 2 | from pygments.token import Text, Keyword, Name, String, Number, Comment 3 | 4 | class PromptScriptLexer(RegexLexer): 5 | name = 'PromptScript' 6 | aliases = ['promptscript'] 7 | filenames = ['*.prompt'] 8 | 9 | tokens = { 10 | 'root': [ 11 | (r'\b(if|elif|else|for|while|in)\b', Keyword), 12 | (r'\b(show|chat|draw|listen|save|yield|load|read)\b', Name.Builtin), 13 | (r'\b(prompt|model|api_key)\b', Name.Variable), 14 | (r'"[^"\\]*(?:\\.[^"\\]*)*"', String), 15 | (r'\b\d+\b', Number), 16 | (r'#.*', Comment.Single), 17 | (r'.', Text) 18 | ], 19 | } -------------------------------------------------------------------------------- /docs/ai/listen.rst: -------------------------------------------------------------------------------- 1 | Transcription 2 | ============= 3 | 4 | .. rst-class:: lead 5 | 6 | Using ``listen`` to perform speech-to-text tasks 7 | 8 | ---- 9 | 10 | PromptScript currently supports audio transcription using `OpenAI's Whisper `_ 11 | through the ``listen`` keyword. 12 | 13 | Syntax 14 | ------ 15 | 16 | .. code-block:: promptscript 17 | 18 | listen file_path, api_key 19 | 20 | **Parameters** 21 | 22 | **file_path** (str: required): File to transcribe. 23 | 24 | **api_key** (str: required): OpenAI API key. 25 | 26 | **Output** 27 | 28 | **str**: Transcribed text. 29 | 30 | .. note:: The following file formats are supported: ``.mp3``, ``.mp4``, ``.wav``, ``.mpeg``, ``.mpga``, ``.webm`` -------------------------------------------------------------------------------- /docs/_build/html/_sources/ai/listen.rst.txt: -------------------------------------------------------------------------------- 1 | Transcription 2 | ============= 3 | 4 | .. rst-class:: lead 5 | 6 | Using ``listen`` to perform speech-to-text tasks 7 | 8 | ---- 9 | 10 | PromptScript currently supports audio transcription using `OpenAI's Whisper `_ 11 | through the ``listen`` keyword. 12 | 13 | Syntax 14 | ------ 15 | 16 | .. code-block:: promptscript 17 | 18 | listen file_path, api_key 19 | 20 | **Parameters** 21 | 22 | **file_path** (str: required): File to transcribe. 23 | 24 | **api_key** (str: required): OpenAI API key. 25 | 26 | **Output** 27 | 28 | **str**: Transcribed text. 29 | 30 | .. note:: The following file formats are supported: ``.mp3``, ``.mp4``, ``.wav``, ``.mpeg``, ``.mpga``, ``.webm`` -------------------------------------------------------------------------------- /docs/_build/html/_static/print.css: -------------------------------------------------------------------------------- 1 | .sy-head { 2 | position: static; 3 | border-bottom: 1px solid var(--sy-c-divider); 4 | } 5 | 6 | .sy-head-inner { 7 | padding: 0; 8 | } 9 | 10 | .sy-breadcrumbs { 11 | display: none; 12 | } 13 | 14 | h1, h2, h3, h4, h5, h6 { 15 | page-break-inside: avoid; 16 | page-break-after: avoid; 17 | } 18 | 19 | .code-block-caption, 20 | pre, code { 21 | page-break-inside: avoid; 22 | white-space: pre-wrap; 23 | 24 | -webkit-print-color-adjust: exact; 25 | } 26 | 27 | .yue a.headerlink { 28 | display: none; 29 | } 30 | 31 | .highlight .linenos { 32 | box-shadow: none; 33 | } 34 | 35 | .admonition, 36 | .sd-sphinx-override { 37 | -webkit-print-color-adjust: exact; 38 | } 39 | 40 | .sd-card { 41 | page-break-inside: avoid; 42 | } 43 | -------------------------------------------------------------------------------- /docs/running/index.rst: -------------------------------------------------------------------------------- 1 | :description: Guide on running PromptScript embedded in Python. 2 | 3 | Running PromptScript 4 | ============================== 5 | 6 | .. rst-class:: lead 7 | 8 | Using the ``promptscript`` package to run PromptScript embedded in Python. 9 | 10 | ---- 11 | 12 | .. grid:: 1 13 | :gutter: 2 14 | :padding: 0 15 | :class-row: surface 16 | 17 | .. grid-item-card:: :octicon:`terminal` CLI 18 | :link: cli.html 19 | 20 | Run PromptScript files & commands from the terminal. 21 | 22 | .. grid-item-card:: :octicon:`plug` Python 23 | :link: python.html 24 | 25 | Use the ``promptscript`` package to run PromptScript embedded in Python. 26 | 27 | .. toctree:: 28 | :hidden: 29 | 30 | cli 31 | python -------------------------------------------------------------------------------- /docs/basic/show.rst: -------------------------------------------------------------------------------- 1 | :description: How to print in PromptScript 2 | 3 | Printing 4 | ======== 5 | 6 | .. rst-class:: lead 7 | 8 | Using ``show`` to print values in PromptScript. 9 | 10 | ---- 11 | 12 | .. code-block:: promptscript 13 | :linenos: 14 | 15 | show "Hello, World!" 16 | show "{} - {}".format("Slot 1", "Slot 2") 17 | 18 | .. note:: Strings can also be created with single quotes 19 | 20 | You can also print variables: 21 | 22 | .. code-block:: promptscript 23 | 24 | message = "Hello, World!" 25 | show message 26 | 27 | Or the output from another process: 28 | 29 | .. code-block:: promptscript 30 | 31 | show [read "file.txt"] 32 | 33 | .. tip:: The square brackets (``[]``) are for chaining. Learn more about :ref:`operation chaining ` here. -------------------------------------------------------------------------------- /docs/_build/html/_sources/running/index.rst.txt: -------------------------------------------------------------------------------- 1 | :description: Guide on running PromptScript embedded in Python. 2 | 3 | Running PromptScript 4 | ============================== 5 | 6 | .. rst-class:: lead 7 | 8 | Using the ``promptscript`` package to run PromptScript embedded in Python. 9 | 10 | ---- 11 | 12 | .. grid:: 1 13 | :gutter: 2 14 | :padding: 0 15 | :class-row: surface 16 | 17 | .. grid-item-card:: :octicon:`terminal` CLI 18 | :link: cli.html 19 | 20 | Run PromptScript files & commands from the terminal. 21 | 22 | .. grid-item-card:: :octicon:`plug` Python 23 | :link: python.html 24 | 25 | Use the ``promptscript`` package to run PromptScript embedded in Python. 26 | 27 | .. toctree:: 28 | :hidden: 29 | 30 | cli 31 | python -------------------------------------------------------------------------------- /docs/_build/html/_sources/basic/show.rst.txt: -------------------------------------------------------------------------------- 1 | :description: How to print in PromptScript 2 | 3 | Printing 4 | ======== 5 | 6 | .. rst-class:: lead 7 | 8 | Using ``show`` to print values in PromptScript. 9 | 10 | ---- 11 | 12 | .. code-block:: promptscript 13 | :linenos: 14 | 15 | show "Hello, World!" 16 | show "{} - {}".format("Slot 1", "Slot 2") 17 | 18 | .. note:: Strings can also be created with single quotes 19 | 20 | You can also print variables: 21 | 22 | .. code-block:: promptscript 23 | 24 | message = "Hello, World!" 25 | show message 26 | 27 | Or the output from another process: 28 | 29 | .. code-block:: promptscript 30 | 31 | show [read "file.txt"] 32 | 33 | .. tip:: The square brackets (``[]``) are for chaining. Learn more about :ref:`operation chaining ` here. -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | name: Upload Python Package 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | deploy: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Set up Python 18 | uses: actions/setup-python@v3 19 | with: 20 | python-version: '3.x' 21 | - name: Install dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | pip install build 25 | - name: Build package 26 | run: python -m build 27 | - name: Publish package 28 | uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 29 | with: 30 | user: __token__ 31 | password: ${{ secrets.PYPI_API_TOKEN }} 32 | -------------------------------------------------------------------------------- /test/commands/_test_command_base.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import subprocess 4 | from typing import List 5 | 6 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '../../promptscript'))) 7 | 8 | from interpreter import interpret 9 | 10 | 11 | def run_command(command: str) -> subprocess.CompletedProcess: 12 | interpreted_command = interpret(command) 13 | subprocess_command = ['python', '-c', interpreted_command] 14 | output = subprocess.run(subprocess_command, capture_output=True, text=True) 15 | 16 | return output 17 | 18 | def run_environment_command(command: str) -> subprocess.CompletedProcess: 19 | interpreted_command = interpret(command) 20 | local_scope = {} 21 | 22 | exec(interpreted_command, globals(), local_scope) 23 | return local_scope -------------------------------------------------------------------------------- /docs/basic/loops.rst: -------------------------------------------------------------------------------- 1 | :description: How to use loops in PromptScript 2 | 3 | Loops 4 | ===== 5 | 6 | .. rst-class:: lead 7 | 8 | Writing ``for`` and ``while`` loops in PromptScript. 9 | 10 | ---- 11 | 12 | Loops in PromptScript function the same as in Python: 13 | 14 | For Loops 15 | --------- 16 | 17 | .. code-block:: promptscript 18 | 19 | for i in range(1, 11): 20 | show i 21 | 22 | You can also use ``len``: 23 | 24 | .. code-block:: promptscript 25 | 26 | string = "word" 27 | for i in range(len(string)): 28 | show i 29 | 30 | Or iterate through values: 31 | 32 | .. code-block:: promptscript 33 | 34 | string = "word" 35 | for character in string: 36 | show character 37 | 38 | While Loops 39 | ----------- 40 | 41 | .. code-block:: promptscript 42 | 43 | x = 10 44 | while x > 0: 45 | show x 46 | x -= 1 -------------------------------------------------------------------------------- /docs/_build/html/_sources/basic/loops.rst.txt: -------------------------------------------------------------------------------- 1 | :description: How to use loops in PromptScript 2 | 3 | Loops 4 | ===== 5 | 6 | .. rst-class:: lead 7 | 8 | Writing ``for`` and ``while`` loops in PromptScript. 9 | 10 | ---- 11 | 12 | Loops in PromptScript function the same as in Python: 13 | 14 | For Loops 15 | --------- 16 | 17 | .. code-block:: promptscript 18 | 19 | for i in range(1, 11): 20 | show i 21 | 22 | You can also use ``len``: 23 | 24 | .. code-block:: promptscript 25 | 26 | string = "word" 27 | for i in range(len(string)): 28 | show i 29 | 30 | Or iterate through values: 31 | 32 | .. code-block:: promptscript 33 | 34 | string = "word" 35 | for character in string: 36 | show character 37 | 38 | While Loops 39 | ----------- 40 | 41 | .. code-block:: promptscript 42 | 43 | x = 10 44 | while x > 0: 45 | show x 46 | x -= 1 -------------------------------------------------------------------------------- /docs/_build/html/_static/design-tabs.js: -------------------------------------------------------------------------------- 1 | var sd_labels_by_text = {}; 2 | 3 | function ready() { 4 | const li = document.getElementsByClassName("sd-tab-label"); 5 | for (const label of li) { 6 | syncId = label.getAttribute("data-sync-id"); 7 | if (syncId) { 8 | label.onclick = onLabelClick; 9 | if (!sd_labels_by_text[syncId]) { 10 | sd_labels_by_text[syncId] = []; 11 | } 12 | sd_labels_by_text[syncId].push(label); 13 | } 14 | } 15 | } 16 | 17 | function onLabelClick() { 18 | // Activate other inputs with the same sync id. 19 | syncId = this.getAttribute("data-sync-id"); 20 | for (label of sd_labels_by_text[syncId]) { 21 | if (label === this) continue; 22 | label.previousElementSibling.checked = true; 23 | } 24 | window.localStorage.setItem("sphinx-design-last-tab", syncId); 25 | } 26 | 27 | document.addEventListener("DOMContentLoaded", ready, false); 28 | -------------------------------------------------------------------------------- /docs/_build/html/_sphinx_design_static/design-tabs.js: -------------------------------------------------------------------------------- 1 | var sd_labels_by_text = {}; 2 | 3 | function ready() { 4 | const li = document.getElementsByClassName("sd-tab-label"); 5 | for (const label of li) { 6 | syncId = label.getAttribute("data-sync-id"); 7 | if (syncId) { 8 | label.onclick = onLabelClick; 9 | if (!sd_labels_by_text[syncId]) { 10 | sd_labels_by_text[syncId] = []; 11 | } 12 | sd_labels_by_text[syncId].push(label); 13 | } 14 | } 15 | } 16 | 17 | function onLabelClick() { 18 | // Activate other inputs with the same sync id. 19 | syncId = this.getAttribute("data-sync-id"); 20 | for (label of sd_labels_by_text[syncId]) { 21 | if (label === this) continue; 22 | label.previousElementSibling.checked = true; 23 | } 24 | window.localStorage.setItem("sphinx-design-last-tab", syncId); 25 | } 26 | 27 | document.addEventListener("DOMContentLoaded", ready, false); 28 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/ai/draw.rst: -------------------------------------------------------------------------------- 1 | Image Generation 2 | ================ 3 | 4 | .. rst-class:: lead 5 | 6 | Using ``draw`` to generate and edit images 7 | 8 | ---- 9 | 10 | PromptScript supports image generation through the ``draw`` keyword. 11 | 12 | Syntax 13 | ------ 14 | 15 | .. code-block:: promptscript 16 | 17 | draw prompt, model, api_key, destination_file 18 | 19 | **Parameters** 20 | 21 | **prompt** (str: required): Prompt to generate image based on. 22 | 23 | **model** (str: required): The model to use for image generation. 24 | 25 | **api_key** (str: required): API key for the image generation service. 26 | 27 | **destination_file** (str: required): File path to save generated image to. 28 | 29 | **Output** 30 | 31 | **None** (output saved to destination_file). 32 | 33 | Supported Models 34 | ---------------- 35 | 36 | .. tabs:: 37 | 38 | .. tab:: OpenAI 39 | 40 | ``dall-e-3``, ``dall-e-2`` 41 | 42 | .. tab:: Stability AI 43 | 44 | ``ultra``, ``core``, ``sd3`` -------------------------------------------------------------------------------- /docs/ai/index.rst: -------------------------------------------------------------------------------- 1 | :description: Guide on using PromptScript to interact with AI. 2 | 3 | AI 4 | == 5 | 6 | .. rst-class:: lead 7 | 8 | Using PromptScript to interact with LLMs, image generation models, and transcription. 9 | 10 | ---- 11 | 12 | Supported Tasks: 13 | ---------------- 14 | 15 | .. grid:: 1 1 3 3 16 | :gutter: 2 17 | :padding: 0 18 | :class-row: surface 19 | 20 | .. grid-item-card:: :octicon:`comment-discussion` Chat 21 | :link: ai/chat.html 22 | 23 | Chat with different large language models (LLMs) in a single line of code. 24 | 25 | .. grid-item-card:: :octicon:`paintbrush` Image Generation 26 | :link: ai/draw.html 27 | 28 | Generate or edit images in different styles, without any boilerplate. 29 | 30 | .. grid-item-card:: :octicon:`unmute` Audio Transcription 31 | :link: ai/listen.html 32 | 33 | Powerful and configurable speech-to-text functionality out-of-the-box. 34 | 35 | .. toctree:: 36 | :hidden: 37 | 38 | chat 39 | draw 40 | listen -------------------------------------------------------------------------------- /docs/_build/html/_sources/ai/draw.rst.txt: -------------------------------------------------------------------------------- 1 | Image Generation 2 | ================ 3 | 4 | .. rst-class:: lead 5 | 6 | Using ``draw`` to generate and edit images 7 | 8 | ---- 9 | 10 | PromptScript supports image generation through the ``draw`` keyword. 11 | 12 | Syntax 13 | ------ 14 | 15 | .. code-block:: promptscript 16 | 17 | draw prompt, model, api_key, destination_file 18 | 19 | **Parameters** 20 | 21 | **prompt** (str: required): Prompt to generate image based on. 22 | 23 | **model** (str: required): The model to use for image generation. 24 | 25 | **api_key** (str: required): API key for the image generation service. 26 | 27 | **destination_file** (str: required): File path to save generated image to. 28 | 29 | **Output** 30 | 31 | **None** (output saved to destination_file). 32 | 33 | Supported Models 34 | ---------------- 35 | 36 | .. tabs:: 37 | 38 | .. tab:: OpenAI 39 | 40 | ``dall-e-3``, ``dall-e-2`` 41 | 42 | .. tab:: Stability AI 43 | 44 | ``ultra``, ``core``, ``sd3`` -------------------------------------------------------------------------------- /docs/_build/html/_sources/ai/index.rst.txt: -------------------------------------------------------------------------------- 1 | :description: Guide on using PromptScript to interact with AI. 2 | 3 | AI 4 | == 5 | 6 | .. rst-class:: lead 7 | 8 | Using PromptScript to interact with LLMs, image generation models, and transcription. 9 | 10 | ---- 11 | 12 | Supported Tasks: 13 | ---------------- 14 | 15 | .. grid:: 1 1 3 3 16 | :gutter: 2 17 | :padding: 0 18 | :class-row: surface 19 | 20 | .. grid-item-card:: :octicon:`comment-discussion` Chat 21 | :link: ai/chat.html 22 | 23 | Chat with different large language models (LLMs) in a single line of code. 24 | 25 | .. grid-item-card:: :octicon:`paintbrush` Image Generation 26 | :link: ai/draw.html 27 | 28 | Generate or edit images in different styles, without any boilerplate. 29 | 30 | .. grid-item-card:: :octicon:`unmute` Audio Transcription 31 | :link: ai/listen.html 32 | 33 | Powerful and configurable speech-to-text functionality out-of-the-box. 34 | 35 | .. toctree:: 36 | :hidden: 37 | 38 | chat 39 | draw 40 | listen -------------------------------------------------------------------------------- /docs/running/cli.rst: -------------------------------------------------------------------------------- 1 | :description: Running PromptScript from the CLI. 2 | 3 | CLI 4 | === 5 | 6 | .. rst-class:: lead 7 | 8 | Using the CLI to run PromptScript. 9 | 10 | ---- 11 | 12 | Using the ``promptscript`` alias, you can execute scripts or run individual commands. 13 | 14 | Running PromptScript Files 15 | -------------------------- 16 | 17 | .. code-block:: shell 18 | 19 | $ promptscript file.prompt 20 | 21 | Or, if you'd like to run the file with parameters: 22 | 23 | .. code-block:: shell 24 | 25 | $ promptscript file.prompt param1="Hello" param2="World" 26 | 27 | These values can then be accessed directly in the file: 28 | 29 | .. container:: demo 30 | 31 | .. code-block:: promptscript 32 | :linenos: 33 | :caption: file.prompt 34 | 35 | show "{}, {}!".format(param1, param2) 36 | 37 | .. code-block:: 38 | :class: demo-result 39 | 40 | Output: Hello, World! 41 | 42 | Running Commands 43 | ---------------- 44 | 45 | .. code-block:: shell 46 | 47 | $ promptscript 48 | 49 | This will enter into the CLI. To exit, press :kbd:`^+d`. -------------------------------------------------------------------------------- /promptscript/utils/file.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import List 3 | 4 | # For the 'save'/'read' operators 5 | def save_to_file(value: str, file_path: str): 6 | with open(file_path, 'w') as f: 7 | f.write(value) 8 | 9 | def read_file(file_path: str) -> str: 10 | with open(file_path, 'r') as f: 11 | return f.read() 12 | 13 | # Helpers 14 | def is_promptscript_file(file_path: str) -> bool: 15 | path_components = file_path.split('/') 16 | file_name = (path_components[0] if len(path_components) == 1 else path_components[-1]) 17 | 18 | if (file_name.endswith('.prompt') or '.' not in file_name) and os.path.exists(file_path): 19 | return True 20 | return False 21 | 22 | def get_environment_file_path(file_path: str) -> str: 23 | return f'{os.path.split(file_path)[0]}/.env.prompt' 24 | 25 | def read_file_lines(file_path: str) -> List[str]: 26 | if not os.path.exists(file_path): 27 | return 28 | with open(file_path, 'r') as f: 29 | return [line.strip('\n').replace(' ', '\t') for line in f.readlines() if line.strip().strip('\n') != ''] -------------------------------------------------------------------------------- /docs/_build/html/_sources/running/cli.rst.txt: -------------------------------------------------------------------------------- 1 | :description: Running PromptScript from the CLI. 2 | 3 | CLI 4 | === 5 | 6 | .. rst-class:: lead 7 | 8 | Using the CLI to run PromptScript. 9 | 10 | ---- 11 | 12 | Using the ``promptscript`` alias, you can execute scripts or run individual commands. 13 | 14 | Running PromptScript Files 15 | -------------------------- 16 | 17 | .. code-block:: shell 18 | 19 | $ promptscript file.prompt 20 | 21 | Or, if you'd like to run the file with parameters: 22 | 23 | .. code-block:: shell 24 | 25 | $ promptscript file.prompt param1="Hello" param2="World" 26 | 27 | These values can then be accessed directly in the file: 28 | 29 | .. container:: demo 30 | 31 | .. code-block:: promptscript 32 | :linenos: 33 | :caption: file.prompt 34 | 35 | show "{}, {}!".format(param1, param2) 36 | 37 | .. code-block:: 38 | :class: demo-result 39 | 40 | Output: Hello, World! 41 | 42 | Running Commands 43 | ---------------- 44 | 45 | .. code-block:: shell 46 | 47 | $ promptscript 48 | 49 | This will enter into the CLI. To exit, press :kbd:`^+d`. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 zainmfjavaid 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /promptscript/ai/listen.py: -------------------------------------------------------------------------------- 1 | from openai import OpenAI 2 | 3 | 4 | # Provider methods 5 | def listen_openai( 6 | audio_file_path: str, 7 | api_key: str 8 | ) -> str: 9 | """Method for interacting with OpenAI Whisper. 10 | 11 | Args: 12 | audio_file_path (str): File to transcribe. 13 | api_key (str): OpenAI API key. 14 | 15 | Returns: 16 | str: Transcribed text. 17 | """ 18 | client = OpenAI(api_key=api_key) 19 | audio_file = open(audio_file_path, 'rb') 20 | transcription = client.audio.transcriptions.create( 21 | model='whisper-1', 22 | file=audio_file, 23 | response_format='text' 24 | ) 25 | return transcription 26 | 27 | # Router 28 | def route_listen( 29 | audio_file_path: str, 30 | api_key: str 31 | ) -> str: 32 | """Routes request to provider methods based on model name (currently only routes to OpenAI). 33 | 34 | Args: 35 | audio_file_path (str): File to transcribe. 36 | api_key (str): Transcription service API key. 37 | 38 | Returns: 39 | str: Transcribed text. 40 | """ 41 | return listen_openai(audio_file_path, api_key) -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | 3 | setup( 4 | name='promptscript', 5 | version='0.3.0', 6 | author='Zain Javaid', 7 | author_email='zainmfj@gmail.com', 8 | description='A simple scripting language for interacting with AI', 9 | long_description=open('README.md').read(), 10 | long_description_content_type='text/markdown', 11 | url='https://github.com/zainmfjavaid/PromptScript', 12 | packages=find_packages(), 13 | entry_points={ 14 | 'console_scripts': [ 15 | 'promptscript=promptscript.__main__:main', 16 | ], 17 | }, 18 | install_requires=[ 19 | 'openai==1.35.1', 20 | 'Pygments==2.8.1', 21 | 'shibuya==2024.6.23', 22 | 'sphinx-tabs==3.4.5', 23 | 'sphinx_design==0.5.0', 24 | 'twine==5.1.1', 25 | 'anthropic==0.30.0', 26 | 'sphinx-docsearch==0.0.7', 27 | 'python-dotenv==1.0.1' 28 | ], 29 | classifiers=[ 30 | 'Programming Language :: Python :: 3', 31 | 'License :: OSI Approved :: MIT License', 32 | 'Operating System :: POSIX :: Linux', 33 | 'Operating System :: MacOS :: MacOS X', 34 | ], 35 | python_requires='>=3.6', 36 | ) -------------------------------------------------------------------------------- /test/commands/test_math.py: -------------------------------------------------------------------------------- 1 | from _test_command_base import run_command 2 | 3 | # Addition 4 | assert run_command('SHOW 1+1').stdout.strip('\n') == '2' 5 | assert run_command('SHOW 1+ 2').stdout.strip('\n') == '3' 6 | assert run_command('SHOW 1 +2').stdout.strip('\n') == '3' 7 | assert run_command('SHOW 1 + 2').stdout.strip('\n') == '3' 8 | 9 | # Subtraction 10 | assert run_command('SHOW 5-1').stdout.strip('\n') == '4' 11 | assert run_command('SHOW 5- 2').stdout.strip('\n') == '3' 12 | assert run_command('SHOW 5 -2').stdout.strip('\n') == '3' 13 | assert run_command('SHOW 5 - 2').stdout.strip('\n') == '3' 14 | assert run_command('SHOW 2 - 5').stdout.strip('\n') == '-3' 15 | 16 | # Multiplication 17 | assert run_command('SHOW 5*2').stdout.strip('\n') == '10' 18 | assert run_command('SHOW 5* 2').stdout.strip('\n') == '10' 19 | assert run_command('SHOW 5 *2').stdout.strip('\n') == '10' 20 | assert run_command('SHOW 5 * 2').stdout.strip('\n') == '10' 21 | assert run_command('SHOW 5 * -2').stdout.strip('\n') == '-10' 22 | assert run_command('SHOW 5 * 0').stdout.strip('\n') == '0' 23 | 24 | # Division 25 | assert run_command('SHOW 10/2').stdout.strip('\n') == '5.0' 26 | assert run_command('SHOW 10/ 2').stdout.strip('\n') == '5.0' 27 | assert run_command('SHOW 10 /2').stdout.strip('\n') == '5.0' 28 | assert run_command('SHOW 10 / 2').stdout.strip('\n') == '5.0' 29 | assert run_command('SHOW 0 / 2').stdout.strip('\n') == '0.0' 30 | assert run_command('SHOW 10 / 0').stderr != '' -------------------------------------------------------------------------------- /docs/basic/files.rst: -------------------------------------------------------------------------------- 1 | :description: How to read and write files in PromptScript? 2 | 3 | File I/O 4 | ======== 5 | 6 | .. rst-class:: lead 7 | 8 | Using ``read`` and ``save`` to perform basic file I/O operations in PromptScript. 9 | 10 | ---- 11 | 12 | PromptScript currently only supports basic file I/O operations on non-binary files. 13 | 14 | Reading Files 15 | ------------- 16 | 17 | To read the content of files, use the ``read`` command 18 | 19 | .. code-block:: promptscript 20 | 21 | read file_path 22 | 23 | 24 | **Parameters** 25 | 26 | **file_path** (str: required): File path to read from. 27 | 28 | **Output** 29 | 30 | **str**: The file's text content. 31 | 32 | Writing Files 33 | ------------- 34 | 35 | To write to files, use the ``save`` command 36 | 37 | .. code-block:: promptscript 38 | 39 | save content, file_path 40 | 41 | **Parameters** 42 | 43 | **content** (str: required): Text to write to file. 44 | 45 | **file_path** (str: required): File path to read from. 46 | 47 | **Output** 48 | 49 | **None**. 50 | 51 | Example Usage 52 | ------------- 53 | 54 | 55 | .. container:: demo 56 | 57 | .. code-block:: promptscript 58 | :linenos: 59 | :emphasize-lines: 3, 4 60 | 61 | message = "File Content" 62 | 63 | save message, "file.txt" 64 | show [read "file.txt"] 65 | 66 | .. code-block:: 67 | :class: demo-result 68 | 69 | Output: File Content 70 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/basic/files.rst.txt: -------------------------------------------------------------------------------- 1 | :description: How to read and write files in PromptScript? 2 | 3 | File I/O 4 | ======== 5 | 6 | .. rst-class:: lead 7 | 8 | Using ``read`` and ``save`` to perform basic file I/O operations in PromptScript. 9 | 10 | ---- 11 | 12 | PromptScript currently only supports basic file I/O operations on non-binary files. 13 | 14 | Reading Files 15 | ------------- 16 | 17 | To read the content of files, use the ``read`` command 18 | 19 | .. code-block:: promptscript 20 | 21 | read file_path 22 | 23 | 24 | **Parameters** 25 | 26 | **file_path** (str: required): File path to read from. 27 | 28 | **Output** 29 | 30 | **str**: The file's text content. 31 | 32 | Writing Files 33 | ------------- 34 | 35 | To write to files, use the ``save`` command 36 | 37 | .. code-block:: promptscript 38 | 39 | save content, file_path 40 | 41 | **Parameters** 42 | 43 | **content** (str: required): Text to write to file. 44 | 45 | **file_path** (str: required): File path to read from. 46 | 47 | **Output** 48 | 49 | **None**. 50 | 51 | Example Usage 52 | ------------- 53 | 54 | 55 | .. container:: demo 56 | 57 | .. code-block:: promptscript 58 | :linenos: 59 | :emphasize-lines: 3, 4 60 | 61 | message = "File Content" 62 | 63 | save message, "file.txt" 64 | show [read "file.txt"] 65 | 66 | .. code-block:: 67 | :class: demo-result 68 | 69 | Output: File Content 70 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | :layout: landing 2 | :description: PromptScript is a simple scripting language for interacting with AI systems. 3 | 4 | PromptScript 5 | ============ 6 | 7 | .. rst-class:: lead 8 | 9 | High-level scripting language for interacting with AI systems. 10 | 11 | .. container:: buttons 12 | 13 | `Docs `_ 14 | `GitHub `_ 15 | 16 | .. raw:: html 17 | 18 |
19 | 20 | .. grid:: 1 1 3 3 21 | :gutter: 2 22 | :padding: 0 23 | :class-row: surface 24 | 25 | .. grid-item-card:: :octicon:`comment-discussion` Chat 26 | :link: ai/chat.html 27 | 28 | Chat with different large language models (LLMs) in a single line of code. 29 | 30 | .. grid-item-card:: :octicon:`paintbrush` Image Generation 31 | :link: ai/draw.html 32 | 33 | Generate or edit images in different styles. 34 | 35 | .. grid-item-card:: :octicon:`unmute` Audio Transcription 36 | :link: ai/listen.html 37 | 38 | Powerful and configurable speech-to-text functionality out-of-the-box. 39 | 40 | .. grid-item-card:: :octicon:`zap` Efficient 41 | 42 | No boilerplate. Perform complex tasks without a sprawling codebase. 43 | 44 | .. grid-item-card:: :octicon:`rocket` Simple Syntax 45 | 46 | Simple, easy-to-learn syntax pattern. 47 | 48 | 49 | .. grid-item-card:: :octicon:`beaker` Flexible 50 | 51 | Run on its own, or embedded in Python applications. 52 | 53 | .. toctree:: 54 | :caption: Contents: 55 | :hidden: 56 | 57 | install 58 | basic/index 59 | ai/index 60 | running/index -------------------------------------------------------------------------------- /docs/basic/index.rst: -------------------------------------------------------------------------------- 1 | :description: Guide on basic PromptScript functionality 2 | 3 | Getting Started 4 | =============== 5 | 6 | .. rst-class:: lead 7 | 8 | Performing basic operations in PromptScript. 9 | 10 | ---- 11 | 12 | The Basics 13 | ----------- 14 | 15 | .. grid:: 1 1 3 3 16 | :gutter: 2 17 | :padding: 0 18 | :class-row: surface 19 | 20 | .. grid-item-card:: :octicon:`comment` Printing 21 | :link: show.html 22 | 23 | Print values using the ``show`` command. 24 | 25 | .. grid-item-card:: :octicon:`workflow` Conditionals 26 | :link: conditionals.html 27 | 28 | Using ``if``/``elif``/``else`` for flow control. 29 | 30 | .. grid-item-card:: :octicon:`iterations` Loops 31 | :link: loops.html 32 | 33 | Iteration using ``for`` and ``while`` loops. 34 | 35 | ---- 36 | 37 | Next Steps 38 | ---------- 39 | 40 | .. grid:: 1 41 | :gutter: 2 42 | :padding: 0 43 | :class-row: surface 44 | 45 | .. grid-item-card:: :octicon:`arrow-switch` File I/O 46 | :link: files.html 47 | 48 | Reading & writing to files using ``read`` and ``save``. 49 | 50 | .. grid-item-card:: :octicon:`package-dependencies` Environment Management 51 | :link: load.html 52 | 53 | Learn the PromptScript environment system. 54 | 55 | .. grid-item-card:: :octicon:`stack` Operation Chaining 56 | :link: chaining.html 57 | 58 | Learn how to chain commands together. 59 | 60 | .. toctree:: 61 | :hidden: 62 | 63 | show 64 | conditionals 65 | loops 66 | files 67 | load 68 | chaining -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from dotenv import load_dotenv 4 | from sphinx.highlighting import lexers 5 | 6 | sys.path.insert(0, os.path.abspath('.')) 7 | 8 | from promptscript_lexer import PromptScriptLexer 9 | 10 | load_dotenv('config.env') 11 | 12 | # -- Project information ----------------------------------------------------- 13 | 14 | project = 'PromptScript' 15 | copyright = '2024, Zain Javaid' 16 | author = 'Zain Javaid' 17 | release = '0.3.0' 18 | 19 | # -- General configuration --------------------------------------------------- 20 | 21 | extensions = [ 22 | 'sphinx_design', 23 | 'sphinx_tabs.tabs', 24 | 'sphinx_docsearch' 25 | ] 26 | 27 | sitemap_excludes = ['404/'] 28 | templates_path = ['_templates'] 29 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 30 | 31 | # -- Options for HTML output ------------------------------------------------- 32 | 33 | html_theme = 'shibuya' 34 | html_static_path = ['_static'] 35 | html_favicon = '_static/favicon.ico' 36 | html_title = 'PromptScript Documentation' 37 | html_theme_options = { 38 | 'accent_color': 'jade', 39 | 'globaltoc_expand_depth': 1, 40 | 'github_url': 'https://github.com/zainmfjavaid/PromptScript', 41 | 'nav_links': [ 42 | { 43 | 'title': 'About', 44 | 'url': 'about' 45 | } 46 | ] 47 | } 48 | 49 | if os.getenv('USE_DOCSEARCH'): 50 | docsearch_app_id = os.environ['DOCSEARCH_APP_ID'] 51 | docsearch_api_key = os.environ['DOCSEARCH_API_KEY'] 52 | docsearch_index_name = os.environ['DOCSEARCH_INDEX_NAME'] 53 | 54 | def setup(app): 55 | lexers['promptscript'] = PromptScriptLexer() -------------------------------------------------------------------------------- /promptscript/utils/config.py: -------------------------------------------------------------------------------- 1 | 2 | # For PromptScript CLI 3 | COMMANDS = ['exit', 'save', 'show', 'chat', 'draw', 'listen', 'if', 'elif', 'else', 'for', 'while'] 4 | 5 | # For CommandExecutor and PersistentCommandExecutor 6 | ILLEGAL_PARAMETER_NAMES = ['yield_output', 'get_environment_variable'] 7 | 8 | # Chat Defaults 9 | DEFAULT_SYSTEM_PROMPT = 'you are a helpful chat assistant.' 10 | 11 | # Models 12 | ## Contains list of supported models from different AI providers 13 | ## Occasionally contains mappings to simplify model usage (maps readable name to actual name). This is only done occasionally 14 | OPENAI_CHAT_MODELS = [ 15 | 'gpt-4o', 16 | 'gpt-4o-mini', 17 | 'o1', 18 | 'o1-mini', 19 | 'gpt-4o-realtime-preview', 20 | 'gpt-4o-mini-realtime-preview', 21 | 'gpt-4o-audio-preview', 22 | 'gpt-4-turbo', 23 | 'gpt-4', 24 | 'gpt-3.5-turbo' 25 | ] 26 | OPENAI_IMAGE_MODELS = ['dall-e-3', 'dall-e-2'] 27 | 28 | ANTHROPIC_CHAT_MODELS = [ 29 | 'claude-3-5-sonnet-20241022', 30 | 'claude-3-5-haiku-20241022', 31 | 'claude-3-opus-20240229', 32 | 'claude-3-sonnet-20240229', 33 | 'claude-3-haiku-20240307' 34 | ] 35 | 36 | ANTHROPIC_CHAT_MAPPING = { 37 | 'claude-3.5-sonnet': 'claude-3-5-sonnet-20241022', 38 | 'claude-3-5-sonnet': 'claude-3-5-sonnet-20241022', 39 | 'claude-3.5-haiku': 'claude-3-5-haiku-20241022', 40 | 'claude-3-5-haiku': 'claude-3-5-haiku-20241022', 41 | 'claude-3-opus': 'claude-3-opus-20240229', 42 | 'claude-3-sonnet': 'claude-3-sonnet-20240229', 43 | 'claude-3-haiku': 'claude-3-haiku-20240307' 44 | } 45 | 46 | STABILITY_IMAGE_MODELS = ['ultra', 'core', 'sd3'] 47 | -------------------------------------------------------------------------------- /docs/_build/html/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | :layout: landing 2 | :description: PromptScript is a simple scripting language for interacting with AI systems. 3 | 4 | PromptScript 5 | ============ 6 | 7 | .. rst-class:: lead 8 | 9 | High-level scripting language for interacting with AI systems. 10 | 11 | .. container:: buttons 12 | 13 | `Docs `_ 14 | `GitHub `_ 15 | 16 | .. raw:: html 17 | 18 |
19 | 20 | .. grid:: 1 1 3 3 21 | :gutter: 2 22 | :padding: 0 23 | :class-row: surface 24 | 25 | .. grid-item-card:: :octicon:`comment-discussion` Chat 26 | :link: ai/chat.html 27 | 28 | Chat with different large language models (LLMs) in a single line of code. 29 | 30 | .. grid-item-card:: :octicon:`paintbrush` Image Generation 31 | :link: ai/draw.html 32 | 33 | Generate or edit images in different styles. 34 | 35 | .. grid-item-card:: :octicon:`unmute` Audio Transcription 36 | :link: ai/listen.html 37 | 38 | Powerful and configurable speech-to-text functionality out-of-the-box. 39 | 40 | .. grid-item-card:: :octicon:`zap` Efficient 41 | 42 | No boilerplate. Perform complex tasks without a sprawling codebase. 43 | 44 | .. grid-item-card:: :octicon:`rocket` Simple Syntax 45 | 46 | Simple, easy-to-learn syntax pattern. 47 | 48 | 49 | .. grid-item-card:: :octicon:`beaker` Flexible 50 | 51 | Run on its own, or embedded in Python applications. 52 | 53 | .. toctree:: 54 | :caption: Contents: 55 | :hidden: 56 | 57 | install 58 | basic/index 59 | ai/index 60 | running/index -------------------------------------------------------------------------------- /docs/_build/html/_sources/basic/index.rst.txt: -------------------------------------------------------------------------------- 1 | :description: Guide on basic PromptScript functionality 2 | 3 | Getting Started 4 | =============== 5 | 6 | .. rst-class:: lead 7 | 8 | Performing basic operations in PromptScript. 9 | 10 | ---- 11 | 12 | The Basics 13 | ----------- 14 | 15 | .. grid:: 1 1 3 3 16 | :gutter: 2 17 | :padding: 0 18 | :class-row: surface 19 | 20 | .. grid-item-card:: :octicon:`comment` Printing 21 | :link: show.html 22 | 23 | Print values using the ``show`` command. 24 | 25 | .. grid-item-card:: :octicon:`workflow` Conditionals 26 | :link: conditionals.html 27 | 28 | Using ``if``/``elif``/``else`` for flow control. 29 | 30 | .. grid-item-card:: :octicon:`iterations` Loops 31 | :link: loops.html 32 | 33 | Iteration using ``for`` and ``while`` loops. 34 | 35 | ---- 36 | 37 | Next Steps 38 | ---------- 39 | 40 | .. grid:: 1 41 | :gutter: 2 42 | :padding: 0 43 | :class-row: surface 44 | 45 | .. grid-item-card:: :octicon:`arrow-switch` File I/O 46 | :link: files.html 47 | 48 | Reading & writing to files using ``read`` and ``save``. 49 | 50 | .. grid-item-card:: :octicon:`package-dependencies` Environment Management 51 | :link: load.html 52 | 53 | Learn the PromptScript environment system. 54 | 55 | .. grid-item-card:: :octicon:`stack` Operation Chaining 56 | :link: chaining.html 57 | 58 | Learn how to chain commands together. 59 | 60 | .. toctree:: 61 | :hidden: 62 | 63 | show 64 | conditionals 65 | loops 66 | files 67 | load 68 | chaining -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PromptScript 2 | 3 | A simple scripting language for interacting with AI built on top of Python. 4 | 5 | ## Quick Install 6 | 7 | With pip: 8 | ```bash 9 | pip install promptscript 10 | ``` 11 | 12 | ## Why PromptScript? 13 | 14 | **PromptScript** is designed for efficient tooling with AI systems. 15 | 16 | PromptScript can be written and executed on its own or embedded into Python projects and allows for no-boilerplate interactions with large language models (LLMs), image generation models, and transcription. 17 | 18 | ## Running PromptScript 19 | 20 | Once you've installed PromptScript, you can run it in one of the following ways 21 | 22 | ### Option 1: CLI 23 | 24 | Run: 25 | 26 | ```bash 27 | promptscript 28 | ``` 29 | 30 | ### Option 2: Files 31 | 32 | Create a file ending in **.prompt** 33 | 34 | Example _(test.prompt)_: 35 | ``` 36 | show "Hello, World!" 37 | ``` 38 | 39 | Then, you can run the file from the terminal: 40 | 41 | ```bash 42 | promptscript test.prompt 43 | ``` 44 | 45 | Replacing _test.prompt_ with the actual file path 46 | 47 | ### Option 3: Embedded in Python 48 | 49 | To run PromptScript from python, you can either run it from a file or individual commands 50 | 51 | **Running From Files** 52 | 53 | ```python 54 | from promptscript.executor import FileExecutor 55 | 56 | FileExecutor().run('.prompt') 57 | ``` 58 | 59 | **Running Individual Commands** 60 | 61 | ```python 62 | from promptscript.executor import CommandExecutor 63 | 64 | CommandExecutor().run('show "Hello World!"') 65 | ``` 66 | 67 | ## Documentation 68 | 69 | Visit [promptscript.wiki](https://promptscript.wiki) for full documentation and usage examples -------------------------------------------------------------------------------- /docs/basic/load.rst: -------------------------------------------------------------------------------- 1 | :description: How to read environment variables in PromptScript? 2 | 3 | Environment Files 4 | ================= 5 | 6 | .. rst-class:: lead 7 | 8 | Using ``load`` to access PromptScript environment files. 9 | 10 | ---- 11 | 12 | PromptScript has its own environment management system. 13 | 14 | Creating an Environment File 15 | ---------------------------- 16 | 17 | You can create a PromptScript environment file be creating a file with the name ``.env.prompt``. 18 | 19 | .. code-block:: promptscript 20 | :linenos: 21 | :caption: .env.prompt 22 | 23 | API_KEY="SUPER_SECRET" 24 | CHAT_MODEL="LLM-01" 25 | 26 | You can also run PromptScript code in your ``.env.prompt`` file: 27 | 28 | .. code-block:: promptscript 29 | :linenos: 30 | :caption: .env.prompt 31 | 32 | prod = True 33 | 34 | if prod: 35 | API_KEY="PROD_KEY" 36 | else: 37 | API_KEY="TESTING_KEY" 38 | CHAT_MODEL="LLM-01" 39 | 40 | Accessing Environment Variables 41 | ------------------------------- 42 | 43 | To access environment variables from a PromptScript file, you can use the ``load`` keyword 44 | 45 | ---- 46 | 47 | .. code-block:: promptscript 48 | 49 | load variable_name 50 | 51 | **Parameters** 52 | 53 | **variable_name** (str: required): Name of the variable to load from the ``.env.prompt`` file. 54 | 55 | **Output** 56 | 57 | **Any**: The variable's value. 58 | 59 | ---- 60 | 61 | So, for this example, we could access the ``API_KEY`` and ``CHAT_MODEL`` fields like this: 62 | 63 | .. code-block:: promptscript 64 | :linenos: 65 | :caption: file.prompt 66 | 67 | api_key = load "API_KEY" 68 | chat_model = load "CHAT_MODEL" 69 | 70 | .. important:: Make sure your PromptScript file and environment file are in the same directory! -------------------------------------------------------------------------------- /docs/ai/chat.rst: -------------------------------------------------------------------------------- 1 | Chat 2 | ==== 3 | 4 | .. rst-class:: lead 5 | 6 | Using ``chat`` to interact with LLMs 7 | 8 | ---- 9 | 10 | PromptScript supports chatting with LLMs through the ``chat`` keyword. 11 | 12 | Syntax 13 | ------ 14 | 15 | .. code-block:: promptscript 16 | 17 | chat prompt, model, api_key 18 | 19 | **Parameters** 20 | 21 | **prompt** (str: required): Prompt to send to LLM. 22 | 23 | **model** (str: required): What LLM to send the prompt to. 24 | 25 | **api_key** (str: required): The API key for whatever service you're sending the chat to. 26 | 27 | **Output** 28 | 29 | **str**: Text response from the LLM. 30 | 31 | 32 | Keyword Arguments 33 | ------------------ 34 | 35 | For more advanced LLM calls, you can pass in additional arguments. To use these, you must include 36 | the name of the parameter you're setting. 37 | 38 | .. code-block:: promptscript 39 | 40 | chat prompt, model, api_key, max_tokens=100, system_prompt="you are a pirate." 41 | 42 | **Keyword Arguments** 43 | 44 | **max_tokens** (int, optional): Max LLM response length in tokens. If not set, the default is 4096. 45 | 46 | **system_prompt** (str, optional): Instructions to tell LLM how to respond to queries. If not set, 47 | the default system prompt is ``you are a helpful chat assistant``. 48 | 49 | Supported Models 50 | ---------------- 51 | 52 | .. tabs:: 53 | 54 | .. tab:: OpenAI 55 | 56 | ``gpt-3.5-turbo``, ``gpt-4``, ``gpt-4-turbo``, ``gpt-4-turbo-preview``, ``gpt-4o`` 57 | 58 | .. tab:: Anthropic 59 | 60 | ``claude-3-5-sonnet``, ``claude-3-opus``, ``claude-3-sonnet``, ``claude-3-haiku`` 61 | 62 | .. note:: These are aliases for the latest versions of each of these models. You can also specify a specific 63 | release (e.g. ``claude-3-5-sonnet-20240620``). -------------------------------------------------------------------------------- /docs/_build/html/_sources/basic/load.rst.txt: -------------------------------------------------------------------------------- 1 | :description: How to read environment variables in PromptScript? 2 | 3 | Environment Files 4 | ================= 5 | 6 | .. rst-class:: lead 7 | 8 | Using ``load`` to access PromptScript environment files. 9 | 10 | ---- 11 | 12 | PromptScript has its own environment management system. 13 | 14 | Creating an Environment File 15 | ---------------------------- 16 | 17 | You can create a PromptScript environment file be creating a file with the name ``.env.prompt``. 18 | 19 | .. code-block:: promptscript 20 | :linenos: 21 | :caption: .env.prompt 22 | 23 | API_KEY="SUPER_SECRET" 24 | CHAT_MODEL="LLM-01" 25 | 26 | You can also run PromptScript code in your ``.env.prompt`` file: 27 | 28 | .. code-block:: promptscript 29 | :linenos: 30 | :caption: .env.prompt 31 | 32 | prod = True 33 | 34 | if prod: 35 | API_KEY="PROD_KEY" 36 | else: 37 | API_KEY="TESTING_KEY" 38 | CHAT_MODEL="LLM-01" 39 | 40 | Accessing Environment Variables 41 | ------------------------------- 42 | 43 | To access environment variables from a PromptScript file, you can use the ``load`` keyword 44 | 45 | ---- 46 | 47 | .. code-block:: promptscript 48 | 49 | load variable_name 50 | 51 | **Parameters** 52 | 53 | **variable_name** (str: required): Name of the variable to load from the ``.env.prompt`` file. 54 | 55 | **Output** 56 | 57 | **Any**: The variable's value. 58 | 59 | ---- 60 | 61 | So, for this example, we could access the ``API_KEY`` and ``CHAT_MODEL`` fields like this: 62 | 63 | .. code-block:: promptscript 64 | :linenos: 65 | :caption: file.prompt 66 | 67 | api_key = load "API_KEY" 68 | chat_model = load "CHAT_MODEL" 69 | 70 | .. important:: Make sure your PromptScript file and environment file are in the same directory! -------------------------------------------------------------------------------- /docs/_build/html/_sources/ai/chat.rst.txt: -------------------------------------------------------------------------------- 1 | Chat 2 | ==== 3 | 4 | .. rst-class:: lead 5 | 6 | Using ``chat`` to interact with LLMs 7 | 8 | ---- 9 | 10 | PromptScript supports chatting with LLMs through the ``chat`` keyword. 11 | 12 | Syntax 13 | ------ 14 | 15 | .. code-block:: promptscript 16 | 17 | chat prompt, model, api_key 18 | 19 | **Parameters** 20 | 21 | **prompt** (str: required): Prompt to send to LLM. 22 | 23 | **model** (str: required): What LLM to send the prompt to. 24 | 25 | **api_key** (str: required): The API key for whatever service you're sending the chat to. 26 | 27 | **Output** 28 | 29 | **str**: Text response from the LLM. 30 | 31 | 32 | Keyword Arguments 33 | ------------------ 34 | 35 | For more advanced LLM calls, you can pass in additional arguments. To use these, you must include 36 | the name of the parameter you're setting. 37 | 38 | .. code-block:: promptscript 39 | 40 | chat prompt, model, api_key, max_tokens=100, system_prompt="you are a pirate." 41 | 42 | **Keyword Arguments** 43 | 44 | **max_tokens** (int, optional): Max LLM response length in tokens. If not set, the default is 4096. 45 | 46 | **system_prompt** (str, optional): Instructions to tell LLM how to respond to queries. If not set, 47 | the default system prompt is ``you are a helpful chat assistant``. 48 | 49 | Supported Models 50 | ---------------- 51 | 52 | .. tabs:: 53 | 54 | .. tab:: OpenAI 55 | 56 | ``gpt-3.5-turbo``, ``gpt-4``, ``gpt-4-turbo``, ``gpt-4-turbo-preview``, ``gpt-4o`` 57 | 58 | .. tab:: Anthropic 59 | 60 | ``claude-3-5-sonnet``, ``claude-3-opus``, ``claude-3-sonnet``, ``claude-3-haiku`` 61 | 62 | .. note:: These are aliases for the latest versions of each of these models. You can also specify a specific 63 | release (e.g. ``claude-3-5-sonnet-20240620``). -------------------------------------------------------------------------------- /docs/_build/html/_static/furo-docsearch-custom.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --docsearch-searchbox-background: var(--color-sidebar-search-background); 3 | --docsearch-key-gradient: none; 4 | } 5 | 6 | .DocSearch-Button { 7 | margin: 0; 8 | border-radius: 0; 9 | width: 100%; 10 | border: none; 11 | border-top: 1px solid var(--color-sidebar-search-border); 12 | border-bottom: 1px solid var(--color-sidebar-search-border); 13 | } 14 | 15 | kbd.DocSearch-Button-Key { 16 | display: flex; 17 | border: unset; 18 | border-radius: 3px; 19 | box-shadow: var(--docsearch-key-shadow); 20 | color: var(--docsearch-muted-color); 21 | margin: 0 0.4em 0 0; 22 | padding: 0 0 2px; 23 | } 24 | 25 | kbd.DocSearch-Commands-Key { 26 | box-shadow: var(--docsearch-key-shadow); 27 | border-radius: 2px; 28 | border: unset; 29 | display: flex; 30 | margin: 0 4px 0 0; 31 | padding: 0 0 1px; 32 | font-size: unset; 33 | color: var(--docsearch-muted-color); 34 | } 35 | 36 | /* Dark mode */ 37 | body[data-theme='dark'] { 38 | --docsearch-text-color: rgb(245, 246, 247); 39 | --docsearch-container-background: rgba(9, 10, 17, 0.8); 40 | --docsearch-modal-background: rgb(21, 23, 42); 41 | --docsearch-modal-shadow: inset 1px 1px 0 0 rgb(44, 46, 64), 42 | 0 3px 8px 0 rgb(0, 3, 9); 43 | --docsearch-searchbox-background: rgb(9, 10, 17); 44 | --docsearch-searchbox-focus-background: #000; 45 | --docsearch-hit-color: rgb(190, 195, 201); 46 | --docsearch-hit-shadow: none; 47 | --docsearch-hit-background: rgb(9, 10, 17); 48 | --docsearch-key-gradient: linear-gradient( 49 | -26.5deg, 50 | rgb(86, 88, 114) 0%, 51 | rgb(49, 53, 91) 100% 52 | ); 53 | --docsearch-key-shadow: inset 0 -2px 0 0 rgb(40, 45, 85), 54 | inset 0 0 1px 1px rgb(81, 87, 125), 0 2px 2px 0 rgba(3, 4, 9, 0.3); 55 | --docsearch-footer-background: rgb(30, 33, 54); 56 | --docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, 0.5), 57 | 0 -4px 8px 0 rgba(0, 0, 0, 0.2); 58 | --docsearch-logo-color: rgb(255, 255, 255); 59 | --docsearch-muted-color: rgb(127, 132, 151); 60 | } 61 | 62 | -------------------------------------------------------------------------------- /promptscript/cli.py: -------------------------------------------------------------------------------- 1 | import os 2 | import atexit 3 | import readline 4 | from promptscript.utils.config import COMMANDS 5 | from promptscript.executor import PersistentCommandExecutor 6 | 7 | 8 | def setup_readline(): 9 | history_file = '.promptscript_cli_history' 10 | try: 11 | readline.read_history_file(history_file) 12 | except Exception as e: 13 | pass 14 | readline.set_history_length(1000) 15 | 16 | atexit.register(readline.write_history_file, history_file) 17 | 18 | def completer(text: str, state: int): 19 | options = [cmd for cmd in COMMANDS if cmd.startswith(text.lower())] 20 | if state < len(options): 21 | if text == '': 22 | return '\t' 23 | 24 | if text.isupper(): 25 | return options[state].upper() 26 | else: 27 | return options[state] 28 | 29 | readline.parse_and_bind('tab: complete') 30 | readline.set_completer(completer) 31 | 32 | def run_cli(): 33 | command_executor = PersistentCommandExecutor() 34 | setup_readline() 35 | 36 | in_buffer = False 37 | command_buffer = [] 38 | while True: 39 | try: 40 | if not in_buffer: 41 | command = input('>>> ') 42 | else: 43 | command = input('... ') 44 | if command.lower() == 'exit': 45 | break 46 | 47 | if command.lower().startswith(('if', 'elif', 'else', 'for', 'while')): 48 | in_buffer = True 49 | 50 | if in_buffer: 51 | if command == '': 52 | command = '\n'.join(command_buffer) 53 | in_buffer = False 54 | else: 55 | command_buffer.append(command) 56 | 57 | if not in_buffer: 58 | command_executor.run(command) 59 | 60 | except KeyboardInterrupt: 61 | print('\nKeyboard Interrupt') 62 | 63 | except EOFError: 64 | print("\n\nExiting...") 65 | break 66 | 67 | except Exception as e: 68 | print(f'Error: {e}') -------------------------------------------------------------------------------- /docs/_build/html/_static/tabs.css: -------------------------------------------------------------------------------- 1 | .sphinx-tabs { 2 | margin-bottom: 1rem; 3 | } 4 | 5 | [role="tablist"] { 6 | border-bottom: 1px solid #a0b3bf; 7 | } 8 | 9 | .sphinx-tabs-tab { 10 | position: relative; 11 | font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; 12 | color: #1D5C87; 13 | line-height: 24px; 14 | margin: 0; 15 | font-size: 16px; 16 | font-weight: 400; 17 | background-color: rgba(255, 255, 255, 0); 18 | border-radius: 5px 5px 0 0; 19 | border: 0; 20 | padding: 1rem 1.5rem; 21 | margin-bottom: 0; 22 | } 23 | 24 | .sphinx-tabs-tab[aria-selected="true"] { 25 | font-weight: 700; 26 | border: 1px solid #a0b3bf; 27 | border-bottom: 1px solid white; 28 | margin: -1px; 29 | background-color: white; 30 | } 31 | 32 | .sphinx-tabs-tab:focus { 33 | z-index: 1; 34 | outline-offset: 1px; 35 | } 36 | 37 | .sphinx-tabs-panel { 38 | position: relative; 39 | padding: 1rem; 40 | border: 1px solid #a0b3bf; 41 | margin: 0px -1px -1px -1px; 42 | border-radius: 0 0 5px 5px; 43 | border-top: 0; 44 | background: white; 45 | } 46 | 47 | .sphinx-tabs-panel.code-tab { 48 | padding: 0.4rem; 49 | } 50 | 51 | .sphinx-tab img { 52 | margin-bottom: 24 px; 53 | } 54 | 55 | /* Dark theme preference styling */ 56 | 57 | @media (prefers-color-scheme: dark) { 58 | body[data-theme="auto"] .sphinx-tabs-panel { 59 | color: white; 60 | background-color: rgb(50, 50, 50); 61 | } 62 | 63 | body[data-theme="auto"] .sphinx-tabs-tab { 64 | color: white; 65 | background-color: rgba(255, 255, 255, 0.05); 66 | } 67 | 68 | body[data-theme="auto"] .sphinx-tabs-tab[aria-selected="true"] { 69 | border-bottom: 1px solid rgb(50, 50, 50); 70 | background-color: rgb(50, 50, 50); 71 | } 72 | } 73 | 74 | /* Explicit dark theme styling */ 75 | 76 | body[data-theme="dark"] .sphinx-tabs-panel { 77 | color: white; 78 | background-color: rgb(50, 50, 50); 79 | } 80 | 81 | body[data-theme="dark"] .sphinx-tabs-tab { 82 | color: white; 83 | background-color: rgba(255, 255, 255, 0.05); 84 | } 85 | 86 | body[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { 87 | border-bottom: 2px solid rgb(50, 50, 50); 88 | background-color: rgb(50, 50, 50); 89 | } 90 | -------------------------------------------------------------------------------- /docs/about.rst: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | About 4 | ===== 5 | 6 | .. rst-class:: lead 7 | 8 | What is PromptScript, why should you use it, and other FAQs. 9 | 10 | ---- 11 | 12 | What is PromptScript? 13 | --------------------- 14 | 15 | PromptScript is a scripting language designed to make programmatically interacting with AI systems as easy as possible. 16 | It's designed to be beginner-friendly, while containing powerful functionality out of the box. 17 | 18 | ---- 19 | 20 | Why use it? 21 | ----------- 22 | 23 | The most basic way to integrate AI into applications is through provider libraries. However, these are often difficult 24 | to work with, and lock you in to using that company. If you ever want to switch from one provider to another, it'll 25 | require refactoring the entire code base. 26 | 27 | Frameworks like `Langchain `_ solve this issue, but introduce a number of their own: 28 | 29 | 1. They're often over-specced, leading to confusing abstraction, bloat, and boilerplate. 30 | 2. Most only support one type of task (text generation, image generation, etc), meaning projects that work with more than one modality require multiple dependencies. 31 | 32 | PromptScript makes it easy to integrate multiple AI systems across different modalities without major 33 | code changes. 34 | 35 | With PromptScript, you can: 36 | 37 | .. grid:: 1 38 | :gutter: 2 39 | :padding: 0 40 | :class-row: surface 41 | 42 | .. grid-item-card:: :octicon:`arrow-switch` Easily switch between AI providers 43 | 44 | Avoid vendor lock-in and choose the best provider for your needs. 45 | 46 | .. grid-item-card:: :octicon:`dependabot` Work with multiple AI modalities 47 | 48 | Integrate `text generation `_, `image generation `_, and other AI capabilities in a single project. 49 | 50 | .. grid-item-card:: :octicon:`issue-reopened` Quickly prototype and test 51 | 52 | Experiment with new ideas and iterate faster with minimal setup. 53 | 54 | .. grid-item-card:: :octicon:`plug` Run anywhere 55 | 56 | PromptScript can be run `on its own `_, or `embedded in Python `_ applications. 57 | 58 | ---- 59 | 60 | Who made it? 61 | ------------ 62 | 63 | Howdy! I'm Zain Javaid, a 17 year-old high schooler living in Austin, Texas. 64 | 65 | If you want to see what I'm up to, you can check out my `GitHub `_ or my `blog `_. 66 | 67 | ---- 68 | 69 | Can I use PromptScript for commercial projects? 70 | ----------------------------------------------- 71 | 72 | Yes, PromptScript is liscensed under the `MIT License `_, which allows free use in both 73 | personal and commercial projects. 74 | 75 | ---- 76 | 77 | How can I contribute? 78 | --------------------- 79 | 80 | Contributions to PromptScript are welcome and encouraged! Here are some ways you can contribute: 81 | 82 | 1. **Report Bugs**: If you encounter any issues, please report them on the `GitHub issue tracker `_. 83 | 2. **Submit Feature Requests**: If you have ideas for new features or improvements, `open an issue `_ with the ``feature`` label. 84 | 3. **Code Contributions**: If you're a developer, you can contribute code by forking the repository and submitting a pull request with your changes. -------------------------------------------------------------------------------- /docs/_build/html/_sources/about.rst.txt: -------------------------------------------------------------------------------- 1 | :orphan: 2 | 3 | About 4 | ===== 5 | 6 | .. rst-class:: lead 7 | 8 | What is PromptScript, why should you use it, and other FAQs. 9 | 10 | ---- 11 | 12 | What is PromptScript? 13 | --------------------- 14 | 15 | PromptScript is a scripting language designed to make programmatically interacting with AI systems as easy as possible. 16 | It's designed to be beginner-friendly, while containing powerful functionality out of the box. 17 | 18 | ---- 19 | 20 | Why use it? 21 | ----------- 22 | 23 | The most basic way to integrate AI into applications is through provider libraries. However, these are often difficult 24 | to work with, and lock you in to using that company. If you ever want to switch from one provider to another, it'll 25 | require refactoring the entire code base. 26 | 27 | Frameworks like `Langchain `_ solve this issue, but introduce a number of their own: 28 | 29 | 1. They're often over-specced, leading to confusing abstraction, bloat, and boilerplate. 30 | 2. Most only support one type of task (text generation, image generation, etc), meaning projects that work with more than one modality require multiple dependencies. 31 | 32 | PromptScript makes it easy to integrate multiple AI systems across different modalities without major 33 | code changes. 34 | 35 | With PromptScript, you can: 36 | 37 | .. grid:: 1 38 | :gutter: 2 39 | :padding: 0 40 | :class-row: surface 41 | 42 | .. grid-item-card:: :octicon:`arrow-switch` Easily switch between AI providers 43 | 44 | Avoid vendor lock-in and choose the best provider for your needs. 45 | 46 | .. grid-item-card:: :octicon:`dependabot` Work with multiple AI modalities 47 | 48 | Integrate `text generation `_, `image generation `_, and other AI capabilities in a single project. 49 | 50 | .. grid-item-card:: :octicon:`issue-reopened` Quickly prototype and test 51 | 52 | Experiment with new ideas and iterate faster with minimal setup. 53 | 54 | .. grid-item-card:: :octicon:`plug` Run anywhere 55 | 56 | PromptScript can be run `on its own `_, or `embedded in Python `_ applications. 57 | 58 | ---- 59 | 60 | Who made it? 61 | ------------ 62 | 63 | Howdy! I'm Zain Javaid, a 17 year-old high schooler living in Austin, Texas. 64 | 65 | If you want to see what I'm up to, you can check out my `GitHub `_ or my `blog `_. 66 | 67 | ---- 68 | 69 | Can I use PromptScript for commercial projects? 70 | ----------------------------------------------- 71 | 72 | Yes, PromptScript is liscensed under the `MIT License `_, which allows free use in both 73 | personal and commercial projects. 74 | 75 | ---- 76 | 77 | How can I contribute? 78 | --------------------- 79 | 80 | Contributions to PromptScript are welcome and encouraged! Here are some ways you can contribute: 81 | 82 | 1. **Report Bugs**: If you encounter any issues, please report them on the `GitHub issue tracker `_. 83 | 2. **Submit Feature Requests**: If you have ideas for new features or improvements, `open an issue `_ with the ``feature`` label. 84 | 3. **Code Contributions**: If you're a developer, you can contribute code by forking the repository and submitting a pull request with your changes. -------------------------------------------------------------------------------- /promptscript/ai/draw.py: -------------------------------------------------------------------------------- 1 | import base64 2 | import requests 3 | from typing import Callable 4 | 5 | from openai import OpenAI 6 | 7 | from promptscript.utils.config import ( 8 | OPENAI_IMAGE_MODELS, 9 | STABILITY_IMAGE_MODELS 10 | ) 11 | 12 | 13 | def save_to_file(func: Callable) -> Callable: 14 | """Decorator to save base64-encoded data to a file. 15 | 16 | Args: 17 | func (Callable): Function to wrap. 18 | 19 | Returns: 20 | Callable: Wrapped function. 21 | """ 22 | def wrapper( 23 | prompt: str, 24 | model: str, 25 | api_key: str, 26 | destination_file: str 27 | ) -> None: 28 | """Wrapper function that saves generated image to a file. 29 | 30 | Args: 31 | prompt (str): Prompt to generate image based on. 32 | model (str): The model to use for image generation. 33 | api_key (str): API key for the image generation service. 34 | destination_file (str): File path to save generated image to. 35 | """ 36 | b64 = func(prompt, model, api_key) 37 | with open(destination_file, 'wb') as f: 38 | f.write(base64.b64decode(b64)) 39 | return wrapper 40 | 41 | # Provider methods 42 | @save_to_file 43 | def draw_dalle( 44 | prompt: str, 45 | model: str, 46 | api_key: str 47 | ) -> str: 48 | """Method for interacting with OpenAI image generation. 49 | 50 | Args: 51 | prompt (str): Prompt to generate image based on. 52 | model (str): The model to use for image generation. 53 | api_key (str): OpenAI API key. 54 | 55 | Returns: 56 | str: base64-encoded image data. 57 | """ 58 | client = OpenAI(api_key=api_key) 59 | response = client.images.generate( 60 | model=model, 61 | prompt=prompt, 62 | size='1024x1024', 63 | quality='standard', 64 | n=1, 65 | response_format='b64_json' 66 | ) 67 | return response.data[0].b64_json 68 | 69 | @save_to_file 70 | def draw_stability( 71 | prompt: str, 72 | model: str, 73 | api_key: str 74 | ) -> str: 75 | """Method for interacting with StabilityAI image generation. 76 | 77 | Args: 78 | prompt (str): Prompt to generate image based on. 79 | model (str): The model to use for image generation. 80 | api_key (str): Stability API key. 81 | 82 | Returns: 83 | str: base64-encoded image data. 84 | """ 85 | url = f'https://api.stability.ai/v2beta/stable-image/generate/{model}' 86 | headers = {'Accept': 'application/json', 'Authorization': f'Bearer {api_key}'} 87 | params = {'prompt': prompt} 88 | files = {'none': ''} 89 | 90 | response = requests.post(url, headers=headers, data=params, files=files).json() 91 | if 'image' in response: 92 | return response['image'] 93 | return Exception(f"Error: {response['errors']}") 94 | 95 | # Router 96 | def route_draw( 97 | prompt: str, 98 | model: str, 99 | api_key: str, 100 | destination_file: str 101 | ) -> None: 102 | """Routes request to provider methods based on model name. 103 | 104 | Args: 105 | prompt (str): Prompt to generate image based on. 106 | model (str): The model to use for image generation. 107 | api_key (str): API key for the image generation service. 108 | destination_file (str): File path to save generated image to. 109 | 110 | Raises: 111 | Exception: If an invalid image generation model is provided. 112 | """ 113 | model = model.lower() 114 | 115 | if model in OPENAI_IMAGE_MODELS: 116 | draw_dalle(prompt, model, api_key, destination_file) 117 | return 118 | 119 | elif model in STABILITY_IMAGE_MODELS: 120 | b64 = draw_stability(prompt, model, api_key, destination_file) 121 | return 122 | 123 | raise Exception(f'ERROR: Invalid draw model') -------------------------------------------------------------------------------- /promptscript/ai/chat.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Any 2 | 3 | from openai import OpenAI 4 | from anthropic import Anthropic 5 | 6 | from promptscript.utils.config import ( 7 | DEFAULT_SYSTEM_PROMPT, 8 | OPENAI_CHAT_MODELS, 9 | ANTHROPIC_CHAT_MODELS, 10 | ANTHROPIC_CHAT_MAPPING 11 | ) 12 | 13 | 14 | # Provider methods 15 | def chat_openai( 16 | prompt: str, 17 | model: str, 18 | api_key: str, 19 | system_prompt: str=DEFAULT_SYSTEM_PROMPT, 20 | **kwargs 21 | ) -> str: 22 | """Method for interacting with OpenAI chat models. 23 | 24 | Args: 25 | prompt (str): Prompt to send to LLM. 26 | model (str): What LLM to send the prompt to. 27 | api_key (str): OpenAI API key. 28 | system_prompt (str, optional): System instructions. Defaults to DEFAULT_SYSTEM_PROMPT. 29 | 30 | Returns: 31 | str: Chat response. 32 | """ 33 | client = OpenAI(api_key=api_key) 34 | completion = client.chat.completions.create( 35 | model=model, 36 | messages=[ 37 | {'role': 'system', 'content': system_prompt}, 38 | {'role': 'user', 'content': prompt} 39 | ], 40 | **kwargs 41 | ) 42 | return completion.choices[0].message.content 43 | 44 | def chat_anthropic( 45 | prompt: str, 46 | model: str, 47 | api_key: str, 48 | max_tokens: int=4096, 49 | system_prompt: str=DEFAULT_SYSTEM_PROMPT, 50 | **kwargs 51 | ) -> str: 52 | """Method for interacting with Anthropic chat models. 53 | 54 | Args: 55 | prompt (str): Prompt to send to LLM. 56 | model (str): What LLM to send the prompt to. 57 | api_key (str): Anthropic API key. 58 | max_tokens (int, optional): Max response token length (required field for Anthropic API). Defaults to 4096. 59 | system_prompt (str, optional): System instructions. Defaults to DEFAULT_SYSTEM_PROMPT. 60 | 61 | Returns: 62 | str: Chat response. 63 | """ 64 | client = Anthropic(api_key=api_key) 65 | message = client.messages.create( 66 | model=model, 67 | max_tokens=max_tokens, 68 | system=system_prompt, 69 | messages=[ 70 | {'role': 'user', 'content': [{'type': 'text', 'text': prompt}]} 71 | ], 72 | **kwargs 73 | ) 74 | return message.content[0].text 75 | 76 | # Router 77 | def _construct_kwargs(**kwargs) -> Dict[str, Any]: 78 | """Helper method for constructing kwargs. Only adds a value if its value is non-null. 79 | 80 | Returns: 81 | Dict[str, Any]: Dictionary of kwargs. 82 | """ 83 | return {key: value for key, value in kwargs.items() if value is not None} 84 | 85 | def route_chat( 86 | prompt: str, 87 | model: str, 88 | api_key: str, 89 | max_tokens: int=None, 90 | system_prompt: str=None 91 | ) -> str: 92 | """Routes request to provider methods based on model name. 93 | 94 | Args: 95 | prompt (str): Prompt to send to LLM. 96 | model (str): What LLM to send the prompt to. 97 | api_key (str): The API key for whatever service the chat is getting sent to. 98 | max_tokens (int, optional): Max response token length. Defaults to None. 99 | system_prompt (str, optional): System instructions. Defaults to None. 100 | 101 | Raises: 102 | Exception: If an invalid chat model is provided. 103 | 104 | Returns: 105 | str: Chat response. 106 | """ 107 | model = model.lower() 108 | kwargs = _construct_kwargs(max_tokens=max_tokens, system_prompt=system_prompt) 109 | 110 | if model in OPENAI_CHAT_MODELS: 111 | return chat_openai(prompt, model, api_key, **kwargs) 112 | 113 | elif model in ANTHROPIC_CHAT_MODELS or model in ANTHROPIC_CHAT_MAPPING: 114 | model = ANTHROPIC_CHAT_MAPPING.get(model, model) 115 | return chat_anthropic(prompt, model, api_key, **kwargs) 116 | 117 | raise Exception('ERROR: Invalid chat model') -------------------------------------------------------------------------------- /docs/running/python.rst: -------------------------------------------------------------------------------- 1 | :description: Guide on running PromptScript embedded in Python. 2 | 3 | Python 4 | ====== 5 | 6 | .. rst-class:: lead 7 | 8 | Using the ``promptscript`` package to run PromptScript embedded in Python. 9 | 10 | ---- 11 | 12 | There are two main ways to run PromptScript in Python using the ``promptscript`` package: running files or commands. 13 | 14 | Running PromptScript Files 15 | -------------------------- 16 | 17 | .. code-block:: python 18 | :linenos: 19 | :caption: main.py 20 | 21 | from promptscript.executor import FileExecutor 22 | 23 | 24 | file_executor = FileExecutor() 25 | file_executor.run('file.prompt') 26 | 27 | You can also pass parameters into the executor: 28 | 29 | .. code-block:: python 30 | :linenos: 31 | :caption: main.py 32 | 33 | file_executor.run('file.prompt', user_prompt='What is 2+2?') 34 | 35 | Then access them directly from your PromptScript file. 36 | 37 | .. code-block:: promptscript 38 | :linenos: 39 | :caption: file.prompt 40 | 41 | chat_response = chat user_prompt, "gpt-4o", "API_KEY" 42 | 43 | Running Commands 44 | ---------------- 45 | 46 | .. code-block:: python 47 | :linenos: 48 | :caption: main.py 49 | 50 | from promptscript.executor import CommandExecutor 51 | 52 | 53 | command_executor = CommandExecutor() 54 | command_executor.run('show "Hello, World!"') 55 | 56 | The CommandExecutor also supports passing in parameters. 57 | 58 | .. code-block:: python 59 | :linenos: 60 | :caption: main.py 61 | 62 | command_executor.run('show msg', msg='Hello, World!') 63 | 64 | Persistent Command Execution 65 | ---------------------------- 66 | 67 | Imagine you want to run a sequence of individual commands that have access to the outputs of the previous commands. Of course, 68 | this is possible with the base ``CommandExecutor`` class through the use of parameters, but this approach is clunky and 69 | inefficient. That's where the ``PersistentCommandExecutor`` comes in. 70 | 71 | The ``PersistentCommandExecutor`` will save the output of commands run previously so you can reference previously set values. 72 | 73 | 74 | .. container:: demo 75 | 76 | .. code-block:: python 77 | :linenos: 78 | :caption: main.py 79 | 80 | from promptscript.executor import PersistentCommandExecutor 81 | 82 | 83 | persistent_command_executor = PersistentCommandExecutor() 84 | persistent_command_executor.run('x += 1', x=5) 85 | persistent_command_executor.run('show x') 86 | 87 | .. code-block:: python 88 | :class: demo-result 89 | 90 | 6 91 | 92 | Getting Output from PromptScript 93 | -------------------------------- 94 | 95 | To make output from PromptScript files avaliable in Python, you can use the ``yield`` command. The first argument to ``yield`` is 96 | the key to make the value avaliable through, while the second argument is the value itself. If no yield statements are present 97 | in the PromptScript code being executed, each of the command executors will return ``{}``. 98 | 99 | .. important:: ``yield`` **does not** operate like return in Python. Code after a ``yield`` statement **will be executed**. 100 | 101 | .. code-block:: promptscript 102 | :linenos: 103 | :caption: file.prompt 104 | :emphasize-lines: 2 105 | 106 | chat_response = chat user_prompt, "gpt-4o", "API_KEY" 107 | yield "chat_response", chat_response 108 | 109 | We can then access the value of chat_response: 110 | 111 | .. container:: demo 112 | 113 | .. code-block:: python 114 | :linenos: 115 | :caption: main.py 116 | 117 | from promptscript.executor import FileExecutor 118 | 119 | 120 | file_executor = FileExecutor() 121 | output = file_executor.run('file.prompt', user_prompt='What is 2+2?') 122 | 123 | print(output) 124 | 125 | .. code-block:: python 126 | :class: demo-result 127 | 128 | {'chat_response': '2+2 equals 4.'} 129 | 130 | .. note:: ``yield`` also works the same way in the ``CommandExecutor`` and ``PersistentCommandExecutor``. -------------------------------------------------------------------------------- /docs/_build/html/_sources/running/python.rst.txt: -------------------------------------------------------------------------------- 1 | :description: Guide on running PromptScript embedded in Python. 2 | 3 | Python 4 | ====== 5 | 6 | .. rst-class:: lead 7 | 8 | Using the ``promptscript`` package to run PromptScript embedded in Python. 9 | 10 | ---- 11 | 12 | There are two main ways to run PromptScript in Python using the ``promptscript`` package: running files or commands. 13 | 14 | Running PromptScript Files 15 | -------------------------- 16 | 17 | .. code-block:: python 18 | :linenos: 19 | :caption: main.py 20 | 21 | from promptscript.executor import FileExecutor 22 | 23 | 24 | file_executor = FileExecutor() 25 | file_executor.run('file.prompt') 26 | 27 | You can also pass parameters into the executor: 28 | 29 | .. code-block:: python 30 | :linenos: 31 | :caption: main.py 32 | 33 | file_executor.run('file.prompt', user_prompt='What is 2+2?') 34 | 35 | Then access them directly from your PromptScript file. 36 | 37 | .. code-block:: promptscript 38 | :linenos: 39 | :caption: file.prompt 40 | 41 | chat_response = chat user_prompt, "gpt-4o", "API_KEY" 42 | 43 | Running Commands 44 | ---------------- 45 | 46 | .. code-block:: python 47 | :linenos: 48 | :caption: main.py 49 | 50 | from promptscript.executor import CommandExecutor 51 | 52 | 53 | command_executor = CommandExecutor() 54 | command_executor.run('show "Hello, World!"') 55 | 56 | The CommandExecutor also supports passing in parameters. 57 | 58 | .. code-block:: python 59 | :linenos: 60 | :caption: main.py 61 | 62 | command_executor.run('show msg', msg='Hello, World!') 63 | 64 | Persistent Command Execution 65 | ---------------------------- 66 | 67 | Imagine you want to run a sequence of individual commands that have access to the outputs of the previous commands. Of course, 68 | this is possible with the base ``CommandExecutor`` class through the use of parameters, but this approach is clunky and 69 | inefficient. That's where the ``PersistentCommandExecutor`` comes in. 70 | 71 | The ``PersistentCommandExecutor`` will save the output of commands run previously so you can reference previously set values. 72 | 73 | 74 | .. container:: demo 75 | 76 | .. code-block:: python 77 | :linenos: 78 | :caption: main.py 79 | 80 | from promptscript.executor import PersistentCommandExecutor 81 | 82 | 83 | persistent_command_executor = PersistentCommandExecutor() 84 | persistent_command_executor.run('x += 1', x=5) 85 | persistent_command_executor.run('show x') 86 | 87 | .. code-block:: python 88 | :class: demo-result 89 | 90 | 6 91 | 92 | Getting Output from PromptScript 93 | -------------------------------- 94 | 95 | To make output from PromptScript files avaliable in Python, you can use the ``yield`` command. The first argument to ``yield`` is 96 | the key to make the value avaliable through, while the second argument is the value itself. If no yield statements are present 97 | in the PromptScript code being executed, each of the command executors will return ``{}``. 98 | 99 | .. important:: ``yield`` **does not** operate like return in Python. Code after a ``yield`` statement **will be executed**. 100 | 101 | .. code-block:: promptscript 102 | :linenos: 103 | :caption: file.prompt 104 | :emphasize-lines: 2 105 | 106 | chat_response = chat user_prompt, "gpt-4o", "API_KEY" 107 | yield "chat_response", chat_response 108 | 109 | We can then access the value of chat_response: 110 | 111 | .. container:: demo 112 | 113 | .. code-block:: python 114 | :linenos: 115 | :caption: main.py 116 | 117 | from promptscript.executor import FileExecutor 118 | 119 | 120 | file_executor = FileExecutor() 121 | output = file_executor.run('file.prompt', user_prompt='What is 2+2?') 122 | 123 | print(output) 124 | 125 | .. code-block:: python 126 | :class: demo-result 127 | 128 | {'chat_response': '2+2 equals 4.'} 129 | 130 | .. note:: ``yield`` also works the same way in the ``CommandExecutor`` and ``PersistentCommandExecutor``. -------------------------------------------------------------------------------- /promptscript/executor.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, Any 2 | 3 | from promptscript.ai.chat import route_chat 4 | from promptscript.ai.draw import route_draw 5 | from promptscript.ai.listen import route_listen 6 | 7 | from promptscript.interpreter import interpret 8 | from promptscript.utils.debug_level import DebugLevel 9 | from promptscript.utils.config import ILLEGAL_PARAMETER_NAMES 10 | from promptscript.utils.file import save_to_file, read_file, read_file_lines, get_environment_file_path, is_promptscript_file 11 | 12 | DEBUG_LEVEL = DebugLevel.INFO 13 | 14 | class BaseExecutor: 15 | def validate_parameters(self, parameters: Dict): 16 | for key_name in parameters: 17 | if key_name in ILLEGAL_PARAMETER_NAMES: 18 | raise ValueError(f"Illegal parameter name '{key_name}'") 19 | 20 | class FileExecutor(BaseExecutor): 21 | """Class for running and getting the yielded output from PromptScript files""" 22 | 23 | def run(self, file_path: str, **kwargs) -> Dict[str, Any]: 24 | """Executes PromptScript file 25 | 26 | Args: 27 | file_path (str): Path to PromptScript file 28 | 29 | Returns: 30 | Dict: Yielded output 31 | """ 32 | environment_scope, local_scope, output = {}, {}, {} 33 | 34 | self.validate_parameters(kwargs) 35 | local_scope.update(kwargs) 36 | 37 | def get_environment_variable(key: str) -> Any: 38 | if key in environment_scope: 39 | return environment_scope[key] 40 | raise KeyError(f"'{key}' not found in environment") 41 | 42 | local_scope['yield_output'] = lambda k, v: output.update({k: v}) 43 | local_scope['get_environment_variable'] = get_environment_variable 44 | 45 | if not is_promptscript_file(file_path): 46 | raise Exception('Unsupported file type') 47 | 48 | promptscript_commands = read_file_lines(file_path) 49 | environment_commands = read_file_lines(get_environment_file_path(file_path)) 50 | 51 | if environment_commands: 52 | interpreted_env_command = interpret('\n'.join(environment_commands), DEBUG_LEVEL) 53 | exec(interpreted_env_command, globals(), environment_scope) 54 | 55 | interpreted_commands = [] 56 | for command in promptscript_commands: 57 | interpreted_command = interpret(command, DEBUG_LEVEL) 58 | interpreted_commands.append(interpreted_command) 59 | 60 | combined_commands = '\n'.join(interpreted_commands) 61 | exec(combined_commands, globals(), local_scope) 62 | 63 | return output 64 | 65 | class CommandExecutor(BaseExecutor): 66 | """Class for running individual PromptScript commands""" 67 | 68 | @staticmethod 69 | def _get_environment_variable(key: str): 70 | """Raises error if environment operations are run outside of files.""" 71 | raise NotImplementedError('Environment operations are only avaliable in files.') 72 | 73 | def run(self, command: str, **kwargs) -> Dict[str, Any]: 74 | """Executes individual PromptScript command 75 | 76 | Args: 77 | command (str): PromptScript command 78 | 79 | Returns: 80 | Dict: Yielded output 81 | """ 82 | local_scope, output = {}, {} 83 | 84 | self.validate_parameters(kwargs) 85 | local_scope.update(kwargs) 86 | 87 | local_scope['yield_output'] = lambda k, v: output.update({k: v}) 88 | local_scope['get_environment_variable'] = CommandExecutor._get_environment_variable 89 | 90 | interpreted_command = interpret(command, DEBUG_LEVEL) 91 | exec(interpreted_command, globals(), local_scope) 92 | 93 | return output 94 | 95 | class PersistentCommandExecutor(BaseExecutor): 96 | """Class for running PromptScript commands with context persisting between runs""" 97 | 98 | def __init__(self): 99 | self.local_scope = {} 100 | self.local_scope['get_environment_variable'] = CommandExecutor._get_environment_variable 101 | 102 | def run(self, command: str, **kwargs) -> Dict[str, Any]: 103 | output = {} 104 | 105 | self.validate_parameters(kwargs) 106 | self.local_scope.update(kwargs) 107 | 108 | self.local_scope['yield_output'] = lambda k, v: output.update({k: v}) 109 | 110 | interpreted_command = interpret(command, DEBUG_LEVEL) 111 | exec(interpreted_command, globals(), self.local_scope) 112 | 113 | return output -------------------------------------------------------------------------------- /docs/_build/html/_static/shibuya.js: -------------------------------------------------------------------------------- 1 | (()=>{function _(t){let e=t.getAttribute("aria-controls"),o=document.getElementById(e),c="data-expanded-"+e;t.addEventListener("click",function(){document.body.hasAttribute(c)?(document.body.removeAttribute(c),o.classList.remove("_expanded"),y(e,"false")):(document.body.setAttribute(c,"true"),o.classList.add("_expanded"),y(e,"true"))})}function y(t,e){let o=document.querySelectorAll('[aria-controls="'+t+'"]');for(el of o)el.setAttribute("aria-expanded",e)}var S=document.querySelectorAll(".js-menu");for(let t=0;t{a.parentNode.removeChild(a),document.head.removeChild(t)}),e(),window.addEventListener("resize",e)}var C;var l=["auto","light","dark"],d=document.querySelector(".js-theme");function k(){let t=h();t+=1,l[t]||(t=0);let e=l[t];setColorMode(e),localStorage._theme=e,L(e)}function h(){return l.indexOf(document.documentElement.getAttribute("data-color-mode")||"auto")}function L(t){let e=d.getAttribute("data-aria-"+t);d.setAttribute("aria-label",e)}d&&(d.addEventListener("click",k),L(l[h()]||"auto"));function I(){let t=document.querySelector(".globaltoc");if(!t)return;let e=parseInt(t.getAttribute("data-expand-depth"),10),o=n=>{if(!e)return!1;let s=0;for(;n.parentNode&&n.parentNode!==t;)n=n.parentNode,n.nodeName==="UL"&&(s+=1);return e>=s};t.querySelectorAll("li > ul").forEach(n=>{let s=n.parentNode;s.classList.contains("current")||o(s)?s.classList.add("_expand"):s.classList.add("_collapse");let i=N(n);s.appendChild(i)})}function N(t){let e=document.createElement("button");e.innerHTML='';let o=t.parentNode,c=t.previousSibling,n=c.textContent,s=()=>{o.classList.contains("_expand")?e.setAttribute("aria-label","Collapse "+n):e.setAttribute("aria-label","Expand "+n)};s();let i=E=>{E.preventDefault(),o.classList.contains("_expand")?(o.classList.remove("_expand"),o.classList.add("_collapse")):(o.classList.remove("_collapse"),o.classList.add("_expand")),s()};return c.getAttribute("href")==="#"&&c.addEventListener("click",i),e.addEventListener("click",i),e}var f=document.querySelector(".globaltoc a.current");f&&f.scrollIntoViewIfNeeded&&f.scrollIntoViewIfNeeded();I();var v=0,m=200,u=document.querySelectorAll(".yue > section section[id]"),r=document.querySelector(".back-to-top");function w(){let t=document.querySelector(".yue > section");t&&(m=t.computedStyleMap().get("scroll-margin-top").value)}function O(t){let e=t.getBoundingClientRect();return e.top<=m&&e.bottom>=m}function A(t){document.querySelectorAll(".localtoc li.active").forEach(e=>{e.classList.remove("active")}),document.querySelector(`.localtoc a[href="#${t}"]`).parentNode.classList.add("active")}function x(){let t;for(let e=0;e=document.body.offsetHeight){let t=u[u.length-1];t&&A(t.id)}else x();r&&(window.scrollY&&window.scrollY{window.scrollTo(0,0)});window.addEventListener("scroll",j);window.addEventListener("DOMContentLoaded",()=>{w(),x()});window.addEventListener("resize",w);var p=document.querySelector(".js-repo-stats");async function M(t,e){let o=`https://api.github.com/repos/${t}/${e}`,n=await(await fetch(o)).json(),s={stars:n.watchers,forks:n.forks};b(s),sessionStorage.setItem("_sy/repo/stats",JSON.stringify(s))}async function T(t,e){let o="https://gitlab.com/api/v4/projects/"+encodeURIComponent(t+"/"+e),n=await(await fetch(o)).json(),s={stars:n.star_count,forks:n.forks_count};b(s),sessionStorage.setItem("_sy/repo/stats",JSON.stringify(s))}function b({stars:t,forks:e}){t&&(document.querySelector(".js-repo-stars").textContent=t),e&&(document.querySelector(".js-repo-forks").textContent=e)}function B(){let t=sessionStorage.getItem("_sy/repo/stats");if(t)b(JSON.parse(t));else{let e=p.getAttribute("data-user"),o=p.getAttribute("data-repo"),c=p.getAttribute("data-type");c==="github"?M(e,o):c==="gitlab"&&T(e,o)}}p&&B();function R(t,e){let o=document.createElement("script");o.id="_carbonads_js",o.src=`//cdn.carbonads.com/carbon.js?serve=${t}&placement=${e}`;let c=document.querySelector(".yue > section"),n=document.querySelector(".yue > section > section");if(n)c.insertBefore(o,n);else{let s=document.querySelector(".yue > section > p");s?c.insertBefore(o,s.nextSibling):c.appendChild(o)}}var g=document.querySelector(".js-carbon");if(g){let t=g.getAttribute("data-carbon-code"),e=g.getAttribute("data-carbon-placement");t&&e&&R(t,e)}/windows/i.test(navigator.userAgent)&&document.body.classList.add("win");})(); 2 | -------------------------------------------------------------------------------- /docs/_build/html/genindex.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Index - PromptScript Documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 |
25 |
26 |
27 | 28 | 29 | 30 | PromptScript 31 | 32 |
33 | 34 |
35 | 36 | 37 | 38 |
39 |
40 |
52 |
53 |
54 |
55 |
56 |
57 | 58 | 59 |

Index

60 | 61 |
62 | 63 |
64 | 65 | 66 |
67 | 68 |
69 |
70 |
71 |
72 | 82 |
83 |
84 |
85 |
86 |
87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /docs/_build/html/_static/tabs.js: -------------------------------------------------------------------------------- 1 | try { 2 | var session = window.sessionStorage || {}; 3 | } catch (e) { 4 | var session = {}; 5 | } 6 | 7 | window.addEventListener("DOMContentLoaded", () => { 8 | const allTabs = document.querySelectorAll('.sphinx-tabs-tab'); 9 | const tabLists = document.querySelectorAll('[role="tablist"]'); 10 | 11 | allTabs.forEach(tab => { 12 | tab.addEventListener("click", changeTabs); 13 | }); 14 | 15 | tabLists.forEach(tabList => { 16 | tabList.addEventListener("keydown", keyTabs); 17 | }); 18 | 19 | // Restore group tab selection from session 20 | const lastSelected = session.getItem('sphinx-tabs-last-selected'); 21 | if (lastSelected != null) selectNamedTabs(lastSelected); 22 | }); 23 | 24 | /** 25 | * Key focus left and right between sibling elements using arrows 26 | * @param {Node} e the element in focus when key was pressed 27 | */ 28 | function keyTabs(e) { 29 | const tab = e.target; 30 | let nextTab = null; 31 | if (e.keyCode === 39 || e.keyCode === 37) { 32 | tab.setAttribute("tabindex", -1); 33 | // Move right 34 | if (e.keyCode === 39) { 35 | nextTab = tab.nextElementSibling; 36 | if (nextTab === null) { 37 | nextTab = tab.parentNode.firstElementChild; 38 | } 39 | // Move left 40 | } else if (e.keyCode === 37) { 41 | nextTab = tab.previousElementSibling; 42 | if (nextTab === null) { 43 | nextTab = tab.parentNode.lastElementChild; 44 | } 45 | } 46 | } 47 | 48 | if (nextTab !== null) { 49 | nextTab.setAttribute("tabindex", 0); 50 | nextTab.focus(); 51 | } 52 | } 53 | 54 | /** 55 | * Select or deselect clicked tab. If a group tab 56 | * is selected, also select tab in other tabLists. 57 | * @param {Node} e the element that was clicked 58 | */ 59 | function changeTabs(e) { 60 | // Use this instead of the element that was clicked, in case it's a child 61 | const notSelected = this.getAttribute("aria-selected") === "false"; 62 | const positionBefore = this.parentNode.getBoundingClientRect().top; 63 | const notClosable = !this.parentNode.classList.contains("closeable"); 64 | 65 | deselectTabList(this); 66 | 67 | if (notSelected || notClosable) { 68 | selectTab(this); 69 | const name = this.getAttribute("name"); 70 | selectNamedTabs(name, this.id); 71 | 72 | if (this.classList.contains("group-tab")) { 73 | // Persist during session 74 | session.setItem('sphinx-tabs-last-selected', name); 75 | } 76 | } 77 | 78 | const positionAfter = this.parentNode.getBoundingClientRect().top; 79 | const positionDelta = positionAfter - positionBefore; 80 | // Scroll to offset content resizing 81 | window.scrollTo(0, window.scrollY + positionDelta); 82 | } 83 | 84 | /** 85 | * Select tab and show associated panel. 86 | * @param {Node} tab tab to select 87 | */ 88 | function selectTab(tab) { 89 | tab.setAttribute("aria-selected", true); 90 | 91 | // Show the associated panel 92 | document 93 | .getElementById(tab.getAttribute("aria-controls")) 94 | .removeAttribute("hidden"); 95 | } 96 | 97 | /** 98 | * Hide the panels associated with all tabs within the 99 | * tablist containing this tab. 100 | * @param {Node} tab a tab within the tablist to deselect 101 | */ 102 | function deselectTabList(tab) { 103 | const parent = tab.parentNode; 104 | const grandparent = parent.parentNode; 105 | 106 | Array.from(parent.children) 107 | .forEach(t => t.setAttribute("aria-selected", false)); 108 | 109 | Array.from(grandparent.children) 110 | .slice(1) // Skip tablist 111 | .forEach(panel => panel.setAttribute("hidden", true)); 112 | } 113 | 114 | /** 115 | * Select grouped tabs with the same name, but no the tab 116 | * with the given id. 117 | * @param {Node} name name of grouped tab to be selected 118 | * @param {Node} clickedId id of clicked tab 119 | */ 120 | function selectNamedTabs(name, clickedId=null) { 121 | const groupedTabs = document.querySelectorAll(`.sphinx-tabs-tab[name="${name}"]`); 122 | const tabLists = Array.from(groupedTabs).map(tab => tab.parentNode); 123 | 124 | tabLists 125 | .forEach(tabList => { 126 | // Don't want to change the tabList containing the clicked tab 127 | const clickedTab = tabList.querySelector(`[id="${clickedId}"]`); 128 | if (clickedTab === null ) { 129 | // Select first tab with matching name 130 | const tab = tabList.querySelector(`.sphinx-tabs-tab[name="${name}"]`); 131 | deselectTabList(tab); 132 | selectTab(tab); 133 | } 134 | }) 135 | } 136 | 137 | if (typeof exports === 'undefined') { 138 | exports = {}; 139 | } 140 | 141 | exports.keyTabs = keyTabs; 142 | exports.changeTabs = changeTabs; 143 | exports.selectTab = selectTab; 144 | exports.deselectTabList = deselectTabList; 145 | exports.selectNamedTabs = selectNamedTabs; 146 | -------------------------------------------------------------------------------- /docs/_build/html/_static/doctools.js: -------------------------------------------------------------------------------- 1 | /* 2 | * doctools.js 3 | * ~~~~~~~~~~~ 4 | * 5 | * Base JavaScript utilities for all Sphinx HTML documentation. 6 | * 7 | * :copyright: Copyright 2007-2023 by the Sphinx team, see AUTHORS. 8 | * :license: BSD, see LICENSE for details. 9 | * 10 | */ 11 | "use strict"; 12 | 13 | const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ 14 | "TEXTAREA", 15 | "INPUT", 16 | "SELECT", 17 | "BUTTON", 18 | ]); 19 | 20 | const _ready = (callback) => { 21 | if (document.readyState !== "loading") { 22 | callback(); 23 | } else { 24 | document.addEventListener("DOMContentLoaded", callback); 25 | } 26 | }; 27 | 28 | /** 29 | * Small JavaScript module for the documentation. 30 | */ 31 | const Documentation = { 32 | init: () => { 33 | Documentation.initDomainIndexTable(); 34 | Documentation.initOnKeyListeners(); 35 | }, 36 | 37 | /** 38 | * i18n support 39 | */ 40 | TRANSLATIONS: {}, 41 | PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), 42 | LOCALE: "unknown", 43 | 44 | // gettext and ngettext don't access this so that the functions 45 | // can safely bound to a different name (_ = Documentation.gettext) 46 | gettext: (string) => { 47 | const translated = Documentation.TRANSLATIONS[string]; 48 | switch (typeof translated) { 49 | case "undefined": 50 | return string; // no translation 51 | case "string": 52 | return translated; // translation exists 53 | default: 54 | return translated[0]; // (singular, plural) translation tuple exists 55 | } 56 | }, 57 | 58 | ngettext: (singular, plural, n) => { 59 | const translated = Documentation.TRANSLATIONS[singular]; 60 | if (typeof translated !== "undefined") 61 | return translated[Documentation.PLURAL_EXPR(n)]; 62 | return n === 1 ? singular : plural; 63 | }, 64 | 65 | addTranslations: (catalog) => { 66 | Object.assign(Documentation.TRANSLATIONS, catalog.messages); 67 | Documentation.PLURAL_EXPR = new Function( 68 | "n", 69 | `return (${catalog.plural_expr})` 70 | ); 71 | Documentation.LOCALE = catalog.locale; 72 | }, 73 | 74 | /** 75 | * helper function to focus on search bar 76 | */ 77 | focusSearchBar: () => { 78 | document.querySelectorAll("input[name=q]")[0]?.focus(); 79 | }, 80 | 81 | /** 82 | * Initialise the domain index toggle buttons 83 | */ 84 | initDomainIndexTable: () => { 85 | const toggler = (el) => { 86 | const idNumber = el.id.substr(7); 87 | const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); 88 | if (el.src.substr(-9) === "minus.png") { 89 | el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; 90 | toggledRows.forEach((el) => (el.style.display = "none")); 91 | } else { 92 | el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; 93 | toggledRows.forEach((el) => (el.style.display = "")); 94 | } 95 | }; 96 | 97 | const togglerElements = document.querySelectorAll("img.toggler"); 98 | togglerElements.forEach((el) => 99 | el.addEventListener("click", (event) => toggler(event.currentTarget)) 100 | ); 101 | togglerElements.forEach((el) => (el.style.display = "")); 102 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); 103 | }, 104 | 105 | initOnKeyListeners: () => { 106 | // only install a listener if it is really needed 107 | if ( 108 | !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && 109 | !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS 110 | ) 111 | return; 112 | 113 | document.addEventListener("keydown", (event) => { 114 | // bail for input elements 115 | if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; 116 | // bail with special keys 117 | if (event.altKey || event.ctrlKey || event.metaKey) return; 118 | 119 | if (!event.shiftKey) { 120 | switch (event.key) { 121 | case "ArrowLeft": 122 | if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; 123 | 124 | const prevLink = document.querySelector('link[rel="prev"]'); 125 | if (prevLink && prevLink.href) { 126 | window.location.href = prevLink.href; 127 | event.preventDefault(); 128 | } 129 | break; 130 | case "ArrowRight": 131 | if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; 132 | 133 | const nextLink = document.querySelector('link[rel="next"]'); 134 | if (nextLink && nextLink.href) { 135 | window.location.href = nextLink.href; 136 | event.preventDefault(); 137 | } 138 | break; 139 | } 140 | } 141 | 142 | // some keyboard layouts may need Shift to get / 143 | switch (event.key) { 144 | case "/": 145 | if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; 146 | Documentation.focusSearchBar(); 147 | event.preventDefault(); 148 | } 149 | }); 150 | }, 151 | }; 152 | 153 | // quick alias for translations 154 | const _ = Documentation.gettext; 155 | 156 | _ready(Documentation.init); 157 | -------------------------------------------------------------------------------- /docs/_build/html/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 404 - PromptScript Documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 33 | 34 |
35 |
36 |
37 | 38 | 39 | 40 | PromptScript 41 | 42 |
43 | 44 |
45 | 46 | 47 | 48 |
49 |
50 |
62 |
63 |
64 |
65 |
66 | 82 | 83 |
84 |
85 |
86 |
87 | 97 |
98 |
99 |
100 |
101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /docs/_build/html/_static/sphinx_highlight.js: -------------------------------------------------------------------------------- 1 | /* Highlighting utilities for Sphinx HTML documentation. */ 2 | "use strict"; 3 | 4 | const SPHINX_HIGHLIGHT_ENABLED = true 5 | 6 | /** 7 | * highlight a given string on a node by wrapping it in 8 | * span elements with the given class name. 9 | */ 10 | const _highlight = (node, addItems, text, className) => { 11 | if (node.nodeType === Node.TEXT_NODE) { 12 | const val = node.nodeValue; 13 | const parent = node.parentNode; 14 | const pos = val.toLowerCase().indexOf(text); 15 | if ( 16 | pos >= 0 && 17 | !parent.classList.contains(className) && 18 | !parent.classList.contains("nohighlight") 19 | ) { 20 | let span; 21 | 22 | const closestNode = parent.closest("body, svg, foreignObject"); 23 | const isInSVG = closestNode && closestNode.matches("svg"); 24 | if (isInSVG) { 25 | span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); 26 | } else { 27 | span = document.createElement("span"); 28 | span.classList.add(className); 29 | } 30 | 31 | span.appendChild(document.createTextNode(val.substr(pos, text.length))); 32 | parent.insertBefore( 33 | span, 34 | parent.insertBefore( 35 | document.createTextNode(val.substr(pos + text.length)), 36 | node.nextSibling 37 | ) 38 | ); 39 | node.nodeValue = val.substr(0, pos); 40 | 41 | if (isInSVG) { 42 | const rect = document.createElementNS( 43 | "http://www.w3.org/2000/svg", 44 | "rect" 45 | ); 46 | const bbox = parent.getBBox(); 47 | rect.x.baseVal.value = bbox.x; 48 | rect.y.baseVal.value = bbox.y; 49 | rect.width.baseVal.value = bbox.width; 50 | rect.height.baseVal.value = bbox.height; 51 | rect.setAttribute("class", className); 52 | addItems.push({ parent: parent, target: rect }); 53 | } 54 | } 55 | } else if (node.matches && !node.matches("button, select, textarea")) { 56 | node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); 57 | } 58 | }; 59 | const _highlightText = (thisNode, text, className) => { 60 | let addItems = []; 61 | _highlight(thisNode, addItems, text, className); 62 | addItems.forEach((obj) => 63 | obj.parent.insertAdjacentElement("beforebegin", obj.target) 64 | ); 65 | }; 66 | 67 | /** 68 | * Small JavaScript module for the documentation. 69 | */ 70 | const SphinxHighlight = { 71 | 72 | /** 73 | * highlight the search words provided in localstorage in the text 74 | */ 75 | highlightSearchWords: () => { 76 | if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight 77 | 78 | // get and clear terms from localstorage 79 | const url = new URL(window.location); 80 | const highlight = 81 | localStorage.getItem("sphinx_highlight_terms") 82 | || url.searchParams.get("highlight") 83 | || ""; 84 | localStorage.removeItem("sphinx_highlight_terms") 85 | url.searchParams.delete("highlight"); 86 | window.history.replaceState({}, "", url); 87 | 88 | // get individual terms from highlight string 89 | const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); 90 | if (terms.length === 0) return; // nothing to do 91 | 92 | // There should never be more than one element matching "div.body" 93 | const divBody = document.querySelectorAll("div.body"); 94 | const body = divBody.length ? divBody[0] : document.querySelector("body"); 95 | window.setTimeout(() => { 96 | terms.forEach((term) => _highlightText(body, term, "highlighted")); 97 | }, 10); 98 | 99 | const searchBox = document.getElementById("searchbox"); 100 | if (searchBox === null) return; 101 | searchBox.appendChild( 102 | document 103 | .createRange() 104 | .createContextualFragment( 105 | '" 109 | ) 110 | ); 111 | }, 112 | 113 | /** 114 | * helper function to hide the search marks again 115 | */ 116 | hideSearchWords: () => { 117 | document 118 | .querySelectorAll("#searchbox .highlight-link") 119 | .forEach((el) => el.remove()); 120 | document 121 | .querySelectorAll("span.highlighted") 122 | .forEach((el) => el.classList.remove("highlighted")); 123 | localStorage.removeItem("sphinx_highlight_terms") 124 | }, 125 | 126 | initEscapeListener: () => { 127 | // only install a listener if it is really needed 128 | if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; 129 | 130 | document.addEventListener("keydown", (event) => { 131 | // bail for input elements 132 | if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; 133 | // bail with special keys 134 | if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; 135 | if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { 136 | SphinxHighlight.hideSearchWords(); 137 | event.preventDefault(); 138 | } 139 | }); 140 | }, 141 | }; 142 | 143 | _ready(SphinxHighlight.highlightSearchWords); 144 | _ready(SphinxHighlight.initEscapeListener); 145 | -------------------------------------------------------------------------------- /promptscript/interpreter.py: -------------------------------------------------------------------------------- 1 | from typing import List, Tuple 2 | from promptscript.utils.numbers import is_number 3 | from promptscript.utils.debug_level import DebugLevel 4 | 5 | PARSER_CONVERSION = {'show':'print_operator', '"':'quote', "'":'quote', '=':'equals', 'load':'load_operator', 6 | 'save':'save_to_file', 'chat':'chat_operator', 'draw':'draw_operator', 7 | 'listen':'listen_operator', 'if': 'if_conditional', 'elif': 'elif_conditional', 8 | 'else': 'else_conditional', 'for': 'for_loop', 'in': 'in_operator', 'while': 'while_loop', 9 | ']': 'chain_close', 'yield': 'yield_operator', 'read': 'read_operator'} 10 | INTERPRETER_CONVERSION = {'print_operator':'print(', 'load_operator':'get_environment_variable(', 11 | 'save_to_file':'save_to_file(', 'equals':'=', 'chat_operator':'route_chat(', 12 | 'draw_operator':'route_draw(', 'listen_operator':'route_listen(', 13 | 'if_conditional': 'if ', 'elif_conditional': 'elif ', 'else_conditional': 'else', 14 | 'for_loop': 'for ', 'in_operator': ' in ', 'while_loop': 'while ', 'chain_close': ')', 15 | 'yield_operator': 'yield_output(', 'read_operator':'read_file('} 16 | PORTED_OPERATIONS = ['.format'] 17 | STANDALONE_CHARACTERS = ['=', '\t', ':', ']', '\n', '('] 18 | PROTECTED_BLOCK_CHARACTERS = ['"', "'"] 19 | OPERATOR_CHARACTERS = ['+', '-', '*', '/'] 20 | NEW_PART_CHARACTERS = [' ', '['] 21 | 22 | 23 | def lex(command: str, DEBUG_LEVEL: DebugLevel) -> List[str]: 24 | parts = [] 25 | current_block = '' 26 | is_protected_block = False 27 | for i, char in enumerate(command): 28 | if char in PROTECTED_BLOCK_CHARACTERS: 29 | if not is_protected_block: 30 | is_protected_block = True 31 | parts.append(char) 32 | else: 33 | is_protected_block = False 34 | parts.append(current_block) 35 | parts.append(char) 36 | current_block = '' 37 | 38 | elif char in STANDALONE_CHARACTERS: 39 | if not is_protected_block: 40 | parts.append(current_block) 41 | parts.append(char) 42 | current_block = '' 43 | else: 44 | current_block += char 45 | 46 | elif char in NEW_PART_CHARACTERS or current_block in PORTED_OPERATIONS: 47 | if not is_protected_block: 48 | parts.append(current_block) 49 | current_block = '' 50 | else: 51 | current_block += char 52 | 53 | elif char not in NEW_PART_CHARACTERS: 54 | current_block += char 55 | 56 | if len(current_block) != 0: 57 | parts.append(current_block) 58 | parts = [part for part in parts if part != ''] 59 | 60 | if DEBUG_LEVEL <= DebugLevel.DEBUG: 61 | print(f'LEXED PARTS :: {parts}') 62 | 63 | return parts 64 | 65 | def parse(command: str, DEBUG_LEVEL: DebugLevel) -> List[Tuple]: 66 | parts = lex(command, DEBUG_LEVEL) 67 | 68 | parsed_operations = [] 69 | is_open = False 70 | for i, part in enumerate(parts): 71 | try: 72 | if part.lower() in PROTECTED_BLOCK_CHARACTERS: 73 | is_open = not is_open 74 | parse_operation = (PARSER_CONVERSION[part.lower()], part.lower()) 75 | elif is_open: 76 | parse_operation = ('msg', part) 77 | elif is_number(part) and not is_open: 78 | parse_operation = ('num', part) 79 | elif not is_open and part.lower() not in PARSER_CONVERSION: 80 | parse_operation = ('var', part) 81 | else: 82 | parse_operation = (PARSER_CONVERSION[part.lower()], part.lower()) 83 | 84 | parsed_operations.append(parse_operation) 85 | except KeyError: 86 | if DEBUG_LEVEL <= DebugLevel.ERROR: 87 | raise SyntaxError(f"SYNTAX ERROR: Unexpected token '{part}'") 88 | 89 | if DEBUG_LEVEL <= DebugLevel.DEBUG: 90 | print(f'PARSED PARTS :: {parsed_operations}') 91 | 92 | return parsed_operations 93 | 94 | def interpret(command: str, DEBUG_LEVEL: DebugLevel=DebugLevel.INFO) -> str: 95 | parsed_operations = parse(command, DEBUG_LEVEL) 96 | 97 | interpreted_commands = [] 98 | current_interpreted_command = '' 99 | for op_name, part in parsed_operations: 100 | conversion = INTERPRETER_CONVERSION.get(op_name, part) 101 | if conversion == '\n': 102 | interpreted_commands.append(current_interpreted_command) 103 | current_interpreted_command = '' 104 | continue 105 | else: 106 | current_interpreted_command += str(conversion) 107 | if current_interpreted_command: 108 | interpreted_commands.append(current_interpreted_command) 109 | 110 | for i, interpreted_command in enumerate(interpreted_commands): 111 | for _ in range(interpreted_command.count('(') - interpreted_command.count(')')): 112 | interpreted_commands[i] += ')' 113 | 114 | if DEBUG_LEVEL <= DebugLevel.DEBUG: 115 | print(f'INTERPRETED COMMANDS :: {interpreted_commands}') 116 | 117 | return '\n'.join(interpreted_commands) -------------------------------------------------------------------------------- /docs/_build/html/install.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Installation - PromptScript Documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 |
27 |
28 |
29 | 30 | 31 | 32 | PromptScript 33 | 34 |
35 | 36 |
37 | 38 | 39 | 40 |
41 |
42 |
54 |
55 |
56 |
57 |
58 | 88 | 89 | 99 | 100 |
123 |
124 |
125 |
126 |

Installation

127 |

Install the PromptScript language and Python package.

128 |
129 |
130 |

pip install

131 |
$ pip install promptscript==0.3.0
132 |
133 |
134 |

Verifying

135 |

To make sure PromptScript was installed correctly, you can run:

136 |
promptscript
137 | 
138 |
139 |

Or:

140 |
python -m promptscript
141 | 
142 |
143 |

If the installation was successful, running these commands should bring up the PromptScript CLI.

144 |
145 |
146 | 147 |
167 |
168 |
169 |
170 |
171 |
172 |
173 | 183 |
184 |
185 |
186 |
187 |
188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /docs/_build/html/basic/chaining.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chaining - PromptScript Documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 |
31 | 32 | 33 | 34 | PromptScript 35 | 36 |
37 | 38 |
39 | 40 | 41 | 42 |
43 |
44 |
56 |
57 |
58 |
59 |
60 | 90 | 91 | 97 | 98 |
125 |
126 |
127 |
128 |

Chaining

129 |

Chaning multiple PromptScript commands together.

130 |
131 |

To pass the output of one process as the parameter of another, surround it in square brackets ([]). Example:

132 |
save [chat "<prompt>", "<model>", "<api_key>"], "file.txt"
133 | 
134 |
135 |
136 |

Note

137 |

Chaining isn’t required for passing the output of one process into a method that only takes one parameter 138 | (e.g. show). It’s still recommended for readability.

139 |
140 |
141 | 142 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | 178 |
179 |
180 |
181 |
182 |
183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /docs/_build/html/basic/conditionals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Conditionals - PromptScript Documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 |
31 | 32 | 33 | 34 | PromptScript 35 | 36 |
37 | 38 |
39 | 40 | 41 | 42 |
43 |
44 |
56 |
57 |
58 |
59 |
60 | 90 | 91 | 97 | 98 |
125 |
126 |
127 |
128 |

Conditionals

129 |

Using conditionals in PromptScript.

130 |
131 |

Conditionals in PromptScript function the same as in python:

132 |
1number = 8
133 | 2guess = 5
134 | 3
135 | 4if guess > number:
136 | 5    show "your guess is too high."
137 | 6elif guess < number:
138 | 7    show "your guess is too low."
139 | 8else:
140 | 9    show "you guessed correctly!"
141 | 
142 |
143 |
144 | 145 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | 181 |
182 |
183 |
184 |
185 |
186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /docs/_build/html/basic/show.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Printing - PromptScript Documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 |
31 | 32 | 33 | 34 | PromptScript 35 | 36 |
37 | 38 |
39 | 40 | 41 | 42 |
43 |
44 |
56 |
57 |
58 |
59 |
60 | 90 | 91 | 97 | 98 |
125 |
126 |
127 |
128 |

Printing

129 |

Using show to print values in PromptScript.

130 |
131 |
1show "Hello, World!"
132 | 2show "{} - {}".format("Slot 1", "Slot 2")
133 | 
134 |
135 |
136 |

Note

137 |

Strings can also be created with single quotes

138 |
139 |

You can also print variables:

140 |
message = "Hello, World!"
141 | show message
142 | 
143 |
144 |

Or the output from another process:

145 |
show [read "file.txt"]
146 | 
147 |
148 |
149 |

Tip

150 |

The square brackets ([]) are for chaining. Learn more about operation chaining here.

151 |
152 |
153 | 154 |
174 |
175 |
176 |
177 |
178 |
179 |
180 | 190 |
191 |
192 |
193 |
194 |
195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /docs/_build/html/ai/listen.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Transcription - PromptScript Documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 |
27 |
28 |
29 | 30 | 31 | 32 | PromptScript 33 | 34 |
35 | 36 |
37 | 38 | 39 | 40 |
41 |
42 |
54 |
55 |
56 |
57 |
58 | 88 | 89 | 98 | 99 |
126 |
127 |
128 |
129 |

Transcription

130 |

Using listen to perform speech-to-text tasks

131 |
132 |

PromptScript currently supports audio transcription using OpenAI’s Whisper 133 | through the listen keyword.

134 |
135 |

Syntax

136 |
listen file_path, api_key
137 | 
138 |
139 |

Parameters

140 |
141 |

file_path (str: required): File to transcribe.

142 |

api_key (str: required): OpenAI API key.

143 |
144 |

Output

145 |
146 |

str: Transcribed text.

147 |
148 |
149 |

Note

150 |

The following file formats are supported: .mp3, .mp4, .wav, .mpeg, .mpga, .webm

151 |
152 |
153 |
154 | 155 |
175 |
176 |
177 |
178 |
179 |
180 |
181 | 191 |
192 |
193 |
194 |
195 |
196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /docs/_build/html/_static/pygments.css: -------------------------------------------------------------------------------- 1 | :root{--syntax-pre-bg: var(--accent-a2);--syntax-cap-bg: var(--accent-a3);--syntax-highlight-bg: var(--accent-a3);--syntax-linenos-divider: var(--gray-a6);--syntax-light-text: #24292f;--syntax-light-meta: #807c87;--syntax-light-comment: #6e7781;--syntax-light-constant: #0550ae;--syntax-light-entity: #268bd2;--syntax-light-property: #8250df;--syntax-light-definition: #24292f;--syntax-light-tag: #085;--syntax-light-builtin: #b58900;--syntax-light-keyword: #cf222e;--syntax-light-exception: #e6212e;--syntax-light-string: #0a3069;--syntax-light-regexp: #e40;--syntax-light-variable: #a4480f;--syntax-light-invalid-illegal-text: #f6f8fa;--syntax-light-invalid-illegal-bg: #82071e;--syntax-light-markup-heading: #0550ae;--syntax-light-markup-italic: #24292f;--syntax-light-markup-bold: #24292f;--syntax-light-markup-deleted-text: #82071e;--syntax-light-markup-deleted-bg: #FFEBE9;--syntax-light-markup-inserted-text: #116329;--syntax-light-markup-inserted-bg: #dafbe1;--syntax-light-markup-changed-text: #953800;--syntax-light-markup-changed-bg: #ffd8b5;--syntax-light-markup-ignored-text: #eaeef2;--syntax-light-markup-ignored-bg: #0550ae;--syntax-light-meta-diff-range: #8250df;--syntax-light-special-bg: #dccafa;--syntax-dark-text: #c9d1d9;--syntax-dark-meta: #6e7781;--syntax-dark-comment: #8b949e;--syntax-dark-constant: #79c0ff;--syntax-dark-entity: #47b0fa;--syntax-dark-property: #d2a8ff;--syntax-dark-definition: #c9d1d9;--syntax-dark-tag: #7ee787;--syntax-dark-builtin: #ffd34c;--syntax-dark-keyword: #ff7b72;--syntax-dark-exception: #da473c;--syntax-dark-string: #a5d6ff;--syntax-dark-regexp: #ef954e;--syntax-dark-variable: #ffa657;--syntax-dark-invalid-illegal-text: #f0f6fc;--syntax-dark-invalid-illegal-bg: #8e1519;--syntax-dark-markup-heading: #1f6feb;--syntax-dark-markup-italic: #c9d1d9;--syntax-dark-markup-bold: #c9d1d9;--syntax-dark-markup-deleted-text: #ffdcd7;--syntax-dark-markup-deleted-bg: #67060c;--syntax-dark-markup-inserted-text: #aff5b4;--syntax-dark-markup-inserted-bg: #033a16;--syntax-dark-markup-changed-text: #ffdfb6;--syntax-dark-markup-changed-bg: #5a1e02;--syntax-dark-markup-ignored-text: #c9d1d9;--syntax-dark-markup-ignored-bg: #1158c7;--syntax-dark-meta-diff-range: #d2a8ff;--syntax-dark-special-bg: #4f425d}:root,html.light{--syntax-text: var(--syntax-light-text);--syntax-meta: var(--syntax-light-meta);--syntax-comment: var(--syntax-light-comment);--syntax-constant: var(--syntax-light-constant);--syntax-entity: var(--syntax-light-entity);--syntax-property: var(--syntax-light-property);--syntax-definition: var(--syntax-light-definition);--syntax-tag: var(--syntax-light-tag);--syntax-builtin: var(--syntax-light-builtin);--syntax-keyword: var(--syntax-light-keyword);--syntax-exception: var(--syntax-light-exception);--syntax-string: var(--syntax-light-string);--syntax-regexp: var(--syntax-light-regexp);--syntax-variable: var(--syntax-light-variable);--syntax-invalid-illegal-text: var(--syntax-light-invalid-illegal-text);--syntax-invalid-illegal-bg: var(--syntax-light-invalid-illegal-bg);--syntax-markup-heading: var(--syntax-light-markup-heading);--syntax-markup-italic: var(--syntax-light-markup-italic);--syntax-markup-bold: var(--syntax-light-markup-bold);--syntax-markup-deleted-text: var(--syntax-light-markup-deleted-text);--syntax-markup-deleted-bg: var(--syntax-light-markup-deleted-bg);--syntax-markup-inserted-text: var(--syntax-light-markup-inserted-text);--syntax-markup-inserted-bg: var(--syntax-light-markup-inserted-bg);--syntax-markup-changed-text: var(--syntax-light-markup-changed-text);--syntax-markup-changed-bg: var(--syntax-light-markup-changed-bg);--syntax-markup-ignored-text: var(--syntax-light-markup-ignored-text);--syntax-markup-ignored-bg: var(--syntax-light-markup-ignored-bg);--syntax-meta-diff-range: var(--syntax-light-meta-diff-range);--syntax-special-bg: var(--syntax-light-special-bg)}@media (prefers-color-scheme: dark){:root{--syntax-text: var(--syntax-dark-text);--syntax-meta: var(--syntax-dark-meta);--syntax-comment: var(--syntax-dark-comment);--syntax-constant: var(--syntax-dark-constant);--syntax-entity: var(--syntax-dark-entity);--syntax-property: var(--syntax-dark-property);--syntax-definition: var(--syntax-dark-definition);--syntax-tag: var(--syntax-dark-tag);--syntax-builtin: var(--syntax-dark-builtin);--syntax-keyword: var(--syntax-dark-keyword);--syntax-exception: var(--syntax-dark-exception);--syntax-string: var(--syntax-dark-string);--syntax-regexp: var(--syntax-dark-regexp);--syntax-variable: var(--syntax-dark-variable);--syntax-invalid-illegal-text: var(--syntax-dark-invalid-illegal-text);--syntax-invalid-illegal-bg: var(--syntax-dark-invalid-illegal-bg);--syntax-markup-heading: var(--syntax-dark-markup-heading);--syntax-markup-italic: var(--syntax-dark-markup-italic);--syntax-markup-bold: var(--syntax-dark-markup-bold);--syntax-markup-deleted-text: var(--syntax-dark-markup-deleted-text);--syntax-markup-deleted-bg: var(--syntax-dark-markup-deleted-bg);--syntax-markup-inserted-text: var(--syntax-dark-markup-inserted-text);--syntax-markup-inserted-bg: var(--syntax-dark-markup-inserted-bg);--syntax-markup-changed-text: var(--syntax-dark-markup-changed-text);--syntax-markup-changed-bg: var(--syntax-dark-markup-changed-bg);--syntax-markup-ignored-text: var(--syntax-dark-markup-ignored-text);--syntax-markup-ignored-bg: var(--syntax-dark-markup-ignored-bg);--syntax-meta-diff-range: var(--syntax-dark-meta-diff-range);--syntax-special-bg: var(--syntax-dark-special-bg)}}html.dark{--syntax-text: var(--syntax-dark-text);--syntax-meta: var(--syntax-dark-meta);--syntax-comment: var(--syntax-dark-comment);--syntax-constant: var(--syntax-dark-constant);--syntax-entity: var(--syntax-dark-entity);--syntax-property: var(--syntax-dark-property);--syntax-definition: var(--syntax-dark-definition);--syntax-tag: var(--syntax-dark-tag);--syntax-builtin: var(--syntax-dark-builtin);--syntax-keyword: var(--syntax-dark-keyword);--syntax-exception: var(--syntax-dark-exception);--syntax-string: var(--syntax-dark-string);--syntax-regexp: var(--syntax-dark-regexp);--syntax-variable: var(--syntax-dark-variable);--syntax-invalid-illegal-text: var(--syntax-dark-invalid-illegal-text);--syntax-invalid-illegal-bg: var(--syntax-dark-invalid-illegal-bg);--syntax-markup-heading: var(--syntax-dark-markup-heading);--syntax-markup-italic: var(--syntax-dark-markup-italic);--syntax-markup-bold: var(--syntax-dark-markup-bold);--syntax-markup-deleted-text: var(--syntax-dark-markup-deleted-text);--syntax-markup-deleted-bg: var(--syntax-dark-markup-deleted-bg);--syntax-markup-inserted-text: var(--syntax-dark-markup-inserted-text);--syntax-markup-inserted-bg: var(--syntax-dark-markup-inserted-bg);--syntax-markup-changed-text: var(--syntax-dark-markup-changed-text);--syntax-markup-changed-bg: var(--syntax-dark-markup-changed-bg);--syntax-markup-ignored-text: var(--syntax-dark-markup-ignored-text);--syntax-markup-ignored-bg: var(--syntax-dark-markup-ignored-bg);--syntax-meta-diff-range: var(--syntax-dark-meta-diff-range);--syntax-special-bg: var(--syntax-dark-special-bg)}.light .dark-code{--syntax-pre-bg: var(--black-a12);--syntax-cap-bg: #1C2024;--syntax-highlight-bg: var(--white-a2);--syntax-linenos-divider: var(--white-a4);--syntax-text: var(--syntax-dark-text);--syntax-meta: var(--syntax-dark-meta);--syntax-comment: var(--syntax-dark-comment);--syntax-constant: var(--syntax-dark-constant);--syntax-entity: var(--syntax-dark-entity);--syntax-property: var(--syntax-dark-property);--syntax-definition: var(--syntax-dark-definition);--syntax-tag: var(--syntax-dark-tag);--syntax-builtin: var(--syntax-dark-builtin);--syntax-keyword: var(--syntax-dark-keyword);--syntax-exception: var(--syntax-dark-exception);--syntax-string: var(--syntax-dark-string);--syntax-regexp: var(--syntax-dark-regexp);--syntax-variable: var(--syntax-dark-variable);--syntax-invalid-illegal-text: var(--syntax-dark-invalid-illegal-text);--syntax-invalid-illegal-bg: var(--syntax-dark-invalid-illegal-bg);--syntax-markup-heading: var(--syntax-dark-markup-heading);--syntax-markup-italic: var(--syntax-dark-markup-italic);--syntax-markup-bold: var(--syntax-dark-markup-bold);--syntax-markup-deleted-text: var(--syntax-dark-markup-deleted-text);--syntax-markup-deleted-bg: var(--syntax-dark-markup-deleted-bg);--syntax-markup-inserted-text: var(--syntax-dark-markup-inserted-text);--syntax-markup-inserted-bg: var(--syntax-dark-markup-inserted-bg);--syntax-markup-changed-text: var(--syntax-dark-markup-changed-text);--syntax-markup-changed-bg: var(--syntax-dark-markup-changed-bg);--syntax-markup-ignored-text: var(--syntax-dark-markup-ignored-text);--syntax-markup-ignored-bg: var(--syntax-dark-markup-ignored-bg);--syntax-meta-diff-range: var(--syntax-dark-meta-diff-range);--syntax-special-bg: var(--syntax-dark-special-bg)}html.light .sd-tab-content,html.light .jupyter_container .cell_output{--syntax-pre-bg: var(--color-surface-accent);--syntax-cap-bg: var(--accent-3);--syntax-highlight-bg: var(--accent-a3);--syntax-text: var(--syntax-light-text);--syntax-meta: var(--syntax-light-meta);--syntax-comment: var(--syntax-light-comment);--syntax-constant: var(--syntax-light-constant);--syntax-entity: var(--syntax-light-entity);--syntax-property: var(--syntax-light-property);--syntax-definition: var(--syntax-light-definition);--syntax-tag: var(--syntax-light-tag);--syntax-builtin: var(--syntax-light-builtin);--syntax-keyword: var(--syntax-light-keyword);--syntax-exception: var(--syntax-light-exception);--syntax-string: var(--syntax-light-string);--syntax-regexp: var(--syntax-light-regexp);--syntax-variable: var(--syntax-light-variable);--syntax-invalid-illegal-text: var(--syntax-light-invalid-illegal-text);--syntax-invalid-illegal-bg: var(--syntax-light-invalid-illegal-bg);--syntax-markup-heading: var(--syntax-light-markup-heading);--syntax-markup-italic: var(--syntax-light-markup-italic);--syntax-markup-bold: var(--syntax-light-markup-bold);--syntax-markup-deleted-text: var(--syntax-light-markup-deleted-text);--syntax-markup-deleted-bg: var(--syntax-light-markup-deleted-bg);--syntax-markup-inserted-text: var(--syntax-light-markup-inserted-text);--syntax-markup-inserted-bg: var(--syntax-light-markup-inserted-bg);--syntax-markup-changed-text: var(--syntax-light-markup-changed-text);--syntax-markup-changed-bg: var(--syntax-light-markup-changed-bg);--syntax-markup-ignored-text: var(--syntax-light-markup-ignored-text);--syntax-markup-ignored-bg: var(--syntax-light-markup-ignored-bg);--syntax-meta-diff-range: var(--syntax-light-meta-diff-range);--syntax-highlight-bg: var(--syntax-light-highlight-bg);--syntax-special-bg: var(--syntax-light-special-bg)}.highlight{color:var(--syntax-text);background-color:transparent}.highlight .hll{display:block;background-color:var(--syntax-highlight-bg)}.highlight .c{color:var(--syntax-comment)}.highlight .err{color:var(--syntax-invalid-illegal-text);background-color:var(--syntax-invalid-illegal-bg)}.highlight .g{color:var(--syntax-meta)}.highlight .k{color:var(--syntax-keyword)}.highlight .l{color:var(--syntax-meta)}.highlight .o{color:var(--syntax-constant)}.highlight .x{color:var(--syntax-meta)}.highlight .cm{color:var(--syntax-comment)}.highlight .cp{color:var(--syntax-constant)}.highlight .c1{color:var(--syntax-comment)}.highlight .cs{color:var(--syntax-comment);background-color:var(--syntax-special-bg)}.highlight .gd{color:var(--syntax-markup-deleted-text);background-color:var(--syntax-markup-deleted-bg)}.highlight .ge{color:var(--syntax-markup-italic);font-style:italic}.highlight .gr{color:var(--syntax-invalid-illegal-text);background-color:var(--syntax-invalid-illegal-bg)}.highlight .gh{color:var(--syntax-markup-heading)}.highlight .gi{color:var(--syntax-markup-inserted-text);background-color:var(--syntax-markup-inserted-bg)}.highlight .go,.highlight .gp{color:var(--syntax-meta)}.highlight .gs{color:var(--syntax-markup-bold);font-weight:700}.highlight .gu{color:var(--syntax-markup-heading)}.highlight .gt{color:var(--syntax-meta)}.highlight .kc{color:var(--syntax-constant)}.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr{color:var(--syntax-keyword)}.highlight .kt{color:var(--syntax-entity)}.highlight .ld{color:var(--syntax-meta)}.highlight .m{color:var(--syntax-constant)}.highlight .s{color:var(--syntax-string)}.highlight .il,.highlight .na{color:var(--syntax-constant)}.highlight .nb{color:var(--syntax-builtin)}.highlight .nc{color:var(--syntax-definition)}.highlight .no{color:var(--syntax-constant)}.highlight .nd,.highlight .ni{color:var(--syntax-entity)}.highlight .ne{color:var(--syntax-exception)}.highlight .nf{color:var(--syntax-definition)}.highlight .nt{color:var(--syntax-tag)}.highlight .ow{color:var(--syntax-constant)}.highlight .w{color:var(--syntax-meta)}.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo{color:var(--syntax-constant)}.highlight .sb{color:var(--syntax-meta)}.highlight .sc{color:var(--syntax-string)}.highlight .sd{color:var(--syntax-comment)}.highlight .s2,.highlight .se{color:var(--syntax-string)}.highlight .sh{color:var(--syntax-comment)}.highlight .si,.highlight .sx{color:var(--syntax-string)}.highlight .sr{color:var(--syntax-regexp)}.highlight .s1,.highlight .ss{color:var(--syntax-string)}.highlight .bp,.highlight .vc,.highlight .vg,.highlight .vi{color:var(--syntax-variable)} 2 | -------------------------------------------------------------------------------- /docs/_build/html/basic/loops.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Loops - PromptScript Documentation 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 |
31 | 32 | 33 | 34 | PromptScript 35 | 36 |
37 | 38 |
39 | 40 | 41 | 42 |
43 |
44 |
56 |
57 |
58 |
59 |
60 | 90 | 91 | 101 | 102 |
129 |
130 |
131 |
132 |

Loops

133 |

Writing for and while loops in PromptScript.

134 |
135 |

Loops in PromptScript function the same as in Python:

136 |
137 |

For Loops

138 |
for i in range(1, 11):
139 |     show i
140 | 
141 |
142 |

You can also use len:

143 |
string = "word"
144 | for i in range(len(string)):
145 |     show i
146 | 
147 |
148 |

Or iterate through values:

149 |
string = "word"
150 | for character in string:
151 |     show character
152 | 
153 |
154 |
155 |
156 |

While Loops

157 |
x = 10
158 | while x > 0:
159 |     show x
160 |     x -= 1
161 | 
162 |
163 |
164 |
165 | 166 |
186 |
187 |
188 |
189 |
190 |
191 |
192 | 202 |
203 |
204 |
205 |
206 |
207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | --------------------------------------------------------------------------------