[OMEGA-179 & OMEGA-183] Context Frames - #284
Conversation
This reverts commit 96ad4a5.
This was implemented in main and this commit is syncing the telgram implementations of last_message with main
Implemented telegram security/capability matrix
Also made the function configurable through CLI input
Load BOT_TOKEN/CHAT_ID from .env via dotenv instead of passing through metta config. Refactor channel selection from case to if chains. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add prompt-configure that asks for each setting interactively with defaults shown. CLI args (name=value) still override and skip the prompt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- replace cfv2-check-ref-id and cfv2-remove-frame-ref with a second cfv2-check-frame-id clause that pattern-matches FrameRef, allowing cfv2-remove-frame to handle both Frame and FrameRef spaces uniformly - update cfv2-remove-frame comment to reflect it now dispatches on both Frame and FrameRef via cfv2-check-frame-id - fix swapped case comments in loop.metta block to match actual branch order of the if expression - remove unnecessary comment above binding
fix(context): frame ID normalisation, FrameRef fixes and 4-case loop signal
…ew modifications on the context frame skills description
With context frames the received message is no longer passed after the ":-:-:-:" delimiter, so the mock never found a registered answer and every test that drives the agent failed. - match the request against the CURRENT_CONTEXT_FRAME_S_EXPR section when the delimiter carries a loop signal, keeping the HUMAN-MSG path first so the suite still runs on core main - serve an answer once per frame and complete the frame afterwards, so an unfinished frame does not keep later messages from becoming current - let a test keep the frame open with set_answer(..., complete_frame=False) - drop registered answers between tests
… default frame embedding model.
Disable Chroma's default embedding function because frame relations provide their own embeddings, and skip similarity queries when no other frames exist. Remove duplicate frame-completion operations from skills.metta so the canonical implementations in context.metta are invoked only once.
Frame completion mutates memory and frame spaces but stays a nondeterministic call, while the command dispatcher evaluates commands under collapse. Every retry re-executed the whole chain with its side effects, each pass produced a different result, and the agent never returned. Wrap the three completion commands in once. balance_parentheses split an answer by lines and then stripped the outer parens of the whole block. An answer whose first form takes no arguments was corrupted: the command name kept its closing paren and the remaining form became a string, so the agent reported a syntax error and ran none of the commands. Split a block into top-level forms first, ignoring parens inside string literals.
[OMEGA-286] Match mock answers against the context frame
[OMEGA-286] Fix frame completion loop and multi-form answer parsing
|
I did review the code changes and tried out my own build version. This looks like, in general, a needed useful addition to OmegaClaw. I've wondered for a while how we could streamline and refine the prompt which is kind of non filtered at the moment. I think this is based on the spirit of Minsky's work on frames. I had to refresh my memory. But the main idea is to create conceptual chunks with slots. The slots are typically properties that can dynamically change in some cases. The frames are related in a network. It's a GOFAI structure, but that's fine so long as applicable. So I think what this PR does is take that basic plan of Minsky's (and I remember it more like a "schema" in the literature) and use it for prompt refinement and state transition. A reasonable plan. I think relations between the frames are handled by embedding similarity. I'm not sure if there is symbolic linking of frames (is there?). The main goal is to make OmegaClaw smarter and more efficient, more able to hold to its goals. Fair enough. That said, I do have numerous questions and issues: There is scant documentation inside the new code to explain it from my scan through it. All of the code is like this, of course, but I don't see why we don't start documenting our code. The code is in general intricate and complex. It's tough to imagine at this juncture how we could come reasonably close to testing it thoroughly. What testing scenarios have been completed? The testing alone if done properly should be quite complex -- as complex as there are conditions in the code. I strongly feel that this should be repackaged as a PLUGIN or made switchable on/off. The reason is that I think we should leave a metta centric "lean and mean" loop available if people don't want the fancy features, and also if they want to create their own stateful mechanisms. I also think the new log should be switchable (from another PR). Vitaly showed me that it could be configured off, but I'd prefer we had switches from practically all NON ESSENTIAL features, especially if they include python, which this does. I suppose I see the need for some Python code, especially for complex text parsing, but I am not sure we need so much. I feel like SNET is a MeTTa-first organization and we should be writing Metta code. There is a lot of code in context.metta, which is a good. But I think there is also a pretty big new Python program. Also, I wish we had discussed this design in detail as a group. Maybe it did happen. I feel like OmegaClaw is on the whole going to be a flexible substrate for cognitive architectures. In that sense, hardcoding frame based logic doesn't work. YES -- it can be pluggable, absolutely. But I think hardcoding frames locks us into a determinate design that may be incompatible with future desired cognitive architectures. I think the frames are related via the embedding same chromadb vector db? There is a means I recall that Patrick built in of using the FAISS facebook embeddings straight in MeTTa. In that way we don't need to create an external association lookup but use native MeTTa. There are some examples of this in my MettaWamJam repo programs. These are my opinions, of course subject to veto by the powers that be. I think Patrick and Vitaly should review this too. I think it is mandatory actually. It makes a huge design commitment, which while seems good, is hard to foresee the wider effects of. So I think this should be an optional feature, not hardcoded, and consideration given to making the embeddings part of the atomspace proper structure if possible, although that idea needs a lot of work and may be impractical. |
patham9
left a comment
There was a problem hiding this comment.
Well-done! I will approve it, but before that, do we already have metrics that show clear benefits of the context frames over the baseline?
vsbogd
left a comment
There was a problem hiding this comment.
Some lines are duplicated in the code, some new functions are not used anywhere. The new messages creates completely new frame but description says its result is saved in the current frame.
From the description it is not clear what should happen if user's input is not relevant to the current frame. For example LLM switched to some task and then user said something. How agent can select the frame relevant to the users's input?
| ($msg (get-state &prevmsg)) | ||
| ($hadActiveFrame (if $msgnew (cfv2-has-current-frame) False)) | ||
| ; New input becomes frame state before prompting. | ||
| ($_ (if $msgnew (ctx-ingest-user-message $msg) _)) |
There was a problem hiding this comment.
The comment in implementation says the code of the called functions requires changes. And actually this code creates new frame from the user message each time instead of updating the frame.
There was a problem hiding this comment.
Good questions and thanks for spotting. So it seems it is actually limited to the last input and is overthrown on new input?
| (= (cfv2StatusActive) Active) | ||
| (= (cfv2StatusFocused) Focused) | ||
| (= (cfv2StatusSuspended) Suspended) | ||
| (= (cfv2StatusBlocked) Blocked) | ||
| (= (cfv2StatusCompleted) Completed) | ||
| (= (cfv2StatusFailed) Failed) | ||
| (= (cfv2StatusArchived) Archived) |
There was a problem hiding this comment.
For example these functions are not used
| (change-state! &cfv2-current-frame-id ()) | ||
| (change-state! &cfv2-current-frame-id ()) |
Description
This PR introduces Context Frames as OmegaClaw’s primary runtime working state.
User requests, autonomous tasks, goals, results, and completion state are now represented as native frames. The main loop admits new messages into frames before prompting the model, records command results back into the active frame, and schedules work according to frame priority and execution mode.
The change also adds semantic frame composition, dedicated frame-management skills, and a separate runtime prompt for frame behavior.
Motivation
Previously, the agent primarily relied on raw conversation history and a standalone human-message suffix. That made it difficult to:
Context Frames provide an explicit lifecycle and bounded working state for each task.
Changes
Context Frames
Added a native frame runtime supporting:
RootFrame,Frame,FrameRef,Goal, andSubFramestructures.UserDirectiveandAgentDirectiveframe sources.FastandSlowexecution modes.New user messages are admitted as high-priority
UserDirectiveframes in Fast mode. Autonomous work is represented by lower-priorityAgentDirectiveframes in Slow mode.Frame-aware main loop
The main loop now:
CURRENT_CONTEXT_FRAME_S_EXPRinstead of raw global history as the model’s working state.spamShieldconfiguration.Conversation history is still recorded for episodes and auditing, but it is no longer injected directly into every LLM request.
Semantic frame composition
Added
frame_relation.pyto identify relationships between frames using:Supported relationship types include:
DuplicateOfContinuationOfFollowUpSubgoalOfParentOfDependsOnBlocksSupersedesSameProjectSameFailureClusterRelatedButSeparateUnrelatedCollections are separated by embedding provider to prevent vector-dimension conflicts. Content hashes prevent unchanged frames from being embedded again.
Runtime frame prompt
Added
memory/prompt_context_frame.txtas a dedicated frame policy.The policy tells the agent to:
The file is loaded safely at runtime and remains separate from the provider-specific base prompt.
Frame-management skills
Added commands for:
send_probe.The command normalizer now recognizes these frame-management operations.
Helper utilities
Added helpers for:
The legacy
searchcommand is also normalized towebsearch.Authentication fix
Safely normalizes
GATEWAY_URLwhen the configuration value is missing ornull.This prevents channel authentication from failing with:
How Has This Been Tested?
Checklist