Jac: Python superset for AI-powered graph applications. Install: pip install jaclang. Python 3.12+ required. CLI: jac run file.jac (execute), jac serve file.jac (API server localhost:8000), jac test file.jac (run tests), jac --version. VS Code: jaclang-extension. Entry: with entry {code}. Files: .jac interface, .impl.jac implementation (auto-import), .test.jac tests. Syntax: semicolons end statements, braces for blocks {}, f"text {var}" formatting, # comments, #* multi-line *#. Types mandatory: var: type = value. Types: Primitives: int str float bool any. Collections: list[T] dict[K,V] set[T] tuple[T1,T2]. Union: type1|type2. Optional: T|None. Enums: enum Status {PENDING, ACTIVE, DONE}; usage: Status.ACTIVE. Type inference: return types inferred. Generic: list[T] dict[K,V]. Callable: callable[[Args], Return]. Control flow: If: if score > 90 {grade = "A";} elif score > 80 {grade = "B";} else {grade = "C";}. While: while count < 10 {count += 1; if count == 5 {continue;}; print(count);}. For: for item in collection {process(item);}; for i in range(5) {print(i);}; for i = 0 to i < 10 by i += 1 {print(i);}; for idx, val in enumerate(items) {print(f"{idx}: {val}");}; for key, val in dict.items() {use(key, val);}. Match: match status {case "active": process(); case "pending": wait(); case _: error();}; match data {case {"type": "user", "id": uid}: load_user(uid); case {"type": "post", "content": text}: create_post(text); case _: invalid();}. Exception handling: try {result = risky_op();} except ValueError as e {print(f"Error: {e}");} except Exception {print("Unknown");} finally {cleanup();}. Raise: raise ValueError("Invalid input"). Custom: class MyError(Exception) {pass}; raise MyError("message"). Functions: def add(a: int, b: int) -> int {return a + b;}. Syntax: def name(param: type = default) -> return_type {body}. Default params: def greet(name: str = "World") -> str {return f"Hello {name}";}. Variadic: def sum_all(*nums: int) -> int {return sum(nums);}; def config(**opts: str) -> dict {return opts;}. Async: async def fetch() {data = await get_data(); return data;}; asyncio.run(fetch()). Lambda: square = lambda x: int: x * x; sorted_items = sorted(items, key=lambda item: tuple: item[1]). Syntax: lambda param: type: expression. Decorators: @timer def func() {code}. Global: glob max_users: int = 100; access via :g:max_users. Objects: obj Person {has name: str; has age: int = 0; def greet(self) -> str {return f"Hi, I'm {self.name}";}}. Auto-constructor from has. Instantiate: person = Person(name="Alice", age=30); print(person.name). Inheritance: obj Animal {has name: str; def speak(self) -> str {return "sound";}}; obj Dog(Animal) {def speak(self) -> str {return "bark";}}; d = Dog(name="Rex"); d.speak(). Static: obj Counter {static has count: int = 0; has id: int; def postinit {Counter.count += 1; self.id = Counter.count;}}. Postinit: obj Database {has conn; def postinit {self.conn = connect();}}. Implementation separation: file.jac: obj Calculator {has val: int; def add(n: int) -> int;}. file.impl.jac: impl Calculator.add(n: int) -> int {self.val += n; return self.val;}. Auto-imported. For functions: def process(data: str) -> str; impl process(data: str) -> str {return data.upper();}. Nodes (graph vertices): node User {has username: str; has email: str; def validate(self) -> bool {return "@" in self.email;}}; node Post {has content: str; has created: str; can process with Moderator entry {visitor.check(here.content);}}. Keywords: here=current node, visitor=walker, self=node. Abilities: can ability_name with WalkerType entry|exit {code}. Example: node Task {has status: str; can start with Worker entry {here.status = "running"; visitor.log(f"Started {here}");}; can finish with Worker exit {here.status = "done";}}. Edges (relationships): edge Friendship {has strength: float; has since: str;}; edge Follows {has notify: bool = True;}. Generic: alice ++> bob (forward), alice <++> bob (bidirectional). Typed: alice +>:Friendship:strength=0.9:+> bob; user +>:Follows:notify=True:+> celebrity. Bidirectional typed: node1 <+:EdgeType:attr=val:<+ node2. Delete: alice del --> bob. Edge abilities: can ability with WalkerType entry|exit {visitor, self, path}. Walkers (mobile computation): walker Crawler {has visited: list = []; has max_depth: int = 3; can crawl with Page entry {here.fetch(); visit [here --> (`?Page)];}}; walker Analyzer {has results: dict = {}; can analyze with DataNode entry {here.process(); visitor.results[here.id] = here.value;}}. Spawn: root spawn Crawler(max_depth=5); user spawn NotificationSender(message="Hello"). Visit: visit [here -->] successors; visit [here <--] predecessors; visit [here <-->] both; visit [here --> (`?User)](?is_active) filtered; visit [here ->:Follows:->] by edge type; visit [-->] else {disengage;} with fallback. Control: disengage exits walker immediately; skip skips current node. Report: walker Query {can search with Result entry {report here.data;}}; multiple reports accumulate in list. Root: walker Init {can setup with `root entry {profile = here ++> Profile();}}. Execution order: location entry abilities → walker entry abilities → visit statements update queue → walker exit abilities → location exit abilities → walker moves to next node. Abilities: can ability_name with NodeType entry {code}; can ability_name with `root entry {code}; can ability_name with entry {code} for any node. Queries & traversal: [node -->] successors, [<-- node] predecessors. Type filter: [root --> (`?User)] by node type; [user --> (`?Post)] posts. Attribute filter: [root --> (`?User)](?is_active) active users; [user --> (`?Post)](?created > cutoff) recent. Edge filter: [user -->:Follows:-> (`?User)] followed users; [person --->:Friendship:->] friendships. Edge property: [user ->:Follows:notify==True:-> (`?Topic)] notifying follows. Multi-hop: [user -->:Follows:-> (`?User) --> (`?Post)] friends' posts; [node --> --> (`?Target)] two hops. Combine: [start --> (`?Mid)](?active) --> (`?End)](?valid) chained filters. Edges access: [node --->] outgoing edges, [<--- node] incoming edges. Persistence: root per-user anchor. Auto-persist if connected to root. Manual: save(node); save(edge); commit() flushes all; commit(User) flushes specific type. Example: new_user = User(name="Alice"); save(new_user); commit(); later: user = [root --> (`?User)](?name == "Alice")[0]; user.age = 30; commit(user). Database: MongoDB stores nodes/edges/walkers. References: friend_id = "n::123abc"; friend = &friend_id; friend.message = "Hi". byLLM (AI integration): pip install byllm. import from byllm {Model, Image, Video}. glob llm = Model(model_name="gpt-4o", temperature=0.7, verbose=True). AI function: def summarize(text: str) -> str by llm(); def classify(content: str) -> Category by llm(); result = summarize("long text"). Methods: obj Article {has content: str; def summary(self) -> str by llm();}; a = Article(content="text"); a.summary(). Reasoning: def solve_math(problem: str) -> int by llm(method='Reason') for chain-of-thought. ReAct: def search_web(query: str) -> str {return api_call(query);}; def assistant(question: str, context: dict) -> str by llm(method='ReAct', tools=[search_web]); result = assistant("What's weather?", {}). Streaming: def generate(prompt: str) -> str by llm(stream=True); for token in generate("Write story") {print(token, end="")}. Structured: obj Person {has name: str; age: int;}; enum Sentiment {POSITIVE, NEGATIVE, NEUTRAL}; def extract(text: str) -> Person by llm(); def analyze(text: str) -> Sentiment by llm(); person = extract("John, 25"); feeling = analyze("I love this!"). Context: docstrings enhance prompts automatically. Semantic: sem ClassName.attr = "description" for domain hints. Additional: by llm(incl_info={"domain": "medical"}) for extra context. Multimodal: img = Image("photo.jpg"); desc = describe_image(img); vid = Video(path="clip.mp4", fps=1); summary = analyze_video(vid). Options: temperature max_tokens top_k top_p verbose max_tries. Jac Cloud (API server): jac serve main.jac → localhost:8000, /docs for Swagger UI. Endpoints: /walker/{name} (root entry), /walker/{name}/{node_id} (node entry). Config: walker create_user {has name: str; has email: str; obj __specs__ {static has methods: list = ["post"]; static has auth: bool = True;}}; call: POST /walker/create_user with JSON {"name": "Alice", "email": "alice@ex.com"}. Methods: ["get","post","put","delete","patch"]. Auth: auth: bool = True requires Bearer token (from /user/login), False disables. Query params: walker search {has query: str; obj __specs__ {static has methods: list = ["get"]; static has auth: bool = False; static has as_query: list = ["query"];}}; call: GET /walker/search?query=test or as_query: "*" for all params. Custom path: static has path: str = "/api/custom". Private: static has private: bool = True hides from API (internal/scheduled only). Response: {"status": 200, "reports": [list of report values], "returns": [return values if enabled]}. File upload: import from fastapi {UploadFile}; walker upload {has file: UploadFile; has name: str; can process with `root entry {content = visitor.file.file.read(); save_file(content, self.name);}}; call: POST /walker/upload multipart/form-data. WebSocket: walker chat {has message: str; obj __specs__ {static has methods: list = ["websocket"];}}; connect: ws://localhost:8000/websocket; optional: Authorization header or ?channel_id=string. Connection event: {"type": "connection", "data": {"client_id": "...", "root_id": "...", "channel_id": "..."}}. Client events: Walker: {"type": "walker", "walker": "chat", "response": true, "context": {"message": "hi"}}. User: {"type": "user", "root_ids": ["n::123"], "data": {"msg": "hello"}}. Channel: {"type": "channel", "channel_ids": ["room1"], "data": {"msg": "hello"}}. Client: {"type": "client", "client_ids": ["cl1"], "data": {"msg": "hello"}}. Change user: {"type": "change_user", "token": "Bearer TOKEN"}. Server notifications: import from jac_cloud.plugin {WEBSOCKET_MANAGER as socket}; socket.notify_self(data); socket.notify_users([root1, root2], data); socket.notify_channels(["ch1"], data); socket.notify_clients(["cl1"], data). Example: walker broadcast {has msg: str; can send with `root entry {socket.notify_channels(["public"], {"text": self.msg});}}. Webhooks: walker webhook_handler {obj __specs__ {static has webhook: dict = {"type": "header", "name": "X-API-KEY"};}; can handle with `root entry {report here;}}; call: POST /webhook/walker/webhook_handler with header X-API-KEY: generated_key. Types: "header|query|path|body". Generate key: POST /webhook/generate-key body {"name": "key1", "walkers": ["handler"], "nodes": ["root"], "expiration": {"count": 60, "interval": "days"}}; response: {"id": "...", "name": "key1", "key": "root:timestamp:secret"}. Manage: GET /webhook lists; PATCH /webhook/extend/{id} body {"count": 30, "interval": "days"} extends; DELETE /webhook/delete body {"ids": ["id1"]} deletes. Scheduler: walker daily_report {obj __specs__ {static has private: bool = True; static has schedule: dict = {"trigger": "cron", "hour": "9", "minute": "0", "save": True};}; can generate with `root entry {report generate_report();}}. Cron: {"trigger": "cron", "hour": "0", "minute": "30", "day": "*", "month": "*"} daily at 00:30. Interval: {"trigger": "interval", "seconds": 30} or "minutes": 5 or "hours": 1 or "days": 1. Date: {"trigger": "date", "run_date": "2025-12-31T23:59:59+00:00"} one-time. Options: max_instances: 1 limits concurrent, next_run_time: datetime first run, propagate: false single service trigger, save: true persist walker. Async walkers: async walker heavy_task {has data: list; can process with `root entry {for item in self.data {compute(item);}}}; result = root spawn heavy_task(data=large_dataset); task_id = result; retrieve: task = &task_id; task.__jac__.status ("completed"|"running"|"failed"), task.__jac__.reports (results list), task.__jac__.error (error message if failed). Task queue: import from jac_cloud.plugin.implementation {create_task}; walker process_item {has item_id: str; obj __specs__ {static has private: bool = True;}; can process with Node entry {logic();}};walker queue_work {can queue with `root entry {items = [root --> (`?Item)]; for item in items {task = create_task(process_item(item_id=item.id), item); report task;}}}. Requires: TASK_CONSUMER_CRON_SECOND env var. Atomic consumption, one instance processes each. Permissions: Levels: NoPerm (no access), ReadPerm (view only), ConnectPerm (can create edges), WritePerm (full access). Grant: _.allow_root(post, friend_root, "READ") specific user; grant(post, ReadPerm) public. Revoke: _.disallow_root(post, friend_root) specific; revoke(post) all public. Check: level = _.check_read_access(node); level = _.check_write_access(node). Custom: node Document {has owner_id: str; is_public: bool; def __jac_access__() -> AccessLevel {if here.is_public {return ReadPerm;}; if _Jac.get_root().id == here.owner_id {return WritePerm;}; return NoPerm;}}. Example: walker share_post {has post_id: str; friend_id: str; can share with `root entry {post = &self.post_id; friend = &self.friend_id; _.allow_root(post, friend, "READ");}}. SSO: Env vars: SSO_{PLATFORM}_CLIENT_ID, SSO_{PLATFORM}_CLIENT_SECRET. Platforms: APPLE, GOOGLE, GOOGLE_ANDROID, GOOGLE_IOS, FACEBOOK, GITHUB, MICROSOFT, LINKEDIN. Apple extra: SSO_APPLE_CLIENT_TEAM_ID, SSO_APPLE_CLIENT_KEY, SSO_APPLE_CLIENT_CERTIFICATE. Callback: GET /sso/{provider}/register/callback?id_token={token} returns user info + jac_token. Example: Frontend gets id_token from Google SDK, calls /sso/google/register/callback?id_token=eyJ..., response: {"email": "user@gmail.com", "name": "User", "token": "jac_auth_token"}. Environment variables: DATABASE_HOST DATABASE_NAME DATABASE_PORT (MongoDB). REDIS_HOST REDIS_PORT REDIS_PASSWORD (WebSocket, tasks, cache). TOKEN_SECRET TOKEN_ALGORITHM TOKEN_TIMEOUT (JWT auth). UV_HOST UV_PORT UV_WORKERS (server config). SHOW_ENDPOINT_RETURNS (bool, show walker returns). DISABLE_AUTO_ENDPOINT (bool). DISABLE_AUTO_CLEANUP (bool). REQUIRE_AUTH_BY_DEFAULT (bool). LOGGER_NAME LOGGER_LEVEL (debug|info|warning|error) LOGGER_FILE_PATH LOGGER_ROLLOVER_INTERVAL (M|H|D|W) LOGGER_MAX_BACKUP LOGGER_USE_UTC. TASK_CONSUMER_CRON_SECOND (task queue polling). Logging: JSON logs at /tmp/jac_cloud_logs/jac-cloud.log. Format: {"timestamp": "ISO8601", "level": "INFO", "message": "Request", "request": {"method": "POST", "path": "/walker/create", "body": {}}, "response": {"status": 200, "body": {}}, "duration": 45, "client_ip": "..."}. View: tail -f /tmp/jac_cloud_logs/jac-cloud.log. Errors: grep '"level":"ERROR"' logfile. Elastic Stack: install Filebeat, config paths /tmp/jac_cloud_logs/*.log, output Elasticsearch, visualize in Kibana. Testing: test test_name {setup; assert condition; assert value == expected; teardown}. Run: jac test file.jac. Examples: test create_user {u = User(name="test"); assert u.name == "test"; assert u.is_valid();}; test graph_structure {root ++> Node(); children = [root -->]; assert len(children) == 1;}; test walker_behavior {root spawn MyWalker(); results = [root --> (`?Result)]; assert len(results) == 2;}. Object-Spatial Programming: Computation moves to data (not data to computation). Nodes=data locations with abilities. Edges=first-class relationships with state. Walkers=mobile agents traversing graph. Abilities=event-driven triggered by walker arrivals. Execution order: 1. Location entry abilities (node/edge) 2. Walker entry abilities 3. Visit statements (queue updates) 4. Walker exit abilities 5. Location exit abilities 6. Walker moves to next. Edge abilities: walker reaches edge → edge entry → destination node auto-queued → edge exit → walker moves to node. Queue: FIFO destination list, visit adds, empty at node=deactivates walker. Path collections: [node1, node2, ...] ordered sequence, visit [path] traverses all. Graph algorithms BFS: walker BFS {has queue: list; has visited: set = set(); can search with Node entry {if here not in self.visited {self.visited.add(here); self.queue.extend([here -->]); process(here);}; if self.queue {visit [self.queue.pop(0)];}}}. DFS: walker DFS {has visited: set = set(); can search with Node entry {if here not in self.visited {self.visited.add(here); process(here); for child in [here -->] {if child not in self.visited {visit [child];}}}}. Shortest path: walker ShortestPath {has target_id: str; has distances: dict; has unvisited: set; can search with Node entry {update_distances(); if here.id == self.target_id {report reconstruct_path(); disengage;}; visit min_unvisited();}}. Patterns RAG: node Document {has text: str; has embedding: list;}; def embed_text(text: str) -> list {return model.encode(text);}; def find_similar(query_emb: list, docs: list) -> list {return sorted(docs, key=lambda d: cosine_similarity(query_emb, d.embedding), reverse=True)[:5];}; def answer_question(question: str, context: list[Document]) -> str by llm(). Usage: query = "what is X?"; q_emb = embed_text(query); docs = [root --> (`?Document)]; similar = find_similar(q_emb, docs); answer = answer_question(query, similar). Patterns social network: node User {has username: str;}; edge Follow {has since: str;}; node Post {has content: str; has created: str;}. Feed: walker GetFeed {has posts: list = []; can collect with User entry {visit [here --> (`?Post)]; visit [here -->:Follow:-> (`?User) --> (`?Post)];}; can gather with Post entry {visitor.posts.append(here);}}. Usage: feed_walker = root spawn GetFeed(); posts = feed_walker.posts. Patterns e-commerce: node Product {has name: str; price: float; stock: int;}; node Order {has status: str; total: float;}; edge Contains {has quantity: int;}. Checkout: walker Checkout {has items: list; can process with `root entry {order = here ++> Order(status="pending", total=0); for item in self.items {product = &item["id"]; if product.stock >= item["qty"] {order +>:Contains:quantity=item["qty"]:+> product; order.total += product.price * item["qty"]; product.stock -= item["qty"]; save(order); save(product);}}; order.status = "confirmed"; commit();}}. Patterns task management: node Task {has title: str; status: str; priority: int;}; edge DependsOn {}. Schedule: walker ScheduleTasks {has result: list = []; can schedule with Task entry {deps = [<-:DependsOn:<- here]; if all(d.status == "done" for d in deps) {if here.status == "pending" {here.status = "ready"; self.result.append(here);}}; visit [-->];}}. Patterns game level gen: obj Level {has difficulty: int; width: int; height: int; enemies: int;}; obj Map {has level: Level; walls: list; enemies: list;}. def generate_level(prev: list[Level], difficulty: int) -> Level by llm(); def generate_map(level: Level) -> Map by llm(). Usage: manager.history.append(prev_level); level = generate_level(manager.history, difficulty+1); map = generate_map(level); render(map). Patterns trading system: obj Item {has name: str; price: float;}; obj Person {has name: str; money: float; inventory: list[Item];}. def make_transaction(buyer: Person, seller: Person, item: Item) -> bool {if buyer.money >= item.price and item in seller.inventory {buyer.money -= item.price; seller.money += item.price; buyer.inventory.append(item); seller.inventory.remove(item); return True;}; return False;}. obj Chat {has person: str; message: str;}. def npc_chat(player: Person, npc: Person, history: list[Chat]) -> Chat by llm(method='ReAct', tools=[make_transaction]). Usage: AI agent can execute transactions during conversation. Patterns multimodal chatbot: enum QueryType {RAG, WEB_SEARCH, IMAGE, VIDEO, GENERAL}; def classify(query: str, has_files: bool) -> QueryType by llm(). walker Route {has query: str; files: list; can route with `root entry {qtype = classify(self.query, len(self.files) > 0); if qtype == QueryType.RAG {visit [-->:RAGHandler:->];} elif qtype == QueryType.IMAGE {visit [-->:ImageHandler:->];} elif qtype == QueryType.VIDEO {visit [-->:VideoHandler:->];}}}. node RAGHandler {can handle with Route entry {docs = search_docs(visitor.query); answer = generate_answer(visitor.query, docs); report answer;}}. node ImageHandler {can handle with Route entry {img = Image(visitor.files[0]); desc = analyze_image(img); report desc;}}. Common patterns: Singleton: node Config {has settings: dict;}; walker GetConfig {can get with `root entry {configs = [here --> (`?Config)]; if not configs {config = here ++> Config(settings=defaults()); report config;} else {report configs[0];}}}. Pagination: walker ListItems {has page: int = 1; per_page: int = 10; can list with `root entry {items = [here --> (`?Item)]; start = (self.page - 1) * self.per_page; end = start + self.per_page; report {"items": items[start:end], "page": self.page, "total": len(items)};}}. Common patterns caching: node Cache {has key: str; value: any; expires: float;}; walker GetCached {has key: str; can get with `root entry {caches = [here --> (`?Cache)](?key == self.key); if caches and caches[0].expires > time() {report caches[0].value;} else {if caches {del caches[0];}; value = compute_expensive(self.key); cache = here ++> Cache(key=self.key, value=value, expires=time()+3600); report value;}}}. Rate limiting: node RateLimit {has user_id: str; count: int; window_start: float;}. Audit logging: node AuditLog {has action: str; user_id: str; timestamp: float; details: dict;}. Soft delete: node Item {has is_deleted: bool = False; deleted_at: float | None = None;}; mark: item.is_deleted = True; item.deleted_at = time(); query: items = [root --> (`?Item)](?not is_deleted). Versioning: node Document {has version: int = 1; content: str;}; node DocumentVersion {has version: int; content: str; created: float;}; update: doc ++> DocumentVersion(version=doc.version, content=doc.content, created=time()); doc.version += 1; doc.content = new_content. Event sourcing: node Event {has type: str; data: dict; timestamp: float;}; append: event = root ++> Event(type=t, data=d, timestamp=time()); replay: events = [root --> (`?Event)]; for evt in sorted(events, key=lambda e: e.timestamp) {apply(evt);}. Advanced patterns: Actor model: nodes=actors with inbox, edges=message channels, walker SendMessage delivers messages. CQRS: separate WriteModel and ReadModel nodes, Command walker updates write, Query walker reads view. Saga: walker with steps_completed list, try {reserve(); charge(); confirm();} except {for step in reversed(steps) {compensate(step);}}. Pub-sub: node Event {has topic: str; data: dict;}; node Subscriber {has topics: list;}; walker Publish finds subscribers and notifies. Performance optimization: Filter early: items = [root -->](?value > 100) not items = [root -->]; filtered = [i for i in items if i.value > 100]. Type filters: [root --> (`?Item)] not [root -->] then type check. Batch commits: for item in items {process(item); save(item);}; commit() not commit() each iteration. Lazy evaluation: def process_all() -> generator {for chunk in chunks {for item in process_chunk(chunk) {yield item;}}}; for result in process_all() {use(result);}. Caching: multi-level (in-memory for hot data, Redis for distributed, DB for persistence). Async: async def for I/O-bound operations. Limit depth: walker Query {has max_depth: int = 3; depth: int = 0; can search with Node entry {if self.depth >= self.max_depth {disengage;}; self.depth += 1; visit [-->];}}. Debugging: Print: print(f"Node: {here.id}, Type: {type(here)}, Attrs: {here.__dict__}"). Graph visualization: data = printgraph(node=root, depth=3); printgraph(node=root, dot_file="graph.dot"); dot -Tpng graph.dot -o graph.png. Debug walker: walker Debug {can inspect with Node entry {print(f"Successors: {[here -->]}"); print(f"Predecessors: {[<-- here]}")}}. API testing: curl -X POST http://localhost:8000/walker/test -H "Content-Type: application/json" -d '{"param": "value"}'. Swagger: localhost:8000/docs for interactive API testing. Logs: tail -f /tmp/jac_cloud_logs/jac-cloud.log; grep '"level":"ERROR"' logfile. Integration: Python libraries: import any package, call from walkers. REST APIs: import requests; walker FetchData {has url: str; can fetch with `root entry {response = requests.get(self.url); data = response.json(); report data;}}. Databases: import psycopg2; walker QueryDB {has sql: str; can query with `root entry {conn = psycopg2.connect(DB_URL); cursor = conn.execute(self.sql); results = cursor.fetchall(); conn.close(); report results;}}. Message queues: from pika import BlockingConnection; publish to RabbitMQ/Kafka from walkers. External API integration: walker ProcessPayment {has amount: float; card: str; can charge with `root entry {import stripe; stripe.api_key = API_KEY; charge = stripe.Charge.create(amount=int(self.amount*100), currency="usd", source=self.card); report {"status": charge.status, "id": charge.id};}}. LLM + external tools: def search_web(query: str) -> str {import requests; return requests.get(f"https://api.search.com?q={query}").json();}; def answer_with_search(question: str) -> str by llm(method='ReAct', tools=[search_web]). Migration from Python: Classes → obj/node. Functions → def. Methods → def in obj/node or impl. __init__ → has auto-constructor. Collections → nodes/edges. Iteration → walker traversal. Example: Python class User: def __init__(self, name): self.name = name; def greet(self): return f"Hi {self.name}" becomes Jac obj User {has name: str; def greet(self) -> str {return f"Hi {self.name}"}}. Breaking changes v0.8+: impl keyword: impl ClassName.method {code} not :obj:Class:def:method. Inheritance: obj Child(Parent) {} not obj Child :Parent: {}. def for functions/methods, can only for abilities with spatial context. visitor keyword: visitor in node abilities for walker reference, here only in walker for current node. Lambda: lambda x: type: expr not with x: type can expr. Arrows: ->:Edge:-> +>:Edge:+> not -:Edge:-> +:Edge:+>. Import: import from pkg {items} not import from pkg, items. Permissions: Jac.perm_grant/perm_revoke not restrict/unrestrict. Testing: assert in test blocks not check. Global: global x, nonlocal y not :global:, :nonlocal:. printgraph not dotgen. byLLM: import from byllm {Model}; Model(model_name="gpt-4o") not separate Gemini/OpenAI classes. Best practices: Use nodes for entities with identity and relationships, obj for value objects and DTOs, walkers for operations and traversal. Separate .jac interface from .impl.jac implementation. Write tests in .test.jac. Always use type annotations. Validate inputs at walker entry. Handle errors with try/except, report errors via report (don't raise in API walkers). Limit graph depth to 5-10 levels. Index frequently accessed nodes at root level. Clean orphaned nodes periodically. Batch database commits. Cache expensive computations. Use async walkers for heavy tasks. Require auth for sensitive operations. Use permissions for multi-user data access. Environment variables for secrets. HTTPS in production. Log structured JSON. Monitor metrics/errors. Document with docstrings. Use semantic strings for AI context. Test AI outputs with varied inputs. Project structure: main.jac entry point with entry. models/ domain objects nodes edges. utils/ helper functions constants. tests/ .test.jac test files. .impl.jac implementation files. Naming: lowercase_with_underscores.jac files, PascalCase for obj/node/edge/walker, snake_case for functions, UPPER_CASE for constants, _ prefix for private. Keywords: with entry (program entry), has (declare attributes), can (declare abilities), def (define methods/functions), impl (implement separated), glob (global variable), obj (OOP class), node (graph vertex), edge (relationship), walker (mobile computation), spawn (activate walker), visit (traverse), disengage (exit walker), skip (skip node), report (stream result), sem (semantic string), by (delegate to AI), `root (root reference), self (instance), here (current location in walker), visitor (walker in node/edge), path (walker queue), del (delete edge), async/await (async execution), match/case (pattern matching), try/except/raise (exceptions), import/from (imports), for/while (loops), if/elif/else (conditionals), return (function return), break/continue (loop control), and/or/not (logical), in (membership), is (identity), lambda (anonymous function), type (type alias), enum (enumeration). CLI tools: jac run file.jac (execute), jac serve file.jac --host 0.0.0.0 --port 8000 --reload (API server with auto-reload), jac test file.jac (run tests), jac build file.jac (compile to .jir), jac format file.jac (format code) or jac format dir/ (recursive), jac check file.jac (type check), jac clean (remove cache), jac enter file.jac entrypoint args (call specific function), jac tool ir ast file.jac (show AST), jac tool ir sym file.jac (show symbol table), jac tool ir py file.jac (show generated Python), jac tool ir ast. file.jac (generate AST dot graph), jac tool ir cfg. file.jac (control flow graph). Options: --verbose, --debug, --help, --version. Streamlit integration: pip install jac-streamlit. jac streamlit app.jac starts web UI. import streamlit as st; st.title("Dashboard"); st.button("Click"); st.text_input("Name"); st.session_state.key for persistent state; with st.form("name") {inputs; if st.form_submit_button("Submit") {process();}}. Call Jac Cloud API: import requests; response = requests.post("http://localhost:8000/walker/query", json={"text": query}, headers={"Authorization": f"Bearer {token}"}); data = response.json()["reports"]. VS Code extension: jaclang-extension. Syntax highlighting, code completion, error detection, graph visualization, debugging support. Jac-Lens: visual graph explorer, interactive node/edge inspection, real-time updates, debugging tool. Jac Playground: web-based IDE, no install, try in browser, example programs, share links, learning tool. Deployment Docker: FROM python:3.12; COPY . /app; WORKDIR /app; RUN pip install -r requirements.txt; CMD ["jac", "serve", "app.jac", "--host", "0.0.0.0"]. Build: docker build -t myapp .. Run: docker run -p 8000:8000 myapp. Kubernetes: deployment.yaml with replicas, containers (image, ports, env), ConfigMap for config, Secrets for API keys, Service (LoadBalancer/ClusterIP), Ingress for routing. Apply: kubectl apply -f deployment.yaml. Scale: kubectl scale deployment myapp --replicas=5. Health checks: livenessProbe, readinessProbe in pod spec. Utility APIs: GET /util/traverse?source=jid&detailed=bool&depth=int&node_types=Type1&node_types=Type2&edge_types=Edge1 returns {"nodes": [...], "edges": [...]}. GET /util/traverse-stream for streaming version. Example: GET /util/traverse?source=n::root123&depth=2&node_types=User&node_types=Post&detailed=true returns full graph data. Philosophy: Scale-agnostic (same code local/cloud). Object-Spatial (computation moves to data). AI-first (byLLM integration). Graph-native (nodes/edges/walkers). Python compatible superset. Type-safe (static typing). Auto-API (walkers → REST endpoints). Per-user isolation (root nodes). Event-driven (abilities). Bidirectional polymorphism (nodes + walkers define interaction). Zero config deployment. Quick syntax reference: Variable: has name: type = val. Global: glob name = val. Function: def name(params) -> type {body}. Object: obj Name {has attrs; def methods}. Node: node Name {has attrs; def methods; can abilities}. Edge: edge Name {has attrs}. Walker: walker Name {has state; can abilities}. Connect: node1 ++> node2. Traverse: [node -->]. Filter: [expr](?cond). Spawn: node spawn walker(). Visit: visit [nodes]. Report: report val. Import: import from pkg {items}. Entry: with entry {code}. Test: test name {assert cond}. AI: def func() -> type by llm(). Lambda: lambda x: type: expr. Match: match val {case p: action}. Try: try {code} except E {handle}. Impl: impl Class.method() {body}. Root: `root or root. References: here visitor self path. Control: disengage skip. Delete: del edge. Persistence: save(obj) commit(). Summary concepts: Jac is object-spatial programming (OSP), Python superset for AI+graph apps. Nodes=stateful graph entities (node MyNode {has attr: type;}). Edges=typed directional relationships (edge MyEdge {has prop: type;}). Walkers=mobile computation (walker W {has state: type;}). Creation: root ++> MyNode(); node1 +>:MyEdge:+> node2. Traversal: node spawn walker(); visit [-->]; disengage. Context: here=current node in walker ability, visitor=walker in node ability. Data spatial: [-->] outgoing, [<--] incoming, [-->(`?Type)] type filter, [-->(`?T)](?attr>10) attribute filter, [->:E:->] edge filter. Abilities: can blocks trigger on walker arrival/departure (can ab with Walker entry|exit {code}). byLLM: AI functions (def f(p: str) -> str by llm;), config (glob llm = Model(model_name="gpt-4o", temperature=0.7)), multimodal (Image("path.jpg"), Video("path.mp4")), context (docstrings, sem Node.attr = "description"), tools (def agent() by llm(tools=[func])). Jac Cloud: jac serve my_app.jac → API server, walkers become endpoints (config with obj __specs__ {static has methods: list = ["get"]; auth: bool;}), persistence (root-connected nodes auto-saved), async/scheduling (async walker, schedule in __specs__), WebSockets (methods: ["websocket"], socket.notify_*()). Testing: test "name" {assert cond;} in .test.jac files, spatial query assertions.