Acts are kept 400 days under the runtime-proven caller and said as act-recorded; a warrant is read from the router's own record and recorded once per ask; hand-acts answers over both logs. The act layout is a copy of mesh-sdk's until L5-S2 lands.
111 lines
4.3 KiB
Go
111 lines
4.3 KiB
Go
package main
|
|
|
|
// The seat's verbs (novox/hq ADR 0565 §10, §15): hand-act and warranted record, hand-acts reads both logs and, with
|
|
// warrants, every warrant recorded. A recovery is a call: a warrant whose act was lost is written again by asking
|
|
// warranted again, from the router's record.
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
stdio "git.novox.be/novox/mesh-sdk/go"
|
|
)
|
|
|
|
// Verbs are the seat's verbs, as the manifest claims them.
|
|
var Verbs = []string{"hand-act", "hand-acts", "warranted"}
|
|
|
|
// Tool names.
|
|
const (
|
|
HandActTool = Seat + ".hand-act"
|
|
HandActsTool = Seat + ".hand-acts"
|
|
WarrantedTool = Seat + ".warranted"
|
|
)
|
|
|
|
func obj(props map[string]any, required ...string) map[string]any {
|
|
m := map[string]any{"type": "object", "properties": props}
|
|
if len(required) > 0 {
|
|
m["required"] = required
|
|
}
|
|
return m
|
|
}
|
|
|
|
func str(d string) map[string]any { return map[string]any{"type": "string", "description": d} }
|
|
|
|
// Tools are what the runtime serves.
|
|
func Tools(l *Log) []stdio.Tool {
|
|
return []stdio.Tool{
|
|
{Name: HandActTool,
|
|
Description: "Record one act done by hand (novox/hq ADR 0565 §10): what was done, why, its cause in a word or a " +
|
|
"condition's kind (the word a second act for the same reason uses, which is how a repair done twice is " +
|
|
"found) and the condition it addresses. Who did it is the caller the runtime proves. verb is the act's " +
|
|
"verb as the log names it: a repair when not given, `hand-act drill` for a drill, or a recorder's own " +
|
|
"(`conditions silence`, `config set`). Said as act-recorded.",
|
|
Input: obj(map[string]any{"what": str("what was done"), "why": str("why, in a sentence"),
|
|
"cause": str("the cause, in a word or a condition's kind"), "condition": str("the condition's key, if any"),
|
|
"verb": str("the act's verb in the log; a repair when not given")}, "what", "why"),
|
|
Run: func(a map[string]any) (any, error) {
|
|
return l.HandAct(stdio.CallerOf(a), arg(a, "verb"), arg(a, "what"), arg(a, "why"), arg(a, "cause"), arg(a, "condition"))
|
|
}},
|
|
{Name: HandActsTool,
|
|
Description: "What was done by hand lately, over both logs (this seat's and the controller's until its lease " +
|
|
"ends), newest first: each act with who, why, its cause and which log holds it, and the causes repaired by " +
|
|
"hand twice or more within a fortnight (a healer is wanted). Narrowed by cause and who; warrants=true lists " +
|
|
"every warrant recorded instead.",
|
|
Input: obj(map[string]any{"days": map[string]any{"type": "number", "description": "how many days back (default 14)"},
|
|
"cause": str("only this cause"), "who": str("only acts whose who contains this"),
|
|
"warrants": str("\"true\": every warrant recorded, `<asker>.<ask>` with its act")}),
|
|
Run: func(a map[string]any) (any, error) {
|
|
if strings.EqualFold(arg(a, "warrants"), "true") || a["warrants"] == true {
|
|
return l.Warrants()
|
|
}
|
|
return l.HandActs(days(a), arg(a, "cause"), arg(a, "who")), nil
|
|
}},
|
|
{Name: WarrantedTool,
|
|
Description: "Record an asker's act on the operator's warrant (ADR 0274, ADR 0259): read from the router's own " +
|
|
"record of that ask — who chose, through which channel, with which proofs and which answer — never from the " +
|
|
"caller, once per ask; refused for an ask still open, ended without a choice, or another asker's.",
|
|
Input: obj(map[string]any{"asker": str("the module that asked"), "ask": str("its ask's id")}, "asker", "ask"),
|
|
Run: func(a map[string]any) (any, error) {
|
|
return l.Warranted(stdio.CallerOf(a), arg(a, "asker"), arg(a, "ask"))
|
|
}},
|
|
}
|
|
}
|
|
|
|
// Warrants is every warrant recorded, by key.
|
|
func (l *Log) Warrants() (any, error) {
|
|
keys, err := l.Store.Keys(WarrantsState)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("the warrants cannot be read: %w", err)
|
|
}
|
|
sort.Strings(keys)
|
|
rows := map[string]json.RawMessage{}
|
|
for _, k := range keys {
|
|
if raw, found, err := l.Store.Get(WarrantsState, k); err == nil && found {
|
|
rows[k] = raw
|
|
}
|
|
}
|
|
return map[string]any{"warrants": rows, "count": len(rows)}, nil
|
|
}
|
|
|
|
func arg(a map[string]any, k string) string {
|
|
s, _ := a[k].(string)
|
|
return strings.TrimSpace(s)
|
|
}
|
|
|
|
func days(a map[string]any) int {
|
|
switch v := a["days"].(type) {
|
|
case float64:
|
|
if v > 0 {
|
|
return int(v)
|
|
}
|
|
case string:
|
|
var n int
|
|
if _, err := fmt.Sscan(v, &n); err == nil && n > 0 {
|
|
return n
|
|
}
|
|
}
|
|
return 14
|
|
}
|