qqeasonchen opened a new pull request, #5408: URL: https://github.com/apache/eventmesh/pull/5408
Fixes #5407 ## Summary of changes **Agent extension points (connector-first):** - **`LlmClient` SPI** (`agent.llm`): token `stream()` + function-calling `chat()` with `ToolSpec`/`ToolCall`/`Completion` records; `OpenAiLlmClient` implements it and gains non-streaming `chat()` (OpenAI tools wire format, mock-tested) - **`ConversationMemory` SPI**: `ConversationStore` (in-memory sliding window) now implements the interface; persistent backends can be constructor-injected - **`AgentTool` SPI + `ToolRegistry`**: name+schema+invoke tools; `StreamingAgent` constructor takes an optional registry and, when non-empty, runs a bounded function-calling loop (≤5 iterations, tool results fed back as messages). No tools registered → behavior unchanged token-by-token streaming - **`ConnectorToolAdapter`**: any `SinkConnector` → write tool (args object wrapped as one CloudEvent → `put()`+`commit()`); any `SourceConnector` → read tool (`poll()` one batch → JSON array). Class-based (system-property wired in `AgentApplication`) and instance-based overloads - **Event-driven triggers**: `agent.subscribe.topics` / `agent.trigger.output.topic` — each consumed CloudEvent becomes a prompt (`trigger:<eventId>` conversation), answered with tools, answer published to the output topic for sink delivery. Uses a dedicated `CloudEventsClient` so the agent lite-channel poller is untouched - **Port drift fix**: `AgentApplication`, `ConnectorApplication`, `start-connector.sh`, `connector.properties`, `agent.properties`, `StreamingCallDemo` — default runtime URL `8080` → `10105` (matches `EventMeshApplication`'s default) - **Docs**: new `docs/feature/agent-tools.md` (extension surface table, connector-as-tools, triggers, embedder API, config reference) + `docs/index.md` entry **Agent boot wiring** (`AgentApplication`): `agent.tools.sink.<name>=<fqcn>` / `agent.tools.source.<name>=<fqcn>` + `agent.tools.props.<name>.*` build the tool registry; connector jars just need to be on the agent classpath. ## Tests - `ToolRegistryTest` — registry lookup, spec rendering, unknown-tool error (3 tests) - `ConnectorToolAdapterTest` — sink tool delivers args as CloudEvent (asserts serialized data), source tool returns batch as JSON array + empty batch (3 tests) - `OpenAiLlmClientChatTest` — tool-call parsing, plain-text completion, tools advertised in request body (3 tests, in-process mock) - All 9 green via JUnit launcher (hermetic; no external LLM) - `ConversationStoreTest` unchanged and still passing (interface extraction is source-compatible: `ConversationStore` still concrete) ## Notes for reviewers - Record components `ToolSpec`/`ToolCall` are flagged [WARN] by local checkstyle 9.0 (`MethodName` on record decls); records are used across the codebase (e.g. `AgentControlClient.RegisterResult`) so CI's checker accepts them - `eventmesh-agent` now depends on `eventmesh-connector-api` (compile) + `io.cloudevents:cloudevents-core` — the architecture guard only constrains plugin→runtime, this direction is unconstrained - Tool-loop answers are published as a single chunk (per-token streaming of the final answer is a follow-up noted in the issue) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
