@pipeline-moe/client-core 0.1.1 → 0.1.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.
Files changed (2) hide show
  1. package/dist/store.js +29 -8
  2. package/package.json +1 -1
package/dist/store.js CHANGED
@@ -82,11 +82,13 @@ export function createRoomStore(opts) {
82
82
  applyEffects(result.effects);
83
83
  };
84
84
  // ── Lifecycle ─────────────────────────────────────────────────────────────
85
- /** Load the REST snapshot and open the SSE stream. Idempotent-safe to call once. */
86
- const start = () => {
87
- // Clear transient fields before (re)loading a reused store must not show a
88
- // prior room's in-flight turn. Fresh stores are already clean; this is cheap.
89
- set(resetTransient(state));
85
+ /**
86
+ * Fetch the full REST snapshot. Runs at start() and again on every SSE open:
87
+ * if the client came up before the server (or the server restarted), the
88
+ * initial fetches failed silently re-running them on (re)connect is what
89
+ * lets providers/settings/conversations self-heal instead of staying empty.
90
+ */
91
+ const loadSnapshot = () => {
90
92
  rApi.transcript().then((m) => patch({ messages: m })).catch(() => { });
91
93
  rApi.workspace().then((w) => patch({ workspace: w })).catch(() => { });
92
94
  rApi.roster().then((r) => patch({ roster: r })).catch(() => { });
@@ -115,8 +117,18 @@ export function createRoomStore(opts) {
115
117
  }).catch(() => { });
116
118
  rApi.conversations().then((c) => patch({ conversations: c.list, currentConversationId: c.currentId })).catch(() => { });
117
119
  api.providers().then((d) => patch({ providers: d.providers, explicitlyEnabled: d.explicitlyEnabled })).catch(() => { });
120
+ };
121
+ /** Load the REST snapshot and open the SSE stream. Idempotent-safe to call once. */
122
+ const start = () => {
123
+ // Clear transient fields before (re)loading — a reused store must not show a
124
+ // prior room's in-flight turn. Fresh stores are already clean; this is cheap.
125
+ set(resetTransient(state));
126
+ loadSnapshot();
118
127
  conn = makeEventSource(sseUrl, {
119
- onOpen: () => patch({ connected: true }),
128
+ onOpen: () => {
129
+ patch({ connected: true });
130
+ loadSnapshot();
131
+ },
120
132
  onError: () => patch({ connected: false }),
121
133
  onEvent,
122
134
  });
@@ -167,7 +179,13 @@ export function createRoomStore(opts) {
167
179
  throw err;
168
180
  }),
169
181
  getParticipant: (id) => rApi.participant(id),
170
- updateParticipant: (id, patchBody) => rApi.updateAgent(id, patchBody).catch((err) => {
182
+ updateParticipant: (id, patchBody) => rApi.updateAgent(id, patchBody).then((updated) => {
183
+ // The response is the fresh RosterItem — fold it in immediately so UIs
184
+ // reading the snapshot right after (e.g. a reopened picker) see the
185
+ // change without waiting for the roster broadcast.
186
+ patch({ roster: state.roster.map((p) => (p.id === updated.id ? { ...p, ...updated } : p)) });
187
+ return updated;
188
+ }).catch((err) => {
171
189
  fail(err);
172
190
  throw err;
173
191
  }),
@@ -253,8 +271,10 @@ export function createRoomStore(opts) {
253
271
  addProvider: (name, key) => {
254
272
  api.addProvider(name, key).then(() => {
255
273
  pushNotice(`Provider "${name}" configured.`);
256
- // Refresh models so the dropdown picks up new models.
274
+ // Refresh models so the dropdown picks up new models, and the provider
275
+ // list so the configured flag flips without a reconnect.
257
276
  api.models().catch(() => { });
277
+ api.providers().then((d) => patch({ providers: d.providers, explicitlyEnabled: d.explicitlyEnabled })).catch(() => { });
258
278
  }).catch(fail);
259
279
  },
260
280
  removeProvider: (name) => {
@@ -264,6 +284,7 @@ export function createRoomStore(opts) {
264
284
  msg += ` Note: ${r.agentsUsing.join(", ")} may need model reassigned.`;
265
285
  }
266
286
  pushNotice(msg);
287
+ api.providers().then((d) => patch({ providers: d.providers, explicitlyEnabled: d.explicitlyEnabled })).catch(() => { });
267
288
  }).catch(fail);
268
289
  },
269
290
  loginProvider: (name) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipeline-moe/client-core",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Framework-agnostic client for a pipeline-moe server: typed REST surface, pure SSE reducer, and an effectful room store. Consumed by the web and terminal clients.",