Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
182 commits
Select commit Hold shift + click to select a range
486ebfe
Update README.md
DavidValin Feb 8, 2026
60d4e51
Update README.md
DavidValin Feb 8, 2026
1d3e7ca
Added tested cross build script
DavidValin Feb 8, 2026
c82d999
More compact README, added aliases samples
DavidValin Feb 8, 2026
675c1a2
.
DavidValin Feb 8, 2026
a6be39f
0.3.0-beta.4
DavidValin Feb 8, 2026
33fb5ba
use windows 32-bit build in cross build
DavidValin Feb 8, 2026
e755c6a
feat: inmemory wav to whisper + whisperfile instead
DavidValin Feb 8, 2026
ee5d5f3
Merge pull request #1 from DavidValin/whisper-inmemory
DavidValin Feb 8, 2026
74933c9
0.3.0-beta.5
DavidValin Feb 8, 2026
cf2dede
fix: cross build for windows working from macos
DavidValin Feb 8, 2026
f875e41
add a demo video link
DavidValin Feb 8, 2026
b6d30f8
polishing instructions
DavidValin Feb 8, 2026
0c5adaf
feat: use full session conversation history for context
DavidValin Feb 8, 2026
79195b1
feat: embedded whisper (no need for external installation)
DavidValin Feb 9, 2026
3e3d68e
Merge pull request #2 from DavidValin/whisper-rs
DavidValin Feb 9, 2026
78fc37c
feat: basics Kokoro TTS working
DavidValin Feb 9, 2026
d0a8507
vendor external lib, need to patch
DavidValin Feb 9, 2026
94dca3e
original lib.rs
DavidValin Feb 9, 2026
1cc2f49
patch: add support for multilingual synthesize in kokoro-tts-0.1.0
DavidValin Feb 9, 2026
3d09b48
spanish voice works great
DavidValin Feb 9, 2026
dedbbcd
fix typo
DavidValin Feb 9, 2026
f73772d
use alex voice
DavidValin Feb 9, 2026
7ea8117
add --tts cli arg and set it to kokoro by default
DavidValin Feb 9, 2026
8393a04
map all kokoro voices per language and set all default voices per lan…
DavidValin Feb 9, 2026
845e1c2
feat: kokoro / opentts support working via switchable --tts
DavidValin Feb 9, 2026
a9b5333
Update README with language + TTS support table
DavidValin Feb 9, 2026
2b52081
Merge pull request #4 from DavidValin/kokoro-tiny
DavidValin Feb 9, 2026
2935dfa
Merge pull request #5 from DavidValin/kokoro-tiny
DavidValin Feb 9, 2026
0674adb
set opentts as default for now
DavidValin Feb 9, 2026
f69449b
fix: audio playback
DavidValin Feb 9, 2026
d28536d
0.3.0-beta.6
DavidValin Feb 9, 2026
8cbcb1d
Update cross build
DavidValin Feb 10, 2026
ab6a22d
set vendored kokoro-tiny version
DavidValin Feb 10, 2026
feb925b
use patch.crates-io
DavidValin Feb 10, 2026
b21ed1b
use new patched kokoro-tiny. voices sound great!
DavidValin Feb 10, 2026
734ad51
Use kokoro as default tts system
DavidValin Feb 10, 2026
76288f9
0.3.0-beta.7
DavidValin Feb 10, 2026
69c7d5b
.
DavidValin Feb 10, 2026
bb1b968
.
DavidValin Feb 10, 2026
2457eaf
fix: fix cross build + remove stdout print from external dep
DavidValin Feb 10, 2026
c2cd1d9
feat: include espeak-ng-data.tar.gz in release to avoid external inst…
DavidValin Feb 10, 2026
5d71da8
fix: windows build which failed
DavidValin Feb 10, 2026
cd19f21
ef_dora
DavidValin Feb 10, 2026
c5e6761
Basics kokoro streaming
DavidValin Feb 10, 2026
0cf808f
fix: better audio interrupt
DavidValin Feb 10, 2026
c83fa65
fix some rendering issues with interrupt banner
DavidValin Feb 10, 2026
62ddd6c
do not translate, and detect the language
DavidValin Feb 10, 2026
c182459
do not play speech for code blocks
DavidValin Feb 10, 2026
34e9ee0
feat: useful features
DavidValin Feb 11, 2026
a2896d0
fix: all warnings gone
DavidValin Feb 11, 2026
55c0757
fix: do not cap phrases by length
DavidValin Feb 11, 2026
b1ffdd0
fix: fix accelerated playback after 5th phrase. use unbounded channel…
DavidValin Feb 11, 2026
52c4e05
fix: use the right lang code for chinese mandarin phoenemes
DavidValin Feb 11, 2026
8be95f0
validate picked language against available ones
DavidValin Feb 11, 2026
698bfeb
0.3.0-beta.8
DavidValin Feb 11, 2026
510d5f9
Merge pull request #6 from DavidValin/develop
DavidValin Feb 11, 2026
86b7e30
fix: remove router which was causing some phrases to play in wrong order
DavidValin Feb 11, 2026
c481a7a
feat: be able to retrieve the available voices
DavidValin Feb 11, 2026
d3487f8
feat: be able to select a voice via cli
DavidValin Feb 11, 2026
04e68b7
feat: add llama-server / llamafile support
DavidValin Feb 11, 2026
20c8380
separated steps
DavidValin Feb 11, 2026
c7ec0df
fix typo
DavidValin Feb 11, 2026
311550a
Updated instructions
DavidValin Feb 11, 2026
3e4ec62
Update status
DavidValin Feb 11, 2026
fd7eae0
highlight install steps
DavidValin Feb 11, 2026
4d019dc
fix typo
DavidValin Feb 12, 2026
10e04df
fix: rework status ui bottom bar, more compact
DavidValin Feb 12, 2026
b145aa3
cargo fmt, change default speed and default voice (en)
DavidValin Feb 12, 2026
9bdca4e
feat: be able to swap voice in realtime via keyboard
DavidValin Feb 12, 2026
5d74582
improve whisper transcription speed by 500%
DavidValin Feb 12, 2026
4f77c8d
print version after the banner
DavidValin Feb 12, 2026
2dd1a1f
feat: terminate the program if terminal is unsupported
DavidValin Feb 12, 2026
bcf6d17
add assets map and a helper to retrieve them
DavidValin Feb 12, 2026
20e3e58
feat: self contained stt & tts models for portability
DavidValin Feb 12, 2026
976cf00
avoid computing assets checksum except if building --release
DavidValin Feb 12, 2026
b839d53
Release candidate 1
DavidValin Feb 12, 2026
f520b65
Update README.md
DavidValin Feb 12, 2026
b4c6a93
Update README.md
DavidValin Feb 12, 2026
e617700
Update README.md
DavidValin Feb 12, 2026
88b6e4d
Update README.md
DavidValin Feb 12, 2026
d9110d4
trying to fix whisper transcription in windows / mac
DavidValin Feb 12, 2026
6547c65
fix: faster whisper and bug fixing
DavidValin Feb 12, 2026
ed07fd4
Merge pull request #7 from DavidValin/whisper-stuff
DavidValin Feb 12, 2026
598cb10
feat: split builds, set baseline cpu based builds per arch and separa…
DavidValin Feb 12, 2026
24ec1c5
0.3.0-rc-2
DavidValin Feb 12, 2026
0e642b9
Use <SPACE> to toggle pause / resume
DavidValin Feb 12, 2026
1cc4141
Merge pull request #8 from DavidValin/develop
DavidValin Feb 12, 2026
0ce1c4c
trying fixing white noise loop in linux
DavidValin Feb 12, 2026
8b29aba
docs
DavidValin Feb 12, 2026
c8bf5e5
host
DavidValin Feb 12, 2026
d82d18d
fmt
DavidValin Feb 12, 2026
6781d4f
Add messaging specs
DavidValin Feb 13, 2026
b5320de
some cleanup
DavidValin Feb 13, 2026
9652529
fixing bugs with silence playback, interruption via keyword
DavidValin Feb 13, 2026
433ae23
print conversation through ui thread
DavidValin Feb 14, 2026
f3eca3b
Windows build script (requires msvc)
DavidValin Feb 14, 2026
69d5638
multi version compatibility for ollama / llamaserver / llamafiles
DavidValin Feb 14, 2026
60e222b
fix: whisper / assets user home directory fix so it works in windows too
DavidValin Feb 14, 2026
47d487a
0.3.0-rc-3
DavidValin Feb 14, 2026
9aaa554
Update README.md
DavidValin Feb 14, 2026
bb76df0
Update README.md
DavidValin Feb 14, 2026
e0279a3
Update README.md
DavidValin Feb 14, 2026
d2423a7
fix: audio playback
DavidValin Feb 9, 2026
656a134
use new patched kokoro-tiny. voices sound great!
DavidValin Feb 10, 2026
da7938c
fix: Force static MSVC runtime so the user doesnt need to install it …
DavidValin Feb 14, 2026
beb1b06
fix: windows build - multinamed binaries
DavidValin Feb 14, 2026
a8636fa
.
DavidValin Feb 14, 2026
457cfb4
UI + conversation lines + speech working fast as hell here
DavidValin Feb 15, 2026
2bbce5a
bang!
DavidValin Feb 15, 2026
38dfe95
works almost perfect
DavidValin Feb 15, 2026
d9cb2bc
Merge pull request #9 from DavidValin/fix-ui-sluggish
DavidValin Feb 15, 2026
e1492b7
0.3.0-rc-4
DavidValin Feb 15, 2026
752e3c3
Actually, i can voice chat with openclaw / clawbot since it exposes a…
DavidValin Feb 15, 2026
c022702
Update README.md
DavidValin Feb 15, 2026
8684eda
interruption + tts + playback never fails
DavidValin Feb 15, 2026
1463784
cleanup responses
DavidValin Feb 15, 2026
734664b
feat: Add Push to Talk feature (via --ppt)
DavidValin Feb 15, 2026
4a928dc
use new openai compatible url as default
DavidValin Feb 16, 2026
5e8ba6a
Update README.md
DavidValin Feb 16, 2026
8ec21c5
PTT sample
DavidValin Feb 16, 2026
5a84281
Update build instructions
DavidValin Feb 16, 2026
63f84db
Update README.md
DavidValin Feb 16, 2026
29a50f3
Update README.md
DavidValin Feb 16, 2026
1ba21e4
add video demos
DavidValin Feb 16, 2026
2560f2e
Update Cargo.toml
DavidValin Feb 16, 2026
d953acd
Add demo links
DavidValin Feb 16, 2026
d2e7ac9
raw links
DavidValin Feb 16, 2026
c1c7c33
update preview
DavidValin Feb 16, 2026
1ddb8c1
add thumbnails
DavidValin Feb 16, 2026
c281aaa
thumbnails
DavidValin Feb 16, 2026
14ec264
Update README.md
DavidValin Feb 16, 2026
1272135
smaller thumbs
DavidValin Feb 16, 2026
983d54c
Update README.md
DavidValin Feb 16, 2026
6ef5738
Update README.md
DavidValin Feb 16, 2026
c0e0e9a
Update README.md
DavidValin Feb 16, 2026
ff4ab04
simplified llm client, use generic --model cli arg
DavidValin Feb 16, 2026
089c8b9
much better voice interrupt: run llm request as sync and separate thr…
DavidValin Feb 17, 2026
469e97d
Merge pull request #12 from DavidValin/paralell-llm
DavidValin Feb 17, 2026
961b00d
immediate tts interrupt on stop_all_rx
DavidValin Feb 17, 2026
2a44811
Merge pull request #13 from DavidValin/tts-interrupt
DavidValin Feb 17, 2026
8f90449
break
DavidValin Feb 18, 2026
1aaa0b3
Merge pull request #10 from DavidValin/develop
DavidValin Feb 18, 2026
1597186
0.3.1
DavidValin Feb 18, 2026
309c06b
Update acceleration compatibility matrix
DavidValin Feb 18, 2026
dd6ee98
Update README.md
DavidValin Feb 18, 2026
d983572
0.3.1
DavidValin Feb 18, 2026
639d913
Update acceleration compatibility matrix
DavidValin Feb 18, 2026
afae1a1
Update README.md
DavidValin Feb 18, 2026
b5a8076
new ui basics
DavidValin Feb 19, 2026
273fd73
cargo fmt
DavidValin Feb 19, 2026
d5e3136
separate thread for bar update + render
DavidValin Feb 19, 2026
6ad5e33
details about interruptions
DavidValin Feb 19, 2026
4fda3e7
.
DavidValin Feb 19, 2026
357e868
fmt
DavidValin Feb 19, 2026
35c714f
cleaning
DavidValin Feb 19, 2026
3ae8798
Merge pull request #14 from DavidValin/new-ui
DavidValin Feb 19, 2026
2023649
log details, status, banner,
DavidValin Feb 19, 2026
f6f3450
Merge branch 'main' into develop
DavidValin Feb 19, 2026
a79df4e
Merge pull request #15 from DavidValin/develop
DavidValin Feb 19, 2026
cbd5ec8
fix different ollama url / payload hell, set voice to bf_emma
DavidValin Feb 20, 2026
f053d78
0.3.3
DavidValin Feb 20, 2026
59a911b
Merge pull request #19 from DavidValin/llm-endpoints
DavidValin Feb 20, 2026
4de53ee
Merge pull request #20 from DavidValin/develop
DavidValin Feb 20, 2026
637aa70
Update instructions
DavidValin Feb 20, 2026
096607d
Update README.md
DavidValin Feb 20, 2026
8562025
Inline video demos
DavidValin Feb 22, 2026
6da893d
Update README.md
DavidValin Feb 23, 2026
c15db09
Use kokoro-micro (reduced kokoro-tiny version)
DavidValin Feb 26, 2026
3b1b40c
skeleton memory with basic predicates
DavidValin Feb 28, 2026
e580cf6
basic memory
DavidValin Feb 28, 2026
31cb720
Add StoreMemoryTool and RememberTool. Add tool handling with validati…
DavidValin Feb 28, 2026
ccb205a
send tools available to llm
DavidValin Feb 28, 2026
d834ddc
detect tool call support and use it conditionally when calling llm
DavidValin Mar 1, 2026
ad302bd
cargo fmt
DavidValin Mar 1, 2026
7ab4e3d
first memories stored on disk
DavidValin Mar 2, 2026
d7b93dd
add cli commands to query mamory
DavidValin Mar 2, 2026
7f2db7a
add memory specs
DavidValin Mar 2, 2026
508dda8
move memory to ~/.ai-mate/agents/default/memory
DavidValin Mar 2, 2026
4f27c15
construct chat history, instead of using a string block for the whole…
DavidValin Mar 2, 2026
b046978
spawn paralell llm call to collect memories of latest user message
DavidValin Mar 3, 2026
a106f49
Merge branch 'main' into memory
DavidValin Mar 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
285 changes: 280 additions & 5 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ hex = "0.4"
directories = "5"
log = "0.4"
env_logger = "0.11"
hnsw_rs = "0.3.4"
anndists = "0.1.4"
sled = "0.34"

