// primitives.el — the agentic primitive SEAM the swarm composes over.
//
// The swarm is orchestration OVER the five CCR primitives, not a replacement for
// them (CCR §2, "The Five Primitives / The Execution Cycle"): a worker executes
// its task blueprint as attend -> think -> intend -> act -> learn against its
// compiled, bounded context.
//
// This file is the SEAM. The parallel API-surface reshape exposes the canonical
// primitive tools; when it lands, bind each primitive below to the reshaped
// implementation (see PRIMITIVE_BINDING). Until then these are thin, engram-
// backed fallbacks so the swarm — its fan-out, containment, CCR context
// compilation, convergence, and work-tracking — is fully exercisable today.
//
// Contract: every primitive takes and returns String (JSON where structured), so
// any primitive is directly threadable via thread.el's spawn (which runs
// top-level (String)->String El fns).
//
// PRIMITIVE_BINDING: to bind the reshape's real tools, replace each fallback body
// with a call to the reshaped El fn / API endpoint. Signatures here are the
// stable contract the swarm depends on; keep them.

// ── attend — retrieve the minimal relevant context for a focus ───────────────
// Vantage-read: pull only what this focus needs from the mind. Backed by the
// engram's spreading-activation retrieval.
fn primitive_attend(query: String, limit: Int) -> String {
    if str_eq(query, "") {
        return "[]"
    }
    // Location-independent worker model: when an engram daemon is configured,
    // retrieve over HTTP (the worker may run anywhere). POST /api/search
    // {query,limit,_auth}. Falls back to the in-process store otherwise.
    let url: String = env("ENGRAM_URL")
    if str_eq(url, "") {
        return engram_activate(query, limit)
    }
    let kv: [String] = el_list_empty()
    let kv = el_list_append(kv, "query")
    let kv = el_list_append(kv, query)
    let body0: String = json_build_object(kv)
    let body1: String = json_set(body0, "limit", int_to_str(limit))
    let body2: String = json_set_str(body1, "_auth", env("ENGRAM_API_KEY"))
    return http_post(url + "/api/search", body2)
}

// ── think — reason over the compiled context ─────────────────────────────────
// In production this routes to a model (CCR dynamic model selection). Here it is
// a deterministic, hermetic transform so swarm behaviour is testable without an
// external model: it echoes a structured verdict derived from the context. The
// binding point for a real model is explicit.
fn primitive_think(compiled_ctx: String, instruction: String) -> String {
    // PRIMITIVE_BINDING: replace with the reshape's think() (model inference).
    let kv: [String] = el_list_empty()
    let kv = el_list_append(kv, "instruction")
    let kv = el_list_append(kv, instruction)
    let kv = el_list_append(kv, "ctx_bytes")
    let kv = el_list_append(kv, int_to_str(str_len(compiled_ctx)))
    let kv = el_list_append(kv, "conclusion")
    let kv = el_list_append(kv, "reasoned:" + instruction)
    return json_build_object(kv)
}

// ── intend — form a bounded plan/decision from a thought ─────────────────────
fn primitive_intend(thought: String) -> String {
    let concl: String = json_get_string(thought, "conclusion")
    let kv: [String] = el_list_empty()
    let kv = el_list_append(kv, "intent")
    let kv = el_list_append(kv, concl)
    return json_build_object(kv)
}

// ── act — execute a bounded effect and return its result ─────────────────────
// Workers defer real side-effects to the coordinator (idempotency requirement,
// Swarm §7.3). Here act produces an artifact-shaped result the coordinator
// collects during convergence.
fn primitive_act(intent: String, input_item: String) -> String {
    let kv: [String] = el_list_empty()
    let kv = el_list_append(kv, "acted_on")
    let kv = el_list_append(kv, input_item)
    let kv = el_list_append(kv, "via")
    let kv = el_list_append(kv, json_get_string(intent, "intent"))
    return json_build_object(kv)
}

// ── learn — record an observation into the mind, tagged by correlation ID ────
// Append-only, naturally idempotent (Swarm §7.3). Best-effort: a worker that
// cannot reach the mind still returns its result.
fn primitive_learn(corr_id: String, observation: String) -> String {
    let url: String = env("ENGRAM_URL")
    if str_eq(url, "") {
        return ""
    }
    let content: String = "swarm-worker-obs corr=" + corr_id + " :: " + observation
    return engram_node(content, "Memory", 0.4)
}
