diff --git a/docs/roadmap.md b/docs/roadmap.md index 5d9bffd..5297168 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -529,6 +529,24 @@ tested). For what's still ahead, see [Next planned work](#next-planned-work). DAG-CBOR's canonical-ordering enforcement is the wrong fit for a browser-produced `attestationObject`), not this SDK; these two primitives were the actual SDK-level gap. + 65. Removed five speculative `tools.ozone.moderation.*` wrappers + (`getLabelDefinitions`/`wf_ozone_get_label_defs`, + `getSuggestions`/`wf_ozone_get_suggestions` and its typed wrapper + `wf_ozone_moderation_get_suggestions`, + `getLabelDefinitions`'s typed wrapper + `wf_ozone_moderation_get_label_definitions`, `getTag`/`wf_ozone_get_tag`, + `queryTags`/`wf_ozone_query_tags`, and `scanVerdicts`/ + `wf_ozone_scan_verdicts`), plus their CLI subcommands + (`ozone moderation get-suggestions`/`get-label-definitions`) and tests. + Item 40 flagged `getSuggestions` as unconfirmed against the reference; + revisiting turned up that none of these five NSIDs exist anywhere in + bluesky-social/atproto's lexicons, the bluesky-social/ozone frontend, + or a GitHub code search of either — not just missing from the local + snapshot, but not real, published, or served by any known deployment. + Shipping API surface for endpoints that don't exist just misleads + wolfram's own users into writing code against something that will + 404/MethodNotImplemented on every real server. `wf_ozone_get_subjects` + (`tools.ozone.moderation.getSubjects`, a real lexicon) is unaffected. ## Next planned work diff --git a/examples/ozone_moderation.c b/examples/ozone_moderation.c index 1c116c6..115c4e7 100644 --- a/examples/ozone_moderation.c +++ b/examples/ozone_moderation.c @@ -112,19 +112,6 @@ int main(int argc, char **argv) { } wf_response_free(&statuses); - /* Fetch label value definitions for the labeler's service record. */ - wf_response defs = {0}; - const char *def_uris[1]; - def_uris[0] = "at://did:plc:examplelabelerexampleexample1234/" - "app.bsky.labeler.service/self"; - status = wf_ozone_get_label_defs(client, def_uris, 1, &defs); - if (status == WF_OK) { - print_json("getLabelDefs", &defs); - } else { - printf("getLabelDefs skipped/failed: %d\n", (int)status); - } - wf_response_free(&defs); - wf_session_free(session); return 0; } diff --git a/include/wolfram/ozone.h b/include/wolfram/ozone.h index 0bf3e9a..44c155a 100644 --- a/include/wolfram/ozone.h +++ b/include/wolfram/ozone.h @@ -12,21 +12,13 @@ * - wf_ozone_report_subject : file a moderation report * (com.atproto.moderation.createReport). * - wf_ozone_query_statuses : tools.ozone.moderation.queryStatuses. - * - wf_ozone_get_label_defs : - * tools.ozone.moderation.getLabelDefinitions. * - wf_ozone_emit_event : tools.ozone.moderation.emitEvent. * - wf_ozone_query_events / * wf_ozone_list_events : tools.ozone.moderation.queryEvents. * - wf_ozone_get_event : tools.ozone.moderation.getEvent. * - wf_ozone_get_reporter_stats : * tools.ozone.moderation.getReporterStats. - * - wf_ozone_scan_verdicts : tools.ozone.moderation.scanVerdicts - * (JSON-in/JSON-out; lexicon not in the local snapshot — see TODO). * - wf_ozone_get_subjects : tools.ozone.moderation.getSubjects. - * - wf_ozone_get_suggestions : tools.ozone.moderation.getSuggestions. - * - wf_ozone_get_tag / - * wf_ozone_query_tags : tag lookup (JSON-out; lexicon not in - * the local snapshot — see TODO). * - Communication templates : tools.ozone.communication.*. * - Set values : tools.ozone.set.*. * @@ -62,9 +54,6 @@ extern "C" { /* NSIDs used by this module. */ #define WF_OZONE_QUERY_STATUSES_NSID "tools.ozone.moderation.queryStatuses" -#define WF_OZONE_GET_LABEL_DEFS_NSID \ - "tools.ozone.moderation.getLabelDefinitions" -#define WF_OZONE_GET_SUGGESTIONS_NSID "tools.ozone.moderation.getSuggestions" #define WF_ATPROTO_CREATE_REPORT_NSID "com.atproto.moderation.createReport" #define WF_OZONE_EMIT_EVENT_NSID "tools.ozone.moderation.emitEvent" @@ -72,10 +61,7 @@ extern "C" { #define WF_OZONE_GET_EVENT_NSID "tools.ozone.moderation.getEvent" #define WF_OZONE_GET_REPORTER_STATS_NSID \ "tools.ozone.moderation.getReporterStats" -#define WF_OZONE_SCAN_VERDICTS_NSID "tools.ozone.moderation.scanVerdicts" #define WF_OZONE_GET_SUBJECTS_NSID "tools.ozone.moderation.getSubjects" -#define WF_OZONE_GET_TAG_NSID "tools.ozone.moderation.getTag" -#define WF_OZONE_QUERY_TAGS_NSID "tools.ozone.moderation.queryTags" #define WF_OZONE_COMM_LIST_TEMPLATES_NSID \ "tools.ozone.communication.listTemplates" @@ -231,18 +217,6 @@ wf_status wf_ozone_report_subject(wf_xrpc_client *client, const char *repo_did, wf_status wf_ozone_query_statuses(wf_xrpc_client *client, const char **subjects, size_t n, wf_response *out); -/* - * Fetch label value definitions via tools.ozone.moderation.getLabelDefinitions - * (falling back to getSuggestions when definitions are unavailable). `uris` is - * an array of `n` labeler service record URIs; each is sent as a repeated - * `uris` query parameter. - * - * On WF_OK, *out is populated and must be released with wf_response_free. - * Returns WF_ERR_INVALID_ARG for NULL client/out, or a transport error. - */ -wf_status wf_ozone_get_label_defs(wf_xrpc_client *client, const char **uris, - size_t n, wf_response *out); - /* ------------------------------------------------------------------ */ /* Emit / query moderation events */ /* ------------------------------------------------------------------ */ @@ -344,22 +318,8 @@ wf_status wf_ozone_get_reporter_stats_parse( const wf_response *resp, wf_lex_tools_ozone_moderation_get_reporter_stats_main_output **out); -/* - * Scan account verdicts via tools.ozone.moderation.scanVerdicts. - * - * TODO: scanVerdicts is NOT present in the local atproto lexicon snapshot - * (/Volumes/Storage/Developer/Local/atproto/lexicons). The NSID is taken from - * the current upstream lexicon; confirm it against the deployment before - * relying on it. The request/response shape is therefore accepted and - * returned as raw JSON: `body_json` is borrowed; on WF_OK *out_json is an - * owned NUL-terminated JSON string freed with free(). Returns - * WF_ERR_INVALID_ARG for NULL client/body_json/out_json, or a transport error. - */ -wf_status wf_ozone_scan_verdicts(wf_xrpc_client *client, const char *body_json, - char **out_json); - /* ------------------------------------------------------------------ */ -/* Subjects / suggestions */ +/* Subjects */ /* ------------------------------------------------------------------ */ /* @@ -382,43 +342,6 @@ wf_status wf_ozone_get_subjects_parse( const wf_response *resp, wf_lex_tools_ozone_moderation_get_subjects_main_output **out); -/* - * Fetch moderation suggestions via tools.ozone.moderation.getSuggestions. - * - * TODO: getSuggestions is NOT present in the local atproto lexicon snapshot, - * so no generated params struct exists. This wrapper builds the best-effort - * query parameters (`limit`, `cursor`, repeated `ignoreSubjects`) and returns - * the raw response. Confirm the exact parameter names against the deployment. - * On WF_OK, *out is populated with the raw response freed with - * wf_response_free. - */ -wf_status wf_ozone_get_suggestions(wf_xrpc_client *client, - const char **ignore_subjects, size_t n, - int64_t limit, const char *cursor, - wf_response *out); - -/* - * Look up a single tag via tools.ozone.moderation.getTag. - * - * TODO: getTag is NOT present in the local atproto lexicon snapshot; the NSID - * is taken from the current upstream lexicon and should be confirmed. Returns - * the raw response body. On WF_OK *out_json is an owned NUL-terminated JSON - * string freed with free(). Returns WF_ERR_INVALID_ARG for NULL client/tag/ - * out_json, or a transport error. - */ -wf_status wf_ozone_get_tag(wf_xrpc_client *client, const char *tag, - char **out_json); - -/* - * Query tags via tools.ozone.moderation.queryTags. - * - * TODO: queryTags is NOT present in the local atproto lexicon snapshot; the - * NSID is taken from the current upstream lexicon and should be confirmed. - * On WF_OK *out_json is an owned NUL-terminated JSON string freed with free(). - */ -wf_status wf_ozone_query_tags(wf_xrpc_client *client, int64_t limit, - const char *cursor, char **out_json); - /* ------------------------------------------------------------------ */ /* Communication templates (tools.ozone.communication.*) */ /* ------------------------------------------------------------------ */ diff --git a/include/wolfram/ozone_typed.h b/include/wolfram/ozone_typed.h index 193b858..9811472 100644 --- a/include/wolfram/ozone_typed.h +++ b/include/wolfram/ozone_typed.h @@ -16,10 +16,7 @@ * * Procedures (and a few queries) whose lexicon defines no owning output * decoder return the raw wf_response, freed by the caller with - * wf_response_free. Endpoints whose lexicon is genuinely missing from the - * local snapshot (tools.ozone.moderation.getSuggestions and - * .getLabelDefinitions) are exposed as JSON-in/JSON-out wrappers returning an - * owned char* body freed with free() (see the TODO on each). + * wf_response_free. * * In addition, two hand-written ergonomic structs mirror the most-used list * responses following the labeler_typed ownership model (static @@ -235,23 +232,6 @@ void wf_ozone_team_member_list_free(wf_ozone_team_member_list *l); WF_OZONE_ENDPOINTS #undef X -/* JSON-in/JSON-out wrappers for endpoints whose lexicon is missing from the - * local snapshot. `out_json` is an owned NUL-terminated string freed with - * free(); on error it is left NULL. */ -/* TODO: tools.ozone.moderation.getSuggestions is NOT in the local atproto - * lexicon snapshot, so no generated params/decoder exist. This wrapper reuses - * the existing ozone.c transport helper and returns the raw response body. */ -wf_status wf_ozone_moderation_get_suggestions( - wf_agent *agent, const char *const *ignore_subjects, size_t n, - int64_t limit, const char *cursor, char **out_json); - -/* TODO: tools.ozone.moderation.getLabelDefinitions is NOT in the local atproto - * lexicon snapshot, so no generated params/decoder exist. This wrapper reuses - * the existing ozone.c transport helper and returns the raw response body. */ -wf_status wf_ozone_moderation_get_label_definitions(wf_agent *agent, - const char *const *uris, - size_t n, char **out_json); - #ifdef __cplusplus } #endif diff --git a/src/agent/ozone_typed.c b/src/agent/ozone_typed.c index 2057538..d382e67 100644 --- a/src/agent/ozone_typed.c +++ b/src/agent/ozone_typed.c @@ -620,69 +620,3 @@ void wf_ozone_team_member_list_free(wf_ozone_team_member_list *l) { #define X(ns, op, genop, kind) WF_OZONE_DEF_##kind(ns, op, genop) WF_OZONE_ENDPOINTS #undef X - -/* ------------------------------------------------------------------ */ -/* JSON-in/JSON-out wrappers for missing lexicon endpoints */ -/* ------------------------------------------------------------------ */ - -/* TODO: tools.ozone.moderation.getSuggestions is NOT in the local atproto - * lexicon snapshot, so no generated params/decoder exist. Reuses the existing - * ozone.c transport helper and returns the raw response body as owned JSON. */ -wf_status wf_ozone_moderation_get_suggestions( - wf_agent *agent, const char *const *ignore_subjects, size_t n, - int64_t limit, const char *cursor, char **out_json) { - if (!agent || !agent->client || !out_json) { - return WF_ERR_INVALID_ARG; - } - *out_json = NULL; - wf_agent_sync_auth(agent); - wf_response res = {0}; - wf_status st = wf_ozone_get_suggestions( - agent->client, (const char **)ignore_subjects, n, limit, cursor, &res); - if (st != WF_OK) { - wf_response_free(&res); - return st; - } - size_t len = res.body_len; - char *cpy = (char *)malloc(len ? len + 1 : 1); - if (!cpy) { - wf_response_free(&res); - return WF_ERR_ALLOC; - } - memcpy(cpy, res.body ? res.body : "", len); - cpy[len] = '\0'; - wf_response_free(&res); - *out_json = cpy; - return WF_OK; -} - -/* TODO: tools.ozone.moderation.getLabelDefinitions is NOT in the local atproto - * lexicon snapshot, so no generated params/decoder exist. Reuses the existing - * ozone.c transport helper and returns the raw response body as owned JSON. */ -wf_status wf_ozone_moderation_get_label_definitions(wf_agent *agent, - const char *const *uris, - size_t n, char **out_json) { - if (!agent || !agent->client || !out_json) { - return WF_ERR_INVALID_ARG; - } - *out_json = NULL; - wf_agent_sync_auth(agent); - wf_response res = {0}; - wf_status st = - wf_ozone_get_label_defs(agent->client, (const char **)uris, n, &res); - if (st != WF_OK) { - wf_response_free(&res); - return st; - } - size_t len = res.body_len; - char *cpy = (char *)malloc(len ? len + 1 : 1); - if (!cpy) { - wf_response_free(&res); - return WF_ERR_ALLOC; - } - memcpy(cpy, res.body ? res.body : "", len); - cpy[len] = '\0'; - wf_response_free(&res); - *out_json = cpy; - return WF_OK; -} diff --git a/src/cli/cli_ozone.c b/src/cli/cli_ozone.c index 39eae40..fa2346b 100644 --- a/src/cli/cli_ozone.c +++ b/src/cli/cli_ozone.c @@ -237,92 +237,6 @@ int cmd_ozone(int argc, char **argv) { return 0; } - /* moderation get-suggestions - * [--ignore-subjects uri]... [--limit N] */ - if (strcmp(group, "moderation") == 0 && - strcmp(sub, "get-suggestions") == 0) { - const char *ignore_subjects[256]; - size_t ignore_count = 0; - int limit = 50; - const char *cursor = NULL; - const char *pos[3]; - int pi = 0; - for (int i = 3; i < argc; ++i) { - if (strcmp(argv[i], "--ignore-subjects") == 0 && i + 1 < argc) - ignore_subjects[ignore_count++] = argv[++i]; - else if (strcmp(argv[i], "--limit") == 0 && i + 1 < argc) - limit = atoi(argv[++i]); - else if (strcmp(argv[i], "--cursor") == 0 && i + 1 < argc) - cursor = argv[++i]; - else if (pi < 3) - pos[pi++] = argv[i]; - } - if (pi < 3) { - fprintf(stderr, - "error: usage: wolfram ozone moderation get-suggestions " - " [--ignore-subjects uri]... " - "[--limit N] [--cursor C]\n"); - return 1; - } - - wf_agent *agent = agent_login_or_err(pos[0], pos[1], pos[2]); - if (!agent) return 1; - - char *out_json = NULL; - wf_status s = wf_ozone_moderation_get_suggestions( - agent, ignore_subjects, ignore_count, limit, cursor, &out_json); - if (s != WF_OK) { - fprintf(stderr, "error: getSuggestions failed (status %d)\n", - (int)s); - wf_agent_free(agent); - return 1; - } - if (out_json) printf("%s\n", out_json); - free(out_json); - wf_agent_free(agent); - return 0; - } - - /* moderation get-label-definitions [--uri - * uri]... */ - if (strcmp(group, "moderation") == 0 && - strcmp(sub, "get-label-definitions") == 0) { - const char *uris[256]; - size_t uri_count = 0; - const char *pos[3]; - int pi = 0; - for (int i = 3; i < argc; ++i) { - if (strcmp(argv[i], "--uri") == 0 && i + 1 < argc) - uris[uri_count++] = argv[++i]; - else if (pi < 3) - pos[pi++] = argv[i]; - } - if (pi < 3) { - fprintf( - stderr, - "error: usage: wolfram ozone moderation get-label-definitions " - " [--uri uri]...\n"); - return 1; - } - - wf_agent *agent = agent_login_or_err(pos[0], pos[1], pos[2]); - if (!agent) return 1; - - char *out_json = NULL; - wf_status s = wf_ozone_moderation_get_label_definitions( - agent, uris, uri_count, &out_json); - if (s != WF_OK) { - fprintf(stderr, "error: getLabelDefinitions failed (status %d)\n", - (int)s); - wf_agent_free(agent); - return 1; - } - if (out_json) printf("%s\n", out_json); - free(out_json); - wf_agent_free(agent); - return 0; - } - /* team list-members [--limit N] [--cursor C] */ if (strcmp(group, "team") == 0 && strcmp(sub, "list-members") == 0) { diff --git a/src/cli/main.c b/src/cli/main.c index 2ca4204..f736ae7 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -240,10 +240,6 @@ void usage_stream(FILE *out) { " Ozone moderation:\n" " ozone moderation query-statuses " "[--limit N] [--cursor C]\n" - " ozone moderation get-suggestions " - "[--ignore-subjects uri]... [--limit N]\n" - " ozone moderation get-label-definitions " - " [--uri uri]...\n" " ozone team list-members " "[--limit N] [--cursor C]\n" " ozone server get-config \n" @@ -491,14 +487,6 @@ static void cmd_help_stream(FILE *out, const char *cmd) { "ozone moderation query-statuses " "[--limit N] [--cursor C]", "Query moderation subject statuses via tools.ozone.moderation."}, - {"ozone", - "ozone moderation get-suggestions " - "[--ignore-subjects uri]... [--limit N]", - "Fetch moderation suggestions via tools.ozone.moderation."}, - {"ozone", - "ozone moderation get-label-definitions " - " [--uri uri]...", - "Fetch moderation label definitions via tools.ozone.moderation."}, {"ozone", "ozone team list-members " "[--limit N] [--cursor C]", diff --git a/src/ozone/ozone.c b/src/ozone/ozone.c index 3444044..cf9996c 100644 --- a/src/ozone/ozone.c +++ b/src/ozone/ozone.c @@ -184,37 +184,6 @@ wf_status wf_ozone_query_statuses(wf_xrpc_client *client, const char **subjects, return status; } -wf_status wf_ozone_get_label_defs(wf_xrpc_client *client, const char **uris, - size_t n, wf_response *out) { - if (!client || !out) { - return WF_ERR_INVALID_ARG; - } - - wf_xrpc_param *params = NULL; - if (uris && n > 0) { - params = (wf_xrpc_param *)calloc(n, sizeof(wf_xrpc_param)); - if (!params) { - return WF_ERR_ALLOC; - } - for (size_t i = 0; i < n; ++i) { - params[i].name = "uris"; - params[i].value = uris[i]; - } - } - - /* Prefer getLabelDefinitions; fall back to getSuggestions when it is not - * served by the instance (transport-level failure only — an HTTP error - * from getLabelDefinitions is propagated as-is). */ - wf_status status = wf_xrpc_query_params( - client, WF_OZONE_GET_LABEL_DEFS_NSID, params, n, out); - if (status != WF_OK && status != WF_ERR_HTTP) { - status = wf_xrpc_query_params(client, WF_OZONE_GET_SUGGESTIONS_NSID, - params, n, out); - } - free(params); - return status; -} - /* --- Emit / query moderation events ------------------------------- */ char *wf_ozone_emit_event_input_serialize( @@ -328,91 +297,7 @@ wf_status wf_ozone_get_reporter_stats_parse( resp->body, resp->body_len, out); } -/* --- Ambiguous / not-in-local-snapshot endpoints ------------------ */ - -/* Duplicate a response body into an owned NUL-terminated string so the - * caller can free it with free() independently of the wf_response. */ -static char *ozone_dup_body(const wf_response *resp) { - if (!resp->body) { - return NULL; - } - size_t len = resp->body_len ? resp->body_len : strlen(resp->body); - char *copy = (char *)malloc(len + 1); - if (!copy) { - return NULL; - } - memcpy(copy, resp->body, len); - copy[len] = '\0'; - return copy; -} - -wf_status wf_ozone_scan_verdicts(wf_xrpc_client *client, const char *body_json, - char **out_json) { - if (!client || !body_json || !out_json) { - return WF_ERR_INVALID_ARG; - } - wf_response resp; - wf_status status = wf_xrpc_procedure(client, WF_OZONE_SCAN_VERDICTS_NSID, - body_json, &resp); - if (status != WF_OK) { - return status; - } - *out_json = ozone_dup_body(&resp); - status = *out_json ? WF_OK : WF_ERR_ALLOC; - wf_response_free(&resp); - return status; -} - -wf_status wf_ozone_get_tag(wf_xrpc_client *client, const char *tag, - char **out_json) { - if (!client || !tag || !out_json) { - return WF_ERR_INVALID_ARG; - } - wf_xrpc_param param = {"tag", tag}; - wf_response resp; - wf_status status = - wf_xrpc_query_params(client, WF_OZONE_GET_TAG_NSID, ¶m, 1, &resp); - if (status != WF_OK) { - return status; - } - *out_json = ozone_dup_body(&resp); - status = *out_json ? WF_OK : WF_ERR_ALLOC; - wf_response_free(&resp); - return status; -} - -wf_status wf_ozone_query_tags(wf_xrpc_client *client, int64_t limit, - const char *cursor, char **out_json) { - if (!client || !out_json) { - return WF_ERR_INVALID_ARG; - } - wf_xrpc_param params[2]; - size_t n = 0; - char limit_buf[32]; - if (limit > 0) { - snprintf(limit_buf, sizeof(limit_buf), "%lld", (long long)limit); - params[n].name = "limit"; - params[n].value = limit_buf; - ++n; - } - if (cursor && cursor[0]) { - params[n].name = "cursor"; - params[n].value = cursor; - ++n; - } - wf_response resp; - wf_status status = wf_xrpc_query_params(client, WF_OZONE_QUERY_TAGS_NSID, - params, n, &resp); - if (status != WF_OK) { - return status; - } - *out_json = ozone_dup_body(&resp); - status = *out_json ? WF_OK : WF_ERR_ALLOC; - wf_response_free(&resp); - return status; -} - -/* --- Subjects / suggestions --------------------------------------- */ +/* --- Subjects --------------------------------------------------- */ wf_status wf_ozone_get_subjects(wf_xrpc_client *client, const char **subjects, size_t n, wf_response *out) { @@ -441,47 +326,6 @@ wf_status wf_ozone_get_subjects_parse( resp->body, resp->body_len, out); } -wf_status wf_ozone_get_suggestions(wf_xrpc_client *client, - const char **ignore_subjects, size_t n, - int64_t limit, const char *cursor, - wf_response *out) { - if (!client || !out) { - return WF_ERR_INVALID_ARG; - } - /* UNCONFIRMED: exhaustive searches of bluesky-social/atproto (every file - * under lexicons/tools/ozone/moderation, the ozone and bsky package - * sources, and a GitHub code search for "getSuggestions" across the - * whole repo) turn up no lexicon file, server route, or test for - * tools.ozone.moderation.getSuggestions -- only the unrelated - * app.bsky.actor.getSuggestions. - * This wrapper's parameter names are therefore a guess, not a match - * against a confirmed reference; the endpoint may be private-only Ozone - * surface never published as a lexicon, or may not exist at all. Treat - * calls through this wrapper as unverified until a real Ozone deployment - * confirms the shape, and do not add more callers depending on it. */ - wf_xrpc_param params[2 + n]; - size_t p = 0; - char limit_buf[32]; - if (limit > 0) { - snprintf(limit_buf, sizeof(limit_buf), "%lld", (long long)limit); - params[p].name = "limit"; - params[p].value = limit_buf; - ++p; - } - if (cursor && cursor[0]) { - params[p].name = "cursor"; - params[p].value = cursor; - ++p; - } - for (size_t i = 0; i < n; ++i) { - params[p].name = "ignoreSubjects"; - params[p].value = ignore_subjects[i]; - ++p; - } - return wf_xrpc_query_params(client, WF_OZONE_GET_SUGGESTIONS_NSID, params, - p, out); -} - /* --- Communication templates -------------------------------------- */ wf_status wf_ozone_list_communication_templates(wf_xrpc_client *client, diff --git a/test/test_ozone_typed.c b/test/test_ozone_typed.c index be98412..b1d2905 100644 --- a/test/test_ozone_typed.c +++ b/test/test_ozone_typed.c @@ -195,12 +195,6 @@ int main(void) { WF_CHECK(wf_ozone_moderation_emitEvent(agent, NULL, &r) == WF_ERR_INVALID_ARG); - char *js = NULL; - WF_CHECK(wf_ozone_moderation_get_suggestions( - NULL, NULL, 0, 0, NULL, &js) == WF_ERR_INVALID_ARG); - WF_CHECK(wf_ozone_moderation_get_label_definitions( - NULL, NULL, 0, &js) == WF_ERR_INVALID_ARG); - wf_agent_free(agent); }