[build-dependencies]
sha2 = "0.10"
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ You can also initialize ai-mate at specific agent:
ai-mate --agent planner
```

If you want to use OpenTTS, start the docker service first: `docker run --rm --platform=linux/amd64 -p 5500:5500 synesthesiam/opentts:all` (it will pull the image the first time). Adjust the platform as needed depending on your hardware.

If you need help:

```
Expand Down
Binary file added demo/ai-mate 0.3.0 - English speech demo.mov
Binary file not shown.
Binary file added demo/ai-mate 0.3.0 - Spanish speech demo.mov
Binary file not shown.
Binary file added demo/e-thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/s-thumb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion spec/acceleration.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@
-----------------------------------------------------------------
ARM64:
Metal support + Accelerate + eigen
-----------------------------------------------------------------
-----------------------------------------------------------------
95 changes: 95 additions & 0 deletions spec/memory.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Memory System Overview

The **Memory** module is a lightweight knowledge‑base that stores *knowledge units* together with their embeddings. It is used by the AI‑assistant to recall past events and facts.

## 1. Data Model

- **KnowledgeUnit** – a semantic triple consisting of `subject`, `predicate`, `object`, optional `location` and a timestamp.
- **VecKnowledgeUnit** – the unit plus a 128‑dimensional embedding vector.
- **Memory** – holds the HNSW graph (`hnsw`), a map of IDs to `VecKnowledgeUnit` (`index_map`), and three *inverted indexes* (subject, predicate, object) that map a value to the set of IDs that contain it.

