Skip to content

Add Agents skills#4327

Open
nelsonkopliku wants to merge 1 commit into
mainfrom
add-agents-skills
Open

Add Agents skills#4327
nelsonkopliku wants to merge 1 commit into
mainfrom
add-agents-skills

Conversation

@nelsonkopliku

@nelsonkopliku nelsonkopliku commented May 21, 2026

Copy link
Copy Markdown
Member

Description

This PR is the result of many conversations with Claude.

Hoping it to be useful for the team.

Visual here

Many copilot complaints are because referenced content is actually here #4320

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an agents/skills/ documentation set intended to help agent CLIs/tools understand Trento’s AI Assistant architecture (Elixir + Phoenix channel side, and React/JS client side), plus a generic sagents v0.7 reference pack.

Changes:

  • Added a Trento AI Assistant “backend” skill (trento-ai-assistant) describing the purported Elixir/Phoenix + sagents/langchain stack.
  • Added a Trento AI Assistant UI skill (trento-ai-assistant-ui) documenting the React components and WebSocketAIAgent transport.
  • Added a generic sagents v0.7 skill with several topic deep-dives, and a top-level skills README.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
agents/skills/README.md Introduces the skills directory and how to consume it in different tools.
agents/skills/trento-ai-assistant/SKILL.md Documents the supposed Elixir/Phoenix-channel AI Assistant stack and contracts.
agents/skills/trento-ai-assistant-ui/SKILL.md Documents the React/JS AI Assistant client and AG-UI event flow.
agents/skills/sagents/SKILL.md One-page sagents v0.7 cheat sheet and index of topic docs.
agents/skills/sagents/api.md sagents API reference overview.
agents/skills/sagents/context.md Explains scope vs tool_context vs state.metadata and propagation rules.
agents/skills/sagents/disabling-middleware.md Guidance for safely commenting out built-in middleware while keeping revertability.
agents/skills/sagents/filesystem.md FileSystem middleware usage/persistence/scoping notes.
agents/skills/sagents/middleware.md Middleware callback surface, ordering rules, tools, interrupts, observability.
agents/skills/sagents/migration-v0.6-to-v0.7.md Migration guide for the v0.6 → v0.7 scope signature break.
agents/skills/sagents/persistence.md Agent state vs display-message persistence behaviors and lifecycle.
agents/skills/sagents/pubsub-events.md PubSub topic/event envelope and event category reference.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread agents/skills/trento-ai-assistant/SKILL.md
Comment thread agents/skills/trento-ai-assistant/SKILL.md
Comment thread agents/skills/README.md
Comment thread agents/skills/trento-ai-assistant-ui/SKILL.md

@chargio chargio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a skill the best way to do this?

You can add skills for Elixir and Phoenix to the tools directly.
What a new Phoenix app does is to add an AGENTS.md file that explains things like:

  • Use 'mix precomit',
  • Use the already included library
  • Use layouts etc...

Most of it should be adapted to Trento because we don't use LIveView, but we can also add information about the project itself.
For instance,

  • Never create PR that are longer than 400 lines
  • Store information in xxx

And architecture descriptions that establish the components used, their relationship, how to test, etc.

@nelsonkopliku

Copy link
Copy Markdown
Member Author

Thanks for the feedback, @chargio!

I believe the content is valid, and I am ok in discussing about the form/location.

Is a skill the best way to do this?

I am not sure, still experimenting.
I believe we might want to start from somewhere anyway and I'd be fine in moving the content into an AGENTS.md file.
If we realize we need/want skills we can always revisit.

In any case the content here would be covering only partly the wholeness of Trento, so we'd need more.

You can add skills for Elixir and Phoenix to the tools directly

What do you mean here?

And architecture descriptions that establish the components used, their relationship, how to test, etc.

Yes, agreed. This is definitely we might want to add to AGENTS.md

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 10 comments.

