SmallAICreator commited on
Commit
e40b6f8
·
verified ·
1 Parent(s): 9952267

GRAFT Code desktop app for Windows

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ GRAFT-Code.exe filter=lfs diff=lfs merge=lfs -text
GRAFT-Code.exe ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:509d96a2ccdae3d96908905e7f646140ad20a81fac609fe8ea562fcb249b8484
3
+ size 41694754
README.md ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ language:
4
+ - en
5
+ tags:
6
+ - windows
7
+ - desktop-app
8
+ - agent
9
+ - tool-calling
10
+ - llama.cpp
11
+ - gguf
12
+ - local-ai
13
+ ---
14
+
15
+ # GRAFT Code
16
+
17
+ **A local AI agent for Windows that actually does things.** GRAFT Code is a desktop app that runs a GRAFT model on
18
+ your own PC and lets it work on your files: it makes folders, writes and reads files, moves, renames, copies and
19
+ deletes things, runs commands and Python, does exact math, and searches and reads the web. Every change asks you
20
+ first. Nothing leaves your computer except web-search keywords.
21
+
22
+ Made by **SmallAICreator / UltraLabs**.
23
+
24
+ | File | What it is |
25
+ |---|---|
26
+ | `GRAFT-Code.exe` | GRAFT Code for **Windows 10/11** (x64, runs on CPU). llama.cpp is bundled. |
27
+ | `graft-bridge/` | Optional: a Claude Code skill that lets GRAFT ask Claude for help (`talk_to_claude`). |
28
+
29
+ ## Pick a model
30
+
31
+ | Model | Size | Best for |
32
+ |---|---|---|
33
+ | [GRAFT-10B-A2B](https://huggingface.co/SmallAICreator/GRAFT-10B-A2B-GGUF) | 6.3 GB, 16 GB RAM | The smartest option: a 10B mixture-of-experts with only 2B active, perfect recall up to 32K tokens |
34
+ | [GRAFT-1B-Agentic](https://huggingface.co/SmallAICreator/GRAFT-1B-Agentic) | 1 GB, 8 GB RAM | Fast and light, tuned for tool use |
35
+
36
+ Put the `.gguf` in your **Downloads** folder and GRAFT Code finds it.
37
+
38
+ ## Get started
39
+
40
+ 1. Download `GRAFT-Code.exe` and a model (above).
41
+ 2. Double-click the EXE. It's unsigned, so Windows SmartScreen may warn you: click *More info → Run anyway*.
42
+ 3. Wait for the model to load. The first launch reads GRAFT's instructions once (about 2 minutes on a laptop CPU with
43
+ the 10B). Later launches restore them from disk in seconds.
44
+ 4. Type what you want done, for example *"make a Python script that renames all my photos by date"*.
45
+
46
+ It needs Microsoft Edge WebView2, which Windows 10 and 11 already have. GRAFT works in `~/GRAFT-Workspace`; change
47
+ the folder from the sidebar.
48
+
49
+ ## Features
50
+
51
+ - **Clean chat window** with light and dark themes. Replies stream in live, with formatted text and code blocks you
52
+ can copy.
53
+ - **Tool cards and approvals.** Each action (write, run, search…) shows up as a card you can expand. Changes need an
54
+ approval: **Yes**, **Yes, and don't ask again** or **No, tell GRAFT what to do instead**.
55
+ - **Model picker.** Searches every `.gguf` in your Downloads, Desktop, Documents and LM Studio folders, has
56
+ *Browse…* for anything else, and reopens the last model you used.
57
+ - **Personas.** GRAFT, Coder, Playful, Concise and Teacher, or make your own with an emoji. Each persona has its own
58
+ system prompt and sampling settings.
59
+ - **Settings.**
60
+ - *Sampling:* temperature, top-p, top-k, min-p, repeat penalty and reply length.
61
+ - *Model:* context size (up to what the model supports), CPU threads and the draft model.
62
+ - *Agent:* max steps, command timeout, auto-approve and full access.
63
+ - **Chat history.** Every chat is saved in the sidebar. Reopen one and GRAFT remembers it.
64
+ - **Copy, Regenerate and a context gauge** that shows how much of GRAFT's memory the chat uses.
65
+ - **Speculative decoding.** If a matching draft model (`GRAFT-10B-A2B-draft-*.gguf`) sits next to GRAFT-10B-A2B,
66
+ GRAFT Code uses it automatically for faster replies.
67
+ - **Use the model from other apps.** While GRAFT Code is open, its model is also an OpenAI-compatible API at
68
+ `http://127.0.0.1:1337/v1`. Other apps get their own slot, so they never slow GRAFT down by wiping its cache.
69
+ - **Web search and page reading.** Just ask. It uses DuckDuckGo with Wikipedia as a backup, and no API key is needed.
70
+ - **GRAFT.md notes.** Facts about your PC and how you like things done, read at the start of every chat.
71
+
72
+ ## Talk to Claude (optional)
73
+
74
+ Copy the `graft-bridge` folder to `~/.claude/skills/`. In a Claude Code window, type `/graft-bridge`. Then tell GRAFT
75
+ *"ask Claude …"*: the question goes to that Claude Code window, and Claude's answer comes back to GRAFT.
76
+
77
+ ## Where things are stored
78
+
79
+ Everything stays in `%LOCALAPPDATA%\GRAFTCode`: settings (`config.json`), personas, saved chats, your `GRAFT.md` notes
80
+ and the saved instruction cache.
81
+
82
+ ## Good to know
83
+
84
+ - GRAFT Code runs real commands on your computer. Keep approvals on unless you trust the task.
85
+ - Only run one big model at a time. Two copies of a 10B model won't fit in 16 GB of RAM.
86
+ - Small models can make mistakes or make up results. Check anything important.
87
+
88
+ GRAFT Code bundles [llama.cpp](https://github.com/ggml-org/llama.cpp) (MIT).
graft-bridge/SKILL.md ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ name: graft-bridge
3
+ description: Listen for questions from GRAFT Code's talk_to_claude tool (GRAFT-1B running locally) and answer them from this Claude Code session. Use when the user types /graft-bridge or asks Claude to listen for / answer GRAFT.
4
+ ---
5
+
6
+ # GRAFT bridge — answer GRAFT-1B from this Claude Code session
7
+
8
+ GRAFT Code (a local GRAFT-1B agent) has a `talk_to_claude` tool. It drops questions into
9
+ `%LOCALAPPDATA%\GRAFTCode\bridge\` and waits (up to 10 min) for an answer file. `graft_bridge.py` lives in this
10
+ skill's folder (`~/.claude/skills/graft-bridge/graft_bridge.py`).
11
+
12
+ ## Start listening
13
+ Run with the Bash tool and `run_in_background: true` (keeps a heartbeat so GRAFT Code knows you're there; exits as
14
+ soon as a question arrives, which wakes you up):
15
+
16
+ ```
17
+ python ~/.claude/skills/graft-bridge/graft_bridge.py wait
18
+ ```
19
+
20
+ Tell the user in one line that the bridge is on.
21
+
22
+ ## When it wakes you (background task completed)
23
+ 1. Read the task output: `GRAFT QUESTION` + JSON with `id`, `message` (what GRAFT asks), `user_request` (what the
24
+ user typed to GRAFT — answer THIS if GRAFT garbled the question), and `cwd`.
25
+ 2. Answer for a 1B model: short, plain, concrete (exact commands / code it can copy), under ~150 words unless code is
26
+ needed. GRAFT runs Windows PowerShell commands in `cwd`.
27
+ 3. Send it (text on stdin):
28
+ ```
29
+ python ~/.claude/skills/graft-bridge/graft_bridge.py answer <id> <<'EOF'
30
+ ...answer...
31
+ EOF
32
+ ```
33
+ 4. Show the user the question and your answer briefly, then restart the listener (step "Start listening").
34
+
35
+ ## Stop
36
+ `python ~/.claude/skills/graft-bridge/graft_bridge.py stop` and stop the background task.
graft-bridge/graft_bridge.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ r"""
2
+ GRAFT <-> Claude Code bridge (the Claude side). GRAFT Code's talk_to_claude tool drops questions in
3
+ %LOCALAPPDATA%\GRAFTCode\bridge\ ; a Claude Code session runs `wait` in the background, gets woken when a question
4
+ arrives, and replies with `answer`. By SmallAICreator / UltraLabs.
5
+
6
+ py graft_bridge.py wait block (with heartbeat) until a question is waiting, print it, exit
7
+ py graft_bridge.py answer <id> < text send the answer for question <id> (text on stdin)
8
+ py graft_bridge.py pending list unanswered questions
9
+ py graft_bridge.py stop mark the listener as gone
10
+ """
11
+ import json, os, sys, time
12
+ from pathlib import Path
13
+
14
+ BRIDGE = Path(os.environ.get("LOCALAPPDATA", str(Path.home()))) / "GRAFTCode" / "bridge"
15
+ LISTENER = BRIDGE / "listener.json"
16
+
17
+
18
+ def atomic_write(p, obj):
19
+ tmp = p.with_suffix(".tmp")
20
+ tmp.write_text(json.dumps(obj, ensure_ascii=False, indent=1), encoding="utf-8")
21
+ os.replace(tmp, p)
22
+
23
+
24
+ def pending():
25
+ out = []
26
+ for q in sorted(BRIDGE.glob("q_*.json"), key=lambda p: p.stat().st_mtime):
27
+ qid = q.stem[2:]
28
+ if not (BRIDGE / f"a_{qid}.json").exists():
29
+ try:
30
+ out.append(json.loads(q.read_text(encoding="utf-8")))
31
+ except Exception: # half-written: pick it up next poll
32
+ pass
33
+ return out
34
+
35
+
36
+ def beat(state):
37
+ atomic_write(LISTENER, {"state": state, "ts": time.time(), "pid": os.getpid()})
38
+
39
+
40
+ def main():
41
+ BRIDGE.mkdir(parents=True, exist_ok=True)
42
+ cmd = sys.argv[1] if len(sys.argv) > 1 else "wait"
43
+ if cmd == "wait":
44
+ while True:
45
+ qs = pending()
46
+ if qs:
47
+ beat("handling") # GRAFT Code treats this as "Claude is on it"
48
+ q = qs[0]
49
+ print("GRAFT QUESTION")
50
+ print(json.dumps(q, ensure_ascii=False, indent=1))
51
+ if len(qs) > 1:
52
+ print(f"({len(qs) - 1} more waiting)")
53
+ return
54
+ beat("listening")
55
+ time.sleep(1.0)
56
+ elif cmd == "answer":
57
+ qid = sys.argv[2]
58
+ text = sys.stdin.buffer.read().decode("utf-8", "replace").strip() # raw bytes: Windows stdin mangles emoji
59
+ if not (BRIDGE / f"q_{qid}.json").exists():
60
+ sys.exit(f"no question {qid}")
61
+ atomic_write(BRIDGE / f"a_{qid}.json", {"id": qid, "answer": text, "time": time.time()})
62
+ beat("listening")
63
+ print(f"answered {qid} ({len(text)} chars)")
64
+ elif cmd == "pending":
65
+ print(json.dumps(pending(), ensure_ascii=False, indent=1))
66
+ elif cmd == "stop":
67
+ LISTENER.unlink(missing_ok=True)
68
+ print("listener stopped")
69
+ else:
70
+ sys.exit(__doc__)
71
+
72
+
73
+ if __name__ == "__main__":
74
+ main()