Skip to content

Architecture planning#3

Merged
teknium1 merged 4 commits intomainfrom
architecture-planning
Jan 8, 2026
Merged

Architecture planning#3
teknium1 merged 4 commits intomainfrom
architecture-planning

Conversation

@dmahan93
Copy link
Copy Markdown
Contributor

No description provided.

@dmahan93 dmahan93 requested a review from teknium1 September 12, 2025 22:47
tools = self.tools()
for agent in self.agent_primitives():
tools.extend(agent.tools())
tools = set(tools)
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.

forcing tools to be hashable might be tedious

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is on lists, lists don't have that requirement

Copy link
Copy Markdown
Contributor Author

@dmahan93 dmahan93 Sep 12, 2025

Choose a reason for hiding this comment

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

oh wait the set thing, yeah, assume there's a tool_name that gets hashed here instead

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm just not going to implement a whole stack in the architecture description

Copy link
Copy Markdown
Contributor Author

@dmahan93 dmahan93 Sep 12, 2025

Choose a reason for hiding this comment

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

basically replace this operation with remove_duplicates(tools)

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.

o kk sick


```python
class BaseAgent:
def agent_primitives(self) -> list[BaseAgent]:
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 an agent primitive the exact same concept as a subagent? only if exactly the same i think we should rename it to subagent bc that's more readable to the outside world

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

subagents are a tool, agent primitives are like run_rubric_judgement

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.

ah gotcha thanks

return self(llm, tools, config, *args, **kwargs)

@staticmethod
def __call__(self, llm, tools, config, *args, **kwargs) -> ConversationGraph:
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.

i feel like it's a bit strange to have both this kind of signature and self.llm, self.tools etc

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

there is no self.llm?

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.

sorry myb only for self.tools then

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I mean what specifically is weird about it to you? Should I add in more documentation on why having a stateless agent is a good thing, should I rename variables?

Copy link
Copy Markdown
Contributor

@hjc-puro hjc-puro Sep 13, 2025

Choose a reason for hiding this comment

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

like both passing in tools into __call__ and having self.tools - confusion is which tools are actually being used?

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.

oh myb i missed the @staticmethod. i think this is fine


Edges are the connections between nodes, and there are two types we are concerned with:
- **Sequential edges**: These represent the flow of conversation, connecting messages in the order they were sent. For example, a user message followed by an assistant response.
- **Parallel edges**: These represent versioning, e.g. edit history, context squishing, etc.
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.

I get that sequential edge tracking has a benefit for training (don't train on a prefix more than once) but what about parallel edge tracking? I guess it's important for observability but is there also a benefit for training?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

what?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sequential is the normal conversation flow, parallel is when there's breaks in the prefix

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.

ah ok. suppose I compact my history by keeping system/user prompt and most recent 2 turns.

is this graph progression correct?

graph for og history:

system -> user1 -> ass1 -> user2 -> ass2 -> user3 -> ass3 -> user4 -> ass4 -> user 5 -> ass5

graph after compact

system -> user1 -> ass1 -> user2 -> ass2 -> user3 -> ass3 -> user4 -> ass4 -> user5 -> ass5
  |         |        |                                         |        |       |        |     (parallel edges)
system -> user1 -> ass1 -----------------------------------> user4 -> ass4 -> user5 -> ass5

or are nodes not duplicated?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Well, the parallel edge here is a reference to the previous graph moreso than individual nodes themselves, I might have to just redescribe it as a DAG with versioning instead of parallel edges

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.

nice i prefer that way too (nodes are message histories edges are transformations on message histories)

@teknium1 teknium1 merged commit d5af538 into main Jan 8, 2026
JasonOA888 added a commit to JasonOA888/hermes-agent that referenced this pull request Mar 8, 2026
Fixes NousResearch#633

Problem:
- Sequential numbering gaps (e.g., NousResearch#1, NousResearch#2, NousResearch#5, NousResearch#8) confuse users
- 200 char truncation too aggressive
- Tool messages completely hidden with no indication

Fix:
1. Use separate counter for displayed messages only
2. Skip tool messages but show count at end
3. Skip system messages
4. Increase truncation to 300 chars
5. Display 'N tool messages hidden' summary

Impact:
- Consistent numbering: NousResearch#1, NousResearch#2, NousResearch#3, NousResearch#4
- Users know when tool calls occurred
- More context visible per message
teknium1 added a commit that referenced this pull request Mar 8, 2026
…resume by name

- Schema v4: unique title index, migration from v2/v3
- set/get/resolve session titles with uniqueness enforcement
- Auto-lineage: context compression auto-numbers titles (Task -> Task #2 -> Task #3)
- resolve_session_by_title: auto-latest finds most recent continuation
- list_sessions_rich: preview (first 60 chars) + last_active timestamp
- CLI: -c accepts optional name arg (hermes -c 'my project')
- CLI: /title command with deferred mode (set before session exists)
- CLI: sessions list shows Title, Preview, Last Active, ID
- 27 new tests (1844 total passing)
0xMikey-ooze pushed a commit to 0xMikey-ooze/hermes-agent that referenced this pull request Mar 16, 2026
Bug #1: Add module-level _dashboard_port and _early_port resolved from
$PORT env var (Railway dynamic ports) with fallback to $DASHBOARD_PORT
then 3001. Prevents OSError port 8080 already in use.

Bug NousResearch#2: Add TelegramPlatform alias for TelegramAdapter and property
setters on BasePlatformAdapter for test compatibility. The conflict
detection (_looks_like_polling_conflict) and handler
(_handle_polling_conflict) already existed.

Bug NousResearch#3: tirith_security.ensure_installed() already handles all failure
modes gracefully (cosign missing, download failed, unsupported platform).
No code changes needed — all 15 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0xMikey-ooze pushed a commit to 0xMikey-ooze/hermes-agent that referenced this pull request Mar 16, 2026
Bug #1: PORT env var — expose _dashboard_port and _early_port as module-level
variables in gateway/run.py so Railway's dynamic $PORT is resolved at import
time and re-resolved at runtime. No more hardcoded 8080.

Bug NousResearch#2: Telegram 409 conflict — add TelegramPlatform alias for TelegramAdapter,
and make BasePlatformAdapter properties (name, has_fatal_error, fatal_error_code)
settable so conflict handler tests can construct instances without __init__.

Bug NousResearch#3: Tirith binary — already handled gracefully (background thread, 24h marker,
cosign optional). No source changes needed; tests confirm behavior.

All 37 RED-phase tests now pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0xMikey-ooze pushed a commit to 0xMikey-ooze/hermes-agent that referenced this pull request Mar 16, 2026
Bug #1: Add module-level _dashboard_port and _early_port to gateway/run.py.
Reads $PORT (Railway), falls back to $DASHBOARD_PORT, defaults to 3001.
Both variables share the same value to prevent port bind conflicts.

Bug NousResearch#2: Fix Telegram connect() Application lookup to be monkeypatch-safe
by using dynamic module attribute resolution via sys.modules[__name__].

Bug NousResearch#3: Tirith graceful failure was already correctly implemented — no
changes needed, all 15 tests passed out of the box.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
teknium1 added a commit that referenced this pull request Mar 17, 2026
1. browser_tool.py: Replace **args spread on browser_click, browser_type,
   and browser_scroll handlers with explicit parameter extraction. The
   **args pattern passed all dict keys as keyword arguments, causing
   TypeError if the LLM sent unexpected parameters. Now extracts only
   the expected params (ref, text, direction) with safe defaults.

2. fuzzy_match.py: Update module docstring to match actual strategy
   order in code. Block anchor was listed as #3 but is actually #7.
   Multi-occurrence is not a separate strategy but a flag. Updated
   count from 9 to 8.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants