Skip to main content

frame_isa/
lib.rs

1//! # Frame ISA - SAM Instruction Set Architecture
2//!
3//! Zero-dependency crate defining the 6-byte opcode format for SAM AI systems.
4//!
5//! ## Overview
6//!
7//! Frame ISA defines a compact instruction format for AI output:
8//!
9//! ```text
10//! [ACT:2 bytes][SUBJ:2 bytes][MOD:2 bytes] = 6 bytes total (big-endian)
11//! ```
12//!
13//! - **ACT (Action)**: What operation to perform (GREET, RESPOND, CALCULATE, etc.)
14//! - **SUBJ (Subject)**: The topic or entity (TIME, USER, WEATHER, RAG reference, etc.)
15//! - **MOD (Modifier)**: Style flags (voice, tone, warmth, format, urgency, etc.)
16//!
17//! ## Usage
18//!
19//! ```rust
20//! use frame_isa::{Action, Subject, Modifier, Instruction};
21//!
22//! // Create an instruction
23//! let instr = Instruction::new(
24//!     Action::RESPOND,
25//!     Subject::TIME,
26//!     Modifier::default(),
27//! );
28//!
29//! // Serialize to bytes
30//! let bytes = instr.to_bytes();
31//! assert_eq!(bytes.len(), 6);
32//!
33//! // Parse from bytes
34//! let parsed = Instruction::parse_one(&bytes).unwrap();
35//! assert_eq!(instr, parsed);
36//!
37//! // Use the builder
38//! use frame_isa::{InstructionBuilder, Voice, Tone};
39//!
40//! let instr = InstructionBuilder::new(Action::GREET)
41//!     .subject(Subject::USER)
42//!     .voice(Voice::Casual)
43//!     .tone(Tone::Positive)
44//!     .build();
45//! ```
46//!
47//! ## Action Categories
48//!
49//! | Range | Category | Examples |
50//! |-------|----------|----------|
51//! | 0x00xx | System | NOP, HALT, ERROR, STATUS |
52//! | 0x01xx | Response | GREET, CONFIRM, DENY, EXPLAIN, RESPOND |
53//! | 0x02xx | Query | ASK, REQUEST, SEARCH, RETRIEVE |
54//! | 0x03xx | Knowledge | DEFINE, DESCRIBE, COMPARE, SUMMARIZE |
55//! | 0x04xx | Skill | CALCULATE, SET_TIMER, KNOWLEDGE_SEARCH |
56//! | 0x05xx | Emotion | EMPATHY, CONCERN, ENCOURAGEMENT |
57//! | 0x06xx | Template | TEMPLATE_LOAD, TEMPLATE_FILL |
58//! | 0x07xx | Chain | CHAIN, FORK, MERGE |
59//!
60//! ## Subject Categories
61//!
62//! | Range | Category | Examples |
63//! |-------|----------|----------|
64//! | 0x00xx | System | NULL, SELF, USER, CONTEXT |
65//! | 0x01xx | Common | WEATHER, TIME, DATE, SCHEDULE |
66//! | 0x02xx | Math/Science | NUMBER, EQUATION, PHYSICS |
67//! | 0x03xx | Technology | COMPUTER, SOFTWARE, AI, API |
68//! | 0x04xx | Knowledge | DOCUMENTATION, CONCEPT |
69//! | 0x05xx | Emotions | FEELINGS, STRESS, ANXIETY |
70//! | 0x06xx | TRM Refs | References to other TRM models |
71//! | 0xE0xx | RAG Refs | Dynamic document lookups |
72//!
73//! ## Modifier Bit Layout
74//!
75//! ```text
76//! Bit:  15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0
77//!       [--VOICE--] [--TONE--] [-WARM-] [--FORMAT--] [ACCURACY] [URGENCY]
78//! ```
79//!
80//! ## Integration with TRM Models
81//!
82//! TinyRecursiveModels (TRMs) output predictions that map to these opcodes.
83//! The factored prediction approach uses 3 heads:
84//!
85//! - ACT head → Action code
86//! - SUBJ head → Subject code
87//! - MOD head → Modifier flags
88//!
89//! This allows small models (~148K params) to achieve 99%+ accuracy on
90//! opcode prediction tasks.
91
92pub mod action;
93pub mod instruction;
94pub mod modifier;
95pub mod subject;
96
97// Re-export main types
98pub use action::Action;
99pub use instruction::{Instruction, InstructionBuilder, InstructionError, INSTRUCTION_SIZE};
100pub use modifier::{Accuracy, Format, Modifier, Tone, Urgency, Voice, Warmth};
101pub use subject::Subject;
102
103/// Current ISA version
104pub const ISA_VERSION: &str = "0.1.0";
105
106/// Convenience prelude for common imports
107pub mod prelude {
108    pub use crate::action::Action;
109    pub use crate::instruction::{Instruction, InstructionBuilder, INSTRUCTION_SIZE};
110    pub use crate::modifier::{Accuracy, Format, Modifier, Tone, Urgency, Voice, Warmth};
111    pub use crate::subject::Subject;
112}
113
114#[cfg(test)]
115mod tests {
116    use super::*;
117
118    #[test]
119    fn test_end_to_end() {
120        // Create instruction using builder
121        let instr = InstructionBuilder::new(Action::RESPOND)
122            .subject(Subject::TIME)
123            .voice(Voice::Casual)
124            .tone(Tone::Positive)
125            .build();
126
127        // Serialize
128        let bytes = instr.to_bytes();
129        assert_eq!(bytes.len(), INSTRUCTION_SIZE);
130
131        // Parse back
132        let parsed = Instruction::parse_one(&bytes).unwrap();
133        assert_eq!(instr, parsed);
134
135        // Verify fields
136        assert_eq!(parsed.action, Action::RESPOND);
137        assert_eq!(parsed.subject, Subject::TIME);
138        assert_eq!(parsed.modifier.voice(), Voice::Casual);
139        assert_eq!(parsed.modifier.tone(), Tone::Positive);
140    }
141
142    #[test]
143    fn test_rag_chain() {
144        // Create a chain instruction that references another TRM
145        let chain = Instruction::new(Action::CHAIN, Subject::trm_ref(3), Modifier::default());
146
147        assert!(chain.is_chain());
148        assert_eq!(chain.subject.trm_model_id(), Some(3));
149
150        // Create a RAG instruction
151        let rag = Instruction::new(
152            Action::RETRIEVE,
153            Subject::rag_ref(0x42),
154            Modifier::default(),
155        );
156
157        assert!(rag.needs_rag());
158        assert_eq!(rag.subject.rag_doc_id(), Some(0x42));
159    }
160
161    #[test]
162    fn test_opcode_string() {
163        let instr = Instruction::new(Action::GREET, Subject::USER, Modifier::default());
164
165        let opcode_str = instr.to_opcode_string();
166        assert!(opcode_str.contains(":"));
167
168        let parsed = Instruction::from_opcode_string(&opcode_str).unwrap();
169        assert_eq!(instr, parsed);
170    }
171}