directive.go raw
1 package organ
2
3 import (
4 "time"
5
6 "git.mleku.dev/mleku/dendrite/pkg/axiom"
7 "git.mleku.dev/mleku/dendrite/pkg/ratio"
8 )
9
10 // Directive is an operator input that bonds to the lattice with
11 // maximum priority. Sticky directives survive dissolution.
12 type Directive struct {
13 Text string `json:"text"`
14 Priority ratio.Ratio `json:"priority"`
15 Timestamp time.Time `json:"timestamp"`
16 Sticky bool `json:"sticky"`
17 }
18
19 // DirectiveElement wraps a Directive as a lattice Element.
20 // It implements axiom.Element and axiom.StickyElement.
21 type DirectiveElement struct {
22 Directive Directive
23 }
24
25 // Type returns "directive" — the type tag for directive elements.
26 func (d DirectiveElement) Type() string { return "directive" }
27
28 // Value returns the directive text.
29 func (d DirectiveElement) Value() any { return d.Directive.Text }
30
31 // IsSticky returns true if this directive survives dissolution.
32 // This implements axiom.StickyElement.
33 func (d DirectiveElement) IsSticky() bool { return d.Directive.Sticky }
34
35 // DirectiveConstraint defines a lattice site that accepts directive elements.
36 type DirectiveConstraint struct{}
37
38 // Tag returns "directive".
39 func (c DirectiveConstraint) Tag() string { return "directive" }
40
41 // Admits returns true only for DirectiveElement instances.
42 func (c DirectiveConstraint) Admits(e axiom.Element) bool {
43 _, ok := e.(DirectiveElement)
44 return ok
45 }
46
47 // NewDirectiveElement creates a DirectiveElement from text with default
48 // high priority and stickiness.
49 func NewDirectiveElement(text string) DirectiveElement {
50 return DirectiveElement{
51 Directive: Directive{
52 Text: text,
53 Priority: ratio.One,
54 Timestamp: time.Now(),
55 Sticky: true,
56 },
57 }
58 }
59
60 // TokenizeDirective splits directive text into individual tokens,
61 // each wrapped as a DirectiveElement. All tokens inherit the
62 // parent directive's priority and stickiness.
63 func TokenizeDirective(text string, sticky bool, priority ratio.Ratio) []DirectiveElement {
64 // Simple whitespace tokenization. The enzyme system will do
65 // finer-grained decomposition once it learns the directive vocabulary.
66 var tokens []DirectiveElement
67 start := -1
68 for i, r := range text {
69 if r == ' ' || r == '\t' || r == '\n' || r == '\r' {
70 if start >= 0 {
71 tokens = append(tokens, DirectiveElement{
72 Directive: Directive{
73 Text: text[start:i],
74 Priority: priority,
75 Timestamp: time.Now(),
76 Sticky: sticky,
77 },
78 })
79 start = -1
80 }
81 } else if start < 0 {
82 start = i
83 }
84 }
85 if start >= 0 {
86 tokens = append(tokens, DirectiveElement{
87 Directive: Directive{
88 Text: text[start:],
89 Priority: priority,
90 Timestamp: time.Now(),
91 Sticky: sticky,
92 },
93 })
94 }
95 return tokens
96 }
97