Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
agent_request_queue.hpp
Go to the documentation of this file.
1#pragma once
2
3// agent_request_queue.hpp — a durable, file-backed queue of free-text requests
4// a human raises from the running design (the inspector's "send to agent"
5// affordance) for the driving agent to pick up on its next turn.
6//
7// The channel is PULL-BASED by design: the inspector appends a request; the
8// agent reads the pending set at the top of its turn and acks what it consumes.
9// Nothing is pushed to the agent, so it degrades honestly across agent harnesses
10// — the worst case is the agent sees a request one turn later, never that a
11// request is lost. This inverts nothing about the MCP request/response model: a
12// `pulp_inspect_pending_requests` read tool surfaces the queue; the human's
13// "send" button just enqueues a payload the agent reliably picks up.
14//
15// The queue lives beside the design ledger (`.pulp-design-meta.json`) as
16// `.pulp-design-requests.json`, so a request is anchored to a specific project.
17// On-disk schema:
18//
19// {
20// "$schema": "pulp-design-requests://v1",
21// "version": 1,
22// "requests": [ { "id","text","design","screen",
23// "editmode_state","screenshot_path","created_at",
24// "consumed" }, ... ]
25// }
26//
27// The pure parse/serialize/append/ack functions are separable from disk I/O so
28// the model is unit-testable without a filesystem. The file-backed wrappers add
29// an atomic write (`<path>.tmp` then rename) so a crash mid-write never leaves a
30// half-flushed queue at the canonical path. The core takes no clock and no RNG:
31// `created_at` is supplied by the caller and ids are assigned deterministically
32// from the existing contents, so a given input always yields the same output.
33
34#include <optional>
35#include <string>
36#include <string_view>
37#include <utility>
38#include <vector>
39
40namespace pulp::inspect {
41
45 std::string id;
46 std::string text;
47 std::string design;
48 std::string screen;
49 std::string editmode_state;
50 std::string screenshot_path;
51 std::string created_at;
52 bool consumed = false;
53};
54
56std::string_view queue_filename();
57
59std::string requests_to_json(const std::vector<AgentRequest>& requests);
60
66std::optional<std::vector<AgentRequest>> requests_from_json(std::string_view queue_json);
67
72std::optional<std::string> append_request(std::string_view queue_json, AgentRequest request);
73
76std::vector<AgentRequest> pending_requests(std::string_view queue_json);
77
81std::optional<std::pair<std::string, bool>> ack_request(std::string_view queue_json,
82 std::string_view id);
83
84// ── file-backed wrappers (atomic write) ─────────────────────────────────────
85
87std::string queue_path(std::string_view project_dir);
88
92std::optional<std::string> enqueue_to_file(const std::string& path, AgentRequest request);
93
96std::vector<AgentRequest> read_pending_file(const std::string& path);
97
100bool ack_in_file(const std::string& path, std::string_view id);
101
102} // namespace pulp::inspect
@ path
Definition scene_node.hpp:93
Definition agent_context.hpp:7
std::optional< std::string > enqueue_to_file(const std::string &path, AgentRequest request)
Read + append + atomically rewrite the queue at path.
std::string requests_to_json(const std::vector< AgentRequest > &requests)
Serialize a request list to the canonical, stable JSON document.
std::string_view queue_filename()
The canonical queue filename (beside .pulp-design-meta.json).
std::optional< std::vector< AgentRequest > > requests_from_json(std::string_view queue_json)
Parse a queue document.
std::optional< std::string > append_request(std::string_view queue_json, AgentRequest request)
Append request to the queue encoded in queue_json, assigning a fresh id when request....
std::vector< AgentRequest > pending_requests(std::string_view queue_json)
The not-yet-consumed requests in queue_json, in order.
std::vector< AgentRequest > read_pending_file(const std::string &path)
The pending requests in the queue file at path (empty when the file is absent or unreadable).
std::optional< std::pair< std::string, bool > > ack_request(std::string_view queue_json, std::string_view id)
Mark the request whose id is id consumed in queue_json.
bool ack_in_file(const std::string &path, std::string_view id)
Ack id in the queue file at path, rewriting atomically.
std::string queue_path(std::string_view project_dir)
The queue file path inside project_dir.
One queued request from the human, with the context the agent needs to act without guessing which des...
Definition agent_request_queue.hpp:44
std::string text
the human's free-text request
Definition agent_request_queue.hpp:46
std::string design
design/asset name (ties to the ledger)
Definition agent_request_queue.hpp:47
std::string screen
optional screen within the design
Definition agent_request_queue.hpp:48
std::string editmode_state
the current EDITMODE block JSON, for context
Definition agent_request_queue.hpp:49
bool consumed
true once the agent has acked it
Definition agent_request_queue.hpp:52
std::string created_at
caller-supplied timestamp (the core keeps no clock)
Definition agent_request_queue.hpp:51
std::string screenshot_path
optional path to a captured screenshot
Definition agent_request_queue.hpp:50
std::string id
stable id; assigned on append when empty
Definition agent_request_queue.hpp:45