@probelabs/visor 0.1.169-ee → 0.1.170-ee
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.
- package/README.md +64 -7
- package/defaults/assistant.yaml +1 -1
- package/defaults/code-talk.yaml +2 -2
- package/dist/defaults/assistant.yaml +1 -1
- package/dist/defaults/code-talk.yaml +2 -2
- package/dist/docs/a2a-provider.md +672 -0
- package/dist/docs/architecture.md +174 -12
- package/dist/docs/commands.md +36 -0
- package/dist/docs/configuration.md +1 -0
- package/dist/docs/index.md +9 -2
- package/dist/docs/pluggable.md +16 -1
- package/dist/index.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,19 +7,20 @@
|
|
|
7
7
|
[](https://nodejs.org/)
|
|
8
8
|
[](LICENSE)
|
|
9
9
|
|
|
10
|
-
Orchestrate checks, MCP tools,
|
|
11
|
-
Runs as GitHub Action, CLI, Slack bot, or
|
|
10
|
+
Orchestrate checks, MCP tools, AI providers, and A2A agents with YAML-driven pipelines.
|
|
11
|
+
Runs as GitHub Action, CLI, Slack bot, HTTP API, or A2A agent server.
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
Visor is an open-source workflow engine that lets you define multi-step AI pipelines in YAML. Wire up shell commands, AI providers, MCP tools, HTTP calls, and custom scripts into dependency-aware DAGs — then run them from your terminal, CI, Slack,
|
|
16
|
+
Visor is an open-source workflow engine that lets you define multi-step AI pipelines in YAML. Wire up shell commands, AI providers, MCP tools, A2A agents, HTTP calls, and custom scripts into dependency-aware DAGs — then run them from your terminal, CI, Slack, an HTTP endpoint, or as a standards-compliant A2A agent server.
|
|
17
17
|
|
|
18
18
|
**What you get out of the box:**
|
|
19
19
|
|
|
20
20
|
- **YAML-driven pipelines** — define checks, transforms, routing, and AI prompts in a single config file.
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
21
|
+
- **5 runtime modes** — CLI, GitHub Action, Slack bot, HTTP server, A2A agent server — same config, any surface.
|
|
22
|
+
- **15+ provider types** — `ai`, `a2a`, `command`, `script`, `mcp`, `http`, `claude-code`, `github`, `memory`, `workflow`, and more.
|
|
23
|
+
- **Agent interoperability** — A2A protocol support: expose workflows as discoverable agents, or call external A2A agents from your pipelines.
|
|
23
24
|
- **AI orchestration** — multi-provider (Gemini, Claude, OpenAI, Bedrock), session reuse, MCP tool calling, retry & fallback.
|
|
24
25
|
- **Execution engine** — dependency DAGs, parallel waves, forEach fan-out, conditional routing, failure auto-remediation.
|
|
25
26
|
- **Built-in testing** — YAML-native integration tests with fixtures, mocks, and assertions.
|
|
@@ -34,6 +35,7 @@ Visor is an open-source workflow engine that lets you define multi-step AI pipel
|
|
|
34
35
|
- [Provider Types](#-provider-types)
|
|
35
36
|
- [Orchestration](#-orchestration)
|
|
36
37
|
- [AI & MCP](#-ai--mcp)
|
|
38
|
+
- [Agent Protocol (A2A)](#-agent-protocol-a2a)
|
|
37
39
|
- [GitHub Provider](#-github-provider)
|
|
38
40
|
- [Templating & Transforms](#-templating--transforms)
|
|
39
41
|
- [Suppressing Warnings](#-suppressing-warnings)
|
|
@@ -163,7 +165,7 @@ Learn more: [docs/assistant-workflows.md](docs/assistant-workflows.md) | Example
|
|
|
163
165
|
|
|
164
166
|
## 🖥️ Runtime Modes
|
|
165
167
|
|
|
166
|
-
Visor runs the same YAML config across
|
|
168
|
+
Visor runs the same YAML config across five surfaces:
|
|
167
169
|
|
|
168
170
|
| Mode | How to run | Best for |
|
|
169
171
|
|------|-----------|----------|
|
|
@@ -171,6 +173,7 @@ Visor runs the same YAML config across four surfaces:
|
|
|
171
173
|
| **GitHub Action** | `uses: probelabs/visor@v1` | PR reviews, issue triage, annotations |
|
|
172
174
|
| **Slack bot** | `visor --slack --config .visor.yaml` | Team assistants, ChatOps |
|
|
173
175
|
| **HTTP server** | `http_server: { enabled: true, port: 8080 }` | Webhooks, API integrations |
|
|
176
|
+
| **A2A agent** | `visor --a2a --config .visor.yaml` | Agent interoperability, multi-agent systems |
|
|
174
177
|
|
|
175
178
|
Additional modes:
|
|
176
179
|
- **TUI** — interactive chat-style terminal UI: `visor --tui`
|
|
@@ -185,6 +188,8 @@ visor --analyze-branch-diff # PR-style diff analysis
|
|
|
185
188
|
visor --event pr_updated # Simulate GitHub events
|
|
186
189
|
visor --tui --config ./workflow.yaml # Interactive TUI
|
|
187
190
|
visor --debug-server --debug-port 3456 # Live web debugger
|
|
191
|
+
visor --a2a --config workflow.yaml # A2A agent server
|
|
192
|
+
visor tasks list --watch # Monitor A2A task queue
|
|
188
193
|
visor config snapshots # Config version history
|
|
189
194
|
visor validate # Validate config
|
|
190
195
|
visor test --progress compact # Run integration tests
|
|
@@ -227,6 +232,7 @@ Learn more: [docs/commands.md](docs/commands.md)
|
|
|
227
232
|
| Provider | Description | Example use |
|
|
228
233
|
|----------|------------|------------|
|
|
229
234
|
| `ai` | Multi-provider AI (Gemini, Claude, OpenAI, Bedrock) | Code review, analysis, generation |
|
|
235
|
+
| `a2a` | Call external A2A agents | Agent delegation, multi-agent workflows |
|
|
230
236
|
| `command` | Shell commands with Liquid templating | Run tests, build, lint |
|
|
231
237
|
| `script` | JavaScript in a secure sandbox | Transform data, custom logic |
|
|
232
238
|
| `mcp` | MCP tool execution (stdio/SSE/HTTP) | External tool integration |
|
|
@@ -434,6 +440,57 @@ steps:
|
|
|
434
440
|
|
|
435
441
|
Learn more: [docs/claude-code.md](docs/claude-code.md) · [docs/mcp-provider.md](docs/mcp-provider.md) · [docs/advanced-ai.md](docs/advanced-ai.md)
|
|
436
442
|
|
|
443
|
+
## 🤝 Agent Protocol (A2A)
|
|
444
|
+
|
|
445
|
+
Visor implements the [A2A (Agent-to-Agent) protocol](https://github.com/google/A2A) for agent interoperability. Every Visor workflow can become a discoverable, standards-compliant agent — and every A2A agent in the ecosystem becomes a callable step in your workflows.
|
|
446
|
+
|
|
447
|
+
### Server: Expose Workflows as an A2A Agent
|
|
448
|
+
|
|
449
|
+
```yaml
|
|
450
|
+
agent_protocol:
|
|
451
|
+
enabled: true
|
|
452
|
+
protocol: a2a
|
|
453
|
+
port: 9000
|
|
454
|
+
agent_card_inline:
|
|
455
|
+
name: "Code Review Agent"
|
|
456
|
+
description: "AI-powered code review"
|
|
457
|
+
skills:
|
|
458
|
+
- id: security
|
|
459
|
+
name: Security Review
|
|
460
|
+
description: Analyze code for vulnerabilities
|
|
461
|
+
skill_routing:
|
|
462
|
+
security: security-review
|
|
463
|
+
default_workflow: general-review
|
|
464
|
+
auth:
|
|
465
|
+
type: bearer
|
|
466
|
+
token_env: AGENT_AUTH_TOKEN
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
visor --a2a --config .visor.yaml # Start A2A server on port 9000
|
|
471
|
+
visor tasks list --watch # Monitor task queue
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Client: Call External A2A Agents
|
|
475
|
+
|
|
476
|
+
```yaml
|
|
477
|
+
steps:
|
|
478
|
+
compliance-scan:
|
|
479
|
+
type: a2a
|
|
480
|
+
agent_url: "http://compliance-agent:9000"
|
|
481
|
+
message: |
|
|
482
|
+
Review PR #{{ pr.number }}: {{ pr.title }}
|
|
483
|
+
blocking: true
|
|
484
|
+
timeout: 60000
|
|
485
|
+
|
|
486
|
+
summarize:
|
|
487
|
+
type: ai
|
|
488
|
+
depends_on: [compliance-scan]
|
|
489
|
+
prompt: "Summarize: {{ outputs['compliance-scan'] | json }}"
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
Learn more: [docs/a2a-provider.md](docs/a2a-provider.md) · [RFC: A2A Protocol Support](rfc/001-a2a-protocol-support.md) · [Example config](examples/a2a-agent-example.yaml)
|
|
493
|
+
|
|
437
494
|
## 🧰 GitHub Provider
|
|
438
495
|
|
|
439
496
|
Native GitHub operations (labels, comments, checks) without shelling out to `gh`:
|
|
@@ -709,7 +766,7 @@ Learn more: [docs/enterprise-policy.md](docs/enterprise-policy.md)
|
|
|
709
766
|
[Assistant workflows](docs/assistant-workflows.md) · [CLI commands](docs/commands.md) · [Configuration](docs/configuration.md) · [AI config](docs/ai-configuration.md) · [Dependencies](docs/dependencies.md) · [forEach propagation](docs/foreach-dependency-propagation.md) · [Failure routing](docs/failure-routing.md) · [Liquid templates](docs/liquid-templates.md) · [Schema-template system](docs/schema-templates.md) · [Fail conditions](docs/fail-if.md) · [Timeouts](docs/timeouts.md) · [Execution limits](docs/limits.md) · [Output formats](docs/output-formats.md) · [Output formatting](docs/output-formatting.md) · [HTTP integration](docs/http.md) · [Scheduler](docs/scheduler.md)
|
|
710
767
|
|
|
711
768
|
**Providers:**
|
|
712
|
-
[Command](docs/command-provider.md) · [Script](docs/script.md) · [MCP](docs/mcp-provider.md) · [MCP tools for AI](docs/mcp.md) · [Claude Code](docs/claude-code.md) · [GitHub ops](docs/github-ops.md) · [Custom providers](docs/pluggable.md)
|
|
769
|
+
[A2A](docs/a2a-provider.md) · [Command](docs/command-provider.md) · [Script](docs/script.md) · [MCP](docs/mcp-provider.md) · [MCP tools for AI](docs/mcp.md) · [Claude Code](docs/claude-code.md) · [GitHub ops](docs/github-ops.md) · [Custom providers](docs/pluggable.md)
|
|
713
770
|
|
|
714
771
|
**Operations:**
|
|
715
772
|
[GitHub Action reference](docs/action-reference.md) · [Security](docs/security.md) · [Performance](docs/performance.md) · [Observability](docs/observability.md) · [Debugging](docs/debugging.md) · [Debug visualizer](docs/debug-visualizer.md) · [Troubleshooting](docs/troubleshooting.md) · [Suppressions](docs/suppressions.md) · [GitHub checks](docs/GITHUB_CHECKS.md)
|
package/defaults/assistant.yaml
CHANGED
|
@@ -766,7 +766,7 @@ steps:
|
|
|
766
766
|
# ProbeAgent resolves "*" and "!" patterns natively.
|
|
767
767
|
ai_allowed_tools_js: |
|
|
768
768
|
// Start with wildcard — allow all tools by default
|
|
769
|
-
const excluded = ['search', 'query', 'extract', 'listFiles', 'searchFiles', 'delegate'];
|
|
769
|
+
const excluded = ['search', 'query', 'extract', 'listFiles', 'searchFiles', 'delegate', 'analyze_all'];
|
|
770
770
|
const bashEnabled = outputs['build-config']?.bash_enabled === true;
|
|
771
771
|
if (!bashEnabled) {
|
|
772
772
|
excluded.push('bash');
|
package/defaults/code-talk.yaml
CHANGED
|
@@ -472,7 +472,7 @@ steps:
|
|
|
472
472
|
ai:
|
|
473
473
|
skip_code_context: true
|
|
474
474
|
enableDelegate: true
|
|
475
|
-
enableExecutePlan:
|
|
475
|
+
enableExecutePlan: false
|
|
476
476
|
max_iterations: 40
|
|
477
477
|
prompt_type: code-explorer
|
|
478
478
|
allowBash: true
|
|
@@ -524,7 +524,7 @@ steps:
|
|
|
524
524
|
- "curl:-s:*"
|
|
525
525
|
- "curl:*"
|
|
526
526
|
timeout: 60000
|
|
527
|
-
|
|
527
|
+
_completion_prompt: |
|
|
528
528
|
Before finalizing your answer, triple-check everything:
|
|
529
529
|
|
|
530
530
|
Challenge assumptions:
|
|
@@ -766,7 +766,7 @@ steps:
|
|
|
766
766
|
# ProbeAgent resolves "*" and "!" patterns natively.
|
|
767
767
|
ai_allowed_tools_js: |
|
|
768
768
|
// Start with wildcard — allow all tools by default
|
|
769
|
-
const excluded = ['search', 'query', 'extract', 'listFiles', 'searchFiles', 'delegate'];
|
|
769
|
+
const excluded = ['search', 'query', 'extract', 'listFiles', 'searchFiles', 'delegate', 'analyze_all'];
|
|
770
770
|
const bashEnabled = outputs['build-config']?.bash_enabled === true;
|
|
771
771
|
if (!bashEnabled) {
|
|
772
772
|
excluded.push('bash');
|
|
@@ -472,7 +472,7 @@ steps:
|
|
|
472
472
|
ai:
|
|
473
473
|
skip_code_context: true
|
|
474
474
|
enableDelegate: true
|
|
475
|
-
enableExecutePlan:
|
|
475
|
+
enableExecutePlan: false
|
|
476
476
|
max_iterations: 40
|
|
477
477
|
prompt_type: code-explorer
|
|
478
478
|
allowBash: true
|
|
@@ -524,7 +524,7 @@ steps:
|
|
|
524
524
|
- "curl:-s:*"
|
|
525
525
|
- "curl:*"
|
|
526
526
|
timeout: 60000
|
|
527
|
-
|
|
527
|
+
_completion_prompt: |
|
|
528
528
|
Before finalizing your answer, triple-check everything:
|
|
529
529
|
|
|
530
530
|
Challenge assumptions:
|
|
@@ -0,0 +1,672 @@
|
|
|
1
|
+
# A2A Provider (Agent-to-Agent Protocol)
|
|
2
|
+
|
|
3
|
+
Visor implements the [A2A (Agent-to-Agent) protocol](https://github.com/google/A2A) for agent interoperability. This enables two modes of operation:
|
|
4
|
+
|
|
5
|
+
- **Server mode** — Visor exposes workflows as a discoverable A2A agent that external systems can call
|
|
6
|
+
- **Client mode** — Visor calls external A2A agents as workflow steps using `type: a2a`
|
|
7
|
+
|
|
8
|
+
### A2A vs MCP
|
|
9
|
+
|
|
10
|
+
| | A2A | MCP |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| **Pattern** | Agent-to-Agent task delegation | Agent-to-Tool function calls |
|
|
13
|
+
| **Communication** | Stateful tasks with lifecycle | Stateless function invocation |
|
|
14
|
+
| **Input** | Natural language + structured data | Typed JSON Schema parameters |
|
|
15
|
+
| **Discovery** | Agent Card at `/.well-known/agent-card.json` | Tool listing via `tools/list` |
|
|
16
|
+
| **Multi-turn** | Built-in (input_required state) | Not applicable |
|
|
17
|
+
|
|
18
|
+
Use MCP when you need deterministic tool calls with typed schemas. Use A2A when you need to delegate complex tasks to another agent that may require multiple turns or long-running execution.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### Server: Expose a Workflow as an A2A Agent
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
# .visor.yaml
|
|
28
|
+
version: "1.0"
|
|
29
|
+
|
|
30
|
+
agent_protocol:
|
|
31
|
+
enabled: true
|
|
32
|
+
protocol: a2a
|
|
33
|
+
port: 9000
|
|
34
|
+
agent_card_inline:
|
|
35
|
+
name: "Review Agent"
|
|
36
|
+
description: "AI code review"
|
|
37
|
+
skills:
|
|
38
|
+
- id: review
|
|
39
|
+
name: Code Review
|
|
40
|
+
description: Review code for issues
|
|
41
|
+
default_workflow: review
|
|
42
|
+
|
|
43
|
+
steps:
|
|
44
|
+
review:
|
|
45
|
+
type: ai
|
|
46
|
+
prompt: "Review the submitted code for issues"
|
|
47
|
+
on: [manual]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Start the A2A server
|
|
52
|
+
visor --a2a --config .visor.yaml
|
|
53
|
+
|
|
54
|
+
# Test with curl
|
|
55
|
+
curl http://localhost:9000/.well-known/agent-card.json
|
|
56
|
+
curl -X POST http://localhost:9000/message:send \
|
|
57
|
+
-H "Content-Type: application/json" \
|
|
58
|
+
-d '{"message": {"message_id": "1", "role": "user", "parts": [{"text": "Review my code"}]}}'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Client: Call an External A2A Agent
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
steps:
|
|
65
|
+
scan:
|
|
66
|
+
type: a2a
|
|
67
|
+
agent_url: "http://compliance-agent:9000"
|
|
68
|
+
message: "Review PR #{{ pr.number }}: {{ pr.title }}"
|
|
69
|
+
blocking: true
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Server Mode: Visor as an A2A Agent
|
|
75
|
+
|
|
76
|
+
### Enabling the Server
|
|
77
|
+
|
|
78
|
+
Start with the `--a2a` CLI flag:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
visor --a2a --config .visor.yaml
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Or enable in configuration:
|
|
85
|
+
|
|
86
|
+
```yaml
|
|
87
|
+
agent_protocol:
|
|
88
|
+
enabled: true
|
|
89
|
+
protocol: a2a
|
|
90
|
+
port: 9000 # default: 9000
|
|
91
|
+
host: "0.0.0.0" # default: 0.0.0.0
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
A2A can run alongside other modes:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
visor --a2a --slack --config .visor.yaml # A2A + Slack simultaneously
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Agent Card
|
|
101
|
+
|
|
102
|
+
The Agent Card describes your agent to external clients. Define it inline or load from a file:
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
# Inline
|
|
106
|
+
agent_protocol:
|
|
107
|
+
agent_card_inline:
|
|
108
|
+
name: "Code Review Agent"
|
|
109
|
+
description: "AI-powered code review"
|
|
110
|
+
version: "1.0.0"
|
|
111
|
+
provider:
|
|
112
|
+
organization: "My Org"
|
|
113
|
+
url: "https://myorg.com"
|
|
114
|
+
skills:
|
|
115
|
+
- id: security
|
|
116
|
+
name: Security Review
|
|
117
|
+
description: OWASP Top 10 analysis
|
|
118
|
+
tags: [security, owasp]
|
|
119
|
+
- id: performance
|
|
120
|
+
name: Performance Review
|
|
121
|
+
description: Performance bottleneck detection
|
|
122
|
+
tags: [performance]
|
|
123
|
+
supported_interfaces:
|
|
124
|
+
- url: "http://localhost:9000"
|
|
125
|
+
protocol_binding: "a2a/v1"
|
|
126
|
+
capabilities:
|
|
127
|
+
streaming: false
|
|
128
|
+
push_notifications: false
|
|
129
|
+
|
|
130
|
+
# Or load from file
|
|
131
|
+
agent_protocol:
|
|
132
|
+
agent_card: "./agent-card.json"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The Agent Card is served publicly at `GET /.well-known/agent-card.json` (no authentication required).
|
|
136
|
+
|
|
137
|
+
### Skill Routing
|
|
138
|
+
|
|
139
|
+
Map incoming A2A skill IDs to internal Visor workflows:
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
agent_protocol:
|
|
143
|
+
skill_routing:
|
|
144
|
+
security: security-review # A2A skill "security" → workflow "security-review"
|
|
145
|
+
performance: performance-review
|
|
146
|
+
default_workflow: general-review # Fallback when skill not matched
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
When a client sends a message with `metadata.skill_id: "security"`, Visor routes it to the `security-review` workflow. Unmatched skills use `default_workflow`.
|
|
150
|
+
|
|
151
|
+
### Authentication
|
|
152
|
+
|
|
153
|
+
Configure authentication for inbound requests:
|
|
154
|
+
|
|
155
|
+
```yaml
|
|
156
|
+
agent_protocol:
|
|
157
|
+
auth:
|
|
158
|
+
type: bearer # bearer | api_key | none
|
|
159
|
+
token_env: AGENT_AUTH_TOKEN # Environment variable containing the token
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Bearer token:**
|
|
163
|
+
```yaml
|
|
164
|
+
auth:
|
|
165
|
+
type: bearer
|
|
166
|
+
token_env: AGENT_AUTH_TOKEN # Checked via Authorization: Bearer <token>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**API key:**
|
|
170
|
+
```yaml
|
|
171
|
+
auth:
|
|
172
|
+
type: api_key
|
|
173
|
+
key_env: AGENT_API_KEY
|
|
174
|
+
header_name: X-API-Key # default: x-api-key
|
|
175
|
+
param_name: api_key # also checked as query parameter
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
> The Agent Card endpoint (`/.well-known/agent-card.json`) is always public regardless of auth configuration.
|
|
179
|
+
|
|
180
|
+
### HTTP Endpoints
|
|
181
|
+
|
|
182
|
+
| Method | Path | Auth | Description |
|
|
183
|
+
|--------|------|------|-------------|
|
|
184
|
+
| `GET` | `/.well-known/agent-card.json` | No | Agent Card for discovery |
|
|
185
|
+
| `POST` | `/message:send` | Yes | Submit a task / send a message |
|
|
186
|
+
| `GET` | `/tasks/{id}` | Yes | Get task by ID |
|
|
187
|
+
| `GET` | `/tasks` | Yes | List all tasks |
|
|
188
|
+
| `POST` | `/tasks/{id}:cancel` | Yes | Cancel a running task |
|
|
189
|
+
|
|
190
|
+
### Task Lifecycle
|
|
191
|
+
|
|
192
|
+
Tasks follow a state machine with these transitions:
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
┌─────────────┐
|
|
196
|
+
│ submitted │
|
|
197
|
+
└──────┬──────┘
|
|
198
|
+
┌────────────┼────────────┐
|
|
199
|
+
v v v
|
|
200
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
201
|
+
│ working │ │ canceled │ │ rejected │
|
|
202
|
+
└────┬─────┘ └──────────┘ └──────────┘
|
|
203
|
+
┌─────┬───┼───┬─────────┐
|
|
204
|
+
v v v v v
|
|
205
|
+
┌─────────┐ │ ┌───┐ │ ┌────────────────┐
|
|
206
|
+
│completed│ │ │ │ │ │input_required │──→ working (resumed)
|
|
207
|
+
└─────────┘ │ │ │ │ └────────────────┘
|
|
208
|
+
┌─────┘ │ │ └──────────┐
|
|
209
|
+
v v v v
|
|
210
|
+
┌──────────┐ ┌──────────┐ ┌────────────────┐
|
|
211
|
+
│ failed │ │ canceled │ │ auth_required │──→ working (resumed)
|
|
212
|
+
└──────────┘ └──────────┘ └────────────────┘
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Terminal states:** `completed`, `failed`, `canceled`, `rejected`
|
|
216
|
+
|
|
217
|
+
| State | Description |
|
|
218
|
+
|-------|-------------|
|
|
219
|
+
| `submitted` | Task created, waiting to be picked up |
|
|
220
|
+
| `working` | Workflow engine is processing the task |
|
|
221
|
+
| `input_required` | Agent needs additional input from the client |
|
|
222
|
+
| `auth_required` | Agent needs authentication credentials |
|
|
223
|
+
| `completed` | Task finished successfully |
|
|
224
|
+
| `failed` | Task execution encountered an error |
|
|
225
|
+
| `canceled` | Task was canceled by the client |
|
|
226
|
+
| `rejected` | Task was rejected at submission |
|
|
227
|
+
|
|
228
|
+
### Task Queue
|
|
229
|
+
|
|
230
|
+
For async execution, configure the task queue:
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
agent_protocol:
|
|
234
|
+
queue:
|
|
235
|
+
poll_interval: 1000 # Poll database every N ms (default: 1000)
|
|
236
|
+
max_concurrent: 5 # Max concurrent tasks (default: 5)
|
|
237
|
+
stale_claim_timeout: 300000 # Worker timeout in ms (default: 300000)
|
|
238
|
+
task_ttl: "7d" # Task retention period (default: 7d)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
**Blocking vs async:**
|
|
242
|
+
- **Blocking** (default): The `POST /message:send` request waits for the workflow to complete and returns the full task with artifacts.
|
|
243
|
+
- **Async**: Set `configuration.blocking: false` in the request. Returns the task ID immediately; the client polls `GET /tasks/{id}` for status updates.
|
|
244
|
+
|
|
245
|
+
### TLS
|
|
246
|
+
|
|
247
|
+
For production deployments:
|
|
248
|
+
|
|
249
|
+
```yaml
|
|
250
|
+
agent_protocol:
|
|
251
|
+
tls:
|
|
252
|
+
cert: "/path/to/cert.pem"
|
|
253
|
+
key: "/path/to/key.pem"
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Client Mode: Calling External A2A Agents
|
|
259
|
+
|
|
260
|
+
Use `type: a2a` to call external A2A-compatible agents from your workflow.
|
|
261
|
+
|
|
262
|
+
### Basic Usage
|
|
263
|
+
|
|
264
|
+
```yaml
|
|
265
|
+
steps:
|
|
266
|
+
compliance-scan:
|
|
267
|
+
type: a2a
|
|
268
|
+
agent_url: "http://compliance-agent:9000"
|
|
269
|
+
message: |
|
|
270
|
+
Review PR #{{ pr.number }}: {{ pr.title }}
|
|
271
|
+
Files changed: {{ files | size }}
|
|
272
|
+
blocking: true
|
|
273
|
+
timeout: 60000
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Agent Discovery
|
|
277
|
+
|
|
278
|
+
Specify the agent endpoint in one of two ways (mutually exclusive):
|
|
279
|
+
|
|
280
|
+
```yaml
|
|
281
|
+
# Option 1: Direct URL to the agent
|
|
282
|
+
agent_url: "http://agent.example.com:9000"
|
|
283
|
+
|
|
284
|
+
# Option 2: URL to the Agent Card (endpoint resolved from card)
|
|
285
|
+
agent_card: "https://agent.example.com/.well-known/agent-card.json"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
When using `agent_card`, Visor fetches the card, caches it for 5 minutes, and resolves the endpoint from `supported_interfaces`.
|
|
289
|
+
|
|
290
|
+
### Authentication
|
|
291
|
+
|
|
292
|
+
```yaml
|
|
293
|
+
steps:
|
|
294
|
+
scan:
|
|
295
|
+
type: a2a
|
|
296
|
+
agent_url: "http://agent:9000"
|
|
297
|
+
message: "Review this code"
|
|
298
|
+
auth:
|
|
299
|
+
scheme: bearer # bearer | api_key
|
|
300
|
+
token_env: AGENT_TOKEN # Environment variable with the token
|
|
301
|
+
# header_name: X-API-Key # For api_key scheme (default: x-api-key)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Message Construction
|
|
305
|
+
|
|
306
|
+
**Text message** (Liquid template):
|
|
307
|
+
```yaml
|
|
308
|
+
message: |
|
|
309
|
+
Review PR #{{ pr.number }}: {{ pr.title }}
|
|
310
|
+
Author: {{ pr.author }}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Structured data** (Liquid-templated key-value pairs sent as data parts):
|
|
314
|
+
```yaml
|
|
315
|
+
data:
|
|
316
|
+
repo_context: '{{ pr.repo | json }}'
|
|
317
|
+
file_list: '{{ files | json }}'
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**File attachments:**
|
|
321
|
+
```yaml
|
|
322
|
+
files:
|
|
323
|
+
- url: "https://example.com/requirements.txt"
|
|
324
|
+
media_type: "text/plain"
|
|
325
|
+
filename: "requirements.txt"
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Polling and Multi-Turn
|
|
329
|
+
|
|
330
|
+
```yaml
|
|
331
|
+
steps:
|
|
332
|
+
interactive-agent:
|
|
333
|
+
type: a2a
|
|
334
|
+
agent_url: "http://agent:9000"
|
|
335
|
+
message: "Analyze {{ pr.title }}"
|
|
336
|
+
|
|
337
|
+
blocking: true # Wait for completion (default: true)
|
|
338
|
+
timeout: 300000 # Max wait in ms (default: 300000)
|
|
339
|
+
poll_interval: 2000 # Poll frequency in ms (default: 2000)
|
|
340
|
+
|
|
341
|
+
# Multi-turn conversation
|
|
342
|
+
max_turns: 3 # Max conversation turns (default: 1)
|
|
343
|
+
on_input_required: | # Auto-reply when agent asks for more info
|
|
344
|
+
Here is additional context:
|
|
345
|
+
{{ pr.body }}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
When the agent enters `input_required` state, Visor automatically sends the `on_input_required` template as a follow-up message. This continues up to `max_turns`.
|
|
349
|
+
|
|
350
|
+
### Output Transformation
|
|
351
|
+
|
|
352
|
+
Transform agent responses into structured issues with JavaScript:
|
|
353
|
+
|
|
354
|
+
```yaml
|
|
355
|
+
steps:
|
|
356
|
+
scan:
|
|
357
|
+
type: a2a
|
|
358
|
+
agent_url: "http://agent:9000"
|
|
359
|
+
message: "Security scan"
|
|
360
|
+
transform_js: |
|
|
361
|
+
return {
|
|
362
|
+
issues: (output.issues || []).map(function(i) {
|
|
363
|
+
return {
|
|
364
|
+
file: i.file,
|
|
365
|
+
line: i.line || 0,
|
|
366
|
+
ruleId: 'a2a/' + (i.ruleId || 'issue'),
|
|
367
|
+
message: i.message,
|
|
368
|
+
severity: i.severity || 'warning'
|
|
369
|
+
};
|
|
370
|
+
})
|
|
371
|
+
};
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Error Handling
|
|
375
|
+
|
|
376
|
+
A2A errors are surfaced as issues with `ruleId: a2a/error`:
|
|
377
|
+
|
|
378
|
+
| Error | When |
|
|
379
|
+
|-------|------|
|
|
380
|
+
| `A2ATimeoutError` | Task didn't complete within `timeout` |
|
|
381
|
+
| `A2AMaxTurnsExceededError` | Conversation exceeded `max_turns` |
|
|
382
|
+
| `A2AInputRequiredError` | Agent needs input but `max_turns` exhausted |
|
|
383
|
+
| `A2AAuthRequiredError` | Agent requires authentication credentials |
|
|
384
|
+
| `A2ATaskFailedError` | Task execution failed on the remote agent |
|
|
385
|
+
| `A2ATaskRejectedError` | Task was rejected or canceled |
|
|
386
|
+
| `A2ARequestError` | HTTP request to the agent failed |
|
|
387
|
+
| `AgentCardFetchError` | Failed to fetch Agent Card |
|
|
388
|
+
| `InvalidAgentCardError` | Agent Card is malformed |
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
## Task Management CLI
|
|
393
|
+
|
|
394
|
+
Monitor and manage A2A tasks with `visor tasks`:
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
visor tasks # List all tasks (alias for list)
|
|
398
|
+
visor tasks list # List tasks
|
|
399
|
+
visor tasks list --state working # Filter by state
|
|
400
|
+
visor tasks list --agent security-review # Filter by workflow
|
|
401
|
+
visor tasks list --limit 50 # Show more results
|
|
402
|
+
visor tasks list --output json # JSON output
|
|
403
|
+
visor tasks list --watch # Live refresh every 2s
|
|
404
|
+
visor tasks stats # Queue summary statistics
|
|
405
|
+
visor tasks stats --output json # Stats as JSON
|
|
406
|
+
visor tasks cancel <task-id> # Cancel a running task
|
|
407
|
+
visor tasks help # Show usage
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**Flags:**
|
|
411
|
+
|
|
412
|
+
| Flag | Description | Default |
|
|
413
|
+
|------|-------------|---------|
|
|
414
|
+
| `--state <state>` | Filter by task state | all |
|
|
415
|
+
| `--agent <workflow-id>` | Filter by workflow | all |
|
|
416
|
+
| `--limit <n>` | Number of tasks to show | 20 |
|
|
417
|
+
| `--output <format>` | Output format: `table`, `json`, `markdown` | table |
|
|
418
|
+
| `--watch` | Refresh every 2 seconds | off |
|
|
419
|
+
|
|
420
|
+
---
|
|
421
|
+
|
|
422
|
+
## Configuration Reference
|
|
423
|
+
|
|
424
|
+
### Server-Side: `agent_protocol`
|
|
425
|
+
|
|
426
|
+
| Key | Type | Default | Description |
|
|
427
|
+
|-----|------|---------|-------------|
|
|
428
|
+
| `enabled` | boolean | `false` | Enable the A2A server |
|
|
429
|
+
| `protocol` | string | `"a2a"` | Protocol binding |
|
|
430
|
+
| `port` | number | `9000` | HTTP listen port |
|
|
431
|
+
| `host` | string | `"0.0.0.0"` | HTTP bind address |
|
|
432
|
+
| `public_url` | string | auto | Public URL for Agent Card |
|
|
433
|
+
| `agent_card_inline` | object | - | Inline Agent Card definition |
|
|
434
|
+
| `agent_card` | string | - | Path to Agent Card JSON file |
|
|
435
|
+
| `auth` | object | - | Authentication config |
|
|
436
|
+
| `auth.type` | string | - | `bearer`, `api_key`, or `none` |
|
|
437
|
+
| `auth.token_env` | string | - | Env var for bearer token |
|
|
438
|
+
| `auth.key_env` | string | - | Env var for API key |
|
|
439
|
+
| `auth.header_name` | string | `"x-api-key"` | Custom header for API key |
|
|
440
|
+
| `auth.param_name` | string | `"api_key"` | Query parameter for API key |
|
|
441
|
+
| `skill_routing` | object | - | Map of skill_id to workflow name |
|
|
442
|
+
| `default_workflow` | string | - | Fallback workflow for unmatched skills |
|
|
443
|
+
| `task_ttl` | string | `"7d"` | Task retention period |
|
|
444
|
+
| `queue.poll_interval` | number | `1000` | Queue poll interval in ms |
|
|
445
|
+
| `queue.max_concurrent` | number | `5` | Max concurrent task executions |
|
|
446
|
+
| `queue.stale_claim_timeout` | number | `300000` | Worker stale claim timeout in ms |
|
|
447
|
+
| `tls.cert` | string | - | Path to TLS certificate |
|
|
448
|
+
| `tls.key` | string | - | Path to TLS private key |
|
|
449
|
+
|
|
450
|
+
### Client-Side: `type: a2a` Check Provider
|
|
451
|
+
|
|
452
|
+
| Key | Type | Default | Required | Description |
|
|
453
|
+
|-----|------|---------|----------|-------------|
|
|
454
|
+
| `agent_url` | string | - | one of | Direct agent endpoint URL |
|
|
455
|
+
| `agent_card` | string | - | one of | URL to Agent Card |
|
|
456
|
+
| `message` | string | - | yes | Liquid template for the message text |
|
|
457
|
+
| `data` | object | - | no | Liquid-templated structured data parts |
|
|
458
|
+
| `files` | array | - | no | File attachments (`url`, `media_type`, `filename`) |
|
|
459
|
+
| `auth.scheme` | string | - | no | `bearer` or `api_key` |
|
|
460
|
+
| `auth.token_env` | string | - | no | Env var containing auth token |
|
|
461
|
+
| `auth.header_name` | string | `"x-api-key"` | no | Custom header for API key |
|
|
462
|
+
| `blocking` | boolean | `true` | no | Wait for task completion |
|
|
463
|
+
| `timeout` | number | `300000` | no | Max wait time in ms |
|
|
464
|
+
| `poll_interval` | number | `2000` | no | Poll interval in ms |
|
|
465
|
+
| `max_turns` | number | `1` | no | Max conversation turns |
|
|
466
|
+
| `on_input_required` | string | - | no | Liquid template for auto-reply |
|
|
467
|
+
| `transform_js` | string | - | no | JavaScript output transformation |
|
|
468
|
+
| `accepted_output_modes` | string[] | `["text/plain", "application/json"]` | no | Accepted MIME types |
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
## Examples
|
|
473
|
+
|
|
474
|
+
### Server: Code Review Agent
|
|
475
|
+
|
|
476
|
+
Full example from [examples/a2a-agent-example.yaml](../examples/a2a-agent-example.yaml):
|
|
477
|
+
|
|
478
|
+
```yaml
|
|
479
|
+
version: "1.0"
|
|
480
|
+
|
|
481
|
+
agent_protocol:
|
|
482
|
+
enabled: true
|
|
483
|
+
protocol: a2a
|
|
484
|
+
port: 9000
|
|
485
|
+
host: "0.0.0.0"
|
|
486
|
+
|
|
487
|
+
agent_card_inline:
|
|
488
|
+
name: "Code Review Agent"
|
|
489
|
+
description: "AI-powered code review agent built with Visor"
|
|
490
|
+
version: "1.0.0"
|
|
491
|
+
provider:
|
|
492
|
+
organization: "Visor"
|
|
493
|
+
skills:
|
|
494
|
+
- id: security
|
|
495
|
+
name: Security Review
|
|
496
|
+
description: Analyze code for security vulnerabilities (OWASP Top 10)
|
|
497
|
+
tags: [security, owasp]
|
|
498
|
+
- id: performance
|
|
499
|
+
name: Performance Review
|
|
500
|
+
description: Analyze code for performance issues and bottlenecks
|
|
501
|
+
tags: [performance]
|
|
502
|
+
supported_interfaces:
|
|
503
|
+
- url: "http://localhost:9000"
|
|
504
|
+
protocol_binding: "a2a/v1"
|
|
505
|
+
capabilities:
|
|
506
|
+
streaming: false
|
|
507
|
+
push_notifications: false
|
|
508
|
+
|
|
509
|
+
auth:
|
|
510
|
+
type: bearer
|
|
511
|
+
token_env: AGENT_AUTH_TOKEN
|
|
512
|
+
|
|
513
|
+
skill_routing:
|
|
514
|
+
security: security-review
|
|
515
|
+
performance: performance-review
|
|
516
|
+
default_workflow: general-review
|
|
517
|
+
|
|
518
|
+
task_ttl: "7d"
|
|
519
|
+
queue:
|
|
520
|
+
max_concurrent: 5
|
|
521
|
+
|
|
522
|
+
steps:
|
|
523
|
+
security-review:
|
|
524
|
+
type: ai
|
|
525
|
+
prompt: |
|
|
526
|
+
Perform a security review focusing on OWASP Top 10 vulnerabilities.
|
|
527
|
+
Check for SQL injection, XSS, CSRF, and authentication issues.
|
|
528
|
+
on: [manual]
|
|
529
|
+
|
|
530
|
+
performance-review:
|
|
531
|
+
type: ai
|
|
532
|
+
prompt: |
|
|
533
|
+
Review for performance issues: N+1 queries, memory leaks,
|
|
534
|
+
unnecessary allocations, and algorithmic complexity.
|
|
535
|
+
on: [manual]
|
|
536
|
+
|
|
537
|
+
general-review:
|
|
538
|
+
type: ai
|
|
539
|
+
prompt: |
|
|
540
|
+
General code quality review: naming, structure, error handling,
|
|
541
|
+
and adherence to project conventions.
|
|
542
|
+
on: [manual]
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
```bash
|
|
546
|
+
# Start
|
|
547
|
+
visor --a2a --config examples/a2a-agent-example.yaml
|
|
548
|
+
|
|
549
|
+
# Discover
|
|
550
|
+
curl http://localhost:9000/.well-known/agent-card.json | jq .
|
|
551
|
+
|
|
552
|
+
# Send a task targeting the security skill
|
|
553
|
+
curl -X POST http://localhost:9000/message:send \
|
|
554
|
+
-H "Content-Type: application/json" \
|
|
555
|
+
-H "Authorization: Bearer $AGENT_AUTH_TOKEN" \
|
|
556
|
+
-d '{
|
|
557
|
+
"message": {
|
|
558
|
+
"message_id": "msg-1",
|
|
559
|
+
"role": "user",
|
|
560
|
+
"parts": [{"text": "Review auth.py for security issues"}],
|
|
561
|
+
"metadata": {"skill_id": "security"}
|
|
562
|
+
}
|
|
563
|
+
}'
|
|
564
|
+
|
|
565
|
+
# Monitor tasks
|
|
566
|
+
visor tasks list --watch
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### Client: Multi-Agent Composition
|
|
570
|
+
|
|
571
|
+
Chain multiple A2A agents and aggregate results:
|
|
572
|
+
|
|
573
|
+
```yaml
|
|
574
|
+
steps:
|
|
575
|
+
compliance-scan:
|
|
576
|
+
type: a2a
|
|
577
|
+
agent_url: "http://compliance-agent:9000"
|
|
578
|
+
message: "Check compliance for PR #{{ pr.number }}"
|
|
579
|
+
blocking: true
|
|
580
|
+
|
|
581
|
+
security-scan:
|
|
582
|
+
type: a2a
|
|
583
|
+
agent_url: "http://security-agent:9000"
|
|
584
|
+
message: "Security review for PR #{{ pr.number }}"
|
|
585
|
+
blocking: true
|
|
586
|
+
|
|
587
|
+
summarize:
|
|
588
|
+
type: ai
|
|
589
|
+
depends_on: [compliance-scan, security-scan]
|
|
590
|
+
prompt: |
|
|
591
|
+
Summarize findings from two agents:
|
|
592
|
+
Compliance: {{ outputs["compliance-scan"] | json }}
|
|
593
|
+
Security: {{ outputs["security-scan"] | json }}
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### Multi-Turn Conversation
|
|
597
|
+
|
|
598
|
+
Handle agents that ask follow-up questions:
|
|
599
|
+
|
|
600
|
+
```yaml
|
|
601
|
+
steps:
|
|
602
|
+
interactive-review:
|
|
603
|
+
type: a2a
|
|
604
|
+
agent_card: "https://agent.example.com/.well-known/agent-card.json"
|
|
605
|
+
message: "Analyze {{ pr.title }} for best practices"
|
|
606
|
+
max_turns: 3
|
|
607
|
+
on_input_required: |
|
|
608
|
+
Here is additional context:
|
|
609
|
+
{{ pr.body }}
|
|
610
|
+
transform_js: |
|
|
611
|
+
return {
|
|
612
|
+
issues: (output.issues || []).map(function(i) {
|
|
613
|
+
return {
|
|
614
|
+
file: i.file,
|
|
615
|
+
line: i.line || 0,
|
|
616
|
+
ruleId: 'a2a/' + (i.ruleId || 'issue'),
|
|
617
|
+
message: i.message,
|
|
618
|
+
severity: i.severity || 'warning'
|
|
619
|
+
};
|
|
620
|
+
})
|
|
621
|
+
};
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
---
|
|
625
|
+
|
|
626
|
+
## Security Considerations
|
|
627
|
+
|
|
628
|
+
- **Always configure auth for production** — without it, anyone can submit tasks to your agent
|
|
629
|
+
- **Use `token_env` / `key_env`** — never hardcode tokens in config files
|
|
630
|
+
- **Enable TLS** for public-facing servers
|
|
631
|
+
- **Agent Card is public** — it's served without auth, so don't include sensitive information
|
|
632
|
+
- **Task TTL** — set appropriate retention to limit stored data (`task_ttl: "7d"`)
|
|
633
|
+
- **Token comparison** uses timing-safe comparison to prevent timing attacks
|
|
634
|
+
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
## Debugging
|
|
638
|
+
|
|
639
|
+
```bash
|
|
640
|
+
# Start with debug logging
|
|
641
|
+
visor --a2a --debug --config .visor.yaml
|
|
642
|
+
|
|
643
|
+
# Verify Agent Card is served correctly
|
|
644
|
+
curl http://localhost:9000/.well-known/agent-card.json | jq .
|
|
645
|
+
|
|
646
|
+
# Monitor live task queue
|
|
647
|
+
visor tasks list --watch
|
|
648
|
+
|
|
649
|
+
# Check queue statistics
|
|
650
|
+
visor tasks stats
|
|
651
|
+
|
|
652
|
+
# View specific task
|
|
653
|
+
visor tasks list --state failed # Find failed tasks
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
With OpenTelemetry enabled, A2A tasks emit spans with:
|
|
657
|
+
- `agent.task.id` — Task ID
|
|
658
|
+
- `agent.task.state` — Current state
|
|
659
|
+
- `agent.task.workflow_id` — Target workflow
|
|
660
|
+
|
|
661
|
+
---
|
|
662
|
+
|
|
663
|
+
## Related Documentation
|
|
664
|
+
|
|
665
|
+
- [MCP Provider](./mcp-provider.md) — MCP tool integration (complementary to A2A)
|
|
666
|
+
- [HTTP Integration](./http.md) — HTTP server and webhooks
|
|
667
|
+
- [Workflows](./workflows.md) — Reusable workflow definitions
|
|
668
|
+
- [Configuration](./configuration.md) — Configuration reference
|
|
669
|
+
- [Architecture](./architecture.md) — System architecture overview
|
|
670
|
+
- [Security](./security.md) — Security best practices
|
|
671
|
+
- [Debugging](./debugging.md) — Debugging techniques
|
|
672
|
+
- [RFC: A2A Protocol Support](../rfc/001-a2a-protocol-support.md) — Design document
|
|
@@ -27,7 +27,7 @@ This document provides a comprehensive overview of Visor's internal architecture
|
|
|
27
27
|
|
|
28
28
|
## System Overview
|
|
29
29
|
|
|
30
|
-
Visor is an AI-powered workflow orchestration tool that can run as a GitHub Action, CLI tool, or
|
|
30
|
+
Visor is an AI-powered workflow orchestration tool that can run as a GitHub Action, CLI tool, Slack bot, or A2A agent server. The system uses a state machine-based execution engine to orchestrate checks (steps) with sophisticated dependency resolution, routing, and error handling.
|
|
31
31
|
|
|
32
32
|
### High-Level Architecture Diagram
|
|
33
33
|
|
|
@@ -36,16 +36,16 @@ Visor is an AI-powered workflow orchestration tool that can run as a GitHub Acti
|
|
|
36
36
|
| Entry Points |
|
|
37
37
|
+------------------+
|
|
38
38
|
| |
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
39
|
+
+------+------+-----+----+--------+---+----------+
|
|
40
|
+
| | | | |
|
|
41
|
+
v v v v v
|
|
42
|
+
+------+------+ +---+----+ +---+---+ +--+-------+ +----+------+
|
|
43
|
+
| GitHub | | CLI | | Slack | | HTTP | | A2A |
|
|
44
|
+
| Action | | | | Socket| | Webhook | | Agent |
|
|
45
|
+
| (index.ts) | | | | Mode | | Server | | Server |
|
|
46
|
+
+------+------+ +---+----+ +---+---+ +--+-------+ +----+------+
|
|
47
|
+
| | | | |
|
|
48
|
+
+------+------+----------+--------+--------------+
|
|
49
49
|
|
|
|
50
50
|
v
|
|
51
51
|
+----------+-----------+
|
|
@@ -82,7 +82,7 @@ Visor is an AI-powered workflow orchestration tool that can run as a GitHub Acti
|
|
|
82
82
|
|
|
83
83
|
| Component | Description |
|
|
84
84
|
|-----------|-------------|
|
|
85
|
-
| **Entry Points** | GitHub Action, CLI, Slack Socket Mode, HTTP webhooks |
|
|
85
|
+
| **Entry Points** | GitHub Action, CLI, Slack Socket Mode, HTTP webhooks, A2A Agent Protocol |
|
|
86
86
|
| **Configuration Manager** | Loads and validates YAML configuration |
|
|
87
87
|
| **State Machine Engine** | Orchestrates check execution with wave-based scheduling |
|
|
88
88
|
| **Provider Registry** | Registry of pluggable check providers |
|
|
@@ -164,6 +164,33 @@ http_server:
|
|
|
164
164
|
transform: "{{ request.body | json }}"
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
+
### A2A Agent Server (`src/agent-protocol/a2a-frontend.ts`)
|
|
168
|
+
|
|
169
|
+
The A2A (Agent-to-Agent) entry point exposes Visor workflows as standards-compliant A2A agents:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
visor --a2a --config .visor.yaml
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Responsibilities:**
|
|
176
|
+
- Serve Agent Card at `/.well-known/agent-card.json` for discovery
|
|
177
|
+
- Accept tasks via `POST /message:send`
|
|
178
|
+
- Route incoming A2A skills to internal workflows via `skill_routing`
|
|
179
|
+
- Manage task lifecycle (submitted → working → completed/failed)
|
|
180
|
+
- Persist tasks in SQLite via `TaskStore`
|
|
181
|
+
- Execute workflows through the state machine engine
|
|
182
|
+
|
|
183
|
+
**Supported A2A Endpoints:**
|
|
184
|
+
| Method | Path | Auth | Description |
|
|
185
|
+
|--------|------|------|-------------|
|
|
186
|
+
| `GET` | `/.well-known/agent-card.json` | No | Agent Card for discovery |
|
|
187
|
+
| `POST` | `/message:send` | Yes | Submit a task |
|
|
188
|
+
| `GET` | `/tasks/{id}` | Yes | Get task status |
|
|
189
|
+
| `GET` | `/tasks` | Yes | List tasks |
|
|
190
|
+
| `POST` | `/tasks/{id}:cancel` | Yes | Cancel a task |
|
|
191
|
+
|
|
192
|
+
See [A2A Provider](./a2a-provider.md) for complete documentation.
|
|
193
|
+
|
|
167
194
|
---
|
|
168
195
|
|
|
169
196
|
## Core Components
|
|
@@ -264,6 +291,104 @@ checks:
|
|
|
264
291
|
run: [aggregation-step]
|
|
265
292
|
```
|
|
266
293
|
|
|
294
|
+
### Agent Protocol Layer
|
|
295
|
+
|
|
296
|
+
The A2A feature introduces a task-based execution layer that sits between external clients and the workflow engine. This is architecturally separate from the step-level state machine — it governs the lifecycle of inbound agent tasks.
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
External A2A Client
|
|
300
|
+
│
|
|
301
|
+
▼
|
|
302
|
+
┌─────────────────────┐
|
|
303
|
+
│ A2A Frontend │ HTTP server, auth, Agent Card
|
|
304
|
+
│ (a2a-frontend.ts) │
|
|
305
|
+
└──────────┬──────────┘
|
|
306
|
+
│
|
|
307
|
+
▼
|
|
308
|
+
┌─────────────────────┐ ┌─────────────────────┐
|
|
309
|
+
│ Task Store │◄───►│ Task Queue │
|
|
310
|
+
│ (SQLite) │ │ (async execution) │
|
|
311
|
+
└──────────┬──────────┘ └──────────┬──────────┘
|
|
312
|
+
│ │
|
|
313
|
+
▼ ▼
|
|
314
|
+
┌──────────────────────────────────────────────────┐
|
|
315
|
+
│ State Machine Execution Engine │
|
|
316
|
+
│ (same engine used by CLI, GitHub Action, etc.) │
|
|
317
|
+
└──────────────────────────────────────────────────┘
|
|
318
|
+
│
|
|
319
|
+
▼
|
|
320
|
+
┌──────────────────────────────────────────────────┐
|
|
321
|
+
│ Provider Registry → [ai, a2a, command, ...] │
|
|
322
|
+
└──────────────────────────────────────────────────┘
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
#### Task Store (`src/agent-protocol/task-store.ts`)
|
|
326
|
+
|
|
327
|
+
SQLite-backed persistence for A2A tasks:
|
|
328
|
+
|
|
329
|
+
```sql
|
|
330
|
+
CREATE TABLE agent_tasks (
|
|
331
|
+
id TEXT PRIMARY KEY, -- UUID
|
|
332
|
+
context_id TEXT NOT NULL, -- Session grouping
|
|
333
|
+
state TEXT NOT NULL, -- Task state
|
|
334
|
+
created_at TEXT NOT NULL, -- ISO 8601
|
|
335
|
+
updated_at TEXT NOT NULL,
|
|
336
|
+
request_message TEXT NOT NULL, -- JSON: original message
|
|
337
|
+
artifacts TEXT DEFAULT '[]', -- JSON: AgentArtifact[]
|
|
338
|
+
history TEXT DEFAULT '[]', -- JSON: AgentMessage[]
|
|
339
|
+
workflow_id TEXT, -- Target workflow
|
|
340
|
+
run_id TEXT, -- Engine run correlation
|
|
341
|
+
claimed_by TEXT, -- Worker ID (queue)
|
|
342
|
+
claimed_at TEXT, -- Claim timestamp
|
|
343
|
+
ttl TEXT -- Expiration
|
|
344
|
+
);
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
The store provides CRUD operations with state transition enforcement — invalid transitions (e.g., `completed` → `working`) throw `InvalidStateTransitionError`.
|
|
348
|
+
|
|
349
|
+
#### Task Queue (`src/agent-protocol/task-queue.ts`)
|
|
350
|
+
|
|
351
|
+
Manages async task execution with configurable concurrency:
|
|
352
|
+
|
|
353
|
+
- Polls the database at `poll_interval` for unclaimed `submitted` tasks
|
|
354
|
+
- Claims tasks using a worker ID with `stale_claim_timeout` to recover from crashed workers
|
|
355
|
+
- Feeds tasks to the state machine engine, limited by `max_concurrent`
|
|
356
|
+
- Updates task state and artifacts on completion
|
|
357
|
+
|
|
358
|
+
#### Task State Machine (`src/agent-protocol/state-transitions.ts`)
|
|
359
|
+
|
|
360
|
+
Separate from the workflow engine state machine — this governs task lifecycle:
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
submitted ──→ working ──→ completed (terminal)
|
|
364
|
+
│ ├──→ failed (terminal)
|
|
365
|
+
│ ├──→ canceled (terminal)
|
|
366
|
+
│ ├──→ input_required ──→ working (resumed)
|
|
367
|
+
│ └──→ auth_required ──→ working (resumed)
|
|
368
|
+
├──→ canceled (terminal)
|
|
369
|
+
└──→ rejected (terminal)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Terminal states: `completed`, `failed`, `canceled`, `rejected`.
|
|
373
|
+
|
|
374
|
+
#### Agent Card & Discovery
|
|
375
|
+
|
|
376
|
+
The Agent Card is a JSON document describing the agent's capabilities:
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
interface AgentCard {
|
|
380
|
+
name: string;
|
|
381
|
+
description?: string;
|
|
382
|
+
version?: string;
|
|
383
|
+
provider?: { organization: string; url?: string };
|
|
384
|
+
skills?: AgentSkill[]; // Advertised capabilities
|
|
385
|
+
supported_interfaces?: Array<{ url: string; protocol_binding?: string }>;
|
|
386
|
+
capabilities?: { streaming?: boolean; push_notifications?: boolean };
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Skills are mapped to internal workflows via `skill_routing` configuration. When a client sends a message with `metadata.skill_id`, the frontend resolves the target workflow and dispatches execution.
|
|
391
|
+
|
|
267
392
|
---
|
|
268
393
|
|
|
269
394
|
## Provider Architecture
|
|
@@ -311,6 +436,7 @@ class CheckProviderRegistry {
|
|
|
311
436
|
|
|
312
437
|
| Provider | Type | Description |
|
|
313
438
|
|----------|------|-------------|
|
|
439
|
+
| `a2a` | A2A Agent | Calls external A2A-compatible agents |
|
|
314
440
|
| `ai` | AI-powered | Uses Gemini, Claude, OpenAI, or Bedrock for analysis |
|
|
315
441
|
| `command` | Command | Executes shell commands |
|
|
316
442
|
| `script` | Script | Executes JavaScript in a sandbox |
|
|
@@ -508,6 +634,19 @@ checks:
|
|
|
508
634
|
{{ data.message }}
|
|
509
635
|
```
|
|
510
636
|
|
|
637
|
+
### A2A Protocol
|
|
638
|
+
|
|
639
|
+
External agents and orchestrators send tasks via the A2A protocol:
|
|
640
|
+
|
|
641
|
+
1. Client fetches Agent Card from `GET /.well-known/agent-card.json`
|
|
642
|
+
2. Client sends `POST /message:send` with `skill_id` in metadata
|
|
643
|
+
3. A2A Frontend authenticates the request (bearer/api_key)
|
|
644
|
+
4. Task created in TaskStore (state: `submitted`)
|
|
645
|
+
5. Skill routing maps `skill_id` → internal workflow name
|
|
646
|
+
6. Engine executes the workflow (same engine as CLI/GitHub Action)
|
|
647
|
+
7. Task updated with artifacts (state: `completed`)
|
|
648
|
+
8. Client receives response (blocking) or polls `GET /tasks/{id}` (async)
|
|
649
|
+
|
|
511
650
|
---
|
|
512
651
|
|
|
513
652
|
## Data Flow
|
|
@@ -1063,6 +1202,7 @@ Currently, Visor does not cache AI responses between runs. For expensive operati
|
|
|
1063
1202
|
- [Security](./security.md) - Security overview and best practices
|
|
1064
1203
|
- [Providers](./providers/) - Provider-specific documentation
|
|
1065
1204
|
- [Custom Tools](./custom-tools.md) - Creating custom tools
|
|
1205
|
+
- [A2A Provider](./a2a-provider.md) - Agent-to-Agent protocol integration
|
|
1066
1206
|
- [MCP Provider](./mcp-provider.md) - MCP integration details
|
|
1067
1207
|
- [Command Provider](./command-provider.md) - Shell command execution
|
|
1068
1208
|
- [HTTP Integration](./http.md) - HTTP server and client features
|
|
@@ -1100,6 +1240,7 @@ src/
|
|
|
1100
1240
|
providers/
|
|
1101
1241
|
check-provider.interface.ts # Provider base class
|
|
1102
1242
|
check-provider-registry.ts # Provider registry
|
|
1243
|
+
a2a-check-provider.ts # A2A agent client provider
|
|
1103
1244
|
ai-check-provider.ts # AI provider (Gemini, Claude, OpenAI)
|
|
1104
1245
|
claude-code-check-provider.ts # Claude Code SDK provider
|
|
1105
1246
|
command-check-provider.ts # Shell command provider
|
|
@@ -1122,6 +1263,17 @@ src/
|
|
|
1122
1263
|
event-bus.ts # Event bus for frontends
|
|
1123
1264
|
types.ts # Event envelope types
|
|
1124
1265
|
|
|
1266
|
+
agent-protocol/
|
|
1267
|
+
a2a-frontend.ts # A2A HTTP server and endpoints
|
|
1268
|
+
types.ts # Protocol-agnostic types and error classes
|
|
1269
|
+
state-transitions.ts # Task state machine validation
|
|
1270
|
+
task-store.ts # SQLite-backed task persistence
|
|
1271
|
+
task-queue.ts # Async task execution queue
|
|
1272
|
+
task-stream-manager.ts # SSE streaming support
|
|
1273
|
+
push-notification-manager.ts # Push notification delivery
|
|
1274
|
+
tasks-cli-handler.ts # CLI: visor tasks
|
|
1275
|
+
index.ts # Re-exports
|
|
1276
|
+
|
|
1125
1277
|
frontends/
|
|
1126
1278
|
host.ts # Frontend manager
|
|
1127
1279
|
github/ # GitHub integration frontend
|
|
@@ -1183,6 +1335,9 @@ interface VisorConfig {
|
|
|
1183
1335
|
// HTTP server
|
|
1184
1336
|
http_server?: HttpServerConfig;
|
|
1185
1337
|
|
|
1338
|
+
// Agent Protocol (A2A)
|
|
1339
|
+
agent_protocol?: AgentProtocolConfig;
|
|
1340
|
+
|
|
1186
1341
|
// Workflow imports
|
|
1187
1342
|
imports?: string[];
|
|
1188
1343
|
|
|
@@ -1257,4 +1412,11 @@ Events that flow through the state machine:
|
|
|
1257
1412
|
| **Scope** | Hierarchical path for nested workflow execution |
|
|
1258
1413
|
| **Frontend** | Integration point (GitHub, Slack) |
|
|
1259
1414
|
| **Routing** | Control flow based on check results |
|
|
1415
|
+
| **A2A** | Agent-to-Agent protocol — Google's open standard for agent interoperability |
|
|
1416
|
+
| **Agent Card** | JSON metadata describing an agent's capabilities, skills, and endpoints |
|
|
1417
|
+
| **Task** | A unit of work in the A2A protocol with lifecycle state (submitted → working → completed) |
|
|
1418
|
+
| **Skill** | A named capability advertised in an Agent Card, mapped to a Visor workflow |
|
|
1419
|
+
| **Skill Routing** | Configuration mapping A2A skill IDs to internal workflow names |
|
|
1420
|
+
| **Task Store** | SQLite-backed persistence layer for A2A tasks |
|
|
1421
|
+
| **Task Queue** | Async execution queue for processing A2A tasks with concurrency control |
|
|
1260
1422
|
| **MCP** | Model Context Protocol - standard for AI tool integration |
|
package/dist/docs/commands.md
CHANGED
|
@@ -113,6 +113,39 @@ visor mcp-server [options]
|
|
|
113
113
|
- `--mcp-tool-name <name>` - Custom tool name for the MCP server
|
|
114
114
|
- `--mcp-tool-description <desc>` - Custom tool description
|
|
115
115
|
|
|
116
|
+
#### `visor tasks`
|
|
117
|
+
|
|
118
|
+
Monitor and manage A2A agent tasks.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
visor tasks [command] [options]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Subcommands:**
|
|
125
|
+
- `list` (default) — List tasks with optional filters
|
|
126
|
+
- `stats` — Queue summary statistics
|
|
127
|
+
- `cancel <task-id>` — Cancel a running task
|
|
128
|
+
- `help` — Show usage
|
|
129
|
+
|
|
130
|
+
**Options:**
|
|
131
|
+
- `--state <state>` — Filter by state: `submitted`, `working`, `completed`, `failed`, `canceled`
|
|
132
|
+
- `--agent <workflow-id>` — Filter by workflow
|
|
133
|
+
- `--limit <n>` — Number of tasks to show (default: 20)
|
|
134
|
+
- `--output <format>` — Output format: `table` (default), `json`, `markdown`
|
|
135
|
+
- `--watch` — Live refresh every 2 seconds
|
|
136
|
+
|
|
137
|
+
**Examples:**
|
|
138
|
+
```bash
|
|
139
|
+
visor tasks # List all tasks
|
|
140
|
+
visor tasks list --state working # Show only working tasks
|
|
141
|
+
visor tasks list --agent security-review # Tasks for a specific workflow
|
|
142
|
+
visor tasks list --output json # JSON output
|
|
143
|
+
visor tasks list --watch # Live monitoring
|
|
144
|
+
visor tasks stats # Queue summary
|
|
145
|
+
visor tasks stats --output json # Stats as JSON
|
|
146
|
+
visor tasks cancel abc123 # Cancel a task
|
|
147
|
+
```
|
|
148
|
+
|
|
116
149
|
### Common CLI Options
|
|
117
150
|
|
|
118
151
|
#### Check Selection
|
|
@@ -175,6 +208,9 @@ See [Tag Filtering](tag-filtering.md) for detailed tag filtering documentation.
|
|
|
175
208
|
|
|
176
209
|
See [GitHub Authentication](github-auth.md) for setup guide and details.
|
|
177
210
|
|
|
211
|
+
#### Agent Protocol
|
|
212
|
+
- `--a2a` - Enable A2A Agent Protocol server mode (see [A2A Provider](a2a-provider.md))
|
|
213
|
+
|
|
178
214
|
#### Other Options
|
|
179
215
|
- `--slack` - Enable Slack Socket Mode runner
|
|
180
216
|
- `--mode <mode>` - Run mode: `cli` (default) or `github-actions`
|
|
@@ -32,6 +32,7 @@ Visor supports the following check types:
|
|
|
32
32
|
|
|
33
33
|
| Type | Description | Documentation |
|
|
34
34
|
|------|-------------|---------------|
|
|
35
|
+
| `a2a` | Call external A2A agents | [A2A Provider](./a2a-provider.md) |
|
|
35
36
|
| `ai` | AI-powered analysis using LLMs | [AI Configuration](./ai-configuration.md) |
|
|
36
37
|
| `claude-code` | Claude Code SDK integration | [Claude Code](./claude-code.md) |
|
|
37
38
|
| `command` | Execute shell commands | [Command Provider](./command-provider.md) |
|
package/dist/docs/index.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Visor Documentation
|
|
2
2
|
|
|
3
|
-
Visor is an AI-powered workflow orchestration tool for code review, automation, and CI/CD pipelines. It supports multiple AI providers, pluggable check providers, and integrates with GitHub Actions and Slack.
|
|
3
|
+
Visor is an AI-powered workflow orchestration tool for code review, automation, and CI/CD pipelines. It supports multiple AI providers, pluggable check providers, A2A agent interoperability, and integrates with GitHub Actions and Slack.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -35,7 +35,7 @@ Visor is an AI-powered workflow orchestration tool for code review, automation,
|
|
|
35
35
|
|
|
36
36
|
## Providers
|
|
37
37
|
|
|
38
|
-
Visor supports
|
|
38
|
+
Visor supports 16 provider types for different check and workflow operations.
|
|
39
39
|
|
|
40
40
|
### AI Providers
|
|
41
41
|
|
|
@@ -67,6 +67,12 @@ Visor supports 15 provider types for different check and workflow operations.
|
|
|
67
67
|
| [Memory Provider](./memory.md) | Persistent key-value storage for stateful workflows |
|
|
68
68
|
| [Human Input](./human-input-provider.md) | Pause workflows to collect user input via CLI, stdin, or SDK |
|
|
69
69
|
|
|
70
|
+
### Agent Protocol
|
|
71
|
+
|
|
72
|
+
| Document | Description |
|
|
73
|
+
|----------|-------------|
|
|
74
|
+
| [A2A Provider](./a2a-provider.md) | Agent-to-Agent protocol: server mode, client provider, task management, and multi-agent composition |
|
|
75
|
+
|
|
70
76
|
### Utility Providers
|
|
71
77
|
|
|
72
78
|
| Document | Description |
|
|
@@ -187,6 +193,7 @@ Internal design documents, proposals, and implementation tracking.
|
|
|
187
193
|
| [on_init Hook](./rfc/on_init-hook.md) | Lifecycle hook for context preprocessing |
|
|
188
194
|
| [Telemetry Tracing](./telemetry-tracing-rfc.md) | OpenTelemetry tracing architecture |
|
|
189
195
|
| [Test Framework](./test-framework-rfc.md) | In-YAML integration test framework design |
|
|
196
|
+
| [A2A Protocol Support](../rfc/001-a2a-protocol-support.md) | Agent-to-Agent protocol for agent interoperability ([docs](./a2a-provider.md)) |
|
|
190
197
|
|
|
191
198
|
### Design Documents
|
|
192
199
|
|
package/dist/docs/pluggable.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Visor supports multiple provider types. You can also add custom providers.
|
|
4
4
|
|
|
5
|
-
**Built-in Providers:** ai, mcp, command, script, http, http_input, http_client, log, memory, noop, github, human-input, workflow, git-checkout, claude-code
|
|
5
|
+
**Built-in Providers:** a2a, ai, mcp, command, script, http, http_input, http_client, log, memory, noop, github, human-input, workflow, git-checkout, claude-code
|
|
6
6
|
|
|
7
7
|
### Custom Provider Skeleton (TypeScript)
|
|
8
8
|
|
|
@@ -18,6 +18,21 @@ class CustomCheckProvider {
|
|
|
18
18
|
|
|
19
19
|
### Built-in Providers
|
|
20
20
|
|
|
21
|
+
#### A2A Provider (`type: a2a`)
|
|
22
|
+
Call external A2A-compatible agents and collect their responses. Supports agent card discovery, multi-turn conversations, and JavaScript output transforms.
|
|
23
|
+
|
|
24
|
+
```yaml
|
|
25
|
+
steps:
|
|
26
|
+
compliance-check:
|
|
27
|
+
type: a2a
|
|
28
|
+
agent_url: "http://compliance-agent:9000"
|
|
29
|
+
message: "Review PR #{{ pr.number }}: {{ pr.title }}"
|
|
30
|
+
blocking: true
|
|
31
|
+
timeout: 60000
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
[Learn more](./a2a-provider.md)
|
|
35
|
+
|
|
21
36
|
#### AI Provider (`type: ai`)
|
|
22
37
|
Execute AI-powered analysis using Google Gemini, Anthropic Claude, OpenAI, or AWS Bedrock.
|
|
23
38
|
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
process.env.VISOR_VERSION = '0.1.
|
|
2
|
+
process.env.VISOR_VERSION = '0.1.170';
|
|
3
3
|
process.env.PROBE_VERSION = '0.6.0-rc286';
|
|
4
|
-
process.env.VISOR_COMMIT_SHA = '
|
|
5
|
-
process.env.VISOR_COMMIT_SHORT = '
|
|
4
|
+
process.env.VISOR_COMMIT_SHA = '3e49bfdee61154013b28eba096637ac60cdd08ac';
|
|
5
|
+
process.env.VISOR_COMMIT_SHORT = '3e49bfd';
|
|
6
6
|
/******/ (() => { // webpackBootstrap
|
|
7
7
|
/******/ var __webpack_modules__ = ({
|
|
8
8
|
|