@arbidocs/react 0.5.49 → 0.5.50

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.d.cts CHANGED
@@ -2321,9 +2321,15 @@ declare function useDeleteConfig(): _tanstack_react_query.UseMutationResult<{
2321
2321
  *
2322
2322
  * save(instrument, field, value, title?) one field (a switch)
2323
2323
  * saveDelta(changes, title?) several at once: { Agents: { ENABLED: true, … } }
2324
- */
2325
- declare function useSaveConfigField(): {
2326
- save: (instrument: string, field: string, value: unknown, title?: string) => void;
2324
+ *
2325
+ * `baseConfigId`: the config a host shows (it can differ from the chat's), which saves build on
2326
+ * instead. Each save reads it first, so one made while it loads keeps its overrides, and builds on
2327
+ * the config the previous save made, so quick edits keep each other, also once the host shows a
2328
+ * config one of them made. The config a save makes becomes the chat's (`session.chatModel`), so
2329
+ * the host shows and uses it. A base that cannot be read is reported like a refused save.
2330
+ */
2331
+ declare function useSaveConfigField(baseConfigId?: string | null): {
2332
+ save: (instrument: string, field: string, value: unknown, title?: string) => undefined;
2327
2333
  saveDelta: (changes: Record<string, Record<string, unknown>>, title?: string) => Promise<{
2328
2334
  external_id: string;
2329
2335
  title: string | null;
package/dist/index.d.ts CHANGED
@@ -2321,9 +2321,15 @@ declare function useDeleteConfig(): _tanstack_react_query.UseMutationResult<{
2321
2321
  *
2322
2322
  * save(instrument, field, value, title?) one field (a switch)
2323
2323
  * saveDelta(changes, title?) several at once: { Agents: { ENABLED: true, … } }
2324
- */
2325
- declare function useSaveConfigField(): {
2326
- save: (instrument: string, field: string, value: unknown, title?: string) => void;
2324
+ *
2325
+ * `baseConfigId`: the config a host shows (it can differ from the chat's), which saves build on
2326
+ * instead. Each save reads it first, so one made while it loads keeps its overrides, and builds on
2327
+ * the config the previous save made, so quick edits keep each other, also once the host shows a
2328
+ * config one of them made. The config a save makes becomes the chat's (`session.chatModel`), so
2329
+ * the host shows and uses it. A base that cannot be read is reported like a refused save.
2330
+ */
2331
+ declare function useSaveConfigField(baseConfigId?: string | null): {
2332
+ save: (instrument: string, field: string, value: unknown, title?: string) => undefined;
2327
2333
  saveDelta: (changes: Record<string, Record<string, unknown>>, title?: string) => Promise<{
2328
2334
  external_id: string;
2329
2335
  title: string | null;
package/dist/index.js CHANGED
@@ -1459,41 +1459,94 @@ function configDelta(active, defaults) {
1459
1459
  }
1460
1460
  return delta;
1461
1461
  }
1462
- function useSaveConfigField() {
1462
+ function deltaOnto(changes, active, defaults) {
1463
+ const delta = configDelta(active, defaults);
1464
+ for (const [instrument, fields] of Object.entries(changes)) {
1465
+ delta[instrument] = { ...delta[instrument] ?? {}, ...fields };
1466
+ const defaultInstrument = defaults[instrument];
1467
+ if (defaultInstrument) {
1468
+ const instrumentDelta = delta[instrument];
1469
+ for (const [field, value] of Object.entries(fields)) {
1470
+ if (JSON.stringify(value) === JSON.stringify(defaultInstrument[field])) {
1471
+ delete instrumentDelta[field];
1472
+ }
1473
+ }
1474
+ if (Object.keys(instrumentDelta).length === 0) delete delta[instrument];
1475
+ }
1476
+ }
1477
+ return delta;
1478
+ }
1479
+ function useSaveConfigField(baseConfigId) {
1480
+ const arbi = useArbi();
1481
+ const queryClient = useQueryClient();
1463
1482
  const saveConfig = useSaveConfig();
1464
1483
  const { data: defaultConfig } = useConfig("default");
1465
1484
  const chatModel = useArbiSessionState((state) => state.chatModel);
1466
1485
  const { data: userSettings } = useUserSettings();
1467
- const activeConfigId = chatModel || userSettings?.last_config || "default";
1486
+ const activeConfigId = baseConfigId || chatModel || userSettings?.last_config || "default";
1468
1487
  const { data: activeConfigData } = useConfig(activeConfigId);
1469
- const buildDelta = (changes) => {
1470
- const defaults = defaultConfig ?? {};
1471
- const active = activeConfigData ?? {};
1472
- const delta = configDelta(active, defaults);
1473
- for (const [instrument, fields] of Object.entries(changes)) {
1474
- delta[instrument] = { ...delta[instrument] ?? {}, ...fields };
1475
- const defaultInstrument = defaults[instrument];
1476
- if (defaultInstrument) {
1477
- const instrumentDelta = delta[instrument];
1478
- for (const [field, value] of Object.entries(fields)) {
1479
- if (JSON.stringify(value) === JSON.stringify(defaultInstrument[field])) {
1480
- delete instrumentDelta[field];
1481
- }
1488
+ const session = useArbiSessionStore();
1489
+ const chain = useRef(null);
1490
+ const buildDelta = (changes) => deltaOnto(
1491
+ changes,
1492
+ activeConfigData ?? {},
1493
+ defaultConfig ?? {}
1494
+ );
1495
+ const readConfig = (configId) => queryClient.fetchQuery({
1496
+ queryKey: arbiQueryKeys.config(configId),
1497
+ queryFn: () => arbi.agentConfig.get(configId),
1498
+ staleTime: 10 * 60 * 1e3
1499
+ });
1500
+ const saveOnBase = (base, changes, title) => {
1501
+ const current = chain.current?.ids.has(base) ? chain.current : null;
1502
+ const ids = current?.ids ?? /* @__PURE__ */ new Set([base]);
1503
+ const from = current?.latest ?? Promise.resolve(base);
1504
+ const saved = from.then(async (configId) => {
1505
+ const [defaults, active] = await Promise.all([
1506
+ readConfig("default"),
1507
+ readConfig(configId)
1508
+ ]).catch((error) => {
1509
+ notify.error(formatConfigValidationError(error), {
1510
+ description: "Configuration not saved \u2014 the settings it builds on could not be read."
1511
+ });
1512
+ throw error;
1513
+ });
1514
+ const response = await saveConfig.mutateAsync({
1515
+ ...deltaOnto(changes, active ?? {}, defaults ?? {}),
1516
+ title
1517
+ });
1518
+ if (response?.external_id) {
1519
+ ids.add(response.external_id);
1520
+ const { chatModel: chatModel2 } = session.getState();
1521
+ const followsSettings = !chatModel2 && base === userSettings?.last_config;
1522
+ if (chain.current?.ids === ids && !followsSettings) {
1523
+ session.setChatModel(response.external_id);
1482
1524
  }
1483
- if (Object.keys(instrumentDelta).length === 0) delete delta[instrument];
1484
1525
  }
1485
- }
1486
- return delta;
1526
+ return { response, configId: response?.external_id ?? configId };
1527
+ });
1528
+ chain.current = {
1529
+ ids,
1530
+ latest: Promise.all([from, saved]).then(
1531
+ ([, done]) => done.configId,
1532
+ () => from
1533
+ )
1534
+ };
1535
+ return saved.then(({ response }) => response);
1487
1536
  };
1488
1537
  return {
1489
- save: (instrument, field, value, title) => saveConfig.mutate({
1490
- ...buildDelta({ [instrument]: { [field]: value } }),
1491
- title: title ?? `prefs-${Date.now()}`
1492
- }),
1493
- saveDelta: (changes, title) => saveConfig.mutateAsync({
1494
- ...buildDelta(changes),
1495
- title: title ?? `prefs-${Date.now()}`
1496
- }),
1538
+ save: (instrument, field, value, title) => {
1539
+ const changes = { [instrument]: { [field]: value } };
1540
+ const name = title ?? `prefs-${Date.now()}`;
1541
+ if (baseConfigId) return void saveOnBase(baseConfigId, changes, name).catch(() => {
1542
+ });
1543
+ saveConfig.mutate({ ...buildDelta(changes), title: name });
1544
+ },
1545
+ saveDelta: (changes, title) => {
1546
+ const name = title ?? `prefs-${Date.now()}`;
1547
+ if (baseConfigId) return saveOnBase(baseConfigId, changes, name);
1548
+ return saveConfig.mutateAsync({ ...buildDelta(changes), title: name });
1549
+ },
1497
1550
  isPending: saveConfig.isPending
1498
1551
  };
1499
1552
  }