@aparte/core 0.18.0 → 0.19.1

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.
@@ -1326,15 +1326,20 @@ function createAparteAgentHandler(options) {
1326
1326
  return jsonError(400, "Invalid JSON body.");
1327
1327
  }
1328
1328
  if (body?.v !== 1) return jsonError(400, "Unsupported agent wire version: expected v 1.");
1329
- if (typeof body.providerId !== "string" || typeof body.messageId !== "string" || !Array.isArray(body.request?.messages)) {
1330
- return jsonError(400, "Body must be { v: 1, providerId, messageId, request: { messages } }.");
1329
+ if (body.providerId !== void 0 && typeof body.providerId !== "string" || typeof body.messageId !== "string" || !Array.isArray(body.request?.messages)) {
1330
+ return jsonError(400, "Body must be { v: 1, providerId?, messageId, request: { messages } }.");
1331
1331
  }
1332
1332
  if (body.request.toolChoice && typeof body.request.toolChoice === "object") {
1333
1333
  return jsonError(400, "A forced tool call cannot come from the browser.");
1334
1334
  }
1335
- const provider = Object.hasOwn(options.providers, body.providerId) ? options.providers[body.providerId] : void 0;
1335
+ const names = Object.keys(options.providers);
1336
+ const providerId = body.providerId || (names.length === 1 ? names[0] : void 0);
1337
+ if (!providerId) {
1338
+ return jsonError(400, `Name the providerId: this handler has ${names.length ? names.join(", ") : "no provider"}.`);
1339
+ }
1340
+ const provider = Object.hasOwn(options.providers, providerId) ? options.providers[providerId] : void 0;
1336
1341
  if (!provider) {
1337
- return jsonError(400, `Unknown providerId "${body.providerId}". Register it in the handler's providers map.`);
1342
+ return jsonError(400, `Unknown providerId "${providerId}". Register it in the handler's providers map.`);
1338
1343
  }
1339
1344
  const clientTools = Array.isArray(body.clientTools) ? body.clientTools : [];
1340
1345
  for (const t of clientTools) {
@@ -1347,6 +1352,7 @@ function createAparteAgentHandler(options) {
1347
1352
  }
1348
1353
  let request = {
1349
1354
  ...body.request,
1355
+ ...!body.request.modelId && options.defaultModel ? { modelId: options.defaultModel } : {},
1350
1356
  tools: [...[...tools.values()].map((t) => t.tool), ...clientTools]
1351
1357
  };
1352
1358
  if (options.prepareRequest) request = await options.prepareRequest(request, req);
@@ -1373,7 +1379,7 @@ function createAparteAgentHandler(options) {
1373
1379
  }
1374
1380
  outcomes = withoutUnacceptedPayloads(given, payload.calls, tools);
1375
1381
  }
1376
- const key = await options.resolveKey?.(body.providerId);
1382
+ const key = await options.resolveKey?.(providerId);
1377
1383
  const external = new Set(clientTools.map((t) => t.name));
1378
1384
  const rule = (call) => options.approvalPolicy?.(call, tools.get(call.name)?.tool);
1379
1385
  const run = new AbortController();
@@ -1415,10 +1421,10 @@ function createAparteAgentHandler(options) {
1415
1421
  };
1416
1422
  void runStreamAgent({
1417
1423
  messageId: body.messageId,
1418
- providerId: body.providerId,
1424
+ providerId,
1419
1425
  baseRequest: request,
1420
1426
  transportCall: async (r) => {
1421
- const response = await transport.chat(provider, r, key, { providerId: body.providerId, signal: run.signal });
1427
+ const response = await transport.chat(provider, r, key, { providerId, signal: run.signal });
1422
1428
  return typeof response === "string" ? response : readableToAsyncIterable(response, run.signal);
1423
1429
  },
1424
1430
  toolLookup: (name) => {
@@ -5887,6 +5893,19 @@ function requestUserInput(request) {
5887
5893
  const COMPACTION_PREAMBLE = "The earlier part of this conversation was compacted. This is a summary of what came before; continue from it.";
5888
5894
  const warnedUninlinedFiles = /* @__PURE__ */ new Set();
5889
5895
  const CHAT_SELECTOR = "aparte-chat, aparte-chat-viewport, [data-aparte-chat]";
5896
+ function remoteProvider(id) {
5897
+ return {
5898
+ id,
5899
+ getMetadata: () => ({ id, name: id }),
5900
+ getModels: () => [],
5901
+ chat: async () => {
5902
+ throw new AparteError(
5903
+ "This turn has no provider in the page. Register one, or use a runner that calls the model elsewhere (createAgentStreamRunner, an AG-UI runner).",
5904
+ AparteErrorCode.CONFIG_NO_PROVIDER
5905
+ );
5906
+ }
5907
+ };
5908
+ }
5890
5909
  class AparteClient {
5891
5910
  _boundHandler = null;
5892
5911
  _boundAbortHandler = null;
@@ -6138,6 +6157,24 @@ class AparteClient {
6138
6157
  * then the aparteGlobalConfig key channel (`setKeyProvider`) so a key registered
6139
6158
  * there reaches the request. One key source on the happy path.
6140
6159
  */
6160
+ /**
6161
+ * The runner calls the model somewhere else — a server loop, an AG-UI agent — so the
6162
+ * page needs no provider of its own. The engine's loop, passed explicitly, still does.
6163
+ */
6164
+ get _modelRunsElsewhere() {
6165
+ const runner = this.options.streamRunner;
6166
+ return Boolean(runner) && runner !== runStreamAgent;
6167
+ }
6168
+ /**
6169
+ * The provider a turn runs on: the registered one, else, when the model runs
6170
+ * elsewhere, a stand-in carrying the id the page named (none is fine: the server
6171
+ * picks). Undefined when the page must have one and has not.
6172
+ */
6173
+ _providerFor(providerId) {
6174
+ const registered = providerId ? this._config.getAIProvider(providerId) : void 0;
6175
+ if (registered) return registered;
6176
+ return this._modelRunsElsewhere ? remoteProvider(providerId ?? "") : void 0;
6177
+ }
6141
6178
  async _resolveAuth(providerId) {
6142
6179
  if (this.options.keyResolver) {
6143
6180
  const resolved = await this.options.keyResolver(providerId);
@@ -6179,6 +6216,15 @@ class AparteClient {
6179
6216
  return;
6180
6217
  }
6181
6218
  dispatchLifecycleEvent(targetElement, "aparte-message-start", { messageId, role: "assistant" }, chatId);
6219
+ if (!opts?.resume && provider.id) {
6220
+ this._updateMessage(targetElement, messageId, {
6221
+ model: {
6222
+ providerId: provider.id,
6223
+ modelId: baseRequest.modelId,
6224
+ ...baseRequest.temperature !== void 0 ? { temperature: baseRequest.temperature } : {}
6225
+ }
6226
+ });
6227
+ }
6182
6228
  const streamController = new AbortController();
6183
6229
  if (this._streamController !== streamController) this._streamController?.abort();
6184
6230
  this._streamController = streamController;
@@ -6298,10 +6344,9 @@ class AparteClient {
6298
6344
  const newMessageId = targetElement.addSiblingOf?.(messageId, newMsg) ?? newMsg.id;
6299
6345
  const config = this._config.getModelConfig();
6300
6346
  const providerId = config.defaultProvider;
6301
- if (!providerId) return;
6302
- const provider = this._config.getAIProvider(providerId);
6347
+ const provider = this._providerFor(providerId);
6303
6348
  if (!provider) return;
6304
- const authConfig = await this._resolveAuth(providerId);
6349
+ const authConfig = providerId ? await this._resolveAuth(providerId) : void 0;
6305
6350
  const chatMessages = this._messagesToChatMessages(historyMessages);
6306
6351
  const systemMessages = this._systemMessages();
6307
6352
  await this._streamTurn(
@@ -6360,10 +6405,9 @@ class AparteClient {
6360
6405
  const systemMessages = this._systemMessages();
6361
6406
  const config = this._config.getModelConfig();
6362
6407
  const providerId = config.defaultProvider;
6363
- if (!providerId) return;
6364
- const provider = this._config.getAIProvider(providerId);
6408
+ const provider = this._providerFor(providerId);
6365
6409
  if (!provider) return;
6366
- const authConfig = await this._resolveAuth(providerId);
6410
+ const authConfig = providerId ? await this._resolveAuth(providerId) : void 0;
6367
6411
  const newMessageId = uuid();
6368
6412
  targetElement.appendMessage?.({
6369
6413
  id: newMessageId,
@@ -6595,7 +6639,7 @@ class AparteClient {
6595
6639
  const messageId = uuid();
6596
6640
  const config = this._config.getModelConfig();
6597
6641
  const providerId = explicitProviderId || config.defaultProvider;
6598
- if (!providerId) {
6642
+ if (!providerId && !this._modelRunsElsewhere) {
6599
6643
  if (!this._warnedNoModel) {
6600
6644
  this._warnedNoModel = true;
6601
6645
  console.warn(
@@ -6608,7 +6652,7 @@ class AparteClient {
6608
6652
  ));
6609
6653
  return;
6610
6654
  }
6611
- const provider = this._config.getAIProvider(providerId);
6655
+ const provider = this._providerFor(providerId);
6612
6656
  if (!provider) {
6613
6657
  this._handleLifecycleError(targetElement, messageId, new AparteError(
6614
6658
  `Provider '${providerId}' is not registered.`,
@@ -6627,7 +6671,7 @@ class AparteClient {
6627
6671
  let authConfig;
6628
6672
  let messages;
6629
6673
  try {
6630
- authConfig = await this._resolveAuth(providerId);
6674
+ authConfig = providerId ? await this._resolveAuth(providerId) : void 0;
6631
6675
  const rawFiles = Array.isArray(event.detail?.files) ? event.detail.files : [];
6632
6676
  const filesToInject = this._selectFilesToInject(rawFiles);
6633
6677
  const contentParts = filesToInject.length > 0 ? await this._filesToContentParts(filesToInject) : [];
@@ -6910,7 +6954,7 @@ ${content}
6910
6954
  const approvalResolver = this._approvalResolverFor(targetElement);
6911
6955
  const usage = await streamRunner({
6912
6956
  messageId,
6913
- providerId: provider.id,
6957
+ ...provider.id ? { providerId: provider.id } : {},
6914
6958
  ...deferral ? { deferral } : {},
6915
6959
  baseRequest,
6916
6960
  transportCall,
@@ -7093,7 +7137,9 @@ ${content}
7093
7137
  const ticket = open.find((s) => s.deferred?.ticket)?.deferred?.ticket;
7094
7138
  if (!last || open.length === 0 || !ticket || this._resuming.has(last.id)) return false;
7095
7139
  const config = this._config.getModelConfig();
7096
- const provider = config.defaultProvider ? this._config.getAIProvider(config.defaultProvider) : void 0;
7140
+ const recorded = last.model && this._config.getAIProvider(last.model.providerId) ? last.model : void 0;
7141
+ const providerId = recorded?.providerId ?? config.defaultProvider;
7142
+ const provider = this._providerFor(providerId);
7097
7143
  if (!provider) {
7098
7144
  console.warn("[AparteClient] Cannot resume the paused turn: no provider is selected.");
7099
7145
  return false;
@@ -7101,7 +7147,7 @@ ${content}
7101
7147
  this._beginUserTurn();
7102
7148
  this._resuming.add(last.id);
7103
7149
  try {
7104
- const authConfig = await this._resolveAuth(provider.id);
7150
+ const authConfig = provider.id ? await this._resolveAuth(provider.id) : void 0;
7105
7151
  const pending = open.map((s) => ({
7106
7152
  toolCallId: s.toolCall.id,
7107
7153
  name: s.toolCall.name,
@@ -7109,8 +7155,9 @@ ${content}
7109
7155
  reason: s.deferred.reason
7110
7156
  }));
7111
7157
  const base = this._resumeBase(messages, messages.indexOf(last));
7112
- await this._streamTurn(targetElement, last.id, provider, base, config.defaultModel || "", authConfig, {
7113
- resume: { pending, ticket }
7158
+ await this._streamTurn(targetElement, last.id, provider, base, recorded?.modelId ?? config.defaultModel ?? "", authConfig, {
7159
+ resume: { pending, ticket },
7160
+ ...recorded?.temperature !== void 0 ? { temperature: recorded.temperature } : {}
7114
7161
  });
7115
7162
  } finally {
7116
7163
  this._resuming.delete(last.id);
@@ -7162,7 +7209,7 @@ function createAgentStreamRunner(options) {
7162
7209
  const { tools, ...request } = opts.baseRequest;
7163
7210
  const body = {
7164
7211
  v: 1,
7165
- providerId: opts.providerId,
7212
+ ...opts.providerId ? { providerId: opts.providerId } : {},
7166
7213
  messageId: opts.messageId,
7167
7214
  request,
7168
7215
  clientTools: tools ?? [],
@@ -7681,4 +7728,4 @@ export {
7681
7728
  collectRendererStyles as y,
7682
7729
  contentToText as z
7683
7730
  };
7684
- //# sourceMappingURL=dialog-triggers-Dad9V_ag.js.map
7731
+ //# sourceMappingURL=dialog-triggers-CEazY76J.js.map