agent99 0.0.4 → 0.0.5
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.
- checksums.yaml +4 -4
- data/A2A_SPEC-dev.md +1829 -0
- data/CHANGELOG.md +31 -0
- data/COMMITS.md +196 -0
- data/DOCS.md +96 -0
- data/README.md +200 -78
- data/Rakefile +62 -0
- data/docs/AI/htm.md +215 -0
- data/docs/AI/htm.rb +141 -0
- data/docs/AI/htm_demo.db +0 -0
- data/docs/AI/notes_on_htm_implementation.md +1319 -0
- data/docs/AI/some_code.rb +692 -0
- data/docs/advanced-topics/a2a-protocol.md +13 -0
- data/docs/{control_actions.md → advanced-topics/control-actions.md} +2 -0
- data/docs/advanced-topics/model-context-protocol.md +4 -0
- data/docs/advanced-topics/multi-agent-processing.md +674 -0
- data/docs/agent-development/request-response-handling.md +512 -0
- data/docs/api-reference/agent99-base.md +463 -0
- data/docs/api-reference/message-clients.md +495 -0
- data/docs/api-reference/registry-client.md +470 -0
- data/docs/api-reference/schemas.md +518 -0
- data/docs/assets/css/custom.css +27 -0
- data/docs/assets/images/agent-lifecycle.svg +73 -0
- data/docs/assets/images/agent-registry-process.svg +86 -0
- data/docs/assets/images/agent-registry-processes.svg +114 -0
- data/docs/assets/images/agent-types-overview.svg +51 -0
- data/docs/assets/images/agent99-architecture.svg +85 -0
- data/docs/assets/images/agent99_logo.png +0 -0
- data/docs/assets/images/control-actions-state.svg +83 -0
- data/docs/assets/images/knowledge-graph.svg +77 -0
- data/docs/assets/images/message-processing-flow.svg +148 -0
- data/docs/assets/images/multi-agent-system.svg +66 -0
- data/docs/assets/images/proxy-pattern-sequence.svg +48 -0
- data/docs/assets/images/request-flow.svg +97 -0
- data/docs/assets/images/request-processing-lifecycle.svg +50 -0
- data/docs/assets/images/request-response-sequence.svg +39 -0
- data/docs/{agent_lifecycle.md → core-concepts/agent-lifecycle.md} +2 -0
- data/docs/core-concepts/agent-types.md +255 -0
- data/docs/{architecture.md → core-concepts/architecture.md} +5 -5
- data/docs/{what_is_an_agent.md → core-concepts/what-is-an-agent.md} +1 -1
- data/docs/diagrams/message-flow-sequence.svg +198 -0
- data/docs/diagrams/p2p-network-topology.svg +181 -0
- data/docs/diagrams/smart-transport-routing.svg +165 -0
- data/docs/diagrams/three-layer-architecture.svg +77 -0
- data/docs/diagrams/transport-extension-api.svg +309 -0
- data/docs/diagrams/transport-extension-architecture.svg +234 -0
- data/docs/diagrams/transport-selection-flowchart.svg +264 -0
- data/docs/examples/advanced-examples.md +951 -0
- data/docs/examples/basic-examples.md +268 -0
- data/docs/{agent_registry_processes.md → framework-components/agent-registry.md} +1 -1
- data/docs/{message_processing.md → framework-components/message-processing.md} +3 -1
- data/docs/getting-started/basic-example.md +306 -0
- data/docs/getting-started/installation.md +160 -0
- data/docs/getting-started/overview.md +64 -0
- data/docs/getting-started/quick-start.md +179 -0
- data/docs/index.md +97 -0
- data/examples/DEMO.md +148 -0
- data/examples/README.md +50 -0
- data/examples/bad_agent.rb +32 -0
- data/examples/registry.rb +0 -8
- data/examples/run_demo.rb +433 -0
- data/lib/agent99/amqp_message_client.rb +2 -2
- data/lib/agent99/base.rb +1 -1
- data/lib/agent99/message_processing.rb +6 -12
- data/lib/agent99/registry_client.rb +4 -1
- data/lib/agent99/version.rb +1 -1
- data/lib/agent99.rb +1 -1
- data/mkdocs.yml +195 -0
- data/p2p_plan.md +533 -0
- data/p2p_roadmap.md +299 -0
- data/registry_plan.md +1818 -0
- metadata +89 -32
- data/docs/README.md +0 -57
- data/docs/diagrams/agent_registry_processes.dot +0 -42
- data/docs/diagrams/agent_registry_processes.png +0 -0
- data/docs/diagrams/high_level_architecture.dot +0 -26
- data/docs/diagrams/high_level_architecture.png +0 -0
- data/docs/diagrams/request_flow.dot +0 -42
- data/docs/diagrams/request_flow.png +0 -0
- /data/docs/{advanced_features.md → advanced-topics/advanced-features.md} +0 -0
- /data/docs/{extending_the_framework.md → advanced-topics/extending-the-framework.md} +0 -0
- /data/docs/{custom_agent_implementation.md → agent-development/custom-agent-implementation.md} +0 -0
- /data/docs/{error_handling_and_logging.md → agent-development/error-handling-and-logging.md} +0 -0
- /data/docs/{schema_definition.md → agent-development/schema-definition.md} +0 -0
- /data/docs/{api_reference.md → api-reference/overview.md} +0 -0
- /data/docs/{agent_discovery.md → framework-components/agent-discovery.md} +0 -0
- /data/docs/{messaging_system.md → framework-components/messaging-system.md} +0 -0
- /data/docs/{breaking_change_v0.0.4.md → operations/breaking-changes.md} +0 -0
- /data/docs/{configuration.md → operations/configuration.md} +0 -0
- /data/docs/{preformance_considerations.md → operations/performance-considerations.md} +0 -0
- /data/docs/{security.md → operations/security.md} +0 -0
- /data/docs/{troubleshooting.md → operations/troubleshooting.md} +0 -0
@@ -0,0 +1,255 @@
|
|
1
|
+
# Agent Types
|
2
|
+
|
3
|
+
Agent99 supports three fundamental agent types, each designed for different communication patterns and use cases. Understanding these types is crucial for designing effective distributed systems.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+