Comment on lines +1 to +3
---
name: trento-ai-assistant
description: Use when modifying TrentoWeb.AIAssistantChannel, TrentoWeb.AIAssistant.AgUi, TrentoWeb.AIAssistantTools, the AI Assistant system prompt, or anything under Trento.AI.* (Agent + Server/Supervisor adapters + LLMBuilder + LLMRegistry + Configurations + UserConfiguration) or Trento.Infrastructure.AI.*. Covers the layered architecture from React assistant-ui down to the Gemini API, the PubSub event vocabulary the channel reacts to, the AG-UI event types emitted over the WebSocket, the Mox adapter pattern wrapping sagents, the langchain fork patches, model selection trade-offs, and how to verify changes end-to-end. Also useful when debugging "Sorry, I encountered an error" messages or when adding new tools, new AG-UI event types, or new prompt sections.
Comment on lines +13 to +16
- Editing `lib/trento_web/channels/ai_assistant_channel.ex`
- Editing `lib/trento_web/channels/ai_assistant/ag_ui.ex`
- Editing `lib/trento_web/channels/ai_assistant/ai_assistant_tools.ex`
- Editing the `@system_prompt` inside `lib/trento/ai/agent.ex`
Comment on lines +20 to +23
- Debugging an `Sorry, I encountered an error: ...` or `Failed to start agent...` push reaching the React UI
- Designing a new AG-UI event type to push to the client
- Adding a new tool to `AIAssistantTools.tools/0`
- Diagnosing `MALFORMED_FUNCTION_CALL`, `Exceeded max failure count`, `:lists.flatten("")`, or any langchain `LangChainError`
Comment on lines +66 to +67
| `TrentoWeb.AIAssistant.AgUi` | `lib/trento_web/channels/ai_assistant/ag_ui.ex` | Socket-in/socket-out functions for every AG-UI event the channel emits. Owns the 10 `AgUi.Core.Events.*` struct aliases + the `Phoenix.Channel.push/3` + camelCase encoding via `AgUi.Encoder.EventEncoder`. |
| `TrentoWeb.AIAssistantTools` | `lib/trento_web/channels/ai_assistant/ai_assistant_tools.ex` | `tools/0` returns 6 `%LangChain.Function{}` for Host/SapSystem/Database/Cluster listing + 2 Prometheus PromQL queries. Each reads `context.scope.id` (the `%Trento.Users.User{id: id}` partial struct passed via `Agent.new!`'s `:scope`). |
Comment on lines +73 to +82
| Assign | Type | Lifetime |
|---|---|---|
| `:current_user_id` | integer | from `UserSocket.connect` |
| `:current_scope` | `%Trento.Users.User{id: id}` partial struct | from `join/3` |
| `:loading` | boolean | toggled per run (double-send guard) |
| `:current_run_id` | UUID string | set per `send_message` (after validation) |
| `:current_thread_id` | UUID string | set per `send_message` (after validation) |
| `:message_id` | UUID string (= `current_run_id` today) | set per run |
| `:message_started` | boolean | per run — drives TEXT_MESSAGE_START dedup + orphan-END guard |
| `:run_has_started` | boolean | per run — stale-`:idle` guard |
Comment on lines +176 to +183
```elixir
%{
"message" => message_text,
"run_id" => run_id,
"thread_id" => thread_id
}
when is_binary(message_text) and is_binary(run_id) and is_binary(thread_id)
```
Comment on lines +21 to +26
def handle_info({:agent, {:llm_message, message}}, socket), do: ...
def handle_info({:agent, {:todos_updated, todos}}, socket), do: ...
def handle_info({:agent, {:tool_started, info}}, socket), do: ...
def handle_info({:agent, {:tool_completed, info}}, socket), do: ...
def handle_info({:agent, {:agent_shutdown, reason}}, socket), do: ...
def handle_info({:agent, {:display_message_persisted, dm}}, socket), do: ...
Comment on lines +36 to +38
| Todos | `{:todos_updated, full_list}` | **Full snapshots, not diffs** |
| Tool lifecycle | `{:tool_started, info}`, `{:tool_completed, info}`, `{:tool_failed, info}`, `{:tool_cancelled, info}`, `{:on_tool_call_identified, info}` | UI display labels propagate via these |
| Display message | `{:display_message_persisted, dm}` | Fired after DisplayMessagePersistence saves a row |
- `{:subagent_cancelled, %{final_messages, turn_count}}` — same payload shape
- Minimal fallback broadcast fires within 300ms even when sub-agent is blocked mid-LLM-call

`display_text` re-fires `{:on_tool_call_identified, ...}` once `subagent_type` is known (since v0.6.0) so UI shows "Drafting KB article" instead of generic "Running task".
Comment on lines +122 to +133
```js
this.channel
.push('send_message', {
message: extractMessageText(lastMessage),
thread_id: threadId,
run_id: runId,
})
.receive('error', (error) => { ... });
```

All three fields are required. The channel strict-matches and replies `{:error, :invalid_payload}` if any are missing or non-string. The `.receive('error', ...)` callback catches both transport errors (channel push failure) AND application errors (the channel's `:invalid_payload` reply).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Development

Successfully merging this pull request may close these issues.

3 participants