## 2. Persistence

The entire state is stored in a single **sled** database file named `memory.json` (the name is a bit of a misnomer – it is a sled DB, not a plain JSON file). The DB contains one key:

```
"memory" => <bytes>
```

The bytes are a JSON object with the following fields:

|-------------------------------------------------------------------------------------|
| Field | Type | Meaning |
|---------------------|----------------------------|----------------------------------|
| `next_id` | u64 | Next available ID for a new unit |
| `units` | map<u64, VecKnowledgeUnit> | All stored units, keyed by ID |
| `subject_index` | map<string, Vec<u64>> | Inverted index for subjects |
| `predicate_index` | map<string, Vec<u64>> | Inverted index for predicates |
| `object_index` | map<string, Vec<u64>> | Inverted index for objects |
---------------------------------------------------------------------------------------

When `Memory::save_to_file` is called it serialises this structure with `serde_json::to_vec` and writes it to sled. Loading reverses the process: the bytes are read, deserialised, and the HNSW graph is rebuilt from the embeddings.

## 3. Storing a Unit

```
let id = memory.next_id;
memory.index_map.insert(id, VecKnowledgeUnit{embedding, knowledge: unit.clone()});
memory.hnsw.insert((&embedding, id));
memory.next_id += 1;
// update inverted indexes
subject_index.entry(unit.subject).or_default().push(id);
predicate_index.entry(unit.predicate.name).or_default().push(id);
object_index.entry(unit.object).or_default().push(id);
```

