Skip to content

Commit a7be958

Browse files
authored
Merge pull request #1359 from danielyuan476-ctrl/master
AII-836
2 parents 58ee544 + 231abbc commit a7be958

4 files changed

Lines changed: 204 additions & 0 deletions

File tree

src/Plugins/BotSharp.Plugin.Membase/Interfaces/IMembaseApi.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public interface IMembaseApi
4747
#endregion
4848

4949
#region PGT
50+
[Get("/graph/{graphId}/pgt-definitions/{definitionId}")]
51+
Task<PgtDefinition> GetPgtDefinitionAsync(string graphId, string definitionId);
52+
5053
[Post("/graph/{graphId}/pgt-definitions/{definitionId}/simulate")]
5154
Task<PgtSimulationResponse> SimulatePgtDefinitionAsync(string graphId, string definitionId, [Body] PgtSimulationRequest request);
5255

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace BotSharp.Plugin.Membase.Models;
4+
5+
/// <summary>
6+
/// Full configuration block returned by the pgt-definitions endpoint.
7+
/// </summary>
8+
public class PgtConfig
9+
{
10+
[JsonPropertyName("startId")]
11+
public string? StartId { get; set; }
12+
13+
[JsonPropertyName("maxDepth")]
14+
public int MaxDepth { get; set; }
15+
16+
[JsonPropertyName("renderDepth")]
17+
public int RenderDepth { get; set; }
18+
19+
[JsonPropertyName("appendTopology")]
20+
public bool AppendTopology { get; set; }
21+
22+
[JsonPropertyName("fuzzyThreshold")]
23+
public double FuzzyThreshold { get; set; }
24+
25+
[JsonPropertyName("maxNodes")]
26+
public int MaxNodes { get; set; }
27+
28+
[JsonPropertyName("strategy")]
29+
public string? Strategy { get; set; }
30+
31+
[JsonPropertyName("maxVisitsPerNode")]
32+
public int MaxVisitsPerNode { get; set; }
33+
34+
[JsonPropertyName("timeoutMs")]
35+
public int TimeoutMs { get; set; }
36+
37+
[JsonPropertyName("maxSubgraphNesting")]
38+
public int MaxSubgraphNesting { get; set; }
39+
40+
[JsonPropertyName("recordTrace")]
41+
public bool RecordTrace { get; set; }
42+
43+
[JsonPropertyName("persistRun")]
44+
public bool PersistRun { get; set; }
45+
46+
[JsonPropertyName("validationChecks")]
47+
public List<string>? ValidationChecks { get; set; }
48+
49+
[JsonPropertyName("targetIdsRaw")]
50+
public string? TargetIdsRaw { get; set; }
51+
52+
[JsonPropertyName("allowedEdgeTypesRaw")]
53+
public string? AllowedEdgeTypesRaw { get; set; }
54+
55+
/// <summary>JSON string containing the environment key-value pairs.</summary>
56+
[JsonPropertyName("environmentJson")]
57+
public string? EnvironmentJson { get; set; }
58+
59+
/// <summary>JSON string containing the initial context key-value pairs.</summary>
60+
[JsonPropertyName("initialContextJson")]
61+
public string? InitialContextJson { get; set; }
62+
63+
/// <summary>
64+
/// JSON array string of actor descriptors. Each element has an <c>actor_id</c>
65+
/// field used as the dictionary key when building a traverse request.
66+
/// </summary>
67+
[JsonPropertyName("actorsJson")]
68+
public string? ActorsJson { get; set; }
69+
70+
[JsonPropertyName("dag")]
71+
public bool Dag { get; set; }
72+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace BotSharp.Plugin.Membase.Models;
4+
5+
/// <summary>
6+
/// Response from GET /graph/{graphId}/pgt-definitions/{definitionId}
7+
/// </summary>
8+
public class PgtDefinition
9+
{
10+
[JsonPropertyName("id")]
11+
public string Id { get; set; } = string.Empty;
12+
13+
[JsonPropertyName("graphId")]
14+
public string GraphId { get; set; } = string.Empty;
15+
16+
[JsonPropertyName("name")]
17+
public string Name { get; set; } = string.Empty;
18+
19+
[JsonPropertyName("description")]
20+
public string? Description { get; set; }
21+
22+
[JsonPropertyName("ownerUserId")]
23+
public string? OwnerUserId { get; set; }
24+
25+
[JsonPropertyName("config")]
26+
public PgtConfig Config { get; set; } = new();
27+
28+
[JsonPropertyName("version")]
29+
public int Version { get; set; }
30+
31+
[JsonPropertyName("createdAt")]
32+
public DateTimeOffset? CreatedAt { get; set; }
33+
34+
[JsonPropertyName("updatedAt")]
35+
public DateTimeOffset? UpdatedAt { get; set; }
36+
}

src/Plugins/BotSharp.Plugin.Membase/Models/Requests/PgtTraversalRequest.cs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,103 @@ namespace BotSharp.Plugin.Membase.Models;
44

55
public class PgtTraversalRequest
66
{
7+
[JsonPropertyName("startId")]
78
public string StartId { get; set; } = string.Empty;
89

910
[JsonPropertyName("options")]
1011
public PgtTraversalOptions? Options { get; set; }
12+
13+
/// <summary>
14+
/// Builds a traverse request from a fetched <see cref="PgtDefinition"/>,
15+
/// merging caller overrides on top of stored config values.
16+
/// </summary>
17+
public static PgtTraversalRequest FromDefinition(
18+
PgtDefinition definition,
19+
string? runId = null,
20+
Dictionary<string, object?>? environmentOverrides = null,
21+
Dictionary<string, object?>? initialContextOverrides = null,
22+
bool stream = false,
23+
bool debug = false,
24+
string[]? pauseOn = null,
25+
int? debugIdleTimeoutMs = null)
26+
{
27+
var cfg = definition.Config;
28+
29+
return new PgtTraversalRequest
30+
{
31+
StartId = cfg.StartId ?? string.Empty,
32+
Options = new PgtTraversalOptions
33+
{
34+
MaxDepth = cfg.MaxDepth,
35+
MaxVisitsPerNode = cfg.MaxVisitsPerNode,
36+
TimeoutMs = cfg.TimeoutMs,
37+
MaxSubGrapNesting = cfg.MaxSubgraphNesting,
38+
Strategy = cfg.Strategy,
39+
RecordTrace = cfg.RecordTrace,
40+
PersistRun = cfg.PersistRun,
41+
RunId = runId,
42+
Stream = stream,
43+
Debug = debug,
44+
PauseOn = pauseOn,
45+
DebugIdleTimeoutMs = debugIdleTimeoutMs,
46+
Actors = ParseActorsJson(cfg.ActorsJson),
47+
Environment = MergeJsonDict(cfg.EnvironmentJson, environmentOverrides),
48+
InitialContext = MergeJsonDict(cfg.InitialContextJson, initialContextOverrides),
49+
},
50+
};
51+
}
52+
53+
private static Dictionary<string, object>? ParseActorsJson(string? actorsJson)
54+
{
55+
if (string.IsNullOrWhiteSpace(actorsJson))
56+
return null;
57+
58+
var array = JsonSerializer.Deserialize<JsonElement[]>(actorsJson);
59+
if (array is null || array.Length == 0)
60+
return null;
61+
62+
var dict = new Dictionary<string, object>(StringComparer.Ordinal);
63+
foreach (var element in array)
64+
{
65+
if (!element.TryGetProperty("actor_id", out var idProp))
66+
continue;
67+
68+
var actorId = idProp.GetString() ?? string.Empty;
69+
dict[actorId] = JsonSerializer.Deserialize<object>(element.GetRawText()) ?? element;
70+
}
71+
72+
return dict.Count > 0 ? dict : null;
73+
}
74+
75+
private static Dictionary<string, object>? MergeJsonDict(
76+
string? existingJson,
77+
Dictionary<string, object?>? overrides)
78+
{
79+
var merged = new Dictionary<string, object>(StringComparer.Ordinal);
80+
81+
if (!string.IsNullOrWhiteSpace(existingJson))
82+
{
83+
var existing = JsonSerializer.Deserialize<Dictionary<string, object>>(existingJson);
84+
if (existing is not null)
85+
{
86+
foreach (var kv in existing)
87+
merged[kv.Key] = kv.Value;
88+
}
89+
}
90+
91+
if (overrides is not null && overrides.Count > 0)
92+
{
93+
foreach (var kv in overrides)
94+
{
95+
if (kv.Value is null)
96+
merged.Remove(kv.Key);
97+
else
98+
merged[kv.Key] = kv.Value;
99+
}
100+
}
101+
102+
return merged.Count > 0 ? merged : null;
103+
}
11104
}
12105

13106
public class PgtTraversalOptions

0 commit comments

Comments
 (0)