@almadar/std 16.144.0 → 16.146.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/behaviors/lolo/ml/atoms/std-ml-classify.lolo +121 -0
- package/behaviors/lolo/ml/atoms/std-ml-exact-check.lolo +90 -0
- package/behaviors/lolo/ml/atoms/std-ml-infer.lolo +141 -0
- package/behaviors/lolo/ml/atoms/std-ml-label-capture.lolo +75 -0
- package/behaviors/lolo/ml/atoms/std-ml-lookup.lolo +83 -0
- package/behaviors/lolo/ml/atoms/std-ml-posterior.lolo +104 -0
- package/behaviors/lolo/ml/atoms/std-ml-similarity.lolo +166 -0
- package/behaviors/lolo/ml/molecules/std-escalating-decision.lolo +271 -0
- package/behaviors/lolo/ml/molecules/std-knowledge-tracing.lolo +115 -0
- package/behaviors/lolo/ui/core/atoms/std-app-layout.lolo +14 -0
- package/behaviors/lolo/ui/core/atoms/std-board.lolo +20 -6
- package/behaviors/lolo/ui/core/atoms/std-browse.lolo +23 -6
- package/behaviors/lolo/ui/core/atoms/std-calendar.lolo +80 -2
- package/behaviors/lolo/ui/core/atoms/std-stats.lolo +1 -1
- package/behaviors/lolo/ui/core/atoms/std-tag-taxonomy.lolo +3 -3
- package/behaviors/lolo/ui/core/atoms/ui-typography.lolo +1 -1
- package/behaviors/lolo/ui/core/molecules/ui-calendar-grid.lolo +18 -0
- package/behaviors/lolo/ui/core/molecules/ui-data-grid.lolo +2 -0
- package/behaviors/lolo/ui/core/molecules/ui-data-list.lolo +3 -2
- package/behaviors/lolo/ui/core/molecules/ui-filter-group.lolo +20 -0
- package/behaviors/lolo/ui/core/molecules/ui-search-input.lolo +7 -2
- package/behaviors/lolo/ui/core/molecules/ui-table-view.lolo +3 -2
- package/behaviors/lolo/ui/core/organisms/ui-entity-cards.lolo +2 -0
- package/behaviors/lolo/ui/core/organisms/ui-entity-list.lolo +2 -0
- package/behaviors/lolo/ui/core/organisms/ui-entity-table.lolo +2 -0
- package/behaviors/lolo/ui/core/organisms/ui-timeline.lolo +2 -0
- package/behaviors/lolo/ui/game/atoms/std-dungeon-combat.lolo +2 -2
- package/behaviors/lolo/ui/game/molecules/std-worldmap-board-2d.lolo +1 -1
- package/behaviors/lolo/ui/game/organisms/ui-boardgame-board.lolo +2 -2
- package/behaviors/lolo/ui/game/organisms/ui-builder-board.lolo +2 -2
- package/behaviors/lolo/ui/game/organisms/ui-debugger-board.lolo +3 -3
- package/behaviors/lolo/ui/game/organisms/ui-physics-sandbox-board.lolo +3 -3
- package/behaviors/lolo/ui/game/organisms/ui-roguelike-board.lolo +1 -1
- package/behaviors/lolo/ui/game/organisms/ui-sequencer-board.lolo +1 -1
- package/behaviors/lolo/ui/learning/atoms/std-algo-heapsort.lolo +2 -2
- package/behaviors/lolo/ui/learning/atoms/std-algo-mst.lolo +3 -3
- package/behaviors/registry/factory-signatures.json +5018 -824
- package/behaviors/registry/ml/atoms/std-ml-classify.orb +622 -0
- package/behaviors/registry/ml/atoms/std-ml-exact-check.orb +505 -0
- package/behaviors/registry/ml/atoms/std-ml-infer.orb +770 -0
- package/behaviors/registry/ml/atoms/std-ml-label-capture.orb +367 -0
- package/behaviors/registry/ml/atoms/std-ml-lookup.orb +473 -0
- package/behaviors/registry/ml/atoms/std-ml-posterior.orb +669 -0
- package/behaviors/registry/ml/atoms/std-ml-similarity.orb +917 -0
- package/behaviors/registry/ml/molecules/std-escalating-decision.orb +1553 -0
- package/behaviors/registry/ml/molecules/std-knowledge-tracing.orb +577 -0
- package/behaviors/registry/ui/core/atoms/std-app-layout.orb +33 -1
- package/behaviors/registry/ui/core/atoms/std-board.orb +64 -20
- package/behaviors/registry/ui/core/atoms/std-browse.orb +83 -48
- package/behaviors/registry/ui/core/atoms/std-calendar.orb +213 -3
- package/behaviors/registry/ui/core/atoms/ui-typography.orb +1 -1
- package/behaviors/registry/ui/core/molecules/ui-calendar-grid.orb +27 -0
- package/behaviors/registry/ui/core/molecules/ui-data-grid.orb +25 -12
- package/behaviors/registry/ui/core/molecules/ui-data-list.orb +26 -13
- package/behaviors/registry/ui/core/molecules/ui-filter-group.orb +86 -0
- package/behaviors/registry/ui/core/molecules/ui-search-input.orb +37 -1
- package/behaviors/registry/ui/core/molecules/ui-table-view.orb +25 -12
- package/behaviors/registry/ui/core/organisms/ui-entity-cards.orb +13 -0
- package/behaviors/registry/ui/core/organisms/ui-entity-list.orb +21 -8
- package/behaviors/registry/ui/core/organisms/ui-entity-table.orb +13 -0
- package/behaviors/registry/ui/core/organisms/ui-timeline.orb +13 -0
- package/behaviors/registry/ui/game/atoms/std-dungeon-combat.orb +4 -4
- package/behaviors/registry/ui/game/molecules/std-worldmap-board-2d.orb +6 -9
- package/behaviors/registry/ui/game/organisms/ui-boardgame-board.orb +4 -4
- package/behaviors/registry/ui/game/organisms/ui-builder-board.orb +4 -4
- package/behaviors/registry/ui/game/organisms/ui-debugger-board.orb +12 -12
- package/behaviors/registry/ui/game/organisms/ui-physics-sandbox-board.orb +19 -19
- package/behaviors/registry/ui/game/organisms/ui-roguelike-board.orb +1 -1
- package/behaviors/registry/ui/game/organisms/ui-sequencer-board.orb +2 -2
- package/behaviors/registry/ui/learning/atoms/std-algo-heapsort.orb +8 -8
- package/canonical-operators.json +30 -6
- package/dist/behaviors/behaviors-embeddings.json +267 -267
- package/dist/behaviors/exports-reader.js +2462 -2080
- package/dist/behaviors/functions/index.d.ts +725 -1
- package/dist/behaviors/functions/index.js +2437 -2081
- package/dist/behaviors/index.d.ts +1 -1
- package/dist/behaviors/index.js +2463 -2081
- package/dist/behaviors/knob-embeddings.json +1 -1
- package/dist/behaviors/query.js +2462 -2080
- package/dist/behaviors/registry/factory-signatures.json +5018 -824
- package/dist/behaviors/registry/ml/atoms/std-ml-classify.orb +622 -0
- package/dist/behaviors/registry/ml/atoms/std-ml-exact-check.orb +505 -0
- package/dist/behaviors/registry/ml/atoms/std-ml-infer.orb +770 -0
- package/dist/behaviors/registry/ml/atoms/std-ml-label-capture.orb +367 -0
- package/dist/behaviors/registry/ml/atoms/std-ml-lookup.orb +473 -0
- package/dist/behaviors/registry/ml/atoms/std-ml-posterior.orb +669 -0
- package/dist/behaviors/registry/ml/atoms/std-ml-similarity.orb +917 -0
- package/dist/behaviors/registry/ml/molecules/std-escalating-decision.orb +1553 -0
- package/dist/behaviors/registry/ml/molecules/std-knowledge-tracing.orb +577 -0
- package/dist/behaviors/registry/ui/core/atoms/std-app-layout.orb +33 -1
- package/dist/behaviors/registry/ui/core/atoms/std-board.orb +64 -20
- package/dist/behaviors/registry/ui/core/atoms/std-browse.orb +83 -48
- package/dist/behaviors/registry/ui/core/atoms/std-calendar.orb +213 -3
- package/dist/behaviors/registry/ui/core/atoms/ui-typography.orb +1 -1
- package/dist/behaviors/registry/ui/core/molecules/ui-calendar-grid.orb +27 -0
- package/dist/behaviors/registry/ui/core/molecules/ui-data-grid.orb +25 -12
- package/dist/behaviors/registry/ui/core/molecules/ui-data-list.orb +26 -13
- package/dist/behaviors/registry/ui/core/molecules/ui-filter-group.orb +86 -0
- package/dist/behaviors/registry/ui/core/molecules/ui-search-input.orb +37 -1
- package/dist/behaviors/registry/ui/core/molecules/ui-table-view.orb +25 -12
- package/dist/behaviors/registry/ui/core/organisms/ui-entity-cards.orb +13 -0
- package/dist/behaviors/registry/ui/core/organisms/ui-entity-list.orb +21 -8
- package/dist/behaviors/registry/ui/core/organisms/ui-entity-table.orb +13 -0
- package/dist/behaviors/registry/ui/core/organisms/ui-timeline.orb +13 -0
- package/dist/behaviors/registry/ui/game/atoms/std-dungeon-combat.orb +4 -4
- package/dist/behaviors/registry/ui/game/molecules/std-worldmap-board-2d.orb +6 -9
- package/dist/behaviors/registry/ui/game/organisms/ui-boardgame-board.orb +4 -4
- package/dist/behaviors/registry/ui/game/organisms/ui-builder-board.orb +4 -4
- package/dist/behaviors/registry/ui/game/organisms/ui-debugger-board.orb +12 -12
- package/dist/behaviors/registry/ui/game/organisms/ui-physics-sandbox-board.orb +19 -19
- package/dist/behaviors/registry/ui/game/organisms/ui-roguelike-board.orb +1 -1
- package/dist/behaviors/registry/ui/game/organisms/ui-sequencer-board.orb +2 -2
- package/dist/behaviors/registry/ui/learning/atoms/std-algo-heapsort.orb +8 -8
- package/dist/behaviors-embeddings.json +267 -267
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2498 -2088
- package/dist/knob-embeddings.json +1 -1
- package/dist/modules/array.js +28 -0
- package/dist/modules/contract.js +4 -4
- package/dist/modules/data.js +3 -3
- package/dist/modules/index.js +35 -7
- package/dist/registry/factory-signatures.json +5018 -824
- package/dist/registry.js +35 -7
- package/package.json +3 -3
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
app std-ml-classify "1.0.0"
|
|
2
|
+
"Generative rung (R5) — structured LLM verdict from a closed category set, via the llm.classify service seam. Bottom of the fall-through: always answers or fails, never abstains."
|
|
3
|
+
|
|
4
|
+
orbital MlClassifyOrbital {
|
|
5
|
+
|
|
6
|
+
entity ClassifierVerdict [runtime] {
|
|
7
|
+
text : string = ""
|
|
8
|
+
category : string = ""
|
|
9
|
+
confidence : float = 0
|
|
10
|
+
reasoning : string = ""
|
|
11
|
+
errorMessage : string = ""
|
|
12
|
+
request : object = {}
|
|
13
|
+
status : "idle" | "classifying" | "done" = idle
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
trait ClassifyRun -> ClassifierVerdict [lifecycle, instance] {
|
|
17
|
+
initial: idle
|
|
18
|
+
|
|
19
|
+
config {
|
|
20
|
+
categories : [string] = []
|
|
21
|
+
@label "Categories"
|
|
22
|
+
@description "Closed set of category labels the LLM must choose from"
|
|
23
|
+
@tier "domain"
|
|
24
|
+
provider : string = ""
|
|
25
|
+
@label "Provider"
|
|
26
|
+
@description "Reserved for provider selection; LLMServiceActions.classify (packages/almadar-llm/src/contracts.ts) takes no provider param today, so this knob is not forwarded to the call"
|
|
27
|
+
@tier "infra"
|
|
28
|
+
model : string = ""
|
|
29
|
+
@label "Model"
|
|
30
|
+
@description "Model override forwarded to the classify call"
|
|
31
|
+
@tier "infra"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
state idle {
|
|
35
|
+
INIT -> idle
|
|
36
|
+
(set @entity.text "")
|
|
37
|
+
(set @entity.category "")
|
|
38
|
+
(set @entity.confidence 0)
|
|
39
|
+
(set @entity.reasoning "")
|
|
40
|
+
(set @entity.errorMessage "")
|
|
41
|
+
(set @entity.request {})
|
|
42
|
+
(set @entity.status idle)
|
|
43
|
+
|
|
44
|
+
CLASSIFY -> classifying
|
|
45
|
+
(set @entity.text ?text)
|
|
46
|
+
(set @entity.request ?request)
|
|
47
|
+
(set @entity.status classifying)
|
|
48
|
+
(call-service "llm" "classify" { text: ?text, categories: @config.categories, model: @config.model }
|
|
49
|
+
{ emit: { success: CLASSIFIED_RAW, failure: CLASSIFY_CALL_FAILED } })
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
state classifying {
|
|
53
|
+
CLASSIFIED_RAW -> done
|
|
54
|
+
(set @entity.category ?category)
|
|
55
|
+
(set @entity.confidence ?confidence)
|
|
56
|
+
(set @entity.reasoning ?reasoning)
|
|
57
|
+
(set @entity.status done)
|
|
58
|
+
(emit CLASSIFIED { category: @entity.category, confidence: @entity.confidence, reasoning: @entity.reasoning })
|
|
59
|
+
|
|
60
|
+
CLASSIFY_CALL_FAILED -> done
|
|
61
|
+
(set @entity.category "")
|
|
62
|
+
(set @entity.confidence 0)
|
|
63
|
+
(set @entity.reasoning "")
|
|
64
|
+
(set @entity.errorMessage ?error)
|
|
65
|
+
(set @entity.status done)
|
|
66
|
+
(emit CLASSIFY_FAILED { error: @entity.errorMessage })
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
state done {
|
|
70
|
+
INIT -> done
|
|
71
|
+
(set @entity.status done)
|
|
72
|
+
RESET -> idle
|
|
73
|
+
(set @entity.text "")
|
|
74
|
+
(set @entity.category "")
|
|
75
|
+
(set @entity.confidence 0)
|
|
76
|
+
(set @entity.reasoning "")
|
|
77
|
+
(set @entity.errorMessage "")
|
|
78
|
+
(set @entity.request {})
|
|
79
|
+
(set @entity.status idle)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
emits {
|
|
83
|
+
CLASSIFIED_RAW {
|
|
84
|
+
category : string!
|
|
85
|
+
confidence : number!
|
|
86
|
+
reasoning : string!
|
|
87
|
+
}
|
|
88
|
+
@description "Raw llm.classify service result, flattened onto the payload by the call-service effect executor"
|
|
89
|
+
@tier "secondary"
|
|
90
|
+
|
|
91
|
+
CLASSIFY_CALL_FAILED {
|
|
92
|
+
error : string!
|
|
93
|
+
}
|
|
94
|
+
@description "call-service classify failure signal"
|
|
95
|
+
@tier "secondary"
|
|
96
|
+
|
|
97
|
+
CLASSIFIED -> external {
|
|
98
|
+
category : string!
|
|
99
|
+
confidence : float!
|
|
100
|
+
reasoning : string!
|
|
101
|
+
}
|
|
102
|
+
@description "Structured LLM verdict — closed-set category with confidence and reasoning"
|
|
103
|
+
@tier "primary"
|
|
104
|
+
|
|
105
|
+
CLASSIFY_FAILED -> external {
|
|
106
|
+
error : string!
|
|
107
|
+
}
|
|
108
|
+
@description "The classify service call failed; this rung never abstains, only answers or fails"
|
|
109
|
+
@tier "primary"
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
listens {
|
|
113
|
+
CLASSIFY {
|
|
114
|
+
text : string!
|
|
115
|
+
request : object
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
page "/ml-classify" as MlClassifyPage -> ClassifyRun
|
|
121
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
app std-ml-exact-check "1.0.0"
|
|
2
|
+
"Rung R0 of the intelligence ladder — normalizes and compares a candidate value against a key value; abstains on no match."
|
|
3
|
+
|
|
4
|
+
orbital MlExactCheckOrbital {
|
|
5
|
+
|
|
6
|
+
entity ExactCheck [runtime] {
|
|
7
|
+
matched : boolean = false
|
|
8
|
+
status : "idle" | "checked" = idle
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
trait ExactCheckRun -> ExactCheck [lifecycle, instance] {
|
|
12
|
+
initial: idle
|
|
13
|
+
|
|
14
|
+
config {
|
|
15
|
+
caseSensitive : boolean = false
|
|
16
|
+
@label "Case sensitive"
|
|
17
|
+
@description "Compare candidate and key with case sensitivity; off lowercases both sides before comparing"
|
|
18
|
+
@tier "policy"
|
|
19
|
+
trimWhitespace : boolean = true
|
|
20
|
+
@label "Trim whitespace"
|
|
21
|
+
@description "Strip leading and trailing whitespace from both sides before comparing"
|
|
22
|
+
@tier "policy"
|
|
23
|
+
numericTolerance : float = 0
|
|
24
|
+
@label "Numeric tolerance"
|
|
25
|
+
@description "Absolute tolerance applied when both candidate and key are numbers; 0 requires an exact numeric match"
|
|
26
|
+
@tier "policy"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
state idle {
|
|
30
|
+
INIT -> idle
|
|
31
|
+
(set @entity.matched false)
|
|
32
|
+
(set @entity.status idle)
|
|
33
|
+
CHECK -> checked
|
|
34
|
+
(let ((bothNumeric (and (validate/number ?candidate) (validate/number ?key)))
|
|
35
|
+
(candStr (str/concat ?candidate))
|
|
36
|
+
(keyStr (str/concat ?key))
|
|
37
|
+
(candTrim (if @config.trimWhitespace (str/trim @candStr) @candStr))
|
|
38
|
+
(keyTrim (if @config.trimWhitespace (str/trim @keyStr) @keyStr))
|
|
39
|
+
(candNorm (if @config.caseSensitive @candTrim (str/lower @candTrim)))
|
|
40
|
+
(keyNorm (if @config.caseSensitive @keyTrim (str/lower @keyTrim)))
|
|
41
|
+
(isMatch (if @bothNumeric
|
|
42
|
+
(<= (math/abs (- ?candidate ?key)) @config.numericTolerance)
|
|
43
|
+
(== @candNorm @keyNorm))))
|
|
44
|
+
(if @isMatch
|
|
45
|
+
(do
|
|
46
|
+
(set @entity.matched true)
|
|
47
|
+
(set @entity.status checked)
|
|
48
|
+
(emit EXACT_MATCHED { candidate: ?candidate, key: ?key }))
|
|
49
|
+
(do
|
|
50
|
+
(set @entity.matched false)
|
|
51
|
+
(set @entity.status checked)
|
|
52
|
+
(emit EXACT_UNMATCHED { candidate: ?candidate, key: ?key, request: ?request }))))
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
state checked {
|
|
56
|
+
INIT -> checked
|
|
57
|
+
(set @entity.status checked)
|
|
58
|
+
RESET -> idle
|
|
59
|
+
(set @entity.matched false)
|
|
60
|
+
(set @entity.status idle)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
emits {
|
|
64
|
+
EXACT_MATCHED -> external {
|
|
65
|
+
candidate : any!
|
|
66
|
+
key : any!
|
|
67
|
+
}
|
|
68
|
+
@description "Fired when the candidate exactly equals the key under the configured normalization"
|
|
69
|
+
@tier "primary"
|
|
70
|
+
|
|
71
|
+
EXACT_UNMATCHED -> external {
|
|
72
|
+
candidate : any!
|
|
73
|
+
key : any!
|
|
74
|
+
request : object
|
|
75
|
+
}
|
|
76
|
+
@description "Abstain — candidate does not equal the key; the next rung should take over. request echoes the originating request untouched so the next rung can project its own inputs out of it"
|
|
77
|
+
@tier "primary"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
listens {
|
|
81
|
+
CHECK {
|
|
82
|
+
candidate : any!
|
|
83
|
+
key : any!
|
|
84
|
+
request : object
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
page "/ml-exact-check" as MlExactCheckPage -> ExactCheckRun
|
|
90
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
app std-ml-infer "1.0.0"
|
|
2
|
+
"std-ml-infer — the learned rung (R4) of the intelligence ladder, and the seam between a .lolo circuit and a trained model deployed on masar (or off-the-shelf HuggingFace weights) reached through the ml service. Sends the caller-supplied input straight to call-service ml infer, then guards the raw output before it ever becomes an effect: validates it against the declared outputContract, clamps it into range, and only then decides. Emits INFERRED when the output satisfies the contract and confidence clears confidenceFloor — carrying the clamped output, confidence, and an empty violations list. Otherwise abstains with INFER_ABSTAINED, whose reason is one of: low confidence (contract satisfied but below floor, violations empty), contract violation (violations populated via contract/violations for diagnosis), or unavailable (the service call itself failed — a masar cold start or a down endpoint, never surfaced as a user-visible error). Use when a numeric or tensor-shaped model answer needs a licensed guard before becoming a decision — classification scores, regressions, embedding-derived predictions — and the next rung (R5 generative) should take over on any abstain."
|
|
3
|
+
|
|
4
|
+
type Range = { min: float!, max: float! }
|
|
5
|
+
type OutputContract = { shape: [int], ranges: Map string Range }
|
|
6
|
+
|
|
7
|
+
orbital MlInferOrbital {
|
|
8
|
+
|
|
9
|
+
entity Inference [runtime] {
|
|
10
|
+
input : object = {}
|
|
11
|
+
output : [float] = []
|
|
12
|
+
confidence : float = 0
|
|
13
|
+
violations : [object] = []
|
|
14
|
+
reason : string = ""
|
|
15
|
+
request : object = {}
|
|
16
|
+
status : "idle" | "inferring" | "resolved" = idle
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
trait InferenceRun -> Inference [lifecycle, instance] {
|
|
20
|
+
initial: idle
|
|
21
|
+
|
|
22
|
+
config {
|
|
23
|
+
model : string = ""
|
|
24
|
+
@label "Model reference"
|
|
25
|
+
@description "hf:<id> for off-the-shelf weights, or a masar checkpoint id, forwarded to the ml service infer action"
|
|
26
|
+
@tier "infra"
|
|
27
|
+
confidenceFloor : float = 0.7
|
|
28
|
+
@label "Confidence floor"
|
|
29
|
+
@description "Minimum service-reported confidence required to answer; below this the atom abstains with reason low confidence"
|
|
30
|
+
@tier "policy"
|
|
31
|
+
outputContract : OutputContract = { ranges: {} }
|
|
32
|
+
@label "Output contract"
|
|
33
|
+
@description "Declared shape and per-dimension ranges the model output must satisfy; a failing check abstains with reason contract violation. Omit shape to assert ranges only — an empty shape [] asserts a SCALAR output, it does not mean unconstrained"
|
|
34
|
+
@tier "domain"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
state idle {
|
|
38
|
+
INIT -> idle
|
|
39
|
+
(set @entity.input {})
|
|
40
|
+
(set @entity.output [])
|
|
41
|
+
(set @entity.confidence 0)
|
|
42
|
+
(set @entity.violations [])
|
|
43
|
+
(set @entity.reason "")
|
|
44
|
+
(set @entity.request {})
|
|
45
|
+
(set @entity.status idle)
|
|
46
|
+
|
|
47
|
+
INFER -> inferring
|
|
48
|
+
(set @entity.input ?input)
|
|
49
|
+
(set @entity.request ?request)
|
|
50
|
+
(set @entity.status inferring)
|
|
51
|
+
(call-service "ml" "infer" { model: @config.model, input: @entity.input }
|
|
52
|
+
{ emit: { success: INFERRED_RAW, failure: INFER_CALL_FAILED } })
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
state inferring {
|
|
56
|
+
INFERRED_RAW -> resolved
|
|
57
|
+
(set @entity.output ?output)
|
|
58
|
+
(set @entity.confidence ?confidence)
|
|
59
|
+
(let ((validation (contract/validate-output @entity.output @config.outputContract)))
|
|
60
|
+
(if (object/get @validation "valid")
|
|
61
|
+
(if (>= @entity.confidence @config.confidenceFloor)
|
|
62
|
+
(do
|
|
63
|
+
(set @entity.output (contract/clamp-output @entity.output @config.outputContract))
|
|
64
|
+
(set @entity.violations [])
|
|
65
|
+
(set @entity.reason "")
|
|
66
|
+
(set @entity.status resolved)
|
|
67
|
+
(emit INFERRED { output: @entity.output, confidence: @entity.confidence, violations: @entity.violations }))
|
|
68
|
+
(do
|
|
69
|
+
(set @entity.violations [])
|
|
70
|
+
(set @entity.reason "low confidence")
|
|
71
|
+
(set @entity.status resolved)
|
|
72
|
+
(emit INFER_ABSTAINED { reason: "low confidence", violations: @entity.violations, request: @entity.request })))
|
|
73
|
+
(do
|
|
74
|
+
(set @entity.violations (contract/violations @entity.output @config.outputContract))
|
|
75
|
+
(set @entity.reason "contract violation")
|
|
76
|
+
(set @entity.status resolved)
|
|
77
|
+
(emit INFER_ABSTAINED { reason: "contract violation", violations: @entity.violations, request: @entity.request }))))
|
|
78
|
+
|
|
79
|
+
INFER_CALL_FAILED -> resolved
|
|
80
|
+
(set @entity.output [])
|
|
81
|
+
(set @entity.confidence 0)
|
|
82
|
+
(set @entity.violations [])
|
|
83
|
+
(set @entity.reason "unavailable")
|
|
84
|
+
(set @entity.status resolved)
|
|
85
|
+
(emit INFER_ABSTAINED { reason: "unavailable", violations: @entity.violations, request: @entity.request })
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
state resolved {
|
|
89
|
+
INIT -> resolved
|
|
90
|
+
(set @entity.status resolved)
|
|
91
|
+
RESET -> idle
|
|
92
|
+
(set @entity.input {})
|
|
93
|
+
(set @entity.output [])
|
|
94
|
+
(set @entity.confidence 0)
|
|
95
|
+
(set @entity.violations [])
|
|
96
|
+
(set @entity.reason "")
|
|
97
|
+
(set @entity.request {})
|
|
98
|
+
(set @entity.status idle)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
emits {
|
|
102
|
+
INFERRED_RAW {
|
|
103
|
+
output : [float]!
|
|
104
|
+
confidence : number!
|
|
105
|
+
}
|
|
106
|
+
@description "Raw ml.infer service result, flattened onto the payload by the call-service effect executor"
|
|
107
|
+
@tier "secondary"
|
|
108
|
+
|
|
109
|
+
INFER_CALL_FAILED {
|
|
110
|
+
error : string!
|
|
111
|
+
}
|
|
112
|
+
@description "call-service infer failure signal — a masar cold start or a down endpoint lands here, not as a user-visible error"
|
|
113
|
+
@tier "secondary"
|
|
114
|
+
|
|
115
|
+
INFERRED -> external {
|
|
116
|
+
output : [float]!
|
|
117
|
+
confidence : float!
|
|
118
|
+
violations : [object]!
|
|
119
|
+
}
|
|
120
|
+
@description "The service answered, the output satisfies outputContract, and confidence clears confidenceFloor — output already clamped"
|
|
121
|
+
@tier "primary"
|
|
122
|
+
|
|
123
|
+
INFER_ABSTAINED -> external {
|
|
124
|
+
reason : string!
|
|
125
|
+
violations : [object]!
|
|
126
|
+
request : object
|
|
127
|
+
}
|
|
128
|
+
@description "The abstain — reason is one of: low confidence, contract violation, unavailable. violations is populated only on the contract violation path. request echoes the originating request untouched so the next rung can project its own inputs out of it"
|
|
129
|
+
@tier "primary"
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
listens {
|
|
133
|
+
INFER {
|
|
134
|
+
input : object!
|
|
135
|
+
request : object
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
page "/ml-infer" as MlInferPage -> InferenceRun
|
|
141
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
app std-ml-label-capture "1.0.0"
|
|
2
|
+
"std-ml-label-capture — records a labeled example (input, verdict, source rung, observed outcome) so that expensive top-rung answers become training data for a cheaper rung later. Generic: it knows nothing about grading or students. sampleRate gates what fraction of examples are kept (1 = capture all); sink tags which named destination the example is attributed to."
|
|
3
|
+
orbital MlLabelCaptureOrbital {
|
|
4
|
+
|
|
5
|
+
entity LabeledExample [persistent: ml_labels] {
|
|
6
|
+
id : string! @key
|
|
7
|
+
input : json @description "The input that was judged." = null
|
|
8
|
+
verdict : json @description "The verdict/output produced by the rung." = null
|
|
9
|
+
source : string @description "Which rung produced the verdict." = ""
|
|
10
|
+
outcome : json @description "The observed ground-truth outcome, once known." = null
|
|
11
|
+
sink : string @description "Named destination this example is attributed to." = ""
|
|
12
|
+
recordedAt : number = 0
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
trait LabelCaptureListener -> @rebindable LabeledExample [lifecycle, instance] {
|
|
16
|
+
initial: idle
|
|
17
|
+
|
|
18
|
+
state idle {
|
|
19
|
+
INIT -> idle
|
|
20
|
+
(set @entity.input null)
|
|
21
|
+
(set @entity.verdict null)
|
|
22
|
+
(set @entity.source "")
|
|
23
|
+
(set @entity.outcome null)
|
|
24
|
+
(set @entity.sink "")
|
|
25
|
+
(set @entity.recordedAt 0)
|
|
26
|
+
CAPTURE -> idle
|
|
27
|
+
(set @entity.input ?input)
|
|
28
|
+
(set @entity.verdict ?verdict)
|
|
29
|
+
(set @entity.source ?source)
|
|
30
|
+
(set @entity.outcome ?outcome)
|
|
31
|
+
(set @entity.sink @config.sink)
|
|
32
|
+
(set @entity.recordedAt @now)
|
|
33
|
+
(if (prob/flip @config.sampleRate)
|
|
34
|
+
(do
|
|
35
|
+
(persist create LabeledExample {
|
|
36
|
+
input: @entity.input
|
|
37
|
+
verdict: @entity.verdict
|
|
38
|
+
source: @entity.source
|
|
39
|
+
outcome: @entity.outcome
|
|
40
|
+
sink: @entity.sink
|
|
41
|
+
recordedAt: @entity.recordedAt
|
|
42
|
+
})
|
|
43
|
+
(emit LABEL_CAPTURED { source: @entity.source, sink: @entity.sink }))
|
|
44
|
+
null)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
emits {
|
|
48
|
+
LABEL_CAPTURED -> external { source : string!, sink : string! }
|
|
49
|
+
@description "Fired after a labeled example is persisted."
|
|
50
|
+
@tier "primary"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
listens {
|
|
54
|
+
CAPTURE {
|
|
55
|
+
input : json!
|
|
56
|
+
verdict : json!
|
|
57
|
+
source : string!
|
|
58
|
+
outcome : json
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
config {
|
|
63
|
+
sink : string = ""
|
|
64
|
+
@label "Label sink"
|
|
65
|
+
@description "Named destination this batch of examples is attributed to; interpreted downstream (the physical label store is not yet decided)."
|
|
66
|
+
@tier "infra"
|
|
67
|
+
sampleRate : float = 1
|
|
68
|
+
@label "Sample rate"
|
|
69
|
+
@description "Fraction of examples to keep (1 = capture all). A prob/flip trial per observation."
|
|
70
|
+
@tier "policy"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
page "/ml-label-capture" as MlLabelCapturePage -> LabelCaptureListener
|
|
75
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
app std-ml-lookup "1.0.0"
|
|
2
|
+
"Rung R1 of the intelligence ladder — finds the candidate value in a list of accepted values; abstains when nothing matches."
|
|
3
|
+
|
|
4
|
+
orbital MlLookupOrbital {
|
|
5
|
+
|
|
6
|
+
entity KeyLookup [runtime] {
|
|
7
|
+
matched : boolean = false
|
|
8
|
+
status : "idle" | "checked" = idle
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
trait LookupRun -> KeyLookup [lifecycle, instance] {
|
|
12
|
+
initial: idle
|
|
13
|
+
|
|
14
|
+
config {
|
|
15
|
+
matchField : string = ""
|
|
16
|
+
@label "Match field"
|
|
17
|
+
@description "When the accepted list holds objects rather than scalars, the field to compare against the candidate; empty compares each element itself"
|
|
18
|
+
@tier "domain"
|
|
19
|
+
normalize : boolean = true
|
|
20
|
+
@label "Normalize"
|
|
21
|
+
@description "Trim and lowercase both sides before comparing"
|
|
22
|
+
@tier "policy"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
state idle {
|
|
26
|
+
INIT -> idle
|
|
27
|
+
(set @entity.matched false)
|
|
28
|
+
(set @entity.status idle)
|
|
29
|
+
LOOKUP -> checked
|
|
30
|
+
(let ((candStr (str/concat ?candidate))
|
|
31
|
+
(candNorm (if @config.normalize (str/lower (str/trim @candStr)) @candStr))
|
|
32
|
+
(found (array/find ?accepted
|
|
33
|
+
(fn item
|
|
34
|
+
(let ((raw (if (== @config.matchField "") @item (object/get @item @config.matchField)))
|
|
35
|
+
(rawStr (str/concat @raw))
|
|
36
|
+
(rawNorm (if @config.normalize (str/lower (str/trim @rawStr)) @rawStr)))
|
|
37
|
+
(== @rawNorm @candNorm))))))
|
|
38
|
+
(if (!= @found null)
|
|
39
|
+
(do
|
|
40
|
+
(set @entity.matched true)
|
|
41
|
+
(set @entity.status checked)
|
|
42
|
+
(emit KEY_HIT { candidate: ?candidate, entry: @found }))
|
|
43
|
+
(do
|
|
44
|
+
(set @entity.matched false)
|
|
45
|
+
(set @entity.status checked)
|
|
46
|
+
(emit KEY_MISS { candidate: ?candidate, request: ?request }))))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
state checked {
|
|
50
|
+
INIT -> checked
|
|
51
|
+
(set @entity.status checked)
|
|
52
|
+
RESET -> idle
|
|
53
|
+
(set @entity.matched false)
|
|
54
|
+
(set @entity.status idle)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
emits {
|
|
58
|
+
KEY_HIT -> external {
|
|
59
|
+
candidate : any!
|
|
60
|
+
entry : any!
|
|
61
|
+
}
|
|
62
|
+
@description "Fired when the candidate matches an entry in the accepted list"
|
|
63
|
+
@tier "primary"
|
|
64
|
+
|
|
65
|
+
KEY_MISS -> external {
|
|
66
|
+
candidate : any!
|
|
67
|
+
request : object
|
|
68
|
+
}
|
|
69
|
+
@description "Abstain — candidate matches nothing in the accepted list; the next rung should take over. request echoes the originating request untouched so the next rung can project its own inputs out of it"
|
|
70
|
+
@tier "primary"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
listens {
|
|
74
|
+
LOOKUP {
|
|
75
|
+
candidate : any!
|
|
76
|
+
accepted : [any]!
|
|
77
|
+
request : object
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
page "/ml-lookup" as MlLookupPage -> LookupRun
|
|
83
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
app std-ml-posterior "1.0.0"
|
|
2
|
+
"std-ml-posterior — the statistical rung (R2) of the intelligence ladder. Holds a Beta(alpha, beta) belief over an unknown success rate and updates it from boolean observations (Bayesian updating, knowledge tracing, Thompson-sampling prior). After each observation it draws samples from the posterior, computes a credible interval, and decides: MASTERY_REACHED when the mean clears the floor with a tight interval, REMEDIATION_NEEDED when the mean sits at or below the ceiling with the same confidence, or EVIDENCE_INSUFFICIENT — the abstain — when the interval is still too wide to trust. Use when a hand-tuned score needs to become a belief that can say 'not enough evidence yet' (mastery, skill, risk, preference, difficulty)."
|
|
3
|
+
orbital MlPosteriorOrbital {
|
|
4
|
+
|
|
5
|
+
entity Posterior [runtime] {
|
|
6
|
+
alpha : float @description "Beta distribution success count (prior + observed successes)." = 1
|
|
7
|
+
beta : float @description "Beta distribution failure count (prior + observed failures)." = 1
|
|
8
|
+
mean : float @description "Posterior mean: alpha / (alpha + beta)." = 0
|
|
9
|
+
intervalLow : float @description "Lower bound of the last computed credible interval." = 0
|
|
10
|
+
intervalHigh : float @description "Upper bound of the last computed credible interval." = 0
|
|
11
|
+
observations : int @description "Number of observations folded into the posterior so far." = 0
|
|
12
|
+
status : "idle" | "insufficient" | "mastered" | "remediate" = idle
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
trait PosteriorBelief -> @rebindable Posterior [lifecycle, instance] {
|
|
16
|
+
initial: idle
|
|
17
|
+
|
|
18
|
+
state idle {
|
|
19
|
+
INIT -> idle
|
|
20
|
+
(set @entity.alpha @config.priorAlpha)
|
|
21
|
+
(set @entity.beta @config.priorBeta)
|
|
22
|
+
(set @entity.mean (/ @config.priorAlpha (+ @config.priorAlpha @config.priorBeta)))
|
|
23
|
+
(set @entity.intervalLow 0)
|
|
24
|
+
(set @entity.intervalHigh 0)
|
|
25
|
+
(set @entity.observations 0)
|
|
26
|
+
(set @entity.status idle)
|
|
27
|
+
OBSERVE -> idle
|
|
28
|
+
(set @entity.alpha (if ?outcome (+ @entity.alpha 1) @entity.alpha))
|
|
29
|
+
(set @entity.beta (if ?outcome @entity.beta (+ @entity.beta 1)))
|
|
30
|
+
(set @entity.observations (+ @entity.observations 1))
|
|
31
|
+
(set @entity.mean (/ @entity.alpha (+ @entity.alpha @entity.beta)))
|
|
32
|
+
(let ((samples (prob/sample @config.sampleCount (prob/beta @entity.alpha @entity.beta)))
|
|
33
|
+
(interval (prob/credible-interval @samples 0.05))
|
|
34
|
+
(low (array/nth @interval 0))
|
|
35
|
+
(high (array/nth @interval 1))
|
|
36
|
+
(width (- @high @low)))
|
|
37
|
+
(do
|
|
38
|
+
(set @entity.intervalLow @low)
|
|
39
|
+
(set @entity.intervalHigh @high)
|
|
40
|
+
(if (> @width @config.intervalWidthMax)
|
|
41
|
+
(do
|
|
42
|
+
(set @entity.status insufficient)
|
|
43
|
+
(emit EVIDENCE_INSUFFICIENT { mean: @entity.mean, intervalLow: @low, intervalHigh: @high }))
|
|
44
|
+
(if (>= @entity.mean @config.masteryFloor)
|
|
45
|
+
(do
|
|
46
|
+
(set @entity.status mastered)
|
|
47
|
+
(emit MASTERY_REACHED { mean: @entity.mean, intervalLow: @low, intervalHigh: @high }))
|
|
48
|
+
(if (<= @entity.mean @config.remediationCeiling)
|
|
49
|
+
(do
|
|
50
|
+
(set @entity.status remediate)
|
|
51
|
+
(emit REMEDIATION_NEEDED { mean: @entity.mean, intervalLow: @low, intervalHigh: @high }))
|
|
52
|
+
(do
|
|
53
|
+
(set @entity.status insufficient)
|
|
54
|
+
(emit EVIDENCE_INSUFFICIENT { mean: @entity.mean, intervalLow: @low, intervalHigh: @high })))))))
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
emits {
|
|
58
|
+
MASTERY_REACHED -> external { mean : float!, intervalLow : float!, intervalHigh : float! }
|
|
59
|
+
@description "The posterior mean clears masteryFloor with a credible interval narrow enough to trust."
|
|
60
|
+
@tier "primary"
|
|
61
|
+
REMEDIATION_NEEDED -> external { mean : float!, intervalLow : float!, intervalHigh : float! }
|
|
62
|
+
@description "The posterior mean is at or below remediationCeiling with a credible interval narrow enough to trust."
|
|
63
|
+
@tier "primary"
|
|
64
|
+
EVIDENCE_INSUFFICIENT -> external { mean : float!, intervalLow : float!, intervalHigh : float! }
|
|
65
|
+
@description "The abstain — the credible interval is still wider than intervalWidthMax, so no verdict is licensed yet."
|
|
66
|
+
@tier "primary"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
listens {
|
|
70
|
+
OBSERVE {
|
|
71
|
+
outcome : boolean!
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
config {
|
|
76
|
+
priorAlpha : float = 1
|
|
77
|
+
@label "Prior alpha"
|
|
78
|
+
@description "Beta prior success pseudo-count before any observation."
|
|
79
|
+
@tier "domain"
|
|
80
|
+
priorBeta : float = 1
|
|
81
|
+
@label "Prior beta"
|
|
82
|
+
@description "Beta prior failure pseudo-count before any observation."
|
|
83
|
+
@tier "domain"
|
|
84
|
+
masteryFloor : float = 0.8
|
|
85
|
+
@label "Mastery floor"
|
|
86
|
+
@description "Posterior mean at or above this, with a tight interval, licenses MASTERY_REACHED."
|
|
87
|
+
@tier "policy"
|
|
88
|
+
remediationCeiling : float = 0.4
|
|
89
|
+
@label "Remediation ceiling"
|
|
90
|
+
@description "Posterior mean at or below this, with a tight interval, licenses REMEDIATION_NEEDED."
|
|
91
|
+
@tier "policy"
|
|
92
|
+
intervalWidthMax : float = 0.3
|
|
93
|
+
@label "Max credible-interval width"
|
|
94
|
+
@description "Above this width the posterior is too uncertain to decide — abstain with EVIDENCE_INSUFFICIENT."
|
|
95
|
+
@tier "policy"
|
|
96
|
+
sampleCount : int = 200
|
|
97
|
+
@label "Posterior sample count"
|
|
98
|
+
@description "Number of Monte Carlo draws from the Beta posterior used to estimate the credible interval."
|
|
99
|
+
@tier "infra"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
page "/ml-posterior" as MlPosteriorPage -> PosteriorBelief
|
|
104
|
+
}
|