mirror of
https://github.com/danielmiessler/Fabric.git
synced 2026-01-09 22:38:10 -05:00
Compare commits
28 Commits
v1.1.0
...
transcribe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbfea93b6c | ||
|
|
c4332c9ee0 | ||
|
|
92f8e08aac | ||
|
|
62f3608144 | ||
|
|
20c1ad90bb | ||
|
|
e866eeafa6 | ||
|
|
5e48c0ef2c | ||
|
|
61421c28cb | ||
|
|
7ebf5bc905 | ||
|
|
9cd15d725c | ||
|
|
138c779f5e | ||
|
|
31ab369e2f | ||
|
|
983084e4f0 | ||
|
|
ed847fd332 | ||
|
|
373d362d35 | ||
|
|
6dff639969 | ||
|
|
6414c26636 | ||
|
|
bc4456b310 | ||
|
|
873bca5230 | ||
|
|
5d984f3687 | ||
|
|
9863573ff6 | ||
|
|
335fea353b | ||
|
|
a0d264bead | ||
|
|
d15e022abf | ||
|
|
8f4ab672c6 | ||
|
|
b127fbec15 | ||
|
|
0deab1ebb3 | ||
|
|
8aacaee643 |
30
README.md
30
README.md
@@ -96,7 +96,7 @@ Fabric has Patterns for all sorts of life and work activities, including:
|
||||
- Getting summaries of long, boring content
|
||||
- Explaining code to you
|
||||
- Turning bad documentation into usable documentation
|
||||
- Create social media posts from any content input
|
||||
- Creating social media posts from any content input
|
||||
- And a million more…
|
||||
|
||||
### Our approach to prompting
|
||||
@@ -146,7 +146,13 @@ git clone https://github.com/danielmiessler/fabric.git
|
||||
cd fabric
|
||||
```
|
||||
|
||||
4. Install poetry
|
||||
4. Ensure the `setup.sh` script is executable. If you're not sure, you can make it executable by running the following command:
|
||||
|
||||
```bash
|
||||
chmod +x setup.sh
|
||||
```
|
||||
|
||||
5. Install poetry
|
||||
|
||||
ref.: https://python-poetry.org/docs/#installing-with-the-official-installer
|
||||
|
||||
@@ -154,17 +160,18 @@ ref.: https://python-poetry.org/docs/#installing-with-the-official-installer
|
||||
curl -sSL https://install.python-poetry.org | python3 -
|
||||
```
|
||||
|
||||
5. Run the `setup.sh`, which will do the following:
|
||||
- Installs python dependencies.
|
||||
- Creates aliases in your OS. It should update `~/.bashrc`, `/.zshrc`, and `~/.bash_profile` if they are present in your file system.
|
||||
6. Run the `setup.sh`, which will do the following:
|
||||
|
||||
- Installs python dependencies.
|
||||
- Creates aliases in your OS. It should update `~/.bashrc`, `/.zshrc`, and `~/.bash_profile` if they are present in your file system.
|
||||
|
||||
```bash
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
6. Restart your shell to reload everything.
|
||||
7. Restart your shell to reload everything.
|
||||
|
||||
7. Set your `OPENAI_API_KEY`.
|
||||
8. Set your `OPENAI_API_KEY`.
|
||||
|
||||
```bash
|
||||
fabric --setup
|
||||
@@ -172,7 +179,7 @@ fabric --setup
|
||||
|
||||
You'll be asked to enter your OpenAI API key, which will be written to `~/.config/fabric/.env`. Patterns will then be downloaded from Github, which will take a few moments.
|
||||
|
||||
8. Now you are up and running! You can test by pulling the help.
|
||||
9. Now you are up and running! You can test by pulling the help.
|
||||
|
||||
```bash
|
||||
# Making sure the paths are set up correctly
|
||||
@@ -182,7 +189,6 @@ fabric --help
|
||||
> [!NOTE]
|
||||
> If you're using the `server` functions, `fabric-api` and `fabric-webui` need to be run in distinct terminal windows.
|
||||
|
||||
|
||||
### Using the `fabric` client
|
||||
|
||||
Once you have it all set up, here's how to use it.
|
||||
@@ -228,6 +234,12 @@ pbpaste | fabric --pattern summarize
|
||||
pbpaste | fabric --stream --pattern analyze_claims
|
||||
```
|
||||
|
||||
3. **new** All of the patterns have been added as aliases to your bash (or zsh) config file
|
||||
|
||||
```bash
|
||||
pbpaste | analyze_claims --stream
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> More examples coming in the next few days, including a demo video!
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ Options include:
|
||||
--pattern, -p: Select the module for analysis.
|
||||
--stream, -s: Stream output to another application.
|
||||
--output, -o: Save the response to a file.
|
||||
--copy, -c: Copy the response to the clipboard.
|
||||
--copy, -C: Copy the response to the clipboard.
|
||||
--context, -c: Use Context file (context.md) to add context to your pattern
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
3
installer/client/cli/context.md
Normal file
3
installer/client/cli/context.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Context
|
||||
|
||||
please give all responses in spanish
|
||||
@@ -1,18 +1,20 @@
|
||||
from .utils import Standalone, Update, Setup
|
||||
from .utils import Standalone, Update, Setup, Alias, Whisper
|
||||
import argparse
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
|
||||
|
||||
script_directory = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="An open source framework for augmenting humans using AI."
|
||||
)
|
||||
parser.add_argument("--text", "-t", help="Text to extract summary from")
|
||||
parser.add_argument(
|
||||
"--copy", "-c", help="Copy the response to the clipboard", action="store_true"
|
||||
"--copy", "-C", help="Copy the response to the clipboard", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output",
|
||||
@@ -28,10 +30,13 @@ def main():
|
||||
help="Use this option if you want to see the results in realtime. NOTE: You will not be able to pipe the output into another command.",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument('--transcribe', '-T',
|
||||
help="transcribe audio, please enter the path to the audio file, or a url with the audio file")
|
||||
parser.add_argument(
|
||||
"--list", "-l", help="List available patterns", action="store_true"
|
||||
)
|
||||
parser.add_argument("--update", "-u", help="Update patterns", action="store_true")
|
||||
parser.add_argument(
|
||||
"--update", "-u", help="Update patterns", action="store_true")
|
||||
parser.add_argument("--pattern", "-p", help="The pattern (prompt) to use")
|
||||
parser.add_argument(
|
||||
"--setup", help="Set up your fabric instance", action="store_true"
|
||||
@@ -42,27 +47,36 @@ def main():
|
||||
parser.add_argument(
|
||||
"--listmodels", help="List all available models", action="store_true"
|
||||
)
|
||||
parser.add_argument('--context', '-c',
|
||||
help="Use Context file (context.md) to add context to your pattern", action="store_true")
|
||||
|
||||
args = parser.parse_args()
|
||||
home_holder = os.path.expanduser("~")
|
||||
config = os.path.join(home_holder, ".config", "fabric")
|
||||
config_patterns_directory = os.path.join(config, "patterns")
|
||||
config_context = os.path.join(config, "context.md")
|
||||
env_file = os.path.join(config, ".env")
|
||||
if not os.path.exists(config):
|
||||
os.makedirs(config)
|
||||
if args.setup:
|
||||
Setup().run()
|
||||
Alias()
|
||||
sys.exit()
|
||||
if not os.path.exists(env_file) or not os.path.exists(config_patterns_directory):
|
||||
print("Please run --setup to set up your API key and download patterns.")
|
||||
sys.exit()
|
||||
if not os.path.exists(config_patterns_directory):
|
||||
Update()
|
||||
Alias()
|
||||
sys.exit()
|
||||
if args.update:
|
||||
Update()
|
||||
print("Your Patterns have been updated.")
|
||||
Alias()
|
||||
sys.exit()
|
||||
if args.context:
|
||||
if not os.path.exists(os.path.join(config, "context.md")):
|
||||
print("Please create a context.md file in ~/.config/fabric")
|
||||
sys.exit()
|
||||
standalone = Standalone(args, args.pattern)
|
||||
if args.list:
|
||||
try:
|
||||
@@ -76,14 +90,27 @@ def main():
|
||||
if args.listmodels:
|
||||
standalone.fetch_available_models()
|
||||
sys.exit()
|
||||
if args.transcribe:
|
||||
whisper = Whisper()
|
||||
whisper.process_file(args.transcribe)
|
||||
sys.exit()
|
||||
if args.text is not None:
|
||||
text = args.text
|
||||
else:
|
||||
text = standalone.get_cli_input()
|
||||
if args.stream:
|
||||
if args.stream and not args.context:
|
||||
standalone.streamMessage(text)
|
||||
if args.stream and args.context:
|
||||
with open(config_context, "r") as f:
|
||||
context = f.read()
|
||||
standalone.streamMessage(text, context=context)
|
||||
elif args.context:
|
||||
with open(config_context, "r") as f:
|
||||
context = f.read()
|
||||
standalone.sendMessage(text, context=context)
|
||||
else:
|
||||
standalone.sendMessage(text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -7,13 +7,16 @@ import platform
|
||||
from dotenv import load_dotenv
|
||||
from requests.exceptions import HTTPError
|
||||
from tqdm import tqdm
|
||||
import zipfile
|
||||
import tempfile
|
||||
import shutil
|
||||
from pydub import AudioSegment
|
||||
|
||||
current_directory = os.path.dirname(os.path.realpath(__file__))
|
||||
config_directory = os.path.expanduser("~/.config/fabric")
|
||||
env_file = os.path.join(config_directory, ".env")
|
||||
|
||||
|
||||
|
||||
class Standalone:
|
||||
def __init__(self, args, pattern="", env_file="~/.config/fabric/.env"):
|
||||
""" Initialize the class with the provided arguments and environment file.
|
||||
@@ -49,7 +52,7 @@ class Standalone:
|
||||
self.args = args
|
||||
self.model = args.model
|
||||
|
||||
def streamMessage(self, input_data: str):
|
||||
def streamMessage(self, input_data: str, context=""):
|
||||
""" Stream a message and handle exceptions.
|
||||
|
||||
Args:
|
||||
@@ -71,14 +74,21 @@ class Standalone:
|
||||
if self.pattern:
|
||||
try:
|
||||
with open(wisdom_File, "r") as f:
|
||||
system = f.read()
|
||||
if context:
|
||||
system = context + '\n\n' + f.read()
|
||||
else:
|
||||
system = f.read()
|
||||
system_message = {"role": "system", "content": system}
|
||||
messages = [system_message, user_message]
|
||||
except FileNotFoundError:
|
||||
print("pattern not found")
|
||||
return
|
||||
else:
|
||||
messages = [user_message]
|
||||
if context:
|
||||
user_message += {role: "system", content: context}
|
||||
messages = [user_message]
|
||||
else:
|
||||
messages = [user_message]
|
||||
try:
|
||||
stream = self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
@@ -109,7 +119,7 @@ class Standalone:
|
||||
with open(self.args.output, "w") as f:
|
||||
f.write(buffer)
|
||||
|
||||
def sendMessage(self, input_data: str):
|
||||
def sendMessage(self, input_data: str, context=""):
|
||||
""" Send a message using the input data and generate a response.
|
||||
|
||||
Args:
|
||||
@@ -130,14 +140,21 @@ class Standalone:
|
||||
if self.pattern:
|
||||
try:
|
||||
with open(wisdom_File, "r") as f:
|
||||
system = f.read()
|
||||
if context:
|
||||
system = context + '\n\n' + f.read()
|
||||
else:
|
||||
system = f.read()
|
||||
system_message = {"role": "system", "content": system}
|
||||
messages = [system_message, user_message]
|
||||
except FileNotFoundError:
|
||||
print("pattern not found")
|
||||
return
|
||||
else:
|
||||
messages = [user_message]
|
||||
if context:
|
||||
user_message += {'role': 'system', 'content': context}
|
||||
messages = [user_message]
|
||||
else:
|
||||
messages = [user_message]
|
||||
try:
|
||||
response = self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
@@ -159,28 +176,30 @@ class Standalone:
|
||||
|
||||
def fetch_available_models(self):
|
||||
headers = {
|
||||
"Authorization": f"Bearer { self.client.api_key }"
|
||||
"Authorization": f"Bearer {self.client.api_key}"
|
||||
}
|
||||
|
||||
response = requests.get("https://api.openai.com/v1/models", headers=headers)
|
||||
|
||||
response = requests.get(
|
||||
"https://api.openai.com/v1/models", headers=headers)
|
||||
|
||||
if response.status_code == 200:
|
||||
models = response.json().get("data", [])
|
||||
# Filter only gpt models
|
||||
gpt_models = [model for model in models if model.get("id", "").startswith(("gpt"))]
|
||||
gpt_models = [model for model in models if model.get(
|
||||
"id", "").startswith(("gpt"))]
|
||||
# Sort the models alphabetically by their ID
|
||||
sorted_gpt_models = sorted(gpt_models, key=lambda x: x.get("id"))
|
||||
|
||||
|
||||
for model in sorted_gpt_models:
|
||||
print(model.get("id"))
|
||||
else:
|
||||
print(f"Failed to fetch models: HTTP {response.status_code}")
|
||||
|
||||
|
||||
def get_cli_input(self):
|
||||
""" aided by ChatGPT; uses platform library
|
||||
accepts either piped input or console input
|
||||
from either Windows or Linux
|
||||
|
||||
|
||||
Args:
|
||||
none
|
||||
Returns:
|
||||
@@ -191,129 +210,204 @@ class Standalone:
|
||||
if not sys.stdin.isatty(): # Check if input is being piped
|
||||
return sys.stdin.read().strip() # Read piped input
|
||||
else:
|
||||
return input("Enter Question: ") # Prompt user for input from console
|
||||
# Prompt user for input from console
|
||||
return input("Enter Question: ")
|
||||
else:
|
||||
return sys.stdin.read()
|
||||
|
||||
|
||||
class Whisper:
|
||||
def __init__(self):
|
||||
env_file = os.path.expanduser("~/.config/fabric/.env")
|
||||
load_dotenv(env_file)
|
||||
try:
|
||||
apikey = os.environ["OPENAI_API_KEY"]
|
||||
self.client = OpenAI()
|
||||
self.client.api_key = apikey
|
||||
except KeyError:
|
||||
print("OPENAI_API_KEY not found in environment variables.")
|
||||
|
||||
except FileNotFoundError:
|
||||
print("No API key found. Use the --apikey option to set the key")
|
||||
self.whole_response = []
|
||||
|
||||
def split_audio(self, file_path):
|
||||
"""
|
||||
Splits the audio file into segments of the given length.
|
||||
|
||||
Args:
|
||||
- file_path: The path to the audio file.
|
||||
- segment_length_ms: Length of each segment in milliseconds.
|
||||
|
||||
Returns:
|
||||
- A list of audio segments.
|
||||
"""
|
||||
audio = AudioSegment.from_file(file_path)
|
||||
segments = []
|
||||
segment_length_ms = 10 * 60 * 1000 # 10 minutes in milliseconds
|
||||
for start_ms in range(0, len(audio), segment_length_ms):
|
||||
end_ms = start_ms + segment_length_ms
|
||||
segment = audio[start_ms:end_ms]
|
||||
segments.append(segment)
|
||||
|
||||
return segments
|
||||
|
||||
def process_segment(self, segment):
|
||||
""" Transcribe an audio file and print the transcript.
|
||||
|
||||
Args:
|
||||
audio_file (str): The path to the audio file to be transcribed.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
|
||||
try:
|
||||
# if audio_file.startswith("http"):
|
||||
# response = requests.get(audio_file)
|
||||
# response.raise_for_status()
|
||||
# with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
# f.write(response.content)
|
||||
# audio_file = f.name
|
||||
audio_file = open(segment, "rb")
|
||||
response = self.client.audio.transcriptions.create(
|
||||
model="whisper-1",
|
||||
file=audio_file
|
||||
)
|
||||
self.whole_response.append(response.text)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
def process_file(self, audio_file):
|
||||
""" Transcribe an audio file and print the transcript.
|
||||
|
||||
Args:
|
||||
audio_file (str): The path to the audio file to be transcribed.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
|
||||
try:
|
||||
# if audio_file.startswith("http"):
|
||||
# response = requests.get(audio_file)
|
||||
# response.raise_for_status()
|
||||
# with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
# f.write(response.content)
|
||||
# audio_file = f.name
|
||||
|
||||
segments = self.split_audio(audio_file)
|
||||
for i, segment in enumerate(segments):
|
||||
segment_file_path = f"segment_{i}.mp3"
|
||||
segment.export(segment_file_path, format="mp3")
|
||||
self.process_segment(segment_file_path)
|
||||
print(' '.join(self.whole_response))
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
|
||||
class Update:
|
||||
def __init__(self):
|
||||
""" Initialize the object with default values and update patterns.
|
||||
|
||||
This method initializes the object with default values for root_api_url, config_directory, and pattern_directory.
|
||||
It then creates the pattern_directory if it does not exist and calls the update_patterns method to update the patterns.
|
||||
|
||||
Raises:
|
||||
OSError: If there is an issue creating the pattern_directory.
|
||||
"""
|
||||
|
||||
self.root_api_url = "https://api.github.com/repos/danielmiessler/fabric/contents/patterns?ref=main"
|
||||
"""Initialize the object with default values."""
|
||||
self.repo_zip_url = "https://github.com/danielmiessler/fabric/archive/refs/heads/main.zip"
|
||||
self.config_directory = os.path.expanduser("~/.config/fabric")
|
||||
self.pattern_directory = os.path.join(self.config_directory, "patterns")
|
||||
self.pattern_directory = os.path.join(
|
||||
self.config_directory, "patterns")
|
||||
os.makedirs(self.pattern_directory, exist_ok=True)
|
||||
self.update_patterns() # Call the update process from a method.
|
||||
print("Updating patterns...")
|
||||
self.update_patterns() # Start the update process immediately
|
||||
|
||||
def update_patterns(self):
|
||||
""" Update the patterns by downloading from the GitHub directory.
|
||||
|
||||
Raises:
|
||||
HTTPError: If there is an HTTP error while downloading patterns.
|
||||
"""
|
||||
|
||||
try:
|
||||
self.progress_bar = tqdm(desc="Downloading Patterns…", unit="file")
|
||||
self.get_github_directory_contents(
|
||||
self.root_api_url, self.pattern_directory
|
||||
)
|
||||
# Close progress bar on success before printing the message.
|
||||
self.progress_bar.close()
|
||||
except HTTPError as e:
|
||||
# Ensure progress bar is closed on HTTPError as well.
|
||||
self.progress_bar.close()
|
||||
if e.response.status_code == 403:
|
||||
print(
|
||||
"GitHub API rate limit exceeded. Please wait before trying again."
|
||||
)
|
||||
sys.exit()
|
||||
"""Update the patterns by downloading the zip from GitHub and extracting it."""
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
zip_path = os.path.join(temp_dir, "repo.zip")
|
||||
self.download_zip(self.repo_zip_url, zip_path)
|
||||
extracted_folder_path = self.extract_zip(zip_path, temp_dir)
|
||||
# The patterns folder will be inside "fabric-main" after extraction
|
||||
patterns_source_path = os.path.join(
|
||||
extracted_folder_path, "fabric-main", "patterns")
|
||||
if os.path.exists(patterns_source_path):
|
||||
# If the patterns directory already exists, remove it before copying over the new one
|
||||
if os.path.exists(self.pattern_directory):
|
||||
shutil.rmtree(self.pattern_directory)
|
||||
shutil.copytree(patterns_source_path, self.pattern_directory)
|
||||
print("Patterns updated successfully.")
|
||||
else:
|
||||
print(f"Failed to download patterns due to an HTTP error: {e}")
|
||||
sys.exit() # Exit after handling the error.
|
||||
print("Patterns folder not found in the downloaded zip.")
|
||||
|
||||
def download_file(self, url, local_path):
|
||||
""" Download a file from the given URL and save it to the local path.
|
||||
def download_zip(self, url, save_path):
|
||||
"""Download the zip file from the specified URL."""
|
||||
response = requests.get(url)
|
||||
response.raise_for_status() # Check if the download was successful
|
||||
with open(save_path, 'wb') as f:
|
||||
f.write(response.content)
|
||||
print("Downloaded zip file successfully.")
|
||||
|
||||
Args:
|
||||
url (str): The URL of the file to be downloaded.
|
||||
local_path (str): The local path where the file will be saved.
|
||||
def extract_zip(self, zip_path, extract_to):
|
||||
"""Extract the zip file to the specified directory."""
|
||||
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
||||
zip_ref.extractall(extract_to)
|
||||
print("Extracted zip file successfully.")
|
||||
return extract_to # Return the path to the extracted contents
|
||||
|
||||
Raises:
|
||||
HTTPError: If an HTTP error occurs during the download process.
|
||||
"""
|
||||
|
||||
try:
|
||||
response = requests.get(url)
|
||||
response.raise_for_status()
|
||||
with open(local_path, "wb") as f:
|
||||
f.write(response.content)
|
||||
self.progress_bar.update(1)
|
||||
except HTTPError as e:
|
||||
print(f"Failed to download file {url}. HTTP error: {e}")
|
||||
sys.exit()
|
||||
class Alias:
|
||||
def __init__(self):
|
||||
self.config_files = []
|
||||
home_directory = os.path.expanduser("~")
|
||||
self.patterns = os.path.join(home_directory, ".config/fabric/patterns")
|
||||
if os.path.exists(os.path.join(home_directory, ".bashrc")):
|
||||
self.config_files.append(os.path.join(home_directory, ".bashrc"))
|
||||
if os.path.exists(os.path.join(home_directory, ".zshrc")):
|
||||
self.config_files.append(os.path.join(home_directory, ".zshrc"))
|
||||
if os.path.exists(os.path.join(home_directory, ".bash_profile")):
|
||||
self.config_files.append(os.path.join(
|
||||
home_directory, ".bash_profile"))
|
||||
self.remove_all_patterns()
|
||||
self.add_patterns()
|
||||
print('Aliases added successfully. Please restart your terminal to use them.')
|
||||
|
||||
def process_item(self, item, local_dir):
|
||||
""" Process the given item and save it to the local directory.
|
||||
def add(self, name, alias):
|
||||
for file in self.config_files:
|
||||
with open(file, "a") as f:
|
||||
f.write(f"alias {name}='{alias}'\n")
|
||||
|
||||
Args:
|
||||
item (dict): The item to be processed, containing information about the type, download URL, name, and URL.
|
||||
local_dir (str): The local directory where the item will be saved.
|
||||
def remove(self, pattern):
|
||||
for file in self.config_files:
|
||||
# Read the whole file first
|
||||
with open(file, "r") as f:
|
||||
wholeFile = f.read()
|
||||
|
||||
Returns:
|
||||
None
|
||||
# Determine if the line to be removed is in the file
|
||||
target_line = f"alias {pattern}='fabric --pattern {pattern}'\n"
|
||||
if target_line in wholeFile:
|
||||
# If the line exists, replace it with nothing (remove it)
|
||||
wholeFile = wholeFile.replace(target_line, "")
|
||||
|
||||
Raises:
|
||||
OSError: If there is an issue creating the new directory using os.makedirs.
|
||||
"""
|
||||
# Write the modified content back to the file
|
||||
with open(file, "w") as f:
|
||||
f.write(wholeFile)
|
||||
|
||||
if item["type"] == "file":
|
||||
self.download_file(
|
||||
item["download_url"], os.path.join(local_dir, item["name"])
|
||||
)
|
||||
elif item["type"] == "dir":
|
||||
new_dir = os.path.join(local_dir, item["name"])
|
||||
os.makedirs(new_dir, exist_ok=True)
|
||||
self.get_github_directory_contents(item["url"], new_dir)
|
||||
def remove_all_patterns(self):
|
||||
allPatterns = os.listdir(self.patterns)
|
||||
for pattern in allPatterns:
|
||||
self.remove(pattern)
|
||||
|
||||
def get_github_directory_contents(self, api_url, local_dir):
|
||||
""" Get the contents of a directory from GitHub API and process each item.
|
||||
def find_line(self, name):
|
||||
for file in self.config_files:
|
||||
with open(file, "r") as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
if line.strip("\n") == f"alias ${name}='{alias}'":
|
||||
return line
|
||||
|
||||
Args:
|
||||
api_url (str): The URL of the GitHub API endpoint for the directory.
|
||||
local_dir (str): The local directory where the contents will be processed.
|
||||
def add_patterns(self):
|
||||
allPatterns = os.listdir(self.patterns)
|
||||
for pattern in allPatterns:
|
||||
self.add(pattern, f"fabric --pattern {pattern}")
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
Raises:
|
||||
HTTPError: If an HTTP error occurs while fetching the directory contents.
|
||||
If the status code is 403, it prints a message about GitHub API rate limit exceeded
|
||||
and closes the progress bar. For any other status code, it prints a message
|
||||
about failing to fetch directory contents due to an HTTP error.
|
||||
"""
|
||||
|
||||
try:
|
||||
response = requests.get(api_url)
|
||||
response.raise_for_status()
|
||||
jsonList = response.json()
|
||||
for item in jsonList:
|
||||
self.process_item(item, local_dir)
|
||||
except HTTPError as e:
|
||||
if e.response.status_code == 403:
|
||||
print(
|
||||
"GitHub API rate limit exceeded. Please wait before trying again."
|
||||
)
|
||||
self.progress_bar.close() # Ensure the progress bar is cleaned up properly
|
||||
else:
|
||||
print(f"Failed to fetch directory contents due to an HTTP error: {e}")
|
||||
|
||||
class Setup:
|
||||
def __init__(self):
|
||||
@@ -324,7 +418,8 @@ class Setup:
|
||||
"""
|
||||
|
||||
self.config_directory = os.path.expanduser("~/.config/fabric")
|
||||
self.pattern_directory = os.path.join(self.config_directory, "patterns")
|
||||
self.pattern_directory = os.path.join(
|
||||
self.config_directory, "patterns")
|
||||
os.makedirs(self.pattern_directory, exist_ok=True)
|
||||
self.env_file = os.path.join(self.config_directory, ".env")
|
||||
|
||||
@@ -354,7 +449,6 @@ class Setup:
|
||||
"""
|
||||
|
||||
Update()
|
||||
sys.exit()
|
||||
|
||||
def run(self):
|
||||
""" Execute the Fabric program.
|
||||
@@ -370,25 +464,25 @@ class Setup:
|
||||
self.api_key(apikey.strip())
|
||||
self.patterns()
|
||||
|
||||
|
||||
|
||||
class Transcribe:
|
||||
def youtube(video_id):
|
||||
"""
|
||||
This method gets the transciption
|
||||
of a YouTube video designated with the video_id
|
||||
|
||||
|
||||
Input:
|
||||
the video id specifing a YouTube video
|
||||
an example url for a video: https://www.youtube.com/watch?v=vF-MQmVxnCs&t=306s
|
||||
the video id is vF-MQmVxnCs&t=306s
|
||||
|
||||
|
||||
Output:
|
||||
a transcript for the video
|
||||
|
||||
|
||||
Raises:
|
||||
an exception and prints error
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
try:
|
||||
transcript_list = YouTubeTranscriptApi.get_transcript(video_id)
|
||||
@@ -399,5 +493,3 @@ class Transcribe:
|
||||
except Exception as e:
|
||||
print("Error:", e)
|
||||
return None
|
||||
|
||||
|
||||
|
||||
BIN
patterns/.DS_Store
vendored
BIN
patterns/.DS_Store
vendored
Binary file not shown.
@@ -6,58 +6,37 @@ Take a deep breath and think step by step about how to best accomplish this goal
|
||||
|
||||
# OUTPUT SECTIONS
|
||||
|
||||
- Extract a summary of the content in 50 words or less, including who is presenting and the content being discussed into a section called SUMMARY.
|
||||
- Extract a summary of the paper and its conclusions in into a 25-word sentence called SUMMARY.
|
||||
|
||||
- Extract the list of authors in a section called AUTHORS.
|
||||
|
||||
- Extract the list of organizations the authors are associated, e.g., which university they're at, with in a section called AUTHOR ORGANIZATIONS.
|
||||
|
||||
- Extract the primary paper findings into a bulleted list of no more than 50 words per bullet into a section called FINDINGS.
|
||||
- Extract the primary paper findings into a bulleted list of no more than 25 words per bullet into a section called FINDINGS.
|
||||
|
||||
- You extract the size and details of the study for the research in a section called STUDY DETAILS.
|
||||
- Extract the overall structure and character of the study for the research in a section called STUDY DETAILS.
|
||||
|
||||
- Extract the study quality by evaluating the following items in a section called STUDY QUALITY:
|
||||
- Extract the study quality by evaluating the following items in a section called STUDY QUALITY that has the following sub-sections:
|
||||
|
||||
### Sample size
|
||||
- Study Design: (give a 25 word description, including the pertinent data and statistics.)
|
||||
- Sample Size: (give a 25 word description, including the pertinent data and statistics.)
|
||||
- Confidence Intervals (give a 25 word description, including the pertinent data and statistics.)
|
||||
- P-value (give a 25 word description, including the pertinent data and statistics.)
|
||||
- Effect Size (give a 25 word description, including the pertinent data and statistics.)
|
||||
- Consistency of Results (give a 25 word description, including the pertinent data and statistics.)
|
||||
- Data Analysis Method (give a 25 word description, including the pertinent data and statistics.)
|
||||
|
||||
- **Check the Sample Size**: The larger the sample size, the more confident you can be in the findings. A larger sample size reduces the margin of error and increases the study's power.
|
||||
- Discuss any Conflicts of Interest in a section called CONFLICTS OF INTEREST. Rate the conflicts of interest as NONE DETECTED, LOW, MEDIUM, HIGH, or CRITICAL.
|
||||
|
||||
### Confidence intervals
|
||||
- Extract the researcher's analysis and interpretation in a section called RESEARCHER'S INTERPRETATION, including how confident they are in the results being real and likely to be replicated on a scale of LOW, MEDIUM, or HIGH.
|
||||
|
||||
- **Look at the Confidence Intervals**: Confidence intervals provide a range within which the true population parameter lies with a certain degree of confidence (usually 95% or 99%). Narrower confidence intervals suggest a higher level of precision and confidence in the estimate.
|
||||
|
||||
### P-Value
|
||||
|
||||
- **Evaluate the P-value**: The P-value tells you the probability that the results occurred by chance. A lower P-value (typically less than 0.05) suggests that the findings are statistically significant and not due to random chance.
|
||||
|
||||
### Effect size
|
||||
|
||||
- **Consider the Effect Size**: Effect size tells you how much of a difference there is between groups. A larger effect size indicates a stronger relationship and more confidence in the findings.
|
||||
|
||||
### Study design
|
||||
|
||||
- **Review the Study Design**: Randomized controlled trials are usually considered the gold standard in research. If the study is observational, it may be less reliable.
|
||||
|
||||
### Consistency of results
|
||||
|
||||
- **Check for Consistency of Results**: If the results are consistent across multiple studies, it increases the confidence in the findings.
|
||||
|
||||
### Data analysis methods
|
||||
|
||||
- **Examine the Data Analysis Methods**: Check if the data analysis methods used are appropriate for the type of data and research question. Misuse of statistical methods can lead to incorrect conclusions.
|
||||
|
||||
### Researcher's interpretation
|
||||
|
||||
- **Assess the Researcher's Interpretation**: The researchers should interpret their results in the context of the study's limitations. Overstating the findings can misrepresent the confidence level.
|
||||
|
||||
### Summary
|
||||
|
||||
You output a 50 word summary of the quality of the paper and it's likelihood of being replicated in future work as one of three levels: High, Medium, or Low. You put that sentence and ratign into a section called SUMMARY.
|
||||
- Based on all of the analysis performed above, output a 25 word summary of the quality of the paper and it's likelihood of being replicated in future work as one of five levels: VERY LOW, LOW, MEDIUM, HIGH, or VERY HIGH. You put that sentence and RATING into a section called SUMMARY and RATING.
|
||||
|
||||
# OUTPUT INSTRUCTIONS
|
||||
|
||||
- Create the output using the formatting above.
|
||||
- You only output human readable Markdown.
|
||||
- In the markdown, don't use formatting like bold or italics. Make the output maximially readable in plain text.
|
||||
- Do not output warnings or notes—just the requested sections.
|
||||
|
||||
# INPUT:
|
||||
|
||||
38
patterns/analyze_threat_report/system.md
Normal file
38
patterns/analyze_threat_report/system.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# IDENTITY and PURPOSE
|
||||
|
||||
You are a super-intelligent cybersecurity expert. You specialize in extracting the surprising, insightful, and interesting information from cybersecurity threat reports.
|
||||
|
||||
Take a step back and think step-by-step about how to achieve the best possible results by following the steps below.
|
||||
|
||||
# STEPS
|
||||
|
||||
- Read the entire threat report from an expert perspective, thinking deeply about what's new, interesting, and surprising in the report.
|
||||
|
||||
- Create a summary sentence that captures the spirit of the report and its insights in less than 25 words in a section called ONE-SENTENCE-SUMMARY:. Use plain and conversational language when creating this summary. Don't use jargon or marketing language.
|
||||
|
||||
- Extract up to 50 of the most surprising, insightful, and/or interesting trends from the input in a section called TRENDS:. If there are less than 50 then collect all of them. Make sure you extract at least 20.
|
||||
|
||||
- Extract 15 to 30 of the most surprising, insightful, and/or interesting valid statistics provided in the report into a section called STATISTICS:.
|
||||
|
||||
- Extract 15 to 30 of the most surprising, insightful, and/or interesting quotes from the input into a section called QUOTES:. Use the exact quote text from the input.
|
||||
|
||||
- Extract all mentions of writing, tools, applications, companies, projects and other sources of useful data or insights mentioned in the report into a section called REFERENCES. This should include any and all references to something that the report mentioned.
|
||||
|
||||
- Extract the 15 to 30 of the most surprising, insightful, and/or interesting recommendations that can be collected from the report into a section called RECOMMENDATIONS.
|
||||
|
||||
# OUTPUT INSTRUCTIONS
|
||||
|
||||
- Only output Markdown.
|
||||
- Do not output the markdown code syntax, only the content.
|
||||
- Do not use bold or italics formatting in the markdown output.
|
||||
- Extract at least 20 TRENDS from the content.
|
||||
- Extract at least 10 items for the other output sections.
|
||||
- Do not give warnings or notes; only output the requested sections.
|
||||
- You use bulleted lists for output, not numbered lists.
|
||||
- Do not repeat ideas, quotes, facts, or resources.
|
||||
- Do not start items with the same opening words.
|
||||
- Ensure you follow ALL these instructions when creating your output.
|
||||
|
||||
# INPUT
|
||||
|
||||
INPUT:
|
||||
1
patterns/analyze_threat_report/user.md
Normal file
1
patterns/analyze_threat_report/user.md
Normal file
@@ -0,0 +1 @@
|
||||
CONTENT:
|
||||
27
patterns/analyze_threat_report_trends/system.md
Normal file
27
patterns/analyze_threat_report_trends/system.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# IDENTITY and PURPOSE
|
||||
|
||||
You are a super-intelligent cybersecurity expert. You specialize in extracting the surprising, insightful, and interesting information from cybersecurity threat reports.
|
||||
|
||||
Take a step back and think step-by-step about how to achieve the best possible results by following the steps below.
|
||||
|
||||
# STEPS
|
||||
|
||||
- Read the entire threat report from an expert perspective, thinking deeply about what's new, interesting, and surprising in the report.
|
||||
|
||||
- Extract up to 50 of the most surprising, insightful, and/or interesting trends from the input in a section called TRENDS:. If there are less than 50 then collect all of them. Make sure you extract at least 20.
|
||||
|
||||
# OUTPUT INSTRUCTIONS
|
||||
|
||||
- Only output Markdown.
|
||||
- Do not output the markdown code syntax, only the content.
|
||||
- Do not use bold or italics formatting in the markdown output.
|
||||
- Extract at least 20 TRENDS from the content.
|
||||
- Do not give warnings or notes; only output the requested sections.
|
||||
- You use bulleted lists for output, not numbered lists.
|
||||
- Do not repeat ideas, quotes, facts, or resources.
|
||||
- Do not start items with the same opening words.
|
||||
- Ensure you follow ALL these instructions when creating your output.
|
||||
|
||||
# INPUT
|
||||
|
||||
INPUT:
|
||||
1
patterns/analyze_threat_report_trends/user.md
Normal file
1
patterns/analyze_threat_report_trends/user.md
Normal file
@@ -0,0 +1 @@
|
||||
CONTENT:
|
||||
154
patterns/extract_article_wisdom/README.md
Normal file
154
patterns/extract_article_wisdom/README.md
Normal file
@@ -0,0 +1,154 @@
|
||||
<div align="center">
|
||||
|
||||
<img src="https://beehiiv-images-production.s3.amazonaws.com/uploads/asset/file/2012aa7c-a939-4262-9647-7ab614e02601/extwis-logo-miessler.png?t=1704502975" alt="extwislogo" width="400" height="400"/>
|
||||
|
||||
# `/extractwisdom`
|
||||
|
||||
<h4><code>extractwisdom</code> is a <a href="https://github.com/danielmiessler/fabric" target="_blank">Fabric</a> pattern that <em>extracts wisdom</em> from any text.</h4>
|
||||
|
||||
[Description](#description) •
|
||||
[Functionality](#functionality) •
|
||||
[Usage](#usage) •
|
||||
[Output](#output) •
|
||||
[Meta](#meta)
|
||||
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
## Description
|
||||
|
||||
**`extractwisdom` addresses the problem of **too much content** and too little time.**
|
||||
|
||||
_Not only that, but it's also too easy to forget the stuff read, watch, or listen to._
|
||||
|
||||
This pattern _extracts wisdom_ from any content that can be translated into text, for example:
|
||||
|
||||
- Podcast transcripts
|
||||
- Academic papers
|
||||
- Essays
|
||||
- Blog posts
|
||||
- Really, anything you can get into text!
|
||||
|
||||
## Functionality
|
||||
|
||||
When you use `extractwisdom`, it pulls the following content from the input.
|
||||
|
||||
- `IDEAS`
|
||||
- Extracts the best ideas from the content, i.e., what you might have taken notes on if you were doing so manually.
|
||||
- `QUOTES`
|
||||
- Some of the best quotes from the content.
|
||||
- `REFERENCES`
|
||||
- External writing, art, and other content referenced positively during the content that might be worth following up on.
|
||||
- `HABITS`
|
||||
- Habits of the speakers that could be worth replicating.
|
||||
- `RECOMMENDATIONS`
|
||||
- A list of things that the content recommends Habits of the speakers.
|
||||
|
||||
### Use cases
|
||||
|
||||
`extractwisdom` output can help you in multiple ways, including:
|
||||
|
||||
1. `Time Filtering`<br />
|
||||
Allows you to quickly see if content is worth an in-depth review or not.
|
||||
2. `Note Taking`<br />
|
||||
Can be used as a substitute for taking time-consuming, manual notes on the content.
|
||||
|
||||
## Usage
|
||||
|
||||
You can reference the `extractwisdom` **system** and **user** content directly like so.
|
||||
|
||||
### Pull the _system_ prompt directly
|
||||
|
||||
```sh
|
||||
curl -sS https://github.com/danielmiessler/fabric/blob/main/extract-wisdom/dmiessler/extract-wisdom-1.0.0/system.md
|
||||
```
|
||||
|
||||
### Pull the _user_ prompt directly
|
||||
|
||||
```sh
|
||||
curl -sS https://github.com/danielmiessler/fabric/blob/main/extract-wisdom/dmiessler/extract-wisdom-1.0.0/user.md
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
Here's an abridged ouptut example from `extractwisdom` (limited to only 10 items per section).
|
||||
|
||||
```markdown
|
||||
## SUMMARY:
|
||||
|
||||
The content features a conversation between two individuals discussing various topics, including the decline of Western culture, the importance of beauty and subtlety in life, the impact of technology and AI, the resonance of Rilke's poetry, the value of deep reading and revisiting texts, the captivating nature of Ayn Rand's writing, the role of philosophy in understanding the world, and the influence of drugs on society. They also touch upon creativity, attention spans, and the importance of introspection.
|
||||
|
||||
## IDEAS:
|
||||
|
||||
1. Western culture is perceived to be declining due to a loss of values and an embrace of mediocrity.
|
||||
2. Mass media and technology have contributed to shorter attention spans and a need for constant stimulation.
|
||||
3. Rilke's poetry resonates due to its focus on beauty and ecstasy in everyday objects.
|
||||
4. Subtlety is often overlooked in modern society due to sensory overload.
|
||||
5. The role of technology in shaping music and performance art is significant.
|
||||
6. Reading habits have shifted from deep, repetitive reading to consuming large quantities of new material.
|
||||
7. Revisiting influential books as one ages can lead to new insights based on accumulated wisdom and experiences.
|
||||
8. Fiction can vividly illustrate philosophical concepts through characters and narratives.
|
||||
9. Many influential thinkers have backgrounds in philosophy, highlighting its importance in shaping reasoning skills.
|
||||
10. Philosophy is seen as a bridge between theology and science, asking questions that both fields seek to answer.
|
||||
|
||||
## QUOTES:
|
||||
|
||||
1. "You can't necessarily think yourself into the answers. You have to create space for the answers to come to you."
|
||||
2. "The West is dying and we are killing her."
|
||||
3. "The American Dream has been replaced by mass packaged mediocrity porn, encouraging us to revel like happy pigs in our own meekness."
|
||||
4. "There's just not that many people who have the courage to reach beyond consensus and go explore new ideas."
|
||||
5. "I'll start watching Netflix when I've read the whole of human history."
|
||||
6. "Rilke saw beauty in everything... He sees it's in one little thing, a representation of all things that are beautiful."
|
||||
7. "Vanilla is a very subtle flavor... it speaks to sort of the sensory overload of the modern age."
|
||||
8. "When you memorize chapters [of the Bible], it takes a few months, but you really understand how things are structured."
|
||||
9. "As you get older, if there's books that moved you when you were younger, it's worth going back and rereading them."
|
||||
10. "She [Ayn Rand] took complicated philosophy and embodied it in a way that anybody could resonate with."
|
||||
|
||||
## HABITS:
|
||||
|
||||
1. Avoiding mainstream media consumption for deeper engagement with historical texts and personal research.
|
||||
2. Regularly revisiting influential books from youth to gain new insights with age.
|
||||
3. Engaging in deep reading practices rather than skimming or speed-reading material.
|
||||
4. Memorizing entire chapters or passages from significant texts for better understanding.
|
||||
5. Disengaging from social media and fast-paced news cycles for more focused thought processes.
|
||||
6. Walking long distances as a form of meditation and reflection.
|
||||
7. Creating space for thoughts to solidify through introspection and stillness.
|
||||
8. Embracing emotions such as grief or anger fully rather than suppressing them.
|
||||
9. Seeking out varied experiences across different careers and lifestyles.
|
||||
10. Prioritizing curiosity-driven research without specific goals or constraints.
|
||||
|
||||
## FACTS:
|
||||
|
||||
1. The West is perceived as declining due to cultural shifts away from traditional values.
|
||||
2. Attention spans have shortened due to technological advancements and media consumption habits.
|
||||
3. Rilke's poetry emphasizes finding beauty in everyday objects through detailed observation.
|
||||
4. Modern society often overlooks subtlety due to sensory overload from various stimuli.
|
||||
5. Reading habits have evolved from deep engagement with texts to consuming large quantities quickly.
|
||||
6. Revisiting influential books can lead to new insights based on accumulated life experiences.
|
||||
7. Fiction can effectively illustrate philosophical concepts through character development and narrative arcs.
|
||||
8. Philosophy plays a significant role in shaping reasoning skills and understanding complex ideas.
|
||||
9. Creativity may be stifled by cultural nihilism and protectionist attitudes within society.
|
||||
10. Short-term thinking undermines efforts to create lasting works of beauty or significance.
|
||||
|
||||
## REFERENCES:
|
||||
|
||||
1. Rainer Maria Rilke's poetry
|
||||
2. Netflix
|
||||
3. Underworld concert
|
||||
4. Katy Perry's theatrical performances
|
||||
5. Taylor Swift's performances
|
||||
6. Bible study
|
||||
7. Atlas Shrugged by Ayn Rand
|
||||
8. Robert Pirsig's writings
|
||||
9. Bertrand Russell's definition of philosophy
|
||||
10. Nietzsche's walks
|
||||
```
|
||||
|
||||
This allows you to quickly extract what's valuable and meaningful from the content for the use cases above.
|
||||
|
||||
## Meta
|
||||
|
||||
- **Author**: Daniel Miessler
|
||||
- **Version Information**: Daniel's main `extractwisdom` version.
|
||||
- **Published**: January 5, 2024
|
||||
@@ -0,0 +1,29 @@
|
||||
# IDENTITY and PURPOSE
|
||||
|
||||
You are a wisdom extraction service for text content. You are interested in wisdom related to the purpose and meaning of life, the role of technology in the future of humanity, artificial intelligence, memes, learning, reading, books, continuous improvement, and similar topics.
|
||||
|
||||
Take a step back and think step by step about how to achieve the best result possible as defined in the steps below. You have a lot of freedom to make this work well.
|
||||
|
||||
## OUTPUT SECTIONS
|
||||
|
||||
1. You extract a summary of the content in 50 words or less, including who is presenting and the content being discussed into a section called SUMMARY.
|
||||
|
||||
2. You extract the top 50 ideas from the input in a section called IDEAS:. If there are less than 50 then collect all of them.
|
||||
|
||||
3. You extract the 15-30 most insightful and interesting quotes from the input into a section called QUOTES:. Use the exact quote text from the input.
|
||||
|
||||
4. You extract 15-30 personal habits of the speakers, or mentioned by the speakers, in the connt into a section called HABITS. Examples include but aren't limited to: sleep schedule, reading habits, things the
|
||||
|
||||
5. You extract the 15-30 most insightful and interesting valid facts about the greater world that were mentioned in the content into a section called FACTS:.
|
||||
|
||||
6. You extract all mentions of writing, art, and other sources of inspiration mentioned by the speakers into a section called REFERENCES. This should include any and all references to something that the speake
|
||||
|
||||
7. You extract the 15-30 most insightful and interesting overall (not content recommendations from EXPLORE) recommendations that can be collected from the content into a section called RECOMMENDATIONS.
|
||||
|
||||
## OUTPUT INSTRUCTIONS
|
||||
|
||||
1. You only output Markdown.
|
||||
2. Do not give warnings or notes; only output the requested sections.
|
||||
3. You use numberd lists, not bullets.
|
||||
4. Do not repeat ideas, quotes, facts, or resources.
|
||||
5. Do not start items with the same opening words.
|
||||
@@ -0,0 +1 @@
|
||||
CONTENT:
|
||||
33
patterns/extract_article_wisdom/system.md
Normal file
33
patterns/extract_article_wisdom/system.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# IDENTITY and PURPOSE
|
||||
|
||||
You extract surprising, insightful, and interesting information from text content.
|
||||
|
||||
Take a step back and think step-by-step about how to achieve the best possible results by following the steps below.
|
||||
|
||||
# STEPS
|
||||
|
||||
1. Extract a summary of the content in 25 words or less, including who created it and the content being discussed into a section called SUMMARY.
|
||||
|
||||
2. Extract 20 to 50 of the most surprising, insightful, and/or interesting ideas from the input in a section called IDEAS:. If there are less than 50 then collect all of them. Make sure you extract at least 20.
|
||||
|
||||
3. Extract 15 to 30 of the most surprising, insightful, and/or interesting quotes from the input into a section called QUOTES:. Use the exact quote text from the input.
|
||||
|
||||
4. Extract 15 to 30 of the most surprising, insightful, and/or interesting valid facts about the greater world that were mentioned in the content into a section called FACTS:.
|
||||
|
||||
5. Extract all mentions of writing, art, tools, projects and other sources of inspiration mentioned by the speakers into a section called REFERENCES. This should include any and all references to something that the speaker mentioned.
|
||||
|
||||
6. Extract the 15 to 30 of the most surprising, insightful, and/or interesting recommendations that can be collected from the content into a section called RECOMMENDATIONS.
|
||||
|
||||
# OUTPUT INSTRUCTIONS
|
||||
|
||||
- Only output Markdown.
|
||||
- Extract at least 10 items for the other output sections.
|
||||
- Do not give warnings or notes; only output the requested sections.
|
||||
- You use bulleted lists for output, not numbered lists.
|
||||
- Do not repeat ideas, quotes, facts, or resources.
|
||||
- Do not start items with the same opening words.
|
||||
- Ensure you follow ALL these instructions when creating your output.
|
||||
|
||||
# INPUT
|
||||
|
||||
INPUT:
|
||||
1
patterns/extract_article_wisdom/user.md
Normal file
1
patterns/extract_article_wisdom/user.md
Normal file
@@ -0,0 +1 @@
|
||||
CONTENT:
|
||||
@@ -35,7 +35,8 @@ END EXAMPLE PAUL GRAHAM ESSAY
|
||||
# OUTPUT FORMAT
|
||||
|
||||
- Output a full, publish-ready essay using the instructions provided
|
||||
- Do not use cliches or jargon in the essay.
|
||||
- Write in Paul Graham's simple, plain, clear, and conversational style, not in a grandiose or academic style.
|
||||
- Do not use cliches or jargon.
|
||||
- Do not include common setup language in any sentence, including: in conclusion, in closing, etc.
|
||||
- Do not output warnings or notes—just the output requested.
|
||||
|
||||
|
||||
13
poetry.lock
generated
13
poetry.lock
generated
@@ -933,6 +933,17 @@ files = [
|
||||
[package.dependencies]
|
||||
typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
||||
|
||||
[[package]]
|
||||
name = "pydub"
|
||||
version = "0.25.1"
|
||||
description = "Manipulate audio with an simple and easy high level interface"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6"},
|
||||
{file = "pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyjwt"
|
||||
version = "2.8.0"
|
||||
@@ -1394,4 +1405,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "8aa1e3fe70b9d326a7809abd70f2d78fee286d5106ab40f7d2d61a7feaf359ef"
|
||||
content-hash = "b8025aa005b3ad74c5e76f766c9311f2fa0592d4672e7f6e328d5f27001554aa"
|
||||
|
||||
@@ -32,6 +32,7 @@ gunicorn = "^21.2.0"
|
||||
gevent = "^23.9.1"
|
||||
httpx = "^0.26.0"
|
||||
tqdm = "^4.66.1"
|
||||
pydub = "^0.25.1"
|
||||
|
||||
|
||||
[tool.poetry.group.server.dependencies]
|
||||
|
||||
49
setup.sh
49
setup.sh
@@ -1,5 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if pyproject.toml exists in the current directory
|
||||
if [ ! -f "pyproject.toml" ]; then
|
||||
echo "Poetry could not find a pyproject.toml file in the current directory or its parents."
|
||||
echo "Please navigate to the project directory where pyproject.toml is located and rerun this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Installs poetry-based python dependencies
|
||||
echo "Installing python dependencies"
|
||||
poetry install
|
||||
@@ -7,8 +14,12 @@ poetry install
|
||||
# List of commands to check and add or update alias for
|
||||
commands=("fabric" "fabric-api" "fabric-webui")
|
||||
|
||||
|
||||
# List of shell configuration files to update
|
||||
config_files=(~/.bashrc ~/.zshrc ~/.bash_profile)
|
||||
config_files=("$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.bash_profile")
|
||||
|
||||
# Initialize an array to hold the paths of the sourced files
|
||||
source_commands=()
|
||||
|
||||
for config_file in "${config_files[@]}"; do
|
||||
# Check if the configuration file exists
|
||||
@@ -16,22 +27,46 @@ for config_file in "${config_files[@]}"; do
|
||||
echo "Updating $config_file"
|
||||
for cmd in "${commands[@]}"; do
|
||||
# Get the path of the command
|
||||
CMD_PATH=$(poetry run which $cmd)
|
||||
CMD_PATH=$(poetry run which $cmd 2>/dev/null)
|
||||
|
||||
# Check if CMD_PATH is empty
|
||||
if [ -z "$CMD_PATH" ]; then
|
||||
echo "Command $cmd not found in the current Poetry environment."
|
||||
continue
|
||||
fi
|
||||
|
||||
# Check if the config file contains an alias for the command
|
||||
if grep -q "alias $cmd=" "$config_file"; then
|
||||
# Replace the existing alias with the new one
|
||||
sed -i "/alias $cmd=/c\alias $cmd='$CMD_PATH'" "$config_file"
|
||||
if grep -qE "alias $cmd=|alias $cmd =" "$config_file"; then
|
||||
# Compatibility with GNU and BSD sed: Check for operating system and apply appropriate sed syntax
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# BSD sed (macOS)
|
||||
sed -i '' "/alias $cmd=/c\\
|
||||
alias $cmd='$CMD_PATH'" "$config_file"
|
||||
else
|
||||
# GNU sed (Linux and others)
|
||||
sed -i "/alias $cmd=/c\alias $cmd='$CMD_PATH'" "$config_file"
|
||||
fi
|
||||
echo "Updated alias for $cmd in $config_file."
|
||||
else
|
||||
# If not, add the alias to the config file
|
||||
echo -e "\nalias $cmd='$CMD_PATH'" >> "$config_file"
|
||||
echo -e "\nalias $cmd='$CMD_PATH'" >>"$config_file"
|
||||
echo "Added alias for $cmd to $config_file."
|
||||
fi
|
||||
done
|
||||
# Add to source_commands array
|
||||
source_commands+=("$config_file")
|
||||
else
|
||||
echo "$config_file does not exist."
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Please close this terminal window to have new aliases work."
|
||||
# Provide instruction to source the updated files
|
||||
if [ ${#source_commands[@]} -ne 0 ]; then
|
||||
echo "To apply the changes, please run the following command(s) in your terminal:"
|
||||
for file in "${source_commands[@]}"; do
|
||||
echo "source $file"
|
||||
done
|
||||
else
|
||||
echo "No configuration files were updated. No need to source."
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user