Skip to content

Commit 5a784d5

Browse files
committed
Add entry points and update readme.
1 parent 6118df2 commit 5a784d5

File tree

4 files changed

+216
-37
lines changed

4 files changed

+216
-37
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ __pycache__
77
build/
88
dist/
99
.ailly_iam_policy
10+
*.log
Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,109 @@
1-
# Ailly Prompt Workflow
1+
# Lliam - LLM-powered IAM Policy Metadata Enhancement
22

3-
This project automates the process of generating, running, parsing, and applying [Ailly](https://www.npmjs.com/package/@ailly/cli) prompt outputs to an AWS DocGen project. It combines all steps into one streamlined command using a single Python script.
3+
Lliam automates the process of generating, running, parsing, and applying [Ailly](https://www.npmjs.com/package/@ailly/cli) prompt outputs to enhance AWS DocGen IAM policy examples with rich metadata.
44

55
---
66

77
## 📦 Overview
88

9-
This tool:
10-
1. **Generates** Ailly prompts from DocGen snippets.
11-
2. **Runs** Ailly CLI to get enhanced metadata.
12-
3. **Parses** Ailly responses into structured JSON.
13-
4. **Updates** your DocGen examples with the new metadata.
9+
Lliam provides a multi-step workflow to:
10+
1. **Generate** Ailly prompts from DocGen IAM policy snippets
11+
2. **Execute** Ailly CLI to get LLM-enhanced metadata
12+
3. **Update** your DocGen examples with the enhanced metadata
1413

15-
All of this is done with one command.
14+
The workflow is designed around three main commands that can be run independently or in sequence.
1615

1716
---
1817

1918
## ✅ Prerequisites
2019

2120
- Python 3.8+
22-
- Node.js and npm (for `npx`)
23-
- A DocGen project directory
21+
- Node.js and npm (for `npx @ailly/cli`)
22+
- A DocGen project directory with IAM policy examples
2423

2524
---
2625

2726
## 🚀 Usage
2827

29-
From your project root, run:
28+
### Step 1: Create Prompts
29+
30+
Generate Ailly prompts from your DocGen IAM policy examples:
3031

3132
```bash
32-
python -m aws_doc_sdk_examples_tools.agent.bin.main \
33+
python -m aws_doc_sdk_examples_tools.lliam.entry_points.lliam_app create-prompts \
3334
/path/to/your/docgen/project \
3435
--system-prompts path/to/system_prompt.txt
3536
```
3637

37-
### 🔧 Arguments
38+
### Step 2: Run Ailly
3839

39-
- `iam_tributary_root`: Path to the root directory of your IAM policy tributary
40-
- `--system-prompts`: List of system prompt files or strings to include in the Ailly configuration
41-
- `--skip-generation`: Skip the prompt generation and Ailly execution steps (useful for reprocessing existing outputs)
40+
Execute Ailly to generate enhanced metadata:
4241

43-
Run `python -m aws_doc_sdk_examples_tools.agent.bin.main update --help` for more info.
42+
```bash
43+
python -m aws_doc_sdk_examples_tools.lliam.entry_points.lliam_app run-ailly
44+
```
4445

45-
---
46+
Optionally process specific batches:
47+
```bash
48+
python -m aws_doc_sdk_examples_tools.lliam.entry_points.lliam_app run-ailly --batches "1,3,5"
49+
python -m aws_doc_sdk_examples_tools.lliam.entry_points.lliam_app run-ailly --batches "10..15"
50+
```
4651

47-
## 🗂 What This Does
52+
### Step 3: Update Repository
4853

49-
Under the hood, this script:
54+
Apply the enhanced metadata back to your DocGen examples:
5055

51-
1. Creates a directory `.ailly_iam_policy` containing:
52-
- One Markdown file per snippet.
53-
- A `.aillyrc` configuration file.
56+
```bash
57+
python -m aws_doc_sdk_examples_tools.lliam.entry_points.lliam_app update-reservoir \
58+
/path/to/your/docgen/project
59+
```
5460

55-
2. Runs `npx @ailly/cli` to generate `.ailly.md` outputs.
61+
Optionally update specific batches or packages:
62+
```bash
63+
python -m aws_doc_sdk_examples_tools.lliam.entry_points.lliam_app update-reservoir \
64+
/path/to/your/docgen/project \
65+
--batches "1..5" \
66+
--packages "package1,package2"
67+
```
68+
69+
---
5670

57-
3. Parses the Ailly `.ailly.md` files into a single `iam_updates.json` file.
71+
## 🗂 Workflow Details
5872

59-
4. Updates each matching `Example` in the DocGen instance with:
60-
- `title`
61-
- `title_abbrev`
62-
- `synopsis`
73+
1. **Prompt Generation**:
74+
- Scans DocGen examples for IAM policies with default metadata prefixes
75+
- Creates batched Markdown files in `.ailly_iam_policy/`
76+
- Generates `.aillyrc` configuration with system prompts
77+
78+
2. **Ailly Execution**:
79+
- Runs `npx @ailly/cli` on generated prompts
80+
- Processes batches to manage large datasets
81+
- Generates `.ailly.md` response files
82+
83+
3. **Metadata Update**:
84+
- Parses Ailly responses for enhanced metadata
85+
- Updates DocGen examples with `title`, `title_abbrev`, `synopsis`, and `description`
86+
- Applies service-specific suffixes to metadata
6387

6488
---
6589

66-
## 💡 Example
90+
## 💡 Example Workflow
6791

6892
```bash
69-
python -m aws_doc_sdk_examples_tools.agent.bin.main \
93+
# Generate prompts from IAM policy examples
94+
python -m aws_doc_sdk_examples_tools.lliam.entry_points.lliam_app create-prompts \
7095
~/projects/AWSIAMPolicyExampleReservoir \
71-
--system-prompts prompts/system_prompt.txt
96+
--system-prompts prompts/iam_system_prompt.txt
97+
98+
# Run Ailly on all generated prompts
99+
python -m aws_doc_sdk_examples_tools.lliam.entry_points.lliam_app run-ailly
100+
101+
# Update the repository with enhanced metadata
102+
python -m aws_doc_sdk_examples_tools.lliam.entry_points.lliam_app update-reservoir \
103+
~/projects/AWSIAMPolicyExampleReservoir
72104
```
73105

74-
This will:
75-
- Write prompts and config to `.ailly_iam_policy/`
76-
- Run Ailly and capture results
77-
- Parse and save output as `.ailly_iam_policy/iam_updates.json`
78-
- Apply updates to your DocGen examples
106+
This workflow will:
107+
- Extract IAM policy snippets and create batched prompts in `.ailly_iam_policy/`
108+
- Execute Ailly to generate enhanced metadata
109+
- Parse responses and update your DocGen examples with rich metadata
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
from pathlib import Path
2+
from typing import List, Optional
3+
from typing_extensions import Annotated
4+
from datetime import datetime
5+
import logging
6+
import typer
7+
8+
from aws_doc_sdk_examples_tools.lliam.config import (
9+
AILLY_DIR,
10+
BATCH_PREFIX
11+
)
12+
from aws_doc_sdk_examples_tools.lliam.domain import commands
13+
from aws_doc_sdk_examples_tools.lliam.service_layer import messagebus, unit_of_work
14+
15+
logging.basicConfig(
16+
level=logging.INFO,
17+
filename=f"lliam-run-{datetime.now().strftime('%Y%m%d_%H%M%S')}.log",
18+
filemode="w",
19+
)
20+
21+
logger = logging.getLogger(__name__)
22+
app = typer.Typer(name="Lliam")
23+
24+
25+
@app.command()
26+
def create_prompts(iam_tributary_root: str, system_prompts: List[str] = []):
27+
doc_gen_root = iam_tributary_root
28+
cmd = commands.CreatePrompts(
29+
doc_gen_root=doc_gen_root,
30+
system_prompts=system_prompts,
31+
out_dir=AILLY_DIR,
32+
)
33+
uow = unit_of_work.FsUnitOfWork()
34+
messagebus.handle(cmd, uow)
35+
36+
37+
@app.command()
38+
def run_ailly(
39+
batches: Annotated[
40+
Optional[str],
41+
typer.Option(
42+
help="Batch names to process (comma-separated list)"
43+
),
44+
] = None,
45+
) -> None:
46+
"""
47+
Run ailly to generate IAM policy content and process the results.
48+
If batches is specified, only those batches will be processed.
49+
If batches is omitted, all batches will be processed.
50+
"""
51+
requested_batches = parse_batch_names(batches)
52+
cmd = commands.RunAilly(batches=requested_batches)
53+
messagebus.handle(cmd)
54+
55+
56+
@app.command()
57+
def update_reservoir(
58+
iam_tributary_root: str,
59+
batches: Annotated[
60+
Optional[str],
61+
typer.Option(
62+
help="Batch names to process (comma-separated list)"
63+
),
64+
] = None,
65+
packages: Annotated[
66+
Optional[str], typer.Option(help="Comma delimited list of packages to update")
67+
] = None,
68+
) -> None:
69+
"""
70+
Update the doc_gen reservoir with processed IAM policy updates.
71+
If batches is specified, only those batch directories will be processed.
72+
If batches is omitted, all available update files will be processed.
73+
"""
74+
doc_gen_root = Path(iam_tributary_root)
75+
batch_names = parse_batch_names(batches)
76+
package_names = parse_package_names(packages)
77+
cmd = commands.UpdateReservoir(
78+
root=doc_gen_root, batches=batch_names, packages=package_names
79+
)
80+
messagebus.handle(cmd)
81+
82+
83+
def parse_batch_names(batch_names_str: Optional[str]) -> List[str]:
84+
"""
85+
Parse batch names from a comma-separated string.
86+
"""
87+
if not batch_names_str:
88+
return []
89+
90+
batch_names = []
91+
92+
for name in batch_names_str.split(","):
93+
maybe_batch_name = name.strip()
94+
assert maybe_batch_name.startswith(BATCH_PREFIX)
95+
batch_names.append(maybe_batch_name)
96+
97+
return batch_names
98+
99+
100+
def parse_package_names(package_names_str: Optional[str]) -> List[str]:
101+
if not package_names_str:
102+
return []
103+
104+
return [n.strip() for n in package_names_str.split(",")]
105+
106+
107+
if __name__ == "__main__":
108+
app()
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from typing import Callable, Dict, Optional, Type
2+
3+
from aws_doc_sdk_examples_tools.lliam.domain import commands
4+
from aws_doc_sdk_examples_tools.lliam.service_layer import (
5+
create_prompts,
6+
update_doc_gen,
7+
run_ailly,
8+
unit_of_work,
9+
)
10+
11+
# Only handling Commands for now.
12+
Message = commands.Command
13+
14+
15+
def handle(
16+
message: commands.Command, uow: Optional[unit_of_work.FsUnitOfWork] = None
17+
):
18+
queue = [message]
19+
20+
while queue:
21+
message = queue.pop(0)
22+
if isinstance(message, commands.Command):
23+
handle_command(message, uow)
24+
else:
25+
raise Exception(f"{message} was not a Command")
26+
27+
28+
def handle_command(
29+
command: commands.Command, uow: Optional[unit_of_work.FsUnitOfWork]
30+
):
31+
handler = COMMAND_HANDLERS[type(command)]
32+
handler(command, uow)
33+
34+
35+
COMMAND_HANDLERS: Dict[Type[commands.Command], Callable] = {
36+
commands.CreatePrompts: create_prompts.create_prompts,
37+
commands.RunAilly: run_ailly.handle_run_ailly,
38+
commands.UpdateReservoir: update_doc_gen.handle_update_reservoir,
39+
}

0 commit comments

Comments
 (0)