|
8
|
+
|
9
|
+
## Server Agents
|
10
|
+
|
11
|
+
Server agents **receive and respond to requests** from other agents. They're the workhorses of the Agent99 ecosystem.
|
12
|
+
|
13
|
+
### Characteristics
|
14
|
+
|
15
|
+
- **Reactive**: Wait for incoming requests
|
16
|
+
- **Stateless**: Each request is handled independently (by default)
|
17
|
+
- **Specialized**: Usually focus on specific capabilities
|
18
|
+
- **Discoverable**: Register their capabilities for others to find
|
19
|
+
|
20
|
+
### Example: Server Agent
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
class WeatherAgent < Agent99::Base
|
24
|
+
def info
|
25
|
+
{
|
26
|
+
name: self.class.to_s,
|
27
|
+
type: :server, # This makes it a server agent
|
28
|
+
capabilities: ['weather', 'forecast', 'temperature']
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def process_request(payload)
|
33
|
+
location = payload.dig(:location)
|
34
|
+
|
35
|
+
# Simulate weather lookup
|
36
|
+
weather_data = {
|
37
|
+
location: location,
|
38
|
+
temperature: rand(15..35),
|
39
|
+
condition: ['sunny', 'cloudy', 'rainy'].sample,
|
40
|
+
timestamp: Time.now.iso8601
|
41
|
+
}
|
42
|
+
|
43
|
+
send_response(weather_data)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
### When to Use Server Agents
|
49
|
+
|
50
|
+
- **Services**: Database access, calculations, data processing
|
51
|
+
- **APIs**: Wrapping external APIs or services
|
52
|
+
- **Workers**: Background job processing
|
53
|
+
- **Specialists**: Domain-specific functionality
|
54
|
+
|
55
|
+
## Client Agents
|
56
|
+
|
57
|
+
Client agents **make requests to other agents** and handle their responses. They're the initiators of communication.
|
58
|
+
|
59
|
+
### Characteristics
|
60
|
+
|
61
|
+
- **Proactive**: Initiate communication
|
62
|
+
- **Discovery-aware**: Find and connect to appropriate services
|
63
|
+
- **Request-driven**: Send requests and wait for responses
|
64
|
+
- **Orchestrating**: Can coordinate multiple service calls
|
65
|
+
|
66
|
+
### Example: Client Agent
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
class WeatherClientAgent < Agent99::Base
|
70
|
+
def info
|
71
|
+
{
|
72
|
+
name: self.class.to_s,
|
73
|
+
type: :client, # This makes it a client agent
|
74
|
+
capabilities: ['weather_requester', 'data_aggregator']
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_weather_report(locations)
|
79
|
+
# Find weather service agents
|
80
|
+
weather_agents = discover_agents(['weather'])
|
81
|
+
|
82
|
+
if weather_agents.empty?
|
83
|
+
logger.warn "No weather agents available"
|
84
|
+
return nil
|
85
|
+
end
|
86
|
+
|
87
|
+
weather_agent = weather_agents.first
|
88
|
+
reports = []
|
89
|
+
|
90
|
+
locations.each do |location|
|
91
|
+
request = { location: location }
|
92
|
+
response = send_request(weather_agent[:name], request)
|
93
|
+
reports << response if response
|
94
|
+
end
|
95
|
+
|
96
|
+
reports
|
97
|
+
end
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
### When to Use Client Agents
|
102
|
+
|
103
|
+
- **Aggregators**: Combine data from multiple sources
|
104
|
+
- **Workflows**: Multi-step business processes
|
105
|
+
- **User Interfaces**: Frontend applications
|
106
|
+
- **Schedulers**: Time-based or event-driven tasks
|
107
|
+
|
108
|
+
## Hybrid Agents
|
109
|
+
|
110
|
+
Hybrid agents can **both send and receive requests**. They're the most flexible but also the most complex.
|
111
|
+
|
112
|
+
### Characteristics
|
113
|
+
|
114
|
+
- **Bidirectional**: Can act as both client and server
|
115
|
+
- **Mediating**: Often serve as intermediaries or proxies
|
116
|
+
- **Stateful**: May maintain state across interactions
|
117
|
+
- **Complex**: Handle multiple communication patterns
|
118
|
+
|
119
|
+
### Example: Hybrid Agent
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
class WeatherProxyAgent < Agent99::Base
|
123
|
+
def initialize
|
124
|
+
super
|
125
|
+
@cache = {} # Simple caching
|
126
|
+
@stats = { requests: 0, cache_hits: 0 }
|
127
|
+
end
|
128
|
+
|
129
|
+
def info
|
130
|
+
{
|
131
|
+
name: self.class.to_s,
|
132
|
+
type: :hybrid, # This makes it a hybrid agent
|
133
|
+
capabilities: ['weather_proxy', 'caching', 'analytics']
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
# Server behavior: respond to weather requests
|
138
|
+
def process_request(payload)
|
139
|
+
location = payload.dig(:location)
|
140
|
+
@stats[:requests] += 1
|
141
|
+
|
142
|
+
# Check cache first
|
143
|
+
if @cache[location] && fresh_enough?(@cache[location])
|
144
|
+
@stats[:cache_hits] += 1
|
145
|
+
logger.info "Cache hit for #{location}"
|
146
|
+
send_response(@cache[location][:data])
|
147
|
+
return
|
148
|
+
end
|
149
|
+
|
150
|
+
# Cache miss - get from weather service
|
151
|
+
weather_data = fetch_weather_data(location)
|
152
|
+
|
153
|
+
if weather_data
|
154
|
+
@cache[location] = {
|
155
|
+
data: weather_data,
|
156
|
+
timestamp: Time.now
|
157
|
+
}
|
158
|
+
send_response(weather_data)
|
159
|
+
else
|
160
|
+
send_error("Weather data unavailable for #{location}")
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Client behavior: request from actual weather service
|
165
|
+
private def fetch_weather_data(location)
|
166
|
+
weather_agents = discover_agents(['weather'])
|
167
|
+
return nil if weather_agents.empty?
|
168
|
+
|
169
|
+
weather_agent = weather_agents.first
|
170
|
+
request = { location: location }
|
171
|
+
send_request(weather_agent[:name], request)
|
172
|
+
end
|
173
|
+
|
174
|
+
private def fresh_enough?(cache_entry)
|
175
|
+
Time.now - cache_entry[:timestamp] < 300 # 5 minutes
|
176
|
+
end
|
177
|
+
|
178
|
+
# Additional hybrid behavior: provide statistics
|
179
|
+
def get_statistics
|
180
|
+
{
|
181
|
+
total_requests: @stats[:requests],
|
182
|
+
cache_hits: @stats[:cache_hits],
|
183
|
+
cache_hit_rate: @stats[:requests] > 0 ? @stats[:cache_hits].to_f / @stats[:requests] : 0
|
184
|
+
}
|
185
|
+
end
|
186
|
+
end
|
187
|
+
```
|
188
|
+
|
189
|
+
### When to Use Hybrid Agents
|
190
|
+
|
191
|
+
- **Proxies**: Caching, load balancing, protocol translation
|
192
|
+
- **Middleware**: Authentication, logging, monitoring
|
193
|
+
- **State Managers**: Session management, workflow coordination
|
194
|
+
- **Aggregators**: Collect, process, and redistribute data
|
195
|
+
|
196
|
+
## Agent Type Comparison
|
197
|
+
|
198
|
+
| Feature | Server | Client | Hybrid |
|
199
|
+
|---------|--------|--------|---------|
|
200
|
+
| **Receives Requests** | ✅ | ❌ | ✅ |
|
201
|
+
| **Sends Requests** | ❌ | ✅ | ✅ |
|
202
|
+
| **Complexity** | Low | Medium | High |
|
203
|
+
| **Statefulness** | Usually stateless | Can be stateful | Often stateful |
|
204
|
+
| **Use Cases** | Services, APIs | UIs, Schedulers | Proxies, Middleware |
|
205
|
+
|
206
|
+
## Communication Patterns
|
207
|
+
|
208
|
+
### Request-Response (Server/Client)
|
209
|
+
|
210
|
+

|
211
|
+
|
212
|
+
### Proxy Pattern (Hybrid)
|
213
|
+
|
214
|
+

|
215
|
+
|
216
|
+
## Best Practices
|
217
|
+
|
218
|
+
### Server Agents
|
219
|
+
|
220
|
+
1. **Keep them focused**: One capability per agent
|
221
|
+
2. **Make them stateless**: Each request independent
|
222
|
+
3. **Validate inputs**: Use schemas for safety
|
223
|
+
4. **Handle errors gracefully**: Always respond, even on error
|
224
|
+
|
225
|
+
### Client Agents
|
226
|
+
|
227
|
+
1. **Handle service unavailability**: Graceful degradation
|
228
|
+
2. **Use timeouts**: Don't wait forever
|
229
|
+
3. **Implement retries**: With exponential backoff
|
230
|
+
4. **Cache discoveries**: Don't rediscover every time
|
231
|
+
|
232
|
+
### Hybrid Agents
|
233
|
+
|
234
|
+
1. **Separate concerns**: Clear distinction between client/server logic
|
235
|
+
2. **Manage state carefully**: Consider thread safety
|
236
|
+
3. **Monitor performance**: Track both directions
|
237
|
+
4. **Document behavior**: Complex interactions need clear docs
|
238
|
+
|
239
|
+
## Choosing the Right Type
|
240
|
+
|
241
|
+
Ask yourself:
|
242
|
+
|
243
|
+
- **Do I need to respond to requests?** → Server or Hybrid
|
244
|
+
- **Do I need to make requests?** → Client or Hybrid
|
245
|
+
- **Do I need both?** → Hybrid
|
246
|
+
- **Is simplicity important?** → Avoid Hybrid if possible
|
247
|
+
- **Is this a leaf service?** → Probably Server
|
248
|
+
- **Is this an orchestrator?** → Probably Client
|
249
|
+
- **Is this middleware?** → Probably Hybrid
|
250
|
+
|
251
|
+
## Next Steps
|
252
|
+
|
253
|
+
- **[Agent Lifecycle](agent-lifecycle.md)** - How agents start, run, and stop
|
254
|
+
- **[Architecture Overview](architecture.md)** - How agents fit into the bigger picture
|
255
|
+
- **[Custom Agent Implementation](../agent-development/custom-agent-implementation.md)** - Build your own agents
|
@@ -10,9 +10,9 @@ Agent99 is a Ruby-based framework designed for building and managing software ag
|
|
10
10
|
|
11
11
|
### System Components Diagram
|
12
12
|
|
13
|
-

|
14
14
|
|
15
|
-
The diagram above
|
15
|
+
The diagram above illustrates the key components and their interactions:
|
16
16
|
|
17
17
|
- **Agents**: Come in three types:
|
18
18
|
- Client Agents: Only make requests
|
@@ -72,6 +72,6 @@ The framework supports three primary message types:
|
|
72
72
|
## Implementation Details
|
73
73
|
|
74
74
|
For detailed implementation information, see:
|
75
|
-
- [API Reference](
|
76
|
-
- [Agent Lifecycle](
|
77
|
-
- [Agent Discovery](
|
75
|
+
- [API Reference](../api-reference/agent99-base.md) for method specifications
|
76
|
+
- [Agent Lifecycle](agent-lifecycle.md) for lifecycle management
|
77
|
+
- [Agent Discovery](../framework-components/agent-discovery.md) for discovery mechanisms
|
@@ -156,7 +156,7 @@ It supports three core operations:
|
|
156
156
|
|
157
157
|
#### 1. Register
|
158
158
|
|
159
|
-

|
160
160
|
|
161
161
|
Agents register by providing their information (e.g., name and capabilities) to the registry service. Here's how registration works in practice:
|
162
162
|
|
@@ -0,0 +1,198 @@
|
|
1
|
+
<svg width="1100" height="800" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<!-- Background transparent -->
|
3
|
+
|
4
|
+
<!-- Title -->
|
5
|
+
<text x="550" y="30" text-anchor="middle" fill="#f7fafc"
|
6
|
+
font-family="Arial, sans-serif" font-size="18" font-weight="bold">
|
7
|
+
Agent99 + SmartMessage + Lanet Message Flow
|
8
|
+
</text>
|
9
|
+
|
10
|
+
<!-- Entity columns -->
|
11
|
+
<line x1="150" y1="60" x2="150" y2="750" stroke="#4a5568" stroke-width="2"/>
|
12
|
+
<rect x="80" y="60" width="140" height="40" fill="#1a365d" stroke="#3182ce" stroke-width="2" rx="5"/>
|
13
|
+
<text x="150" y="85" text-anchor="middle" fill="#bee3f8"
|
14
|
+
font-family="Arial, sans-serif" font-size="12" font-weight="bold">
|
15
|
+
Source Agent
|
16
|
+
</text>
|
17
|
+
|
18
|
+
<line x1="350" y1="60" x2="350" y2="750" stroke="#4a5568" stroke-width="2"/>
|
19
|
+
<rect x="275" y="60" width="150" height="40" fill="#553c9a" stroke="#7c3aed" stroke-width="2" rx="5"/>
|
20
|
+
<text x="350" y="85" text-anchor="middle" fill="#e9d5ff"
|
21
|
+
font-family="Arial, sans-serif" font-size="12" font-weight="bold">
|
22
|
+
SmartMessage
|
23
|
+
</text>
|
24
|
+
|
25
|
+
<line x1="550" y1="60" x2="550" y2="750" stroke="#4a5568" stroke-width="2"/>
|
26
|
+
<rect x="480" y="60" width="140" height="40" fill="#065f46" stroke="#10b981" stroke-width="2" rx="5"/>
|
27
|
+
<text x="550" y="85" text-anchor="middle" fill="#d1fae5"
|
28
|
+
font-family="Arial, sans-serif" font-size="12" font-weight="bold">
|
29
|
+
Lanet Transport
|
30
|
+
</text>
|
31
|
+
|
32
|
+
<line x1="750" y1="60" x2="750" y2="750" stroke="#4a5568" stroke-width="2"/>
|
33
|
+
<rect x="680" y="60" width="140" height="40" fill="#92400e" stroke="#f59e0b" stroke-width="2" rx="5"/>
|
34
|
+
<text x="750" y="85" text-anchor="middle" fill="#fef3c7"
|
35
|
+
font-family="Arial, sans-serif" font-size="12" font-weight="bold">
|
36
|
+
NATS/AMQP
|
37
|
+
</text>
|
38
|
+
|
39
|
+
<line x1="950" y1="60" x2="950" y2="750" stroke="#4a5568" stroke-width="2"/>
|
40
|
+
<rect x="880" y="60" width="140" height="40" fill="#2d3748" stroke="#4a5568" stroke-width="2" rx="5"/>
|
41
|
+
<text x="950" y="85" text-anchor="middle" fill="#e2e8f0"
|
42
|
+
font-family="Arial, sans-serif" font-size="12" font-weight="bold">
|
43
|
+
Target Agent
|
44
|
+
</text>
|
45
|
+
|
46
|
+
<!-- Arrow definitions -->
|
47
|
+
<defs>
|
48
|
+
<marker id="arrow" markerWidth="10" markerHeight="7"
|
49
|
+
refX="9" refY="3.5" orient="auto">
|
50
|
+
<polygon points="0 0, 10 3.5, 0 7" fill="#cbd5e0"/>
|
51
|
+
</marker>
|
52
|
+
<marker id="greenarrow" markerWidth="10" markerHeight="7"
|
53
|
+
refX="9" refY="3.5" orient="auto">
|
54
|
+
<polygon points="0 0, 10 3.5, 0 7" fill="#10b981"/>
|
55
|
+
</marker>
|
56
|
+
<marker id="yellowarrow" markerWidth="10" markerHeight="7"
|
57
|
+
refX="9" refY="3.5" orient="auto">
|
58
|
+
<polygon points="0 0, 10 3.5, 0 7" fill="#f59e0b"/>
|
59
|
+
</marker>
|
60
|
+
</defs>
|
61
|
+
|
62
|
+
<!-- Message Flow Steps -->
|
63
|
+
|
64
|
+
<!-- Step 1: Agent publishes message -->
|
65
|
+
<line x1="150" y1="130" x2="340" y2="130"
|
66
|
+
stroke="#cbd5e0" stroke-width="2" marker-end="url(#arrow)"/>
|
67
|
+
<text x="245" y="125" text-anchor="middle" fill="#cbd5e0"
|
68
|
+
font-family="Arial, sans-serif" font-size="10">
|
69
|
+
1. publish(:greeting, to: 'target_uuid')
|
70
|
+
</text>
|
71
|
+
|
72
|
+
<!-- Step 2: SmartMessage routing decision -->
|
73
|
+
<rect x="270" y="150" width="160" height="60"
|
74
|
+
fill="#44337a" stroke="#7c3aed" stroke-width="2" rx="5" opacity="0.8"/>
|
75
|
+
<text x="350" y="170" text-anchor="middle" fill="#e9d5ff"
|
76
|
+
font-family="Arial, sans-serif" font-size="11" font-weight="bold">
|
77
|
+
2. Transport Selection
|
78
|
+
</text>
|
79
|
+
<text x="350" y="185" text-anchor="middle" fill="#c4b5fd"
|
80
|
+
font-family="Arial, sans-serif" font-size="10">
|
81
|
+
Check: same_lan?(target)
|
82
|
+
</text>
|
83
|
+
<text x="350" y="200" text-anchor="middle" fill="#c4b5fd"
|
84
|
+
font-family="Arial, sans-serif" font-size="10">
|
85
|
+
→ Use Lanet for LAN
|
86
|
+
</text>
|
87
|
+
|
88
|
+
<!-- Step 3a: LAN route (Lanet) -->
|
89
|
+
<line x1="350" y1="230" x2="540" y2="250"
|
90
|
+
stroke="#10b981" stroke-width="3" marker-end="url(#greenarrow)"/>
|
91
|
+
<text x="445" y="235" text-anchor="middle" fill="#10b981"
|
92
|
+
font-family="Arial, sans-serif" font-size="10" font-weight="bold">
|
93
|
+
3a. LAN: Lanet.send_to(ip, message)
|
94
|
+
</text>
|
95
|
+
|
96
|
+
<!-- Step 3b: WAN route (NATS/AMQP) -->
|
97
|
+
<line x1="350" y1="280" x2="740" y2="300"
|
98
|
+
stroke="#f59e0b" stroke-width="2" stroke-dasharray="8,4" marker-end="url(#yellowarrow)"/>
|
99
|
+
<text x="545" y="285" text-anchor="middle" fill="#f59e0b"
|
100
|
+
font-family="Arial, sans-serif" font-size="10">
|
101
|
+
3b. WAN: broker.publish(queue, message)
|
102
|
+
</text>
|
103
|
+
|
104
|
+
<!-- Step 4a: Lanet direct delivery -->
|
105
|
+
<line x1="550" y1="330" x2="940" y2="350"
|
106
|
+
stroke="#10b981" stroke-width="3" marker-end="url(#greenarrow)"/>
|
107
|
+
<text x="745" y="335" text-anchor="middle" fill="#10b981"
|
108
|
+
font-family="Arial, sans-serif" font-size="10" font-weight="bold">
|
109
|
+
4a. Direct P2P delivery (encrypted)
|
110
|
+
</text>
|
111
|
+
|
112
|
+
<!-- Step 4b: Broker delivery -->
|
113
|
+
<line x1="750" y1="380" x2="940" y2="400"
|
114
|
+
stroke="#f59e0b" stroke-width="2" stroke-dasharray="8,4" marker-end="url(#yellowarrow)"/>
|
115
|
+
<text x="845" y="385" text-anchor="middle" fill="#f59e0b"
|
116
|
+
font-family="Arial, sans-serif" font-size="10">
|
117
|
+
4b. Broker delivery
|
118
|
+
</text>
|
119
|
+
|
120
|
+
<!-- Step 5: Message processing -->
|
121
|
+
<rect x="870" y="430" width="160" height="60"
|
122
|
+
fill="#1f2937" stroke="#4b5563" stroke-width="2" rx="5" opacity="0.8"/>
|
123
|
+
<text x="950" y="450" text-anchor="middle" fill="#e5e7eb"
|
124
|
+
font-family="Arial, sans-serif" font-size="11" font-weight="bold">
|
125
|
+
5. Process Message
|
126
|
+
</text>
|
127
|
+
<text x="950" y="465" text-anchor="middle" fill="#d1d5db"
|
128
|
+
font-family="Arial, sans-serif" font-size="10">
|
129
|
+
SmartMessage.handle()
|
130
|
+
</text>
|
131
|
+
<text x="950" y="480" text-anchor="middle" fill="#d1d5db"
|
132
|
+
font-family="Arial, sans-serif" font-size="10">
|
133
|
+
→ Agent business logic
|
134
|
+
</text>
|
135
|
+
|
136
|
+
<!-- Response flow -->
|
137
|
+
<text x="550" y="540" text-anchor="middle" fill="#cbd5e0"
|
138
|
+
font-family="Arial, sans-serif" font-size="14" font-weight="bold">
|
139
|
+
Response Flow (Same Path in Reverse)
|
140
|
+
</text>
|
141
|
+
|
142
|
+
<!-- Response step 6 -->
|
143
|
+
<line x1="950" y1="570" x2="360" y2="590"
|
144
|
+
stroke="#a78bfa" stroke-width="2" stroke-dasharray="3,3" marker-end="url(#arrow)"/>
|
145
|
+
<text x="655" y="575" text-anchor="middle" fill="#a78bfa"
|
146
|
+
font-family="Arial, sans-serif" font-size="10">
|
147
|
+
6. Response via same transport path
|
148
|
+
</text>
|
149
|
+
|
150
|
+
<!-- Response step 7 -->
|
151
|
+
<line x1="350" y1="620" x2="160" y2="640"
|
152
|
+
stroke="#a78bfa" stroke-width="2" stroke-dasharray="3,3" marker-end="url(#arrow)"/>
|
153
|
+
<text x="255" y="625" text-anchor="middle" fill="#a78bfa"
|
154
|
+
font-family="Arial, sans-serif" font-size="10">
|
155
|
+
7. Delivered to source agent
|
156
|
+
</text>
|
157
|
+
|
158
|
+
<!-- Benefits box -->
|
159
|
+
<rect x="50" y="680" width="1000" height="60"
|
160
|
+
fill="#0f172a" stroke="#334155" stroke-width="1" rx="5" opacity="0.9"/>
|
161
|
+
<text x="70" y="705" fill="#f1f5f9"
|
162
|
+
font-family="Arial, sans-serif" font-size="12" font-weight="bold">
|
163
|
+
Benefits:
|
164
|
+
</text>
|
165
|
+
<text x="140" y="705" fill="#cbd5e0"
|
166
|
+
font-family="Arial, sans-serif" font-size="11">
|
167
|
+
• Automatic transport selection
|
168
|
+
</text>
|
169
|
+
<text x="320" y="705" fill="#cbd5e0"
|
170
|
+
font-family="Arial, sans-serif" font-size="11">
|
171
|
+
• Unified API regardless of transport
|
172
|
+
</text>
|
173
|
+
<text x="520" y="705" fill="#cbd5e0"
|
174
|
+
font-family="Arial, sans-serif" font-size="11">
|
175
|
+
• LAN optimization with Lanet P2P
|
176
|
+
</text>
|
177
|
+
<text x="720" y="705" fill="#cbd5e0"
|
178
|
+
font-family="Arial, sans-serif" font-size="11">
|
179
|
+
• WAN fallback with brokers
|
180
|
+
</text>
|
181
|
+
|
182
|
+
<text x="140" y="725" fill="#cbd5e0"
|
183
|
+
font-family="Arial, sans-serif" font-size="11">
|
184
|
+
• Built-in encryption/security
|
185
|
+
</text>
|
186
|
+
<text x="320" y="725" fill="#cbd5e0"
|
187
|
+
font-family="Arial, sans-serif" font-size="11">
|
188
|
+
• Clean separation of concerns
|
189
|
+
</text>
|
190
|
+
<text x="520" y="725" fill="#cbd5e0"
|
191
|
+
font-family="Arial, sans-serif" font-size="11">
|
192
|
+
• Transparent to Agent99 logic
|
193
|
+
</text>
|
194
|
+
<text x="720" y="725" fill="#cbd5e0"
|
195
|
+
font-family="Arial, sans-serif" font-size="11">
|
196
|
+
• Extensible plugin architecture
|
197
|
+
</text>
|
198
|
+
</svg>
|
@@ -0,0 +1,181 @@
|
|
1
|
+
<svg width="1000" height="700" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<!-- Background transparent -->
|
3
|
+
|
4
|
+
<!-- Title -->
|
5
|
+
<text x="500" y="30" text-anchor="middle" fill="#f7fafc"
|
6
|
+
font-family="Arial, sans-serif" font-size="20" font-weight="bold">
|
7
|
+
Agent99 Hybrid P2P Network Topology
|
8
|
+
</text>
|
9
|
+
|
10
|
+
<!-- LAN 1 -->
|
11
|
+
<rect x="50" y="80" width="400" height="250"
|
12
|
+
fill="none" stroke="#10b981" stroke-width="2" stroke-dasharray="10,5" rx="15"/>
|
13
|
+
<text x="250" y="105" text-anchor="middle" fill="#10b981"
|
14
|
+
font-family="Arial, sans-serif" font-size="16" font-weight="bold">
|
15
|
+
LAN Segment 1 (192.168.1.0/24)
|
16
|
+
</text>
|
17
|
+
|
18
|
+
<!-- LAN 2 -->
|
19
|
+
<rect x="550" y="80" width="400" height="250"
|
20
|
+
fill="none" stroke="#3b82f6" stroke-width="2" stroke-dasharray="10,5" rx="15"/>
|
21
|
+
<text x="750" y="105" text-anchor="middle" fill="#3b82f6"
|
22
|
+
font-family="Arial, sans-serif" font-size="16" font-weight="bold">
|
23
|
+
LAN Segment 2 (192.168.2.0/24)
|
24
|
+
</text>
|
25
|
+
|
26
|
+
<!-- Registry Server -->
|
27
|
+
<rect x="425" y="400" width="150" height="80"
|
28
|
+
fill="#7c2d12" stroke="#dc2626" stroke-width="3" rx="10"/>
|
29
|
+
<text x="500" y="430" text-anchor="middle" fill="#fef2f2"
|
30
|
+
font-family="Arial, sans-serif" font-size="14" font-weight="bold">
|
31
|
+
Agent Registry
|
32
|
+
</text>
|
33
|
+
<text x="500" y="450" text-anchor="middle" fill="#fecaca"
|
34
|
+
font-family="Arial, sans-serif" font-size="12">
|
35
|
+
Central Discovery
|
36
|
+
</text>
|
37
|
+
<text x="500" y="470" text-anchor="middle" fill="#fecaca"
|
38
|
+
font-family="Arial, sans-serif" font-size="12">
|
39
|
+
& Coordination
|
40
|
+
</text>
|
41
|
+
|
42
|
+
<!-- NATS/AMQP Broker -->
|
43
|
+
<rect x="425" y="520" width="150" height="80"
|
44
|
+
fill="#92400e" stroke="#f59e0b" stroke-width="3" rx="10"/>
|
45
|
+
<text x="500" y="550" text-anchor="middle" fill="#fef3c7"
|
46
|
+
font-family="Arial, sans-serif" font-size="14" font-weight="bold">
|
47
|
+
Message Broker
|
48
|
+
</text>
|
49
|
+
<text x="500" y="570" text-anchor="middle" fill="#fde68a"
|
50
|
+
font-family="Arial, sans-serif" font-size="12">
|
51
|
+
NATS/AMQP
|
52
|
+
</text>
|
53
|
+
<text x="500" y="590" text-anchor="middle" fill="#fde68a"
|
54
|
+
font-family="Arial, sans-serif" font-size="12">
|
55
|
+
Cross-LAN Bridge
|
56
|
+
</text>
|
57
|
+
|
58
|
+
<!-- Agents in LAN 1 -->
|
59
|
+
<circle cx="150" cy="180" r="30" fill="#1a365d" stroke="#3182ce" stroke-width="2"/>
|
60
|
+
<text x="150" y="185" text-anchor="middle" fill="#bee3f8"
|
61
|
+
font-family="Arial, sans-serif" font-size="10" font-weight="bold">
|
62
|
+
Agent A
|
63
|
+
</text>
|
64
|
+
|
65
|
+
<circle cx="280" cy="150" r="30" fill="#1a365d" stroke="#3182ce" stroke-width="2"/>
|
66
|
+
<text x="280" y="155" text-anchor="middle" fill="#bee3f8"
|
67
|
+
font-family="Arial, sans-serif" font-size="10" font-weight="bold">
|
68
|
+
Agent B
|
69
|
+
</text>
|
70
|
+
|
71
|
+
<circle cx="350" cy="220" r="30" fill="#1a365d" stroke="#3182ce" stroke-width="2"/>
|
72
|
+
<text x="350" y="225" text-anchor="middle" fill="#bee3f8"
|
73
|
+
font-family="Arial, sans-serif" font-size="10" font-weight="bold">
|
74
|
+
Agent C
|
75
|
+
</text>
|
76
|
+
|
77
|
+
<!-- Agents in LAN 2 -->
|
78
|
+
<circle cx="650" cy="180" r="30" fill="#2d3748" stroke="#4a5568" stroke-width="2"/>
|
79
|
+
<text x="650" y="185" text-anchor="middle" fill="#e2e8f0"
|
80
|
+
font-family="Arial, sans-serif" font-size="10" font-weight="bold">
|
81
|
+
Agent X
|
82
|
+
</text>
|
83
|
+
|
84
|
+
<circle cx="780" cy="150" r="30" fill="#2d3748" stroke="#4a5568" stroke-width="2"/>
|
85
|
+
<text x="780" y="155" text-anchor="middle" fill="#e2e8f0"
|
86
|
+
font-family="Arial, sans-serif" font-size="10" font-weight="bold">
|
87
|
+
Agent Y
|
88
|
+
</text>
|
89
|
+
|
90
|
+
<circle cx="850" cy="220" r="30" fill="#2d3748" stroke="#4a5568" stroke-width="2"/>
|
91
|
+
<text x="850" y="225" text-anchor="middle" fill="#e2e8f0"
|
92
|
+
font-family="Arial, sans-serif" font-size="10" font-weight="bold">
|
93
|
+
Agent Z
|
94
|
+
</text>
|
95
|
+
|
96
|
+
<!-- Lanet P2P Connections within LANs (green) -->
|
97
|
+
<defs>
|
98
|
+
<marker id="greenarrow" markerWidth="8" markerHeight="6"
|
99
|
+
refX="7" refY="3" orient="auto">
|
100
|
+
<polygon points="0 0, 8 3, 0 6" fill="#10b981"/>
|
101
|
+
</marker>
|
102
|
+
<marker id="yellowarrow" markerWidth="8" markerHeight="6"
|
103
|
+
refX="7" refY="3" orient="auto">
|
104
|
+
<polygon points="0 0, 8 3, 0 6" fill="#f59e0b"/>
|
105
|
+
</marker>
|
106
|
+
<marker id="redarrow" markerWidth="8" markerHeight="6"
|
107
|
+
refX="7" refY="3" orient="auto">
|
108
|
+
<polygon points="0 0, 8 3, 0 6" fill="#dc2626"/>
|
109
|
+
</marker>
|
110
|
+
</defs>
|
111
|
+
|
112
|
+
<!-- P2P connections in LAN 1 -->
|
113
|
+
<line x1="180" y1="180" x2="250" y2="150"
|
114
|
+
stroke="#10b981" stroke-width="3" stroke-dasharray="5,3"
|
115
|
+
marker-end="url(#greenarrow)"/>
|
116
|
+
<line x1="250" y1="170" x2="180" y2="180"
|
117
|
+
stroke="#10b981" stroke-width="2" stroke-dasharray="5,3"
|
118
|
+
marker-end="url(#greenarrow)"/>
|
119
|
+
<line x1="310" y1="150" x2="340" y2="190"
|
120
|
+
stroke="#10b981" stroke-width="3" stroke-dasharray="5,3"
|
121
|
+
marker-end="url(#greenarrow)"/>
|
122
|
+
|
123
|
+
<!-- P2P connections in LAN 2 -->
|
124
|
+
<line x1="680" y1="180" x2="750" y2="150"
|
125
|
+
stroke="#10b981" stroke-width="3" stroke-dasharray="5,3"
|
126
|
+
marker-end="url(#greenarrow)"/>
|
127
|
+
<line x1="750" y1="170" x2="680" y2="180"
|
128
|
+
stroke="#10b981" stroke-width="2" stroke-dasharray="5,3"
|
129
|
+
marker-end="url(#greenarrow)"/>
|
130
|
+
<line x1="810" y1="150" x2="840" y2="190"
|
131
|
+
stroke="#10b981" stroke-width="3" stroke-dasharray="5,3"
|
132
|
+
marker-end="url(#greenarrow)"/>
|
133
|
+
|
134
|
+
<!-- Cross-LAN broker connections (yellow) -->
|
135
|
+
<line x1="350" y1="250" x2="450" y2="520"
|
136
|
+
stroke="#f59e0b" stroke-width="2"
|
137
|
+
marker-end="url(#yellowarrow)"/>
|
138
|
+
<line x1="650" y1="250" x2="550" y2="520"
|
139
|
+
stroke="#f59e0b" stroke-width="2"
|
140
|
+
marker-end="url(#yellowarrow)"/>
|
141
|
+
|
142
|
+
<!-- Registry connections (red) -->
|
143
|
+
<line x1="280" y1="280" x2="450" y2="400"
|
144
|
+
stroke="#dc2626" stroke-width="2"
|
145
|
+
marker-end="url(#redarrow)"/>
|
146
|
+
<line x1="750" y1="280" x2="550" y2="400"
|
147
|
+
stroke="#dc2626" stroke-width="2"
|
148
|
+
marker-end="url(#redarrow)"/>
|
149
|
+
|
150
|
+
<!-- Legend -->
|
151
|
+
<rect x="50" y="620" width="900" height="60"
|
152
|
+
fill="#1a202c" stroke="#2d3748" stroke-width="1" rx="5"/>
|
153
|
+
<text x="70" y="645" fill="#f7fafc"
|
154
|
+
font-family="Arial, sans-serif" font-size="14" font-weight="bold">
|
155
|
+
Connection Types:
|
156
|
+
</text>
|
157
|
+
|
158
|
+
<line x1="200" y1="650" x2="250" y2="650"
|
159
|
+
stroke="#10b981" stroke-width="3" stroke-dasharray="5,3"
|
160
|
+
marker-end="url(#greenarrow)"/>
|
161
|
+
<text x="260" y="655" fill="#10b981"
|
162
|
+
font-family="Arial, sans-serif" font-size="12">
|
163
|
+
Lanet P2P (Same LAN)
|
164
|
+
</text>
|
165
|
+
|
166
|
+
<line x1="420" y1="650" x2="470" y2="650"
|
167
|
+
stroke="#f59e0b" stroke-width="2"
|
168
|
+
marker-end="url(#yellowarrow)"/>
|
169
|
+
<text x="480" y="655" fill="#f59e0b"
|
170
|
+
font-family="Arial, sans-serif" font-size="12">
|
171
|
+
Broker (Cross-LAN)
|
172
|
+
</text>
|
173
|
+
|
174
|
+
<line x1="620" y1="650" x2="670" y2="650"
|
175
|
+
stroke="#dc2626" stroke-width="2"
|
176
|
+
marker-end="url(#redarrow)"/>
|
177
|
+
<text x="680" y="655" fill="#dc2626"
|
178
|
+
font-family="Arial, sans-serif" font-size="12">
|
179
|
+
Registry (Discovery)
|
180
|
+
</text>
|
181
|
+
</svg>
|