6 Commits

Author SHA1 Message Date
Dark-Alex-17 c172736362 docs: clarified OAuth more 2026-05-22 19:56:00 -06:00
github-actions[bot] 4a2b9fa42a bump: version 0.3.0 → 0.4.0 [skip ci] 2026-05-23 01:53:47 +00:00
Dark-Alex-17 98db37866c docs: Fixed a typo in the README 2026-05-22 19:49:40 -06:00
Dark-Alex-17 ad31fbd169 test: fixed broken cross tests that required home directory access 2026-05-22 19:49:01 -06:00
Dark-Alex-17 d69e28fd39 docs: fixed broken sharing configurations link 2026-05-22 19:48:44 -06:00
Alex Clarke 279eaa5300 Merge pull request #12 from Dark-Alex-17/develop
Release v0.4.0: Graph-based agents, remote asset installation, self-update and god-config refactor
2026-05-22 19:18:13 -06:00
5 changed files with 110 additions and 4 deletions
+99
View File
@@ -1,3 +1,102 @@
## v0.4.0 (2026-05-23)
### Feat
- LLM node failures propgate up
- Added .install remote tab completions to the REPL
- feature complete install remote with category selection
- Support to interactively add secrets to Loki that are missing from MCP configs when merging
- Added MCP config merging support for remote asset installations
- install remote now writes files to disk
- Created basic install_remote functions
- Created a more comprehensive and immediately useful default config for first runs
- Created an example graph-based agent called deep-research
- Improved coder agent that is now a graph-based agent
- Removed indicatif spinners. The UX just won't stop clobbering for parallel graph nodes
- Added agent variables support for graph agents and improved script executor to use the same environment variables as normal agent tool calling for further flexibility
- Improved UX with colored spinners for parallel graph agents and no clobbering outputs for sub-agents
- created new graph-based deep-research agent
- improved UX for parallel graph execution
- added branch progress tracker for better visualization of parallel graph super-steps
- Removed the jira-helper agent and replaced it with the atlassian role
- created the RenderMode enum to suppress stdout streaming during parallel graph super-steps
- Full support for map node types
- implemented the frontier-based scheduling for the graph executor with simplified state management (gotta love .clone)
- validation support for parallel graph execution; restricted map nodes to only run for nodes without next targets and not supporting chained map nodes
- created the staging area for state merges per super-step and created the built-in reducers (and their application) for the state merge phase of a super step
- scaffolding work for fan-out nodes for parallel branch execution support and stubbed out Map node types
- Loki can now update itself via .update and --update commands
- added a .edit command for editing the MCP configuration file
- Created a new .install command to install bundled assets on-demand
- migrated llm node validation to graph loading time instead of graph runtime
- ripped out user input timeout scaffolding for approval and input node types; implementation can't be done cleanly
- added additional support for all RAG-configuration fields in RAG nodes
- initial support for RAG nodes in the graph execution system
- implemented structured logging for graph execution
- merged normal agent config and graph agent configs into one file (either/or)
- added structured-output extraction for llm and agent nodes
- created full llm node runtime implementation
- scaffolded together the initial llm node type and its executor
- wired together graph execution and agent graph dispatch
- implemented support for the graph executor
- created the approval node executor and the input node executor for user interaction
- Added initial support for native Loki agent nodes in the graph-based agent system
- Added direct script invocation support for graph-based agents
- Added graph validation
- Implemented state management for agent graphs
- initial agent graph scaffolding
- add auto-continue support to all contexts
- dynamic tab completions now show the sessions for a given agent instead of only listing global sessions
- legacy SSE support for MCP server configurations
- support http/sse transport types for MCP server configurations so it fully supports claude desktop-style MCP configs
- 99% complete migration to new state structs to get away from God-Config struct; i.e. AppConfig, AppState, and RequestContext
- Automatic runtime customization using shebangs
- Created a demo TypeScript tool and a get_current_weather function in TypeScript
- Updated the Python demo tool to show all possible parameter types and variations
- Added TypeScript tool support using the refactored common ScriptedLanguage trait
### Fix
- Generified the functions usage of script detection for an executable bit on unix systems
- merge required claude code system prompt into instructions
- updated argc argument passing in run-tool and run-agent scripts
- Added additional graph validation for parallel reads and writes with dependencies between nodes states
- bug in next_single method and improved outcome handling for LLM node execution
- inline RAG bug when globbing files by extension without subdirectory globbing
- update the estimate_token_length function to use the standard word count method
- removed unnecessary regenerate logic for sessions and use the same logic for all contexts; prevents a panic on empty message list
- error when users try to start a session on a graph agent
- added on_other field for approval nodes so users can specify an alternative free-text target when none of the options match what they want
- accidentally added back in full agent tools on LLM nodes
- Improve the coder agent's usage of tools
- make the agent__collect escalation-aware so it doesn't freeze on sub-agent escalations
- check for an existing session before starting up MCP servers when switching to a role
- do not switch to agent if a session is active.
- Do not append todo instructions when function calling is disabled
- a bug in the dynamic completions because the crate name is loki-ai but the binary is named loki
- bug found by copilot that would create a lock on the PollSender for sse-based MCP servers
- Accidental shadow of temp_file function for Windows function calling
- upgraded to newer rmcp version to get native-tls support
- RagCache was not being used for agent and sub-agent instantiation
- TypeScript function args were being passed as objects rather than direct parameters
- Added in forgotten wrapper scripts for TypeScript tools
- don't shadow variables in binary path handling for Windows
- Tool call improvements for Windows systems
### Refactor
- migrated llm nodes to use Roles to simplify instructions handling and to function like inline roles
- migrated the next_node and apply_state_updates logic for LLM nodes into the LlmExecutor
- fully complete state re-architecting
- Fully ripped out the god Config struct
- Deprecated old Config struct initialization logic
- migrate functions and MCP servers to AppConfig
- Migrate the vault/bare_init logic
- created a single install_builtins free function to remove from Config::init
- partial migration to init in AppConfig
- Extracted common Python parser logic into a common.rs module
- python tools now use tree-sitter queries instead of AST
## v0.3.0 (2026-04-02) ## v0.3.0 (2026-04-02)
### Feat ### Feat
Generated
+1 -1
View File
@@ -3317,7 +3317,7 @@ dependencies = [
[[package]] [[package]]
name = "loki-ai" name = "loki-ai"
version = "0.3.0" version = "0.4.0"
dependencies = [ dependencies = [
"ansi_colours", "ansi_colours",
"anyhow", "anyhow",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "loki-ai" name = "loki-ai"
version = "0.3.0" version = "0.4.0"
edition = "2024" edition = "2024"
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"] authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
description = "An all-in-one, batteries included LLM CLI Tool" description = "An all-in-one, batteries included LLM CLI Tool"
+3 -2
View File
@@ -11,7 +11,7 @@ Agents, and More.
It is designed to include a number of useful agents, roles, macros, and more so users can get up and running with Loki It is designed to include a number of useful agents, roles, macros, and more so users can get up and running with Loki
in as little time as possible. You can also install entire bundles of agents, roles, macros, tools, and MCP servers from in as little time as possible. You can also install entire bundles of agents, roles, macros, tools, and MCP servers from
any git repository — see [Sharing Configurations](#sharing-configurations). any git repository. See [Sharing Configurations](https://github.com/Dark-Alex-17/loki/wiki/Sharing-Configurations) for more information.
![Agent example](https://raw.githubusercontent.com/wiki/Dark-Alex-17/loki/images/agents/sql.gif) ![Agent example](https://raw.githubusercontent.com/wiki/Dark-Alex-17/loki/images/agents/sql.gif)
@@ -176,11 +176,12 @@ subscribers, Google Gemini), you can authenticate with your existing subscriptio
# In your config.yaml # In your config.yaml
clients: clients:
- type: claude - type: claude
name: my-claude-oauth
auth: oauth # Indicate you want to authenticate with OAuth instead of an API key auth: oauth # Indicate you want to authenticate with OAuth instead of an API key
``` ```
```sh ```sh
loki --authenticate claude loki --authenticate my-claude-oauth
# Or via the REPL: .authenticate # Or via the REPL: .authenticate
``` ```
+6
View File
@@ -2969,6 +2969,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn rebuild_tool_scope_mcp_disabled_skips_servers() { fn rebuild_tool_scope_mcp_disabled_skips_servers() {
let _guard = TestConfigDirGuard::new();
let app_state = app_state_with_mcp_config(false, &["github", "slack"]); let app_state = app_state_with_mcp_config(false, &["github", "slack"]);
let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd); let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd);
let app = ctx.app.config.clone(); let app = ctx.app.config.clone();
@@ -2982,6 +2983,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn rebuild_tool_scope_no_enabled_servers_yields_empty_runtime() { fn rebuild_tool_scope_no_enabled_servers_yields_empty_runtime() {
let _guard = TestConfigDirGuard::new();
let app_state = app_state_with_mcp_config(true, &["github"]); let app_state = app_state_with_mcp_config(true, &["github"]);
let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd); let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd);
let app = ctx.app.config.clone(); let app = ctx.app.config.clone();
@@ -2995,6 +2997,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn rebuild_tool_scope_no_mcp_config_yields_empty_runtime() { fn rebuild_tool_scope_no_mcp_config_yields_empty_runtime() {
let _guard = TestConfigDirGuard::new();
let app_state = app_state_with_mcp_config(true, &[]); let app_state = app_state_with_mcp_config(true, &[]);
let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd); let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd);
let app = ctx.app.config.clone(); let app = ctx.app.config.clone();
@@ -3008,6 +3011,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn rebuild_tool_scope_preserves_tool_tracker() { fn rebuild_tool_scope_preserves_tool_tracker() {
let _guard = TestConfigDirGuard::new();
let app_state = app_state_with_mcp_config(false, &[]); let app_state = app_state_with_mcp_config(false, &[]);
let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd); let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd);
let dummy = ToolCall { let dummy = ToolCall {
@@ -3035,6 +3039,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn rebuild_tool_scope_repl_mode_appends_user_interaction_functions() { fn rebuild_tool_scope_repl_mode_appends_user_interaction_functions() {
let _guard = TestConfigDirGuard::new();
let app_state = app_state_with_mcp_config(false, &[]); let app_state = app_state_with_mcp_config(false, &[]);
let mut ctx = RequestContext::new(app_state, WorkingMode::Repl); let mut ctx = RequestContext::new(app_state, WorkingMode::Repl);
let app = ctx.app.config.clone(); let app = ctx.app.config.clone();
@@ -3058,6 +3063,7 @@ mod tests {
#[test] #[test]
#[serial] #[serial]
fn rebuild_tool_scope_cmd_mode_no_user_interaction_functions() { fn rebuild_tool_scope_cmd_mode_no_user_interaction_functions() {
let _guard = TestConfigDirGuard::new();
let app_state = app_state_with_mcp_config(false, &[]); let app_state = app_state_with_mcp_config(false, &[]);
let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd); let mut ctx = RequestContext::new(app_state, WorkingMode::Cmd);
let app = ctx.app.config.clone(); let app = ctx.app.config.clone();