After the in‑memory state is updated, `save_to_file` persists the data.

## 4. Querying

### a. Full‑text / Embedding query

`Memory::query(query, k, ef_search)` performs a vector similarity search:
1. The query string is turned into a 128‑dimensional vector via `embed_text` (hash‑based word frequency).
2. HNSW returns the `k` nearest neighbour IDs.
3. The corresponding `KnowledgeUnit`s are returned.
4. A final filter keeps only results that contain any word from the query (case‑insensitive, alphanumeric only).

### b. Inverted‑index lookup

Functions `get_by_subject`, `get_by_predicate`, `get_by_object`, and `get_by_location` simply look up the relevant ID list in the inverted index and fetch the units. This is O(1) to get the list plus O(1) per result.

## 5. CLI Commands

The binary exposes four new flags:

```
--get-memories-by-subject <subject>
--get-memories-by-predicate <predicate>
--get-memories-by-object <object>
--get-memories-by-location <location>
```

Each flag loads `memory.json`, calls the appropriate `get_by_*` method, and prints each unit’s context via `Memory::build_context_from_units`.

## 6. Summary

* Units are stored with an embedding and an ID.
* All data is persisted as a single sled database entry containing JSON.
* Retrieval can be done either by embedding similarity or by fast inverted‑index lookups.
* The CLI provides convenient commands for inspecting and querying the memory.

