211 lines
9.4 KiB
C#
211 lines
9.4 KiB
C#
using PlotLine.Models;
|
|
|
|
namespace PlotLine.Services;
|
|
|
|
public static class StoryIntelligenceSceneStructuredOutputSchema
|
|
{
|
|
public const string ContractName = "scene_intelligence_v1";
|
|
|
|
public static StoryIntelligenceResponseContract Contract { get; } = new()
|
|
{
|
|
Name = ContractName,
|
|
Strict = true,
|
|
Schema = BuildSchema()
|
|
};
|
|
|
|
private static Dictionary<string, object> BuildSchema()
|
|
{
|
|
var sceneReference = Obj(Props(
|
|
("projectId", NullableInteger()),
|
|
("bookId", NullableInteger()),
|
|
("chapterId", NullableInteger()),
|
|
("sceneId", NullableInteger()),
|
|
("chapterNumber", NullableNumber()),
|
|
("sceneNumber", NullableNumber()),
|
|
("sourceLabel", Str())));
|
|
var purpose = Obj(Props(("observedFunction", Str()), ("confidence", Confidence())));
|
|
var pointOfView = Obj(Props(
|
|
("characterName", NullableString()),
|
|
("narrativeMode", NullableString()),
|
|
("confidence", Confidence()),
|
|
("evidence", NullableString())));
|
|
var setting = Obj(Props(
|
|
("timeOfDay", NullableString()),
|
|
("dateOrTimeReference", NullableString()),
|
|
("locationName", NullableString()),
|
|
("locationType", Enum("named", "generic", "unclear")),
|
|
("genericRoomType", NullableString()),
|
|
("parentLocationHint", NullableString()),
|
|
("confidence", Confidence())));
|
|
|
|
var characters = Arr(Obj(Props(
|
|
("name", Str()),
|
|
("roleInScene", Enum("present", "pointOfView", "speaker", "mentioned", "unclear")),
|
|
("mentionedOnly", Bool()),
|
|
("aliases", Arr(Str())),
|
|
("actions", Arr(Str())),
|
|
("confidence", Confidence()),
|
|
("notes", NullableString()))));
|
|
var characterAppearance = Arr(Obj(Props(
|
|
("canonicalName", Str()),
|
|
("aliases", Arr(Str())),
|
|
("title", NullableString()),
|
|
("presentation", NullableString()),
|
|
("explicitAge", NullableString()),
|
|
("inferredAgeBand", NullableString()),
|
|
("hairColour", NullableString()),
|
|
("hairLength", NullableString()),
|
|
("hairStyle", NullableString()),
|
|
("eyeColour", NullableString()),
|
|
("facialHair", NullableString()),
|
|
("glasses", NullableString()),
|
|
("height", NullableString()),
|
|
("build", NullableString()),
|
|
("distinctiveFeatures", Arr(Str())),
|
|
("clothing", NullableString()),
|
|
("roleOrOccupation", NullableString()),
|
|
("relationshipAgeEvidence", NullableString()),
|
|
("pronounEvidence", NullableString()),
|
|
("evidence", Str()),
|
|
("confidence", Confidence()),
|
|
("evidenceKind", Enum("explicit", "inferred")))));
|
|
var locations = Arr(Obj(Props(
|
|
("name", Str()),
|
|
("locationType", Enum("named", "generic", "unclear")),
|
|
("genericRoomType", NullableString()),
|
|
("parentLocationHint", NullableString()),
|
|
("presentInScene", Bool()),
|
|
("mentionedOnly", Bool()),
|
|
("confidence", Confidence()),
|
|
("notes", NullableString()))));
|
|
var assets = Arr(Obj(Props(
|
|
("name", Str()),
|
|
("assetType", NullableString()),
|
|
("status", NullableString()),
|
|
("ownerOrHolder", NullableString()),
|
|
("mentionedOnly", Bool()),
|
|
("confidence", Confidence()),
|
|
("notes", NullableString()))));
|
|
var relationships = Arr(Obj(Props(
|
|
("characterA", Str()),
|
|
("characterB", Str()),
|
|
("relationshipSignal", Enum("trust", "mistrust", "affection", "fear", "authority", "secrecy", "conflict", "dependence", "protection", "rivalry", "obligation")),
|
|
("evidence", Str()),
|
|
("confidence", Confidence()))));
|
|
var knowledgeChanges = Arr(Obj(Props(
|
|
("recipientCharacter", Str()),
|
|
("knowledgeItem", Str()),
|
|
("changeType", Enum("Learns", "Realises", "IsTold", "Discovers", "Confirms", "Suspects", "Misunderstands")),
|
|
("sourceCharacter", NullableString()),
|
|
("sourceType", NullableString()),
|
|
("evidence", Str()),
|
|
("confidence", Confidence()))));
|
|
var timelineClues = Arr(Obj(Props(
|
|
("clue", Str()),
|
|
("relativeOrder", NullableString()),
|
|
("absoluteDate", NullableString()),
|
|
("evidence", Str()),
|
|
("confidence", Confidence()))));
|
|
var narrativeArcs = Arr(Obj(Props(
|
|
("title", Str()),
|
|
("description", Str()),
|
|
("arcType", Str()),
|
|
("scale", Enum("major", "secondary", "thread")),
|
|
("changeType", Enum("Introduced", "Developed", "Complicated", "Revealed", "Escalated", "Resolved", "Reopened", "Mentioned")),
|
|
("significance", Enum("major", "moderate", "minor")),
|
|
("continuityKey", Str()),
|
|
("parentArcTitle", NullableString()),
|
|
("matchingExistingPlotLineId", NullableInteger()),
|
|
("matchingExistingThreadId", NullableInteger()),
|
|
("evidence", Str()),
|
|
("confidence", Confidence()))));
|
|
var questionsRaised = Arr(Obj(Props(("question", Str()), ("scope", Str()), ("evidence", Str()), ("confidence", Confidence()))));
|
|
var questionsAnswered = Arr(Obj(Props(("question", Str()), ("answer", Str()), ("evidence", Str()), ("confidence", Confidence()))));
|
|
var observations = Arr(Obj(Props(
|
|
("observationType", Enum("CharacterAction", "CharacterKnowledge", "CharacterLocation", "RelationshipSignal", "AssetInteraction", "LocationSignal", "TimelineSignal", "QuestionSignal")),
|
|
("subjectEntityType", Enum("Character", "Location", "Asset", "Knowledge", "Relationship", "Timeline", "Scene", "Unknown")),
|
|
("subjectName", Str()),
|
|
("objectEntityType", NullableEnum("Character", "Location", "Asset", "Knowledge", "Relationship", "Timeline", "Scene", "Unknown")),
|
|
("objectName", NullableString()),
|
|
("predicate", Str()),
|
|
("description", Str()),
|
|
("evidence", Str()),
|
|
("confidence", Confidence()))));
|
|
var metricValues = Arr(Obj(Props(
|
|
("key", Str("Configured metric key from sceneContext.configuredMetrics.")),
|
|
("score", Integer()),
|
|
("confidence", Confidence()))));
|
|
var sourceLimits = Obj(Props(("containsAmbiguity", Bool()), ("ambiguityNotes", Arr(Str()))));
|
|
|
|
return Obj(Props(
|
|
("schemaVersion", Str("Scene Intelligence schema version. Use 1.0.")),
|
|
("sceneReference", sceneReference),
|
|
("scenePurpose", purpose),
|
|
("pointOfView", pointOfView),
|
|
("setting", setting),
|
|
("characters", characters),
|
|
("characterAppearance", characterAppearance),
|
|
("locations", locations),
|
|
("assets", assets),
|
|
("relationships", relationships),
|
|
("knowledgeChanges", knowledgeChanges),
|
|
("timelineClues", timelineClues),
|
|
("narrativeArcs", narrativeArcs),
|
|
("questionsRaised", questionsRaised),
|
|
("questionsAnswered", questionsAnswered),
|
|
("observations", observations),
|
|
("metricValues", metricValues),
|
|
("sourceLimits", sourceLimits)));
|
|
}
|
|
|
|
private static Dictionary<string, object> Obj(Dictionary<string, object> properties)
|
|
=> new()
|
|
{
|
|
["type"] = "object",
|
|
["properties"] = properties,
|
|
["required"] = properties.Keys.ToArray(),
|
|
["additionalProperties"] = false
|
|
};
|
|
|
|
private static Dictionary<string, object> Arr(object items)
|
|
=> new() { ["type"] = "array", ["items"] = items };
|
|
|
|
private static Dictionary<string, object> Str(string? description = null)
|
|
{
|
|
var value = new Dictionary<string, object> { ["type"] = "string" };
|
|
if (!string.IsNullOrWhiteSpace(description))
|
|
{
|
|
value["description"] = description;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
private static Dictionary<string, object> NullableString()
|
|
=> new() { ["type"] = new[] { "string", "null" } };
|
|
|
|
private static Dictionary<string, object> Integer()
|
|
=> new() { ["type"] = "integer" };
|
|
|
|
private static Dictionary<string, object> NullableInteger()
|
|
=> new() { ["type"] = new[] { "integer", "null" } };
|
|
|
|
private static Dictionary<string, object> NullableNumber()
|
|
=> new() { ["type"] = new[] { "number", "null" } };
|
|
|
|
private static Dictionary<string, object> Bool()
|
|
=> new() { ["type"] = "boolean" };
|
|
|
|
private static Dictionary<string, object> Confidence()
|
|
=> new() { ["type"] = "number", ["minimum"] = 0, ["maximum"] = 1 };
|
|
|
|
private static Dictionary<string, object> Enum(params string[] values)
|
|
=> new() { ["type"] = "string", ["enum"] = values };
|
|
|
|
private static Dictionary<string, object> NullableEnum(params string[] values)
|
|
=> new() { ["type"] = new[] { "string", "null" }, ["enum"] = values.Cast<string?>().Append(null).ToArray() };
|
|
|
|
private static Dictionary<string, object> Props(params (string Name, object Schema)[] properties)
|
|
=> properties.ToDictionary(property => property.Name, property => property.Schema, StringComparer.Ordinal);
|
|
}
|