summaryrefslogtreecommitdiffstats
path: root/src/tools.h
blob: 9423320403e9dd0ff90eeab8842161fac16949be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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