This design keeps the runtime lightweight while enabling efficient queries over thousands of units.

## 7. LLM integration

Store memories:

1. when sending llm prompt, provide "story_memory" tool with available predicates
2. execute tool calls (new memories to store) from LLM response

Retrieve memories:

1. Before submitting prompt, query memories
2. Collect results (knowledge units) and produce text readable sentences using build_context_from_units(&retrieved_units);
3. Provide context to the llm
55 changes: 55 additions & 0 deletions spec/messaging.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
Threads and the channels they use

------------------------------------------------------------------------------------
Main (src/main.rs)
------------------------------------------------------------------------------------
- Sends the global stop signal through stop_all_tx.
- Sends raw microphone audio to the recording thread via tx_rec.
- Sends recognized utterances to the conversation thread via tx_utt.
- Sends raw microphone audio to the conversation thread via conv_tx (for synchronous processing).
- Sends playback audio to the playback thread through tx_play.
- Sends playback‑stop requests to the recording and playback threads via stop_play_tx.
- Sends the playback‑stop receiver to the playback thread via stop_play_rx.

------------------------------------------------------------------------------------
UI thread (src/ui.rs)
------------------------------------------------------------------------------------
- Receives the global stop signal on stop_all_rx.
- Reads the shared status_line, print_lock, and peak to update the terminal.

