@superblocksteam/vite-plugin-file-sync 2.0.43-next.12 → 2.0.43-next.14

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 (106) hide show
  1. package/dist/ai-service/agent/subagents/apis/generate-api-source.d.ts.map +1 -1
  2. package/dist/ai-service/agent/subagents/apis/generate-api-source.js +269 -249
  3. package/dist/ai-service/agent/subagents/apis/generate-api-source.js.map +1 -1
  4. package/dist/ai-service/agent/tools/build-finalize.d.ts +1 -22
  5. package/dist/ai-service/agent/tools/build-finalize.d.ts.map +1 -1
  6. package/dist/ai-service/agent/tools/build-finalize.js +27 -18
  7. package/dist/ai-service/agent/tools/build-finalize.js.map +1 -1
  8. package/dist/ai-service/agent/tools2/types.d.ts +12 -0
  9. package/dist/ai-service/agent/tools2/types.d.ts.map +1 -1
  10. package/dist/ai-service/agent/tools2/types.js +20 -0
  11. package/dist/ai-service/agent/tools2/types.js.map +1 -1
  12. package/dist/ai-service/llm/context/constants.d.ts +7 -6
  13. package/dist/ai-service/llm/context/constants.d.ts.map +1 -1
  14. package/dist/ai-service/llm/context/constants.js +7 -6
  15. package/dist/ai-service/llm/context/constants.js.map +1 -1
  16. package/dist/ai-service/llm/context/context-handle.d.ts +106 -0
  17. package/dist/ai-service/llm/context/context-handle.d.ts.map +1 -0
  18. package/dist/ai-service/llm/context/context-handle.js +134 -0
  19. package/dist/ai-service/llm/context/context-handle.js.map +1 -0
  20. package/dist/ai-service/llm/context/context-lock.d.ts +144 -0
  21. package/dist/ai-service/llm/context/context-lock.d.ts.map +1 -0
  22. package/dist/ai-service/llm/context/context-lock.js +221 -0
  23. package/dist/ai-service/llm/context/context-lock.js.map +1 -0
  24. package/dist/ai-service/llm/context/context.d.ts +18 -19
  25. package/dist/ai-service/llm/context/context.d.ts.map +1 -1
  26. package/dist/ai-service/llm/context/context.js +76 -127
  27. package/dist/ai-service/llm/context/context.js.map +1 -1
  28. package/dist/ai-service/llm/context/index.d.ts +4 -0
  29. package/dist/ai-service/llm/context/index.d.ts.map +1 -1
  30. package/dist/ai-service/llm/context/index.js +5 -0
  31. package/dist/ai-service/llm/context/index.js.map +1 -1
  32. package/dist/ai-service/llm/context/internal-types.d.ts +0 -2
  33. package/dist/ai-service/llm/context/internal-types.d.ts.map +1 -1
  34. package/dist/ai-service/llm/context/internal-types.js.map +1 -1
  35. package/dist/ai-service/llm/context/levels/l1.d.ts.map +1 -1
  36. package/dist/ai-service/llm/context/levels/l1.js +3 -5
  37. package/dist/ai-service/llm/context/levels/l1.js.map +1 -1
  38. package/dist/ai-service/llm/context/manager.d.ts +60 -11
  39. package/dist/ai-service/llm/context/manager.d.ts.map +1 -1
  40. package/dist/ai-service/llm/context/manager.js +111 -35
  41. package/dist/ai-service/llm/context/manager.js.map +1 -1
  42. package/dist/ai-service/llm/context/utils/content-compaction.d.ts +2 -2
  43. package/dist/ai-service/llm/context/utils/content-compaction.d.ts.map +1 -1
  44. package/dist/ai-service/llm/context/utils/content-compaction.js +6 -3
  45. package/dist/ai-service/llm/context/utils/content-compaction.js.map +1 -1
  46. package/dist/ai-service/llm/context/utils/index.d.ts +1 -1
  47. package/dist/ai-service/llm/context/utils/index.d.ts.map +1 -1
  48. package/dist/ai-service/llm/context/utils/index.js +1 -1
  49. package/dist/ai-service/llm/context/utils/index.js.map +1 -1
  50. package/dist/ai-service/llm/context/utils/message-utils.d.ts +17 -7
  51. package/dist/ai-service/llm/context/utils/message-utils.d.ts.map +1 -1
  52. package/dist/ai-service/llm/context/utils/message-utils.js +31 -18
  53. package/dist/ai-service/llm/context/utils/message-utils.js.map +1 -1
  54. package/dist/ai-service/llmobs/middleware/stream-text.d.ts.map +1 -1
  55. package/dist/ai-service/llmobs/middleware/stream-text.js +1 -0
  56. package/dist/ai-service/llmobs/middleware/stream-text.js.map +1 -1
  57. package/dist/ai-service/llmobs/tracer.d.ts +4 -0
  58. package/dist/ai-service/llmobs/tracer.d.ts.map +1 -1
  59. package/dist/ai-service/llmobs/tracer.js +11 -0
  60. package/dist/ai-service/llmobs/tracer.js.map +1 -1
  61. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/ButtonPropsDocs.js +1 -1
  62. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/CheckboxPropsDocs.js +1 -1
  63. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/ColumnPropsDocs.js +1 -1
  64. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/ContainerPropsDocs.js +1 -1
  65. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/DatePickerPropsDocs.js +1 -1
  66. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/DropdownPropsDocs.js +1 -1
  67. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/IconPropsDocs.js +1 -1
  68. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/ImagePropsDocs.js +1 -1
  69. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/InputPropsDocs.js +1 -1
  70. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/ModalPropsDocs.js +1 -1
  71. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/PagePropsDocs.js +1 -1
  72. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/SectionPropsDocs.js +1 -1
  73. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/SlideoutPropsDocs.js +1 -1
  74. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/SwitchPropsDocs.js +1 -1
  75. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/TablePropsDocs.js +1 -1
  76. package/dist/ai-service/prompt-builder-service/static-fragments/library-components/TextPropsDocs.js +1 -1
  77. package/dist/ai-service/prompt-builder-service/static-fragments/library-typedefs/Dim.js +1 -1
  78. package/dist/ai-service/prompt-builder-service/static-fragments/library-typedefs/EventFlow.js +1 -1
  79. package/dist/ai-service/prompt-builder-service/static-fragments/library-typedefs/TextStyleWithVariant.js +1 -1
  80. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/full-examples.js +1 -1
  81. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-api.js +1 -1
  82. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-components-rules.js +1 -1
  83. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-custom-components.js +1 -1
  84. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-data-filtering.js +1 -1
  85. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-event-flow.js +1 -1
  86. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-forms.js +1 -1
  87. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-layouts.js +1 -1
  88. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-page.js +1 -1
  89. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-rbac.js +1 -1
  90. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-routes.js +1 -1
  91. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-state.js +1 -1
  92. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/superblocks-theming-chakra-new.js +1 -1
  93. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/system-base.js +1 -1
  94. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/system-incremental.js +1 -1
  95. package/dist/ai-service/prompt-builder-service/static-fragments/platform-parts/system-specific-edit.js +1 -1
  96. package/dist/ai-service/state-machine/handlers/llm-generating.d.ts.map +1 -1
  97. package/dist/ai-service/state-machine/handlers/llm-generating.js +351 -334
  98. package/dist/ai-service/state-machine/handlers/llm-generating.js.map +1 -1
  99. package/dist/ai-service/util/stop-condition.d.ts +4 -1
  100. package/dist/ai-service/util/stop-condition.d.ts.map +1 -1
  101. package/dist/ai-service/util/stop-condition.js +14 -2
  102. package/dist/ai-service/util/stop-condition.js.map +1 -1
  103. package/dist/sync-service/download.d.ts.map +1 -1
  104. package/dist/sync-service/download.js +28 -7
  105. package/dist/sync-service/download.js.map +1 -1
  106. package/package.json +9 -8
