Entropic 2.3.8
Local-first agentic inference engine
Loading...
Searching...
No Matches
c_interface.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
14
16
17#include <cstring>
18#include <new>
19#include <optional>
20#include <string>
21
23
24namespace {
25auto logger = entropic::log::get("storage.c_api");
26} // anonymous namespace
27
28// ── Handle mapping ────────────────────────────────────────
29
33
40 explicit entropic_storage_backend(const char* path)
41 : impl(path) {}
42};
43
44// ── Helpers ───────────────────────────────────────────────
45
53static char* dup_string(const std::string& s) {
54 auto* p = static_cast<char*>(std::malloc(s.size() + 1));
55 if (p) std::memcpy(p, s.c_str(), s.size() + 1);
56 return p;
57}
58
66static std::optional<std::string> opt_str(const char* s) {
67 return s ? std::optional<std::string>(s) : std::nullopt;
68}
69
70// ── Lifecycle ─────────────────────────────────────────────
71
80entropic_storage_create(const char* db_path) {
81 if (!db_path) return nullptr;
82 try {
83 return new entropic_storage_backend(db_path);
84 } catch (const std::exception& e) {
85 logger->error("storage_create failed: {}", e.what());
86 return nullptr;
87 }
88}
89
99 if (!storage) return ENTROPIC_ERROR_INVALID_ARGUMENT;
100 try {
101 return storage->impl.initialize()
103 } catch (const std::exception& e) {
104 logger->error("storage_initialize failed: {}", e.what());
105 return ENTROPIC_ERROR_IO;
106 }
107}
108
116 delete storage;
117}
118
119// ── Conversation CRUD ─────────────────────────────────────
120
133 const char* title,
134 const char* project_path,
135 const char* model_id) {
136 if (!storage || !title) return nullptr;
137 try {
138 auto id = storage->impl.create_conversation(
139 title, opt_str(project_path), opt_str(model_id));
140 return dup_string(id);
141 } catch (const std::exception& e) {
142 logger->error("create_conversation failed: {}", e.what());
143 return nullptr;
144 }
145}
146
158 const char* conversation_id,
159 const char* messages_json) {
160 if (!storage || !conversation_id || !messages_json) {
162 }
163 try {
164 return storage->impl.save_messages(conversation_id, messages_json)
166 } catch (const std::exception& e) {
167 logger->error("save_conversation failed: {}", e.what());
168 return ENTROPIC_ERROR_IO;
169 }
170}
171
183 const char* conversation_id,
184 char** result_json) {
185 if (!storage || !conversation_id || !result_json) {
187 }
188 try {
189 std::string json;
190 bool found = storage->impl.load_conversation(
191 conversation_id, json);
192 *result_json = found ? dup_string(json) : nullptr;
194 } catch (const std::exception& e) {
195 logger->error("load_conversation failed: {}", e.what());
196 return ENTROPIC_ERROR_IO;
197 }
198}
199
212 int limit, int offset,
213 char** result_json) {
214 if (!storage || !result_json) {
216 }
217 try {
218 std::string json;
219 storage->impl.list_conversations(limit, offset, json);
220 *result_json = dup_string(json);
221 return ENTROPIC_OK;
222 } catch (const std::exception& e) {
223 logger->error("list_conversations failed: {}", e.what());
224 return ENTROPIC_ERROR_IO;
225 }
226}
227
240 const char* query, int limit,
241 char** result_json) {
242 if (!storage || !query || !result_json) {
244 }
245 try {
246 std::string json;
247 storage->impl.search_conversations(query, limit, json);
248 *result_json = dup_string(json);
249 return ENTROPIC_OK;
250 } catch (const std::exception& e) {
251 logger->error("search_conversations failed: {}", e.what());
252 return ENTROPIC_ERROR_IO;
253 }
254}
255
266 const char* conversation_id) {
267 if (!storage || !conversation_id) {
269 }
270 try {
271 return storage->impl.delete_conversation(conversation_id)
273 } catch (const std::exception& e) {
274 logger->error("delete_conversation failed: {}", e.what());
275 return ENTROPIC_ERROR_IO;
276 }
277}
278
279// ── Delegation storage ────────────────────────────────────
280
296 const char* parent_conversation_id,
297 const char* delegating_tier,
298 const char* target_tier,
299 const char* task,
300 int max_turns,
301 char** result_json) {
302 if (!storage || !parent_conversation_id || !delegating_tier ||
303 !target_tier || !task || !result_json) {
305 }
306 try {
307 std::string del_id, child_id;
308 bool ok = storage->impl.create_delegation(
309 parent_conversation_id, delegating_tier,
310 target_tier, task, max_turns, del_id, child_id);
311 if (ok) {
312 auto json = "{\"delegation_id\":\"" + del_id +
313 "\",\"child_conversation_id\":\"" + child_id + "\"}";
314 *result_json = dup_string(json);
315 }
316 return ok ? ENTROPIC_OK : ENTROPIC_ERROR_IO;
317 } catch (const std::exception& e) {
318 logger->error("create_delegation failed: {}", e.what());
319 return ENTROPIC_ERROR_IO;
320 }
321}
322
335 const char* delegation_id,
336 const char* status,
337 const char* result_summary) {
338 if (!storage || !delegation_id || !status) {
340 }
341 try {
342 return storage->impl.complete_delegation(
343 delegation_id, status, opt_str(result_summary))
345 } catch (const std::exception& e) {
346 logger->error("complete_delegation failed: {}", e.what());
347 return ENTROPIC_ERROR_IO;
348 }
349}
350
362 const char* conversation_id,
363 char** result_json) {
364 if (!storage || !conversation_id || !result_json) {
366 }
367 try {
368 std::string json;
369 storage->impl.get_delegations(conversation_id, json);
370 *result_json = dup_string(json);
371 return ENTROPIC_OK;
372 } catch (const std::exception& e) {
373 logger->error("get_delegations failed: {}", e.what());
374 return ENTROPIC_ERROR_IO;
375 }
376}
377
378// ── Compaction snapshots ──────────────────────────────────
379
391 const char* conversation_id,
392 const char* messages_json) {
393 if (!storage || !conversation_id || !messages_json) {
395 }
396 try {
397 return storage->impl.save_snapshot(conversation_id, messages_json)
399 } catch (const std::exception& e) {
400 logger->error("save_snapshot failed: {}", e.what());
401 return ENTROPIC_ERROR_IO;
402 }
403}
404
405// ── Statistics ────────────────────────────────────────────
406
417 char** result_json) {
418 if (!storage || !result_json) {
420 }
421 try {
422 std::string json;
423 storage->impl.get_stats(json);
424 *result_json = dup_string(json);
425 return ENTROPIC_OK;
426 } catch (const std::exception& e) {
427 logger->error("get_stats failed: {}", e.what());
428 return ENTROPIC_ERROR_IO;
429 }
430}
entropic_error_t entropic_storage_get_stats(entropic_storage_backend_t storage, char **result_json)
Get statistics.
entropic_error_t entropic_storage_list_conversations(entropic_storage_backend_t storage, int limit, int offset, char **result_json)
List conversations.
entropic_error_t entropic_storage_load_conversation(entropic_storage_backend_t storage, const char *conversation_id, char **result_json)
Load a conversation.
entropic_error_t entropic_storage_create_delegation(entropic_storage_backend_t storage, const char *parent_conversation_id, const char *delegating_tier, const char *target_tier, const char *task, int max_turns, char **result_json)
Create a delegation.
entropic_error_t entropic_storage_save_snapshot(entropic_storage_backend_t storage, const char *conversation_id, const char *messages_json)
Save a compaction snapshot.
entropic_storage_backend_t entropic_storage_create(const char *db_path)
Create a storage backend.
void entropic_storage_destroy(entropic_storage_backend_t storage)
Destroy storage.
entropic_error_t entropic_storage_search_conversations(entropic_storage_backend_t storage, const char *query, int limit, char **result_json)
Search conversations.
static std::optional< std::string > opt_str(const char *s)
Convert optional C string to std::optional<std::string>.
entropic_error_t entropic_storage_initialize(entropic_storage_backend_t storage)
Initialize storage.
static char * dup_string(const std::string &s)
Duplicate a std::string to a malloc'd C string.
char * entropic_storage_create_conversation(entropic_storage_backend_t storage, const char *title, const char *project_path, const char *model_id)
Create a conversation.
entropic_error_t entropic_storage_complete_delegation(entropic_storage_backend_t storage, const char *delegation_id, const char *status, const char *result_summary)
Complete a delegation.
entropic_error_t entropic_storage_delete_conversation(entropic_storage_backend_t storage, const char *conversation_id)
Delete a conversation.
entropic_error_t entropic_storage_get_delegations(entropic_storage_backend_t storage, const char *conversation_id, char **result_json)
Get delegations for a conversation.
entropic_error_t entropic_storage_save_conversation(entropic_storage_backend_t storage, const char *conversation_id, const char *messages_json)
Save messages to a conversation.
SQLite-based storage backend.
Definition backend.h:43
bool save_messages(const std::string &conversation_id, const std::string &messages_json)
Save messages to a conversation.
Definition backend.cpp:225
bool complete_delegation(const std::string &delegation_id, const std::string &status, const std::optional< std::string > &result_summary=std::nullopt)
Mark a delegation as completed or failed.
Definition backend.cpp:602
bool create_delegation(const std::string &parent_conversation_id, const std::string &delegating_tier, const std::string &target_tier, const std::string &task, int max_turns, std::string &delegation_id, std::string &child_conversation_id)
Create a delegation record with a child conversation.
Definition backend.cpp:540
bool search_conversations(const std::string &query, int limit, std::string &result_json)
Full-text search across conversations.
Definition backend.cpp:426
bool get_delegations(const std::string &conversation_id, std::string &result_json)
Get delegations for a parent conversation.
Definition backend.cpp:681
bool save_snapshot(const std::string &conversation_id, const std::string &messages_json)
Save a pre-compaction snapshot of full conversation history.
Definition backend.cpp:774
std::string create_conversation(const std::string &title="New Conversation", const std::optional< std::string > &project_path=std::nullopt, const std::optional< std::string > &model_id=std::nullopt)
Create a new conversation.
Definition backend.cpp:131
bool load_conversation(const std::string &conversation_id, std::string &result_json)
Load a conversation with messages.
Definition backend.cpp:309
bool get_stats(std::string &result_json)
Get storage statistics.
Definition backend.cpp:807
bool delete_conversation(const std::string &conversation_id)
Delete a conversation and all associated records.
Definition backend.cpp:385
bool list_conversations(int limit, int offset, std::string &result_json)
List conversations with pagination.
Definition backend.cpp:349
bool initialize()
Initialize storage (open database, run migrations).
Definition backend.cpp:107
entropic_error_t
Error codes returned by all C API functions.
Definition error.h:35
@ ENTROPIC_OK
Success.
Definition error.h:36
@ ENTROPIC_ERROR_INVALID_ARGUMENT
NULL pointer, empty string, out-of-range value.
Definition error.h:37
@ ENTROPIC_ERROR_IO
File/network I/O error.
Definition error.h:50
Pure C interface contract for storage backends.
spdlog initialization and logger access.
ENTROPIC_EXPORT std::shared_ptr< spdlog::logger > get(const std::string &name)
Get or create a named logger.
Definition logging.cpp:211
SqliteStorageBackend — conversation persistence via SQLite.
entropic_storage_backend(const char *path)
Construct with database path.