package resolution import ( "maps" "slices" ) // schema is a JSON schema for an object of string properties, which is every argument the verbs // above take. Kept small on purpose: a schema an agent cannot read is a tool it cannot call. The // switches are the properties that are "true" or "false" and nothing else, said in the schema as an // enum so a caller sees it and the verb can refuse any other word rather than read it as false. // // **The schema is the whole of what a verb takes** (novox/hq issue 244): an argument it does not // name is refused when the verb is called, never passed over. // withObject adds to a verb's input s the property name, an object of the string fields given, each required. func withObject(s map[string]any, name, description string, fields map[string]string) map[string]any { inner := schema(fields, slices.Sorted(maps.Keys(fields))) inner["description"], inner["additionalProperties"] = description, false s["properties"].(map[string]any)[name] = inner return s } func schema(properties map[string]string, required []string, switches ...string) map[string]any { isSwitch := map[string]bool{} for _, s := range switches { if _, declared := properties[s]; !declared { panic("a switch that is not a property: " + s) } isSwitch[s] = true } props := map[string]any{} for name, description := range properties { p := map[string]any{"type": "string", "description": description} if isSwitch[name] { p["enum"] = []string{"true", "false"} } props[name] = p } out := map[string]any{"type": "object", "properties": props} if len(required) > 0 { out["required"] = required } return out } // listed makes the named properties of a schema lists of text: a caller gives them as a JSON array (or, as // any argument, one text separated by commas). func listed(in map[string]any, names ...string) map[string]any { props, _ := in["properties"].(map[string]any) for _, n := range names { p, _ := props[n].(map[string]any) if p == nil { panic("a list that is not a property: " + n) } props[n] = map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": p["description"]} } return in }