@cartanova/qgrid-ai-sdk 2.4.1 → 2.4.2

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/index.js +48 -40
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ const QGRID_PROVIDER_NAME = "qgrid";
3
3
  const THREAD_COORD_TTL_MS = 10 * 6e4;
4
4
  const TEXT_STREAM_ID_PREFIX = "text";
5
5
  const TOP_LEVEL_SCHEMA_WARNING = "OpenAI structured output requires \"object\". Falling back to client-side parsing.";
6
- const PENDING_TOOL_RESULTS_WARNING = "[qgrid] pending tool results not found in prompt, clearing client run state";
6
+ const PENDING_TOOL_RESULTS_WARNING = "[qgrid] tool results did not match any pending qgrid run; sending request without runContext";
7
7
  //#endregion
8
8
  //#region src/utils.ts
9
9
  async function createRun(serverUrl, body) {
@@ -659,7 +659,39 @@ function qgrid(modelId, config) {
659
659
  const serverUrl = config?.serverUrl ?? process.env.QGRID_URL ?? "http://localhost:44900";
660
660
  const effort = config?.defaultEffort ?? "low";
661
661
  const projectName = config?.projectName ?? process.env.QGRID_PROJECT_NAME;
662
- let clientRun = null;
662
+ const clientRuns = /* @__PURE__ */ new Map();
663
+ let anonymousClientRunId = 0;
664
+ function clientRunKey(runContext) {
665
+ if (runContext.requestLogId !== void 0) return `request:${runContext.requestLogId}`;
666
+ if (runContext.threadCoord) {
667
+ const { workerId, epoch, threadId } = runContext.threadCoord;
668
+ return `thread:${workerId}:${epoch}:${threadId}`;
669
+ }
670
+ anonymousClientRunId++;
671
+ return `anonymous:${anonymousClientRunId}`;
672
+ }
673
+ function rememberClientRun(runContext, toolCallIds) {
674
+ if (toolCallIds.length === 0) return;
675
+ clientRuns.set(clientRunKey(runContext), {
676
+ runContext,
677
+ pendingToolCallIds: new Set(toolCallIds)
678
+ });
679
+ }
680
+ function matchClientRun(messages) {
681
+ const toolResults = extractToolResultsFromHistory(messages);
682
+ if (toolResults.length === 0) return null;
683
+ const resultIds = new Set(toolResults.map((r) => r.callId));
684
+ for (const [key, run] of clientRuns) if (run.pendingToolCallIds.size > 0 && [...run.pendingToolCallIds].every((id) => resultIds.has(id))) return {
685
+ key,
686
+ runContext: run.runContext,
687
+ toolResultsPayload: toolResults.filter((r) => run.pendingToolCallIds.has(r.callId)).map((r) => ({
688
+ toolCallId: r.callId,
689
+ output: r.result
690
+ }))
691
+ };
692
+ if (clientRuns.size > 0) console.warn(PENDING_TOOL_RESULTS_WARNING);
693
+ return null;
694
+ }
663
695
  return {
664
696
  specificationVersion: "v3",
665
697
  provider: QGRID_PROVIDER_NAME,
@@ -687,20 +719,11 @@ function qgrid(modelId, config) {
687
719
  let runContext;
688
720
  let toolResultsPayload;
689
721
  let logMode;
690
- if (clientRun) {
691
- const toolResults = extractToolResultsFromHistory(options.prompt);
692
- const resultIds = new Set(toolResults.map((r) => r.callId));
693
- if (clientRun.pendingToolCallIds.size > 0 && [...clientRun.pendingToolCallIds].every((id) => resultIds.has(id))) {
694
- runContext = clientRun.runContext;
695
- toolResultsPayload = toolResults.filter((r) => clientRun.pendingToolCallIds.has(r.callId)).map((r) => ({
696
- toolCallId: r.callId,
697
- output: r.result
698
- }));
699
- logMode = "run";
700
- } else {
701
- console.warn(PENDING_TOOL_RESULTS_WARNING);
702
- clientRun = null;
703
- }
722
+ const matchedClientRun = matchClientRun(options.prompt);
723
+ if (matchedClientRun) {
724
+ runContext = matchedClientRun.runContext;
725
+ toolResultsPayload = matchedClientRun.toolResultsPayload;
726
+ logMode = "run";
704
727
  }
705
728
  const storedCoord = reuseSessionKey ? getThreadCoord(reuseSessionKey) : void 0;
706
729
  if (!runContext && storedCoord) runContext = { threadCoord: storedCoord };
@@ -765,11 +788,8 @@ function qgrid(modelId, config) {
765
788
  text: data.text
766
789
  });
767
790
  if (imageGeneration && !content.some((c) => c.type === "file")) throw new Error("qgrid: imageGeneration was requested but the response contained no image — the server may be an older version that does not support image generation.");
768
- if (data.runContext && finishReason.unified === "tool-calls") clientRun = {
769
- runContext: data.runContext,
770
- pendingToolCallIds: new Set(content.filter((c) => c.type === "tool-call").map((c) => c.toolCallId))
771
- };
772
- else clientRun = null;
791
+ if (matchedClientRun) clientRuns.delete(matchedClientRun.key);
792
+ if (data.runContext && finishReason.unified === "tool-calls") rememberClientRun(data.runContext, content.filter((c) => c.type === "tool-call").map((c) => c.toolCallId));
773
793
  if (reuseSessionKey && data.runContext?.threadCoord) setThreadCoord(reuseSessionKey, data.runContext.threadCoord);
774
794
  return {
775
795
  content,
@@ -803,20 +823,11 @@ function qgrid(modelId, config) {
803
823
  let runContext;
804
824
  let toolResultsPayload;
805
825
  let logMode;
806
- if (clientRun) {
807
- const toolResults = extractToolResultsFromHistory(options.prompt);
808
- const resultIds = new Set(toolResults.map((r) => r.callId));
809
- if (clientRun.pendingToolCallIds.size > 0 && [...clientRun.pendingToolCallIds].every((id) => resultIds.has(id))) {
810
- runContext = clientRun.runContext;
811
- toolResultsPayload = toolResults.filter((r) => clientRun.pendingToolCallIds.has(r.callId)).map((r) => ({
812
- toolCallId: r.callId,
813
- output: r.result
814
- }));
815
- logMode = "run";
816
- } else {
817
- console.warn(PENDING_TOOL_RESULTS_WARNING);
818
- clientRun = null;
819
- }
826
+ const matchedClientRun = matchClientRun(options.prompt);
827
+ if (matchedClientRun) {
828
+ runContext = matchedClientRun.runContext;
829
+ toolResultsPayload = matchedClientRun.toolResultsPayload;
830
+ logMode = "run";
820
831
  }
821
832
  const storedCoord = reuseSessionKey ? getThreadCoord(reuseSessionKey) : void 0;
822
833
  if (!runContext && storedCoord) runContext = { threadCoord: storedCoord };
@@ -883,11 +894,8 @@ function qgrid(modelId, config) {
883
894
  textStarted = false;
884
895
  }
885
896
  const done = event.data;
886
- if (done.runContext && done.finishReason === "tool-calls") clientRun = {
887
- runContext: done.runContext,
888
- pendingToolCallIds: new Set((done.content ?? []).filter((c) => c.type === "tool-call").map((c) => c.toolCallId))
889
- };
890
- else clientRun = null;
897
+ if (matchedClientRun) clientRuns.delete(matchedClientRun.key);
898
+ if (done.runContext && done.finishReason === "tool-calls") rememberClientRun(done.runContext, (done.content ?? []).filter((c) => c.type === "tool-call").map((c) => c.toolCallId));
891
899
  if (reuseSessionKey && done.runContext?.threadCoord) setThreadCoord(reuseSessionKey, done.runContext.threadCoord);
892
900
  if (done.content) {
893
901
  for (const item of done.content) if (item.type === "text" && !deltaTextEmitted) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cartanova/qgrid-ai-sdk",
3
- "version": "2.4.1",
3
+ "version": "2.4.2",
4
4
  "description": "AI SDK LanguageModelV3 provider for qgrid",
5
5
  "repository": {
6
6
  "type": "git",