------------------------------------------------------------------------------------
Playback thread (src/playback.rs)
------------------------------------------------------------------------------------
- Receives the global stop signal on stop_all_rx.
- Receives playback audio chunks on rx_play.
- Receives a playback‑stop signal on stop_play_rx.
- Reads control flags: playback_active, gate_until_ms, paused.
- Reads UI state (ui) and updates it.
- Reads and updates the shared volume.

------------------------------------------------------------------------------------
Record thread (src/record.rs)
------------------------------------------------------------------------------------
- Receives the global stop signal on stop_all_rx.
- Reads the interrupt counter via interrupt_counter.
- Reads and updates shared state: volume, recording_paused, and peak.
- Sends microphone audio to the conversation thread via conv_tx.
- Sends recognized utterance audio to the conversation thread via tx_utt.
- Sends a playback‑stop request on stop_play_tx.

------------------------------------------------------------------------------------
Conversation thread (src/conversation.rs)
------------------------------------------------------------------------------------
- Receives the global stop signal on stop_all_rx.
- Receives utterance chunks from the record thread on rx_utt.
- Sends processed speech audio to the playback thread via tx_play.
- Sends a global stop signal on stop_all_tx when needed.

------------------------------------------------------------------------------------
Keyboard thread (src/keyword.rs)
------------------------------------------------------------------------------------
- Receives the global stop signal on stop_all_rx.
- Sends the global stop signal via stop_all_tx.
- Reads control flags: paused, playback_active.
- Reads the recording‑paused flag via recording_paused.
- Reads configuration: voice, args.tts, args.language.
23 changes: 23 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,29 @@ pub struct Args {

#[arg(long)]
pub ptt: Option<bool>,

#[arg(long, action=clap::ArgAction::SetTrue)]
pub get_memories: bool,

/// Get memories by subject
#[arg(long, value_name="SUBJECT", action=clap::ArgAction::Set)]
pub get_memories_by_subject: Option<String>,

/// Get memories by predicate
#[arg(long, value_name="PREDICATE", action=clap::ArgAction::Set)]
pub get_memories_by_predicate: Option<String>,

/// Get memories by object
#[arg(long, value_name="OBJECT", action=clap::ArgAction::Set)]
pub get_memories_by_object: Option<String>,

/// Get memories by location
#[arg(long, value_name="LOCATION", action=clap::ArgAction::Set)]
pub get_memories_by_location: Option<String>,

/// Query memory using embeddings and print results
#[arg(long, value_name="QUERY", action=clap::ArgAction::Set)]
pub query_memory: Option<String>,
}

// internal static values
Expand Down
Loading