Skip to content

Commit 199a9be

Browse files
committed
Docs Updates + Adding Host option to recipes and serving
1 parent 11617bb commit 199a9be

17 files changed

+188
-15
lines changed

.cursor/rules/elements.mdc

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
description:
3+
globs:
4+
---
5+
6+
# Your rule content
7+
8+
- You can @ files here
9+
- You can use markdown but dont have to

docs/_quarto.yml

+30-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ website:
2121
sidebar:
2222
style: floating
2323
contents:
24-
- text: "📚 Introduction"
24+
- text: "🚀 Introduction"
2525
href: index.qmd
2626
- text: "🔧 Installation"
2727
href: installation.qmd
@@ -33,6 +33,11 @@ website:
3333
contents: elements/*
3434
- section: "💡 Explanation"
3535
contents: explanation/*
36+
- section: "👨‍🍳 Recipes"
37+
href: recipes/index.qmd
38+
contents:
39+
- auto: recipes/*.qmd
40+
- auto: recipes/*/*.qmd
3641
format:
3742
html:
3843
theme:
@@ -41,8 +46,30 @@ format:
4146
css: styles.css
4247
toc: true
4348
highlight-style: github
44-
execute:
45-
freeze: auto
49+
freeze: auto
50+
include-in-header:
51+
- text: |
52+
<script src="https://unpkg.com/powerglitch@latest/dist/powerglitch.min.js"></script>
53+
<script>
54+
document.addEventListener("DOMContentLoaded", function() {
55+
// Immediately trigger the glitch effect on menu text when the DOM is ready
56+
PowerGlitch.glitch('span.menu-text', { playMode: 'click' });
57+
58+
// Wait 300ms before checking for the sidebar toggle element to ensure it exists
59+
setTimeout(function() {
60+
var toggleElement = document.querySelector('.quarto-sidebar-toggle');
61+
if (toggleElement) {
62+
toggleElement.addEventListener('click', function() {
63+
// After the toggle is clicked, wait 500ms for any UI updates then trigger the glitch effect again
64+
setTimeout(function() {
65+
PowerGlitch.glitch('span.menu-text', { playMode: 'click' });
66+
}, 500);
67+
});
68+
}
69+
}, 300);
70+
});
71+
</script>
72+
4673

4774

4875

docs/custom.scss

+20
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ $fontcolor: $white;
2222
$navbar-fg: $white;
2323
$breadcrumb-bg: $secondary-background-color;
2424
$breadcrumb-active-color: $lesser-white;
25+
$code-background-color: rgba(52, 58, 64, .65);
26+
$table-accent-bg: None;
2527

2628
/*-- Mermaid styling --*/
2729
$mermaid-bg-color: $primary-background-color;
@@ -76,6 +78,10 @@ $mermaid-node-fg-color: $light-outline-color;
7678
}
7779