@@ -1 +1 @@
1
- {"version":3,"file":"generate-api-source.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/agent/subagents/apis/generate-api-source.ts"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,KAAK,EACV,KAAK,EACL,uBAAuB,EACxB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EACV,aAAa,EACb,wBAAwB,EAIzB,MAAM,uCAAuC,CAAC;AAE/C,eAAO,MAAM,aAAa,GACxB,OAAO;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,EACD,UAAU,OAAO,EACjB,eAAe,aAAa,GAAG,SAAS,EACxC,OAAO,KAAK,EACZ,UAAU,uBAAuB,EACjC,kBAAkB,cAAc,EAEhC,aAAa,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;yBAqD9B,CAAF;uBAIF,CAAJ;;;;;;uBAOsC,CAAC;2BACf,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;CA4K1B,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,UAAU,MAAM,EAChB,SAAS,MAAM,EACf,iBAAiB,MAAM,EAAE,GAAG,SAAS,EACrC,UAAU,uBAAuB,sCA0ClC,CAAC;AAEF,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;GAgehD,CAAC"}
1
+ {"version":3,"file":"generate-api-source.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/agent/subagents/apis/generate-api-source.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,KAAK,EACV,KAAK,EACL,uBAAuB,EACxB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EACV,aAAa,EACb,wBAAwB,EAIzB,MAAM,uCAAuC,CAAC;AAE/C,eAAO,MAAM,aAAa,GACxB,OAAO;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,EACD,UAAU,OAAO,EACjB,eAAe,aAAa,GAAG,SAAS,EACxC,OAAO,KAAK,EACZ,UAAU,uBAAuB,EACjC,kBAAkB,cAAc,EAEhC,aAAa,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;yBAmDJ,CAAC;uBAErB,CAAC;;;;;;uBAUS,CAAC;2BACyB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;CA6KpD,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,UAAU,MAAM,EAChB,SAAS,MAAM,EACf,iBAAiB,MAAM,EAAE,GAAG,SAAS,EACrC,UAAU,uBAAuB,sCA0ClC,CAAC;AAEF,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;GA6fhD,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { hasToolCall, smoothStream, tool, } from "ai";
3
+ import { smoothStream, tool } from "ai";
4
4
  import z from "zod";
5
5
  import { getErrorMeta, getLogger } from "../../../../util/logger.js";
6
6
  import { datasourceSdkClassByType, Paths } from "../../../const.js";
@@ -11,6 +11,7 @@ import { YamlToApiBuilderTransformer } from "../../../transform/api-builder/to-s
11
11
  import { ApiBuilderToYamlTransformer } from "../../../transform/api-builder/to-yaml-transformer.js";
12
12
  import { applyFileTransformations, renderPath, } from "../../../transform/shared.js";
13
13
  import { processLLMConfig } from "../../../util/llm-config-utils.js";
14
+ import { hasToolSuccess } from "../../../util/stop-condition.js";
14
15
  import { getToolCallArguments } from "../../tool-message-utils.js";
15
16
  import { executeRequestToIntegrationToolFactory, searchIntegrationsToolFactory, } from "../../tools/index.js";
16
17
  import { ensureScopeFileDraft, getPageEntitiesFiltered, processStreamChunk, } from "../../utils.js";
@@ -299,276 +300,295 @@ When calling this tool, analyze the user's requirements and provide 2-4 relevant
299
300
  logRef.content += `[EXAMPLE SELECTION] Hints: ${exampleHints.join(", ")}\n`;
300
301
  logRef.content += `[EXAMPLE SELECTION] Selected: ${selectedExampleMetadata.map((e) => e.id).join(", ")}\n\n`;
301
302
  }
302
- // Set up context for the API subagent
303
- const contextId = getContextId(clark, services);
303
+ // Set up context for the API subagent with thread-safe ownership
304
+ const subagentName = `api-subagent-${pageName}-${apiName}`;
305
+ const contextId = getContextId(clark, services, subagentName);
304
306
  const contextOptions = clark.context.llmConfig?.contextOptions;
305
- const context = await services.contextManager.getContext(contextId, contextOptions);
306
- const mainSystemPrompt = context.getSystemPrompt();
307
- // Combine system prompt with examples
308
- const fullSystemPrompt = examplesContent
309
- ? `${systemPrompt}\n\n${examplesContent}`
310
- : systemPrompt;
311
- context.setSystemPrompt({
312
- role: "system",
313
- content: fullSystemPrompt,
307
+ // Generate a unique owner ID for this subagent execution
308
+ const ownerId = `${subagentName}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
309
+ // Acquire exclusive context access with retries
310
+ const contextHandle = await services.contextManager.acquireContext(contextId, ownerId, {
311
+ contextOptions,
312
+ acquireOptions: {
313
+ waitTimeoutMs: 10000, // Wait up to 10 seconds for context
314
+ lockTimeoutMs: 300000, // Hold lock for up to 5 minutes
315
+ retryIntervalMs: 100,
316
+ },
314
317
  });
315
- context.startTurn({
316
- role: "user",
317
- content: apiPrompt,
318
- });
319
- // Process LLM configuration
320
- const { providerOptions, headers } = processLLMConfig(llmConfig, 5000, // default budget tokens
321
- `API Subagent (model=${model.modelId})`);
322
- const apiSubagentTrack = "api_subagent";
323
- services.clarkProfiler
324
- .getProfiler()
325
- .createTrack(apiSubagentTrack, "API Subagent", "tool");
326
- return services.clarkProfiler.getProfiler().timeAsync(`generateApiSource:${apiName}`, async () => {
327
- let stepCount = 0;
328
- let thinkingSpanActive = false;
329
- let textSpanActive = false;
330
- const allReasoningDeltas = [];
331
- let currentStepReasoningDeltas = [];
332
- let currentStepTextDeltas = [];
333
- // Step accumulators for accurate token counting
334
- const startTime = new Date().toISOString();
335
- let totalInputTokens = 0;
336
- let totalOutputTokens = 0;
337
- let totalCachedTokens = 0;
338
- let finalizeApiData = {
339
- apiName,
340
- responseInterface: "",
341
- inputInterface: "",
342
- summary: "",
343
- };
344
- const response = tracedStreamText({
345
- model,
346
- messages: context.getMessages(),
347
- abortSignal: clark.context.abortController?.signal,
348
- providerOptions,
349
- headers,
350
- experimental_transform: [smoothStream({ chunking: "line" })],
351
- tools,
352
- prepareStep: async (step) => {
353
- context.startStep();
354
- const messages = context.getMessages();
355
- return { ...step, messages };
356
- },
357
- stopWhen: hasToolCall("finalizeApi"),
358
- onChunk: (chunkData) => {
359
- if (chunkData.chunk.type === "reasoning-delta") {
360
- allReasoningDeltas.push(chunkData.chunk.text);
361
- currentStepReasoningDeltas.push(chunkData.chunk.text);
362
- if (!thinkingSpanActive) {
363
- thinkingSpanActive = true;
318
+ try {
319
+ const context = contextHandle.context;
320
+ const mainSystemPrompt = context.getSystemPrompt();
321
+ // Combine system prompt with examples
322
+ const fullSystemPrompt = examplesContent
323
+ ? `${systemPrompt}\n\n${examplesContent}`
324
+ : systemPrompt;
325
+ context.setSystemPrompt({
326
+ role: "system",
327
+ content: fullSystemPrompt,
328
+ });
329
+ context.startTurn({
330
+ role: "user",
331
+ content: apiPrompt,
332
+ });
333
+ // Process LLM configuration
334
+ const { providerOptions, headers } = processLLMConfig(llmConfig, 5000, // default budget tokens
335
+ `API Subagent (model=${model.modelId})`);
336
+ const apiSubagentTrack = "api_subagent";
337
+ services.clarkProfiler
338
+ .getProfiler()
339
+ .createTrack(apiSubagentTrack, "API Subagent", "tool");
340
+ return await services.clarkProfiler.getProfiler().timeAsync(`generateApiSource:${apiName}`, async () => {
341
+ let stepCount = 0;
342
+ let thinkingSpanActive = false;
343
+ let textSpanActive = false;
344
+ const allReasoningDeltas = [];
345
+ let currentStepReasoningDeltas = [];
346
+ let currentStepTextDeltas = [];
347
+ // Step accumulators for accurate token counting
348
+ const startTime = new Date().toISOString();
349
+ let totalInputTokens = 0;
350
+ let totalOutputTokens = 0;
351
+ let totalCachedTokens = 0;
352
+ let finalizeApiData = {
353
+ apiName,
354
+ responseInterface: "",
355
+ inputInterface: "",
356
+ summary: "",
357
+ };
358
+ const response = tracedStreamText({
359
+ model,
360
+ messages: context.getMessages(),
361
+ abortSignal: clark.context.abortController?.signal,
362
+ providerOptions,
363
+ headers,
364
+ experimental_transform: [smoothStream({ chunking: "line" })],
365
+ tools,
366
+ prepareStep: async (step) => {
367
+ context.startStep();
368
+ const messages = context.getMessages();
369
+ return { ...step, messages };
370
+ },
371
+ stopWhen: hasToolSuccess("finalizeApi"),
372
+ onChunk: (chunkData) => {
373
+ if (chunkData.chunk.type === "reasoning-delta") {
374
+ allReasoningDeltas.push(chunkData.chunk.text);
375
+ currentStepReasoningDeltas.push(chunkData.chunk.text);
376
+ if (!thinkingSpanActive) {
377
+ thinkingSpanActive = true;
378
+ services.clarkProfiler
379
+ .getProfiler()
380
+ .startFrame(`API Thinking Step ${stepCount + 1}`, apiSubagentTrack, {
381
+ stepNumber: stepCount + 1,
382
+ chunkType: chunkData.chunk.type,
383
+ apiName,
384
+ });
385
+ }
386
+ }
387
+ if (chunkData.chunk.type === "text-delta") {
388
+ currentStepTextDeltas.push(chunkData.chunk.text);
389
+ if (!textSpanActive) {
390
+ textSpanActive = true;
391
+ services.clarkProfiler
392
+ .getProfiler()
393
+ .startFrame(`API Text Generation Step ${stepCount + 1}`, apiSubagentTrack, {
394
+ stepNumber: stepCount + 1,
395
+ firstTextDelta: chunkData.chunk.text.slice(0, 50) +
396
+ (chunkData.chunk.text.length > 50 ? "..." : ""),
397
+ apiName,
398
+ });
399
+ }
400
+ }
401
+ },
402
+ onStepFinish: async (step) => {
403
+ stepCount++;
404
+ const stepTimestamp = new Date().toISOString();
405
+ context.endStep(step.response.messages, step.usage);
406
+ logRef.content += `--- OUTPUT STEP (API subagent) [${stepTimestamp}] ---\n`;
407
+ totalInputTokens += step.usage?.inputTokens ?? 0;
408
+ if (step.reasoning && thinkingSpanActive) {
364
409
  services.clarkProfiler
365
410
  .getProfiler()
366
- .startFrame(`API Thinking Step ${stepCount + 1}`, apiSubagentTrack, {
367
- stepNumber: stepCount + 1,
368
- chunkType: chunkData.chunk.type,
411
+ .updateActiveFrameArgs(apiSubagentTrack, {
412
+ completeReasoningText: currentStepReasoningDeltas.join(" "),
413
+ reasoningLength: step.reasoning.length,
414
+ stepComplete: true,
369
415
  apiName,
370
416
  });
417
+ services.clarkProfiler
418
+ .getProfiler()
419
+ .endFrame(apiSubagentTrack);
420
+ thinkingSpanActive = false;
421
+ currentStepReasoningDeltas = [];
371
422
  }
372
- }
373
- if (chunkData.chunk.type === "text-delta") {
374
- currentStepTextDeltas.push(chunkData.chunk.text);
375
- if (!textSpanActive) {
376
- textSpanActive = true;
423
+ if (step.text && textSpanActive) {
377
424
  services.clarkProfiler
378
425
  .getProfiler()
379
- .startFrame(`API Text Generation Step ${stepCount + 1}`, apiSubagentTrack, {
380
- stepNumber: stepCount + 1,
381
- firstTextDelta: chunkData.chunk.text.slice(0, 50) +
382
- (chunkData.chunk.text.length > 50 ? "..." : ""),
426
+ .updateActiveFrameArgs(apiSubagentTrack, {
427
+ completeTextContent: currentStepTextDeltas.join(""),
428
+ finalText: step.text,
429
+ textLength: step.text.length,
430
+ stepComplete: true,
383
431
  apiName,
384
432
  });
433
+ services.clarkProfiler
434
+ .getProfiler()
435
+ .endFrame(apiSubagentTrack);
436
+ textSpanActive = false;
437
+ currentStepTextDeltas = [];
385
438
  }
386
- }
387
- },
388
- onStepFinish: async (step) => {
389
- stepCount++;
390
- const stepTimestamp = new Date().toISOString();
391
- context.endStep(step.response.messages, step.usage);
392
- logRef.content += `--- OUTPUT STEP (API subagent) [${stepTimestamp}] ---\n`;
393
- totalInputTokens += step.usage?.inputTokens ?? 0;
394
- if (step.reasoning && thinkingSpanActive) {
395
- services.clarkProfiler
396
- .getProfiler()
397
- .updateActiveFrameArgs(apiSubagentTrack, {
398
- completeReasoningText: currentStepReasoningDeltas.join(" "),
399
- reasoningLength: step.reasoning.length,
400
- stepComplete: true,
401
- apiName,
402
- });
403
- services.clarkProfiler
404
- .getProfiler()
405
- .endFrame(apiSubagentTrack);
406
- thinkingSpanActive = false;
407
- currentStepReasoningDeltas = [];
408
- }
409
- if (step.text && textSpanActive) {
410
- services.clarkProfiler
411
- .getProfiler()
412
- .updateActiveFrameArgs(apiSubagentTrack, {
413
- completeTextContent: currentStepTextDeltas.join(""),
414
- finalText: step.text,
415
- textLength: step.text.length,
416
- stepComplete: true,
417
- apiName,
418
- });
419
- services.clarkProfiler
420
- .getProfiler()
421
- .endFrame(apiSubagentTrack);
422
- textSpanActive = false;
423
- currentStepTextDeltas = [];
424
- }
425
- if (step.reasoning) {
426
- const reasoningLines = [
427
- "[REASONING]",
428
- ...step.reasoning.map(({ text }) => text),
429
- "",
430
- ];
431
- logRef.content += reasoningLines.join("\n");
432
- const reasoningText = step.reasoning
433
- .map(({ text }) => text)
434
- .join(" ");
435
- if (reasoningText.trim()) {
436
- void services.chatSessionStore.recordAssistant({
437
- type: "reasoning",
438
- text: reasoningText,
439
- group: `api-${apiName}`,
440
- });
441
- }
442
- }
443
- if (step.toolCalls.length > 0) {
444
- try {
445
- await Promise.all(step.toolCalls.map(async (toolCall) => {
446
- const args = await getToolCallArguments(toolCall.toolName, toolCall.input, clark);
447
- await services.chatSessionStore.recordAssistant({
448
- type: "tool",
449
- tool: toolCall.toolName,
450
- args: args,
439
+ if (step.reasoning) {
440
+ const reasoningLines = [
441
+ "[REASONING]",
442
+ ...step.reasoning.map(({ text }) => text),
443
+ "",
444
+ ];
445
+ logRef.content += reasoningLines.join("\n");
446
+ const reasoningText = step.reasoning
447
+ .map(({ text }) => text)
448
+ .join(" ");
449
+ if (reasoningText.trim()) {
450
+ void services.chatSessionStore.recordAssistant({
451
+ type: "reasoning",
452
+ text: reasoningText,
451
453
  group: `api-${apiName}`,
452
454
  });
453
- }));
454
- }
455
- catch (error) {
456
- getLogger().error("Failed to record subagent tool calls", getErrorMeta(error));
457
- }
458
- }
459
- // Record text messages AFTER tool calls
460
- if (step.text) {
461
- logRef.content += `[ASSISTANT TEXT] ${step.text}\n`;
462
- void services.chatSessionStore.recordAssistant({
463
- type: "text",
464
- text: step.text,
465
- group: `api-${apiName}`,
466
- });
467
- }
468
- // Accumulate token usage for this step
469
- if (step.usage) {
470
- const stepInputTokens = step.usage.inputTokens ?? 0;
471
- const stepOutputTokens = step.usage.outputTokens ?? 0;
472
- const stepCachedTokens = step.usage.cachedInputTokens ?? 0;
473
- // Accumulate tokens across all steps
474
- totalInputTokens += stepInputTokens;
475
- totalOutputTokens += stepOutputTokens;
476
- totalCachedTokens += stepCachedTokens;
477
- }
478
- const finalizeApiResult = step.toolResults.find((r) => r.toolName === "finalizeApi");
479
- if (finalizeApiResult) {
480
- finalizeApiData = finalizeApiResult.input;
481
- }
482
- const toolsCalled = step.content
483
- .filter((c) => c.type === "tool-result")
484
- .map((c) => ({
485
- toolName: c.toolName,
486
- input: JSON.stringify(c.input),
487
- output: JSON.stringify(c.output, null, 2),
488
- }));
489
- if (toolsCalled.length > 0) {
490
- logRef.content += `[TOOLS CALLED]\n`;
491
- toolsCalled.forEach((tool, idx) => {
492
- logRef.content += ` Tool ${idx + 1}: ${tool.toolName}\n`;
493
- logRef.content += ` Input: ${tool.input}\n`;
494
- logRef.content += ` Output: ${tool.output}\n`;
495
- });
496
- toolsCalled.forEach((tool, idx) => {
497
- let parsedInput, parsedOutput;
498
- try {
499
- parsedInput = JSON.parse(tool.input);
500
- }
501
- catch {
502
- parsedInput = tool.input;
503
455
  }
456
+ }
457
+ if (step.toolCalls.length > 0) {
504
458
  try {
505
- parsedOutput = JSON.parse(tool.output);
459
+ await Promise.all(step.toolCalls.map(async (toolCall) => {
460
+ const args = await getToolCallArguments(toolCall.toolName, toolCall.input, clark);
461
+ await services.chatSessionStore.recordAssistant({
462
+ type: "tool",
463
+ tool: toolCall.toolName,
464
+ args: args,
465
+ group: `api-${apiName}`,
466
+ });
467
+ }));
506
468
  }
507
- catch {
508
- parsedOutput = tool.output;
469
+ catch (error) {
470
+ getLogger().error("Failed to record subagent tool calls", getErrorMeta(error));
509
471
  }
510
- services.clarkProfiler
511
- .getProfiler()
512
- .addInstantEvent(`API Tool Call: ${tool.toolName}`, apiSubagentTrack, {
513
- step: stepCount,
514
- toolIndex: idx + 1,
515
- toolName: tool.toolName,
516
- input: parsedInput,
517
- output: parsedOutput,
518
- inputSize: tool.input.length,
519
- outputSize: tool.output.length,
520
- apiName,
472
+ }
473
+ // Record text messages AFTER tool calls
474
+ if (step.text) {
475
+ logRef.content += `[ASSISTANT TEXT] ${step.text}\n`;
476
+ void services.chatSessionStore.recordAssistant({
477
+ type: "text",
478
+ text: step.text,
479
+ group: `api-${apiName}`,
521
480
  });
522
- });
523
- }
524
- logRef.content += `\n`;
525
- },
526
- onFinish: (result) => {
527
- context.endTurn(result.totalUsage);
528
- if (mainSystemPrompt) {
529
- // restore main system prompt
530
- context.setSystemPrompt(mainSystemPrompt);
531
- }
532
- },
533
- }, clark.tracer, clark.logger);
534
- for await (const chunk of response.fullStream) {
535
- await processStreamChunk(chunk, clark, logRef, `api-${apiName}`);
536
- }
537
- if (thinkingSpanActive) {
538
- services.clarkProfiler.getProfiler().endFrame(apiSubagentTrack);
539
- }
540
- if (textSpanActive) {
541
- services.clarkProfiler.getProfiler().endFrame(apiSubagentTrack);
542
- }
543
- try {
544
- const requestTokenData = {
545
- requestId: `api-subagent-${apiName}-${Date.now()}`,
546
- inputTokens: totalInputTokens,
547
- outputTokens: totalOutputTokens,
548
- totalTokens: totalInputTokens + totalOutputTokens,
549
- cachedInputTokens: totalCachedTokens,
550
- model: model.modelId,
551
- startTime: startTime,
552
- endTime: new Date().toISOString(),
481
+ }
482
+ // Accumulate token usage for this step
483
+ if (step.usage) {
484
+ const stepInputTokens = step.usage.inputTokens ?? 0;
485
+ const stepOutputTokens = step.usage.outputTokens ?? 0;
486
+ const stepCachedTokens = step.usage.cachedInputTokens ?? 0;
487
+ // Accumulate tokens across all steps
488
+ totalInputTokens += stepInputTokens;
489
+ totalOutputTokens += stepOutputTokens;
490
+ totalCachedTokens += stepCachedTokens;
491
+ }
492
+ const finalizeApiResult = step.toolResults.find((r) => r.toolName === "finalizeApi");
493
+ if (finalizeApiResult) {
494
+ finalizeApiData =
495
+ finalizeApiResult.input;
496
+ }
497
+ const toolsCalled = step.content
498
+ .filter((c) => c.type === "tool-result")
499
+ .map((c) => ({
500
+ toolName: c.toolName,
501
+ input: JSON.stringify(c.input),
502
+ output: JSON.stringify(c.output, null, 2),
503
+ }));
504
+ if (toolsCalled.length > 0) {
505
+ logRef.content += `[TOOLS CALLED]\n`;
506
+ toolsCalled.forEach((tool, idx) => {
507
+ logRef.content += ` Tool ${idx + 1}: ${tool.toolName}\n`;
508
+ logRef.content += ` Input: ${tool.input}\n`;
509
+ logRef.content += ` Output: ${tool.output}\n`;
510
+ });
511
+ toolsCalled.forEach((tool, idx) => {
512
+ let parsedInput, parsedOutput;
513
+ try {
514
+ parsedInput = JSON.parse(tool.input);
515
+ }
516
+ catch {
517
+ parsedInput = tool.input;
518
+ }
519
+ try {
520
+ parsedOutput = JSON.parse(tool.output);
521
+ }
522
+ catch {
523
+ parsedOutput = tool.output;
524
+ }
525
+ services.clarkProfiler
526
+ .getProfiler()
527
+ .addInstantEvent(`API Tool Call: ${tool.toolName}`, apiSubagentTrack, {
528
+ step: stepCount,
529
+ toolIndex: idx + 1,
530
+ toolName: tool.toolName,
531
+ input: parsedInput,
532
+ output: parsedOutput,
533
+ inputSize: tool.input.length,
534
+ outputSize: tool.output.length,
535
+ apiName,
536
+ });
537
+ });
538
+ }
539
+ logRef.content += `\n`;
540
+ },
541
+ onFinish: (result) => {
542
+ context.endTurn(result.totalUsage);
543
+ if (mainSystemPrompt) {
544
+ // restore main system prompt
545
+ context.setSystemPrompt(mainSystemPrompt);
546
+ }
547
+ },
548
+ }, clark.tracer, clark.logger);
549
+ for await (const chunk of response.fullStream) {
550
+ await processStreamChunk(chunk, clark, logRef, `api-${apiName}`);
551
+ }
552
+ if (thinkingSpanActive) {
553
+ services.clarkProfiler.getProfiler().endFrame(apiSubagentTrack);
554
+ }
555
+ if (textSpanActive) {
556
+ services.clarkProfiler.getProfiler().endFrame(apiSubagentTrack);
557
+ }
558
+ try {
559
+ const requestTokenData = {
560
+ requestId: `api-subagent-${apiName}-${Date.now()}`,
561
+ inputTokens: totalInputTokens,
562
+ outputTokens: totalOutputTokens,
563
+ totalTokens: totalInputTokens + totalOutputTokens,
564
+ cachedInputTokens: totalCachedTokens,
565
+ model: model.modelId,
566
+ startTime: startTime,
567
+ endTime: new Date().toISOString(),
568
+ };
569
+ await clark.context.peer?.call.aiPushTokenUsage(requestTokenData);
570
+ }
571
+ catch (error) {
572
+ // Token tracking is non-critical - log error but don't fail the API generation
573
+ getLogger().warn("Failed to send token usage data for API generation", error instanceof Error ? error.message : String(error));
574
+ }
575
+ return {
576
+ message: finalizedMessage,
577
+ apiName,
578
+ pageName,
579
+ apiData: finalizeApiData,
553
580
  };
554
- await clark.context.peer?.call.aiPushTokenUsage(requestTokenData);
555
- }
556
- catch (error) {
557
- // Token tracking is non-critical - log error but don't fail the API generation
558
- getLogger().warn("Failed to send token usage data for API generation", error instanceof Error ? error.message : String(error));
559
- }
560
- return {
561
- message: finalizedMessage,
581
+ }, apiSubagentTrack, {
562
582
  apiName,
563
583
  pageName,
564
- apiData: finalizeApiData,
565
- };
566
- }, apiSubagentTrack, {
567
- apiName,
568
- pageName,
569
- promptLength: apiPrompt.length,
570
- model: model.modelId,
571
- });
584
+ promptLength: apiPrompt.length,
585
+ model: model.modelId,
586
+ });
587
+ }
588
+ finally {
589
+ // Always release the context lock when done
590
+ contextHandle.release();
591
+ }
572
592
  },
573
593
  };
574
594
  });