Forge
csharpc0b81713
1using System.Text.Json;
2using System.Text.RegularExpressions;
3
4internal static class ToolArgs
5{
6 internal static string RequiredString(IReadOnlyDictionary<string, JsonElement> args, string key)
7 {
8 if (!args.TryGetValue(key, out var value))
9 throw new ArgumentException($"{key} is required.");
10 var str = value.GetString();
11 if (string.IsNullOrWhiteSpace(str))
12 throw new ArgumentException($"{key} is required.");
13 return str.Trim();
14 }
15
16 internal static string? OptionalString(IReadOnlyDictionary<string, JsonElement> args, string key)
17 {
18 if (!args.TryGetValue(key, out var value))
19 return null;
20 var str = value.GetString();
21 return string.IsNullOrWhiteSpace(str) ? null : str.Trim();
22 }
23
24 internal static string? OptionalKnowledgePath(IReadOnlyDictionary<string, JsonElement> args) =>
25 OptionalString(args, "knowledge_path");
26
27 internal static string? OptionalKnowledgeRootId(IReadOnlyDictionary<string, JsonElement> args) =>
28 OptionalString(args, "knowledge_root_id");
29
30 internal static int GetIntOrDefault(IReadOnlyDictionary<string, JsonElement> args, string key, int defaultValue, int min, int max)
31 {
32 if (!args.TryGetValue(key, out var raw))
33 return defaultValue;
34
35 int parsed;
36 if (raw.ValueKind == JsonValueKind.Number)
37 {
38 parsed = raw.GetInt32();
39 }
40 else if (raw.ValueKind == JsonValueKind.String && int.TryParse(raw.GetString(), out var asInt))
41 {
42 parsed = asInt;
43 }
44 else
45 {
46 return defaultValue;
47 }
48
49 return Math.Clamp(parsed, min, max);
50 }
51
52 /// <summary>Optional integer: key missing or null → null; otherwise parse number or string, then clamp to [min, max].</summary>
53 internal static int? OptionalClampedInt(IReadOnlyDictionary<string, JsonElement> args, string key, int min, int max)
54 {
55 if (!args.TryGetValue(key, out var raw) || raw.ValueKind == JsonValueKind.Null)
56 return null;
57 int parsed;
58 if (raw.ValueKind == JsonValueKind.Number)
59 parsed = raw.GetInt32();
60 else if (raw.ValueKind == JsonValueKind.String && int.TryParse(raw.GetString(), out var s))
61 parsed = s;
62 else
63 return null;
64 return Math.Clamp(parsed, min, max);
65 }
66
67 internal static bool IsValidSectionId(string sectionId) => Regex.IsMatch(sectionId, "^[A-Za-z0-9._-]+$");
68
69 internal static bool GetBoolOrDefault(IReadOnlyDictionary<string, JsonElement> args, string key, bool defaultValue)
70 {
71 if (!args.TryGetValue(key, out var raw))
72 return defaultValue;
73
74 return raw.ValueKind switch
75 {
76 JsonValueKind.True => true,
77 JsonValueKind.False => false,
78 JsonValueKind.String when bool.TryParse(raw.GetString(), out var parsed) => parsed,
79 _ => defaultValue
80 };
81 }
82}
83
View only · write via MCP/CIDE