Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
da86611
support lumo v2 content blocks
ZeroTricks Mar 6, 2026
8de9e44
use upstream type MessagePriv instead of own type MessagePrivate
ZeroTricks Mar 6, 2026
55c1783
remove obsolete type NativeToolData
ZeroTricks Mar 6, 2026
6c2d190
browser authenticate: unconditionally fetch keys (ignore enableSync)
ZeroTricks Mar 6, 2026
6205354
Goodbye FallbackStore!
ZeroTricks Mar 6, 2026
394614d
remove lazily loaded import
ZeroTricks Mar 8, 2026
f6890aa
remove stale type; add comments on AssistantMessageData
ZeroTricks Mar 8, 2026
87f2ce2
Merge branch 'main' into feature/remove-fallback-conversation-store
ZeroTricks Mar 30, 2026
83870e3
simplify initializeSync
ZeroTricks Mar 30, 2026
003d3a6
remove obsolete useFallbackStore
ZeroTricks Mar 30, 2026
d452a2d
fetch all missing messages on start-up
ZeroTricks Mar 30, 2026
7e8cf0e
add super basic /search command, searching in messages + conv title, …
ZeroTricks Mar 30, 2026
f95df60
support server tools: register, detect and execute server-side tool c…
ZeroTricks Mar 31, 2026
874de29
Tool terminology updates
ZeroTricks Mar 31, 2026
b200326
rename runServerToolLoop → chatAndExecute
ZeroTricks Mar 31, 2026
76d9eab
persist server tool call and outputs
ZeroTricks Apr 1, 2026
64ff6c6
simplify erver config getters
ZeroTricks Apr 1, 2026
8b8e5e6
fix title not being set when first Lumo message is bounced
ZeroTricks Apr 1, 2026
1381b9d
add server tool to return current time&date (as hello world basically)
ZeroTricks Apr 1, 2026
16ece97
emit server tool calls and results to client
ZeroTricks Apr 1, 2026
a2ff39c
message deduplication: fix continuations after server tool calls; rem…
ZeroTricks Apr 1, 2026
1ad6660
mock mode: install mock fetch adapter to intercept store api calls
ZeroTricks Apr 1, 2026
d9d5c6f
add metrics for server tools calls; rename metric for custom-complete…
ZeroTricks Apr 1, 2026
aeb27dc
fix alwas registering server tools
ZeroTricks Apr 1, 2026
2e0034c
git rid of MinimalStore and IConversationStore B-)
ZeroTricks Apr 1, 2026
6a54d1a
suppress softDeleteSpaceCascade warnings
ZeroTricks Apr 1, 2026
0a9b9b7
fix type mismatches and import paths
ZeroTricks Apr 2, 2026
dbc2582
fix not awating bounced tool call
ZeroTricks Apr 2, 2026
d7e6e89
fix tests covering executeServerTools
ZeroTricks Apr 2, 2026
dba36ec
fix CLI error upon misrouted tool call
ZeroTricks Apr 2, 2026
af6774b
Added conversations.enableStore config option (default true)
ZeroTricks Apr 2, 2026
9cda8f2
ConversationStore: simplify init return types, drop "primary" from names
ZeroTricks Apr 2, 2026
a03db05
add ServerTool.isAvailable(), use it to make search dependent on Conv…
ZeroTricks Apr 2, 2026
b1582e1
add ServerTool to read previous conversations B-)
ZeroTricks Apr 2, 2026
a404b32
mention server tools shortly in docs
ZeroTricks Apr 2, 2026
a8e4ee0
Clean up conversations/ dead code and unnecessary exports
ZeroTricks Apr 2, 2026
6da7901
move store initialization to conversations/init.ts
ZeroTricks Apr 2, 2026
4ba7c54
Remove impossible and incomplte in-chat /load command
ZeroTricks Apr 2, 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
54 changes: 27 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ lumo-tamer is a lightweight local proxy that talks to Proton's Lumo API using th

- OpenAI-compatible API server with experimental tool support.
- Interactive CLI, let Lumo help you execute commands, read, create and edit files.
- Sync your conversations with Proton to access them on https://lumo.proton.me or in mobile apps.
- Sync your conversations with Proton to access them on https://lumo.proton.me or in mobile apps. Let Lumo search through and read your past conversations.