7880
ol.breadcrumb {
81+
background-color: $primary-background-color;
82+
border-radius: 25px; // Set border radius for the breadcrumb
83+
border: 1px solid $light-outline-color; // Set border width and color for the breadcrumb
84+
7985
// Assign a color to all breadcrumb items except the last one
8086
.breadcrumb-item {
8187
a {
@@ -128,4 +134,18 @@ ol.breadcrumb {
128134

129135
#quarto-search .aa-Form {
130136
background-color: $white;
137+
}
138+
139+
p code:not(.sourceCode) {
140+
color: $lesser-white;
141+
background-color: $code-background-color;
142+
}
143+
144+
table {
145+
background-color: $secondary-background-color;
146+
font-size: 14px;
147+
148+
.header {
149+
border-bottom: 1px solid $secondary-accent-color;
150+
}
131151
}

docs/index.qmd

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Pyllments consists of a set of **Elements** with a consistent interface that all
4141

4242
#### Elements:
4343
* Easily integrate into your own projects
44-
* Built to have front end components associated with them, which allows you to build your own composable GUIs to interact with your flows
44+
* Have front end components associated with them, which allows you to build your own composable GUIs to interact with your flows
4545
* Can individually or in a flow be served as an API (with limitless endpoints at any given part of the flow)
4646

4747
::: {.column-page}

docs/installation.qmd

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
---
2-
title: "Installation"
2+
title: "Installation Instructions"
33
---
44

5+
You can install Pyllments using either of the following methods:
6+
7+
::: {.panel-tabset}
8+
## Using pip
9+
```{.bash}
10+
pip install pyllments
11+
```
12+
## Using uv pip
13+
```{.bash}
14+
uv pip install pyllments
15+
```
16+
:::
Loading
90.9 KB
Loading

docs/recipes/branch_flow/index.qmd

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: "Branching Chat Flow"
3+
format:
4+
html:
5+
code-links:
6+
- text: Recipe Code
7+
icon: github
8+
href: https://github.com/Prudent-Patterns/pyllments/blob/main/pyllments/recipes/branch_flow.py
9+
description: "Create a multi-tabbed chat interface that allows users to branch conversations and create new ones."
10+
---
11+
12+
```bash
13+
pyllments recipe run branch_flow
14+
```
15+
### Configuration
16+
17+
| Argument | Example | Description | Default |
18+
| :--------------- | :--- | :------------------------------------------------:| :------ |
19+
| width | 800 | Width of the chat interface. | 800 |
20+
| height | 942 | Height of the application. | 942 |
21+
| custom_models | *See Below* | Add custom LLM models and/or base urls. | "{}" |
22+
23+
::: {layout-ncol=2}
24+
![Branch Flow GUI](branch_flow_gui.jpg){.lightbox}
25+
26+
![Branch Flow Flow Diagram](branch_flow_flowchart.jpg){.lightbox}
27+
:::
28+
29+
This recipe enables both entirely new chats and forked conversations from existing ones, managed by an integrated flow system.
30+
31+
- **New Chat**: Start fresh conversations.
32+
- **Branching**: Fork from existing chats, optionally copying messages.
33+
- **Tabbed Interface**: Manage multiple chats/branches simultaneously.
34+
- **LLM Integration**: Seamlessly connects UI with LLM backend.

docs/recipes/index.qmd

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
title: Recipes
3+
listing:
4+
id: recipes-listing
5+
contents:
6+
- /*.qmd
7+
- /*/*.qmd
8+
fields:
9+
- title
10+
- description
11+
type: table
12+
filter-ui: false
13+
sort-ui: false
14+
---
15+
16+
Recipes are pre-made flows that you can run straight from the command line.
17+
18+
Click on a recipe to see more details and configuration options.
19+
20+
```bash
21+
pyllments recipe run <recipe-name> [<args>...]
22+
```
23+
24+
::: {#recipes-listing}
25+
:::
26+

docs/recipes/multi_chat_flow.qmd

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: Multi Chat Flow
3+
description: "A multi chat flow recipe"
4+
---
5+
6+
7+

docs/recipes/simple_flow.qmd

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: "Simple Flow"
3+
description: "A simple flow recipe"
4+
---
5+
6+
```bash
7+
pyllments recipe run simple_flow
8+
```

docs/recipes/simple_flow_api.qmd

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: "Simple Flow API"
3+
description: "A simple flow API recipe"
4+
---
5+
6+
```bash
7+
pyllments recipe run simple_flow_api
8+
```

pyllments/cli/recipes.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,20 @@ def recipe_command(
131131
no_gui: bool = typer.Option(False, help="Don't look for GUI components"),
132132
port: int = typer.Option(8000, help="Port to run server on"),
133133
env: Optional[str] = typer.Option(None, help="Path to .env file"),
134+
host: str = typer.Option(
135+
"127.0.0.1",
136+
"--host",
137+
"-H",
138+
help=("Network interface to bind the server to. "
139+
"Defaults to 127.0.0.1 for local development.")
140+
),
134141
profile: bool = typer.Option(False, help="Enable profiling output"),
135142
config: List[str] = typer.Option(
136143
[],
137144
help="Additional configuration options as key=value pairs"
138145
)
139146
):
140-
# Combine key=value pairs into a config dictionary.
147+
# Combine key=value pairs into a configuration dictionary.
141148
config_dict = {}
142149
for pair in config:
143150
try:
@@ -162,6 +169,7 @@ def recipe_command(
162169
no_gui=no_gui,
163170
port=port,
164171
env=env,
172+
host=host,
165173
config=config_dict
166174
)
167175
except Exception as e:

pyllments/recipes/discovery.py

+18-7
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ def extract_config_metadata(node: ast.ClassDef) -> Optional[Dict]:
6666
6767
This function parses the AST (abstract syntax tree) of a Config class to retrieve:
6868
- The class-level docstring.
69-
- A dictionary mapping each field name to its associated type, default value (if any),
70-
and metadata (such as help text and numeric constraints).
69+
- A dictionary mapping each field name to a dictionary with field information,
70+
including its type, default value (if any), and metadata (such as help text and constraints).
7171
7272
Parameters
7373
----------
@@ -79,8 +79,7 @@ def extract_config_metadata(node: ast.ClassDef) -> Optional[Dict]:
7979
Optional[Dict]
8080
A dictionary with keys:
8181
- 'docstring': The docstring of the class.
82-
- 'fields': A mapping from field names to a dictionary with field information,
83-
including 'type' (str), and optionally 'default' and 'metadata'.
82+
- 'fields': A mapping from field names to field information (type, default, metadata).
8483
Returns None if no fields are found.
8584
"""
8685
# Retrieve the class-level docstring.
@@ -99,18 +98,31 @@ def extract_config_metadata(node: ast.ClassDef) -> Optional[Dict]:
9998
if field_type:
10099
field_data['type'] = field_type
101100

102-
# Initialize the default value as None.
103101
default_value = None
104102

105103
# Check if the field value is defined using a call to the 'field' function.
106104
if isinstance(item.value, ast.Call) and getattr(item.value.func, 'id', None) == 'field':
107-
# Iterate over keyword arguments to extract 'default' value.
105+
# Iterate over keyword arguments to extract 'default' or 'default_factory' value.
108106
for kw in item.value.keywords:
109107
if kw.arg == 'default':
110108
try:
111109
default_value = ast.literal_eval(kw.value)
112110
except Exception as e:
113111
logger.error(f"Failed to eval default for field {field_name}: {e}")
112+
elif kw.arg == 'default_factory':
113+
if isinstance(kw.value, ast.Name):
114+
# Handle common default factories.
115+
if kw.value.id == 'dict':
116+
default_value = {}
117+
elif kw.value.id == 'list':
118+
default_value = []
119+
else:
120+
logger.warning(f"Unknown default_factory {kw.value.id} for field {field_name}, skipping evaluation.")
121+
else:
122+
try:
123+
default_value = ast.literal_eval(kw.value)
124+
except Exception as e:
125+
logger.error(f"Failed to eval default_factory for field {field_name}: {e}")
114126
# Iterate again to extract 'metadata' if available.
115127
for kw in item.value.keywords:
116128
if kw.arg == 'metadata' and isinstance(kw.value, ast.Dict):
@@ -131,7 +143,6 @@ def extract_config_metadata(node: ast.ClassDef) -> Optional[Dict]:
131143
if default_value is not None:
132144
field_data['default'] = default_value
133145

134-
# Save the processed field data under its name.
135146
fields[field_name] = field_data
136147

137148
# Return the gathered metadata if any fields were identified; otherwise, return None.

pyllments/recipes/runner.py

+4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def run_recipe(
7474
no_gui: bool = False,
7575
port: int = 8000,
7676
env: Optional[str] = None,
77+
host: str = "127.0.0.1",
7778
config: Optional[dict[str, Any]] = None
7879
) -> None:
7980
"""Run a recipe.
@@ -92,6 +93,8 @@ def run_recipe(
9293
Port to run server on, by default 8000
9394
env : Optional[str], optional
9495
Path to .env file, by default None
96+
host : str, optional
97+
Network interface to bind the server to, by default "127.0.0.1"
9598
config : Optional[dict[str, Any]], optional
9699
Configuration parameters for the recipe, by default None
97100
"""
@@ -108,6 +111,7 @@ def run_recipe(
108111
find_gui=not no_gui,
109112
port=port,
110113
env=env,
114+
host=host,
111115
config=config or {}
112116
)
113117
except Exception as e:

pyllments/recipes/simple_flow/simple_flow.py

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
and expose it through an API endpoint.
55
"""
66
from dataclasses import dataclass, field
7-
from typing import Optional
87

98
from pyllments.elements import ChatInterfaceElement, LLMChatElement, APIElement
109
from pyllments.payloads import MessagePayload

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ dependencies = [
2727
"langchain-community",
2828
"langchain-chroma",
2929
"langchain-anthropic",
30-
"sentence-transformers",
30+
"sentence-transformers[onnx-gpu]",
3131
"openai",
3232
"jsonlines",
3333
"opencv-python",

0 commit comments

Comments
 (0)