summaryrefslogtreecommitdiffstats
path: root/src/tools.h
diff options
context:
space:
mode:
authorEthan Werner <mail@ethanwerner.com>2026-10-10 20:55:33 +0000
committerEthan Werner <mail@ethanwerner.com>2026-10-10 20:56:50 +0000
commitf8423ebea413605b42de23f5dd06c5479d3fa1dd (patch)
tree2612a5eb026c59e7aae01f10a1cf62f2ee43042c /src/tools.h
initial commitHEADmaster
Diffstat (limited to 'src/tools.h')
-rw-r--r--src/tools.h118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/tools.h b/src/tools.h
new file mode 100644
index 0000000..9423320
--- /dev/null
+++ b/src/tools.h
@@ -0,0 +1,118 @@
+#ifndef LLSH_TOOLS_H
+#define LLSH_TOOLS_H
+
+#include <cjson/cJSON.h>
+
+#include "config.h"
+#include "util.h"
+#include "dotagents.h"
+
+/* Mirrors tools.rs: the built-in tools the agent can call.
+ * Each tool returns an owned string on success, or NULL with an owned
+ * error message in **err (caller frees whichever was returned). */
+
+char *tool_read_file(const char *path, unsigned long offset, unsigned long limit,
+ char **err);
+char *tool_write_file(const char *path, const char *content, char **err);
+char *tool_run_shell(const char *command, char **err);
+char *tool_run_shell_timed(const char *command, unsigned long timeout_secs,
+ char **err);
+/* `dot` is the caller's loaded .agents snapshot (borrowed); NULL means "no
+ * skills/memories". */
+char *tool_use_skill(const dotagents *dot, const char *id, char **err);
+char *tool_search_memories(const dotagents *dot, const char *query, char **err);
+
+/* Embedding tool. The `default` preset of `.agents/models.json` supplies
+ * the connection; preset fields fall back to the top-level values. */
+typedef struct {
+ char *model; /* owned */
+ char *base_url; /* owned */
+ char *api_key; /* owned */
+} embed_target;
+void embed_target_free(embed_target *t);
+/* Resolve the configured embedding connection. 0 + *out filled, or -1 with
+ * *err owned. */
+int tool_embed_resolve(const config *cfg, const dotagents *dot,
+ embed_target *out, char **err);
+
+/* Pure helpers (no network; unit-testable). */
+char *tool_embed_request(const char *model, const char *text, char **err);
+char *tool_embed_url(const char *base_url);
+/* `body` -> the `data[0].embedding` array as a JSON array string. 0 +
+ * *vector_json owned, or -1 with *err owned. */
+int tool_embed_parse(const char *body, char **vector_json, char **err);
+
+/* Full tool: resolve + POST {base}/embeddings + parse. Returns owned
+ * `{"dimensions":N,"vector":[...]}` or NULL with *err owned. */
+char *tool_embed(const char *text, const config *cfg, const dotagents *dot,
+ char **err);
+
+/* LLM call tool: a one-shot completion through the session's provider
+ * (OpenAI-compatible, Anthropic, or Ollama). `prompt` is the single user
+ * message. The remaining fields are optional generation parameters, each
+ * with an "unset" value (temperature < 0, max_tokens / thinking_budget 0,
+ * pointers NULL); `embed` true routes the prompt to the embeddings
+ * endpoint instead. All strings borrowed for the call's lifetime. */
+typedef struct {
+ const char *prompt; /* required */
+ const char *model; /* optional override; NULL = session model */
+ double temperature; /* < 0 = unset */
+ unsigned long max_tokens; /* 0 = unset */
+ const char *reasoning_effort; /* "low" / "medium" / "high"; NULL = unset */
+ unsigned long thinking_budget; /* 0 = unset (tokens) */
+ const char *response_schema; /* JSON Schema text; NULL = unset */
+ bool embed; /* true = embed the prompt instead */
+} llm_tool_call;
+
+/* Full tool: one-shot completion (or embed when `call->embed`). Returns
+ * owned result text, or NULL with *err owned. */
+char *tool_llm(const llm_tool_call *call, const config *cfg, const dotagents *dot,
+ char **err);
+
+/* Pure helpers (mirroring the tested functions in tools.rs). */
+char *tool_truncate_output(const char *text);
+void tool_tokenize(const char *query, strlist *out);
+bool tool_is_subsequence(const char *needle, const char *haystack);
+double tool_field_match_strength(const char *field, const char *term);
+double tool_memory_relevance(const memory *m, const strlist *terms);
+
+/* Static registry for /tools display. Returns the entry count and sets
+ * *out to a static array valid for the process lifetime. */
+typedef struct {
+ const char *name;
+ const char *desc;
+} tool_entry;
+size_t tool_list_entries(const tool_entry **out);
+
+/* ------------------------------------------------------------------ */
+/* Display vtable: per-tool transcript rendering */
+/* ------------------------------------------------------------------ */
+/*
+ * Presentation hooks for the built-in tools. A tool may supply a
+ * `render_call` that renders the one-line transcript display for an
+ * invocation from its raw args JSON (freshly allocated; return NULL to
+ * fall back to the generic `# name <args>` line). Tools without an
+ * entry (e.g. MCP tools) always use the generic line. `dim_result`
+ * marks the tool's result as shell-style (the UI renders it muted).
+ */
+typedef char *(*tool_render_call)(const char *args_json);
+
+typedef struct {
+ const char *name;
+ tool_render_call render_call; /* NULL -> generic display */
+ bool dim_result;
+} tool_display;
+
+/* The vtable entry for a built-in tool (borrowed; valid for the
+ * process lifetime), or NULL when `name` is not a built-in tool. */
+const tool_display *tool_display_for(const char *name);
+
+/* Built-in tool registry (single source of truth; llm.h builds the
+ * provider tool schemas and the default preamble from it). */
+size_t tool_builtin_count(void);
+const char *tool_builtin_name(size_t i);
+const char *tool_desc(const char *name); /* schema description; "" if unknown */
+cJSON *tool_params_json(const char *name); /* fresh object; caller frees */
+char *tool_preamble_list(void); /* "Available tools:" section; caller frees */
+
+#endif