## Project Status
Expand Down Expand Up @@ -146,7 +146,7 @@ tamer # use Lumo interactively
tamer "make me laugh" # one-time prompt
```

To give Lumo access to your files and let it execute commands locally, set `cli.localActions.enabled: true` in `config.yaml` (see [Local Actions](#local-actions-cli)).
To give Lumo access to your files and let it execute commands locally, set `cli.tools.local.enabled: true` in `config.yaml` (see [Local Tools](#local-tools-cli)).
You can ask Lumo to give you a demo of its capabilities, or see this [demo chat](docs/demo-cli-chat.md).

### In-chat commands
Expand Down Expand Up @@ -186,14 +186,13 @@ cli:

### Web Search

Enable Lumo's native web search (and other external tools: weather, stock, cryptocurrency):
Enable Lumo's web search (and other native tools: weather, stock, cryptocurrency):

```yaml
server:
enableWebSearch: true

cli:
enableWebSearch: true
server: # or cli:
tools:
native:
enabled: true
```

### Instructions
Expand All @@ -205,37 +204,39 @@ Instructions from API clients will be inserted in the main template. If you can,

> **Note:** Under the hood, lumo-tamer injects instructions into normal messages (the same way it is done in Lumo's webclient). Instructions set in the webclient's personal or project settings will be ignored and left unchanged.

### Custom Tools (Server)
### Client Tools (API)

Let Lumo use tools provided by your OpenAI-compatible client.

```yaml
server:
customTools:
enabled: true
tools:
client:
enabled: true
```

> **Warning:** Custom tool support is experimental and can fail in various ways. Experiment with `server.instructions` settings to improve results. See [Custom Tools](docs/custom-tools.md) for details, tweaking, and troubleshooting.
> **Tip:** See [Tools](docs/tools.md) for details, tweaking, and troubleshooting.


### Local Actions (CLI)
### Local Tools (CLI)

Let Lumo read, create and edit files, and execute commands on your machine:

```yaml
cli:
localActions:
enabled: true
fileReads:
tools:
local:
enabled: true
executors:
bash: ["bash", "-c"]
python: ["python", "-c"]
fileReads:
enabled: true
executors:
bash: ["bash", "-c"]
python: ["python", "-c"]
```

The CLI always asks for confirmation before executing commands or applying file changes. File reads are automatic.
Configure available languages for your system in `executors`. By default, `bash`, `python`, and `sh` are enabled.
See [Local Actions](docs/local-actions.md) for further configuration and troubleshooting.
The CLI always asks for confirmation before executing commands or applying file changes. File reads are automatic.
Configure available languages for your system in `executors`. By default, `bash`, `python`, and `sh` are enabled.
See [Tools](docs/tools.md#local-tools-cli) for further configuration and troubleshooting.

### Conversation Sync

Expand Down Expand Up @@ -269,7 +270,7 @@ See the [full guide](docs/howto-home-assistant.md). TLDR:

- Pass the environment variable `OPENAI_BASE_URL=http://yourhost:3003/v1` to Home Assistant.
- Add the OpenAI integration and create a new Voice Assistant that uses it.
- To let Lumo control your devices, set `server.customTools.enabled: true` in `config.yaml` (Experimental, see [Custom Tools](docs/custom-tools.md)).
- To let Lumo control your devices, set `server.tools.client.enabled: true` in `config.yaml` (Experimental, see [Tools](docs/tools.md#client-tools-api)).
- Open HA Assist in your dashboard or phone and chat away.

### OpenClaw
Expand Down Expand Up @@ -302,7 +303,7 @@ curl http://localhost:3003/v1/chat/completions \

### Other API clients

Many clients are untested with lumo-tamer but should work if they only use the `/v1/responses` or `/v1/chat/completions` endpoints. As a rule of thumb: basic chatting will most likely work, but the more a client relies on custom tools, the more the experience is degraded.
Many clients are untested with lumo-tamer but should work if they only use the `/v1/responses` or `/v1/chat/completions` endpoints. As a rule of thumb: basic chatting will most likely work, but the more a client relies on tools, the more the experience is degraded.
To test an API client, increase log levels on both the client and lumo-tamer: `server.log.level: debug` and check for errors.

Please share your experiences with new API clients (both issues and successes) in [the project discussions](https://github.com/ZeroTricks/lumo-tamer/discussions/new?category=general)!
Expand Down Expand Up @@ -367,7 +368,7 @@ docker compose run --rm -it -v ./some-dir:/dir/ tamer cli

> **Note:** Running the CLI within Docker may not be very useful:
> - Lumo will not have access to your files unless you mount a directory.
> - The image is Alpine-based, so your system may not have the commands Lumo tries to run. You can change config options `cli.localActions.executors` and `cli.instructions.forLocalActions` to be more explicit what commands Lumo should use, or you can rebase the `Dockerfile`.
> - The image is Alpine-based, so your system may not have the commands Lumo tries to run. You can change config options `cli.tools.local.executors` and `cli.instructions.forLocalTools` to be more explicit what commands Lumo should use, or you can rebase the `Dockerfile`.



Expand All @@ -377,9 +378,8 @@ See [docs/](docs/) for detailed documentation:

- [Authentication](docs/authentication.md): Auth methods, setup and troubleshooting
- [Conversations](docs/conversations.md): Conversation persistence and sync
- [Custom Tools](docs/custom-tools.md): Tool support for API clients
- [Tools](docs/tools.md): Native, client, server, and local tools
- [Home Assistant Guide](docs/howto-home-assistant.md): Use Lumo as your Voice Assistant
- [Local Actions](docs/local-actions.md): CLI file operations and code execution
- [Development](docs/development.md): Development setup and workflow
- [Upstream Files](docs/upstream.md): Proton WebClients files, shims and path aliases

Expand Down
125 changes: 67 additions & 58 deletions config.defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ test:
mock:
# Enable mock mode: bypass authentication, return simulated Lumo responses
enabled: false
# Scenario: success, error, timeout, rejected, toolCall, misroutedToolCall, weeklyLimit, cycle
# Scenario: success, error, timeout, rejected, toolCall, misroutedToolCall, weeklyLimit, cycle, serverToolCall
scenario: "success"

# Shared Logging Configuration (can be overridden in server/cli sections)
Expand All @@ -62,29 +62,25 @@ log:
messageContent: false

# Shared Conversations Configuration (can be overridden in server/cli sections)
# Note: In-memory conversation storage is always active regardless of sync settings
# - do they still work/make sense with upstream store?
# - can they still be overwritten for cli/server? (ie. overwriting dbpath doesn't make sense if sync enabled, does it otherwise?)
conversations:
# Path for IndexedDB SQLite files (used when useUpstreamStorage is true)
# Path for IndexedDB SQLite files
databasePath: "sessions/"

# WORKAROUND for clients without conversation_id support (e.g., Home Assistant).
# WORKAROUND for API clients without conversation_id support (e.g., Home Assistant).
# Derives conversation ID from the `user` field in the request.
# Home Assistant sends its internal conversation_id as user, making it unique per chat session.
# WARNING: May incorrectly merge unrelated conversations with same "user" field. Ignored if `user` is absent.
deriveIdFromUser: false

# Use fallback in-memory store instead of the primary store
# When true, uses the legacy in-memory store (will be removed in future).
# When false (default), uses the primary Redux + IndexedDB store.
useFallbackStore: true

# Enable syncing conversations to Proton servers (requires browser auth)
enableSync: false
# Project name for conversations (created if doesn't exist)
projectName: lumo-tamer

# Enable ConversationStore for conversation persistence
# When disabled, conversations are not persisted (same as when encryption keys unavailable)
enableStore: true

# Shared Commands Configuration (can be overridden in server/cli sections)
commands:
# Enable slash commands (/save, /help, /logout, etc.)
Expand Down Expand Up @@ -116,20 +112,29 @@ server:
# Prefix for all metric names
prefix: "lumo_"

# Enable Lumo's native web_search tool (and other external tools: weather, stock, cryptocurrency)
enableWebSearch: false

# Custom tool detection for API clients
# Enable detection of JSON tool calls in Lumo's responses
# WARNING: When enabled, Lumo can trigger actions via API clients!
customTools:
enabled: false
# Tool configuration
tools:
# Enable Lumo's native external tools (web_search, weather, stock, cryptocurrency)
# Internal native tools (proton_info) are always enabled.
native:
enabled: false

# Prefix added to custom tool names to distinguish from Lumo's native tools.
# Prefix added to custom tool names (client + server tools) to distinguish from native tools.
# Applied to tool definitions sent to Lumo, stripped from tool calls returned to client.
# Set to "" to disable prefixing.
prefix: "user:"

# Server-side tools callable by Lumo (search, etc.)
# When enabled, Lumo can call these tools and the server executes them directly.
server:
enabled: true

# Client tool detection for API clients
# Enable detection of JSON tool calls in Lumo's responses
# WARNING: When enabled, Lumo can trigger actions via API clients!
client:
enabled: false


instructions:

Expand All @@ -140,7 +145,7 @@ server:
# - clientInstructions: system/developer message from request
# - forTools: the forTools block below (pre-interpolated with {{prefix}})
# - fallback: the fallback block below
# - prefix: tool prefix from customTools.prefix
# - prefix: tool prefix from tools.prefix
template: |
{{#if tools}}
{{forTools}}
Expand Down Expand Up @@ -209,50 +214,54 @@ cli:
target: "file"
filePath: "lumo-tamer-cli.log"

# Enable Lumo's native web_search tool (and other external tools: weather, stock, cryptocurrency)
enableWebSearch: false

# Local actions: code block detection and execution
localActions:
# Enable code block detection (```bash, ```read, ```edit, etc.)
# WARNING: When enabled, Lumo can trigger actions on your machine!
enabled: false

# ```read blocks: Lumo can read local files without user confirmation
fileReads:
# Enable ```read blocks
# Note that if this is false, Lumo can still ask to read a file using shell tools (ie. cat)
enabled: true
# Max file size. Reading files larger than this fail with an error.
# 512kb translates to roughly 32K tokens (Lumo's "warning level" on context size).
maxFileSize: "360kb"

# Executors for code block execution
# Maps language tag -> [command, ...args]. Code is appended as last arg.
# Override to restrict or extend
executors:
bash: ["bash", "-c"]
python: ["python", "-c"]
sh: ["sh", "-c"]
# zsh: ["zsh", "-c"]
# powershell: ["powershell", "-Command"]
# ps1: ["powershell", "-Command"]
# cmd: ["cmd", "/c"]
# node: ["node", "-e"]
# javascript: ["node", "-e"]
# js: ["node", "-e"]
# perl: ["perl", "-e"]
# Tool configuration
tools:
# Enable Lumo's native external tools (web_search, weather, stock, cryptocurrency)
# Internal native tools (proton_info) are always enabled.
native:
enabled: false

# Local tools: code block detection and execution
local:
# Enable code block detection (```bash, ```read, ```edit, etc.)
# WARNING: When enabled, Lumo can trigger actions on your machine!
enabled: false

# ```read blocks: Lumo can read local files without user confirmation
fileReads:
# Enable ```read blocks
# Note that if this is false, Lumo can still ask to read a file using shell tools (ie. cat)
enabled: true
# Max file size. Reading files larger than this fail with an error.
# 512kb translates to roughly 32K tokens (Lumo's "warning level" on context size).
maxFileSize: "360kb"

# Executors for code block execution
# Maps language tag -> [command, ...args]. Code is appended as last arg.
# Override to restrict or extend
executors:
bash: ["bash", "-c"]
python: ["python", "-c"]
sh: ["sh", "-c"]
# zsh: ["zsh", "-c"]
# powershell: ["powershell", "-Command"]
# ps1: ["powershell", "-Command"]
# cmd: ["cmd", "/c"]
# node: ["node", "-e"]
# javascript: ["node", "-e"]
# js: ["node", "-e"]
# perl: ["perl", "-e"]

instructions:
template: |
You are a command line assistant. Your output will be read in a terminal. Keep the formatting to a minimum and be concise.

{{#if localActions}}
{{forLocalActions}}
{{#if localTools}}
{{forLocalTools}}
{{/if}}

# Injected as {{forLocalActions}} when localActions.enabled=true
forLocalActions: |
# Injected as {{forLocalTools}} when tools.local.enabled=true
forLocalTools: |
You can read, edit and create files, and you can execute {{executors}} commands on the user's machine.
To execute code, use a code block like ```python. The user will be prompted to execute it and the result will be returned to you. Don't explain the user can execute commands, it will be handled automatically. Keep commands simple and safe.
To read files, use a ```read block with one file path per line. Contents will be returned to you automatically without prompting the user. Example:
Expand Down
Loading