@aleph-alpha/chat-kit 5.9.0 → 5.10.0

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.
@@ -260,7 +260,5 @@ export interface ResponseConversationTree extends ConversationTree {
260
260
  * return type is assignable to `ConversationTree`, so you can pipe it
261
261
  * straight into `useMessageHandler().setTree(...)`.
262
262
  */
263
- export declare function responsesToTree(responses: StoredResponse[], opts?: {
264
- arenaWinners?: Record<string, string>;
265
- }): ResponseConversationTree;
263
+ export declare function responsesToTree(responses: StoredResponse[]): ResponseConversationTree;
266
264
  //# sourceMappingURL=responses-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"responses-api.d.ts","sourceRoot":"","sources":["../../src/adapters/responses-api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"responses-api.d.ts","sourceRoot":"","sources":["../../src/adapters/responses-api.ts"],"names":[],"mappings":"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"}
@@ -222,7 +222,7 @@ function linkResponse(state, resp) {
222
222
  }
223
223
  tailMessageByResponse.set(resp.id, chainParent);
224
224
  }
225
- function responsesToTree(responses, opts) {
225
+ function responsesToTree(responses) {
226
226
  if (responses.length === 0) {
227
227
  return { nodes: {}, rootId: null };
228
228
  }
@@ -238,7 +238,6 @@ function responsesToTree(responses, opts) {
238
238
  const rootId = collapseArenaComparisons(
239
239
  state.treeNodes,
240
240
  responses,
241
- opts?.arenaWinners ?? {},
242
241
  state.rootMessageId,
243
242
  state.userMessageByResponse
244
243
  );
@@ -260,27 +259,19 @@ function parseArenaMeta(resp) {
260
259
  return {
261
260
  matchupId: a.matchup_id,
262
261
  modelId: typeof a.model_id === "string" ? a.model_id : void 0,
263
- slot: typeof a.slot === "string" ? a.slot : void 0,
264
- slotSeed: typeof a.slot_seed === "string" ? a.slot_seed : void 0,
265
- variant: typeof a.variant === "string" ? a.variant : void 0
262
+ slot: typeof a.slot === "string" ? a.slot : void 0
266
263
  };
267
264
  }
268
- function collapseArenaComparisons(nodes, responses, arenaWinners, rootMessageId, userMessageByResponse) {
265
+ function collapseArenaComparisons(nodes, responses, rootMessageId, userMessageByResponse) {
269
266
  const userNodeFor = (responseId) => {
270
267
  const id = userMessageByResponse.get(responseId);
271
268
  return id ? nodes[id] : void 0;
272
269
  };
273
270
  let root = rootMessageId;
274
- for (const [matchupId, group] of groupResponsesByMatchup(responses)) {
271
+ for (const [, group] of groupResponsesByMatchup(responses)) {
275
272
  if (group.length < 2) continue;
276
273
  try {
277
- root = foldArenaGroup(
278
- nodes,
279
- group,
280
- arenaWinners[matchupId],
281
- userNodeFor,
282
- root
283
- );
274
+ root = foldArenaGroup(nodes, group, userNodeFor, root);
284
275
  } catch {
285
276
  }
286
277
  }
@@ -311,7 +302,8 @@ function stampLaneAssistant(nodes, resp) {
311
302
  const meta = parseArenaMeta(resp);
312
303
  const assistant = nodes[getAssistantNodeId(resp)];
313
304
  if (assistant && meta) {
314
- assistant.metadata.arena = { modelId: meta.modelId, slot: meta.slot };
305
+ assistant.metadata.arena = { slot: meta.slot };
306
+ delete assistant.metadata.model;
315
307
  }
316
308
  }
317
309
  function attachLane(canonicalUser, assistant) {
@@ -340,17 +332,7 @@ function activateForkNode(nodes, canonicalUser, sharedParentId, root) {
340
332
  }
341
333
  return root;
342
334
  }
343
- function applyArenaWinner(canonicalUser, group, winnerRespId) {
344
- if (!winnerRespId) return;
345
- const winnerResp = group.find((r) => r.id === winnerRespId);
346
- if (!winnerResp) return;
347
- const winnerAssistantId = getAssistantNodeId(winnerResp);
348
- const idx = canonicalUser.childrenIds.indexOf(winnerAssistantId);
349
- if (idx === -1) return;
350
- canonicalUser.comparisonWinnerId = winnerAssistantId;
351
- canonicalUser.activeChildIndex = idx;
352
- }
353
- function foldArenaGroup(nodes, group, winnerRespId, userNodeFor, root) {
335
+ function foldArenaGroup(nodes, group, userNodeFor, root) {
354
336
  const first = group[0];
355
337
  if (!first) return root;
356
338
  const canonicalUser = userNodeFor(first.id);
@@ -358,11 +340,7 @@ function foldArenaGroup(nodes, group, winnerRespId, userNodeFor, root) {
358
340
  const sharedParentId = canonicalUser.parentId;
359
341
  const forkMeta = parseArenaMeta(first);
360
342
  if (forkMeta) {
361
- canonicalUser.metadata.arena = {
362
- matchupId: forkMeta.matchupId,
363
- slotSeed: forkMeta.slotSeed,
364
- variant: forkMeta.variant
365
- };
343
+ canonicalUser.metadata.arena = { matchupId: forkMeta.matchupId };
366
344
  }
367
345
  let newRoot = root;
368
346
  for (const [i, resp] of group.entries()) {
@@ -385,7 +363,6 @@ function foldArenaGroup(nodes, group, winnerRespId, userNodeFor, root) {
385
363
  canonicalUser.childrenIds.sort((x, y) => compareLaneSlots(nodes, x, y));
386
364
  canonicalUser.comparing = true;
387
365
  newRoot = activateForkNode(nodes, canonicalUser, sharedParentId, newRoot);
388
- applyArenaWinner(canonicalUser, group, winnerRespId);
389
366
  return newRoot;
390
367
  }
391
368
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aleph-alpha/chat-kit",
3
- "version": "5.9.0",
3
+ "version": "5.10.0",
4
4
  "description": "Chat kit package for building chat interfaces with Vue",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -108,8 +108,8 @@
108
108
  "vue-tsc": "^3.2.4",
109
109
  "wait-on": "9.0.3",
110
110
  "@aleph-alpha/eslint-config-frontend": "0.7.0",
111
- "@aleph-alpha/prettier-config-frontend": "2.1.0",
112
- "@aleph-alpha/tsconfig-frontend": "0.7.1"
111
+ "@aleph-alpha/tsconfig-frontend": "0.7.1",
112
+ "@aleph-alpha/prettier-config-frontend": "2.1.0"
113
113
  },
114
114
  "scripts": {
115
115
  "build": "vite build && vue-tsc --project tsconfig.build.json --declaration --emitDeclarationOnly --outDir dist",
@@ -32,7 +32,6 @@ function arenaResponse(
32
32
  matchup_id: matchupId,
33
33
  slot,
34
34
  model_id: modelId,
35
- variant: 'king-of-the-hill',
36
35
  }),
37
36
  },
38
37
  } as StoredResponse;
@@ -54,29 +53,24 @@ describe('responsesToTree arena collapse', () => {
54
53
 
55
54
  const children = root.childrenIds.map((id) => tree.nodes[id]!);
56
55
  expect(children.every((c) => c.role === 'assistant')).toBe(true);
57
- // Model id stamped for lane labels; ordered slot a then b.
56
+ // Ordered slot a then b.
58
57
  const slots = children.map(
59
58
  (c) => (c.metadata.arena as { slot?: string }).slot,
60
59
  );
61
60
  expect(slots).toEqual(['a', 'b']);
61
+ // Blind until the vote: no model label leaks (neither arena.modelId nor
62
+ // metadata.model), so the columns render "Response A/B".
63
+ for (const c of children) {
64
+ expect(
65
+ (c.metadata.arena as { modelId?: string }).modelId,
66
+ ).toBeUndefined();
67
+ expect(c.metadata.model).toBeUndefined();
68
+ }
62
69
  });
63
70
 
64
- it('marks the recorded winner when arenaWinners is supplied', () => {
65
- const tree = responsesToTree(
66
- [
67
- arenaResponse('respA', 'm1', 'a', 'phoenix-latest', 'A'),
68
- arenaResponse('respB', 'm1', 'b', 'kimi-k2.6', 'B'),
69
- ],
70
- { arenaWinners: { m1: 'respB' } },
71
- );
72
- const root = tree.nodes[tree.rootId!]!;
73
- // Winner is respB's assistant node (its wire message id).
74
- expect(root.comparisonWinnerId).toBe('msg-respB');
75
- expect(root.childrenIds[root.activeChildIndex]).toBe('msg-respB');
76
- });
77
-
78
- it('leaves a single surviving response as an ordinary linear turn', () => {
79
- // 7-Discard: after continue, the BE dropped the loser — one response left.
71
+ it('leaves a single (server-collapsed resolved) response as a linear turn', () => {
72
+ // The backend collapses a resolved matchup to its winning branch, so a
73
+ // resolved pair arrives as a lone response — an ordinary linear turn.
80
74
  const tree = responsesToTree([
81
75
  arenaResponse('respA', 'm1', 'a', 'phoenix-latest', 'A'),
82
76
  ]);
@@ -703,7 +703,6 @@ function linkResponse(state: TreeBuildState, resp: StoredResponse): void {
703
703
  */
704
704
  export function responsesToTree(
705
705
  responses: StoredResponse[],
706
- opts?: { arenaWinners?: Record<string, string> },
707
706
  ): ResponseConversationTree {
708
707
  if (responses.length === 0) {
709
708
  return { nodes: {}, rootId: null };
@@ -723,7 +722,6 @@ export function responsesToTree(
723
722
  const rootId = collapseArenaComparisons(
724
723
  state.treeNodes,
725
724
  responses,
726
- opts?.arenaWinners ?? {},
727
725
  state.rootMessageId,
728
726
  state.userMessageByResponse,
729
727
  );
@@ -735,8 +733,6 @@ interface ParsedArena {
735
733
  matchupId: string;
736
734
  modelId?: string;
737
735
  slot?: string;
738
- slotSeed?: string;
739
- variant?: string;
740
736
  }
741
737
 
742
738
  /** Parse a stored response's `metadata.arena` (JSON string or dict). */
@@ -755,16 +751,12 @@ function parseArenaMeta(resp: StoredResponse): ParsedArena | null {
755
751
  matchup_id?: unknown;
756
752
  model_id?: unknown;
757
753
  slot?: unknown;
758
- slot_seed?: unknown;
759
- variant?: unknown;
760
754
  };
761
755
  if (typeof a.matchup_id !== 'string') return null;
762
756
  return {
763
757
  matchupId: a.matchup_id,
764
758
  modelId: typeof a.model_id === 'string' ? a.model_id : undefined,
765
759
  slot: typeof a.slot === 'string' ? a.slot : undefined,
766
- slotSeed: typeof a.slot_seed === 'string' ? a.slot_seed : undefined,
767
- variant: typeof a.variant === 'string' ? a.variant : undefined,
768
760
  };
769
761
  }
770
762
 
@@ -776,18 +768,17 @@ function parseArenaMeta(resp: StoredResponse): ParsedArena | null {
776
768
  * collapses those duplicates so reload matches the live shape (one prompt, N
777
769
  * lanes) that {@link projectActivePath} renders.
778
770
  *
779
- * Only pairs still present as ≥2 responses are folded: once a comparison is
780
- * voted-and-continued the backend drops the loser (Decision 7-Discard), so a
781
- * single surviving response is left as an ordinary linear turn. `arenaWinners`
782
- * (matchup id → winning response id) marks the resolved winner so the reloaded
783
- * comparison renders revealed rather than blind.
771
+ * Only pairs still present as ≥2 responses are folded, which now means only an
772
+ * unresolved (pending) pair: the backend collapses a resolved matchup to its
773
+ * winning branch server-side, so a resolved pair arrives as a single response
774
+ * and is left as an ordinary linear turn. A folded pending pair renders blind
775
+ * (no winner marked) until the user votes.
784
776
  *
785
777
  * Returns the (possibly updated) root id. Best-effort per group.
786
778
  */
787
779
  function collapseArenaComparisons(
788
780
  nodes: Record<string, ResponseTreeMessage>,
789
781
  responses: StoredResponse[],
790
- arenaWinners: Record<string, string>,
791
782
  rootMessageId: string | null,
792
783
  userMessageByResponse: Map<string, string>,
793
784
  ): string | null {
@@ -797,18 +788,12 @@ function collapseArenaComparisons(
797
788
  };
798
789
 
799
790
  let root = rootMessageId;
800
- for (const [matchupId, group] of groupResponsesByMatchup(responses)) {
801
- // Fewer than two survivors is no comparison: a lone response left after a
802
- // vote-and-continue (7-Discard) stays an ordinary linear turn.
791
+ for (const [, group] of groupResponsesByMatchup(responses)) {
792
+ // Fewer than two survivors is no comparison: a resolved matchup is already
793
+ // collapsed to its winner server-side, so it arrives as a lone response.
803
794
  if (group.length < 2) continue;
804
795
  try {
805
- root = foldArenaGroup(
806
- nodes,
807
- group,
808
- arenaWinners[matchupId],
809
- userNodeFor,
810
- root,
811
- );
796
+ root = foldArenaGroup(nodes, group, userNodeFor, root);
812
797
  } catch {
813
798
  // Leave this group as-is on any structural surprise.
814
799
  }
@@ -858,7 +843,12 @@ function stampLaneAssistant(
858
843
  const meta = parseArenaMeta(resp);
859
844
  const assistant = nodes[getAssistantNodeId(resp)];
860
845
  if (assistant && meta) {
861
- assistant.metadata.arena = { modelId: meta.modelId, slot: meta.slot };
846
+ // A folded pair is always still pending (resolved matchups arrive collapsed
847
+ // server-side), so it renders BLIND until the user votes: keep only `slot`
848
+ // for column order and drop any model label so the lane shows "Response
849
+ // A/B", not the model name. The vote response reveals the real names.
850
+ assistant.metadata.arena = { slot: meta.slot };
851
+ delete assistant.metadata.model;
862
852
  }
863
853
  }
864
854
 
@@ -913,23 +903,6 @@ function activateForkNode(
913
903
  return root;
914
904
  }
915
905
 
916
- // Reveal the recorded winner lane: mark it and make it the active child. No-op
917
- // when no winner is recorded or its assistant is not among the lanes.
918
- function applyArenaWinner(
919
- canonicalUser: ResponseTreeMessage,
920
- group: StoredResponse[],
921
- winnerRespId: string | undefined,
922
- ): void {
923
- if (!winnerRespId) return;
924
- const winnerResp = group.find((r) => r.id === winnerRespId);
925
- if (!winnerResp) return;
926
- const winnerAssistantId = getAssistantNodeId(winnerResp);
927
- const idx = canonicalUser.childrenIds.indexOf(winnerAssistantId);
928
- if (idx === -1) return;
929
- canonicalUser.comparisonWinnerId = winnerAssistantId;
930
- canonicalUser.activeChildIndex = idx;
931
- }
932
-
933
906
  // Fold one matchup's sibling responses onto a single comparison node: the first
934
907
  // lane's user turn becomes the shared fork parent, every lane's assistant becomes
935
908
  // a child, and the duplicate echoed-user turns are dropped. The first lane's
@@ -938,7 +911,6 @@ function applyArenaWinner(
938
911
  function foldArenaGroup(
939
912
  nodes: Record<string, ResponseTreeMessage>,
940
913
  group: StoredResponse[],
941
- winnerRespId: string | undefined,
942
914
  userNodeFor: (responseId: string) => ResponseTreeMessage | undefined,
943
915
  root: string | null,
944
916
  ): string | null {
@@ -948,15 +920,11 @@ function foldArenaGroup(
948
920
  if (!canonicalUser) return root;
949
921
  const sharedParentId = canonicalUser.parentId;
950
922
 
951
- // Stamp matchup context on the fork parent so a reloaded comparison can be
952
- // voted on (the host reconstructs the preference payload from here).
923
+ // Stamp the matchup id on the fork parent so a reloaded comparison can be
924
+ // voted on (the host builds the vote payload from `matchup_id`).
953
925
  const forkMeta = parseArenaMeta(first);
954
926
  if (forkMeta) {
955
- canonicalUser.metadata.arena = {
956
- matchupId: forkMeta.matchupId,
957
- slotSeed: forkMeta.slotSeed,
958
- variant: forkMeta.variant,
959
- };
927
+ canonicalUser.metadata.arena = { matchupId: forkMeta.matchupId };
960
928
  }
961
929
 
962
930
  let newRoot = root;
@@ -982,6 +950,5 @@ function foldArenaGroup(
982
950
 
983
951
  canonicalUser.comparing = true;
984
952
  newRoot = activateForkNode(nodes, canonicalUser, sharedParentId, newRoot);
985
- applyArenaWinner(canonicalUser, group, winnerRespId);
986
953
  return newRoot;
987
954
  }