Skip to content
Merged

AII-836 #1359

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Plugins/BotSharp.Plugin.Membase/Interfaces/IMembaseApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ public interface IMembaseApi
#endregion

#region PGT
[Get("/graph/{graphId}/pgt-definitions/{definitionId}")]
Task<PgtDefinition> GetPgtDefinitionAsync(string graphId, string definitionId);

[Post("/graph/{graphId}/pgt-definitions/{definitionId}/simulate")]
Task<PgtSimulationResponse> SimulatePgtDefinitionAsync(string graphId, string definitionId, [Body] PgtSimulationRequest request);

Expand Down
72 changes: 72 additions & 0 deletions src/Plugins/BotSharp.Plugin.Membase/Models/PgtConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System.Text.Json.Serialization;

namespace BotSharp.Plugin.Membase.Models;

/// <summary>
/// Full configuration block returned by the pgt-definitions endpoint.
/// </summary>
public class PgtConfig
{
[JsonPropertyName("startId")]
public string? StartId { get; set; }

[JsonPropertyName("maxDepth")]
public int MaxDepth { get; set; }

[JsonPropertyName("renderDepth")]
public int RenderDepth { get; set; }

[JsonPropertyName("appendTopology")]
public bool AppendTopology { get; set; }

[JsonPropertyName("fuzzyThreshold")]
public double FuzzyThreshold { get; set; }

[JsonPropertyName("maxNodes")]
public int MaxNodes { get; set; }

[JsonPropertyName("strategy")]
public string? Strategy { get; set; }

[JsonPropertyName("maxVisitsPerNode")]
public int MaxVisitsPerNode { get; set; }

[JsonPropertyName("timeoutMs")]
public int TimeoutMs { get; set; }

[JsonPropertyName("maxSubgraphNesting")]
public int MaxSubgraphNesting { get; set; }

[JsonPropertyName("recordTrace")]
public bool RecordTrace { get; set; }

[JsonPropertyName("persistRun")]
public bool PersistRun { get; set; }

[JsonPropertyName("validationChecks")]
public List<string>? ValidationChecks { get; set; }

[JsonPropertyName("targetIdsRaw")]
public string? TargetIdsRaw { get; set; }

[JsonPropertyName("allowedEdgeTypesRaw")]
public string? AllowedEdgeTypesRaw { get; set; }

/// <summary>JSON string containing the environment key-value pairs.</summary>
[JsonPropertyName("environmentJson")]
public string? EnvironmentJson { get; set; }

/// <summary>JSON string containing the initial context key-value pairs.</summary>
[JsonPropertyName("initialContextJson")]
public string? InitialContextJson { get; set; }

/// <summary>
/// JSON array string of actor descriptors. Each element has an <c>actor_id</c>
/// field used as the dictionary key when building a traverse request.
/// </summary>
[JsonPropertyName("actorsJson")]
public string? ActorsJson { get; set; }

[JsonPropertyName("dag")]
public bool Dag { get; set; }
}
36 changes: 36 additions & 0 deletions src/Plugins/BotSharp.Plugin.Membase/Models/PgtDefinition.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Text.Json.Serialization;

namespace BotSharp.Plugin.Membase.Models;

/// <summary>
/// Response from GET /graph/{graphId}/pgt-definitions/{definitionId}
/// </summary>
public class PgtDefinition
{
[JsonPropertyName("id")]
public string Id { get; set; } = string.Empty;

[JsonPropertyName("graphId")]
public string GraphId { get; set; } = string.Empty;

[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;

[JsonPropertyName("description")]
public string? Description { get; set; }

[JsonPropertyName("ownerUserId")]
public string? OwnerUserId { get; set; }

[JsonPropertyName("config")]
public PgtConfig Config { get; set; } = new();

[JsonPropertyName("version")]
public int Version { get; set; }

[JsonPropertyName("createdAt")]
public DateTimeOffset? CreatedAt { get; set; }

[JsonPropertyName("updatedAt")]
public DateTimeOffset? UpdatedAt { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,103 @@ namespace BotSharp.Plugin.Membase.Models;

public class PgtTraversalRequest
{
[JsonPropertyName("startId")]
public string StartId { get; set; } = string.Empty;

[JsonPropertyName("options")]
public PgtTraversalOptions? Options { get; set; }

/// <summary>
/// Builds a traverse request from a fetched <see cref="PgtDefinition"/>,
/// merging caller overrides on top of stored config values.
/// </summary>
public static PgtTraversalRequest FromDefinition(
PgtDefinition definition,
string? runId = null,
Dictionary<string, object?>? environmentOverrides = null,
Dictionary<string, object?>? initialContextOverrides = null,
bool stream = false,
bool debug = false,
string[]? pauseOn = null,
int? debugIdleTimeoutMs = null)
{
var cfg = definition.Config;

return new PgtTraversalRequest
{
StartId = cfg.StartId ?? string.Empty,
Options = new PgtTraversalOptions
{
MaxDepth = cfg.MaxDepth,
MaxVisitsPerNode = cfg.MaxVisitsPerNode,
TimeoutMs = cfg.TimeoutMs,
MaxSubGrapNesting = cfg.MaxSubgraphNesting,
Strategy = cfg.Strategy,
RecordTrace = cfg.RecordTrace,
PersistRun = cfg.PersistRun,
RunId = runId,
Stream = stream,
Debug = debug,
PauseOn = pauseOn,
DebugIdleTimeoutMs = debugIdleTimeoutMs,
Actors = ParseActorsJson(cfg.ActorsJson),
Environment = MergeJsonDict(cfg.EnvironmentJson, environmentOverrides),
InitialContext = MergeJsonDict(cfg.InitialContextJson, initialContextOverrides),
},
};
}

private static Dictionary<string, object>? ParseActorsJson(string? actorsJson)
{
if (string.IsNullOrWhiteSpace(actorsJson))
return null;

var array = JsonSerializer.Deserialize<JsonElement[]>(actorsJson);
if (array is null || array.Length == 0)
return null;

var dict = new Dictionary<string, object>(StringComparer.Ordinal);
foreach (var element in array)
{
if (!element.TryGetProperty("actor_id", out var idProp))
continue;

var actorId = idProp.GetString() ?? string.Empty;
dict[actorId] = JsonSerializer.Deserialize<object>(element.GetRawText()) ?? element;
}

return dict.Count > 0 ? dict : null;
}

private static Dictionary<string, object>? MergeJsonDict(
string? existingJson,
Dictionary<string, object?>? overrides)
{
var merged = new Dictionary<string, object>(StringComparer.Ordinal);

if (!string.IsNullOrWhiteSpace(existingJson))
{
var existing = JsonSerializer.Deserialize<Dictionary<string, object>>(existingJson);
if (existing is not null)
{
foreach (var kv in existing)
merged[kv.Key] = kv.Value;
}
}

if (overrides is not null && overrides.Count > 0)
{
foreach (var kv in overrides)
{
if (kv.Value is null)
merged.Remove(kv.Key);
else
merged[kv.Key] = kv.Value;
}
}

return merged.Count > 0 ? merged : null;
}
}

public class PgtTraversalOptions
Expand Down
Loading