133 lines
5.8 KiB
JavaScript
133 lines
5.8 KiB
JavaScript
import {
|
|
ConfidenceLevel,
|
|
SituationKind,
|
|
SituationRelationship,
|
|
SituationStatus,
|
|
} from "./schema.js";
|
|
|
|
const DEFAULT_PROMPT_VERSION = "v0.4";
|
|
|
|
function formatEnumValues(values) {
|
|
return Object.values(values).join(" | ");
|
|
}
|
|
|
|
function formatGraph(graph) {
|
|
return JSON.stringify(graph, null, 2);
|
|
}
|
|
|
|
function formatExampleAnswerBlock() {
|
|
return [
|
|
"Example answer the model must be able to handle without hard-coding output:",
|
|
'"The complaint rate fell from 2.0 complaints per 100 units to 1.9 complaints per 100 units."',
|
|
"This may justify resolving a rate-related unknown or updating a metric node, but only if the current graph and answer support that proposal.",
|
|
].join("\n");
|
|
}
|
|
|
|
export function buildGraphUpdatePrompt({
|
|
situationGraph,
|
|
previousQuestion,
|
|
answer,
|
|
promptVersion = DEFAULT_PROMPT_VERSION,
|
|
}) {
|
|
const nodeKinds = formatEnumValues(SituationKind);
|
|
const nodeStatuses = formatEnumValues(SituationStatus);
|
|
const edgeRelationships = formatEnumValues(SituationRelationship);
|
|
const confidenceLevels = formatEnumValues(ConfidenceLevel);
|
|
|
|
return `You are proposing a graph update for Confidence Engine ${promptVersion}.
|
|
|
|
Return exactly one JSON object matching the GraphUpdate contract.
|
|
Return JSON only. Do not include markdown, explanation, or any text before or after the JSON object.
|
|
|
|
## Current Situation Graph
|
|
${formatGraph(situationGraph)}
|
|
|
|
## Previous Selected Question
|
|
${previousQuestion}
|
|
|
|
## User Answer
|
|
${answer}
|
|
|
|
## Allowed Node Kinds
|
|
${nodeKinds}
|
|
|
|
## Allowed Node Statuses
|
|
${nodeStatuses}
|
|
|
|
## Allowed Edge Relationships
|
|
${edgeRelationships}
|
|
|
|
## Allowed Confidence Values
|
|
${confidenceLevels}
|
|
|
|
## Required JSON Field Names
|
|
The JSON object must contain exactly these top-level fields:
|
|
- addedNodes
|
|
- updatedNodes
|
|
- addedEdges
|
|
- removedEdgeIds
|
|
- resolvedUnknownNodeIds
|
|
- affectedNodeIds
|
|
- selectedQuestion
|
|
|
|
## Required Shapes
|
|
- addedNodes: array of nodes using these exact keys:
|
|
id, label, description, kind, status, confidence, value, unit, evidenceIds, dependsOn, affects, parentId, childIds
|
|
- updatedNodes: array of node updates using these exact keys:
|
|
nodeId, previousStatus, newStatus, previousValue, newValue, reason
|
|
- addedEdges: array of edges using these exact keys:
|
|
id, fromNodeId, toNodeId, relationship, confidence, description
|
|
- removedEdgeIds: array of strings
|
|
- resolvedUnknownNodeIds: array of strings
|
|
- affectedNodeIds: array of strings
|
|
- selectedQuestion: either null or an object using these exact keys:
|
|
nodeId, question, reason
|
|
|
|
## Proposal Rules
|
|
1. Propose changes only. Never return a replacement graph.
|
|
2. Preserve unrelated nodes and edges by omitting them from the proposal.
|
|
3. Reference existing node IDs when updating an existing concept.
|
|
4. Use addedNodes only for genuinely new concepts.
|
|
5. Resolve the answered unknown first when the answer supports it.
|
|
6. Then inspect the answer for newly introduced consequential uncertainty.
|
|
7. Add new unknown nodes only when the answer introduces a new decision, claim, object, measure, dependency, or unresolved term directly relevant to the case.
|
|
8. Add at most 3 new unknown nodes.
|
|
9. Every new unknown must be directly traceable to the user's answer and its description must state why that uncertainty matters.
|
|
9a. In the description of every new unknown, explicitly include a short why-it-matters clause using wording such as because, so that, needed to decide, or matters because.
|
|
10. Do not add broad generic discovery questions.
|
|
11. Do not add duplicate unknowns.
|
|
12. Do not expand unrelated branches.
|
|
13. Propagate only through explicit dependencies or relationships already present in the graph, except for the minimal new edges needed to connect validated new unknowns to the relevant answer-derived decision or context node.
|
|
13a. For every new unknown node, include at least one added edge that connects it to an existing updated/resolved node or to a newly added non-unknown node introduced from the answer.
|
|
14. Do not invent evidence.
|
|
15. Do not create unsupported causal edges.
|
|
16. Select exactly one new active unknown in selectedQuestion when any consequential unresolved unknown exists.
|
|
17. selectedQuestion.nodeId must reference an unresolved unknown node that exists either already in the graph or in addedNodes.
|
|
18. selectedQuestion.question must be one narrow non-compound question about that one unknown.
|
|
19. Return selectedQuestion as null only when no consequential unresolved unknown remains.
|
|
20. Use empty arrays when there are no changes in a category.
|
|
21. Never return null array entries.
|
|
22. Never use unknown enum values.
|
|
23. Do not change existing IDs.
|
|
24. Do not replace the whole graph, and do not restate unchanged graph content inside the proposal.
|
|
|
|
## Additional Guidance
|
|
- If the answer only clarifies an existing unknown, prefer updatedNodes and resolvedUnknownNodeIds over creating duplicate nodes.
|
|
- When an answer resolves an existing unknown, include that existing node ID in resolvedUnknownNodeIds and update that node rather than creating only a parallel observation.
|
|
- If the answer creates a more specific decision situation, add the smallest set of new nodes and edges needed to represent that situation and only its most consequential unknowns.
|
|
- If you add a new unknown, do not leave it floating: connect it with an added edge to the relevant decision/context node created or updated from the answer.
|
|
- If you add a new unknown, its description must do two jobs in one sentence: what is unknown, and why resolving it matters for the case.
|
|
- If the answer does not justify a change, return empty arrays for every category.
|
|
|
|
## Example Constraint Reminder
|
|
${formatExampleAnswerBlock()}
|
|
|
|
## Output Contract Reminder
|
|
Return one JSON object only, with exact field names and exact enum values.
|
|
Never include a full graph.
|
|
Never include any field other than the contract fields above.
|
|
`;
|
|
}
|
|
|
|
export const buildUpdatePrompt = buildGraphUpdatePrompt;
|