Synchronous client over libcurl + vendored cJSON. Single public
header (include/clawdforge.h) with an opaque cf_client_t and the
full surface: /healthz, /run, /files, /admin/tokens.
- C11, no GNU extensions; -Wall -Wextra -Wpedantic clean
- Hidden visibility on the shared lib + CF_API export attribute
- Static + shared lib via CMake; relocatable pkg-config (${pcfiledir})
- Errors via out-param cf_error_t; every output struct has a _free()
- Multipart upload streams from disk via curl_mime_filedata
- 15 in-process socket-loop tests; valgrind + ASan clean
69 lines
1.9 KiB
C
69 lines
1.9 KiB
C
/* Basic clawdforge client example.
|
|
*
|
|
* Build: see clients/c/README.md
|
|
* Run: CLAWDFORGE_URL=http://localhost:8800 \
|
|
* CLAWDFORGE_TOKEN=cf_xxx \
|
|
* ./clawdforge_example_basic
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <clawdforge.h>
|
|
|
|
int main(int argc, char **argv) {
|
|
(void)argc; (void)argv;
|
|
|
|
const char *base = getenv("CLAWDFORGE_URL");
|
|
const char *tok = getenv("CLAWDFORGE_TOKEN");
|
|
if (!base) base = "http://localhost:8800";
|
|
if (!tok) tok = "";
|
|
|
|
cf_client_t *c = cf_client_new(base, tok);
|
|
if (!c) {
|
|
fprintf(stderr, "cf_client_new failed (oom or bad url)\n");
|
|
return 1;
|
|
}
|
|
|
|
cf_error_t err = {0};
|
|
|
|
/* Health check (no auth required). */
|
|
cf_healthz_t h = {0};
|
|
if (cf_healthz(c, &h, &err) != CF_OK) {
|
|
fprintf(stderr, "healthz: %s\n", cf_error_message(&err));
|
|
cf_error_free(&err);
|
|
cf_client_free(c);
|
|
return 1;
|
|
}
|
|
printf("ok=%d claude_present=%d version=%s\n",
|
|
h.ok, h.claude_present, h.claude_version ? h.claude_version : "(none)");
|
|
cf_healthz_free(&h);
|
|
|
|
/* Skip the /run round-trip if there's no token. */
|
|
if (!tok || !*tok) {
|
|
printf("(no CLAWDFORGE_TOKEN; skipping /run)\n");
|
|
cf_client_free(c);
|
|
return 0;
|
|
}
|
|
|
|
cf_run_request_t req = {
|
|
.prompt = "Reply with JSON: {\"hello\":\"world\"}",
|
|
.model = "sonnet",
|
|
.timeout_secs = 60,
|
|
};
|
|
cf_run_result_t res = {0};
|
|
if (cf_run(c, &req, &res, &err) != CF_OK) {
|
|
fprintf(stderr, "run: %s\n", cf_error_message(&err));
|
|
cf_error_free(&err);
|
|
cf_client_free(c);
|
|
return 1;
|
|
}
|
|
printf("result_json: %s\n", res.result_json ? res.result_json : "(null)");
|
|
printf("duration_ms: %ld\n", res.duration_ms);
|
|
if (res.stop_reason) printf("stop_reason: %s\n", res.stop_reason);
|
|
cf_run_result_free(&res);
|
|
|
|
cf_client_free(c);
|
|
return 0;
|
|
}
|