agent99 0.0.3 → 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 +38 -0
- data/COMMITS.md +196 -0
- data/DOCS.md +96 -0
- data/README.md +212 -84
- 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/{advanced_features.md → advanced-topics/advanced-features.md} +9 -4
- 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/agent99_framework/central_registry.md +94 -0
- data/docs/agent99_framework/message_client.md +120 -0
- data/docs/agent99_framework/registry_client.md +119 -0
- data/docs/api-reference/agent99-base.md +463 -0
- data/docs/api-reference/message-clients.md +495 -0
- data/docs/{api_reference.md → api-reference/overview.md} +14 -4
- 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/core-concepts/what-is-an-agent.md +293 -0
- 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_discovery.md → framework-components/agent-discovery.md} +9 -5
- data/docs/{agent_registry_processes.md → framework-components/agent-registry.md} +9 -3
- 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/docs/operations/breaking-changes.md +26 -0
- data/examples/DEMO.md +148 -0
- data/examples/README.md +50 -0
- data/examples/agent_watcher.rb +5 -1
- data/examples/bad_agent.rb +32 -0
- data/examples/chief_agent.rb +17 -6
- data/examples/control.rb +16 -7
- data/examples/example_agent.rb +16 -3
- data/examples/maxwell_agent86.rb +15 -26
- data/examples/registry.rb +10 -9
- data/examples/run_demo.rb +433 -0
- data/lib/agent99/agent_discovery.rb +4 -0
- data/lib/agent99/agent_lifecycle.rb +34 -10
- data/lib/agent99/amqp_message_client.rb +2 -2
- data/lib/agent99/base.rb +6 -2
- data/lib/agent99/message_processing.rb +6 -10
- data/lib/agent99/registry_client.rb +15 -11
- data/lib/agent99/tcp_message_client.rb +183 -0
- 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 +93 -30
- 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/{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/{messaging_system.md → framework-components/messaging-system.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,183 @@
|
|
1
|
+
# lib/agent99/tcp_message_client.rb
|
2
|
+
#
|
3
|
+
# NOTE: This is an early attempt at a true
|
4
|
+
# peer-to-peer messaging platform. Its not
|
5
|
+
# not ready for prime time.
|
6
|
+
|
7
|
+
require 'socket'
|
8
|
+
require 'json'
|
9
|
+
require 'logger'
|
10
|
+
|
11
|
+
class Agent99::TcpMessageClient
|
12
|
+
attr_accessor :agents
|
13
|
+
|
14
|
+
def initialize(
|
15
|
+
agents: {},
|
16
|
+
logger: Logger.new($stdout)
|
17
|
+
)
|
18
|
+
@agents = agents
|
19
|
+
@logger = logger
|
20
|
+
@server_socket = nil
|
21
|
+
@client_connections = {}
|
22
|
+
@handlers = {}
|
23
|
+
@running = false
|
24
|
+
end
|
25
|
+
|
26
|
+
def listen_for_messages(queue, request_handler:, response_handler:, control_handler:)
|
27
|
+
@handlers = {
|
28
|
+
request: request_handler,
|
29
|
+
response: response_handler,
|
30
|
+
control: control_handler
|
31
|
+
}
|
32
|
+
|
33
|
+
start_server(queue[:port])
|
34
|
+
end
|
35
|
+
|
36
|
+
def publish(message)
|
37
|
+
target = message.dig(:header, :to_uuid)
|
38
|
+
return unless target
|
39
|
+
|
40
|
+
agent_info = agents(target)
|
41
|
+
return unless agent_info
|
42
|
+
|
43
|
+
socket = connect_to_agent(agent_info[:ip], agent_info[:port])
|
44
|
+
return unless socket
|
45
|
+
|
46
|
+
begin
|
47
|
+
socket.puts(message.to_json)
|
48
|
+
true
|
49
|
+
|
50
|
+
rescue StandardError => e
|
51
|
+
@logger.error("Failed to send message: #{e.message}")
|
52
|
+
false
|
53
|
+
|
54
|
+
ensure
|
55
|
+
socket.close unless socket.closed?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def stop
|
60
|
+
@running = false
|
61
|
+
@server_socket&.close
|
62
|
+
@client_connections.each_value(&:close)
|
63
|
+
@client_connections.clear
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def start_server(port)
|
69
|
+
@server_socket = TCPServer.new(port)
|
70
|
+
@running = true
|
71
|
+
|
72
|
+
Thread.new do
|
73
|
+
while @running
|
74
|
+
begin
|
75
|
+
client = @server_socket.accept
|
76
|
+
handle_client(client)
|
77
|
+
rescue StandardError => e
|
78
|
+
@logger.error("Server error: #{e.message}")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def handle_client(client)
|
85
|
+
Thread.new do
|
86
|
+
while @running
|
87
|
+
begin
|
88
|
+
message = client.gets
|
89
|
+
break if message.nil?
|
90
|
+
|
91
|
+
parsed_message = JSON.parse(message, symbolize_names: true)
|
92
|
+
route_message(parsed_message)
|
93
|
+
|
94
|
+
rescue JSON::ParserError => e
|
95
|
+
@logger.error("Invalid JSON received: #{e.message}")
|
96
|
+
|
97
|
+
rescue StandardError => e
|
98
|
+
@logger.error("Error handling client: #{e.message}")
|
99
|
+
break
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
client.close unless client.closed?
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def route_message(message)
|
108
|
+
type = message.dig(:header, :type)&.to_sym
|
109
|
+
handler = @handlers[type]
|
110
|
+
|
111
|
+
if handler
|
112
|
+
handler.call(message)
|
113
|
+
else
|
114
|
+
@logger.warn("No handler for message type: #{type}")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def connect_to_agent(ip, port)
|
119
|
+
TCPSocket.new(ip, port)
|
120
|
+
|
121
|
+
rescue StandardError => e
|
122
|
+
@logger.error("Failed to connect to #{ip}:#{port}: #{e.message}")
|
123
|
+
nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
__END__
|
129
|
+
|
130
|
+
Based on the provided code for the `Agent99::TcpMessageClient` class, here's an analysis of your questions:
|
131
|
+
|
132
|
+
1. Does this class queue up JSON messages while a previous message is being processed?
|
133
|
+
|
134
|
+
No, this class does not explicitly queue up JSON messages while a previous message is being processed. The class processes messages as they are received, without maintaining an internal queue. Each incoming message is handled in its own thread (see the `handle_client` method), which allows for concurrent processing of messages from multiple clients.
|
135
|
+
|
136
|
+
2. Does it present a complete JSON message at once or does it only provide part of one?
|
137
|
+
|
138
|
+
The class attempts to present complete JSON messages at once. Here's why:
|
139
|
+
|
140
|
+
- In the `handle_client` method, messages are read using `client.gets`, which typically reads a full line of input (up to a newline character).
|
141
|
+
- The received message is then parsed as JSON using `JSON.parse(message, symbolize_names: true)`.
|
142
|
+
- If the parsing is successful, the entire parsed message is passed to the `route_message` method.
|
143
|
+
|
144
|
+
However, there are a few potential issues to consider:
|
145
|
+
|
146
|
+
- If a JSON message spans multiple lines, `client.gets` might not capture the entire message in one read.
|
147
|
+
- There's no explicit handling for partial messages or message boundaries.
|
148
|
+
- Large messages might be split across multiple TCP packets, and the current implementation doesn't account for reassembling these.
|
149
|
+
|
150
|
+
To ensure complete message handling, you might want to consider implementing a more robust message framing protocol, such as using message length prefixes or delimiter-based framing.
|
151
|
+
|
152
|
+
For example, you could modify the `handle_client` method to use a delimiter-based approach:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
def handle_client(client)
|
156
|
+
Thread.new do
|
157
|
+
buffer = ""
|
158
|
+
while @running
|
159
|
+
begin
|
160
|
+
chunk = client.readpartial(1024)
|
161
|
+
buffer += chunk
|
162
|
+
while (message_end = buffer.index("\n"))
|
163
|
+
message = buffer[0...message_end]
|
164
|
+
buffer = buffer[(message_end + 1)..]
|
165
|
+
parsed_message = JSON.parse(message, symbolize_names: true)
|
166
|
+
route_message(parsed_message)
|
167
|
+
end
|
168
|
+
rescue EOFError
|
169
|
+
break
|
170
|
+
rescue JSON::ParserError => e
|
171
|
+
@logger.error("Invalid JSON received: #{e.message}")
|
172
|
+
rescue StandardError => e
|
173
|
+
@logger.error("Error handling client: #{e.message}")
|
174
|
+
break
|
175
|
+
end
|
176
|
+
end
|
177
|
+
client.close unless client.closed?
|
178
|
+
end
|
179
|
+
end
|
180
|
+
```
|
181
|
+
|
182
|
+
This modification would allow for handling of messages that might be split across multiple reads, ensuring that complete JSON messages are processed.
|
183
|
+
|
data/lib/agent99/version.rb
CHANGED
data/lib/agent99.rb
CHANGED
data/mkdocs.yml
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
# MkDocs Configuration for Agent99 Documentation
|
2
|
+
site_name: Agent99 Framework Documentation
|
3
|
+
site_description: Comprehensive documentation for the Agent99 Ruby gem - A framework for building distributed AI agents
|
4
|
+
site_author: Dewayne VanHoozer
|
5
|
+
site_url: https://madbomber.github.io/agent99
|
6
|
+
copyright: Copyright © 2015-2025 Dewayne VanHoozer
|
7
|
+
|
8
|
+
# Repository information
|
9
|
+
repo_url: https://github.com/MadBomber/agent99
|
10
|
+
repo_name: MadBomber/agent99
|
11
|
+
edit_uri: edit/main/docs/
|
12
|
+
|
13
|
+
# Configuration
|
14
|
+
theme:
|
15
|
+
name: material
|
16
|
+
|
17
|
+
# Color scheme - Default to light mode
|
18
|
+
palette:
|
19
|
+
# Palette toggle for light mode (default)
|
20
|
+
- scheme: default
|
21
|
+
primary: blue
|
22
|
+
accent: blue
|
23
|
+
toggle:
|
24
|
+
icon: material/brightness-7
|
25
|
+
name: Switch to dark mode
|
26
|
+
|
27
|
+
# Palette toggle for dark mode
|
28
|
+
- scheme: slate
|
29
|
+
primary: blue
|
30
|
+
accent: blue
|
31
|
+
toggle:
|
32
|
+
icon: material/brightness-4
|
33
|
+
name: Switch to light mode
|
34
|
+
|
35
|
+
# Typography
|
36
|
+
font:
|
37
|
+
text: Roboto
|
38
|
+
code: Roboto Mono
|
39
|
+
|
40
|
+
# Theme features
|
41
|
+
features:
|
42
|
+
# Navigation
|
43
|
+
- navigation.instant
|
44
|
+
- navigation.tracking
|
45
|
+
- navigation.tabs
|
46
|
+
- navigation.tabs.sticky
|
47
|
+
- navigation.sections
|
48
|
+
- navigation.path
|
49
|
+
- navigation.indexes
|
50
|
+
- navigation.top
|
51
|
+
|
52
|
+
# Table of contents
|
53
|
+
- toc.follow
|
54
|
+
|
55
|
+
# Search
|
56
|
+
- search.suggest
|
57
|
+
- search.highlight
|
58
|
+
- search.share
|
59
|
+
|
60
|
+
# Header
|
61
|
+
- header.autohide
|
62
|
+
|
63
|
+
# Content
|
64
|
+
- content.code.copy
|
65
|
+
- content.code.annotate
|
66
|
+
- content.tabs.link
|
67
|
+
- content.tooltips
|
68
|
+
- content.action.edit
|
69
|
+
- content.action.view
|
70
|
+
|
71
|
+
# Plugins
|
72
|
+
plugins:
|
73
|
+
- search:
|
74
|
+
separator: '[\s\-,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
|
75
|
+
|
76
|
+
# Extensions
|
77
|
+
markdown_extensions:
|
78
|
+
# Python Markdown
|
79
|
+
- abbr
|
80
|
+
- admonition
|
81
|
+
- attr_list
|
82
|
+
- def_list
|
83
|
+
- footnotes
|
84
|
+
- md_in_html
|
85
|
+
- toc:
|
86
|
+
permalink: true
|
87
|
+
title: On this page
|
88
|
+
|
89
|
+
# Python Markdown Extensions
|
90
|
+
- pymdownx.arithmatex:
|
91
|
+
generic: true
|
92
|
+
- pymdownx.betterem:
|
93
|
+
smart_enable: all
|
94
|
+
- pymdownx.caret
|
95
|
+
- pymdownx.details
|
96
|
+
- pymdownx.emoji:
|
97
|
+
emoji_generator: !!python/name:material.extensions.emoji.to_svg
|
98
|
+
emoji_index: !!python/name:material.extensions.emoji.twemoji
|
99
|
+
- pymdownx.highlight:
|
100
|
+
anchor_linenums: true
|
101
|
+
line_spans: __span
|
102
|
+
pygments_lang_class: true
|
103
|
+
- pymdownx.inlinehilite
|
104
|
+
- pymdownx.keys
|
105
|
+
- pymdownx.magiclink:
|
106
|
+
repo_url_shorthand: true
|
107
|
+
user: madbomber
|
108
|
+
repo: agent99
|
109
|
+
- pymdownx.mark
|
110
|
+
- pymdownx.smartsymbols
|
111
|
+
- pymdownx.superfences:
|
112
|
+
custom_fences:
|
113
|
+
- name: mermaid
|
114
|
+
class: mermaid
|
115
|
+
format: !!python/name:pymdownx.superfences.fence_code_format
|
116
|
+
- pymdownx.tabbed:
|
117
|
+
alternate_style: true
|
118
|
+
- pymdownx.tasklist:
|
119
|
+
custom_checkbox: true
|
120
|
+
- pymdownx.tilde
|
121
|
+
|
122
|
+
# Extra CSS and JavaScript
|
123
|
+
extra_css:
|
124
|
+
- assets/css/custom.css
|
125
|
+
|
126
|
+
extra_javascript:
|
127
|
+
# - assets/js/mathjax.js
|
128
|
+
- https://polyfill.io/v3/polyfill.min.js?features=es6
|
129
|
+
- https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
|
130
|
+
|
131
|
+
# Social media and extra configuration
|
132
|
+
extra:
|
133
|
+
social:
|
134
|
+
- icon: fontawesome/brands/github
|
135
|
+
link: https://github.com/madbomber/agemt99
|
136
|
+
name: AIA on GitHub
|
137
|
+
- icon: fontawesome/solid/gem
|
138
|
+
link: https://rubygems.org/gems/agemt99
|
139
|
+
name: AIA on RubyGems
|
140
|
+
|
141
|
+
# version:
|
142
|
+
# provider: mike
|
143
|
+
|
144
|
+
# Navigation
|
145
|
+
nav:
|
146
|
+
- Home: index.md
|
147
|
+
- Getting Started:
|
148
|
+
- Overview: getting-started/overview.md
|
149
|
+
- Installation: getting-started/installation.md
|
150
|
+
- Quick Start: getting-started/quick-start.md
|
151
|
+
- Basic Example: getting-started/basic-example.md
|
152
|
+
- Core Concepts:
|
153
|
+
- What is an Agent?: core-concepts/what-is-an-agent.md
|
154
|
+
- Architecture Overview: core-concepts/architecture.md
|
155
|
+
- Agent Lifecycle: core-concepts/agent-lifecycle.md
|
156
|
+
- Agent Types: core-concepts/agent-types.md
|
157
|
+
- Framework Components:
|
158
|
+
- Agent Registry: framework-components/agent-registry.md
|
159
|
+
- Agent Discovery: framework-components/agent-discovery.md
|
160
|
+
- Messaging System: framework-components/messaging-system.md
|
161
|
+
- Message Processing: framework-components/message-processing.md
|
162
|
+
- Agent Development:
|
163
|
+
- Custom Agent Implementation: agent-development/custom-agent-implementation.md
|
164
|
+
- Schema Definition: agent-development/schema-definition.md
|
165
|
+
- Request & Response Handling: agent-development/request-response-handling.md
|
166
|
+
- Error Handling: agent-development/error-handling-and-logging.md
|
167
|
+
- Advanced Topics:
|
168
|
+
- Control Actions: advanced-topics/control-actions.md
|
169
|
+
- Advanced Features: advanced-topics/advanced-features.md
|
170
|
+
- Multi-Agent Processing: advanced-topics/multi-agent-processing.md
|
171
|
+
- A2A Protocol: advanced-topics/a2a-protocol.md
|
172
|
+
- Model Context Protocol: advanced-topics/model-context-protocol.md
|
173
|
+
- Extending the Framework: advanced-topics/extending-the-framework.md
|
174
|
+
- API Reference:
|
175
|
+
- Overview: api-reference/overview.md
|
176
|
+
- Agent99::Base: api-reference/agent99-base.md
|
177
|
+
- Registry Client: api-reference/registry-client.md
|
178
|
+
- Message Clients: api-reference/message-clients.md
|
179
|
+
- Schemas: api-reference/schemas.md
|
180
|
+
- Operations:
|
181
|
+
- Configuration: operations/configuration.md
|
182
|
+
- Security: operations/security.md
|
183
|
+
- Performance Considerations: operations/performance-considerations.md
|
184
|
+
- Troubleshooting: operations/troubleshooting.md
|
185
|
+
- Breaking Changes: operations/breaking-changes.md
|
186
|
+
- Examples:
|
187
|
+
- Basic Examples: examples/basic-examples.md
|
188
|
+
- Advanced Examples: examples/advanced-examples.md
|
189
|
+
- AI Concepts:
|
190
|
+
- HTM: AI/htm.md
|
191
|
+
- Notes on HTM Implementation: AI/notes_on_htm_implementation.md
|
192
|
+
- Internal Framework:
|
193
|
+
- Central Registry: agent99_framework/central_registry.md
|
194
|
+
- Message Client: agent99_framework/message_client.md
|
195
|
+
- Registry Client: agent99_framework/registry_client.md
|