@inkeep/agents-run-api 0.23.3 → 0.23.5
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.cjs +553 -481
- package/dist/index.js +552 -480
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -7677,326 +7677,334 @@ var Agent = class {
|
|
|
7677
7677
|
}
|
|
7678
7678
|
}
|
|
7679
7679
|
async generate(userMessage, runtimeContext) {
|
|
7680
|
-
return tracer.startActiveSpan(
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
|
|
7685
|
-
|
|
7686
|
-
this.streamRequestId = streamRequestId;
|
|
7687
|
-
this.streamHelper = streamRequestId ? getStreamHelper(streamRequestId) : void 0;
|
|
7688
|
-
const conversationId = runtimeContext?.metadata?.conversationId;
|
|
7689
|
-
if (conversationId) {
|
|
7690
|
-
this.setConversationId(conversationId);
|
|
7680
|
+
return tracer.startActiveSpan(
|
|
7681
|
+
"agent.generate",
|
|
7682
|
+
{
|
|
7683
|
+
attributes: {
|
|
7684
|
+
"subagent.id": this.config.id,
|
|
7685
|
+
"subagent.name": this.config.name
|
|
7691
7686
|
}
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
"session.id": sessionId
|
|
7705
|
-
}
|
|
7706
|
-
},
|
|
7707
|
-
async (childSpan) => {
|
|
7708
|
-
try {
|
|
7709
|
-
const result = await Promise.all([
|
|
7710
|
-
this.getMcpTools(sessionId, streamRequestId),
|
|
7711
|
-
this.buildSystemPrompt(runtimeContext, false),
|
|
7712
|
-
// Normal prompt with data components
|
|
7713
|
-
this.buildSystemPrompt(runtimeContext, true),
|
|
7714
|
-
// Thinking prompt without data components
|
|
7715
|
-
this.getFunctionTools(sessionId, streamRequestId),
|
|
7716
|
-
Promise.resolve(this.getRelationTools(runtimeContext, sessionId)),
|
|
7717
|
-
this.getDefaultTools(streamRequestId)
|
|
7718
|
-
]);
|
|
7719
|
-
childSpan.setStatus({ code: SpanStatusCode.OK });
|
|
7720
|
-
return result;
|
|
7721
|
-
} catch (err) {
|
|
7722
|
-
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
7723
|
-
setSpanWithError(childSpan, errorObj);
|
|
7724
|
-
throw err;
|
|
7725
|
-
} finally {
|
|
7726
|
-
childSpan.end();
|
|
7727
|
-
}
|
|
7728
|
-
}
|
|
7729
|
-
);
|
|
7730
|
-
const allTools = {
|
|
7731
|
-
...mcpTools,
|
|
7732
|
-
...functionTools,
|
|
7733
|
-
...relationTools,
|
|
7734
|
-
...defaultTools
|
|
7735
|
-
};
|
|
7736
|
-
const sanitizedTools = this.sanitizeToolsForAISDK(allTools);
|
|
7737
|
-
let conversationHistory = "";
|
|
7738
|
-
const historyConfig = this.config.conversationHistoryConfig ?? createDefaultConversationHistoryConfig();
|
|
7739
|
-
if (historyConfig && historyConfig.mode !== "none") {
|
|
7740
|
-
if (historyConfig.mode === "full") {
|
|
7741
|
-
conversationHistory = await getFormattedConversationHistory({
|
|
7742
|
-
tenantId: this.config.tenantId,
|
|
7743
|
-
projectId: this.config.projectId,
|
|
7744
|
-
conversationId: contextId,
|
|
7745
|
-
currentMessage: userMessage,
|
|
7746
|
-
options: historyConfig,
|
|
7747
|
-
filters: {}
|
|
7748
|
-
});
|
|
7749
|
-
} else if (historyConfig.mode === "scoped") {
|
|
7750
|
-
conversationHistory = await getFormattedConversationHistory({
|
|
7751
|
-
tenantId: this.config.tenantId,
|
|
7752
|
-
projectId: this.config.projectId,
|
|
7753
|
-
conversationId: contextId,
|
|
7754
|
-
currentMessage: userMessage,
|
|
7755
|
-
options: historyConfig,
|
|
7756
|
-
filters: {
|
|
7757
|
-
subAgentId: this.config.id,
|
|
7758
|
-
taskId
|
|
7759
|
-
}
|
|
7760
|
-
});
|
|
7687
|
+
},
|
|
7688
|
+
async (span) => {
|
|
7689
|
+
const contextId = runtimeContext?.contextId || "default";
|
|
7690
|
+
const taskId = runtimeContext?.metadata?.taskId || "unknown";
|
|
7691
|
+
const streamRequestId = runtimeContext?.metadata?.streamRequestId;
|
|
7692
|
+
const sessionId = streamRequestId || "fallback-session";
|
|
7693
|
+
try {
|
|
7694
|
+
this.streamRequestId = streamRequestId;
|
|
7695
|
+
this.streamHelper = streamRequestId ? getStreamHelper(streamRequestId) : void 0;
|
|
7696
|
+
const conversationId = runtimeContext?.metadata?.conversationId;
|
|
7697
|
+
if (conversationId) {
|
|
7698
|
+
this.setConversationId(conversationId);
|
|
7761
7699
|
}
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
const timeoutMs = Math.min(configuredTimeout, MAX_ALLOWED_TIMEOUT_MS);
|
|
7772
|
-
if (modelSettings.maxDuration && modelSettings.maxDuration * 1e3 > MAX_ALLOWED_TIMEOUT_MS) {
|
|
7773
|
-
logger15.warn(
|
|
7700
|
+
const [
|
|
7701
|
+
mcpTools,
|
|
7702
|
+
systemPrompt,
|
|
7703
|
+
thinkingSystemPrompt,
|
|
7704
|
+
functionTools,
|
|
7705
|
+
relationTools,
|
|
7706
|
+
defaultTools
|
|
7707
|
+
] = await tracer.startActiveSpan(
|
|
7708
|
+
"agent.load_tools",
|
|
7774
7709
|
{
|
|
7775
|
-
|
|
7776
|
-
|
|
7777
|
-
|
|
7778
|
-
},
|
|
7779
|
-
"Requested timeout exceeded maximum allowed, capping to 10 minutes"
|
|
7780
|
-
);
|
|
7781
|
-
}
|
|
7782
|
-
const phase1SystemPrompt = hasStructuredOutput ? thinkingSystemPrompt : systemPrompt;
|
|
7783
|
-
const messages = [];
|
|
7784
|
-
messages.push({ role: "system", content: phase1SystemPrompt });
|
|
7785
|
-
if (conversationHistory.trim() !== "") {
|
|
7786
|
-
messages.push({ role: "user", content: conversationHistory });
|
|
7787
|
-
}
|
|
7788
|
-
messages.push({
|
|
7789
|
-
role: "user",
|
|
7790
|
-
content: userMessage
|
|
7791
|
-
});
|
|
7792
|
-
if (shouldStreamPhase1) {
|
|
7793
|
-
const streamConfig = {
|
|
7794
|
-
...modelSettings,
|
|
7795
|
-
toolChoice: "auto"
|
|
7796
|
-
// Allow natural text + tools
|
|
7797
|
-
};
|
|
7798
|
-
const streamResult = streamText({
|
|
7799
|
-
...streamConfig,
|
|
7800
|
-
messages,
|
|
7801
|
-
tools: sanitizedTools,
|
|
7802
|
-
stopWhen: async ({ steps }) => {
|
|
7803
|
-
const last = steps.at(-1);
|
|
7804
|
-
if (last && "text" in last && last.text) {
|
|
7805
|
-
try {
|
|
7806
|
-
await agentSessionManager.recordEvent(
|
|
7807
|
-
this.getStreamRequestId(),
|
|
7808
|
-
"agent_reasoning",
|
|
7809
|
-
this.config.id,
|
|
7810
|
-
{
|
|
7811
|
-
parts: [{ type: "text", content: last.text }]
|
|
7812
|
-
}
|
|
7813
|
-
);
|
|
7814
|
-
} catch (error) {
|
|
7815
|
-
logger15.debug({ error }, "Failed to track agent reasoning");
|
|
7816
|
-
}
|
|
7817
|
-
}
|
|
7818
|
-
if (steps.length >= 2) {
|
|
7819
|
-
const previousStep = steps[steps.length - 2];
|
|
7820
|
-
if (previousStep && "toolCalls" in previousStep && previousStep.toolCalls) {
|
|
7821
|
-
const hasTransferCall = previousStep.toolCalls.some(
|
|
7822
|
-
(tc) => tc.toolName.startsWith("transfer_to_")
|
|
7823
|
-
);
|
|
7824
|
-
if (hasTransferCall && "toolResults" in previousStep && previousStep.toolResults) {
|
|
7825
|
-
return true;
|
|
7826
|
-
}
|
|
7827
|
-
}
|
|
7710
|
+
attributes: {
|
|
7711
|
+
"subAgent.name": this.config.name,
|
|
7712
|
+
"session.id": sessionId
|
|
7828
7713
|
}
|
|
7829
|
-
return steps.length >= this.getMaxGenerationSteps();
|
|
7830
|
-
},
|
|
7831
|
-
experimental_telemetry: {
|
|
7832
|
-
isEnabled: true,
|
|
7833
|
-
functionId: this.config.id,
|
|
7834
|
-
recordInputs: true,
|
|
7835
|
-
recordOutputs: true
|
|
7836
7714
|
},
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
7856
|
-
|
|
7715
|
+
async (childSpan) => {
|
|
7716
|
+
try {
|
|
7717
|
+
const result = await Promise.all([
|
|
7718
|
+
this.getMcpTools(sessionId, streamRequestId),
|
|
7719
|
+
this.buildSystemPrompt(runtimeContext, false),
|
|
7720
|
+
// Normal prompt with data components
|
|
7721
|
+
this.buildSystemPrompt(runtimeContext, true),
|
|
7722
|
+
// Thinking prompt without data components
|
|
7723
|
+
this.getFunctionTools(sessionId, streamRequestId),
|
|
7724
|
+
Promise.resolve(this.getRelationTools(runtimeContext, sessionId)),
|
|
7725
|
+
this.getDefaultTools(streamRequestId)
|
|
7726
|
+
]);
|
|
7727
|
+
childSpan.setStatus({ code: SpanStatusCode.OK });
|
|
7728
|
+
return result;
|
|
7729
|
+
} catch (err) {
|
|
7730
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
7731
|
+
setSpanWithError(childSpan, errorObj);
|
|
7732
|
+
throw err;
|
|
7733
|
+
} finally {
|
|
7734
|
+
childSpan.end();
|
|
7735
|
+
}
|
|
7736
|
+
}
|
|
7857
7737
|
);
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7861
|
-
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
|
|
7865
|
-
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7738
|
+
const allTools = {
|
|
7739
|
+
...mcpTools,
|
|
7740
|
+
...functionTools,
|
|
7741
|
+
...relationTools,
|
|
7742
|
+
...defaultTools
|
|
7743
|
+
};
|
|
7744
|
+
const sanitizedTools = this.sanitizeToolsForAISDK(allTools);
|
|
7745
|
+
let conversationHistory = "";
|
|
7746
|
+
const historyConfig = this.config.conversationHistoryConfig ?? createDefaultConversationHistoryConfig();
|
|
7747
|
+
if (historyConfig && historyConfig.mode !== "none") {
|
|
7748
|
+
if (historyConfig.mode === "full") {
|
|
7749
|
+
conversationHistory = await getFormattedConversationHistory({
|
|
7750
|
+
tenantId: this.config.tenantId,
|
|
7751
|
+
projectId: this.config.projectId,
|
|
7752
|
+
conversationId: contextId,
|
|
7753
|
+
currentMessage: userMessage,
|
|
7754
|
+
options: historyConfig,
|
|
7755
|
+
filters: {}
|
|
7756
|
+
});
|
|
7757
|
+
} else if (historyConfig.mode === "scoped") {
|
|
7758
|
+
conversationHistory = await getFormattedConversationHistory({
|
|
7759
|
+
tenantId: this.config.tenantId,
|
|
7760
|
+
projectId: this.config.projectId,
|
|
7761
|
+
conversationId: contextId,
|
|
7762
|
+
currentMessage: userMessage,
|
|
7763
|
+
options: historyConfig,
|
|
7764
|
+
filters: {
|
|
7765
|
+
subAgentId: this.config.id,
|
|
7766
|
+
taskId
|
|
7880
7767
|
}
|
|
7768
|
+
});
|
|
7881
7769
|
}
|
|
7882
7770
|
}
|
|
7883
|
-
|
|
7884
|
-
|
|
7885
|
-
|
|
7886
|
-
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7771
|
+
const primaryModelSettings = this.getPrimaryModel();
|
|
7772
|
+
const modelSettings = ModelFactory.prepareGenerationConfig(primaryModelSettings);
|
|
7773
|
+
let response;
|
|
7774
|
+
let textResponse;
|
|
7775
|
+
const hasStructuredOutput = this.config.dataComponents && this.config.dataComponents.length > 0;
|
|
7776
|
+
const shouldStreamPhase1 = this.getStreamingHelper() && !hasStructuredOutput;
|
|
7777
|
+
const MAX_ALLOWED_TIMEOUT_MS = 6e5;
|
|
7778
|
+
const configuredTimeout = modelSettings.maxDuration ? Math.min(modelSettings.maxDuration * 1e3, MAX_ALLOWED_TIMEOUT_MS) : shouldStreamPhase1 ? CONSTANTS.PHASE_1_TIMEOUT_MS : CONSTANTS.NON_STREAMING_PHASE_1_TIMEOUT_MS;
|
|
7779
|
+
const timeoutMs = Math.min(configuredTimeout, MAX_ALLOWED_TIMEOUT_MS);
|
|
7780
|
+
if (modelSettings.maxDuration && modelSettings.maxDuration * 1e3 > MAX_ALLOWED_TIMEOUT_MS) {
|
|
7781
|
+
logger15.warn(
|
|
7782
|
+
{
|
|
7783
|
+
requestedTimeout: modelSettings.maxDuration * 1e3,
|
|
7784
|
+
appliedTimeout: timeoutMs,
|
|
7785
|
+
maxAllowed: MAX_ALLOWED_TIMEOUT_MS
|
|
7786
|
+
},
|
|
7787
|
+
"Requested timeout exceeded maximum allowed, capping to 10 minutes"
|
|
7788
|
+
);
|
|
7894
7789
|
}
|
|
7895
|
-
const
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
...part.kind === "text" && { text: part.text },
|
|
7901
|
-
...part.kind === "data" && { data: part.data }
|
|
7902
|
-
}))
|
|
7903
|
-
};
|
|
7790
|
+
const phase1SystemPrompt = hasStructuredOutput ? thinkingSystemPrompt : systemPrompt;
|
|
7791
|
+
const messages = [];
|
|
7792
|
+
messages.push({ role: "system", content: phase1SystemPrompt });
|
|
7793
|
+
if (conversationHistory.trim() !== "") {
|
|
7794
|
+
messages.push({ role: "user", content: conversationHistory });
|
|
7904
7795
|
}
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
// Force tool usage, prevent text generation
|
|
7912
|
-
};
|
|
7913
|
-
} else {
|
|
7914
|
-
genConfig = {
|
|
7796
|
+
messages.push({
|
|
7797
|
+
role: "user",
|
|
7798
|
+
content: userMessage
|
|
7799
|
+
});
|
|
7800
|
+
if (shouldStreamPhase1) {
|
|
7801
|
+
const streamConfig = {
|
|
7915
7802
|
...modelSettings,
|
|
7916
7803
|
toolChoice: "auto"
|
|
7917
|
-
// Allow
|
|
7804
|
+
// Allow natural text + tools
|
|
7918
7805
|
};
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
)
|
|
7936
|
-
|
|
7937
|
-
|
|
7806
|
+
const streamResult = streamText({
|
|
7807
|
+
...streamConfig,
|
|
7808
|
+
messages,
|
|
7809
|
+
tools: sanitizedTools,
|
|
7810
|
+
stopWhen: async ({ steps }) => {
|
|
7811
|
+
const last = steps.at(-1);
|
|
7812
|
+
if (last && "text" in last && last.text) {
|
|
7813
|
+
try {
|
|
7814
|
+
await agentSessionManager.recordEvent(
|
|
7815
|
+
this.getStreamRequestId(),
|
|
7816
|
+
"agent_reasoning",
|
|
7817
|
+
this.config.id,
|
|
7818
|
+
{
|
|
7819
|
+
parts: [{ type: "text", content: last.text }]
|
|
7820
|
+
}
|
|
7821
|
+
);
|
|
7822
|
+
} catch (error) {
|
|
7823
|
+
logger15.debug({ error }, "Failed to track agent reasoning");
|
|
7824
|
+
}
|
|
7938
7825
|
}
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7826
|
+
if (steps.length >= 2) {
|
|
7827
|
+
const previousStep = steps[steps.length - 2];
|
|
7828
|
+
if (previousStep && "toolCalls" in previousStep && previousStep.toolCalls) {
|
|
7829
|
+
const hasTransferCall = previousStep.toolCalls.some(
|
|
7830
|
+
(tc) => tc.toolName.startsWith("transfer_to_")
|
|
7831
|
+
);
|
|
7832
|
+
if (hasTransferCall && "toolResults" in previousStep && previousStep.toolResults) {
|
|
7833
|
+
return true;
|
|
7834
|
+
}
|
|
7948
7835
|
}
|
|
7949
7836
|
}
|
|
7837
|
+
return steps.length >= this.getMaxGenerationSteps();
|
|
7838
|
+
},
|
|
7839
|
+
experimental_telemetry: {
|
|
7840
|
+
isEnabled: true,
|
|
7841
|
+
functionId: this.config.id,
|
|
7842
|
+
recordInputs: true,
|
|
7843
|
+
recordOutputs: true
|
|
7844
|
+
},
|
|
7845
|
+
abortSignal: AbortSignal.timeout(timeoutMs)
|
|
7846
|
+
});
|
|
7847
|
+
const streamHelper = this.getStreamingHelper();
|
|
7848
|
+
if (!streamHelper) {
|
|
7849
|
+
throw new Error("Stream helper is unexpectedly undefined in streaming context");
|
|
7850
|
+
}
|
|
7851
|
+
const session = toolSessionManager.getSession(sessionId);
|
|
7852
|
+
const artifactParserOptions = {
|
|
7853
|
+
sessionId,
|
|
7854
|
+
taskId: session?.taskId,
|
|
7855
|
+
projectId: session?.projectId,
|
|
7856
|
+
artifactComponents: this.artifactComponents,
|
|
7857
|
+
streamRequestId: this.getStreamRequestId(),
|
|
7858
|
+
subAgentId: this.config.id
|
|
7859
|
+
};
|
|
7860
|
+
const parser = new IncrementalStreamParser(
|
|
7861
|
+
streamHelper,
|
|
7862
|
+
this.config.tenantId,
|
|
7863
|
+
contextId,
|
|
7864
|
+
artifactParserOptions
|
|
7865
|
+
);
|
|
7866
|
+
for await (const event of streamResult.fullStream) {
|
|
7867
|
+
switch (event.type) {
|
|
7868
|
+
case "text-delta":
|
|
7869
|
+
await parser.processTextChunk(event.text);
|
|
7870
|
+
break;
|
|
7871
|
+
case "tool-call":
|
|
7872
|
+
parser.markToolResult();
|
|
7873
|
+
break;
|
|
7874
|
+
case "tool-result":
|
|
7875
|
+
parser.markToolResult();
|
|
7876
|
+
break;
|
|
7877
|
+
case "finish":
|
|
7878
|
+
if (event.finishReason === "tool-calls") {
|
|
7879
|
+
parser.markToolResult();
|
|
7880
|
+
}
|
|
7881
|
+
break;
|
|
7882
|
+
case "error":
|
|
7883
|
+
if (event.error instanceof Error) {
|
|
7884
|
+
throw event.error;
|
|
7885
|
+
} else {
|
|
7886
|
+
const errorMessage = event.error?.error?.message;
|
|
7887
|
+
throw new Error(errorMessage);
|
|
7888
|
+
}
|
|
7950
7889
|
}
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
|
|
7985
|
-
|
|
7890
|
+
}
|
|
7891
|
+
await parser.finalize();
|
|
7892
|
+
response = await streamResult;
|
|
7893
|
+
const collectedParts = parser.getCollectedParts();
|
|
7894
|
+
if (collectedParts.length > 0) {
|
|
7895
|
+
response.formattedContent = {
|
|
7896
|
+
parts: collectedParts.map((part) => ({
|
|
7897
|
+
kind: part.kind,
|
|
7898
|
+
...part.kind === "text" && { text: part.text },
|
|
7899
|
+
...part.kind === "data" && { data: part.data }
|
|
7900
|
+
}))
|
|
7901
|
+
};
|
|
7902
|
+
}
|
|
7903
|
+
const streamedContent = parser.getAllStreamedContent();
|
|
7904
|
+
if (streamedContent.length > 0) {
|
|
7905
|
+
response.streamedContent = {
|
|
7906
|
+
parts: streamedContent.map((part) => ({
|
|
7907
|
+
kind: part.kind,
|
|
7908
|
+
...part.kind === "text" && { text: part.text },
|
|
7909
|
+
...part.kind === "data" && { data: part.data }
|
|
7910
|
+
}))
|
|
7911
|
+
};
|
|
7912
|
+
}
|
|
7913
|
+
} else {
|
|
7914
|
+
let genConfig;
|
|
7915
|
+
if (hasStructuredOutput) {
|
|
7916
|
+
genConfig = {
|
|
7917
|
+
...modelSettings,
|
|
7918
|
+
toolChoice: "required"
|
|
7919
|
+
// Force tool usage, prevent text generation
|
|
7920
|
+
};
|
|
7921
|
+
} else {
|
|
7922
|
+
genConfig = {
|
|
7923
|
+
...modelSettings,
|
|
7924
|
+
toolChoice: "auto"
|
|
7925
|
+
// Allow both tools and text generation
|
|
7926
|
+
};
|
|
7927
|
+
}
|
|
7928
|
+
response = await generateText({
|
|
7929
|
+
...genConfig,
|
|
7930
|
+
messages,
|
|
7931
|
+
tools: sanitizedTools,
|
|
7932
|
+
stopWhen: async ({ steps }) => {
|
|
7933
|
+
const last = steps.at(-1);
|
|
7934
|
+
if (last && "text" in last && last.text) {
|
|
7935
|
+
try {
|
|
7936
|
+
await agentSessionManager.recordEvent(
|
|
7937
|
+
this.getStreamRequestId(),
|
|
7938
|
+
"agent_reasoning",
|
|
7939
|
+
this.config.id,
|
|
7940
|
+
{
|
|
7941
|
+
parts: [{ type: "text", content: last.text }]
|
|
7986
7942
|
}
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
|
|
7990
|
-
|
|
7991
|
-
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
|
|
7999
|
-
|
|
7943
|
+
);
|
|
7944
|
+
} catch (error) {
|
|
7945
|
+
logger15.debug({ error }, "Failed to track agent reasoning");
|
|
7946
|
+
}
|
|
7947
|
+
}
|
|
7948
|
+
if (steps.length >= 2) {
|
|
7949
|
+
const previousStep = steps[steps.length - 2];
|
|
7950
|
+
if (previousStep && "toolCalls" in previousStep && previousStep.toolCalls) {
|
|
7951
|
+
const hasStopTool = previousStep.toolCalls.some(
|
|
7952
|
+
(tc) => tc.toolName.startsWith("transfer_to_") || tc.toolName === "thinking_complete"
|
|
7953
|
+
);
|
|
7954
|
+
if (hasStopTool && "toolResults" in previousStep && previousStep.toolResults) {
|
|
7955
|
+
return true;
|
|
7956
|
+
}
|
|
7957
|
+
}
|
|
7958
|
+
}
|
|
7959
|
+
return steps.length >= this.getMaxGenerationSteps();
|
|
7960
|
+
},
|
|
7961
|
+
experimental_telemetry: {
|
|
7962
|
+
isEnabled: true,
|
|
7963
|
+
functionId: this.config.id,
|
|
7964
|
+
recordInputs: true,
|
|
7965
|
+
recordOutputs: true,
|
|
7966
|
+
metadata: {
|
|
7967
|
+
phase: "planning"
|
|
7968
|
+
}
|
|
7969
|
+
},
|
|
7970
|
+
abortSignal: AbortSignal.timeout(timeoutMs)
|
|
7971
|
+
});
|
|
7972
|
+
}
|
|
7973
|
+
if (response.steps) {
|
|
7974
|
+
const resolvedSteps = await response.steps;
|
|
7975
|
+
response = { ...response, steps: resolvedSteps };
|
|
7976
|
+
}
|
|
7977
|
+
if (hasStructuredOutput && !hasToolCallWithPrefix("transfer_to_")(response)) {
|
|
7978
|
+
const thinkingCompleteCall = response.steps?.flatMap((s) => s.toolCalls || [])?.find((tc) => tc.toolName === "thinking_complete");
|
|
7979
|
+
if (thinkingCompleteCall) {
|
|
7980
|
+
const reasoningFlow = [];
|
|
7981
|
+
if (response.steps) {
|
|
7982
|
+
response.steps.forEach((step) => {
|
|
7983
|
+
if (step.toolCalls && step.toolResults) {
|
|
7984
|
+
step.toolCalls.forEach((call, index) => {
|
|
7985
|
+
const result = step.toolResults[index];
|
|
7986
|
+
if (result) {
|
|
7987
|
+
const storedResult = toolSessionManager.getToolResult(
|
|
7988
|
+
sessionId,
|
|
7989
|
+
result.toolCallId
|
|
7990
|
+
);
|
|
7991
|
+
const toolName = storedResult?.toolName || call.toolName;
|
|
7992
|
+
if (toolName === "thinking_complete") {
|
|
7993
|
+
return;
|
|
7994
|
+
}
|
|
7995
|
+
const actualResult = storedResult?.result || result.result || result;
|
|
7996
|
+
const actualArgs = storedResult?.args || call.args;
|
|
7997
|
+
const cleanResult = actualResult && typeof actualResult === "object" && !Array.isArray(actualResult) ? Object.fromEntries(
|
|
7998
|
+
Object.entries(actualResult).filter(
|
|
7999
|
+
([key]) => key !== "_structureHints"
|
|
8000
|
+
)
|
|
8001
|
+
) : actualResult;
|
|
8002
|
+
const input = actualArgs ? JSON.stringify(actualArgs, null, 2) : "No input";
|
|
8003
|
+
const output = typeof cleanResult === "string" ? cleanResult : JSON.stringify(cleanResult, null, 2);
|
|
8004
|
+
let structureHintsFormatted = "";
|
|
8005
|
+
if (actualResult?._structureHints && this.artifactComponents && this.artifactComponents.length > 0) {
|
|
8006
|
+
const hints = actualResult._structureHints;
|
|
8007
|
+
structureHintsFormatted = `
|
|
8000
8008
|
### \u{1F4CA} Structure Hints for Artifact Creation
|
|
8001
8009
|
|
|
8002
8010
|
**Terminal Field Paths (${hints.terminalPaths?.length || 0} found):**
|
|
@@ -8020,8 +8028,8 @@ ${hints.commonFields?.map((field) => ` \u2022 ${field}`).join("\n") || " None
|
|
|
8020
8028
|
|
|
8021
8029
|
**Forbidden Syntax:** ${hints.forbiddenSyntax || "Use these paths for artifact base selectors."}
|
|
8022
8030
|
`;
|
|
8023
|
-
|
|
8024
|
-
|
|
8031
|
+
}
|
|
8032
|
+
const formattedResult = `## Tool: ${call.toolName}
|
|
8025
8033
|
|
|
8026
8034
|
### \u{1F527} TOOL_CALL_ID: ${result.toolCallId}
|
|
8027
8035
|
|
|
@@ -8030,130 +8038,61 @@ ${input}
|
|
|
8030
8038
|
|
|
8031
8039
|
### Output
|
|
8032
8040
|
${output}${structureHintsFormatted}`;
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
}
|
|
8040
|
-
});
|
|
8041
|
-
}
|
|
8042
|
-
const componentSchemas = [];
|
|
8043
|
-
if (this.config.dataComponents && this.config.dataComponents.length > 0) {
|
|
8044
|
-
this.config.dataComponents.forEach((dc) => {
|
|
8045
|
-
const propsSchema = jsonSchemaToZod(dc.props);
|
|
8046
|
-
componentSchemas.push(
|
|
8047
|
-
z.object({
|
|
8048
|
-
id: z.string(),
|
|
8049
|
-
name: z.literal(dc.name),
|
|
8050
|
-
props: propsSchema
|
|
8051
|
-
})
|
|
8052
|
-
);
|
|
8053
|
-
});
|
|
8054
|
-
}
|
|
8055
|
-
if (this.artifactComponents.length > 0) {
|
|
8056
|
-
const artifactCreateSchemas = ArtifactCreateSchema.getSchemas(
|
|
8057
|
-
this.artifactComponents
|
|
8058
|
-
);
|
|
8059
|
-
componentSchemas.push(...artifactCreateSchemas);
|
|
8060
|
-
componentSchemas.push(ArtifactReferenceSchema.getSchema());
|
|
8061
|
-
}
|
|
8062
|
-
let dataComponentsSchema;
|
|
8063
|
-
if (componentSchemas.length === 1) {
|
|
8064
|
-
dataComponentsSchema = componentSchemas[0];
|
|
8065
|
-
} else {
|
|
8066
|
-
dataComponentsSchema = z.union(
|
|
8067
|
-
componentSchemas
|
|
8068
|
-
);
|
|
8069
|
-
}
|
|
8070
|
-
const structuredModelSettings = ModelFactory.prepareGenerationConfig(
|
|
8071
|
-
this.getStructuredOutputModel()
|
|
8072
|
-
);
|
|
8073
|
-
const phase2TimeoutMs = structuredModelSettings.maxDuration ? structuredModelSettings.maxDuration * 1e3 : CONSTANTS.PHASE_2_TIMEOUT_MS;
|
|
8074
|
-
const shouldStreamPhase2 = this.getStreamingHelper();
|
|
8075
|
-
if (shouldStreamPhase2) {
|
|
8076
|
-
const phase2Messages = [
|
|
8077
|
-
{
|
|
8078
|
-
role: "system",
|
|
8079
|
-
content: await this.buildPhase2SystemPrompt(runtimeContext)
|
|
8080
|
-
}
|
|
8081
|
-
];
|
|
8082
|
-
if (conversationHistory.trim() !== "") {
|
|
8083
|
-
phase2Messages.push({ role: "user", content: conversationHistory });
|
|
8084
|
-
}
|
|
8085
|
-
phase2Messages.push({ role: "user", content: userMessage });
|
|
8086
|
-
phase2Messages.push(...reasoningFlow);
|
|
8087
|
-
const streamResult = streamObject({
|
|
8088
|
-
...structuredModelSettings,
|
|
8089
|
-
messages: phase2Messages,
|
|
8090
|
-
schema: z.object({
|
|
8091
|
-
dataComponents: z.array(dataComponentsSchema)
|
|
8092
|
-
}),
|
|
8093
|
-
experimental_telemetry: {
|
|
8094
|
-
isEnabled: true,
|
|
8095
|
-
functionId: this.config.id,
|
|
8096
|
-
recordInputs: true,
|
|
8097
|
-
recordOutputs: true,
|
|
8098
|
-
metadata: {
|
|
8099
|
-
phase: "structured_generation"
|
|
8041
|
+
reasoningFlow.push({
|
|
8042
|
+
role: "assistant",
|
|
8043
|
+
content: formattedResult
|
|
8044
|
+
});
|
|
8045
|
+
}
|
|
8046
|
+
});
|
|
8100
8047
|
}
|
|
8101
|
-
}
|
|
8102
|
-
abortSignal: AbortSignal.timeout(phase2TimeoutMs)
|
|
8103
|
-
});
|
|
8104
|
-
const streamHelper = this.getStreamingHelper();
|
|
8105
|
-
if (!streamHelper) {
|
|
8106
|
-
throw new Error("Stream helper is unexpectedly undefined in streaming context");
|
|
8048
|
+
});
|
|
8107
8049
|
}
|
|
8108
|
-
const
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
contextId,
|
|
8121
|
-
artifactParserOptions
|
|
8122
|
-
);
|
|
8123
|
-
for await (const delta of streamResult.partialObjectStream) {
|
|
8124
|
-
if (delta) {
|
|
8125
|
-
await parser.processObjectDelta(delta);
|
|
8126
|
-
}
|
|
8050
|
+
const componentSchemas = [];
|
|
8051
|
+
if (this.config.dataComponents && this.config.dataComponents.length > 0) {
|
|
8052
|
+
this.config.dataComponents.forEach((dc) => {
|
|
8053
|
+
const propsSchema = jsonSchemaToZod(dc.props);
|
|
8054
|
+
componentSchemas.push(
|
|
8055
|
+
z.object({
|
|
8056
|
+
id: z.string(),
|
|
8057
|
+
name: z.literal(dc.name),
|
|
8058
|
+
props: propsSchema
|
|
8059
|
+
})
|
|
8060
|
+
);
|
|
8061
|
+
});
|
|
8127
8062
|
}
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
kind: part.kind,
|
|
8135
|
-
...part.kind === "text" && { text: part.text },
|
|
8136
|
-
...part.kind === "data" && { data: part.data }
|
|
8137
|
-
}))
|
|
8138
|
-
};
|
|
8063
|
+
if (this.artifactComponents.length > 0) {
|
|
8064
|
+
const artifactCreateSchemas = ArtifactCreateSchema.getSchemas(
|
|
8065
|
+
this.artifactComponents
|
|
8066
|
+
);
|
|
8067
|
+
componentSchemas.push(...artifactCreateSchemas);
|
|
8068
|
+
componentSchemas.push(ArtifactReferenceSchema.getSchema());
|
|
8139
8069
|
}
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
}
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
const phase2Messages = [
|
|
8148
|
-
{ role: "system", content: await this.buildPhase2SystemPrompt(runtimeContext) }
|
|
8149
|
-
];
|
|
8150
|
-
if (conversationHistory.trim() !== "") {
|
|
8151
|
-
phase2Messages.push({ role: "user", content: conversationHistory });
|
|
8070
|
+
let dataComponentsSchema;
|
|
8071
|
+
if (componentSchemas.length === 1) {
|
|
8072
|
+
dataComponentsSchema = componentSchemas[0];
|
|
8073
|
+
} else {
|
|
8074
|
+
dataComponentsSchema = z.union(
|
|
8075
|
+
componentSchemas
|
|
8076
|
+
);
|
|
8152
8077
|
}
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8078
|
+
const structuredModelSettings = ModelFactory.prepareGenerationConfig(
|
|
8079
|
+
this.getStructuredOutputModel()
|
|
8080
|
+
);
|
|
8081
|
+
const phase2TimeoutMs = structuredModelSettings.maxDuration ? structuredModelSettings.maxDuration * 1e3 : CONSTANTS.PHASE_2_TIMEOUT_MS;
|
|
8082
|
+
const shouldStreamPhase2 = this.getStreamingHelper();
|
|
8083
|
+
if (shouldStreamPhase2) {
|
|
8084
|
+
const phase2Messages = [
|
|
8085
|
+
{
|
|
8086
|
+
role: "system",
|
|
8087
|
+
content: await this.buildPhase2SystemPrompt(runtimeContext)
|
|
8088
|
+
}
|
|
8089
|
+
];
|
|
8090
|
+
if (conversationHistory.trim() !== "") {
|
|
8091
|
+
phase2Messages.push({ role: "user", content: conversationHistory });
|
|
8092
|
+
}
|
|
8093
|
+
phase2Messages.push({ role: "user", content: userMessage });
|
|
8094
|
+
phase2Messages.push(...reasoningFlow);
|
|
8095
|
+
const streamResult = streamObject({
|
|
8157
8096
|
...structuredModelSettings,
|
|
8158
8097
|
messages: phase2Messages,
|
|
8159
8098
|
schema: z.object({
|
|
@@ -8169,65 +8108,135 @@ ${output}${structureHintsFormatted}`;
|
|
|
8169
8108
|
}
|
|
8170
8109
|
},
|
|
8171
8110
|
abortSignal: AbortSignal.timeout(phase2TimeoutMs)
|
|
8172
|
-
})
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8111
|
+
});
|
|
8112
|
+
const streamHelper = this.getStreamingHelper();
|
|
8113
|
+
if (!streamHelper) {
|
|
8114
|
+
throw new Error("Stream helper is unexpectedly undefined in streaming context");
|
|
8115
|
+
}
|
|
8116
|
+
const session = toolSessionManager.getSession(sessionId);
|
|
8117
|
+
const artifactParserOptions = {
|
|
8118
|
+
sessionId,
|
|
8119
|
+
taskId: session?.taskId,
|
|
8120
|
+
projectId: session?.projectId,
|
|
8121
|
+
artifactComponents: this.artifactComponents,
|
|
8122
|
+
streamRequestId: this.getStreamRequestId(),
|
|
8123
|
+
subAgentId: this.config.id
|
|
8124
|
+
};
|
|
8125
|
+
const parser = new IncrementalStreamParser(
|
|
8126
|
+
streamHelper,
|
|
8127
|
+
this.config.tenantId,
|
|
8128
|
+
contextId,
|
|
8129
|
+
artifactParserOptions
|
|
8130
|
+
);
|
|
8131
|
+
for await (const delta of streamResult.partialObjectStream) {
|
|
8132
|
+
if (delta) {
|
|
8133
|
+
await parser.processObjectDelta(delta);
|
|
8134
|
+
}
|
|
8135
|
+
}
|
|
8136
|
+
await parser.finalize();
|
|
8137
|
+
const structuredResponse = await streamResult;
|
|
8138
|
+
const collectedParts = parser.getCollectedParts();
|
|
8139
|
+
if (collectedParts.length > 0) {
|
|
8140
|
+
response.formattedContent = {
|
|
8141
|
+
parts: collectedParts.map((part) => ({
|
|
8142
|
+
kind: part.kind,
|
|
8143
|
+
...part.kind === "text" && { text: part.text },
|
|
8144
|
+
...part.kind === "data" && { data: part.data }
|
|
8145
|
+
}))
|
|
8146
|
+
};
|
|
8147
|
+
}
|
|
8148
|
+
response = {
|
|
8149
|
+
...response,
|
|
8150
|
+
object: structuredResponse.object
|
|
8151
|
+
};
|
|
8152
|
+
textResponse = JSON.stringify(structuredResponse.object, null, 2);
|
|
8153
|
+
} else {
|
|
8154
|
+
const { withJsonPostProcessing } = await import('./json-postprocessor-VOMU4E5L.js');
|
|
8155
|
+
const phase2Messages = [
|
|
8156
|
+
{ role: "system", content: await this.buildPhase2SystemPrompt(runtimeContext) }
|
|
8157
|
+
];
|
|
8158
|
+
if (conversationHistory.trim() !== "") {
|
|
8159
|
+
phase2Messages.push({ role: "user", content: conversationHistory });
|
|
8160
|
+
}
|
|
8161
|
+
phase2Messages.push({ role: "user", content: userMessage });
|
|
8162
|
+
phase2Messages.push(...reasoningFlow);
|
|
8163
|
+
const structuredResponse = await generateObject(
|
|
8164
|
+
withJsonPostProcessing({
|
|
8165
|
+
...structuredModelSettings,
|
|
8166
|
+
messages: phase2Messages,
|
|
8167
|
+
schema: z.object({
|
|
8168
|
+
dataComponents: z.array(dataComponentsSchema)
|
|
8169
|
+
}),
|
|
8170
|
+
experimental_telemetry: {
|
|
8171
|
+
isEnabled: true,
|
|
8172
|
+
functionId: this.config.id,
|
|
8173
|
+
recordInputs: true,
|
|
8174
|
+
recordOutputs: true,
|
|
8175
|
+
metadata: {
|
|
8176
|
+
phase: "structured_generation"
|
|
8177
|
+
}
|
|
8178
|
+
},
|
|
8179
|
+
abortSignal: AbortSignal.timeout(phase2TimeoutMs)
|
|
8180
|
+
})
|
|
8181
|
+
);
|
|
8182
|
+
response = {
|
|
8183
|
+
...response,
|
|
8184
|
+
object: structuredResponse.object
|
|
8185
|
+
};
|
|
8186
|
+
textResponse = JSON.stringify(structuredResponse.object, null, 2);
|
|
8187
|
+
}
|
|
8188
|
+
} else {
|
|
8189
|
+
textResponse = response.text || "";
|
|
8179
8190
|
}
|
|
8180
8191
|
} else {
|
|
8181
|
-
textResponse = response.text || "";
|
|
8192
|
+
textResponse = response.steps[response.steps.length - 1].text || "";
|
|
8182
8193
|
}
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
8187
|
-
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8202
|
-
|
|
8203
|
-
contextId
|
|
8204
|
-
|
|
8205
|
-
} else if (textResponse) {
|
|
8206
|
-
formattedContent = await responseFormatter.formatResponse(textResponse, contextId);
|
|
8194
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
8195
|
+
span.end();
|
|
8196
|
+
let formattedContent = response.formattedContent || null;
|
|
8197
|
+
if (!formattedContent) {
|
|
8198
|
+
const session = toolSessionManager.getSession(sessionId);
|
|
8199
|
+
const responseFormatter = new ResponseFormatter(this.config.tenantId, {
|
|
8200
|
+
sessionId,
|
|
8201
|
+
taskId: session?.taskId,
|
|
8202
|
+
projectId: session?.projectId,
|
|
8203
|
+
contextId,
|
|
8204
|
+
artifactComponents: this.artifactComponents,
|
|
8205
|
+
streamRequestId: this.getStreamRequestId(),
|
|
8206
|
+
subAgentId: this.config.id
|
|
8207
|
+
});
|
|
8208
|
+
if (response.object) {
|
|
8209
|
+
formattedContent = await responseFormatter.formatObjectResponse(
|
|
8210
|
+
response.object,
|
|
8211
|
+
contextId
|
|
8212
|
+
);
|
|
8213
|
+
} else if (textResponse) {
|
|
8214
|
+
formattedContent = await responseFormatter.formatResponse(textResponse, contextId);
|
|
8215
|
+
}
|
|
8207
8216
|
}
|
|
8217
|
+
const formattedResponse = {
|
|
8218
|
+
...response,
|
|
8219
|
+
formattedContent
|
|
8220
|
+
};
|
|
8221
|
+
if (streamRequestId) {
|
|
8222
|
+
const generationType = response.object ? "object_generation" : "text_generation";
|
|
8223
|
+
agentSessionManager.recordEvent(streamRequestId, "agent_generate", this.config.id, {
|
|
8224
|
+
parts: (formattedContent?.parts || []).map((part) => ({
|
|
8225
|
+
type: part.kind === "text" ? "text" : part.kind === "data" ? "tool_result" : "text",
|
|
8226
|
+
content: part.text || JSON.stringify(part.data)
|
|
8227
|
+
})),
|
|
8228
|
+
generationType
|
|
8229
|
+
});
|
|
8230
|
+
}
|
|
8231
|
+
return formattedResponse;
|
|
8232
|
+
} catch (error) {
|
|
8233
|
+
const errorToThrow = error instanceof Error ? error : new Error(String(error));
|
|
8234
|
+
setSpanWithError(span, errorToThrow);
|
|
8235
|
+
span.end();
|
|
8236
|
+
throw errorToThrow;
|
|
8208
8237
|
}
|
|
8209
|
-
const formattedResponse = {
|
|
8210
|
-
...response,
|
|
8211
|
-
formattedContent
|
|
8212
|
-
};
|
|
8213
|
-
if (streamRequestId) {
|
|
8214
|
-
const generationType = response.object ? "object_generation" : "text_generation";
|
|
8215
|
-
agentSessionManager.recordEvent(streamRequestId, "agent_generate", this.config.id, {
|
|
8216
|
-
parts: (formattedContent?.parts || []).map((part) => ({
|
|
8217
|
-
type: part.kind === "text" ? "text" : part.kind === "data" ? "tool_result" : "text",
|
|
8218
|
-
content: part.text || JSON.stringify(part.data)
|
|
8219
|
-
})),
|
|
8220
|
-
generationType
|
|
8221
|
-
});
|
|
8222
|
-
}
|
|
8223
|
-
return formattedResponse;
|
|
8224
|
-
} catch (error) {
|
|
8225
|
-
const errorToThrow = error instanceof Error ? error : new Error(String(error));
|
|
8226
|
-
setSpanWithError(span, errorToThrow);
|
|
8227
|
-
span.end();
|
|
8228
|
-
throw errorToThrow;
|
|
8229
8238
|
}
|
|
8230
|
-
|
|
8239
|
+
);
|
|
8231
8240
|
}
|
|
8232
8241
|
};
|
|
8233
8242
|
|
|
@@ -10576,7 +10585,17 @@ var generatePreviewRoute = createRoute({
|
|
|
10576
10585
|
tenantId: z.string(),
|
|
10577
10586
|
projectId: z.string(),
|
|
10578
10587
|
id: z.string()
|
|
10579
|
-
})
|
|
10588
|
+
}),
|
|
10589
|
+
body: {
|
|
10590
|
+
content: {
|
|
10591
|
+
"application/json": {
|
|
10592
|
+
schema: z.object({
|
|
10593
|
+
instructions: z.string().optional().describe("Custom instructions for modifying the component"),
|
|
10594
|
+
existingCode: z.string().optional().describe("Existing component code to modify")
|
|
10595
|
+
})
|
|
10596
|
+
}
|
|
10597
|
+
}
|
|
10598
|
+
}
|
|
10580
10599
|
},
|
|
10581
10600
|
responses: {
|
|
10582
10601
|
200: {
|
|
@@ -10597,7 +10616,18 @@ var generatePreviewRoute = createRoute({
|
|
|
10597
10616
|
});
|
|
10598
10617
|
app4.openapi(generatePreviewRoute, async (c) => {
|
|
10599
10618
|
const { tenantId, projectId, id } = c.req.valid("param");
|
|
10600
|
-
|
|
10619
|
+
const body = c.req.valid("json");
|
|
10620
|
+
const { instructions, existingCode } = body;
|
|
10621
|
+
logger22.info(
|
|
10622
|
+
{
|
|
10623
|
+
tenantId,
|
|
10624
|
+
projectId,
|
|
10625
|
+
dataComponentId: id,
|
|
10626
|
+
hasInstructions: !!instructions,
|
|
10627
|
+
hasExistingCode: !!existingCode
|
|
10628
|
+
},
|
|
10629
|
+
"Generating component preview"
|
|
10630
|
+
);
|
|
10601
10631
|
const dataComponent = await getDataComponent(dbClient_default)({
|
|
10602
10632
|
scopes: { tenantId, projectId },
|
|
10603
10633
|
dataComponentId: id
|
|
@@ -10617,7 +10647,7 @@ app4.openapi(generatePreviewRoute, async (c) => {
|
|
|
10617
10647
|
message: "Project base model configuration is required"
|
|
10618
10648
|
});
|
|
10619
10649
|
}
|
|
10620
|
-
const prompt = buildGenerationPrompt(dataComponent);
|
|
10650
|
+
const prompt = buildGenerationPrompt(dataComponent, instructions, existingCode);
|
|
10621
10651
|
try {
|
|
10622
10652
|
const modelConfig = ModelFactory.prepareGenerationConfig(project.models.base);
|
|
10623
10653
|
const previewSchema = z.object({
|
|
@@ -10633,10 +10663,12 @@ app4.openapi(generatePreviewRoute, async (c) => {
|
|
|
10633
10663
|
c.header("Content-Type", "text/plain; charset=utf-8");
|
|
10634
10664
|
c.header("Cache-Control", "no-cache");
|
|
10635
10665
|
c.header("Connection", "keep-alive");
|
|
10666
|
+
const existingData = existingCode && dataComponent.preview?.data ? dataComponent.preview.data : null;
|
|
10636
10667
|
return stream(c, async (stream3) => {
|
|
10637
10668
|
try {
|
|
10638
10669
|
for await (const partialObject of result.partialObjectStream) {
|
|
10639
|
-
|
|
10670
|
+
const outputObject = instructions && existingData ? { ...partialObject, data: existingData } : partialObject;
|
|
10671
|
+
await stream3.write(JSON.stringify(outputObject) + "\n");
|
|
10640
10672
|
}
|
|
10641
10673
|
} catch (error) {
|
|
10642
10674
|
logger22.error(
|
|
@@ -10659,10 +10691,50 @@ app4.openapi(generatePreviewRoute, async (c) => {
|
|
|
10659
10691
|
});
|
|
10660
10692
|
}
|
|
10661
10693
|
});
|
|
10662
|
-
function buildGenerationPrompt(dataComponent) {
|
|
10694
|
+
function buildGenerationPrompt(dataComponent, instructions, existingCode) {
|
|
10663
10695
|
const propsSchema = dataComponent.props || {};
|
|
10664
10696
|
const propsJson = JSON.stringify(propsSchema, null, 2);
|
|
10665
10697
|
const componentName = sanitizeComponentName(dataComponent.name);
|
|
10698
|
+
if (instructions && existingCode) {
|
|
10699
|
+
return `You are an expert React and Tailwind CSS developer. You need to modify an existing React component based on specific instructions.
|
|
10700
|
+
|
|
10701
|
+
COMPONENT DETAILS:
|
|
10702
|
+
- Original Name: ${dataComponent.name}
|
|
10703
|
+
- Component Function Name: ${componentName}
|
|
10704
|
+
- Description: ${dataComponent.description}
|
|
10705
|
+
- Props Schema (JSON Schema): ${propsJson}
|
|
10706
|
+
|
|
10707
|
+
EXISTING COMPONENT CODE:
|
|
10708
|
+
\`\`\`jsx
|
|
10709
|
+
${existingCode}
|
|
10710
|
+
\`\`\`
|
|
10711
|
+
|
|
10712
|
+
MODIFICATION INSTRUCTIONS:
|
|
10713
|
+
${instructions}
|
|
10714
|
+
|
|
10715
|
+
REQUIREMENTS:
|
|
10716
|
+
1. Modify the existing component code according to the instructions
|
|
10717
|
+
2. Keep using Tailwind CSS SEMANTIC COLOR CLASSES (bg-background, text-foreground, etc.)
|
|
10718
|
+
3. Maintain the balanced spacing and design principles from the original
|
|
10719
|
+
4. Keep using lucide-react icons where appropriate
|
|
10720
|
+
5. DO NOT include export statements - just the imports and function
|
|
10721
|
+
6. DO NOT include TypeScript type annotations
|
|
10722
|
+
7. Component name should remain: ${componentName}
|
|
10723
|
+
8. DO NOT regenerate sample data - keep the same data structure
|
|
10724
|
+
|
|
10725
|
+
OUTPUT FORMAT:
|
|
10726
|
+
You need to generate only one thing:
|
|
10727
|
+
1. "code": The modified React component code as a string
|
|
10728
|
+
|
|
10729
|
+
Return ONLY the code field, the data field will be reused from the existing preview.
|
|
10730
|
+
|
|
10731
|
+
EXAMPLE OUTPUT:
|
|
10732
|
+
{
|
|
10733
|
+
"code": "import { Mail, User } from 'lucide-react';\\n\\nfunction ${componentName}(props) {\\n // Modified component code here\\n}"
|
|
10734
|
+
}
|
|
10735
|
+
|
|
10736
|
+
Focus on making the requested changes while maintaining the component's quality and design principles.`;
|
|
10737
|
+
}
|
|
10666
10738
|
return `You are an expert React and Tailwind CSS developer. Generate a beautiful, modern React component for displaying data and sample data to preview it.
|
|
10667
10739
|
|
|
10668
10740
|
COMPONENT DETAILS:
|