pub struct AxonFlowClient { /* private fields */ }Implementations§
Source§impl AxonFlowClient
impl AxonFlowClient
pub fn new(config: AxonFlowConfig) -> Result<Self, AxonFlowError>
pub async fn proxy_llm_call( &self, user_token: &str, query: &str, request_type: &str, context: HashMap<String, Value>, ) -> Result<ClientResponse, AxonFlowError>
pub async fn list_connectors( &self, ) -> Result<Vec<ConnectorMetadata>, AxonFlowError>
pub async fn get_connector( &self, connector_id: &str, ) -> Result<ConnectorMetadata, AxonFlowError>
pub async fn get_connector_health( &self, connector_id: &str, ) -> Result<ConnectorHealthStatus, AxonFlowError>
pub async fn install_connector( &self, req: ConnectorInstallRequest, ) -> Result<(), AxonFlowError>
pub async fn query_connector( &self, user_token: &str, connector_name: &str, query: &str, params: HashMap<String, Value>, ) -> Result<ConnectorResponse, AxonFlowError>
pub async fn generate_plan( &self, query: &str, domain: &str, user_token: Option<&str>, ) -> Result<PlanResponse, AxonFlowError>
pub async fn execute_plan( &self, plan_id: &str, user_token: Option<&str>, ) -> Result<PlanExecutionResponse, AxonFlowError>
pub async fn get_plan_status( &self, plan_id: &str, ) -> Result<PlanExecutionResponse, AxonFlowError>
pub async fn cancel_plan( &self, plan_id: &str, reason: Option<&str>, ) -> Result<CancelPlanResponse, AxonFlowError>
pub async fn audit_llm_call( &self, req: &AuditRequest, ) -> Result<AuditResult, AxonFlowError>
Source§impl AxonFlowClient
impl AxonFlowClient
Sourcepub async fn explain_decision(
&self,
decision_id: &str,
) -> Result<DecisionExplanation, AxonFlowError>
pub async fn explain_decision( &self, decision_id: &str, ) -> Result<DecisionExplanation, AxonFlowError>
Fetches the full explanation for a previously-made policy decision.
The caller must either own the decision (X-User-Email match) or belong to the same tenant as the decision (X-Tenant-ID match). Returns an error wrapping HTTP 404 when the decision is past the tier’s audit retention window.
§Example
let client = AxonFlowClient::new(AxonFlowConfig::new("http://localhost:8080"))?;
let exp = client.explain_decision("dec_wf123_step4").await?;
if exp.override_available {
// Surface a "request override" UI affordance
}Sourcepub async fn list_decisions(
&self,
opts: ListDecisionsOptions,
) -> Result<Vec<DecisionSummary>, AxonFlowError>
pub async fn list_decisions( &self, opts: ListDecisionsOptions, ) -> Result<Vec<DecisionSummary>, AxonFlowError>
Lists recent policy decisions for the caller’s tenant.
Returns the slim 5-field DecisionSummary page; the platform
applies a tier-gated cap (5/24h on Free + Community, 100/30d on
Pro + Evaluation, 1000/full on Enterprise). Requesting a limit
above the tier cap yields a 429 with the V1 upgrade envelope —
surfaced here as AxonFlowError::RateLimited so callers can
branch on envelope.upgrade.{tier,compare_url,buy_url} without
re-parsing the body.
Filters compose: passing decision = Some("deny") AND
policy_id = Some("pol-sqli") returns only deny decisions
matching that policy. since is RFC3339 (chrono DateTime<Utc>).
§Example
let client = AxonFlowClient::new(AxonFlowConfig::new("http://localhost:8080"))?;
let opts = ListDecisionsOptions {
decision: Some("deny".into()),
limit: Some(10),
..Default::default()
};
let decisions = client.list_decisions(opts).await?;
for d in decisions {
println!("{} {} {}", d.decision_id, d.decision, d.timestamp);
}Source§impl AxonFlowClient
impl AxonFlowClient
Sourcepub async fn list_hitl_queue(
&self,
opts: HITLQueueListOptions,
) -> Result<HITLQueueListResponse, AxonFlowError>
pub async fn list_hitl_queue( &self, opts: HITLQueueListOptions, ) -> Result<HITLQueueListResponse, AxonFlowError>
Lists approval requests in the HITL queue.
Enterprise Feature: Requires AxonFlow Enterprise license.
§Example
let client = AxonFlowClient::new(AxonFlowConfig::new("http://localhost:8080"))?;
let opts = HITLQueueListOptions {
status: Some("pending".into()),
severity: Some("high,critical".into()),
limit: Some(20),
..Default::default()
};
let page = client.list_hitl_queue(opts).await?;
println!("{} of {} pending HITL approvals", page.items.len(), page.total);Sourcepub async fn get_hitl_request(
&self,
request_id: &str,
) -> Result<HITLApprovalRequest, AxonFlowError>
pub async fn get_hitl_request( &self, request_id: &str, ) -> Result<HITLApprovalRequest, AxonFlowError>
Gets a specific HITL approval request by ID.
Enterprise Feature: Requires AxonFlow Enterprise license.
Sourcepub async fn create_hitl_request(
&self,
input: HITLCreateInput,
) -> Result<HITLApprovalRequest, AxonFlowError>
pub async fn create_hitl_request( &self, input: HITLCreateInput, ) -> Result<HITLApprovalRequest, AxonFlowError>
Creates a new HITL approval request via POST /api/v1/hitl/queue.
Enterprise Feature: Requires AxonFlow Enterprise license. The
platform returns 403 with ErrHITLApprovalDisabledByTier when
called against a community tier that hasn’t enabled HITL, and
401 when credentials are invalid.
This is the explicit row-creation step for callers that detect
require_approval from a separate gate (pre_check,
check_tool_input, MAP plan approvals) and want the row
enqueued so a reviewer can act on it. After creating, either
poll get_hitl_request until terminal
state, or supply
HITLCreateInput::notify_url
so the platform fires a signed webhook on the transition (n8n
Wait-node “On Webhook Call” pattern, ADK plugin polling-free
mode).
client_id, original_query, and request_type are required;
all other fields are optional. Bad notify_url schemes are
rejected by the platform with HTTP 400 (surfaced here as
AxonFlowError::ApiError with status = 400); only https://
(and http:// for self-hosted local-dev) are accepted.
§Example
let client = AxonFlowClient::new(AxonFlowConfig::new("http://localhost:8080"))?;
let req = client
.create_hitl_request(HITLCreateInput {
client_id: "loan-desk".into(),
original_query: "disburse $50000 to cust-001".into(),
request_type: "adk-tool".into(),
triggered_policy_id: Some("loan-amount-cap".into()),
triggered_policy_name: Some("Loan amount cap".into()),
trigger_reason: Some(
"Disbursement above $10k requires manager approval".into(),
),
severity: Some("high".into()),
notify_url: Some(
"https://workflows.example.com/hooks/loan-approve".into(),
),
..Default::default()
})
.await?;
println!("Created HITL approval {}", req.request_id);Sourcepub async fn approve_hitl_request(
&self,
request_id: &str,
review: HITLReviewInput,
) -> Result<(), AxonFlowError>
pub async fn approve_hitl_request( &self, request_id: &str, review: HITLReviewInput, ) -> Result<(), AxonFlowError>
Approves a pending HITL approval request.
Enterprise Feature: Requires AxonFlow Enterprise license.
Sourcepub async fn reject_hitl_request(
&self,
request_id: &str,
review: HITLReviewInput,
) -> Result<(), AxonFlowError>
pub async fn reject_hitl_request( &self, request_id: &str, review: HITLReviewInput, ) -> Result<(), AxonFlowError>
Rejects a pending HITL approval request.
Enterprise Feature: Requires AxonFlow Enterprise license.
Sourcepub async fn get_hitl_stats(&self) -> Result<HITLStats, AxonFlowError>
pub async fn get_hitl_stats(&self) -> Result<HITLStats, AxonFlowError>
Gets HITL queue dashboard statistics.
Enterprise Feature: Requires AxonFlow Enterprise license.
Source§impl AxonFlowClient
impl AxonFlowClient
Sourcepub async fn decide(
&self,
request: DecideRequest,
) -> Result<DecideResponse, AxonFlowError>
pub async fn decide( &self, request: DecideRequest, ) -> Result<DecideResponse, AxonFlowError>
Ask the PDP for a verdict on a request (POST /api/v1/decide).
This is the PDP step of a PEP. /decide is a pure decision point: it
NEVER mutates content. When an allow verdict carries a redact_pii
obligation, discharge it with fulfill_request
(or use the one-call decide_and_fulfill) —
never by redacting locally.
Decision Mode auth is HTTP Basic (org:license), which this client already
sends on every request. Demo / wrong credentials are refused with HTTP
401 → AxonFlowError::ApiError with status: 401. A deny verdict is
returned in the body with HTTP 200, not as an error.
§Errors
AxonFlowError::ApiErrorwithstatus: 401for bad / demo creds.AxonFlowError::ApiErrorfor other non-2xx responses.AxonFlowError::HttpErrorfor transport failures.
§Example
let client = AxonFlowClient::new(
AxonFlowConfig::new("http://localhost:8080").with_auth("org", "license"))?;
let decision = client.decide(DecideRequest::new("tool", "send to a@b.com")).await?;
println!("{}", decision.verdict);Sourcepub async fn fulfill_request(
&self,
decision: &DecideResponse,
statement: &str,
) -> Result<(String, bool), AxonFlowError>
pub async fn fulfill_request( &self, decision: &DecideResponse, statement: &str, ) -> Result<(String, bool), AxonFlowError>
Discharge every request-phase redact_pii obligation on decision.
For each request-phase redact_pii obligation, POSTs statement to the
engine endpoint the obligation names (check-input) and returns the
engine-redacted statement to forward.
There is NO code path in which this method redacts locally — fulfillment is always the engine round-trip (ADR-056 / #2563).
Returns (content, did_redact). content is the engine-redacted
statement (or the original when no obligation mutates the request).
did_redact reflects whether the ENGINE actually changed the content,
not merely that an obligation was present.
§Errors
AxonFlowError::ObligationNotFulfillable when a redact_pii obligation
cannot be discharged through the engine: it named no request-phase
fulfillment, advertised a content-type the PEP is not holding, named an
endpoint this client will not call, the engine call failed / returned
non-200, or the engine reported the redactor did not run
(redaction_evaluated=false). The caller MUST fail closed (block) —
never forward the original statement.
Sourcepub async fn decide_and_fulfill(
&self,
request: DecideRequest,
) -> Result<(String, String, DecideResponse), AxonFlowError>
pub async fn decide_and_fulfill( &self, request: DecideRequest, ) -> Result<(String, String, DecideResponse), AxonFlowError>
One-call PEP path: decide, then fulfill any request-phase obligation.
Returns (verdict, content, decision). Branch on verdict: forward
content on "allow"; block on "deny" / "needs_approval".
On the not-fulfillable path this returns
AxonFlowError::ObligationNotFulfillable — a caller that handles the
error cannot accidentally forward the unredacted query, so fail-closed is
guaranteed by construction (#2563 L2). The original query is returned as
content only on the non-allow path (where the caller blocks anyway).
§Errors
Propagates Self::decide errors, and
AxonFlowError::ObligationNotFulfillable from Self::fulfill_request.
Trait Implementations§
Source§impl Clone for AxonFlowClient
impl Clone for AxonFlowClient
Source§fn clone(&self) -> AxonFlowClient
fn clone(&self) -> AxonFlowClient
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more