boundflow 0.6.0__tar.gz → 0.7.0.dev7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/PKG-INFO +1 -1
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/cli/commands/policies.py +20 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/control_plane.py +33 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/ui/labels.py +2 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/ui/render.py +11 -5
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/ui/server.py +9 -3
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/ui/views.py +137 -1
- boundflow-0.7.0.dev7/boundflow/v1/lifecycle_pb2.py +201 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/lifecycle_pb2_grpc.py +43 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow.egg-info/PKG-INFO +1 -1
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/pyproject.toml +1 -1
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_interrupted_run_metrics.py +29 -7
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_ui_console.py +187 -3
- boundflow-0.6.0/boundflow/v1/lifecycle_pb2.py +0 -195
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/LICENSE +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/__init__.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/_transport.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/anthropic_client.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/cli/__init__.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/cli/__main__.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/cli/_client.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/cli/commands/__init__.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/cli/commands/audit.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/cli/commands/pricing.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/cli/commands/tenants.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/cli/commands/workflows.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/cli/output.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/errors.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/examples/__init__.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/examples/approval_gate.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/examples/governed_langgraph.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/examples/hello.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/examples/langchain_adapter.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/examples/langgraph_workflow.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/examples/model_switching.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/examples/runtime_caps.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/examples/self_healing.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/governed.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/langchain_client.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/lifecycle.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/llm.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/policies.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/trace.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/ui/__init__.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/__init__.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/agent_policy_pb2.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/agent_policy_pb2_grpc.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/operation_pb2.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/operation_pb2_grpc.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/policy_pb2.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/policy_pb2_grpc.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/pricing_pb2.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/pricing_pb2_grpc.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/registration_pb2.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/registration_pb2_grpc.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/tenant_group_pb2.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/tenant_group_pb2_grpc.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/tenant_pb2.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/tenant_pb2_grpc.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/worker_pb2.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/worker_pb2_grpc.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/workflow_pb2.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/v1/workflow_pb2_grpc.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow/worker.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow.egg-info/SOURCES.txt +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow.egg-info/dependency_links.txt +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow.egg-info/entry_points.txt +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow.egg-info/requires.txt +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/boundflow.egg-info/top_level.txt +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/setup.cfg +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_agent_call_timeout.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_agent_lifecycle_policy.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_agent_metrics_latency.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_agent_policy_audit.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_approval_audit.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_approval_gate.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_await_input.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_capability_routing.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_complete_result.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_cooldown_and_resume.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_custom_runtime_policy.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_delayed_next.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_delete_tenant.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_delete_workflow.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_get_workflow.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_get_workflow_metrics.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_governed_model.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_governed_model_e2e.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_interim_metrics.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_invoke_context.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_invoke_mode.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_langchain_client.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_lifecycle_states.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_list_tenants.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_list_workflows.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_max_tokens_per_call.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_metrics_epoch_isolation.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_mock_llm.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_model_pricing.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_operation_context_ids.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_orchestrator_call_caps.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_orphaned_job_recovery.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_otel_sink.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_pending_approval.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_periodic_workflow.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_policy_audit.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_policy_getters.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_request_info.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_resolve_interrupted_workflow.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_resumable_workflow.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_run_agent_budget.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_run_agent_budget_e2e.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_set_workflow_config.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_suspend_parked_gate.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_suspend_resume.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_tenant_purge_reconciler.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_tool_call_limits.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_tool_failure_limits.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_trace.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_workflow_lifecycle_policy.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_workflow_purge_reconciler.py +0 -0
- {boundflow-0.6.0 → boundflow-0.7.0.dev7}/tests/test_workflow_runs.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boundflow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0.dev7
|
|
4
4
|
Summary: BoundFlow Python SDK — build governed fleets of agents against a self-hostable control plane.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Keywords: agents,llm,orchestration,control-plane,governance
|
|
@@ -83,6 +83,26 @@ def runtime_set(
|
|
|
83
83
|
success(f"Runtime policy set on {workflow_id} / {agent_name}.")
|
|
84
84
|
|
|
85
85
|
|
|
86
|
+
@app.command("agents")
|
|
87
|
+
def list_agents(
|
|
88
|
+
workflow_id: str = typer.Argument(..., help="Workflow ID"),
|
|
89
|
+
):
|
|
90
|
+
"""List a workflow's agents and their armed policies.
|
|
91
|
+
|
|
92
|
+
Every other agent command needs a name; this is where the names come from.
|
|
93
|
+
"""
|
|
94
|
+
agents = cp_call(lambda cp: cp.list_agents(workflow_id))
|
|
95
|
+
output([
|
|
96
|
+
{
|
|
97
|
+
"agent_name": a.agent_name,
|
|
98
|
+
"runtime_policy": a.runtime_policy or {},
|
|
99
|
+
"lifecycle_policy": a.lifecycle_policy or {},
|
|
100
|
+
"updated_at": a.updated_at,
|
|
101
|
+
}
|
|
102
|
+
for a in agents
|
|
103
|
+
])
|
|
104
|
+
|
|
105
|
+
|
|
86
106
|
@app.command("get-runtime")
|
|
87
107
|
def runtime_get(
|
|
88
108
|
workflow_id: str = typer.Argument(..., help="Workflow ID"),
|
|
@@ -364,6 +364,20 @@ class InputAuditRecord:
|
|
|
364
364
|
prompt: str = ""
|
|
365
365
|
|
|
366
366
|
|
|
367
|
+
@dataclass
|
|
368
|
+
class Agent:
|
|
369
|
+
"""One agent the server knows about, from `list_agents`.
|
|
370
|
+
|
|
371
|
+
A row exists once an agent has run or had a policy set, so an empty policy means
|
|
372
|
+
none is armed — not that the agent is unknown. Policies are dicts rather than
|
|
373
|
+
typed objects because the server stores them opaquely.
|
|
374
|
+
"""
|
|
375
|
+
agent_name: str
|
|
376
|
+
runtime_policy: dict
|
|
377
|
+
lifecycle_policy: dict
|
|
378
|
+
updated_at: datetime | None
|
|
379
|
+
|
|
380
|
+
|
|
367
381
|
@dataclass
|
|
368
382
|
class PolicyActionRecord:
|
|
369
383
|
"""One workflow-lifecycle policy firing. Self-describing: the rule that fired
|
|
@@ -983,6 +997,25 @@ class ControlPlaneClient:
|
|
|
983
997
|
metadata=self._metadata)
|
|
984
998
|
return [_workflow_rule_from_proto(r) for r in resp.lifecycle_policy.rules]
|
|
985
999
|
|
|
1000
|
+
async def list_agents(self, workflow_id: str) -> list[Agent]:
|
|
1001
|
+
"""Every agent the server knows about for a workflow, sorted by name.
|
|
1002
|
+
|
|
1003
|
+
The other agent getters all take an agent_name the caller is assumed to
|
|
1004
|
+
already know, which only works for whoever wrote the workflow. This is how
|
|
1005
|
+
anyone else discovers them.
|
|
1006
|
+
"""
|
|
1007
|
+
resp = await self._lc.ListAgents(
|
|
1008
|
+
lc.ListAgentsRequest(workflow_id=workflow_id), metadata=self._metadata)
|
|
1009
|
+
return [
|
|
1010
|
+
Agent(
|
|
1011
|
+
agent_name=a.agent_name,
|
|
1012
|
+
runtime_policy=MessageToDict(a.runtime_policy),
|
|
1013
|
+
lifecycle_policy=MessageToDict(a.lifecycle_policy),
|
|
1014
|
+
updated_at=_ts(a, "updated_at"),
|
|
1015
|
+
)
|
|
1016
|
+
for a in resp.agents
|
|
1017
|
+
]
|
|
1018
|
+
|
|
986
1019
|
async def get_agent_runtime_policy(self, workflow_id: str, agent_name: str) -> dict:
|
|
987
1020
|
"""The armed runtime policy (hard caps + model override) for one agent, as a dict.
|
|
988
1021
|
Empty dict if none is set."""
|
|
@@ -44,6 +44,7 @@ class Labels:
|
|
|
44
44
|
deleted: str = "Deleted"
|
|
45
45
|
metrics: str = "Metrics"
|
|
46
46
|
audit: str = "Audit"
|
|
47
|
+
policies: str = "Policies"
|
|
47
48
|
abandon: str = "Abandon queued runs"
|
|
48
49
|
danger: str = "Delete"
|
|
49
50
|
|
|
@@ -52,6 +53,7 @@ class Labels:
|
|
|
52
53
|
empty_fleet: str = "No workflows yet."
|
|
53
54
|
empty_runs: str = "No runs yet."
|
|
54
55
|
empty_holds: str = "Nothing is held."
|
|
56
|
+
empty_policies: str = "No policy armed."
|
|
55
57
|
empty_deleted: str = "Nothing deleted."
|
|
56
58
|
|
|
57
59
|
|
|
@@ -140,7 +140,7 @@ a{color:inherit;text-decoration:none}
|
|
|
140
140
|
.wrap{display:grid;grid-template-columns:190px 1fr;min-height:100vh}
|
|
141
141
|
aside{background:var(--panel);border-right:1px solid var(--line);padding:14px 0;
|
|
142
142
|
display:flex;flex-direction:column}
|
|
143
|
-
aside .brand{padding:0 16px 14px;font-size:
|
|
143
|
+
aside .brand{padding:0 16px 14px;font-size:15px;font-weight:700;letter-spacing:.06em;
|
|
144
144
|
color:var(--acc);text-transform:uppercase}
|
|
145
145
|
aside nav a{display:flex;justify-content:space-between;padding:6px 16px;color:var(--dim)}
|
|
146
146
|
aside nav a:hover{background:var(--sel);color:var(--fg)}
|
|
@@ -152,15 +152,15 @@ aside .foot{margin-top:auto;padding:12px 16px 0;border-top:1px solid var(--line)
|
|
|
152
152
|
main{display:flex;flex-direction:column;min-width:0}
|
|
153
153
|
.bar{display:flex;align-items:center;gap:10px;padding:9px 16px;
|
|
154
154
|
border-bottom:1px solid var(--line);background:var(--panel)}
|
|
155
|
-
.bar .ctx{color:var(--acc);font-weight:
|
|
155
|
+
.bar .ctx{color:var(--acc);font-weight:700;font-size:14px;white-space:nowrap}
|
|
156
156
|
.bar input{flex:1;background:var(--bg);border:1px solid var(--line);border-radius:3px;
|
|
157
157
|
color:var(--fg);font:inherit;padding:4px 8px;min-width:0}
|
|
158
158
|
.bar input::placeholder{color:var(--dim)}
|
|
159
159
|
.body{padding:14px 16px;overflow:auto;flex:1}
|
|
160
|
-
h2{font-size:
|
|
161
|
-
margin:
|
|
160
|
+
h2{font-size:13px;text-transform:uppercase;letter-spacing:.1em;color:var(--fg);
|
|
161
|
+
margin:26px 0 10px;font-weight:700}
|
|
162
162
|
h2:first-child{margin-top:0}
|
|
163
|
-
h3{font-size:13px;margin:
|
|
163
|
+
h3{font-size:13px;margin:16px 0 6px;font-weight:600}
|
|
164
164
|
table{border-collapse:collapse;width:100%}
|
|
165
165
|
th a{color:inherit}
|
|
166
166
|
th a:hover{color:var(--acc)}
|
|
@@ -176,6 +176,12 @@ tbody tr.cur{background:var(--sel);box-shadow:inset 2px 0 0 var(--acc)}
|
|
|
176
176
|
.pill.good{color:var(--good)}.pill.bad{color:var(--bad)}
|
|
177
177
|
.pill.warn{color:var(--warn)}.pill.info{color:var(--info)}
|
|
178
178
|
.muted,.dim{color:var(--dim)}
|
|
179
|
+
.chip{display:inline-block;padding:1px 7px;margin:1px 3px 1px 0;border-radius:2px;
|
|
180
|
+
background:var(--sel);border:1px solid var(--line);font-size:11px;white-space:nowrap}
|
|
181
|
+
.act{color:var(--acc);font-weight:600}
|
|
182
|
+
strong.sub{display:block;font-size:11px;text-transform:uppercase;letter-spacing:.1em;
|
|
183
|
+
color:var(--fg);margin-bottom:9px;font-weight:700}
|
|
184
|
+
.card td{white-space:normal}
|
|
179
185
|
.card{background:var(--panel);border:1px solid var(--line);
|
|
180
186
|
border-left:2px solid var(--warn);padding:12px 14px;margin-bottom:10px}
|
|
181
187
|
dl{display:grid;grid-template-columns:minmax(110px,auto) 1fr;gap:3px 18px;margin:0}
|
|
@@ -248,21 +248,26 @@ def build_app(console: Console):
|
|
|
248
248
|
return failed(request, console.labels.workflow.capitalize(), exc)
|
|
249
249
|
# Every panel is optional: a workflow with a broken metrics read still has
|
|
250
250
|
# to render, because the page is how an operator finds out what is wrong.
|
|
251
|
-
runs, metrics, audit, policies = await asyncio.gather(
|
|
251
|
+
runs, metrics, audit, policies, wf_policy, agents = await asyncio.gather(
|
|
252
252
|
console.cp.list_workflow_runs(wid),
|
|
253
253
|
console.cp.get_workflow_metrics(wid),
|
|
254
254
|
console.cp.get_audit_log(wid),
|
|
255
255
|
console.cp.get_workflow_policy_audit(wid),
|
|
256
|
+
console.cp.get_workflow_lifecycle_policy(wid),
|
|
257
|
+
console.cp.list_agents(wid),
|
|
256
258
|
return_exceptions=True,
|
|
257
259
|
)
|
|
258
260
|
for name, value in (("runs", runs), ("metrics", metrics),
|
|
259
|
-
("audit", audit), ("policy audit", policies)
|
|
261
|
+
("audit", audit), ("policy audit", policies),
|
|
262
|
+
("lifecycle policy", wf_policy), ("agents", agents)):
|
|
260
263
|
if isinstance(value, BaseException):
|
|
261
264
|
log.warning("could not load %s for %s", name, wid, exc_info=value)
|
|
262
265
|
runs = [] if isinstance(runs, BaseException) else runs
|
|
263
266
|
metrics = None if isinstance(metrics, BaseException) else metrics
|
|
264
267
|
audit = [] if isinstance(audit, BaseException) else audit
|
|
265
268
|
policies = [] if isinstance(policies, BaseException) else policies
|
|
269
|
+
wf_policy = [] if isinstance(wf_policy, BaseException) else wf_policy
|
|
270
|
+
agents = [] if isinstance(agents, BaseException) else agents
|
|
266
271
|
|
|
267
272
|
# The decision that put the workflow in its current state, so the callout can
|
|
268
273
|
# say what crossed rather than only that something did.
|
|
@@ -270,7 +275,8 @@ def build_app(console: Console):
|
|
|
270
275
|
(p for p in policies
|
|
271
276
|
if p.request_id == workflow.last_policy_decision_request_id), None)
|
|
272
277
|
return render(wid, views.workflow_detail(workflow, runs, metrics,
|
|
273
|
-
console.labels, audit, decision
|
|
278
|
+
console.labels, audit, decision,
|
|
279
|
+
wf_policy, agents),
|
|
274
280
|
request, current="", filterable=False)
|
|
275
281
|
|
|
276
282
|
async def act(request, fn):
|
|
@@ -519,9 +519,144 @@ def audit_table(records: list[Any], lb: Labels = DEFAULT) -> str:
|
|
|
519
519
|
empty="Nothing recorded yet.")
|
|
520
520
|
|
|
521
521
|
|
|
522
|
+
def _duration(seconds: int) -> str:
|
|
523
|
+
if seconds % 3600 == 0 and seconds >= 3600:
|
|
524
|
+
return f"{seconds // 3600}h"
|
|
525
|
+
if seconds % 60 == 0 and seconds >= 60:
|
|
526
|
+
return f"{seconds // 60}m"
|
|
527
|
+
return f"{seconds}s"
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
def _threshold(metric: str, value: Any) -> str:
|
|
531
|
+
"""Thresholds are bare numbers on the wire; a cost of 5 and a count of 5 read the
|
|
532
|
+
same without their unit."""
|
|
533
|
+
metric = fmt(metric)
|
|
534
|
+
if metric == "cost":
|
|
535
|
+
return f"${float(value):,.2f}"
|
|
536
|
+
if metric == "latency":
|
|
537
|
+
return _duration(int(float(value)))
|
|
538
|
+
if metric == "tool_failure_rate":
|
|
539
|
+
return f"{float(value) * 100:g}%"
|
|
540
|
+
return fmt(value)
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
def _action(action: Any) -> str:
|
|
544
|
+
"""A workflow policy action, in words. The window is a column of its own, so it
|
|
545
|
+
isn't repeated here.
|
|
546
|
+
|
|
547
|
+
These are dataclasses, so letting them fall through to str() put a Python repr —
|
|
548
|
+
`kind='cooldown' window=10 seconds=1800` — on the page.
|
|
549
|
+
"""
|
|
550
|
+
kind = fmt(getattr(action, "kind", action))
|
|
551
|
+
if kind == "cooldown":
|
|
552
|
+
return f"cool down {_duration(getattr(action, 'seconds', 0))}"
|
|
553
|
+
if kind == "pause":
|
|
554
|
+
return "pause"
|
|
555
|
+
if kind == "set_version":
|
|
556
|
+
return f"roll back to version {fmt(getattr(action, 'target', ''))}"
|
|
557
|
+
return kind
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
def _window(n: Any) -> str:
|
|
561
|
+
n = int(n or 0)
|
|
562
|
+
if not n:
|
|
563
|
+
return "—"
|
|
564
|
+
return f"{n} run" if n == 1 else f"{n} runs"
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
def _agent_rule_rows(agents: list[Any]) -> list[list[str]]:
|
|
568
|
+
"""Agent adaptive rules, one row each, in the same columns as the workflow rules.
|
|
569
|
+
|
|
570
|
+
These arrive as plain dicts, since the server stores the policy opaquely.
|
|
571
|
+
"""
|
|
572
|
+
rows = []
|
|
573
|
+
for a in agents:
|
|
574
|
+
for r in (a.lifecycle_policy or {}).get("rules") or []:
|
|
575
|
+
metric = fmt(r.get("metric"))
|
|
576
|
+
action = r.get("action") or {}
|
|
577
|
+
target = (f"{fmt(action.get('field'))} = {fmt(action.get('value'))}"
|
|
578
|
+
if isinstance(action, dict) else fmt(action))
|
|
579
|
+
rows.append([
|
|
580
|
+
f'<span class="mono">{esc(a.agent_name)}</span>',
|
|
581
|
+
f'<span class="chip">{esc(metric)}</span>',
|
|
582
|
+
f'{esc(fmt(r.get("op") or "≥"))} '
|
|
583
|
+
f'{esc(_threshold(metric.replace("_usd", ""), r.get("threshold", 0)))}',
|
|
584
|
+
esc(_window(r.get("window"))),
|
|
585
|
+
f'<span class="act">{esc(target)}</span>',
|
|
586
|
+
])
|
|
587
|
+
return rows
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
def _chips(policy: dict) -> str:
|
|
591
|
+
"""An agent's caps as chips rather than a run-on of key: value pairs."""
|
|
592
|
+
if not policy:
|
|
593
|
+
return '<span class="muted">none armed</span>'
|
|
594
|
+
out = []
|
|
595
|
+
for k, v in sorted(policy.items()):
|
|
596
|
+
if v in (0, 0.0, "", None, [], {}):
|
|
597
|
+
continue # unset fields come back as zeroes, not absences
|
|
598
|
+
label = str(k).replace("_", " ")
|
|
599
|
+
if k == "max_cost_usd":
|
|
600
|
+
text = f"cost ≤ ${float(v):,.2f}"
|
|
601
|
+
elif k == "model":
|
|
602
|
+
text = fmt(v)
|
|
603
|
+
elif isinstance(v, (list, dict)):
|
|
604
|
+
text = f"{label} ({len(v)})"
|
|
605
|
+
else:
|
|
606
|
+
text = f"{label} {fmt(v)}"
|
|
607
|
+
out.append(f'<span class="chip">{esc(text)}</span>')
|
|
608
|
+
return " ".join(out) or '<span class="muted">none armed</span>'
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
def policies_section(workflow_policy: Any, agents: list[Any],
|
|
612
|
+
lb: Labels = DEFAULT) -> str:
|
|
613
|
+
"""What is actually armed on this workflow and its agents.
|
|
614
|
+
|
|
615
|
+
The console could say a lifecycle policy had paused a workflow without ever
|
|
616
|
+
showing the rule that did it. Agents are listed even when nothing is armed,
|
|
617
|
+
because "this agent has no caps" is itself worth seeing on a governance screen —
|
|
618
|
+
and it's the row you'd most want to catch.
|
|
619
|
+
"""
|
|
620
|
+
rules = workflow_policy or []
|
|
621
|
+
if rules:
|
|
622
|
+
wf_rows = [
|
|
623
|
+
[f'<span class="chip">{esc(fmt(getattr(r, "metric", "")))}</span>',
|
|
624
|
+
f'≥ {_threshold(getattr(r, "metric", ""), getattr(r, "threshold", 0))}',
|
|
625
|
+
esc(_window(getattr(getattr(r, "action", None), "window", 0))),
|
|
626
|
+
esc(getattr(r, "tool", "") or "—"),
|
|
627
|
+
f'<span class="act">{esc(_action(getattr(r, "action", None)))}</span>']
|
|
628
|
+
for r in rules
|
|
629
|
+
]
|
|
630
|
+
wf = table(["when", "crosses", "over", "tool", "then"], wf_rows)
|
|
631
|
+
else:
|
|
632
|
+
wf = f'<p class="muted">{esc(lb.empty_policies)}</p>'
|
|
633
|
+
|
|
634
|
+
if agents:
|
|
635
|
+
caps = table(
|
|
636
|
+
["agent", "caps", "updated"],
|
|
637
|
+
[[f'<span class="mono">{esc(a.agent_name)}</span>',
|
|
638
|
+
_chips(a.runtime_policy), esc(a.updated_at)] for a in agents],
|
|
639
|
+
)
|
|
640
|
+
rule_rows = _agent_rule_rows(agents)
|
|
641
|
+
rules_tbl = table(["agent", "when", "crosses", "over", "then"], rule_rows,
|
|
642
|
+
empty="No adaptive rules armed.")
|
|
643
|
+
else:
|
|
644
|
+
caps = '<p class="muted">No agents have run yet.</p>'
|
|
645
|
+
rules_tbl = caps
|
|
646
|
+
|
|
647
|
+
return (
|
|
648
|
+
f"<h2>{esc(lb.policies)}</h2>"
|
|
649
|
+
f'<div class="card"><strong class="sub">Workflow lifecycle</strong>{wf}</div>'
|
|
650
|
+
f'<div class="card"><strong class="sub">Agent runtime caps</strong>{caps}</div>'
|
|
651
|
+
f'<div class="card"><strong class="sub">Agent lifecycle rules</strong>'
|
|
652
|
+
f'{rules_tbl}</div>'
|
|
653
|
+
)
|
|
654
|
+
|
|
655
|
+
|
|
522
656
|
def workflow_detail(w: WorkflowInfo, runs: list[Any], metrics: Any,
|
|
523
657
|
lb: Labels = DEFAULT, audit: list[Any] | None = None,
|
|
524
|
-
policy: Any = None
|
|
658
|
+
policy: Any = None, workflow_policy: Any = None,
|
|
659
|
+
agents: list[Any] | None = None) -> str:
|
|
525
660
|
gates = approval_form(w) + input_form(w)
|
|
526
661
|
gates_section = f"<h2>{esc(lb.inbox)}</h2>{gates}" if gates else ""
|
|
527
662
|
return (
|
|
@@ -531,6 +666,7 @@ def workflow_detail(w: WorkflowInfo, runs: list[Any], metrics: Any,
|
|
|
531
666
|
f"{status_callout(w, lb, policy)}"
|
|
532
667
|
f"{gates_section}"
|
|
533
668
|
f'<div class="card">{detail_rows(w, skip=("pending_approval", "pending_input"))}</div>'
|
|
669
|
+
f"{policies_section(workflow_policy, agents or [], lb)}"
|
|
534
670
|
f"<h2>{esc(lb.metrics)} (version {esc(w.version)})</h2>"
|
|
535
671
|
f"{metrics_cards(metrics, lb)}"
|
|
536
672
|
f"<h2>{esc(lb.runs).capitalize()}</h2>{runs_table(runs, lb)}"
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
3
|
+
# NO CHECKED-IN PROTOBUF GENCODE
|
|
4
|
+
# source: boundflow/v1/lifecycle.proto
|
|
5
|
+
# Protobuf Python Version: 6.33.5
|
|
6
|
+
"""Generated protocol buffer code."""
|
|
7
|
+
from google.protobuf import descriptor as _descriptor
|
|
8
|
+
from google.protobuf import descriptor_pool as _descriptor_pool
|
|
9
|
+
from google.protobuf import runtime_version as _runtime_version
|
|
10
|
+
from google.protobuf import symbol_database as _symbol_database
|
|
11
|
+
from google.protobuf.internal import builder as _builder
|
|
12
|
+
_runtime_version.ValidateProtobufRuntimeVersion(
|
|
13
|
+
_runtime_version.Domain.PUBLIC,
|
|
14
|
+
6,
|
|
15
|
+
33,
|
|
16
|
+
5,
|
|
17
|
+
'',
|
|
18
|
+
'boundflow/v1/lifecycle.proto'
|
|
19
|
+
)
|
|
20
|
+
# @@protoc_insertion_point(imports)
|
|
21
|
+
|
|
22
|
+
_sym_db = _symbol_database.Default()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
|
|
26
|
+
from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
|
|
27
|
+
from boundflow.v1 import workflow_pb2 as boundflow_dot_v1_dot_workflow__pb2
|
|
28
|
+
from boundflow.v1 import agent_policy_pb2 as boundflow_dot_v1_dot_agent__policy__pb2
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x62oundflow/v1/lifecycle.proto\x12\x0c\x62oundflow.v1\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1b\x62oundflow/v1/workflow.proto\x1a\x1f\x62oundflow/v1/agent_policy.proto\"\xb9\x01\n\x15\x43reateWorkflowRequest\x12\x16\n\x0e\x63orrelation_id\x18\x01 \x01(\t\x12\x15\n\rworkflow_type\x18\x02 \x01(\t\x12\x11\n\ttenant_id\x18\x03 \x01(\t\x12!\n\x19operation_timeout_seconds\x18\x05 \x01(\x05\x12\x35\n\x0fworkflow_config\x18\x06 \x01(\x0b\x32\x1c.boundflow.v1.WorkflowConfigJ\x04\x08\x04\x10\x05\"B\n\x16\x43reateWorkflowResponse\x12(\n\x08workflow\x18\x01 \x01(\x0b\x32\x16.boundflow.v1.Workflow\"\x16\n\x14ListWorkflowsRequest\"B\n\x15ListWorkflowsResponse\x12)\n\tworkflows\x18\x01 \x03(\x0b\x32\x16.boundflow.v1.Workflow\"5\n\x10RuntimeOverrides\x12!\n\x19operation_timeout_seconds\x18\x02 \x01(\x05\"\xb1\x01\n\x15InvokeWorkflowRequest\x12\x16\n\x0e\x63orrelation_id\x18\x01 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x02 \x01(\t\x12\x39\n\x11runtime_overrides\x18\x03 \x01(\x0b\x32\x1e.boundflow.v1.RuntimeOverrides\x12\x30\n\x0finitial_context\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\",\n\x16InvokeWorkflowResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\"\x86\x01\n\x16SuspendWorkflowRequest\x12\x16\n\x0e\x63orrelation_id\x18\x01 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x02 \x01(\t\x12\x0e\n\x06reason\x18\x03 \x01(\t\x12\x18\n\x10stop_current_run\x18\x04 \x01(\x08\x12\x15\n\rsuspension_id\x18\x06 \x01(\t\"0\n\x17SuspendWorkflowResponse\x12\x15\n\rsuspension_id\x18\x01 \x01(\t\"m\n\x1c\x41\x62\x61ndonQueuedRequestsRequest\x12\x16\n\x0e\x63orrelation_id\x18\x01 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x02 \x01(\t\x12\x13\n\x0brequest_ids\x18\x03 \x03(\t\x12\x0b\n\x03\x61ll\x18\x04 \x01(\x08\"4\n\x1d\x41\x62\x61ndonQueuedRequestsResponse\x12\x13\n\x0brequest_ids\x18\x01 \x03(\t\"[\n\x15ResumeWorkflowRequest\x12\x16\n\x0e\x63orrelation_id\x18\x01 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x02 \x01(\t\x12\x15\n\rsuspension_id\x18\x03 \x01(\t\"\x18\n\x16ResumeWorkflowResponse\"g\n\x15\x44\x65leteWorkflowRequest\x12\x16\n\x0e\x63orrelation_id\x18\x01 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x02 \x01(\t\x12!\n\x19operation_timeout_seconds\x18\x03 \x01(\x05\",\n\x16\x44\x65leteWorkflowResponse\x12\x12\n\nrequest_id\x18\x01 \x01(\t\")\n\x12GetWorkflowRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\"?\n\x13GetWorkflowResponse\x12(\n\x08workflow\x18\x01 \x01(\x0b\x32\x16.boundflow.v1.Workflow\"x\n\x1cSetAgentRuntimePolicyRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x12\n\nagent_name\x18\x02 \x01(\t\x12/\n\x0eruntime_policy\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\"\x1f\n\x1dSetAgentRuntimePolicyResponse\"|\n\x1eSetAgentLifecyclePolicyRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x12\n\nagent_name\x18\x02 \x01(\t\x12\x31\n\x10lifecycle_policy\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\"!\n\x1fSetAgentLifecyclePolicyResponse\"=\n\x12\x44\x65leteAgentRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x12\n\nagent_name\x18\x02 \x01(\t\"\x15\n\x13\x44\x65leteAgentResponse\"\x87\x01\n\x1dWorkflowLifecyclePolicyAction\x12\x34\n\x04type\x18\x01 \x01(\x0e\x32&.boundflow.v1.WorkflowPolicyActionType\x12\x18\n\x10\x63ooldown_seconds\x18\x02 \x01(\x05\x12\x16\n\x0etarget_version\x18\x03 \x01(\x05\"\xbe\x01\n\x1bWorkflowLifecyclePolicyRule\x12,\n\x06metric\x18\x01 \x01(\x0e\x32\x1c.boundflow.v1.WorkflowMetric\x12\x11\n\tthreshold\x18\x02 \x01(\x01\x12\x0e\n\x06window\x18\x03 \x01(\x05\x12\x11\n\ttool_name\x18\x04 \x01(\t\x12;\n\x06\x61\x63tion\x18\x05 \x01(\x0b\x32+.boundflow.v1.WorkflowLifecyclePolicyAction\"S\n\x17WorkflowLifecyclePolicy\x12\x38\n\x05rules\x18\x01 \x03(\x0b\x32).boundflow.v1.WorkflowLifecyclePolicyRule\"y\n!SetWorkflowLifecyclePolicyRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12?\n\x10lifecycle_policy\x18\x02 \x01(\x0b\x32%.boundflow.v1.WorkflowLifecyclePolicy\"$\n\"SetWorkflowLifecyclePolicyResponse\"8\n!GetWorkflowLifecyclePolicyRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\"e\n\"GetWorkflowLifecyclePolicyResponse\x12?\n\x10lifecycle_policy\x18\x01 \x01(\x0b\x32%.boundflow.v1.WorkflowLifecyclePolicy\"(\n\x11ListAgentsRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\"9\n\x12ListAgentsResponse\x12#\n\x06\x61gents\x18\x01 \x03(\x0b\x32\x13.boundflow.v1.Agent\"\xaf\x01\n\x05\x41gent\x12\x12\n\nagent_name\x18\x01 \x01(\t\x12/\n\x0eruntime_policy\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x31\n\x10lifecycle_policy\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12.\n\nupdated_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"G\n\x1cGetAgentRuntimePolicyRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x12\n\nagent_name\x18\x02 \x01(\t\"P\n\x1dGetAgentRuntimePolicyResponse\x12/\n\x0eruntime_policy\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\"I\n\x1eGetAgentLifecyclePolicyRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x12\n\nagent_name\x18\x02 \x01(\t\"T\n\x1fGetAgentLifecyclePolicyResponse\x12\x31\n\x10lifecycle_policy\x18\x01 \x01(\x0b\x32\x17.google.protobuf.Struct\"a\n\x16\x41pproveWorkflowRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x13\n\x0b\x61pproval_id\x18\x02 \x01(\t\x12\r\n\x05\x61\x63tor\x18\x03 \x01(\t\x12\x0e\n\x06reason\x18\x04 \x01(\t\"\x19\n\x17\x41pproveWorkflowResponse\"`\n\x15RejectWorkflowRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x13\n\x0b\x61pproval_id\x18\x02 \x01(\t\x12\r\n\x05\x61\x63tor\x18\x03 \x01(\t\x12\x0e\n\x06reason\x18\x04 \x01(\t\"s\n\x12SubmitInputRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x10\n\x08input_id\x18\x02 \x01(\t\x12\'\n\x06\x61nswer\x18\x03 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\r\n\x05\x61\x63tor\x18\x04 \x01(\t\"\x15\n\x13SubmitInputResponse\".\n\x17GetApprovalAuditRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\"N\n\x18GetApprovalAuditResponse\x12\x32\n\x07records\x18\x01 \x03(\x0b\x32!.boundflow.v1.ApprovalAuditRecord\"2\n\x1bGetApprovalAuditByIdRequest\x12\x13\n\x0b\x61pproval_id\x18\x01 \x01(\t\"Q\n\x1cGetApprovalAuditByIdResponse\x12\x31\n\x06record\x18\x01 \x01(\x0b\x32!.boundflow.v1.ApprovalAuditRecord\"+\n\x14GetInputAuditRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\"H\n\x15GetInputAuditResponse\x12/\n\x07records\x18\x01 \x03(\x0b\x32\x1e.boundflow.v1.InputAuditRecord\"4\n\x1dGetWorkflowPolicyAuditRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\"Z\n\x1eGetWorkflowPolicyAuditResponse\x12\x38\n\x07records\x18\x01 \x03(\x0b\x32\'.boundflow.v1.WorkflowPolicyAuditRecord\"E\n\x1aGetAgentPolicyAuditRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x12\n\nagent_name\x18\x02 \x01(\t\"T\n\x1bGetAgentPolicyAuditResponse\x12\x35\n\x07records\x18\x01 \x03(\x0b\x32$.boundflow.v1.AgentPolicyAuditRecord\")\n\x12GetAuditLogRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\"@\n\x13GetAuditLogResponse\x12)\n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x18.boundflow.v1.AuditEntry\"\xff\x01\n\nAuditEntry\x12\x35\n\x08\x61pproval\x18\x01 \x01(\x0b\x32!.boundflow.v1.ApprovalAuditRecordH\x00\x12\x42\n\x0fworkflow_policy\x18\x02 \x01(\x0b\x32\'.boundflow.v1.WorkflowPolicyAuditRecordH\x00\x12<\n\x0c\x61gent_policy\x18\x03 \x01(\x0b\x32$.boundflow.v1.AgentPolicyAuditRecordH\x00\x12/\n\x05input\x18\x04 \x01(\x0b\x32\x1e.boundflow.v1.InputAuditRecordH\x00\x42\x07\n\x05\x65ntry\"\xcb\x02\n\x13\x41pprovalAuditRecord\x12\x13\n\x0b\x61pproval_id\x18\x01 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x02 \x01(\t\x12\x12\n\nrequest_id\x18\x03 \x01(\t\x12\x30\n\x08\x64\x65\x63ision\x18\x04 \x01(\x0e\x32\x1e.boundflow.v1.ApprovalDecision\x12-\n\topened_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\ndecided_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\r\n\x05\x61\x63tor\x18\x07 \x01(\t\x12/\n\x0boccurred_at\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x15\n\rjustification\x18\t \x01(\t\x12\x0e\n\x06reason\x18\n \x01(\t\"\xd4\x02\n\x10InputAuditRecord\x12\x10\n\x08input_id\x18\x01 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x02 \x01(\t\x12\x12\n\nrequest_id\x18\x03 \x01(\t\x12-\n\x08\x64\x65\x63ision\x18\x04 \x01(\x0e\x32\x1b.boundflow.v1.InputDecision\x12-\n\topened_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\ndecided_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\r\n\x05\x61\x63tor\x18\x07 \x01(\t\x12/\n\x0boccurred_at\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\'\n\x06\x61nswer\x18\t \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x0e\n\x06prompt\x18\n \x01(\t\"\x86\x02\n\x19WorkflowPolicyAuditRecord\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x12\n\nrequest_id\x18\x02 \x01(\t\x12\r\n\x05\x61\x63tor\x18\x03 \x01(\t\x12/\n\x0boccurred_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x37\n\x04rule\x18\x05 \x01(\x0b\x32).boundflow.v1.WorkflowLifecyclePolicyRule\x12\x15\n\rtrigger_value\x18\x06 \x01(\x01\x12\x18\n\x10previous_version\x18\x07 \x01(\x05\x12\x16\n\x0eprevious_state\x18\x08 \x01(\t\"\xc6\x01\n\x16\x41gentPolicyAuditRecord\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x12\n\nrequest_id\x18\x02 \x01(\t\x12\r\n\x05\x61\x63tor\x18\x03 \x01(\t\x12/\n\x0boccurred_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nagent_name\x18\x05 \x01(\t\x12/\n\x06\x61\x63tion\x18\x06 \x01(\x0b\x32\x1f.boundflow.v1.AgentPolicyAction\"\x18\n\x16RejectWorkflowResponse\"B\n\x17\x41\x63tivateWorkflowRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x12\n\nrequest_id\x18\x02 \x01(\t\"\x1a\n\x18\x41\x63tivateWorkflowResponse\"L\n!ResolveInterruptedWorkflowRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12\x12\n\nrequest_id\x18\x02 \x01(\t\"$\n\"ResolveInterruptedWorkflowResponse\".\n\x17ListWorkflowRunsRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\"\xce\x01\n\x03Run\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x14\n\x0crequest_type\x18\x02 \x01(\t\x12\x0e\n\x06status\x18\x07 \x01(\t\x12\x13\n\x0brun_outcome\x18\x03 \x01(\t\x12\x16\n\x0e\x66\x61ilure_reason\x18\x04 \x01(\t\x12.\n\ncreated_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0c\x63ompleted_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\";\n\x18ListWorkflowRunsResponse\x12\x1f\n\x04runs\x18\x01 \x03(\x0b\x32\x11.boundflow.v1.Run\"+\n\x15GetRequestInfoRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t\"\xb2\x03\n\x0bRequestInfo\x12\x12\n\nrequest_id\x18\x01 \x01(\t\x12\x13\n\x0bworkflow_id\x18\x02 \x01(\t\x12\x14\n\x0crequest_type\x18\x03 \x01(\t\x12\x0e\n\x06status\x18\x04 \x01(\t\x12\x13\n\x0brun_outcome\x18\x05 \x01(\t\x12\x16\n\x0e\x66\x61ilure_reason\x18\x06 \x01(\t\x12\x0f\n\x07version\x18\x07 \x01(\x03\x12.\n\ncreated_at\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0c\x63ompleted_at\x18\t \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\'\n\x06result\x18\n \x01(\x0b\x32\x17.google.protobuf.Struct\x12/\n\x0einvoke_context\x18\x0b \x01(\x0b\x32\x17.google.protobuf.Struct\x12!\n\x19operation_timeout_seconds\x18\x0c \x01(\x05\x12\x37\n\x16\x61gent_runtime_policies\x18\r \x01(\x0b\x32\x17.google.protobuf.Struct\"D\n\x16GetRequestInfoResponse\x12*\n\x07request\x18\x01 \x01(\x0b\x32\x19.boundflow.v1.RequestInfo\"0\n\x19GetWorkflowMetricsRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\"\xdf\x02\n\x1aGetWorkflowMetricsResponse\x12\x0f\n\x07version\x18\x01 \x01(\x05\x12\x12\n\ntotal_cost\x18\x02 \x01(\x01\x12\x11\n\trun_count\x18\x03 \x01(\x05\x12\x16\n\x0etotal_failures\x18\x04 \x01(\x05\x12\x17\n\x0ftotal_llm_calls\x18\x05 \x01(\x05\x12\x1d\n\x15total_latency_seconds\x18\x06 \x01(\x01\x12!\n\x19total_approval_rejections\x18\x07 \x01(\x05\x12\\\n\x13tool_failure_counts\x18\x08 \x03(\x0b\x32?.boundflow.v1.GetWorkflowMetricsResponse.ToolFailureCountsEntry\x1a\x38\n\x16ToolFailureCountsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"]\n\x18SetWorkflowConfigRequest\x12\x13\n\x0bworkflow_id\x18\x01 \x01(\t\x12,\n\x06\x63onfig\x18\x02 \x01(\x0b\x32\x1c.boundflow.v1.WorkflowConfig\"E\n\x19SetWorkflowConfigResponse\x12(\n\x08workflow\x18\x01 \x01(\x0b\x32\x16.boundflow.v1.Workflow*\xdc\x01\n\x0eWorkflowMetric\x12 \n\x1cWORKFLOW_METRIC_NUM_FAILURES\x10\x00\x12\x18\n\x14WORKFLOW_METRIC_COST\x10\x01\x12!\n\x1dWORKFLOW_METRIC_NUM_LLM_CALLS\x10\x02\x12\x1b\n\x17WORKFLOW_METRIC_LATENCY\x10\x03\x12\'\n#WORKFLOW_METRIC_APPROVAL_REJECTIONS\x10\x04\x12%\n!WORKFLOW_METRIC_TOOL_FAILURE_RATE\x10\x05*\x89\x01\n\x18WorkflowPolicyActionType\x12 \n\x1cWORKFLOW_POLICY_ACTION_PAUSE\x10\x00\x12#\n\x1fWORKFLOW_POLICY_ACTION_COOLDOWN\x10\x01\x12&\n\"WORKFLOW_POLICY_ACTION_SET_VERSION\x10\x02*\x96\x01\n\x10\x41pprovalDecision\x12!\n\x1d\x41PPROVAL_DECISION_UNSPECIFIED\x10\x00\x12\x1e\n\x1a\x41PPROVAL_DECISION_APPROVED\x10\x01\x12\x1e\n\x1a\x41PPROVAL_DECISION_REJECTED\x10\x02\x12\x1f\n\x1b\x41PPROVAL_DECISION_TIMED_OUT\x10\x03*j\n\rInputDecision\x12\x1e\n\x1aINPUT_DECISION_UNSPECIFIED\x10\x00\x12\x1b\n\x17INPUT_DECISION_ANSWERED\x10\x01\x12\x1c\n\x18INPUT_DECISION_TIMED_OUT\x10\x02\x32\xe5\x18\n\x0fWorkflowService\x12[\n\x0e\x43reateWorkflow\x12#.boundflow.v1.CreateWorkflowRequest\x1a$.boundflow.v1.CreateWorkflowResponse\x12[\n\x0eInvokeWorkflow\x12#.boundflow.v1.InvokeWorkflowRequest\x1a$.boundflow.v1.InvokeWorkflowResponse\x12[\n\x0e\x44\x65leteWorkflow\x12#.boundflow.v1.DeleteWorkflowRequest\x1a$.boundflow.v1.DeleteWorkflowResponse\x12^\n\x0fSuspendWorkflow\x12$.boundflow.v1.SuspendWorkflowRequest\x1a%.boundflow.v1.SuspendWorkflowResponse\x12[\n\x0eResumeWorkflow\x12#.boundflow.v1.ResumeWorkflowRequest\x1a$.boundflow.v1.ResumeWorkflowResponse\x12p\n\x15\x41\x62\x61ndonQueuedRequests\x12*.boundflow.v1.AbandonQueuedRequestsRequest\x1a+.boundflow.v1.AbandonQueuedRequestsResponse\x12R\n\x0bGetWorkflow\x12 .boundflow.v1.GetWorkflowRequest\x1a!.boundflow.v1.GetWorkflowResponse\x12X\n\rListWorkflows\x12\".boundflow.v1.ListWorkflowsRequest\x1a#.boundflow.v1.ListWorkflowsResponse\x12p\n\x15SetAgentRuntimePolicy\x12*.boundflow.v1.SetAgentRuntimePolicyRequest\x1a+.boundflow.v1.SetAgentRuntimePolicyResponse\x12v\n\x17SetAgentLifecyclePolicy\x12,.boundflow.v1.SetAgentLifecyclePolicyRequest\x1a-.boundflow.v1.SetAgentLifecyclePolicyResponse\x12R\n\x0b\x44\x65leteAgent\x12 .boundflow.v1.DeleteAgentRequest\x1a!.boundflow.v1.DeleteAgentResponse\x12\x7f\n\x1aSetWorkflowLifecyclePolicy\x12/.boundflow.v1.SetWorkflowLifecyclePolicyRequest\x1a\x30.boundflow.v1.SetWorkflowLifecyclePolicyResponse\x12\x7f\n\x1aGetWorkflowLifecyclePolicy\x12/.boundflow.v1.GetWorkflowLifecyclePolicyRequest\x1a\x30.boundflow.v1.GetWorkflowLifecyclePolicyResponse\x12p\n\x15GetAgentRuntimePolicy\x12*.boundflow.v1.GetAgentRuntimePolicyRequest\x1a+.boundflow.v1.GetAgentRuntimePolicyResponse\x12v\n\x17GetAgentLifecyclePolicy\x12,.boundflow.v1.GetAgentLifecyclePolicyRequest\x1a-.boundflow.v1.GetAgentLifecyclePolicyResponse\x12O\n\nListAgents\x12\x1f.boundflow.v1.ListAgentsRequest\x1a .boundflow.v1.ListAgentsResponse\x12^\n\x0f\x41pproveWorkflow\x12$.boundflow.v1.ApproveWorkflowRequest\x1a%.boundflow.v1.ApproveWorkflowResponse\x12[\n\x0eRejectWorkflow\x12#.boundflow.v1.RejectWorkflowRequest\x1a$.boundflow.v1.RejectWorkflowResponse\x12R\n\x0bSubmitInput\x12 .boundflow.v1.SubmitInputRequest\x1a!.boundflow.v1.SubmitInputResponse\x12\x61\n\x10GetApprovalAudit\x12%.boundflow.v1.GetApprovalAuditRequest\x1a&.boundflow.v1.GetApprovalAuditResponse\x12m\n\x14GetApprovalAuditById\x12).boundflow.v1.GetApprovalAuditByIdRequest\x1a*.boundflow.v1.GetApprovalAuditByIdResponse\x12X\n\rGetInputAudit\x12\".boundflow.v1.GetInputAuditRequest\x1a#.boundflow.v1.GetInputAuditResponse\x12s\n\x16GetWorkflowPolicyAudit\x12+.boundflow.v1.GetWorkflowPolicyAuditRequest\x1a,.boundflow.v1.GetWorkflowPolicyAuditResponse\x12j\n\x13GetAgentPolicyAudit\x12(.boundflow.v1.GetAgentPolicyAuditRequest\x1a).boundflow.v1.GetAgentPolicyAuditResponse\x12R\n\x0bGetAuditLog\x12 .boundflow.v1.GetAuditLogRequest\x1a!.boundflow.v1.GetAuditLogResponse\x12\x61\n\x10\x41\x63tivateWorkflow\x12%.boundflow.v1.ActivateWorkflowRequest\x1a&.boundflow.v1.ActivateWorkflowResponse\x12\x7f\n\x1aResolveInterruptedWorkflow\x12/.boundflow.v1.ResolveInterruptedWorkflowRequest\x1a\x30.boundflow.v1.ResolveInterruptedWorkflowResponse\x12\x61\n\x10ListWorkflowRuns\x12%.boundflow.v1.ListWorkflowRunsRequest\x1a&.boundflow.v1.ListWorkflowRunsResponse\x12[\n\x0eGetRequestInfo\x12#.boundflow.v1.GetRequestInfoRequest\x1a$.boundflow.v1.GetRequestInfoResponse\x12g\n\x12GetWorkflowMetrics\x12\'.boundflow.v1.GetWorkflowMetricsRequest\x1a(.boundflow.v1.GetWorkflowMetricsResponse\x12\x64\n\x11SetWorkflowConfig\x12&.boundflow.v1.SetWorkflowConfigRequest\x1a\'.boundflow.v1.SetWorkflowConfigResponseB=Z;github.com/boundflow/boundflow/gen/boundflow/v1;boundflowv1b\x06proto3')
|
|
32
|
+
|
|
33
|
+
_globals = globals()
|
|
34
|
+
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
35
|
+
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'boundflow.v1.lifecycle_pb2', _globals)
|
|
36
|
+
if not _descriptor._USE_C_DESCRIPTORS:
|
|
37
|
+
_globals['DESCRIPTOR']._loaded_options = None
|
|
38
|
+
_globals['DESCRIPTOR']._serialized_options = b'Z;github.com/boundflow/boundflow/gen/boundflow/v1;boundflowv1'
|
|
39
|
+
_globals['_GETWORKFLOWMETRICSRESPONSE_TOOLFAILURECOUNTSENTRY']._loaded_options = None
|
|
40
|
+
_globals['_GETWORKFLOWMETRICSRESPONSE_TOOLFAILURECOUNTSENTRY']._serialized_options = b'8\001'
|
|
41
|
+
_globals['_WORKFLOWMETRIC']._serialized_start=7503
|
|
42
|
+
_globals['_WORKFLOWMETRIC']._serialized_end=7723
|
|
43
|
+
_globals['_WORKFLOWPOLICYACTIONTYPE']._serialized_start=7726
|
|
44
|
+
_globals['_WORKFLOWPOLICYACTIONTYPE']._serialized_end=7863
|
|
45
|
+
_globals['_APPROVALDECISION']._serialized_start=7866
|
|
46
|
+
_globals['_APPROVALDECISION']._serialized_end=8016
|
|
47
|
+
_globals['_INPUTDECISION']._serialized_start=8018
|
|
48
|
+
_globals['_INPUTDECISION']._serialized_end=8124
|
|
49
|
+
_globals['_CREATEWORKFLOWREQUEST']._serialized_start=172
|
|
50
|
+
_globals['_CREATEWORKFLOWREQUEST']._serialized_end=357
|
|
51
|
+
_globals['_CREATEWORKFLOWRESPONSE']._serialized_start=359
|
|
52
|
+
_globals['_CREATEWORKFLOWRESPONSE']._serialized_end=425
|
|
53
|
+
_globals['_LISTWORKFLOWSREQUEST']._serialized_start=427
|
|
54
|
+
_globals['_LISTWORKFLOWSREQUEST']._serialized_end=449
|
|
55
|
+
_globals['_LISTWORKFLOWSRESPONSE']._serialized_start=451
|
|
56
|
+
_globals['_LISTWORKFLOWSRESPONSE']._serialized_end=517
|
|
57
|
+
_globals['_RUNTIMEOVERRIDES']._serialized_start=519
|
|
58
|
+
_globals['_RUNTIMEOVERRIDES']._serialized_end=572
|
|
59
|
+
_globals['_INVOKEWORKFLOWREQUEST']._serialized_start=575
|
|
60
|
+
_globals['_INVOKEWORKFLOWREQUEST']._serialized_end=752
|
|
61
|
+
_globals['_INVOKEWORKFLOWRESPONSE']._serialized_start=754
|
|
62
|
+
_globals['_INVOKEWORKFLOWRESPONSE']._serialized_end=798
|
|
63
|
+
_globals['_SUSPENDWORKFLOWREQUEST']._serialized_start=801
|
|
64
|
+
_globals['_SUSPENDWORKFLOWREQUEST']._serialized_end=935
|
|
65
|
+
_globals['_SUSPENDWORKFLOWRESPONSE']._serialized_start=937
|
|
66
|
+
_globals['_SUSPENDWORKFLOWRESPONSE']._serialized_end=985
|
|
67
|
+
_globals['_ABANDONQUEUEDREQUESTSREQUEST']._serialized_start=987
|
|
68
|
+
_globals['_ABANDONQUEUEDREQUESTSREQUEST']._serialized_end=1096
|
|
69
|
+
_globals['_ABANDONQUEUEDREQUESTSRESPONSE']._serialized_start=1098
|
|
70
|
+
_globals['_ABANDONQUEUEDREQUESTSRESPONSE']._serialized_end=1150
|
|
71
|
+
_globals['_RESUMEWORKFLOWREQUEST']._serialized_start=1152
|
|
72
|
+
_globals['_RESUMEWORKFLOWREQUEST']._serialized_end=1243
|
|
73
|
+
_globals['_RESUMEWORKFLOWRESPONSE']._serialized_start=1245
|
|
74
|
+
_globals['_RESUMEWORKFLOWRESPONSE']._serialized_end=1269
|
|
75
|
+
_globals['_DELETEWORKFLOWREQUEST']._serialized_start=1271
|
|
76
|
+
_globals['_DELETEWORKFLOWREQUEST']._serialized_end=1374
|
|
77
|
+
_globals['_DELETEWORKFLOWRESPONSE']._serialized_start=1376
|
|
78
|
+
_globals['_DELETEWORKFLOWRESPONSE']._serialized_end=1420
|
|
79
|
+
_globals['_GETWORKFLOWREQUEST']._serialized_start=1422
|
|
80
|
+
_globals['_GETWORKFLOWREQUEST']._serialized_end=1463
|
|
81
|
+
_globals['_GETWORKFLOWRESPONSE']._serialized_start=1465
|
|
82
|
+
_globals['_GETWORKFLOWRESPONSE']._serialized_end=1528
|
|
83
|
+
_globals['_SETAGENTRUNTIMEPOLICYREQUEST']._serialized_start=1530
|
|
84
|
+
_globals['_SETAGENTRUNTIMEPOLICYREQUEST']._serialized_end=1650
|
|
85
|
+
_globals['_SETAGENTRUNTIMEPOLICYRESPONSE']._serialized_start=1652
|
|
86
|
+
_globals['_SETAGENTRUNTIMEPOLICYRESPONSE']._serialized_end=1683
|
|
87
|
+
_globals['_SETAGENTLIFECYCLEPOLICYREQUEST']._serialized_start=1685
|
|
88
|
+
_globals['_SETAGENTLIFECYCLEPOLICYREQUEST']._serialized_end=1809
|
|
89
|
+
_globals['_SETAGENTLIFECYCLEPOLICYRESPONSE']._serialized_start=1811
|
|
90
|
+
_globals['_SETAGENTLIFECYCLEPOLICYRESPONSE']._serialized_end=1844
|
|
91
|
+
_globals['_DELETEAGENTREQUEST']._serialized_start=1846
|
|
92
|
+
_globals['_DELETEAGENTREQUEST']._serialized_end=1907
|
|
93
|
+
_globals['_DELETEAGENTRESPONSE']._serialized_start=1909
|
|
94
|
+
_globals['_DELETEAGENTRESPONSE']._serialized_end=1930
|
|
95
|
+
_globals['_WORKFLOWLIFECYCLEPOLICYACTION']._serialized_start=1933
|
|
96
|
+
_globals['_WORKFLOWLIFECYCLEPOLICYACTION']._serialized_end=2068
|
|
97
|
+
_globals['_WORKFLOWLIFECYCLEPOLICYRULE']._serialized_start=2071
|
|
98
|
+
_globals['_WORKFLOWLIFECYCLEPOLICYRULE']._serialized_end=2261
|
|
99
|
+
_globals['_WORKFLOWLIFECYCLEPOLICY']._serialized_start=2263
|
|
100
|
+
_globals['_WORKFLOWLIFECYCLEPOLICY']._serialized_end=2346
|
|
101
|
+
_globals['_SETWORKFLOWLIFECYCLEPOLICYREQUEST']._serialized_start=2348
|
|
102
|
+
_globals['_SETWORKFLOWLIFECYCLEPOLICYREQUEST']._serialized_end=2469
|
|
103
|
+
_globals['_SETWORKFLOWLIFECYCLEPOLICYRESPONSE']._serialized_start=2471
|
|
104
|
+
_globals['_SETWORKFLOWLIFECYCLEPOLICYRESPONSE']._serialized_end=2507
|
|
105
|
+
_globals['_GETWORKFLOWLIFECYCLEPOLICYREQUEST']._serialized_start=2509
|
|
106
|
+
_globals['_GETWORKFLOWLIFECYCLEPOLICYREQUEST']._serialized_end=2565
|
|
107
|
+
_globals['_GETWORKFLOWLIFECYCLEPOLICYRESPONSE']._serialized_start=2567
|
|
108
|
+
_globals['_GETWORKFLOWLIFECYCLEPOLICYRESPONSE']._serialized_end=2668
|
|
109
|
+
_globals['_LISTAGENTSREQUEST']._serialized_start=2670
|
|
110
|
+
_globals['_LISTAGENTSREQUEST']._serialized_end=2710
|
|
111
|
+
_globals['_LISTAGENTSRESPONSE']._serialized_start=2712
|
|
112
|
+
_globals['_LISTAGENTSRESPONSE']._serialized_end=2769
|
|
113
|
+
_globals['_AGENT']._serialized_start=2772
|
|
114
|
+
_globals['_AGENT']._serialized_end=2947
|
|
115
|
+
_globals['_GETAGENTRUNTIMEPOLICYREQUEST']._serialized_start=2949
|
|
116
|
+
_globals['_GETAGENTRUNTIMEPOLICYREQUEST']._serialized_end=3020
|
|
117
|
+
_globals['_GETAGENTRUNTIMEPOLICYRESPONSE']._serialized_start=3022
|
|
118
|
+
_globals['_GETAGENTRUNTIMEPOLICYRESPONSE']._serialized_end=3102
|
|
119
|
+
_globals['_GETAGENTLIFECYCLEPOLICYREQUEST']._serialized_start=3104
|
|
120
|
+
_globals['_GETAGENTLIFECYCLEPOLICYREQUEST']._serialized_end=3177
|
|
121
|
+
_globals['_GETAGENTLIFECYCLEPOLICYRESPONSE']._serialized_start=3179
|
|
122
|
+
_globals['_GETAGENTLIFECYCLEPOLICYRESPONSE']._serialized_end=3263
|
|
123
|
+
_globals['_APPROVEWORKFLOWREQUEST']._serialized_start=3265
|
|
124
|
+
_globals['_APPROVEWORKFLOWREQUEST']._serialized_end=3362
|
|
125
|
+
_globals['_APPROVEWORKFLOWRESPONSE']._serialized_start=3364
|
|
126
|
+
_globals['_APPROVEWORKFLOWRESPONSE']._serialized_end=3389
|
|
127
|
+
_globals['_REJECTWORKFLOWREQUEST']._serialized_start=3391
|
|
128
|
+
_globals['_REJECTWORKFLOWREQUEST']._serialized_end=3487
|
|
129
|
+
_globals['_SUBMITINPUTREQUEST']._serialized_start=3489
|
|
130
|
+
_globals['_SUBMITINPUTREQUEST']._serialized_end=3604
|
|
131
|
+
_globals['_SUBMITINPUTRESPONSE']._serialized_start=3606
|
|
132
|
+
_globals['_SUBMITINPUTRESPONSE']._serialized_end=3627
|
|
133
|
+
_globals['_GETAPPROVALAUDITREQUEST']._serialized_start=3629
|
|
134
|
+
_globals['_GETAPPROVALAUDITREQUEST']._serialized_end=3675
|
|
135
|
+
_globals['_GETAPPROVALAUDITRESPONSE']._serialized_start=3677
|
|
136
|
+
_globals['_GETAPPROVALAUDITRESPONSE']._serialized_end=3755
|
|
137
|
+
_globals['_GETAPPROVALAUDITBYIDREQUEST']._serialized_start=3757
|
|
138
|
+
_globals['_GETAPPROVALAUDITBYIDREQUEST']._serialized_end=3807
|
|
139
|
+
_globals['_GETAPPROVALAUDITBYIDRESPONSE']._serialized_start=3809
|
|
140
|
+
_globals['_GETAPPROVALAUDITBYIDRESPONSE']._serialized_end=3890
|
|
141
|
+
_globals['_GETINPUTAUDITREQUEST']._serialized_start=3892
|
|
142
|
+
_globals['_GETINPUTAUDITREQUEST']._serialized_end=3935
|
|
143
|
+
_globals['_GETINPUTAUDITRESPONSE']._serialized_start=3937
|
|
144
|
+
_globals['_GETINPUTAUDITRESPONSE']._serialized_end=4009
|
|
145
|
+
_globals['_GETWORKFLOWPOLICYAUDITREQUEST']._serialized_start=4011
|
|
146
|
+
_globals['_GETWORKFLOWPOLICYAUDITREQUEST']._serialized_end=4063
|
|
147
|
+
_globals['_GETWORKFLOWPOLICYAUDITRESPONSE']._serialized_start=4065
|
|
148
|
+
_globals['_GETWORKFLOWPOLICYAUDITRESPONSE']._serialized_end=4155
|
|
149
|
+
_globals['_GETAGENTPOLICYAUDITREQUEST']._serialized_start=4157
|
|
150
|
+
_globals['_GETAGENTPOLICYAUDITREQUEST']._serialized_end=4226
|
|
151
|
+
_globals['_GETAGENTPOLICYAUDITRESPONSE']._serialized_start=4228
|
|
152
|
+
_globals['_GETAGENTPOLICYAUDITRESPONSE']._serialized_end=4312
|
|
153
|
+
_globals['_GETAUDITLOGREQUEST']._serialized_start=4314
|
|
154
|
+
_globals['_GETAUDITLOGREQUEST']._serialized_end=4355
|
|
155
|
+
_globals['_GETAUDITLOGRESPONSE']._serialized_start=4357
|
|
156
|
+
_globals['_GETAUDITLOGRESPONSE']._serialized_end=4421
|
|
157
|
+
_globals['_AUDITENTRY']._serialized_start=4424
|
|
158
|
+
_globals['_AUDITENTRY']._serialized_end=4679
|
|
159
|
+
_globals['_APPROVALAUDITRECORD']._serialized_start=4682
|
|
160
|
+
_globals['_APPROVALAUDITRECORD']._serialized_end=5013
|
|
161
|
+
_globals['_INPUTAUDITRECORD']._serialized_start=5016
|
|
162
|
+
_globals['_INPUTAUDITRECORD']._serialized_end=5356
|
|
163
|
+
_globals['_WORKFLOWPOLICYAUDITRECORD']._serialized_start=5359
|
|
164
|
+
_globals['_WORKFLOWPOLICYAUDITRECORD']._serialized_end=5621
|
|
165
|
+
_globals['_AGENTPOLICYAUDITRECORD']._serialized_start=5624
|
|
166
|
+
_globals['_AGENTPOLICYAUDITRECORD']._serialized_end=5822
|
|
167
|
+
_globals['_REJECTWORKFLOWRESPONSE']._serialized_start=5824
|
|
168
|
+
_globals['_REJECTWORKFLOWRESPONSE']._serialized_end=5848
|
|
169
|
+
_globals['_ACTIVATEWORKFLOWREQUEST']._serialized_start=5850
|
|
170
|
+
_globals['_ACTIVATEWORKFLOWREQUEST']._serialized_end=5916
|
|
171
|
+
_globals['_ACTIVATEWORKFLOWRESPONSE']._serialized_start=5918
|
|
172
|
+
_globals['_ACTIVATEWORKFLOWRESPONSE']._serialized_end=5944
|
|
173
|
+
_globals['_RESOLVEINTERRUPTEDWORKFLOWREQUEST']._serialized_start=5946
|
|
174
|
+
_globals['_RESOLVEINTERRUPTEDWORKFLOWREQUEST']._serialized_end=6022
|
|
175
|
+
_globals['_RESOLVEINTERRUPTEDWORKFLOWRESPONSE']._serialized_start=6024
|
|
176
|
+
_globals['_RESOLVEINTERRUPTEDWORKFLOWRESPONSE']._serialized_end=6060
|
|
177
|
+
_globals['_LISTWORKFLOWRUNSREQUEST']._serialized_start=6062
|
|
178
|
+
_globals['_LISTWORKFLOWRUNSREQUEST']._serialized_end=6108
|
|
179
|
+
_globals['_RUN']._serialized_start=6111
|
|
180
|
+
_globals['_RUN']._serialized_end=6317
|
|
181
|
+
_globals['_LISTWORKFLOWRUNSRESPONSE']._serialized_start=6319
|
|
182
|
+
_globals['_LISTWORKFLOWRUNSRESPONSE']._serialized_end=6378
|
|
183
|
+
_globals['_GETREQUESTINFOREQUEST']._serialized_start=6380
|
|
184
|
+
_globals['_GETREQUESTINFOREQUEST']._serialized_end=6423
|
|
185
|
+
_globals['_REQUESTINFO']._serialized_start=6426
|
|
186
|
+
_globals['_REQUESTINFO']._serialized_end=6860
|
|
187
|
+
_globals['_GETREQUESTINFORESPONSE']._serialized_start=6862
|
|
188
|
+
_globals['_GETREQUESTINFORESPONSE']._serialized_end=6930
|
|
189
|
+
_globals['_GETWORKFLOWMETRICSREQUEST']._serialized_start=6932
|
|
190
|
+
_globals['_GETWORKFLOWMETRICSREQUEST']._serialized_end=6980
|
|
191
|
+
_globals['_GETWORKFLOWMETRICSRESPONSE']._serialized_start=6983
|
|
192
|
+
_globals['_GETWORKFLOWMETRICSRESPONSE']._serialized_end=7334
|
|
193
|
+
_globals['_GETWORKFLOWMETRICSRESPONSE_TOOLFAILURECOUNTSENTRY']._serialized_start=7278
|
|
194
|
+
_globals['_GETWORKFLOWMETRICSRESPONSE_TOOLFAILURECOUNTSENTRY']._serialized_end=7334
|
|
195
|
+
_globals['_SETWORKFLOWCONFIGREQUEST']._serialized_start=7336
|
|
196
|
+
_globals['_SETWORKFLOWCONFIGREQUEST']._serialized_end=7429
|
|
197
|
+
_globals['_SETWORKFLOWCONFIGRESPONSE']._serialized_start=7431
|
|
198
|
+
_globals['_SETWORKFLOWCONFIGRESPONSE']._serialized_end=7500
|
|
199
|
+
_globals['_WORKFLOWSERVICE']._serialized_start=8127
|
|
200
|
+
_globals['_WORKFLOWSERVICE']._serialized_end=11300
|
|
201
|
+
# @@protoc_insertion_point(module_scope)
|
|
@@ -109,6 +109,11 @@ class WorkflowServiceStub:
|
|
|
109
109
|
request_serializer=boundflow_dot_v1_dot_lifecycle__pb2.GetAgentLifecyclePolicyRequest.SerializeToString,
|
|
110
110
|
response_deserializer=boundflow_dot_v1_dot_lifecycle__pb2.GetAgentLifecyclePolicyResponse.FromString,
|
|
111
111
|
_registered_method=True)
|
|
112
|
+
self.ListAgents = channel.unary_unary(
|
|
113
|
+
'/boundflow.v1.WorkflowService/ListAgents',
|
|
114
|
+
request_serializer=boundflow_dot_v1_dot_lifecycle__pb2.ListAgentsRequest.SerializeToString,
|
|
115
|
+
response_deserializer=boundflow_dot_v1_dot_lifecycle__pb2.ListAgentsResponse.FromString,
|
|
116
|
+
_registered_method=True)
|
|
112
117
|
self.ApproveWorkflow = channel.unary_unary(
|
|
113
118
|
'/boundflow.v1.WorkflowService/ApproveWorkflow',
|
|
114
119
|
request_serializer=boundflow_dot_v1_dot_lifecycle__pb2.ApproveWorkflowRequest.SerializeToString,
|
|
@@ -289,6 +294,12 @@ class WorkflowServiceServicer:
|
|
|
289
294
|
context.set_details('Method not implemented!')
|
|
290
295
|
raise NotImplementedError('Method not implemented!')
|
|
291
296
|
|
|
297
|
+
def ListAgents(self, request, context):
|
|
298
|
+
"""Missing associated documentation comment in .proto file."""
|
|
299
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
300
|
+
context.set_details('Method not implemented!')
|
|
301
|
+
raise NotImplementedError('Method not implemented!')
|
|
302
|
+
|
|
292
303
|
def ApproveWorkflow(self, request, context):
|
|
293
304
|
"""Missing associated documentation comment in .proto file."""
|
|
294
305
|
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
@@ -459,6 +470,11 @@ def add_WorkflowServiceServicer_to_server(servicer, server):
|
|
|
459
470
|
request_deserializer=boundflow_dot_v1_dot_lifecycle__pb2.GetAgentLifecyclePolicyRequest.FromString,
|
|
460
471
|
response_serializer=boundflow_dot_v1_dot_lifecycle__pb2.GetAgentLifecyclePolicyResponse.SerializeToString,
|
|
461
472
|
),
|
|
473
|
+
'ListAgents': grpc.unary_unary_rpc_method_handler(
|
|
474
|
+
servicer.ListAgents,
|
|
475
|
+
request_deserializer=boundflow_dot_v1_dot_lifecycle__pb2.ListAgentsRequest.FromString,
|
|
476
|
+
response_serializer=boundflow_dot_v1_dot_lifecycle__pb2.ListAgentsResponse.SerializeToString,
|
|
477
|
+
),
|
|
462
478
|
'ApproveWorkflow': grpc.unary_unary_rpc_method_handler(
|
|
463
479
|
servicer.ApproveWorkflow,
|
|
464
480
|
request_deserializer=boundflow_dot_v1_dot_lifecycle__pb2.ApproveWorkflowRequest.FromString,
|
|
@@ -950,6 +966,33 @@ class WorkflowService:
|
|
|
950
966
|
metadata,
|
|
951
967
|
_registered_method=True)
|
|
952
968
|
|
|
969
|
+
@staticmethod
|
|
970
|
+
def ListAgents(request,
|
|
971
|
+
target,
|
|
972
|
+
options=(),
|
|
973
|
+
channel_credentials=None,
|
|
974
|
+
call_credentials=None,
|
|
975
|
+
insecure=False,
|
|
976
|
+
compression=None,
|
|
977
|
+
wait_for_ready=None,
|
|
978
|
+
timeout=None,
|
|
979
|
+
metadata=None):
|
|
980
|
+
return grpc.experimental.unary_unary(
|
|
981
|
+
request,
|
|
982
|
+
target,
|
|
983
|
+
'/boundflow.v1.WorkflowService/ListAgents',
|
|
984
|
+
boundflow_dot_v1_dot_lifecycle__pb2.ListAgentsRequest.SerializeToString,
|
|
985
|
+
boundflow_dot_v1_dot_lifecycle__pb2.ListAgentsResponse.FromString,
|
|
986
|
+
options,
|
|
987
|
+
channel_credentials,
|
|
988
|
+
insecure,
|
|
989
|
+
call_credentials,
|
|
990
|
+
compression,
|
|
991
|
+
wait_for_ready,
|
|
992
|
+
timeout,
|
|
993
|
+
metadata,
|
|
994
|
+
_registered_method=True)
|
|
995
|
+
|
|
953
996
|
@staticmethod
|
|
954
997
|
def ApproveWorkflow(request,
|
|
955
998
|
target,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: boundflow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0.dev7
|
|
4
4
|
Summary: BoundFlow Python SDK — build governed fleets of agents against a self-hostable control plane.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Keywords: agents,llm,orchestration,control-plane,governance
|