Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
3ebf72bfb5
2 changed files with 94 additions and 13 deletions
|
|
@ -1,11 +1,13 @@
|
|||
"""
|
||||
Core base class for all listeners in the organism.
|
||||
Core base class for all listeners in the xml-pipeline organism.
|
||||
|
||||
All capabilities — personalities, tools, gateways — inherit from this class.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import List, Dict, Any, Optional
|
||||
from typing import List, Optional, Dict, Any
|
||||
|
||||
from lxml import etree
|
||||
|
||||
|
|
@ -17,13 +19,14 @@ class XMLListener:
|
|||
Base class for all capabilities (personalities, tools, gateways).
|
||||
|
||||
Subclasses must:
|
||||
- Define `listens_to` (list of root tags they handle)
|
||||
- Implement `async handle()`
|
||||
- Define `listens_to` as a class attribute (list of root tags they handle)
|
||||
- Implement `async handle()` method
|
||||
|
||||
The `convo_id` received in handle() MUST be preserved in any response payload.
|
||||
The `convo_id` received in handle() MUST be preserved in any response payload
|
||||
(via make_response() helper or manually).
|
||||
"""
|
||||
|
||||
listens_to: List[str] = [] # Must be overridden in subclass
|
||||
listens_to: List[str] = [] # Must be overridden in subclass — required
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
|
@ -32,6 +35,11 @@ class XMLListener:
|
|||
config: Optional[Dict[str, Any]] = None,
|
||||
**kwargs,
|
||||
):
|
||||
"""
|
||||
Args:
|
||||
name: Optional explicit name (defaults to class name)
|
||||
config: Owner-provided configuration from privileged registration
|
||||
"""
|
||||
self.name = name or self.__class__.__name__
|
||||
self.config = config or {}
|
||||
self.logger = logging.getLogger(f"{__name__}.{self.name}")
|
||||
|
|
@ -40,14 +48,14 @@ class XMLListener:
|
|||
self, msg: etree.Element, convo_id: str
|
||||
) -> Optional[etree.Element]:
|
||||
"""
|
||||
Handle a message whose root tag matches this listener.
|
||||
Process an incoming message whose root tag matches this listener.
|
||||
|
||||
Args:
|
||||
msg: The payload element (repaired and C14N'd)
|
||||
convo_id: Thread/conversation UUID — must be preserved in response
|
||||
msg: The payload element (already repaired and C14N'd)
|
||||
convo_id: Thread/conversation UUID — must be preserved in any response
|
||||
|
||||
Returns:
|
||||
Response payload element with the same convo_id, or None
|
||||
Response payload element (with convo_id preserved), or None if no response
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
f"{self.__class__.__name__}.handle() must be implemented"
|
||||
|
|
@ -62,8 +70,9 @@ class XMLListener:
|
|||
**attribs,
|
||||
) -> etree.Element:
|
||||
"""
|
||||
Helper to create a response element with a preserved convo_id attribute.
|
||||
Recommended for all listeners.
|
||||
Convenience helper to create a response element with preserved convo_id.
|
||||
|
||||
Strongly recommended for all listeners to ensure thread continuity.
|
||||
"""
|
||||
elem = etree.Element(tag, convo_id=convo_id, **attribs)
|
||||
if text is not None:
|
||||
|
|
@ -71,4 +80,4 @@ class XMLListener:
|
|||
return elem
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<{self.__class__.__name__} listens_to={self.listens_to}>"
|
||||
return f"<{self.__class__.__name__} name='{self.name}' listens_to={self.listens_to}>"
|
||||
72
docs/logic and iteration.md
Normal file
72
docs/logic and iteration.md
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Executive Summary: Self-Calling Iteration Framework in xml-pipeline
|
||||
|
||||
**Date**: December 29, 2025
|
||||
**Component**: Core reasoning mechanism for LLM personalities
|
||||
|
||||
### Principle
|
||||
|
||||
In xml-pipeline, **multi-step reasoning, planning, tool use, and iteration are implemented through open, auditable self-calls** — not hidden loops or state machines.
|
||||
|
||||
The LLM personality participates in the conversation exactly like any other listener: it can send messages to its own root tag.
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **Conversation thread = memory**
|
||||
Every message (user, personality, tool) is appended to history keyed by `convo_id`.
|
||||
|
||||
2. **Self-reflection = self-message**
|
||||
To think step-by-step, the LLM emits its own root tag with the same `convo_id`:
|
||||
```xml
|
||||
<ask-grok convo_id="123">
|
||||
First, let's outline the steps...
|
||||
</ask-grok>
|
||||
```
|
||||
|
||||
3. **MessageBus routes it back** to the same personality instance.
|
||||
|
||||
4. **Personality appends its own message** to history and calls the LLM again.
|
||||
|
||||
5. **LLM sees full context** — including its previous thoughts — and continues.
|
||||
|
||||
6. **Iteration emerges naturally** from repeated self-calls until final response.
|
||||
|
||||
### Key Properties
|
||||
|
||||
- **No hidden state** — the thread history is the only memory
|
||||
- **No special controller** — MessageBus and `convo_id` do all coordination
|
||||
- **Fully auditable** — every thought, plan, and intermediate step is a logged message
|
||||
- **Tool use fits identically** — tool calls are messages to other root tags
|
||||
- **Termination is natural** — LLM decides when to emit final response tag (e.g., `<grok-response>`)
|
||||
|
||||
### Structured Planning Support
|
||||
|
||||
Personalities are encouraged to use visible structures:
|
||||
|
||||
```xml
|
||||
<todo-until condition="all primes under 100 listed">
|
||||
<step done="true">List 2</step>
|
||||
<step done="true">List 3</step>
|
||||
<step done="false">List 5</step>
|
||||
</todo-until>
|
||||
```
|
||||
|
||||
This enables:
|
||||
- Self-coordination (LLM reads its own plan)
|
||||
- GUI progress rendering
|
||||
- Explicit termination conditions
|
||||
|
||||
### Owner Control
|
||||
|
||||
- `iteration-capacity` config (`high`/`medium`/`low`/`none`) tunes how strongly the personality is prompted to iterate
|
||||
- All behavior governed by owner-provided prompts and response templates
|
||||
- No personality can loop indefinitely without owner consent
|
||||
|
||||
### Result
|
||||
|
||||
The framework turns **conversation into computation**.
|
||||
|
||||
Loops, conditionals, and planning become **visible message patterns** rather than hidden code.
|
||||
|
||||
The organism reasons by talking to itself in the open — producing a complete, transparent trace of thought at every step.
|
||||
|
||||
This is the core iteration mechanism for all LLM personalities in xml-pipeline.
|
||||
Loading…
Reference in a new issue