Skip to content

Commit 18b07aa

Browse files
0bserver07claude
andcommitted
docs(function_synthesis): add full-lifecycle demo runnable without a GGUF
examples/function_synthesis_quickstart.py covers steps 1-3 (spec → compile → install). This new demo extends to 6 steps including actual invoke + agent-tool integration, using an inline StubBackend so users can run it end-to-end without downloading a multi-GB base model. Walks through: 1. FunctionSpec with examples 2. MockCompiler (no network) 3. ProgramRegistry.install 4. ZIP-inspect the .chi bundle (shows the format) 5. CompiledFunction.from_path + StubBackend.invoke 6. CompiledFunctionTool for agent integration Everything runs in a TemporaryDirectory — user's real ~/.chimera/ is untouched. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c99d736 commit 18b07aa

1 file changed

Lines changed: 137 additions & 0 deletions

File tree

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#!/usr/bin/env python3
2+
"""Full-lifecycle function-synthesis demo — no GGUF required.
3+
4+
Walks through the whole path a user would take:
5+
1. Write a FunctionSpec (name + description + examples)
6+
2. Compile with MockCompiler (no network, no training)
7+
3. Install into the local registry (~/.chimera/function_synthesis/)
8+
4. Peek inside the resulting .chi bundle (ZIP archive format)
9+
5. Load the bundle with a local StubBackend (no llama.cpp needed)
10+
6. Call the compiled function
11+
7. Expose it as a Chimera agent tool via CompiledFunctionTool
12+
13+
For the real-model path, swap StubBackend for LlamaCppBackend with a base
14+
GGUF on disk.
15+
16+
Usage:
17+
python examples/function_synthesis_full_demo.py
18+
"""
19+
from __future__ import annotations
20+
21+
import json
22+
import os
23+
import tempfile
24+
import zipfile
25+
26+
from chimera.function_synthesis import (
27+
ChiBundle,
28+
CompiledFunction,
29+
FunctionSpec,
30+
RuntimeBackend,
31+
)
32+
from chimera.function_synthesis.cache import CacheDirs
33+
from chimera.function_synthesis.compilers.mock import MockCompiler
34+
from chimera.function_synthesis.registry import ProgramRegistry
35+
from chimera.tools.compiled_function_tool import CompiledFunctionTool
36+
37+
38+
class StubBackend(RuntimeBackend):
39+
"""Tiny local backend that ignores the adapter and echoes a template.
40+
41+
Useful for demos + tests. For real inference, use LlamaCppBackend.
42+
"""
43+
44+
def __init__(self) -> None:
45+
self._bundle: ChiBundle | None = None
46+
47+
def load(self, bundle: ChiBundle) -> None:
48+
self._bundle = bundle
49+
50+
def invoke(self, user_input: str, *, max_tokens: int = 256) -> str:
51+
if self._bundle is None:
52+
raise RuntimeError("backend not loaded")
53+
spec = self._bundle.spec
54+
# Deterministic stub: echo the spec description + user input.
55+
return f"[{spec.name}] {spec.description.strip()} :: {user_input}"
56+
57+
def close(self) -> None:
58+
self._bundle = None
59+
60+
61+
def section(title: str) -> None:
62+
print(f"\n{'=' * 60}\n{title}\n{'=' * 60}")
63+
64+
65+
def main() -> None:
66+
# Use a scratch dir so the demo doesn't pollute real state
67+
with tempfile.TemporaryDirectory(prefix="chimera-fs-demo-") as tmp:
68+
os.environ["CHIMERA_FS_HOME"] = tmp
69+
70+
section("1. Define the function spec")
71+
spec = FunctionSpec(
72+
name="sentiment",
73+
description="Classify text as 'positive' or 'negative'.",
74+
examples=[
75+
{"input": "I love this product", "output": "positive"},
76+
{"input": "Total waste of money", "output": "negative"},
77+
],
78+
)
79+
print(f" name: {spec.name}")
80+
print(f" description: {spec.description}")
81+
print(f" examples: {len(spec.examples)}")
82+
83+
section("2. Compile with MockCompiler (offline, deterministic)")
84+
compiler = MockCompiler()
85+
bundle = compiler.compile(spec)
86+
print(f" adapter: {len(bundle.adapter_bytes)} bytes")
87+
print(f" system: {bundle.prompts['system']!r}")
88+
print(f" metadata: {bundle.metadata}")
89+
90+
section("3. Install into local registry")
91+
registry = ProgramRegistry(CacheDirs.default())
92+
slug = registry.install(spec=spec, bundle=bundle)
93+
entry = registry.resolve(slug)
94+
print(f" slug: {slug}")
95+
print(f" path: {entry.bundle_path}")
96+
97+
section("4. Inspect the .chi bundle (it's a ZIP)")
98+
with zipfile.ZipFile(entry.bundle_path) as zf:
99+
for info in zf.infolist():
100+
print(f" {info.filename:20s} {info.file_size:6d} bytes")
101+
print()
102+
manifest = json.loads(zf.read("manifest.json"))
103+
print(f" manifest.schema_version: {manifest['schema_version']}")
104+
print(f" manifest.adapter_format: {manifest['adapter_format']}")
105+
106+
section("5. Load + call via StubBackend (no GGUF needed)")
107+
fn = CompiledFunction.from_path(entry.bundle_path, backend=StubBackend())
108+
output = fn("The performance is amazing")
109+
print(" fn('The performance is amazing')")
110+
print(f" -> {output}")
111+
fn.close()
112+
113+
section("6. Expose as an agent tool")
114+
fn = CompiledFunction.from_path(entry.bundle_path, backend=StubBackend())
115+
tool = CompiledFunctionTool(fn)
116+
print(f" tool.name: {tool.name}")
117+
print(f" tool.description: {tool.description[:60]}")
118+
# Call the tool the way an agent would
119+
result = tool.execute({"user_input": "boring and slow"}, env=None)
120+
print(" tool.execute({'user_input': 'boring and slow'})")
121+
print(f" -> success={result.success}")
122+
print(f" output={result.output}")
123+
fn.close()
124+
125+
section("Done")
126+
print("This demo used StubBackend — a local echo. For real inference,")
127+
print("use LlamaCppBackend:")
128+
print(" pip install 'chimera[function_synthesis]'")
129+
print(" from chimera.function_synthesis.backends.llama_cpp import LlamaCppBackend")
130+
print(" backend = LlamaCppBackend(base_model_path='path/to/base.gguf')")
131+
print()
132+
print(f"Registry lived at: {tmp}")
133+
print("(destroyed on exit so your real ~/.chimera/ is untouched)")
134+
135+
136+
if __name__ == "__main__":
137+
main()

0 commit comments

Comments
 (0)