Skip to content

Commit c26f79a

Browse files
authored
Merge pull request #339 from ai-agent-assembly/v0.0.1/AAASM-4838/live_mode_inert
[AAASM-4838] 📝 (examples): Make crewai/langchain-research live-mode honest (was inert)
2 parents 8f17bfc + a2039ae commit c26f79a

4 files changed

Lines changed: 83 additions & 54 deletions

File tree

python/crewai-research-crew/README.md

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,11 @@ audit event.
4444
| [uv](https://github.com/astral-sh/uv) | latest |
4545
| Agent Assembly Python SDK | >= 0.0.1rc6 |
4646

47-
The mock demo needs no gateway, no `crewai`, and no API keys. The optional
48-
`live` extra (`crewai`) is only required for the real-crew integration.
47+
The mock demo needs no gateway, no `crewai`, and no API keys — and it is the
48+
only run mode this example implements (see "A real CrewAI integration is not
49+
shipped in this example" below). The optional `live` extra (`crewai`) is
50+
declared for a future real-crew integration but is not exercised by any code
51+
here.
4952

5053
## Setup
5154

@@ -60,8 +63,10 @@ uv sync --extra dev
6063
uv run python src/main.py --mock
6164
```
6265

63-
`--mock` replays a scripted crew delegation trajectory offline. The example also
64-
auto-falls back to mock mode whenever `OPENAI_API_KEY` is unset.
66+
`--mock` replays a scripted crew delegation trajectory offline. This is the only
67+
run mode this example implements — running without `--mock` (with an
68+
`OPENAI_API_KEY` set) prints a notice that the live CrewAI integration is not
69+
implemented here and exits without doing anything.
6570

6671
### Expected governance output
6772

@@ -146,24 +151,20 @@ event then records an `allow` decision.
146151
uv run pytest tests/ -v
147152
```
148153

149-
## Switching to the live CrewAI integration
154+
## A real CrewAI integration is not shipped in this example
150155

151-
1. Install the live extra: `pip install -e '.[live]'` (pulls in `crewai`).
152-
2. Start an Agent Assembly gateway (or use your SaaS workspace URL).
153-
3. Copy `.env.example` to `.env` and fill in your credentials.
154-
4. Configure the approval gate and shared budget in the gateway.
155-
5. Run without `--mock` and with a real LLM provider key:
156+
This example is an **offline scripted governance demo** — it replays a fixed
157+
crew delegation trajectory so the governance wiring can be exercised
158+
deterministically, with no `crewai` install and no API keys. It does **not**
159+
drive a real CrewAI crew, and there is no runnable "live" mode: invoking it
160+
without `--mock` prints a notice to that effect and exits.
156161

157-
```bash
158-
AGENT_ASSEMBLY_GATEWAY_URL=http://localhost:8080 \
159-
AGENT_ASSEMBLY_API_KEY=your-key \
160-
OPENAI_API_KEY=sk-your-real-key \
161-
uv run python src/main.py
162-
```
163-
164-
In production, map each `CrewMember` onto a `crewai.Agent` and replace
165-
`CrewPolicyEngine` with the gateway-backed interceptor; the SDK enforces the
166-
gateway's policy and emits delegation-aware audit events automatically.
162+
Wiring a real crew is left as an integration exercise. Conceptually it means
163+
mapping each `CrewMember` onto a `crewai.Agent`, running the real crew, and
164+
replacing `CrewPolicyEngine` with the gateway-backed interceptor so the SDK
165+
enforces the gateway's policy and emits delegation-aware audit events
166+
automatically. That real loop is intentionally out of scope for this example
167+
gallery, so nothing here promises a live command that the code does not run.
167168

168169
## Links
169170

python/crewai-research-crew/src/main.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@
1212
- caps spend across all three agents at $2.00 / day (shared budget)
1313
- records every call as an AuditEvent with a delegation call stack
1414
15-
Run (offline mock mode — no crewai, no API keys, what CI runs):
15+
This example is an *offline scripted* governance demo: it replays a fixed crew
16+
delegation trajectory (``MOCK_TRAJECTORY``) so the governance wiring can be
17+
exercised deterministically with no ``crewai`` install and no API keys. It does
18+
**not** drive a real CrewAI crew — there is no live LLM loop wired in here.
19+
Mapping each ``CrewMember`` onto a real ``crewai.Agent`` is left as an
20+
integration exercise (see the README); a non-mock invocation is therefore
21+
refused with a clear message rather than replaying the script mislabelled as
22+
"live".
23+
24+
Run (what CI runs):
1625
uv run python src/main.py --mock
17-
18-
For the live CrewAI integration:
19-
pip install -e '.[live]'
20-
OPENAI_API_KEY=sk-... AGENT_ASSEMBLY_GATEWAY_URL=http://localhost:8080 \\
21-
uv run python src/main.py
2226
"""
2327
from __future__ import annotations
2428

@@ -74,7 +78,17 @@ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
7478

7579
def main(argv: list[str] | None = None) -> None:
7680
args = _parse_args(argv)
77-
mock = args.mock or not os.environ.get("OPENAI_API_KEY")
81+
# This example ships only the offline scripted trajectory — no real CrewAI
82+
# crew is wired in. Refuse a live run plainly instead of replaying the
83+
# script under a "live" label (the inert-live-mode bug this fixes).
84+
if not args.mock and os.environ.get("OPENAI_API_KEY"):
85+
print(
86+
"Live CrewAI integration is not implemented in this example — it is "
87+
"an offline scripted governance demo.\n"
88+
"Re-run with --mock (or without OPENAI_API_KEY) to replay the crew "
89+
"delegation trajectory."
90+
)
91+
return
7892

7993
print("=" * 64)
8094
print(" Agent Assembly — CrewAI Multi-Agent Research Crew")
@@ -83,7 +97,7 @@ def main(argv: list[str] | None = None) -> None:
8397

8498
gateway_url = os.environ.get("AGENT_ASSEMBLY_GATEWAY_URL", "http://localhost:8080")
8599
api_key = os.environ.get("AGENT_ASSEMBLY_API_KEY")
86-
mode_label = "mock (offline)" if mock else "live"
100+
mode_label = "mock (offline)"
87101

88102
print(f"Initializing Agent Assembly (gateway: {gateway_url}, sdk-only mode)...")
89103

python/langchain-research-agent/README.md

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ uv sync --extra dev
5858
uv run python src/main.py --mock
5959
```
6060

61-
`--mock` replays a scripted ReAct trajectory offline. The example also auto-falls
62-
back to mock mode whenever `OPENAI_API_KEY` is unset.
61+
`--mock` replays a scripted ReAct trajectory offline. This is the only run mode
62+
this example implements — running without `--mock` (with an `OPENAI_API_KEY`
63+
set) prints a notice that the live LangChain integration is not implemented here
64+
and exits without doing anything.
6365

6466
### Expected governance output
6567

@@ -130,22 +132,21 @@ governance evidence a real gateway would persist server-side.
130132
uv run pytest tests/ -v
131133
```
132134

133-
## Switching to production mode
134-
135-
1. Start an Agent Assembly gateway (or use your SaaS workspace URL).
136-
2. Copy `.env.example` to `.env` and fill in your credentials.
137-
3. Configure the balanced policy (allowlist / budget / redaction) in the gateway.
138-
4. Run without `--mock` and with a real LLM provider key:
139-
140-
```bash
141-
AGENT_ASSEMBLY_GATEWAY_URL=http://localhost:8080 \
142-
AGENT_ASSEMBLY_API_KEY=your-key \
143-
OPENAI_API_KEY=sk-your-real-key \
144-
uv run python src/main.py
145-
```
146-
147-
In production, replace `BalancedPolicyEngine` with the gateway-backed interceptor;
148-
the SDK enforces the policy rules configured in the gateway automatically.
135+
## A real LangChain integration is not shipped in this example
136+
137+
This example is an **offline scripted governance demo** — it replays a fixed
138+
ReAct trajectory so the governance wiring can be exercised deterministically,
139+
with no API keys. It does **not** drive a real LangChain agent loop, and there
140+
is no runnable "live" mode: invoking it without `--mock` prints a notice to that
141+
effect and exits.
142+
143+
Wiring a real agent is left as an integration exercise. Conceptually it means
144+
driving a real LangChain ReAct loop over the `web_search` and `calculator` tools
145+
with an LLM provider, and replacing `BalancedPolicyEngine` with the
146+
gateway-backed interceptor so the SDK enforces the policy rules configured in
147+
the gateway automatically. That real loop is intentionally out of scope for this
148+
example gallery, so nothing here promises a live command that the code does not
149+
run.
149150

150151
## Links
151152

python/langchain-research-agent/src/main.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@
1414
The run finishes with a deliberate credential-leak attempt using a SAFE FAKE
1515
key, which the policy blocks.
1616
17-
Run (offline mock mode — no API keys, what CI runs):
17+
This example is an *offline scripted* governance demo: it replays a fixed ReAct
18+
trajectory (``_MOCK_REACT_STEPS``) so the governance wiring can be exercised
19+
deterministically with no API keys. It does **not** drive a real LangChain
20+
agent loop — no LLM provider is wired in here. Building a real ReAct loop over
21+
these tools is left as an integration exercise (see the README); a non-mock
22+
invocation is therefore refused with a clear message rather than replaying the
23+
script mislabelled as "live".
24+
25+
Run (what CI runs):
1826
uv run python src/main.py --mock
19-
20-
For production use, start the Agent Assembly gateway and drop ``--mock``:
21-
AGENT_ASSEMBLY_GATEWAY_URL=http://localhost:8080 \\
22-
OPENAI_API_KEY=sk-... uv run python src/main.py
2327
"""
2428
from __future__ import annotations
2529

@@ -87,8 +91,17 @@ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
8791

8892
def main(argv: list[str] | None = None) -> None:
8993
args = _parse_args(argv)
90-
# No real LLM provider is wired in this example, so --mock is the only path.
91-
mock = args.mock or not os.environ.get("OPENAI_API_KEY")
94+
# No real LLM provider is wired in this example, so the scripted trajectory
95+
# is the only path. Refuse a live run plainly instead of replaying the
96+
# script under a "live" label (the inert-live-mode bug this fixes).
97+
if not args.mock and os.environ.get("OPENAI_API_KEY"):
98+
print(
99+
"Live LangChain integration is not implemented in this example — it "
100+
"is an offline scripted governance demo.\n"
101+
"Re-run with --mock (or without OPENAI_API_KEY) to replay the ReAct "
102+
"research trajectory."
103+
)
104+
return
92105

93106
print("=" * 64)
94107
print(" Agent Assembly — LangChain ReAct Research Agent")
@@ -97,7 +110,7 @@ def main(argv: list[str] | None = None) -> None:
97110

98111
gateway_url = os.environ.get("AGENT_ASSEMBLY_GATEWAY_URL", "http://localhost:8080")
99112
api_key = os.environ.get("AGENT_ASSEMBLY_API_KEY")
100-
mode_label = "mock (offline)" if mock else "live"
113+
mode_label = "mock (offline)"
101114

102115
print(f"Initializing Agent Assembly (gateway: {gateway_url}, sdk-only mode)...")
103116

0 commit comments

Comments
 (0)