diff options
| author | soryu <soryu@soryu.co> | 2026-02-10 23:29:43 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2026-02-10 23:29:43 +0000 |
| commit | a1ecbc23f1f289ba312e7a8d8c6e92c9d1e81ecf (patch) | |
| tree | 32857278937db5cab13bceea86acaac5f0fe743d | |
| parent | 339c1769379a851c4126021132573bd4b7994cf2 (diff) | |
| download | soryu-makima/makima--add-an-optional-memory-system-for-directiv-e123bc35.tar.gz soryu-makima/makima--add-an-optional-memory-system-for-directiv-e123bc35.zip | |
WIP: heartbeat checkpointmakima/makima--add-an-optional-memory-system-for-directiv-e123bc35
| -rw-r--r-- | makima/src/daemon/api/directive.rs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/makima/src/daemon/api/directive.rs b/makima/src/daemon/api/directive.rs index cd21692..1ca099b 100644 --- a/makima/src/daemon/api/directive.rs +++ b/makima/src/daemon/api/directive.rs @@ -30,6 +30,47 @@ pub struct UpdateStepDepsRequest { pub depends_on: Vec<Uuid>, } +/// Percent-encode a string for use as a URL path segment. +/// +/// Encodes all characters except unreserved characters (alphanumeric, `-`, `.`, `_`, `~`). +fn percent_encode_path(s: &str) -> String { + let mut encoded = String::with_capacity(s.len()); + for byte in s.bytes() { + match byte { + b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'.' | b'_' | b'~' => { + encoded.push(byte as char); + } + _ => { + encoded.push_str(&format!("%{:02X}", byte)); + } + } + } + encoded +} + +/// Request body for setting a single memory entry. +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SetMemoryRequest { + pub key: String, + pub value: String, +} + +/// A single entry within a batch set request. +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct BatchMemoryEntry { + pub key: String, + pub value: String, +} + +/// Request body for setting multiple memory entries at once. +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct BatchSetMemoryRequest { + pub entries: Vec<BatchMemoryEntry>, +} + impl ApiClient { /// List all directives. pub async fn list_directives(&self) -> Result<JsonValue, ApiError> { @@ -134,4 +175,80 @@ impl ApiClient { let req = UpdateGoalRequest { goal: goal.to_string() }; self.put(&format!("/api/v1/directives/{}/goal", directive_id), &req).await } + + // ── Directive Memory ────────────────────────────────────────────── + + /// List all memory entries for a directive. + pub async fn list_memories(&self, directive_id: Uuid) -> Result<JsonValue, ApiError> { + self.get(&format!("/api/v1/directives/{}/memory", directive_id)) + .await + } + + /// Get a single memory entry by key. + pub async fn get_memory( + &self, + directive_id: Uuid, + key: &str, + ) -> Result<JsonValue, ApiError> { + self.get(&format!( + "/api/v1/directives/{}/memory/{}", + directive_id, + percent_encode_path(key) + )) + .await + } + + /// Set (create or update) a single memory entry. + pub async fn set_memory( + &self, + directive_id: Uuid, + key: &str, + value: &str, + ) -> Result<JsonValue, ApiError> { + let req = SetMemoryRequest { + key: key.to_string(), + value: value.to_string(), + }; + self.put(&format!("/api/v1/directives/{}/memory", directive_id), &req) + .await + } + + /// Set multiple memory entries in a single request. + pub async fn batch_set_memories( + &self, + directive_id: Uuid, + entries: Vec<(String, String)>, + ) -> Result<JsonValue, ApiError> { + let req = BatchSetMemoryRequest { + entries: entries + .into_iter() + .map(|(key, value)| BatchMemoryEntry { key, value }) + .collect(), + }; + self.post( + &format!("/api/v1/directives/{}/memory/batch", directive_id), + &req, + ) + .await + } + + /// Delete a single memory entry by key. + pub async fn delete_memory( + &self, + directive_id: Uuid, + key: &str, + ) -> Result<(), ApiError> { + self.delete(&format!( + "/api/v1/directives/{}/memory/{}", + directive_id, + percent_encode_path(key) + )) + .await + } + + /// Clear all memory entries for a directive. + pub async fn clear_memories(&self, directive_id: Uuid) -> Result<(), ApiError> { + self.delete(&format!("/api/v1/directives/{}/memory", directive_id)) + .await + } } |
