@trustgraph/react-state 1.7.2 → 1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1922,11 +1922,13 @@ const useExplainabilityStore = zustand.create()((set, get) => ({
1922
1922
  /**
1923
1923
  * Explainability utilities for parsing and structuring explain events
1924
1924
  */
1925
- // Agent-specific predicates (not yet in client library)
1925
+ // Predicates not yet in client library
1926
1926
  const TG_ACTION = client.TG + "action";
1927
1927
  const TG_ARGUMENTS = client.TG + "arguments";
1928
1928
  const TG_SUBAGENT_GOAL = client.TG + "subagentGoal";
1929
- // RDF type URIs for agent events
1929
+ const TG_CONCEPT = client.TG + "concept";
1930
+ const TG_ENTITY = client.TG + "entity";
1931
+ // RDF type URIs
1930
1932
  const TG_AGENT_QUESTION = client.TG + "AgentQuestion";
1931
1933
  const TG_ANALYSIS = client.TG + "Analysis";
1932
1934
  const TG_TOOL_USE = client.TG + "ToolUse";
@@ -1934,13 +1936,14 @@ const TG_OBSERVATION = client.TG + "Observation";
1934
1936
  const TG_THOUGHT_TYPE = client.TG + "Thought";
1935
1937
  const TG_REFLECTION_TYPE = client.TG + "Reflection";
1936
1938
  const TG_CONCLUSION = client.TG + "Conclusion";
1937
- const TG_ANSWER = client.TG + "Answer";
1938
1939
  const TG_FINDING = client.TG + "Finding";
1939
- const TG_SYNTHESIS_TYPE = client.TG + "Synthesis";
1940
1940
  const TG_DECOMPOSITION = client.TG + "Decomposition";
1941
+ const TG_GROUNDING = client.TG + "Grounding";
1942
+ const TG_EXPLORATION_TYPE = client.TG + "Exploration";
1943
+ const TG_FOCUS_TYPE = client.TG + "Focus";
1941
1944
  // ── Helpers ─────────────────────────────────────────────────────────
1942
1945
  /**
1943
- * Extract event type from explainId URI (graph-rag only)
1946
+ * Extract event type from explainId URI (graph-rag fallback)
1944
1947
  */
1945
1948
  function getEventType(explainId) {
1946
1949
  if (explainId.includes("question"))
@@ -1953,9 +1956,6 @@ function getEventType(explainId) {
1953
1956
  return "synthesis";
1954
1957
  return "unknown";
1955
1958
  }
1956
- /**
1957
- * Get term value from a Term object
1958
- */
1959
1959
  function getTermValue$1(term) {
1960
1960
  if (!term)
1961
1961
  return "";
@@ -1964,7 +1964,6 @@ function getTermValue$1(term) {
1964
1964
  if (term.t === "l")
1965
1965
  return term.v || "";
1966
1966
  if (term.t === "t" && term.tr) {
1967
- // Quoted triple - return a serialized form
1968
1967
  const s = getTermValue$1(term.tr.s);
1969
1968
  const p = getTermValue$1(term.tr.p);
1970
1969
  const o = getTermValue$1(term.tr.o);
@@ -1972,9 +1971,6 @@ function getTermValue$1(term) {
1972
1971
  }
1973
1972
  return "";
1974
1973
  }
1975
- /**
1976
- * Extract quoted triple from a Term
1977
- */
1978
1974
  function extractQuotedTriple(term) {
1979
1975
  if (term.t === "t" && term.tr) {
1980
1976
  return {
@@ -1985,9 +1981,15 @@ function extractQuotedTriple(term) {
1985
1981
  }
1986
1982
  return null;
1987
1983
  }
1988
- // ── Agent event type detection ──────────────────────────────────────
1989
- /** Map RDF type URI → agent event type (first match wins) */
1990
- const AGENT_TYPE_CHECKS = [
1984
+ // ── RDF type detection ──────────────────────────────────────────────
1985
+ /**
1986
+ * Map RDF type URI → event type (first match wins).
1987
+ * Agent-specific types only — shared types like tg:Synthesis and
1988
+ * tg:Answer are excluded to avoid catching graph-rag events.
1989
+ * Grounding, Exploration, Focus are included since they now carry
1990
+ * embedded triples with their RDF type.
1991
+ */
1992
+ const RDF_TYPE_CHECKS = [
1991
1993
  [TG_AGENT_QUESTION, "agent-question"],
1992
1994
  [TG_DECOMPOSITION, "decomposition"],
1993
1995
  [TG_ANALYSIS, "analysis"],
@@ -1997,12 +1999,12 @@ const AGENT_TYPE_CHECKS = [
1997
1999
  [TG_REFLECTION_TYPE, "reflection"],
1998
2000
  [TG_CONCLUSION, "conclusion"],
1999
2001
  [TG_FINDING, "conclusion"],
2000
- [TG_SYNTHESIS_TYPE, "conclusion"],
2001
- [TG_ANSWER, "conclusion"],
2002
+ [TG_GROUNDING, "grounding"],
2003
+ [TG_EXPLORATION_TYPE, "exploration"],
2004
+ [TG_FOCUS_TYPE, "focus"],
2002
2005
  ];
2003
2006
  /**
2004
2007
  * Detect event type from RDF types in embedded triples.
2005
- * Returns an agent event type if matched, "unknown" otherwise.
2006
2008
  */
2007
2009
  function getEventTypeFromTriples(triples) {
2008
2010
  const types = new Set();
@@ -2011,7 +2013,7 @@ function getEventTypeFromTriples(triples) {
2011
2013
  types.add(getTermValue$1(t.o));
2012
2014
  }
2013
2015
  }
2014
- for (const [typeUri, eventType] of AGENT_TYPE_CHECKS) {
2016
+ for (const [typeUri, eventType] of RDF_TYPE_CHECKS) {
2015
2017
  if (types.has(typeUri))
2016
2018
  return eventType;
2017
2019
  }
@@ -2031,38 +2033,48 @@ function extractCommonFields(triples) {
2031
2033
  }
2032
2034
  return { label, derivedFrom };
2033
2035
  }
2034
- // ── Graph-RAG parsers (existing) ────────────────────────────────────
2036
+ /**
2037
+ * Extract inline edges from triples (tg:edge quoted triples).
2038
+ * Returns SelectedEdge objects with URIs — labels resolved later.
2039
+ */
2040
+ function extractInlineEdges(triples) {
2041
+ const edges = [];
2042
+ for (const t of triples) {
2043
+ if (getTermValue$1(t.p) === client.TG_EDGE && t.o.t === "t" && t.o.tr) {
2044
+ const edge = extractQuotedTriple(t.o);
2045
+ if (edge) {
2046
+ edges.push({ edge });
2047
+ }
2048
+ }
2049
+ }
2050
+ return edges;
2051
+ }
2052
+ // ── Parsers ─────────────────────────────────────────────────────────
2035
2053
  function parseQuestionTriples(explainId, explainGraph, triples) {
2036
- const event = {
2037
- type: "question",
2038
- explainId,
2039
- explainGraph,
2040
- };
2041
- for (const triple of triples) {
2042
- const p = getTermValue$1(triple.p);
2043
- const o = getTermValue$1(triple.o);
2044
- if (p === client.TG_QUERY) {
2054
+ const event = { type: "question", explainId, explainGraph };
2055
+ for (const t of triples) {
2056
+ const p = getTermValue$1(t.p);
2057
+ const o = getTermValue$1(t.o);
2058
+ if (p === client.TG_QUERY)
2045
2059
  event.query = o;
2046
- }
2047
- else if (p === client.PROV_STARTED_AT_TIME) {
2060
+ else if (p === client.PROV_STARTED_AT_TIME)
2048
2061
  event.timestamp = o;
2049
- }
2050
2062
  }
2051
2063
  return event;
2052
2064
  }
2053
2065
  function parseExplorationTriples(explainId, explainGraph, triples) {
2054
- const event = {
2055
- type: "exploration",
2056
- explainId,
2057
- explainGraph,
2058
- };
2059
- for (const triple of triples) {
2060
- const p = getTermValue$1(triple.p);
2061
- const o = getTermValue$1(triple.o);
2062
- if (p === client.TG_EDGE_COUNT) {
2066
+ const event = { type: "exploration", explainId, explainGraph };
2067
+ const entities = [];
2068
+ for (const t of triples) {
2069
+ const p = getTermValue$1(t.p);
2070
+ const o = getTermValue$1(t.o);
2071
+ if (p === client.TG_EDGE_COUNT)
2063
2072
  event.edgeCount = parseInt(o, 10);
2064
- }
2073
+ if (p === TG_ENTITY && o)
2074
+ entities.push(o);
2065
2075
  }
2076
+ if (entities.length > 0)
2077
+ event.entities = entities;
2066
2078
  return event;
2067
2079
  }
2068
2080
  function parseFocusTriples(explainId, explainGraph, triples) {
@@ -2072,27 +2084,28 @@ function parseFocusTriples(explainId, explainGraph, triples) {
2072
2084
  explainGraph,
2073
2085
  edgeSelectionUris: [],
2074
2086
  };
2075
- for (const triple of triples) {
2076
- const p = getTermValue$1(triple.p);
2077
- const o = getTermValue$1(triple.o);
2087
+ // Collect edge selection URIs (old format)
2088
+ for (const t of triples) {
2089
+ const p = getTermValue$1(t.p);
2090
+ const o = getTermValue$1(t.o);
2078
2091
  if (p === client.TG_SELECTED_EDGE && typeof o === "string") {
2079
2092
  event.edgeSelectionUris.push(o);
2080
2093
  }
2081
2094
  }
2095
+ // Extract inline edges (new format: tg:edge with quoted triples)
2096
+ const inlineEdges = extractInlineEdges(triples);
2097
+ if (inlineEdges.length > 0) {
2098
+ event.selectedEdges = inlineEdges;
2099
+ }
2082
2100
  return event;
2083
2101
  }
2084
2102
  function parseSynthesisTriples(explainId, explainGraph, triples) {
2085
- const event = {
2086
- type: "synthesis",
2087
- explainId,
2088
- explainGraph,
2089
- };
2090
- for (const triple of triples) {
2091
- const p = getTermValue$1(triple.p);
2092
- const o = getTermValue$1(triple.o);
2093
- if (p === client.TG_CONTENT) {
2103
+ const event = { type: "synthesis", explainId, explainGraph };
2104
+ for (const t of triples) {
2105
+ const p = getTermValue$1(t.p);
2106
+ const o = getTermValue$1(t.o);
2107
+ if (p === client.TG_CONTENT)
2094
2108
  event.contentLength = o.length;
2095
- }
2096
2109
  }
2097
2110
  return event;
2098
2111
  }
@@ -2101,24 +2114,28 @@ function parseEdgeSelectionTriples(triples) {
2101
2114
  let reasoning = null;
2102
2115
  for (const triple of triples) {
2103
2116
  const p = getTermValue$1(triple.p);
2104
- if (p === client.TG_EDGE) {
2117
+ if (p === client.TG_EDGE)
2105
2118
  edge = extractQuotedTriple(triple.o);
2106
- }
2107
- else if (p === client.TG_REASONING) {
2119
+ else if (p === client.TG_REASONING)
2108
2120
  reasoning = getTermValue$1(triple.o);
2109
- }
2110
2121
  }
2111
2122
  return { edge, reasoning };
2112
2123
  }
2113
- // ── Agent parsers (new) ─────────────────────────────────────────────
2124
+ function parseGroundingTriples(explainId, explainGraph, triples) {
2125
+ const { label, derivedFrom } = extractCommonFields(triples);
2126
+ const concepts = [];
2127
+ for (const t of triples) {
2128
+ const p = getTermValue$1(t.p);
2129
+ const o = getTermValue$1(t.o);
2130
+ if (p === TG_CONCEPT && o)
2131
+ concepts.push(o);
2132
+ }
2133
+ return { type: "grounding", explainId, explainGraph, label, concepts, derivedFrom };
2134
+ }
2114
2135
  function parseAgentQuestionTriples(explainId, explainGraph, triples) {
2115
2136
  const { label, derivedFrom } = extractCommonFields(triples);
2116
2137
  const event = {
2117
- type: "agent-question",
2118
- explainId,
2119
- explainGraph,
2120
- label,
2121
- derivedFrom,
2138
+ type: "agent-question", explainId, explainGraph, label, derivedFrom,
2122
2139
  };
2123
2140
  for (const t of triples) {
2124
2141
  const p = getTermValue$1(t.p);
@@ -2139,23 +2156,12 @@ function parseDecompositionTriples(explainId, explainGraph, triples) {
2139
2156
  if (p === TG_SUBAGENT_GOAL && o)
2140
2157
  goals.push(o);
2141
2158
  }
2142
- return {
2143
- type: "decomposition",
2144
- explainId,
2145
- explainGraph,
2146
- label,
2147
- goals,
2148
- derivedFrom,
2149
- };
2159
+ return { type: "decomposition", explainId, explainGraph, label, goals, derivedFrom };
2150
2160
  }
2151
2161
  function parseAnalysisTriples(explainId, explainGraph, triples) {
2152
2162
  const { label, derivedFrom } = extractCommonFields(triples);
2153
2163
  const event = {
2154
- type: "analysis",
2155
- explainId,
2156
- explainGraph,
2157
- label,
2158
- derivedFrom,
2164
+ type: "analysis", explainId, explainGraph, label, derivedFrom,
2159
2165
  };
2160
2166
  for (const t of triples) {
2161
2167
  const p = getTermValue$1(t.p);
@@ -2169,34 +2175,22 @@ function parseAnalysisTriples(explainId, explainGraph, triples) {
2169
2175
  }
2170
2176
  function parseReflectionTriples(explainId, explainGraph, triples) {
2171
2177
  const { label, derivedFrom } = extractCommonFields(triples);
2172
- return {
2173
- type: "reflection",
2174
- explainId,
2175
- explainGraph,
2176
- label,
2177
- derivedFrom,
2178
- };
2178
+ return { type: "reflection", explainId, explainGraph, label, derivedFrom };
2179
2179
  }
2180
2180
  function parseConclusionTriples(explainId, explainGraph, triples) {
2181
2181
  const { label, derivedFrom } = extractCommonFields(triples);
2182
- return {
2183
- type: "conclusion",
2184
- explainId,
2185
- explainGraph,
2186
- label,
2187
- derivedFrom,
2188
- };
2182
+ return { type: "conclusion", explainId, explainGraph, label, derivedFrom };
2189
2183
  }
2190
2184
  // ── Unified parser ──────────────────────────────────────────────────
2191
2185
  /**
2192
2186
  * Parse triples into a structured event.
2193
- * Tries RDF type detection first (agent events), then URI patterns (graph-rag).
2194
- * Returns null for events with no triples (inner graph-rag plumbing).
2187
+ * Tries RDF type detection first, then URI patterns as fallback.
2188
+ * Returns null for events with no triples.
2195
2189
  */
2196
2190
  function parseExplainTriples(explainId, explainGraph, triples) {
2197
2191
  if (triples.length === 0)
2198
2192
  return null;
2199
- // Try RDF type detection first (agent events with embedded triples)
2193
+ // Try RDF type detection first
2200
2194
  const rdfEventType = getEventTypeFromTriples(triples);
2201
2195
  if (rdfEventType !== "unknown") {
2202
2196
  switch (rdfEventType) {
@@ -2210,6 +2204,12 @@ function parseExplainTriples(explainId, explainGraph, triples) {
2210
2204
  return parseReflectionTriples(explainId, explainGraph, triples);
2211
2205
  case "conclusion":
2212
2206
  return parseConclusionTriples(explainId, explainGraph, triples);
2207
+ case "grounding":
2208
+ return parseGroundingTriples(explainId, explainGraph, triples);
2209
+ case "exploration":
2210
+ return parseExplorationTriples(explainId, explainGraph, triples);
2211
+ case "focus":
2212
+ return parseFocusTriples(explainId, explainGraph, triples);
2213
2213
  }
2214
2214
  }
2215
2215
  // Fall back to URI pattern detection (graph-rag events)
@@ -2230,8 +2230,10 @@ function parseExplainTriples(explainId, explainGraph, triples) {
2230
2230
 
2231
2231
  /**
2232
2232
  * Hook for tracing provenance chains in the knowledge graph
2233
- * Follows prov:wasDerivedFrom relationships from any entity to its source documents
2233
+ * Follows tg:contains to find subgraphs, then prov:wasDerivedFrom
2234
+ * to trace chunk → page → document chains
2234
2235
  */
2236
+ const TG_CONTAINS = client.TG + "contains";
2235
2237
  /**
2236
2238
  * Hook for tracing provenance chains
2237
2239
  */
@@ -2328,13 +2330,13 @@ const useProvenance = (options = {}) => {
2328
2330
  }
2329
2331
  }, [maxDepth, resolveLabel, queryDerivedFrom]);
2330
2332
  /**
2331
- * Query for statements that reify an edge via tg:reifies
2333
+ * Find subgraphs that contain an edge via tg:contains with a quoted triple
2332
2334
  */
2333
- const queryReifyingStatements = react.useCallback(async (s, p, o) => {
2335
+ const queryContainingSubgraphs = react.useCallback(async (s, p, o) => {
2334
2336
  if (!isConnected())
2335
2337
  return [];
2336
2338
  try {
2337
- // Build the quoted triple term
2339
+ // Build the quoted triple term for the edge
2338
2340
  const quotedTriple = {
2339
2341
  t: "t",
2340
2342
  tr: {
@@ -2347,7 +2349,7 @@ const useProvenance = (options = {}) => {
2347
2349
  };
2348
2350
  const triples = await socket
2349
2351
  .flow(effectiveFlow)
2350
- .triplesQuery(undefined, { t: "i", i: client.TG_REIFIES }, quotedTriple, 10, collection);
2352
+ .triplesQuery(undefined, { t: "i", i: TG_CONTAINS }, quotedTriple, 10, collection);
2351
2353
  return triples.map((t) => getTermValue$1(t.s));
2352
2354
  }
2353
2355
  catch {
@@ -2355,20 +2357,21 @@ const useProvenance = (options = {}) => {
2355
2357
  }
2356
2358
  }, [socket, effectiveFlow, collection, isConnected]);
2357
2359
  /**
2358
- * Trace provenance for an edge - finds reifying statements and traces each
2360
+ * Trace provenance for an edge find containing subgraph, then follow
2361
+ * wasDerivedFrom chain: subgraph → chunk → page → document
2359
2362
  */
2360
2363
  const traceEdgeProvenance = react.useCallback(async (s, p, o) => {
2361
2364
  setIsTracing(true);
2362
2365
  try {
2363
- // Find statements that reify this edge
2364
- const stmtUris = await queryReifyingStatements(s, p, o);
2365
- // For each reifying statement, trace its provenance chain
2366
+ // Find subgraphs containing this edge
2367
+ const subgraphUris = await queryContainingSubgraphs(s, p, o);
2366
2368
  const chains = [];
2367
- for (const stmtUri of stmtUris) {
2368
- // Get the wasDerivedFrom source for this statement
2369
- const sourceUri = await queryDerivedFrom(stmtUri);
2370
- if (sourceUri) {
2371
- const chain = await traceChain(sourceUri);
2369
+ for (const subgraphUri of subgraphUris) {
2370
+ // Follow wasDerivedFrom from the subgraph to the chunk
2371
+ const chunkUri = await queryDerivedFrom(subgraphUri);
2372
+ if (chunkUri) {
2373
+ // Trace the full chain from chunk upward
2374
+ const chain = await traceChain(chunkUri);
2372
2375
  chains.push(chain);
2373
2376
  }
2374
2377
  }
@@ -2377,7 +2380,7 @@ const useProvenance = (options = {}) => {
2377
2380
  finally {
2378
2381
  setIsTracing(false);
2379
2382
  }
2380
- }, [queryReifyingStatements, queryDerivedFrom, traceChain]);
2383
+ }, [queryContainingSubgraphs, queryDerivedFrom, traceChain]);
2381
2384
  /**
2382
2385
  * Clear the label cache
2383
2386
  */
@@ -2479,56 +2482,82 @@ const useExplainability = (options = {}) => {
2479
2482
  setSession(updater);
2480
2483
  onUpdateRef.current?.(sessionRef.current);
2481
2484
  }, []);
2482
- const AGENT_EVENT_TYPES = new Set([
2485
+ const AGENT_STEP_TYPES = new Set([
2483
2486
  "agent-question", "decomposition", "analysis", "reflection", "conclusion",
2487
+ "grounding",
2484
2488
  ]);
2489
+ /**
2490
+ * Resolve labels for inline edges (edges already extracted, just need labels)
2491
+ */
2492
+ const resolveEdgeLabels = react.useCallback(async (focusEvent) => {
2493
+ if (!focusEvent.selectedEdges || focusEvent.selectedEdges.length === 0) {
2494
+ return focusEvent;
2495
+ }
2496
+ const resolved = await Promise.all(focusEvent.selectedEdges.map(async (se) => {
2497
+ const [sLabel, pLabel, oLabel] = await Promise.all([
2498
+ resolveLabel(se.edge.s),
2499
+ resolveLabel(se.edge.p),
2500
+ resolveLabel(se.edge.o),
2501
+ ]);
2502
+ let sources;
2503
+ if (traceProvenance) {
2504
+ const chains = await traceEdgeProvenance(se.edge.s, se.edge.p, se.edge.o);
2505
+ if (chains.length > 0) {
2506
+ sources = chains.map((c) => c.chain).flat();
2507
+ }
2508
+ }
2509
+ return {
2510
+ ...se,
2511
+ labels: { s: sLabel, p: pLabel, o: oLabel },
2512
+ sources,
2513
+ };
2514
+ }));
2515
+ return { ...focusEvent, selectedEdges: resolved };
2516
+ }, [resolveLabel, traceProvenance, traceEdgeProvenance]);
2485
2517
  /**
2486
2518
  * Process a single explain event
2487
2519
  */
2488
2520
  const processEvent = react.useCallback(async (event) => {
2489
- // Use embedded triples directly from the event
2490
2521
  const triples = event.explainTriples ?? [];
2491
- // Parse into structured data
2492
2522
  const parsed = parseExplainTriples(event.explainId, event.explainGraph, triples);
2493
2523
  if (!parsed)
2494
2524
  return;
2495
- if (AGENT_EVENT_TYPES.has(parsed.type)) {
2496
- // Agent event — append to timeline
2525
+ if (AGENT_STEP_TYPES.has(parsed.type)) {
2526
+ // Agent step — append to timeline
2497
2527
  updateSession((prev) => ({
2498
2528
  ...prev,
2499
2529
  agentSteps: [...(prev.agentSteps || []), parsed],
2500
2530
  }));
2501
2531
  }
2502
- else {
2503
- // Graph-RAG event — populate fixed fields
2504
- updateSession((prev) => {
2505
- const next = { ...prev };
2506
- switch (parsed.type) {
2507
- case "question":
2508
- next.question = parsed;
2509
- break;
2510
- case "exploration":
2511
- next.exploration = parsed;
2512
- break;
2513
- case "focus":
2514
- next.focus = parsed;
2515
- break;
2516
- case "synthesis":
2517
- next.synthesis = parsed;
2518
- break;
2532
+ // Graph-RAG fields — populate regardless (agent produces these too)
2533
+ switch (parsed.type) {
2534
+ case "question":
2535
+ updateSession((prev) => ({ ...prev, question: parsed }));
2536
+ break;
2537
+ case "exploration":
2538
+ updateSession((prev) => ({ ...prev, exploration: parsed }));
2539
+ break;
2540
+ case "focus": {
2541
+ updateSession((prev) => ({ ...prev, focus: parsed }));
2542
+ // Resolve labels for inline edges, or unpack old-format edges
2543
+ const focusEvent = parsed;
2544
+ if (focusEvent.selectedEdges && focusEvent.selectedEdges.length > 0) {
2545
+ // New format: edges already extracted, resolve labels
2546
+ const resolved = await resolveEdgeLabels(focusEvent);
2547
+ updateSession((prev) => ({ ...prev, focus: resolved }));
2519
2548
  }
2520
- return next;
2521
- });
2522
- // For focus events, unpack edges (labels still need store lookup)
2523
- if (parsed.type === "focus") {
2524
- const unpackedFocus = await unpackFocusEvent(parsed, triples);
2525
- updateSession((prev) => ({
2526
- ...prev,
2527
- focus: unpackedFocus,
2528
- }));
2549
+ else if (focusEvent.edgeSelectionUris.length > 0) {
2550
+ // Old format: unpack edge selection URIs
2551
+ const unpacked = await unpackFocusEvent(focusEvent, triples);
2552
+ updateSession((prev) => ({ ...prev, focus: unpacked }));
2553
+ }
2554
+ break;
2529
2555
  }
2556
+ case "synthesis":
2557
+ updateSession((prev) => ({ ...prev, synthesis: parsed }));
2558
+ break;
2530
2559
  }
2531
- }, [unpackFocusEvent, updateSession]);
2560
+ }, [unpackFocusEvent, resolveEdgeLabels, updateSession]);
2532
2561
  /**
2533
2562
  * Process the unpack queue
2534
2563
  */